all repos

mugit @ b6e1830

🐮 git server that your cow will love

mugit/internal/git/tags.go (view raw)

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