• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

a1y-developer / doc-formatter / 20685185169

04 Jan 2026 12:40AM UTC coverage: 84.097%. First build
20685185169

Pull #30

github

web-flow
Merge 640add189 into 22dfaab32
Pull Request #30: ci: goreleaser

277 of 340 new or added lines in 5 files covered. (81.47%)

1560 of 1855 relevant lines covered (84.1%)

0.92 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

75.17
/pkg/util/gitutil/utils.go
1
package gitutil
2

3
import (
4
        "context"
5
        "errors"
6
        "os/exec"
7
        "strings"
8

9
        "github.com/blang/semver/v4"
10
        "github.com/google/go-github/v50/github"
11
)
12

13
// https://git-scm.com/docs/git-tag
14
// https://github.com/vivin/better-setuptools-git-version/blob/master/better_setuptools_git_version.py
15

16
var (
17
        ErrEmptyGitTag = errors.New("empty tag")
18
        ErrNoTagFound  = errors.New("no tag found")
19
)
20

21
const (
22
        Owner = "a1y-developer"
23
        Repo  = "doc-formatter"
24
)
25

26
func GetLatestTag() (string, error) {
1✔
27
        tag, err := getLatestTagFromLocal()
1✔
28
        if tag == "" || err != nil {
2✔
29
                return getLatestTagFromRemote()
1✔
30
        }
1✔
31
        return tag, nil
1✔
32
}
33

34
// getLatestTagFromRemote the fitting git clone depth is 1
NEW
35
func getLatestTagFromRemote() (string, error) {
×
NEW
36
        tags, err := getTagListFromRemote(Owner, Repo)
×
NEW
37
        if err != nil {
×
NEW
38
                return "", err
×
NEW
39
        }
×
40

NEW
41
        return tags[0], nil
×
42
}
43

44
// get remote url
45
func getRemoteURL() (string, error) {
1✔
46
        stdout, err := exec.Command(
1✔
47
                "git", "config", "--get", "remote.origin.url",
1✔
48
        ).CombinedOutput()
1✔
49
        if err != nil {
2✔
50
                return "", err
1✔
51
        }
1✔
52
        return strings.TrimSpace(string(stdout)), nil
1✔
53
}
54

55
func getLatestTagFromLocal() (tag string, err error) {
1✔
56
        tags, err := getTagListFromLocal()
1✔
57
        if err != nil {
2✔
58
                return "", err
1✔
59
        }
1✔
60
        if len(tags) > 0 {
2✔
61
                tag = tags[len(tags)-1]
1✔
62
        }
1✔
63
        return strings.TrimSpace(tag), nil
1✔
64
}
65

66
func getTagListFromLocal() (tags []string, err error) {
1✔
67
        // git tag --merged
1✔
68
        stdout, err := exec.Command(
1✔
69
                `git`, `describe`, `--abbrev=0`, `--tags`,
1✔
70
        ).CombinedOutput()
1✔
71
        if err != nil {
2✔
72
                return nil, err
1✔
73
        }
1✔
74

NEW
75
        for _, s := range strings.Split(strings.TrimSpace(string(stdout)), "\n") {
×
NEW
76
                if s := strings.TrimSpace(s); s != "" {
×
NEW
77
                        tags = append(tags, s)
×
NEW
78
                }
×
79
        }
NEW
80
        return
×
81
}
82

NEW
83
func getTagListFromRemote(owner, repo string) (tags []string, err error) {
×
NEW
84
        client := github.NewClient(nil)
×
NEW
85
        rts, _, err := client.Repositories.ListTags(context.Background(), owner, repo, nil)
×
NEW
86
        if err != nil {
×
NEW
87
                return nil, err
×
NEW
88
        }
×
NEW
89
        if len(rts) == 0 {
×
NEW
90
                return nil, ErrNoTagFound
×
NEW
91
        }
×
92

NEW
93
        for _, rt := range rts {
×
NEW
94
                v, err := semver.ParseTolerant(rt.GetName())
×
NEW
95
                if err != nil {
×
NEW
96
                        continue
×
97
                }
NEW
98
                if len(v.Pre) > 0 || len(v.Build) > 0 {
×
NEW
99
                        continue
×
100
                }
NEW
101
                tags = append(tags, rt.GetName())
×
102
        }
103

NEW
104
        return tags, nil
×
105
}
106

