mirror of
https://github.com/kubernetes-sigs/kustomize.git
synced 2026-06-12 01:14:22 +00:00
Replace bash release helper scripts with Go progam
This commit is contained in:
98
cmd/gorepomod/internal/semver/semver.go
Normal file
98
cmd/gorepomod/internal/semver/semver.go
Normal file
@@ -0,0 +1,98 @@
|
||||
package semver
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// SemVer is the immutable semantic version per https://semver.org
|
||||
type SemVer struct {
|
||||
major int
|
||||
minor int
|
||||
patch int
|
||||
}
|
||||
|
||||
func New(major, minor, patch int) SemVer {
|
||||
return SemVer{
|
||||
major: major,
|
||||
minor: minor,
|
||||
patch: patch,
|
||||
}
|
||||
}
|
||||
|
||||
var zero = New(0, 0, 0)
|
||||
|
||||
func Zero() SemVer {
|
||||
return zero
|
||||
}
|
||||
|
||||
// Versions implements sort.Interface to get decreasing order.
|
||||
type Versions []SemVer
|
||||
|
||||
func (v Versions) Len() int { return len(v) }
|
||||
func (v Versions) Less(i, j int) bool { return v[j].LessThan(v[i]) }
|
||||
func (v Versions) Swap(i, j int) { v[i], v[j] = v[j], v[i] }
|
||||
|
||||
func Parse(raw string) (SemVer, error) {
|
||||
if len(raw) < 6 {
|
||||
// e.g. minimal length is 6, e.g. "v1.2.3"
|
||||
return zero, fmt.Errorf("%q too short to be a version", raw)
|
||||
}
|
||||
if raw[0] != 'v' {
|
||||
return zero, fmt.Errorf("%q must start with letter 'v'", raw)
|
||||
}
|
||||
fields := strings.Split(raw[1:], ".")
|
||||
if len(fields) < 3 {
|
||||
return zero, fmt.Errorf("%q doesn't have the form v1.2.3", raw)
|
||||
}
|
||||
n := make([]int, 3)
|
||||
for i := 0; i < 3; i++ {
|
||||
var err error
|
||||
n[i], err = strconv.Atoi(fields[i])
|
||||
if err != nil {
|
||||
return zero, err
|
||||
}
|
||||
}
|
||||
return New(n[0], n[1], n[2]), nil
|
||||
}
|
||||
|
||||
func (v SemVer) Bump(b SvBump) SemVer {
|
||||
switch b {
|
||||
case Major:
|
||||
return New(v.major+1, 0, 0)
|
||||
case Minor:
|
||||
return New(v.major, v.minor+1, 0)
|
||||
default:
|
||||
return New(v.major, v.minor, v.patch+1)
|
||||
}
|
||||
}
|
||||
|
||||
func (v SemVer) BranchLabel() string {
|
||||
return fmt.Sprintf("v%d.%d", v.major, v.minor)
|
||||
}
|
||||
|
||||
func (v SemVer) String() string {
|
||||
return fmt.Sprintf("v%d.%d.%d", v.major, v.minor, v.patch)
|
||||
}
|
||||
|
||||
func (v SemVer) Pretty() string {
|
||||
if v.IsZero() {
|
||||
return ""
|
||||
}
|
||||
return v.String()
|
||||
}
|
||||
|
||||
func (v SemVer) Equals(o SemVer) bool {
|
||||
return v.major == o.major && v.minor == o.minor && v.patch == o.patch
|
||||
}
|
||||
|
||||
func (v SemVer) LessThan(o SemVer) bool {
|
||||
return v.major < o.major ||
|
||||
(v.major == o.major && v.minor < o.minor) ||
|
||||
(v.major == o.major && v.minor == o.minor && v.patch < o.patch)
|
||||
}
|
||||
|
||||
func (v SemVer) IsZero() bool {
|
||||
return v.Equals(zero)
|
||||
}
|
||||
105
cmd/gorepomod/internal/semver/semver_test.go
Normal file
105
cmd/gorepomod/internal/semver/semver_test.go
Normal file
@@ -0,0 +1,105 @@
|
||||
package semver
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestParse(t *testing.T) {
|
||||
var testCases = map[string]struct {
|
||||
raw string
|
||||
v SemVer
|
||||
errMsg string
|
||||
}{
|
||||
"one": {
|
||||
raw: "v1.2.3",
|
||||
v: SemVer{major: 1, minor: 2, patch: 3},
|
||||
errMsg: "",
|
||||
},
|
||||
"two": {
|
||||
raw: "v2.0.9999",
|
||||
v: SemVer{major: 2, minor: 0, patch: 9999},
|
||||
errMsg: "",
|
||||
},
|
||||
"three": {
|
||||
raw: "pizza",
|
||||
v: zero,
|
||||
errMsg: "\"pizza\" too short to be a version",
|
||||
},
|
||||
"non-digit": {
|
||||
raw: "v1.x.222",
|
||||
v: zero,
|
||||
errMsg: "strconv.Atoi: parsing \"x\": invalid syntax",
|
||||
},
|
||||
"bad fields": {
|
||||
raw: "v1.222",
|
||||
v: zero,
|
||||
errMsg: "\"v1.222\" doesn't have the form v1.2.3",
|
||||
},
|
||||
}
|
||||
for n, tc := range testCases {
|
||||
v, err := Parse(tc.raw)
|
||||
if err == nil {
|
||||
if tc.errMsg != "" {
|
||||
t.Errorf(
|
||||
"%s: no error, but expected err %q", n, tc.errMsg)
|
||||
}
|
||||
if !v.Equals(tc.v) {
|
||||
t.Errorf(
|
||||
"%s: expected %v, got %v", n, tc.v, v)
|
||||
}
|
||||
} else {
|
||||
if tc.errMsg == "" {
|
||||
t.Errorf(
|
||||
"%s: unexpected error %v", n, err)
|
||||
} else {
|
||||
if tc.errMsg != err.Error() {
|
||||
t.Errorf(
|
||||
"%s: expected err msg %q, but got %q",
|
||||
n, tc.errMsg, err.Error())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestLessThan(t *testing.T) {
|
||||
var testCases = map[string]struct {
|
||||
v1 SemVer
|
||||
v2 SemVer
|
||||
expected bool
|
||||
}{
|
||||
"one": {
|
||||
v1: SemVer{major: 2, minor: 2, patch: 3},
|
||||
v2: SemVer{major: 1, minor: 2, patch: 3},
|
||||
expected: false,
|
||||
},
|
||||
"two": {
|
||||
v1: SemVer{major: 1, minor: 3, patch: 3},
|
||||
v2: SemVer{major: 1, minor: 2, patch: 3},
|
||||
expected: false,
|
||||
},
|
||||
"three": {
|
||||
v1: SemVer{major: 1, minor: 2, patch: 4},
|
||||
v2: SemVer{major: 1, minor: 2, patch: 3},
|
||||
expected: false,
|
||||
},
|
||||
"eq": {
|
||||
v1: SemVer{major: 2, minor: 2, patch: 3},
|
||||
v2: SemVer{major: 2, minor: 2, patch: 3},
|
||||
expected: false,
|
||||
},
|
||||
"four": {
|
||||
v1: zero,
|
||||
v2: SemVer{major: 0, minor: 0, patch: 1},
|
||||
expected: true,
|
||||
},
|
||||
}
|
||||
for n, tc := range testCases {
|
||||
actual := tc.v1.LessThan(tc.v2)
|
||||
if actual != tc.expected {
|
||||
t.Errorf(
|
||||
"%s: expected %v, got %v for %s LessThan %s",
|
||||
n, tc.expected, actual, tc.v1.String(), tc.v2.String())
|
||||
}
|
||||
}
|
||||
}
|
||||
17
cmd/gorepomod/internal/semver/svbump.go
Normal file
17
cmd/gorepomod/internal/semver/svbump.go
Normal file
@@ -0,0 +1,17 @@
|
||||
package semver
|
||||
|
||||
type SvBump int
|
||||
|
||||
const (
|
||||
Patch SvBump = iota
|
||||
Minor
|
||||
Major
|
||||
)
|
||||
|
||||
func (b SvBump) String() string {
|
||||
return map[SvBump]string{
|
||||
Patch: "Patch",
|
||||
Minor: "Minor",
|
||||
Major: "Major",
|
||||
}[b]
|
||||
}
|
||||
Reference in New Issue
Block a user