package git /* #include extern int _go_git_tag_foreach(git_repository *repo, void *payload); */ import "C" import ( "runtime" "unsafe" ) // Tag type Tag struct { Object cast_ptr *C.git_tag } func (t *Tag) AsObject() *Object { return &t.Object } func (t *Tag) Message() string { ret := C.GoString(C.git_tag_message(t.cast_ptr)) runtime.KeepAlive(t) return ret } func (t *Tag) Name() string { ret := C.GoString(C.git_tag_name(t.cast_ptr)) runtime.KeepAlive(t) return ret } func (t *Tag) Tagger() *Signature { cast_ptr := C.git_tag_tagger(t.cast_ptr) ret := newSignatureFromC(cast_ptr) runtime.KeepAlive(t) return ret } func (t *Tag) Target() *Object { var ptr *C.git_object ret := C.git_tag_target(&ptr, t.cast_ptr) runtime.KeepAlive(t) if ret != 0 { return nil } return allocObject(ptr, t.repo) } func (t *Tag) TargetId() *Oid { ret := newOidFromC(C.git_tag_target_id(t.cast_ptr)) runtime.KeepAlive(t) return ret } func (t *Tag) TargetType() ObjectType { ret := ObjectType(C.git_tag_target_type(t.cast_ptr)) runtime.KeepAlive(t) return ret } type TagsCollection struct { repo *Repository } func (c *TagsCollection) Create(name string, obj Objecter, tagger *Signature, message string) (*Oid, error) { oid := new(Oid) cname := C.CString(name) defer C.free(unsafe.Pointer(cname)) cmessage := C.CString(message) defer C.free(unsafe.Pointer(cmessage)) taggerSig, err := tagger.toC() if err != nil { return nil, err } defer C.git_signature_free(taggerSig) runtime.LockOSThread() defer runtime.UnlockOSThread() o := obj.AsObject() ret := C.git_tag_create(oid.toC(), c.repo.ptr, cname, o.ptr, taggerSig, cmessage, 0) runtime.KeepAlive(c) runtime.KeepAlive(obj) if ret < 0 { return nil, MakeGitError(ret) } return oid, nil } func (c *TagsCollection) Remove(name string) error { runtime.LockOSThread() defer runtime.UnlockOSThread() cname := C.CString(name) defer C.free(unsafe.Pointer(cname)) ret := C.git_tag_delete(c.repo.ptr, cname) runtime.KeepAlive(c) if ret < 0 { return MakeGitError(ret) } return nil } // CreateLightweight creates a new lightweight tag pointing to an object // and returns the id of the target object. // // The name of the tag is validated for consistency (see git_tag_create() for the rules // https://libgit2.github.com/libgit2/#HEAD/group/tag/git_tag_create) and should // not conflict with an already existing tag name. // // If force is true and a reference already exists with the given name, it'll be replaced. // // The created tag is a simple reference and can be queried using // repo.References.Lookup("refs/tags/"). The name of the tag (eg "v1.0.0") // is queried with ref.Shorthand(). func (c *TagsCollection) CreateLightweight(name string, obj Objecter, force bool) (*Oid, error) { oid := new(Oid) cname := C.CString(name) defer C.free(unsafe.Pointer(cname)) runtime.LockOSThread() defer runtime.UnlockOSThread() o := obj.AsObject() err := C.git_tag_create_lightweight(oid.toC(), c.repo.ptr, cname, o.ptr, cbool(force)) runtime.KeepAlive(c) runtime.KeepAlive(obj) if err < 0 { return nil, MakeGitError(err) } return oid, nil } // List returns the names of all the tags in the repository, // eg: ["v1.0.1", "v2.0.0"]. func (c *TagsCollection) List() ([]string, error) { var strC C.git_strarray runtime.LockOSThread() defer runtime.UnlockOSThread() ecode := C.git_tag_list(&strC, c.repo.ptr) runtime.KeepAlive(c) if ecode < 0 { return nil, MakeGitError(ecode) } defer C.git_strarray_dispose(&strC) tags := makeStringsFromCStrings(strC.strings, int(strC.count)) return tags, nil } // ListWithMatch returns the names of all the tags in the repository // that match a given pattern. // // The pattern is a standard fnmatch(3) pattern http://man7.org/linux/man-pages/man3/fnmatch.3.html func (c *TagsCollection) ListWithMatch(pattern string) ([]string, error) { var strC C.git_strarray patternC := C.CString(pattern) defer C.free(unsafe.Pointer(patternC)) runtime.LockOSThread() defer runtime.UnlockOSThread() ecode := C.git_tag_list_match(&strC, patternC, c.repo.ptr) runtime.KeepAlive(c) if ecode < 0 { return nil, MakeGitError(ecode) } defer C.git_strarray_dispose(&strC) tags := makeStringsFromCStrings(strC.strings, int(strC.count)) return tags, nil } // TagForeachCallback is called for each tag in the repository. // // The name is the full ref name eg: "refs/tags/v1.0.0". // // Note that the callback is called for lightweight tags as well, // so repo.LookupTag() will return an error for these tags. Use // repo.References.Lookup() instead. type TagForeachCallback func(name string, id *Oid) error type tagForeachCallbackData struct { callback TagForeachCallback errorTarget *error } //export tagForeachCallback func tagForeachCallback(name *C.char, id *C.git_oid, handle unsafe.Pointer) C.int { payload := pointerHandles.Get(handle) data, ok := payload.(*tagForeachCallbackData) if !ok { panic("could not retrieve tag foreach CB handle") } err := data.callback(C.GoString(name), newOidFromC(id)) if err != nil { *data.errorTarget = err return C.int(ErrorCodeUser) } return C.int(ErrorCodeOK) } // Foreach calls the callback for each tag in the repository. func (c *TagsCollection) Foreach(callback TagForeachCallback) error { var err error data := tagForeachCallbackData{ callback: callback, errorTarget: &err, } handle := pointerHandles.Track(&data) defer pointerHandles.Untrack(handle) runtime.LockOSThread() defer runtime.UnlockOSThread() ret := C._go_git_tag_foreach(c.repo.ptr, handle) runtime.KeepAlive(c) if ret == C.int(ErrorCodeUser) && err != nil { return err } if ret < 0 { return MakeGitError(ret) } return nil }