Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions internal/version/version.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@ import (

var logVersion = logger.New("version:version")

// readBuildInfo is a package-level variable wrapping debug.ReadBuildInfo to
// allow test injection without changing the public API.
var readBuildInfo = debug.ReadBuildInfo

const shortHashLength = 7

// vcsCommitFromBuildInfo extracts the vcs.revision setting from build info,
Expand Down Expand Up @@ -88,15 +92,15 @@ func BuildVersionString(mainVersion, gitCommit, buildDate string) string {

if gitCommit != "" {
parts = append(parts, fmt.Sprintf("commit: %s", gitCommit))
} else if buildInfo, ok := debug.ReadBuildInfo(); ok {
} else if buildInfo, ok := readBuildInfo(); ok {
if commit := vcsCommitFromBuildInfo(buildInfo); commit != "" {
parts = append(parts, fmt.Sprintf("commit: %s", commit))
}
}

if buildDate != "" {
parts = append(parts, fmt.Sprintf("built: %s", buildDate))
} else if buildInfo, ok := debug.ReadBuildInfo(); ok {
} else if buildInfo, ok := readBuildInfo(); ok {
if date := vcsTimeFromBuildInfo(buildInfo); date != "" {
parts = append(parts, fmt.Sprintf("built: %s", date))
}
Expand Down
43 changes: 43 additions & 0 deletions internal/version/version_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,49 @@ func makeTestBuildInfo(settings map[string]string) *debug.BuildInfo {
return info
}

func TestBuildVersionString_FallbackFromBuildInfo(t *testing.T) {
origReadBuildInfo := readBuildInfo
t.Cleanup(func() { readBuildInfo = origReadBuildInfo })

mockInfo := makeTestBuildInfo(map[string]string{
"vcs.revision": "abcdef1234567890abcdef12",
"vcs.time": "2024-06-01T12:00:00Z",
})
readBuildInfo = func() (*debug.BuildInfo, bool) {
return mockInfo, true
}

t.Run("uses truncated vcs.revision when gitCommit is empty", func(t *testing.T) {
got := BuildVersionString("v1.0.0", "", "2024-01-01")
assert.Contains(t, got, "commit: abcdef1", "should include truncated commit from build info")
assert.Contains(t, got, "built: 2024-01-01", "should use explicit buildDate")
})

t.Run("uses vcs.time when buildDate is empty", func(t *testing.T) {
got := BuildVersionString("v1.0.0", "explicit", "")
assert.Contains(t, got, "commit: explicit", "should use explicit gitCommit")
assert.Contains(t, got, "built: 2024-06-01T12:00:00Z", "should include vcs.time from build info")
})

t.Run("uses both vcs fields when gitCommit and buildDate are empty", func(t *testing.T) {
got := BuildVersionString("v1.0.0", "", "")
assert.Equal(t, "v1.0.0, commit: abcdef1, built: 2024-06-01T12:00:00Z", got)
})

t.Run("build info unavailable leaves commit and date absent", func(t *testing.T) {
readBuildInfo = func() (*debug.BuildInfo, bool) { return nil, false }
got := BuildVersionString("v1.0.0", "", "")
assert.Equal(t, "v1.0.0", got, "no fallback data when build info is unavailable")
})

t.Run("build info available but no vcs settings", func(t *testing.T) {
emptyInfo := makeTestBuildInfo(map[string]string{})
readBuildInfo = func() (*debug.BuildInfo, bool) { return emptyInfo, true }
got := BuildVersionString("v2.0.0", "", "")
assert.Equal(t, "v2.0.0", got, "no commit or date appended when vcs settings absent")
})
}

func TestVCSCommitFromBuildInfo(t *testing.T) {
tests := []struct {
name string
Expand Down
Loading