mugit/internal/git/tags.go(view raw)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 |
package git
import (
"fmt"
"sort"
"time"
"github.com/go-git/go-git/v5"
"github.com/go-git/go-git/v5/plumbing"
"github.com/go-git/go-git/v5/plumbing/object"
)
type TagList struct {
refs []*TagReference
r *git.Repository
}
// TagReference represents both lightweight and annotated tags.
// Lightweight tags contain only a reference.
// Annotated tags contain both a reference and tag metadata.
type TagReference struct {
ref *plumbing.Reference
tag *object.Tag
}
func (t *TagReference) Name() string {
return t.ref.Name().Short()
}
func (t *TagReference) Message() string {
if t.tag != nil {
return t.tag.Message
}
return ""
}
func (g *Repo) Tags() ([]*TagReference, error) {
iter, err := g.r.Tags()
if err != nil {
return nil, fmt.Errorf("tag objects: %w", err)
}
tags := make([]*TagReference, 0)
if err := iter.ForEach(func(ref *plumbing.Reference) error {
obj, err := g.r.TagObject(ref.Hash())
switch err {
case nil:
tags = append(tags, &TagReference{
ref: ref,
tag: obj,
})
case plumbing.ErrObjectNotFound:
tags = append(tags, &TagReference{
ref: ref,
})
default:
return err
}
return nil
}); err != nil {
return nil, err
}
tagList := &TagList{r: g.r, refs: tags}
sort.Sort(tagList)
return tags, nil
}
func (t *TagList) Len() int {
return len(t.refs)
}
func (t *TagList) Swap(i, j int) {
t.refs[i], t.refs[j] = t.refs[j], t.refs[i]
}
// Less sorting tags in reverse chronological order
func (t *TagList) Less(i, j int) bool {
return t.getDate(i).After(t.getDate(j))
}
func (t *TagList) getDate(i int) time.Time {
if t.refs[i].tag != nil {
return t.refs[i].tag.Tagger.When
}
c, err := t.r.CommitObject(t.refs[i].ref.Hash())
if err != nil {
return time.Now()
}
return c.Committer.When
}
|