package debtik import ( "embed" "fmt" "regexp" "strconv" "strings" ) //go:embed VERSION var files embed.FS var pattern = regexp.MustCompile(`^(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)$`) func Version() string { b, _ := files.ReadFile("VERSION"); return strings.TrimSpace(string(b)) } func ParseVersion(s string) ([3]uint64, error) { var out [3]uint64 if !pattern.MatchString(s) { return out, fmt.Errorf("invalid release version: %s", s) } for i, p := range strings.Split(s, ".") { n, err := strconv.ParseUint(p, 10, 64) if err != nil { return out, err } out[i] = n } return out, nil } func Newer(candidate, current string) (bool, error) { a, err := ParseVersion(candidate) if err != nil { return false, err } b, err := ParseVersion(current) if err != nil { return false, err } for i := range a { if a[i] != b[i] { return a[i] > b[i], nil } } return false, nil } func LatestTag(output string) (string, string, error) { best := "" commit := "" for _, line := range strings.Split(output, "\n") { fields := strings.Fields(line) if len(fields) != 2 { continue } tag := strings.TrimSuffix(fields[1], "^{}") if !strings.HasPrefix(tag, "refs/tags/v") { continue } version := strings.TrimPrefix(tag, "refs/tags/v") if _, err := ParseVersion(version); err != nil { continue } greater := best == "" if best != "" { greater, _ = Newer(version, best) } if greater { best = version commit = fields[0] } else if version == best && strings.HasSuffix(fields[1], "^{}") { commit = fields[0] } } if best == "" { return "", "", fmt.Errorf("repository has no stable vMAJOR.MINOR.PATCH release tags") } return best, commit, nil }