diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..bdaf4b8 --- /dev/null +++ b/go.mod @@ -0,0 +1,5 @@ +module github.com/haya14busa/xtag + +go 1.12 + +require github.com/haya14busa/go-versionsort v0.0.0-20190326014014-5b3a40d6070a diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..d01780d --- /dev/null +++ b/go.sum @@ -0,0 +1,2 @@ +github.com/haya14busa/go-versionsort v0.0.0-20190326014014-5b3a40d6070a h1:C75TMjl9nVoJt0B2KcbO6qESAF3lG4vVYgDXoxotWrg= +github.com/haya14busa/go-versionsort v0.0.0-20190326014014-5b3a40d6070a/go.mod h1:LUfyxWIo5I3AzeZxF5+/wAUM5sz5ZibEh/Ck3dZrN50= diff --git a/xtag.go b/xtag.go new file mode 100644 index 0000000..1f9ddc2 --- /dev/null +++ b/xtag.go @@ -0,0 +1,35 @@ +package xtag + +import ( + "fmt" + "regexp" + "strings" + + "github.com/haya14busa/go-versionsort" +) + +// FindLatest finds latest tag matched with give xtag (e.g. v1.2.x). +func FindLatest(xtag string, tags []string) (string, error) { + if !strings.HasSuffix(xtag, "x") { + return "", fmt.Errorf("xtag must ends with 'x': %q", xtag) + } + target := "x" + if strings.HasSuffix(xtag, ".x") { + target = `\.x` + } + pattern := strings.Replace(regexp.QuoteMeta(xtag), target, `[0-9.]*`, -1) + re, err := regexp.Compile(pattern) + if err != nil { + return "", err + } + latest := "" + for _, tag := range tags { + if re.MatchString(tag) && versionsort.Less(latest, tag) { + latest = tag + } + } + if latest != "" { + return latest, nil + } + return "", fmt.Errorf("latest tag not found: %q", xtag) +} diff --git a/xtag_test.go b/xtag_test.go new file mode 100644 index 0000000..83bb3da --- /dev/null +++ b/xtag_test.go @@ -0,0 +1,28 @@ +package xtag + +import "testing" + +func TestFindLatest(t *testing.T) { + tests := []struct { + xtag string + tags []string + want string + }{ + {"v1.x", []string{"v1.0", "v1.5", "v1.4", "v2.0"}, "v1.5"}, + {"1.x", []string{"1.0", "1.5", "1.4", "2.0"}, "1.5"}, + {"v2.x", []string{"v1.0", "v2.0.0", "v3.0"}, "v2.0.0"}, + {"v1.2.x", []string{"v1.0", "v2.0.0", "v1.2.1", "v1.2.3"}, "v1.2.3"}, + {"vx", []string{"v1.0", "v2.0.0", "v1.2.1"}, "v2.0.0"}, + {"x", []string{"1.0", "2.0.0", "1.2.1"}, "2.0.0"}, + } + for _, tt := range tests { + got, err := FindLatest(tt.xtag, tt.tags) + if err != nil { + t.Errorf("%s: got error: %v", tt.xtag, err) + continue + } + if got != tt.want { + t.Errorf("FindLatest(%q, %s) = %q, want %q", tt.xtag, tt.tags, got, tt.want) + } + } +}