diff --git a/Makefile b/Makefile index c57792927f..f0c07a0f2e 100644 --- a/Makefile +++ b/Makefile @@ -75,7 +75,9 @@ $(MYGOBIN)/pluginator: # Build from local source. $(MYGOBIN)/kustomize: build-kustomize-api cd kustomize; \ - go install -ldflags "-X sigs.k8s.io/kustomize/api/provenance.buildDate=$(shell date -u +'%Y-%m-%dT%H:%M:%SZ')" \ + go install -ldflags \ + "-X sigs.k8s.io/kustomize/api/provenance.buildDate=$(shell date -u +'%Y-%m-%dT%H:%M:%SZ') \ + -X sigs.k8s.io/kustomize/api/provenance.version=$(shell git describe --tags --always --dirty)" \ . kustomize: $(MYGOBIN)/kustomize diff --git a/api/go.mod b/api/go.mod index af736f04a8..69eae826c5 100644 --- a/api/go.mod +++ b/api/go.mod @@ -15,6 +15,7 @@ require ( ) require ( + github.com/blang/semver/v4 v4.0.0 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/go-openapi/jsonpointer v0.19.6 // indirect github.com/go-openapi/jsonreference v0.20.2 // indirect diff --git a/api/go.sum b/api/go.sum index c2d652f6d9..90914ec755 100644 --- a/api/go.sum +++ b/api/go.sum @@ -1,3 +1,5 @@ +github.com/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM= +github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= diff --git a/api/provenance/provenance.go b/api/provenance/provenance.go index 0e24fc36ca..0b7acd9b8c 100644 --- a/api/provenance/provenance.go +++ b/api/provenance/provenance.go @@ -8,6 +8,8 @@ import ( "runtime" "runtime/debug" "strings" + + "github.com/blang/semver/v4" ) // These variables are set at build time using ldflags. @@ -62,9 +64,34 @@ func GetProvenance() Provenance { p.GitCommit = setting.Value } } + + for _, dep := range info.Deps { + if dep != nil && dep.Path == "sigs.k8s.io/kustomize/kustomize/v5" { + p.Version = GetMostRecentTag(*dep) + } + } + return p } +func GetMostRecentTag(m debug.Module) string { + for m.Replace != nil { + m = *m.Replace + } + + split := strings.Split(m.Version, "-") + sv, err := semver.Parse(strings.TrimPrefix(split[0], "v")) + + if err != nil { + return "unknown" + } + + if len(split) > 1 && sv.Patch > 0 { + sv.Patch -= 1 + } + return fmt.Sprintf("v%s", sv.FinalizeVersion()) +} + // Short returns the shortened provenance stamp. func (v Provenance) Short() string { return fmt.Sprintf( diff --git a/api/provenance/provenance_test.go b/api/provenance/provenance_test.go index 9aede8d643..d418ef0080 100644 --- a/api/provenance/provenance_test.go +++ b/api/provenance/provenance_test.go @@ -5,6 +5,7 @@ package provenance_test import ( "fmt" + "runtime/debug" "testing" "github.com/stretchr/testify/assert" @@ -45,3 +46,52 @@ func TestProvenance_Semver(t *testing.T) { p.Version = "kustomize/v4.11.12" assert.Equal(t, "v4.11.12", p.Semver()) } + +func mockModule(version string) debug.Module { + return debug.Module{ + Path: "sigs.k8s.io/kustomize/kustomize/v5", + Version: version, + Replace: nil, + } +} + +func TestGetMostRecentTag(t *testing.T) { + tests := []struct { + name string + module debug.Module + expectedTag string + }{ + { + name: "Standard version", + module: mockModule("v1.2.3"), + expectedTag: "v1.2.3", + }, + { + name: "Pseudo-version with patch increment", + module: mockModule("v0.0.0-20210101010101-abcdefabcdef"), + expectedTag: "v0.0.0", + }, + { + name: "Invalid semver string", + module: mockModule("invalid-version"), + expectedTag: "unknown", + }, + { + name: "Valid semver with patch increment and pre-release info", + module: mockModule("v1.2.3-0.20210101010101-abcdefabcdef"), + expectedTag: "v1.2.2", + }, + { + name: "Valid semver no patch increment", + module: mockModule("v1.2.0"), + expectedTag: "v1.2.0", + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + tag := provenance.GetMostRecentTag(tt.module) + assert.Equal(t, tt.expectedTag, tag) + }) + } +}