mirror of
https://github.com/SkinnyMind/libgit2dart.git
synced 2025-05-04 20:29:08 -04:00
feat(repository): add ability to lookup different types of git objects with []
This commit is contained in:
parent
f19a34a768
commit
2cf974c624
14 changed files with 124 additions and 67 deletions
|
@ -3,13 +3,23 @@ import 'bindings/libgit2_bindings.dart';
|
|||
import 'bindings/blob.dart' as bindings;
|
||||
import 'oid.dart';
|
||||
import 'repository.dart';
|
||||
import 'util.dart';
|
||||
|
||||
class Blob {
|
||||
/// Initializes a new instance of [Blob] class from provided
|
||||
/// [Repository] and [Oid] objects.
|
||||
/// Initializes a new instance of [Blob] class from provided pointer to
|
||||
/// blob object in memory.
|
||||
///
|
||||
/// Should be freed with `free()` to release allocated memory.
|
||||
Blob.lookup(Repository repo, Oid oid) {
|
||||
Blob(this._blobPointer) {
|
||||
libgit2.git_libgit2_init();
|
||||
}
|
||||
|
||||
/// Initializes a new instance of [Blob] class from provided
|
||||
/// [Repository] object and [sha] hex string.
|
||||
///
|
||||
/// Should be freed with `free()` to release allocated memory.
|
||||
Blob.lookup(Repository repo, String sha) {
|
||||
final oid = Oid.fromSHA(repo, sha);
|
||||
_blobPointer = bindings.lookup(repo.pointer, oid.pointer);
|
||||
}
|
||||
|
||||
|
|
|
@ -16,11 +16,12 @@ class Commit {
|
|||
libgit2.git_libgit2_init();
|
||||
}
|
||||
|
||||
/// Initializes a new instance of [Commit] class from provided [Repository]
|
||||
/// and [Oid] objects.
|
||||
/// Initializes a new instance of [Commit] class from provided [Repository] object
|
||||
/// and [sha] hex string.
|
||||
///
|
||||
/// Should be freed with `free()` to release allocated memory.
|
||||
Commit.lookup(Repository repo, Oid oid) {
|
||||
Commit.lookup(Repository repo, String sha) {
|
||||
final oid = Oid.fromSHA(repo, sha);
|
||||
_commitPointer = bindings.lookup(repo.pointer, oid.pointer);
|
||||
}
|
||||
|
||||
|
@ -40,8 +41,7 @@ class Commit {
|
|||
String? updateRef,
|
||||
String? messageEncoding,
|
||||
}) {
|
||||
final treeOid = Oid.fromSHA(repo, treeSHA);
|
||||
final tree = Tree.lookup(repo, treeOid);
|
||||
final tree = Tree.lookup(repo, treeSHA);
|
||||
|
||||
final result = Oid(bindings.create(
|
||||
repo.pointer,
|
||||
|
|
|
@ -63,33 +63,33 @@ class GitSort {
|
|||
}
|
||||
|
||||
/// Basic type (loose or packed) of any Git object.
|
||||
class GitObjectType {
|
||||
const GitObjectType._(this._value);
|
||||
class GitObject {
|
||||
const GitObject._(this._value);
|
||||
final int _value;
|
||||
|
||||
/// Object can be any of the following.
|
||||
static const any = GitObjectType._(-2);
|
||||
static const any = GitObject._(-2);
|
||||
|
||||
/// Object is invalid.
|
||||
static const invalid = GitObjectType._(-1);
|
||||
static const invalid = GitObject._(-1);
|
||||
|
||||
/// A commit object.
|
||||
static const commit = GitObjectType._(1);
|
||||
static const commit = GitObject._(1);
|
||||
|
||||
/// A tree (directory listing) object.
|
||||
static const tree = GitObjectType._(2);
|
||||
static const tree = GitObject._(2);
|
||||
|
||||
/// A file revision object.
|
||||
static const blob = GitObjectType._(3);
|
||||
static const blob = GitObject._(3);
|
||||
|
||||
/// An annotated tag object.
|
||||
static const tag = GitObjectType._(4);
|
||||
static const tag = GitObject._(4);
|
||||
|
||||
/// A delta, base is given by an offset.
|
||||
static const offsetDelta = GitObjectType._(6);
|
||||
static const offsetDelta = GitObject._(6);
|
||||
|
||||
/// A delta, base is given by object id.
|
||||
static const refDelta = GitObjectType._(7);
|
||||
static const refDelta = GitObject._(7);
|
||||
|
||||
int get value => _value;
|
||||
}
|
||||
|
|
|
@ -93,21 +93,21 @@ class Index {
|
|||
/// Updates the contents of an existing index object in memory by reading from the
|
||||
/// specified tree.
|
||||
void readTree(Object target) {
|
||||
late final Oid oid;
|
||||
late final Tree tree;
|
||||
|
||||
if (target is Oid) {
|
||||
final repo = Repository(bindings.owner(_indexPointer));
|
||||
tree = Tree.lookup(repo, target);
|
||||
tree = Tree.lookup(repo, target.sha);
|
||||
} else if (target is Tree) {
|
||||
tree = target;
|
||||
} else if (isValidShaHex(target as String)) {
|
||||
} else if (target is String) {
|
||||
final repo = Repository(bindings.owner(_indexPointer));
|
||||
oid = Oid.fromSHA(repo, target);
|
||||
tree = Tree.lookup(repo, oid);
|
||||
tree = Tree.lookup(repo, target);
|
||||
} else {
|
||||
throw ArgumentError.value(
|
||||
'$target should be either Oid object, SHA hex string or Tree object');
|
||||
}
|
||||
|
||||
bindings.readTree(_indexPointer, tree.pointer);
|
||||
tree.free();
|
||||
}
|
||||
|
|
|
@ -15,8 +15,11 @@ class Oid {
|
|||
/// in the ODB of [repository] with provided hexadecimal [sha] string that is 40 characters
|
||||
/// long or shorter.
|
||||
///
|
||||
/// Throws [ArgumentError] if provided [sha] hex string is not valid.
|
||||
///
|
||||
/// Throws a [LibGit2Error] if error occured.
|
||||
Oid.fromSHA(Repository repository, String sha) {
|
||||
if (isValidShaHex(sha)) {
|
||||
if (sha.length == 40) {
|
||||
_oidPointer = bindings.fromSHA(sha);
|
||||
} else {
|
||||
|
@ -24,6 +27,9 @@ class Oid {
|
|||
_oidPointer = odb.existsPrefix(bindings.fromStrN(sha), sha.length);
|
||||
odb.free();
|
||||
}
|
||||
} else {
|
||||
throw ArgumentError.value('$sha is not a valid sha hex string');
|
||||
}
|
||||
}
|
||||
|
||||
/// Initializes a new instance of [Oid] class from provided raw git_oid.
|
||||
|
|
|
@ -4,6 +4,7 @@ import 'package:libgit2dart/libgit2dart.dart';
|
|||
import 'bindings/libgit2_bindings.dart';
|
||||
import 'bindings/repository.dart' as bindings;
|
||||
import 'bindings/merge.dart' as merge_bindings;
|
||||
import 'bindings/object.dart' as object_bindings;
|
||||
import 'commit.dart';
|
||||
import 'config.dart';
|
||||
import 'index.dart';
|
||||
|
@ -273,8 +274,8 @@ class Repository {
|
|||
late final Oid oid;
|
||||
late final bool isDirect;
|
||||
|
||||
if (target.runtimeType == Oid) {
|
||||
oid = target as Oid;
|
||||
if (target is Oid) {
|
||||
oid = target;
|
||||
isDirect = true;
|
||||
} else if (isValidShaHex(target as String)) {
|
||||
oid = Oid.fromSHA(this, target);
|
||||
|
@ -314,18 +315,39 @@ class Repository {
|
|||
/// Throws a [LibGit2Error] if error occured.
|
||||
Odb get odb => Odb(bindings.odb(_repoPointer));
|
||||
|
||||
/// Looksup [Commit] for provided [sha] hex string.
|
||||
/// Looksup git object (commit, tree, blob, tag) for provided [sha] hex string.
|
||||
///
|
||||
/// Throws [ArgumentError] if provided [sha] is not valid sha hex string.
|
||||
Commit operator [](String sha) {
|
||||
late final Oid oid;
|
||||
/// Returned object should be explicitly downcasted to one of four of git object types.
|
||||
///
|
||||
/// ```dart
|
||||
/// final commit = repo['s0m3sh4'] as Commit;
|
||||
/// final tree = repo['s0m3sh4'] as Tree;
|
||||
/// final blob = repo['s0m3sh4'] as Blob;
|
||||
/// final tag = repo['s0m3sh4'] as Tag;
|
||||
/// ```
|
||||
///
|
||||
/// Throws [ArgumentError] if provided [sha] is not pointing to commit, tree, blob or tag.
|
||||
Object operator [](String sha) {
|
||||
final oid = Oid.fromSHA(this, sha);
|
||||
final object = object_bindings.lookup(
|
||||
_repoPointer,
|
||||
oid.pointer,
|
||||
GitObject.any.value,
|
||||
);
|
||||
final type = object_bindings.type(object);
|
||||
|
||||
if (isValidShaHex(sha)) {
|
||||
oid = Oid.fromSHA(this, sha);
|
||||
if (type == GitObject.commit.value) {
|
||||
return Commit(object.cast());
|
||||
} else if (type == GitObject.tree.value) {
|
||||
return Tree(object.cast());
|
||||
} else if (type == GitObject.blob.value) {
|
||||
return Blob(object.cast());
|
||||
} else if (type == GitObject.tag.value) {
|
||||
return Tag(object.cast());
|
||||
} else {
|
||||
throw ArgumentError.value('$sha is not a valid sha hex string');
|
||||
throw ArgumentError.value(
|
||||
'$sha should be pointing to either commit, tree, blob or a tag');
|
||||
}
|
||||
return Commit.lookup(this, oid);
|
||||
}
|
||||
|
||||
/// Returns the list of commits starting from provided [oid].
|
||||
|
@ -415,7 +437,7 @@ class Repository {
|
|||
Oid createTag({
|
||||
required String tagName,
|
||||
required Oid target,
|
||||
required GitObjectType targetType,
|
||||
required GitObject targetType,
|
||||
required Signature tagger,
|
||||
required String message,
|
||||
bool force = false,
|
||||
|
|
|
@ -8,13 +8,23 @@ import 'oid.dart';
|
|||
import 'repository.dart';
|
||||
import 'signature.dart';
|
||||
import 'git_types.dart';
|
||||
import 'util.dart';
|
||||
|
||||
class Tag {
|
||||
/// Initializes a new instance of [Tag] class from provided
|
||||
/// [Repository] and [Oid] objects.
|
||||
/// Initializes a new instance of [Tag] class from provided pointer to
|
||||
/// tag object in memory.
|
||||
///
|
||||
/// Should be freed with `free()` to release allocated memory.
|
||||
Tag.lookup(Repository repo, Oid oid) {
|
||||
Tag(this._tagPointer) {
|
||||
libgit2.git_libgit2_init();
|
||||
}
|
||||
|
||||
/// Initializes a new instance of [Tag] class from provided
|
||||
/// [Repository] object and [sha] hex string.
|
||||
///
|
||||
/// Should be freed with `free()` to release allocated memory.
|
||||
Tag.lookup(Repository repo, String sha) {
|
||||
final oid = Oid.fromSHA(repo, sha);
|
||||
_tagPointer = bindings.lookup(repo.pointer, oid.pointer);
|
||||
}
|
||||
|
||||
|
@ -39,7 +49,7 @@ class Tag {
|
|||
required Repository repository,
|
||||
required String tagName,
|
||||
required Oid target,
|
||||
required GitObjectType targetType,
|
||||
required GitObject targetType,
|
||||
required Signature tagger,
|
||||
required String message,
|
||||
bool force = false,
|
||||
|
|
|
@ -7,11 +7,20 @@ import 'git_types.dart';
|
|||
import 'util.dart';
|
||||
|
||||
class Tree {
|
||||
/// Initializes a new instance of [Tree] class from provided
|
||||
/// [Repository] and [Oid] objects.
|
||||
/// Initializes a new instance of [Tree] class from provided pointer to
|
||||
/// tree object in memory.
|
||||
///
|
||||
/// Should be freed with `free()` to release allocated memory.
|
||||
Tree.lookup(Repository repo, Oid oid) {
|
||||
Tree(this._treePointer) {
|
||||
libgit2.git_libgit2_init();
|
||||
}
|
||||
|
||||
/// Initializes a new instance of [Tree] class from provided
|
||||
/// [Repository] object and [sha] hex string.
|
||||
///
|
||||
/// Should be freed with `free()` to release allocated memory.
|
||||
Tree.lookup(Repository repo, String sha) {
|
||||
final oid = Oid.fromSHA(repo, sha);
|
||||
_treePointer = bindings.lookup(repo.pointer, oid.pointer);
|
||||
}
|
||||
|
||||
|
|
|
@ -21,7 +21,7 @@ void main() {
|
|||
to: await Directory(tmpDir).create(),
|
||||
);
|
||||
repo = Repository.open(tmpDir);
|
||||
blob = Blob.lookup(repo, Oid.fromSHA(repo, blobSHA));
|
||||
blob = Blob.lookup(repo, blobSHA);
|
||||
});
|
||||
|
||||
tearDown(() async {
|
||||
|
@ -44,7 +44,7 @@ void main() {
|
|||
|
||||
test('successfully creates new blob', () {
|
||||
final oid = Blob.create(repo, newBlobContent);
|
||||
final newBlob = Blob.lookup(repo, oid);
|
||||
final newBlob = Blob.lookup(repo, oid.sha);
|
||||
|
||||
expect(newBlob.id.sha, '18fdaeef018e57a92bcad2d4a35b577f34089af6');
|
||||
expect(newBlob.isBinary, false);
|
||||
|
@ -57,7 +57,7 @@ void main() {
|
|||
test('successfully creates new blob from file at provided relative path',
|
||||
() {
|
||||
final oid = Blob.createFromWorkdir(repo, 'feature_file');
|
||||
final newBlob = Blob.lookup(repo, oid);
|
||||
final newBlob = Blob.lookup(repo, oid.sha);
|
||||
|
||||
expect(newBlob.id.sha, blobSHA);
|
||||
expect(newBlob.isBinary, false);
|
||||
|
@ -89,7 +89,7 @@ void main() {
|
|||
final outsideFile =
|
||||
File('${Directory.current.absolute.path}/test/blob_test.dart');
|
||||
final oid = Blob.createFromDisk(repo, outsideFile.path);
|
||||
final newBlob = Blob.lookup(repo, oid);
|
||||
final newBlob = Blob.lookup(repo, oid.sha);
|
||||
|
||||
expect(newBlob, isA<Blob>());
|
||||
expect(newBlob.isBinary, false);
|
||||
|
|
|
@ -45,13 +45,13 @@ void main() {
|
|||
|
||||
group('Commit', () {
|
||||
test('successfully returns when 40 char sha hex is provided', () {
|
||||
final commit = repo[mergeCommit];
|
||||
final commit = repo[mergeCommit] as Commit;
|
||||
expect(commit, isA<Commit>());
|
||||
commit.free();
|
||||
});
|
||||
|
||||
test('successfully returns when sha hex is short', () {
|
||||
final commit = repo[mergeCommit.substring(0, 5)];
|
||||
final commit = repo[mergeCommit.substring(0, 5)] as Commit;
|
||||
expect(commit, isA<Commit>());
|
||||
commit.free();
|
||||
});
|
||||
|
@ -66,7 +66,7 @@ void main() {
|
|||
parents: [mergeCommit],
|
||||
);
|
||||
|
||||
final commit = repo[oid.sha];
|
||||
final commit = repo[oid.sha] as Commit;
|
||||
|
||||
expect(commit.id.sha, oid.sha);
|
||||
expect(commit.message, message);
|
||||
|
@ -91,7 +91,7 @@ void main() {
|
|||
parents: [],
|
||||
);
|
||||
|
||||
final commit = repo[oid.sha];
|
||||
final commit = repo[oid.sha] as Commit;
|
||||
|
||||
expect(commit.id.sha, oid.sha);
|
||||
expect(commit.message, message);
|
||||
|
@ -115,7 +115,7 @@ void main() {
|
|||
parents: [mergeCommit, 'fc38877b2552ab554752d9a77e1f48f738cca79b'],
|
||||
);
|
||||
|
||||
final commit = repo[oid.sha];
|
||||
final commit = repo[oid.sha] as Commit;
|
||||
|
||||
expect(commit.id.sha, oid.sha);
|
||||
expect(commit.message, message);
|
||||
|
@ -141,7 +141,7 @@ void main() {
|
|||
parents: [mergeCommit],
|
||||
);
|
||||
|
||||
final commit = repo[oid.sha];
|
||||
final commit = repo[oid.sha] as Commit;
|
||||
|
||||
expect(commit.id.sha, oid.sha);
|
||||
expect(commit.message, message);
|
||||
|
|
|
@ -275,7 +275,7 @@ void main() {
|
|||
|
||||
test('successfully creates new blob', () {
|
||||
final oid = repo.createBlob(newBlobContent);
|
||||
final newBlob = Blob.lookup(repo, oid);
|
||||
final newBlob = repo[oid.sha] as Blob;
|
||||
|
||||
expect(newBlob, isA<Blob>());
|
||||
|
||||
|
@ -286,7 +286,7 @@ void main() {
|
|||
'successfully creates new blob from file at provided relative path',
|
||||
() {
|
||||
final oid = repo.createBlobFromWorkdir('feature_file');
|
||||
final newBlob = Blob.lookup(repo, oid);
|
||||
final newBlob = repo[oid.sha] as Blob;
|
||||
|
||||
expect(newBlob, isA<Blob>());
|
||||
|
||||
|
@ -297,7 +297,7 @@ void main() {
|
|||
final outsideFile =
|
||||
File('${Directory.current.absolute.path}/test/blob_test.dart');
|
||||
final oid = repo.createBlobFromDisk(outsideFile.path);
|
||||
final newBlob = Blob.lookup(repo, oid);
|
||||
final newBlob = repo[oid.sha] as Blob;
|
||||
|
||||
expect(newBlob, isA<Blob>());
|
||||
|
||||
|
@ -320,12 +320,12 @@ void main() {
|
|||
repository: repo,
|
||||
tagName: tagName,
|
||||
target: target,
|
||||
targetType: GitObjectType.commit,
|
||||
targetType: GitObject.commit,
|
||||
tagger: signature,
|
||||
message: message,
|
||||
);
|
||||
|
||||
final newTag = Tag.lookup(repo, oid);
|
||||
final newTag = repo[oid.sha] as Tag;
|
||||
final tagger = newTag.tagger;
|
||||
final newTagTarget = newTag.target;
|
||||
|
||||
|
|
|
@ -19,7 +19,7 @@ void main() {
|
|||
to: await Directory(tmpDir).create(),
|
||||
);
|
||||
repo = Repository.open(tmpDir);
|
||||
tag = Tag.lookup(repo, Oid.fromSHA(repo, tagSHA));
|
||||
tag = Tag.lookup(repo, tagSHA);
|
||||
});
|
||||
|
||||
tearDown(() async {
|
||||
|
@ -68,12 +68,12 @@ void main() {
|
|||
repository: repo,
|
||||
tagName: tagName,
|
||||
target: target,
|
||||
targetType: GitObjectType.commit,
|
||||
targetType: GitObject.commit,
|
||||
tagger: signature,
|
||||
message: message,
|
||||
);
|
||||
|
||||
final newTag = Tag.lookup(repo, oid);
|
||||
final newTag = Tag.lookup(repo, oid.sha);
|
||||
final tagger = newTag.tagger;
|
||||
final newTagTarget = newTag.target;
|
||||
|
||||
|
|
|
@ -20,7 +20,7 @@ void main() {
|
|||
to: await Directory(tmpDir).create(),
|
||||
);
|
||||
repo = Repository.open(tmpDir);
|
||||
tree = Tree.lookup(repo, Oid.fromSHA(repo, treeSHA));
|
||||
tree = Tree.lookup(repo, treeSHA);
|
||||
});
|
||||
|
||||
tearDown(() async {
|
||||
|
@ -73,7 +73,7 @@ void main() {
|
|||
final builder = TreeBuilder(repo);
|
||||
|
||||
builder.add('filename', fileOid, GitFilemode.blob);
|
||||
final newTree = Tree.lookup(repo, builder.write());
|
||||
final newTree = Tree.lookup(repo, builder.write().sha);
|
||||
|
||||
final entry = newTree['filename'];
|
||||
expect(newTree.length, 1);
|
||||
|
|
|
@ -19,7 +19,7 @@ void main() {
|
|||
to: await Directory(tmpDir).create(),
|
||||
);
|
||||
repo = Repository.open(tmpDir);
|
||||
tree = Tree.lookup(repo, Oid.fromSHA(repo, treeSHA));
|
||||
tree = Tree.lookup(repo, treeSHA);
|
||||
});
|
||||
|
||||
tearDown(() async {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue