version.go 1.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. package debtik
  2. import (
  3. "embed"
  4. "fmt"
  5. "regexp"
  6. "strconv"
  7. "strings"
  8. )
  9. //go:embed VERSION
  10. var files embed.FS
  11. var pattern = regexp.MustCompile(`^(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)$`)
  12. func Version() string { b, _ := files.ReadFile("VERSION"); return strings.TrimSpace(string(b)) }
  13. func ParseVersion(s string) ([3]uint64, error) {
  14. var out [3]uint64
  15. if !pattern.MatchString(s) {
  16. return out, fmt.Errorf("invalid release version: %s", s)
  17. }
  18. for i, p := range strings.Split(s, ".") {
  19. n, err := strconv.ParseUint(p, 10, 64)
  20. if err != nil {
  21. return out, err
  22. }
  23. out[i] = n
  24. }
  25. return out, nil
  26. }
  27. func Newer(candidate, current string) (bool, error) {
  28. a, err := ParseVersion(candidate)
  29. if err != nil {
  30. return false, err
  31. }
  32. b, err := ParseVersion(current)
  33. if err != nil {
  34. return false, err
  35. }
  36. for i := range a {
  37. if a[i] != b[i] {
  38. return a[i] > b[i], nil
  39. }
  40. }
  41. return false, nil
  42. }
  43. func LatestTag(output string) (string, string, error) {
  44. best := ""
  45. commit := ""
  46. for _, line := range strings.Split(output, "\n") {
  47. fields := strings.Fields(line)
  48. if len(fields) != 2 {
  49. continue
  50. }
  51. tag := strings.TrimSuffix(fields[1], "^{}")
  52. if !strings.HasPrefix(tag, "refs/tags/v") {
  53. continue
  54. }
  55. version := strings.TrimPrefix(tag, "refs/tags/v")
  56. if _, err := ParseVersion(version); err != nil {
  57. continue
  58. }
  59. greater := best == ""
  60. if best != "" {
  61. greater, _ = Newer(version, best)
  62. }
  63. if greater {
  64. best = version
  65. commit = fields[0]
  66. } else if version == best && strings.HasSuffix(fields[1], "^{}") {
  67. commit = fields[0]
  68. }
  69. }
  70. if best == "" {
  71. return "", "", fmt.Errorf("repository has no stable vMAJOR.MINOR.PATCH release tags")
  72. }
  73. return best, commit, nil
  74. }