|
8 | 8 | "os" |
9 | 9 | "os/exec" |
10 | 10 | "path/filepath" |
11 | | - "regexp" |
12 | 11 | "runtime" |
13 | 12 | "sort" |
14 | 13 | "strconv" |
@@ -160,69 +159,20 @@ func (dg DefaultGitter) CheckGitRepo(dir string) (repo string, err error) { |
160 | 159 | return |
161 | 160 | } |
162 | 161 |
|
163 | | -// Intentionally accepts partial numeric tags (v1, v1.2, v1.2.3), |
164 | | -// with or without a leading "v". |
165 | | -var reMatchSemver = regexp.MustCompile(`^v?[0-9]+(?:\.[0-9]+)?(?:\.[0-9]+)?$`) |
166 | | - |
167 | | -func normalizeNumericString(s string) string { |
168 | | - s = strings.TrimLeft(s, "0") |
169 | | - if s == "" { |
170 | | - return "0" |
171 | | - } |
172 | | - return s |
173 | | -} |
174 | | - |
175 | | -func compareNumericStrings(a, b string) int { |
176 | | - a = normalizeNumericString(a) |
177 | | - b = normalizeNumericString(b) |
178 | | - if len(a) != len(b) { |
179 | | - if len(a) > len(b) { |
180 | | - return 1 |
181 | | - } |
182 | | - return -1 |
183 | | - } |
184 | | - if a == b { |
185 | | - return 0 |
186 | | - } |
187 | | - if a > b { |
188 | | - return 1 |
189 | | - } |
190 | | - return -1 |
191 | | -} |
192 | | - |
193 | | -func semverPart(tag string, index int) string { |
194 | | - core := strings.TrimPrefix(tag, "v") |
195 | | - parts := strings.Split(core, ".") |
196 | | - if index >= 0 && index < len(parts) { |
197 | | - return parts[index] |
198 | | - } |
199 | | - return "0" |
200 | | -} |
201 | | - |
202 | | -func semverGreater(leftTag, rightTag string) bool { |
203 | | - for idx := 0; idx < 3; idx++ { |
204 | | - cmp := compareNumericStrings(semverPart(leftTag, idx), semverPart(rightTag, idx)) |
205 | | - if cmp != 0 { |
206 | | - return cmp > 0 |
207 | | - } |
208 | | - } |
209 | | - return false |
210 | | -} |
211 | | - |
212 | 162 | // GetTags returns all tags, sorted by version descending. |
213 | 163 | // The latest tag is the first in the list. |
214 | 164 | func (dg DefaultGitter) GetTags(repo string) (tags []string, err error) { |
215 | 165 | var b []byte |
216 | 166 | if b, err = dg.Exec("-C", repo, "tag", "--sort=-v:refname", "--list", "v[0-9]*", "[0-9]*"); len(b) > 0 /* #nosec G204 */ { |
217 | 167 | for _, tag := range strings.Split(string(b), "\n") { |
218 | | - if tag = strings.TrimSpace(tag); tag != "" && reMatchSemver.MatchString(tag) { |
| 168 | + if tag = strings.TrimSpace(tag); tag != "" && isSemverTag(tag) { |
219 | 169 | tags = append(tags, tag) |
220 | 170 | } |
221 | 171 | } |
222 | 172 | // Git's multi-pattern listing can interleave v-prefixed and non-prefixed |
223 | 173 | // tags in a way that is not globally version-sorted. Normalize here. |
224 | 174 | sort.SliceStable(tags, func(i, j int) bool { |
225 | | - return semverGreater(tags[i], tags[j]) |
| 175 | + return semverTagGreater(tags[i], tags[j]) |
226 | 176 | }) |
227 | 177 | } |
228 | 178 | return |
@@ -310,7 +260,7 @@ func (dg DefaultGitter) GetClosestTag(repo, commit string) (tag string, err erro |
310 | 260 | var b []byte |
311 | 261 | if b, err = dg.Exec(args...); err == nil { |
312 | 262 | candidate := strings.TrimSpace(string(b)) |
313 | | - if candidate == "" || reMatchSemver.MatchString(candidate) { |
| 263 | + if candidate == "" || isSemverTag(candidate) { |
314 | 264 | tag = candidate |
315 | 265 | return |
316 | 266 | } |
|
0 commit comments