mirror of
https://github.com/SkinnyMind/libgit2dart.git
synced 2025-05-05 04:39:07 -04:00
feat(attr): add bindings and api
This commit is contained in:
parent
934b601d68
commit
ec80ad3dd4
5 changed files with 116 additions and 6 deletions
44
lib/src/bindings/attr.dart
Normal file
44
lib/src/bindings/attr.dart
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
import 'dart:ffi';
|
||||||
|
import 'package:ffi/ffi.dart';
|
||||||
|
import '../error.dart';
|
||||||
|
import '../util.dart';
|
||||||
|
import 'libgit2_bindings.dart';
|
||||||
|
|
||||||
|
/// Look up the value of one git attribute for path.
|
||||||
|
///
|
||||||
|
/// Returned value can be either `true`, `false`, `null` (if the attribute was not set at all),
|
||||||
|
/// or a [String] value, if the attribute was set to an actual string.
|
||||||
|
///
|
||||||
|
/// Throws a [LibGit2Error] if error occured.
|
||||||
|
dynamic getAttribute({
|
||||||
|
required Pointer<git_repository> repoPointer,
|
||||||
|
required int flags,
|
||||||
|
required String path,
|
||||||
|
required String name,
|
||||||
|
}) {
|
||||||
|
final out = calloc<Pointer<Int8>>();
|
||||||
|
final pathC = path.toNativeUtf8().cast<Int8>();
|
||||||
|
final nameC = name.toNativeUtf8().cast<Int8>();
|
||||||
|
final error = libgit2.git_attr_get(out, repoPointer, flags, pathC, nameC);
|
||||||
|
|
||||||
|
calloc.free(pathC);
|
||||||
|
calloc.free(nameC);
|
||||||
|
|
||||||
|
if (error < 0) {
|
||||||
|
throw LibGit2Error(libgit2.git_error_last());
|
||||||
|
}
|
||||||
|
|
||||||
|
final attributeValue = libgit2.git_attr_value(out.value);
|
||||||
|
|
||||||
|
if (attributeValue == git_attr_value_t.GIT_ATTR_VALUE_UNSPECIFIED) {
|
||||||
|
return null;
|
||||||
|
} else if (attributeValue == git_attr_value_t.GIT_ATTR_VALUE_TRUE) {
|
||||||
|
return true;
|
||||||
|
} else if (attributeValue == git_attr_value_t.GIT_ATTR_VALUE_FALSE) {
|
||||||
|
return false;
|
||||||
|
} else if (attributeValue == git_attr_value_t.GIT_ATTR_VALUE_STRING) {
|
||||||
|
return out.value.cast<Utf8>().toDartString();
|
||||||
|
} else {
|
||||||
|
throw Exception('The attribute value from libgit2 is invalid');
|
||||||
|
}
|
||||||
|
}
|
|
@ -1356,3 +1356,31 @@ class GitFeature {
|
||||||
@override
|
@override
|
||||||
String toString() => 'GitFeature.$_name';
|
String toString() => 'GitFeature.$_name';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Combinations of these values determine the lookup order for attribute.
|
||||||
|
class GitAttributeCheck {
|
||||||
|
const GitAttributeCheck._(this._value, this._name);
|
||||||
|
final int _value;
|
||||||
|
final String _name;
|
||||||
|
|
||||||
|
static const fileThenIndex = GitAttributeCheck._(0, 'fileThenIndex');
|
||||||
|
static const indexThenFile = GitAttributeCheck._(1, 'indexThenFile');
|
||||||
|
static const indexOnly = GitAttributeCheck._(2, 'indexOnly');
|
||||||
|
static const noSystem = GitAttributeCheck._(4, 'noSystem');
|
||||||
|
static const includeHead = GitAttributeCheck._(8, 'includeHead');
|
||||||
|
static const includeCommit = GitAttributeCheck._(16, 'includeCommit');
|
||||||
|
|
||||||
|
static const List<GitAttributeCheck> values = [
|
||||||
|
fileThenIndex,
|
||||||
|
indexThenFile,
|
||||||
|
indexOnly,
|
||||||
|
noSystem,
|
||||||
|
includeHead,
|
||||||
|
includeCommit,
|
||||||
|
];
|
||||||
|
|
||||||
|
int get value => _value;
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() => 'GitAttributeCheck.$_name';
|
||||||
|
}
|
||||||
|
|
|
@ -11,6 +11,7 @@ import 'bindings/checkout.dart' as checkout_bindings;
|
||||||
import 'bindings/reset.dart' as reset_bindings;
|
import 'bindings/reset.dart' as reset_bindings;
|
||||||
import 'bindings/diff.dart' as diff_bindings;
|
import 'bindings/diff.dart' as diff_bindings;
|
||||||
import 'bindings/stash.dart' as stash_bindings;
|
import 'bindings/stash.dart' as stash_bindings;
|
||||||
|
import 'bindings/attr.dart' as attr_bindings;
|
||||||
import 'branch.dart';
|
import 'branch.dart';
|
||||||
import 'commit.dart';
|
import 'commit.dart';
|
||||||
import 'config.dart';
|
import 'config.dart';
|
||||||
|
@ -955,4 +956,26 @@ class Repository {
|
||||||
|
|
||||||
/// Returns [Remotes] object.
|
/// Returns [Remotes] object.
|
||||||
Remotes get remotes => Remotes(this);
|
Remotes get remotes => Remotes(this);
|
||||||
|
|
||||||
|
/// Looks up the value of one git attribute for path.
|
||||||
|
///
|
||||||
|
/// Returned value can be either `true`, `false`, `null` (if the attribute was not set at all),
|
||||||
|
/// or a [String] value, if the attribute was set to an actual string.
|
||||||
|
///
|
||||||
|
/// Throws a [LibGit2Error] if error occured.
|
||||||
|
dynamic getAttribute({
|
||||||
|
required String path,
|
||||||
|
required String name,
|
||||||
|
Set<GitAttributeCheck> flags = const {GitAttributeCheck.fileThenIndex},
|
||||||
|
}) {
|
||||||
|
final int flagsInt =
|
||||||
|
flags.fold(0, (previousValue, e) => previousValue | e.value);
|
||||||
|
|
||||||
|
return attr_bindings.getAttribute(
|
||||||
|
repoPointer: _repoPointer,
|
||||||
|
flags: flagsInt,
|
||||||
|
path: path,
|
||||||
|
name: name,
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,15 +5,15 @@ import 'package:libgit2dart/libgit2dart.dart';
|
||||||
void main() {
|
void main() {
|
||||||
final cloneDir = Directory('${Directory.systemTemp.path}/credentials_cloned');
|
final cloneDir = Directory('${Directory.systemTemp.path}/credentials_cloned');
|
||||||
|
|
||||||
setUp(() async {
|
setUp(() {
|
||||||
if (await cloneDir.exists()) {
|
if (cloneDir.existsSync()) {
|
||||||
cloneDir.delete(recursive: true);
|
cloneDir.deleteSync(recursive: true);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
tearDown(() async {
|
tearDown(() {
|
||||||
if (await cloneDir.exists()) {
|
if (cloneDir.existsSync()) {
|
||||||
cloneDir.delete(recursive: true);
|
cloneDir.deleteSync(recursive: true);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
group('Credentials', () {
|
group('Credentials', () {
|
||||||
|
|
|
@ -236,5 +236,20 @@ void main() {
|
||||||
signature.free();
|
signature.free();
|
||||||
config.free();
|
config.free();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('returns attribute value', () async {
|
||||||
|
expect(repo.getAttribute(path: 'invalid', name: 'not-there'), null);
|
||||||
|
|
||||||
|
final attrFile = await File('${repo.workdir}.gitattributes').create();
|
||||||
|
attrFile.writeAsString('*.dart text\n*.jpg -text\n*.sh eol=lf\n');
|
||||||
|
|
||||||
|
await File('${repo.workdir}file.dart').create();
|
||||||
|
await File('${repo.workdir}file.sh').create();
|
||||||
|
|
||||||
|
expect(repo.getAttribute(path: 'file.dart', name: 'not-there'), null);
|
||||||
|
expect(repo.getAttribute(path: 'file.dart', name: 'text'), true);
|
||||||
|
expect(repo.getAttribute(path: 'file.jpg', name: 'text'), false);
|
||||||
|
expect(repo.getAttribute(path: 'file.sh', name: 'eol'), 'lf');
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue