feat(tag): add bindings and api

This commit is contained in:
Aleksey Kulikov 2021-09-03 12:13:23 +03:00
parent f0803298c8
commit 0cdaa6f8f4
10 changed files with 392 additions and 1 deletions

View file

@ -1,6 +1,41 @@
import 'dart:ffi';
import 'package:ffi/ffi.dart';
import 'libgit2_bindings.dart';
import '../error.dart';
import '../util.dart';
/// Get the object type of an object.
int type(Pointer<git_object> obj) => libgit2.git_object_type(obj);
/// Lookup a reference to one of the objects in a repository.
///
/// The generated reference is owned by the repository and should be closed with
/// the `free()` method instead of free'd manually.
///
/// The 'type' parameter must match the type of the object in the odb; the method will
/// fail otherwise. The special value 'GIT_OBJECT_ANY' may be passed to let the method
/// guess the object's type.
///
/// Throws a [LibGit2Error] if error occured.
Pointer<git_object> lookup(
Pointer<git_repository> repo,
Pointer<git_oid> id,
int type,
) {
final out = calloc<Pointer<git_object>>();
final error = libgit2.git_object_lookup(out, repo, id, type);
if (error < 0) {
throw LibGit2Error(libgit2.git_error_last());
} else {
return out.value;
}
}
/// Close an open object to release memory.
///
/// This method instructs the library to close an existing object; note that git_objects
/// are owned and cached by the repository so the object may or may not be freed after
/// this library call, depending on how aggressive is the caching mechanism used by
/// the repository.
void free(Pointer<git_object> object) => libgit2.git_object_free(object);

97
lib/src/bindings/tag.dart Normal file
View file

@ -0,0 +1,97 @@
import 'dart:ffi';
import 'package:ffi/ffi.dart';
import '../error.dart';
import 'libgit2_bindings.dart';
import '../util.dart';
/// Lookup a tag object from the repository.
///
/// Throws a [LibGit2Error] if error occured.
Pointer<git_tag> lookup(Pointer<git_repository> repo, Pointer<git_oid> id) {
final out = calloc<Pointer<git_tag>>();
final error = libgit2.git_tag_lookup(out, repo, id);
if (error < 0) {
throw LibGit2Error(libgit2.git_error_last());
} else {
return out.value;
}
}
/// Get the tagged object of a tag.
///
/// This method performs a repository lookup for the given object and returns it.
///
/// Throws a [LibGit2Error] if error occured.
Pointer<git_object> target(Pointer<git_tag> tag) {
final out = calloc<Pointer<git_object>>();
final error = libgit2.git_tag_target(out, tag);
if (error < 0) {
throw LibGit2Error(libgit2.git_error_last());
} else {
return out.value;
}
}
/// Get the id of a tag.
Pointer<git_oid> id(Pointer<git_tag> tag) => libgit2.git_tag_id(tag);
/// Get the name of a tag.
String name(Pointer<git_tag> tag) =>
libgit2.git_tag_name(tag).cast<Utf8>().toDartString();
/// Get the message of a tag.
String message(Pointer<git_tag> tag) =>
libgit2.git_tag_message(tag).cast<Utf8>().toDartString();
/// Get the tagger (author) of a tag.
Pointer<git_signature> tagger(Pointer<git_tag> tag) =>
libgit2.git_tag_tagger(tag);
/// Create a new tag in the repository from an object.
///
/// A new reference will also be created pointing to this tag object. If force is true
/// and a reference already exists with the given name, it'll be replaced.
///
/// The message will not be cleaned up.
///
/// The tag name will be checked for validity. You must avoid the characters
/// '~', '^', ':', '\', '?', '[', and '*', and the sequences ".." and "@{" which have
/// special meaning to revparse.
///
/// Throws a [LibGit2Error] if error occured.
Pointer<git_oid> create(
Pointer<git_repository> repo,
String tagName,
Pointer<git_object> target,
Pointer<git_signature> tagger,
String message,
bool force,
) {
final out = calloc<git_oid>();
final tagNameC = tagName.toNativeUtf8().cast<Int8>();
final messageC = message.toNativeUtf8().cast<Int8>();
final forceC = force ? 1 : 0;
final error = libgit2.git_tag_create(
out,
repo,
tagNameC,
target,
tagger,
messageC,
forceC,
);
calloc.free(tagNameC);
calloc.free(messageC);
if (error < 0) {
throw LibGit2Error(libgit2.git_error_last());
} else {
return out;
}
}
/// Close an open tag to release memory.
void free(Pointer<git_tag> tag) => libgit2.git_tag_free(tag);

View file

@ -12,6 +12,8 @@ import 'revwalk.dart';
import 'revparse.dart';
import 'blob.dart';
import 'enums.dart';
import 'signature.dart';
import 'tag.dart';
import 'util.dart';
class Repository {
@ -397,4 +399,34 @@ class Repository {
///
/// Throws a [LibGit2Error] if error occured.
Oid createBlobFromDisk(String path) => Blob.createFromDisk(this, path);
/// Creates a new tag in the repository from provided Oid object.
///
/// A new reference will also be created pointing to this tag object. If force is true
/// and a reference already exists with the given name, it'll be replaced.
///
/// The message will not be cleaned up.
///
/// The tag name will be checked for validity. You must avoid the characters
/// '~', '^', ':', '\', '?', '[', and '*', and the sequences ".." and "@{" which have
/// special meaning to revparse.
///
/// Throws a [LibGit2Error] if error occured.
Oid createTag({
required String tagName,
required Oid target,
required GitObject targetType,
required Signature tagger,
required String message,
bool force = false,
}) {
return Tag.create(
repository: this,
tagName: tagName,
target: target,
targetType: targetType,
tagger: tagger,
message: message,
force: force);
}
}

94
lib/src/tag.dart Normal file
View file

@ -0,0 +1,94 @@
import 'dart:ffi';
import 'bindings/libgit2_bindings.dart';
import 'bindings/tag.dart' as bindings;
import 'bindings/object.dart' as object_bindings;
import 'commit.dart';
import 'oid.dart';
import 'repository.dart';
import 'signature.dart';
import 'enums.dart';
class Tag {
/// Initializes a new instance of [Tag] class from provided
/// [Repository] and [Oid] objects.
///
/// Should be freed with `free()` to release allocated memory.
Tag.lookup(Repository repo, Oid oid) {
_tagPointer = bindings.lookup(repo.pointer, oid.pointer);
}
late final Pointer<git_tag> _tagPointer;
/// Pointer to memory address for allocated tag object.
Pointer<git_tag> get pointer => _tagPointer;
/// Creates a new tag in the repository from provided Oid object.
///
/// A new reference will also be created pointing to this tag object. If force is true
/// and a reference already exists with the given name, it'll be replaced.
///
/// The message will not be cleaned up.
///
/// The tag name will be checked for validity. You must avoid the characters
/// '~', '^', ':', '\', '?', '[', and '*', and the sequences ".." and "@{" which have
/// special meaning to revparse.
///
/// Throws a [LibGit2Error] if error occured.
static Oid create({
required Repository repository,
required String tagName,
required Oid target,
required GitObject targetType,
required Signature tagger,
required String message,
bool force = false,
}) {
// add 1 to GitObject enum index to match libgit2
final object = object_bindings.lookup(
repository.pointer,
target.pointer,
targetType.index + 1,
);
final result = bindings.create(
repository.pointer,
tagName,
object,
tagger.pointer,
message,
force,
);
object_bindings.free(object);
return Oid(result);
}
/// Get the tagged object of a tag.
///
/// This method performs a repository lookup for the given object and returns it.
///
/// Throws a [LibGit2Error] if error occured.
Commit get target => Commit(bindings.target(_tagPointer).cast());
/// Get the id of a tag.
Oid get id => Oid(bindings.id(_tagPointer));
/// Returns the name of a tag.
String get name => bindings.name(_tagPointer);
/// Returns the message of a tag.
String get message => bindings.message(_tagPointer);
/// Returns the tagger (author) of a tag if there is one.
Signature? get tagger {
final sigPointer = bindings.tagger(_tagPointer);
if (sigPointer != nullptr) {
return Signature(sigPointer);
} else {
return null;
}
}
/// Releases memory allocated for tag object.
void free() => bindings.free(_tagPointer);
}