107
func GetHeadHash() (sha string, err error) {
1✔
108
        // git rev-parse HEAD
1✔
109
        stdout, err := exec.Command(
1✔
110
                `git`, `rev-parse`, `HEAD`,
1✔
111
        ).CombinedOutput()
1✔
112
        if err != nil {
2✔
113
                return "", err
1✔
114
        }
1✔
115

116
        sha = strings.TrimSpace(string(stdout))
1✔
117
        return
1✔
118
}
119

120
func GetHeadHashShort() (sha string, err error) {
1✔
121
        sha, err = GetHeadHash()
1✔
122
        if err != nil {
2✔
123
                return "", err
1✔
124
        }
1✔
125
        if len(sha) > 8 {
2✔
126
                sha = sha[:8]
1✔
127
        }
1✔
128
        return
1✔
129
}
130

131
func IsHeadAtTag(tag string) (bool, error) {
1✔
132
        if tag == "" {
2✔
133
                return false, ErrEmptyGitTag
1✔
134
        }
1✔
135
        sha1, err1 := getTagCommitSha(tag)
1✔
136
        if err1 != nil {
2✔
137
                return false, err1
1✔
138
        }
1✔
139
        sha2, err2 := GetHeadHash()
1✔
140
        if err2 != nil {
2✔
141
                return false, err2
1✔
142
        }
1✔
143
        return sha1 == sha2, nil
1✔
144
}
145

146
func getTagCommitSha(tag string) (sha string, err error) {
1✔
147
        if tag == "" {
2✔
148
                return "", ErrEmptyGitTag
1✔
149
        }
1✔
150

151
        sha, err = getTagCommitShaFromLocal(tag)
1✔
152
        if sha == "" || err != nil {
2✔
153
                return getTagCommitShaFromRemote(tag)
1✔
154
        }
1✔
155
        return
1✔
156
}
157

158
func getTagCommitShaFromLocal(tag string) (sha string, err error) {
1✔
159
        // git rev-list -n 1 {tag}
1✔
160
        stdout, err := exec.Command(
1✔
161
                `git`, `rev-list`, `-n`, `1`, tag,
1✔
162
        ).CombinedOutput()
1✔
163
        if err != nil {
2✔
164
                return "", err
1✔
165
        }
1✔
NEW
166
        var lines []string
×
NEW
167
        for _, s := range strings.Split(strings.TrimSpace(string(stdout)), "\n") {
×
NEW
168
                if s := strings.TrimSpace(s); s != "" {
×
NEW
169
                        lines = append(lines, s)
×
NEW
170
                }
×
171
        }
NEW
172
        if len(lines) > 0 {
×
NEW
173
                sha = lines[len(lines)-1]
×
NEW
174
        }
×
NEW
175
        return strings.TrimSpace(sha), nil
×
176
}
177

178
// get tag commit sha from remote,
179
// the fitting git clone depth is 1
180
func getTagCommitShaFromRemote(_ string) (string, error) {
1✔
181
        // get remote url
1✔
182
        remoteURL, err := getRemoteURL()
1✔
183
        if err != nil {
2✔
184
                return "", err
1✔
185
        }
1✔
186

187
        stdout, err := exec.Command(
1✔
188
                `bash`, `-c`, `git ls-remote --tags --sort=v:refname `+remoteURL+` | tail -n1 | awk '{print $1}'`,
1✔
189
        ).CombinedOutput()
1✔
190
        if err != nil {
2✔
191
                return "", err
1✔
192
        }
1✔
193

194
        return strings.TrimSpace(string(stdout)), nil
1✔
195
}
196

197
func IsDirty() (dirty bool, err error) {
1✔
198
        // git status -s
1✔
199
        stdout, err := exec.Command(
1✔
200
                `git`, `status`, `-s`,
1✔
201
        ).CombinedOutput()
1✔
202
        if err != nil {
2✔
203
                return false, err
1✔
204
        }
1✔
205

206
        dirty = strings.TrimSpace(string(stdout)) != ""
1✔
207
        return
1✔
208
}
209

210
func GetCurrentBranch() (string, error) {
1✔
211
        // git status -s
1✔
212
        stdout, err := exec.Command(
1✔
213
                `git`, `symbolic-ref`, `--short`, `-q`, `HEAD`,
1✔
214
        ).CombinedOutput()
1✔
215
        if err != nil {
2✔
216
                return "", err
1✔
217
        }
1✔
218

219
        return strings.TrimSpace(string(stdout)), nil
1✔
220
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc