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
33 changes: 33 additions & 0 deletions internal/cli/version.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package cli

import (
"fmt"
"runtime/debug"

"github.com/devrimcavusoglu/skern/internal/output"
"github.com/spf13/cobra"
Expand All @@ -14,6 +15,38 @@ var (
Date = "unknown"
)

func init() {
initVersionFromBuildInfo(debug.ReadBuildInfo)
}

// initVersionFromBuildInfo populates Version, Commit, and Date from Go build
// info when ldflags have not been set. The reader parameter allows tests to
// inject a fake ReadBuildInfo.
func initVersionFromBuildInfo(reader func() (*debug.BuildInfo, bool)) {
if Version != "dev" {
return // ldflags already set
}
info, ok := reader()
if !ok {
return
}
if info.Main.Version != "" && info.Main.Version != "(devel)" {
Version = info.Main.Version
}
for _, s := range info.Settings {
switch s.Key {
case "vcs.revision":
if s.Value != "" {
Commit = s.Value
}
case "vcs.time":
if s.Value != "" {
Date = s.Value
}
}
}
}

func newVersionCmd() *cobra.Command {
return &cobra.Command{
Use: "version",
Expand Down
110 changes: 110 additions & 0 deletions internal/cli/version_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package cli

import (
"bytes"
"runtime/debug"
"testing"

"github.com/stretchr/testify/assert"
Expand Down Expand Up @@ -36,6 +37,115 @@ func TestVersionCommand_JSON(t *testing.T) {
require.NoError(t, err)
}

func TestInitVersionFromBuildInfo(t *testing.T) {
tests := []struct {
name string
initialVersion string
buildInfo *debug.BuildInfo
buildInfoOk bool
expectedVersion string
expectedCommit string
expectedDate string
}{
{
name: "ldflags already set",
initialVersion: "v1.0.0",
buildInfo: &debug.BuildInfo{Main: debug.Module{Version: "v2.0.0"}},
buildInfoOk: true,
expectedVersion: "v1.0.0",
expectedCommit: "none",
expectedDate: "unknown",
},
{
name: "build info unavailable",
initialVersion: "dev",
buildInfo: nil,
buildInfoOk: false,
expectedVersion: "dev",
expectedCommit: "none",
expectedDate: "unknown",
},
{
name: "go install with version and vcs info",
initialVersion: "dev",
buildInfo: &debug.BuildInfo{
Main: debug.Module{Version: "v0.1.1"},
Settings: []debug.BuildSetting{
{Key: "vcs.revision", Value: "abc123def456"},
{Key: "vcs.time", Value: "2026-01-15T10:30:00Z"},
},
},
buildInfoOk: true,
expectedVersion: "v0.1.1",
expectedCommit: "abc123def456",
expectedDate: "2026-01-15T10:30:00Z",
},
{
name: "devel version is ignored",
initialVersion: "dev",
buildInfo: &debug.BuildInfo{
Main: debug.Module{Version: "(devel)"},
Settings: []debug.BuildSetting{
{Key: "vcs.revision", Value: "abc123"},
},
},
buildInfoOk: true,
expectedVersion: "dev",
expectedCommit: "abc123",
expectedDate: "unknown",
},
{
name: "version set but no vcs info",
initialVersion: "dev",
buildInfo: &debug.BuildInfo{
Main: debug.Module{Version: "v0.2.0"},
},
buildInfoOk: true,
expectedVersion: "v0.2.0",
expectedCommit: "none",
expectedDate: "unknown",
},
{
name: "empty vcs values are ignored",
initialVersion: "dev",
buildInfo: &debug.BuildInfo{
Main: debug.Module{Version: "v0.3.0"},
Settings: []debug.BuildSetting{
{Key: "vcs.revision", Value: ""},
{Key: "vcs.time", Value: ""},
},
},
buildInfoOk: true,
expectedVersion: "v0.3.0",
expectedCommit: "none",
expectedDate: "unknown",
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
// Save and restore globals
origVersion, origCommit, origDate := Version, Commit, Date
t.Cleanup(func() {
Version, Commit, Date = origVersion, origCommit, origDate
})

Version = tt.initialVersion
Commit = "none"
Date = "unknown"

reader := func() (*debug.BuildInfo, bool) {
return tt.buildInfo, tt.buildInfoOk
}
initVersionFromBuildInfo(reader)

assert.Equal(t, tt.expectedVersion, Version)
assert.Equal(t, tt.expectedCommit, Commit)
assert.Equal(t, tt.expectedDate, Date)
})
}
}

func TestRootCommand_Help(t *testing.T) {
cmd := NewRootCmd()
buf := new(bytes.Buffer)
Expand Down
Loading