Skip to content

Commit 638b015

Browse files
Testclaude
andcommitted
Show git commit info in dev builds for wt version
When built locally without ldflags, wt version now shows the commit hash and dirty state (e.g., "dev (abc1234-dirty)") instead of just "dev". Release builds continue to show the semver tag. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
1 parent 270e9a7 commit 638b015

2 files changed

Lines changed: 140 additions & 10 deletions

File tree

main.go

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"fmt"
66
"io"
77
"os"
8+
"runtime/debug"
89
)
910

1011
// Sentinel errors for testing
@@ -13,6 +14,9 @@ var errShowHelp = errors.New("show help")
1314
// exitFn is the exit function, replaceable for testing
1415
var exitFn = os.Exit
1516

17+
// readBuildInfo is replaceable for testing
18+
var readBuildInfo = debug.ReadBuildInfo
19+
1620
// validCommands lists all valid command names
1721
var validCommands = []string{"create", "remove", "jump", "list", "completion", "version", "__complete"}
1822

@@ -234,9 +238,44 @@ func run(args []string) error {
234238
}
235239
}
236240

241+
// versionString returns the version string, including VCS info for dev builds
242+
func versionString() string {
243+
if Version != "dev" {
244+
return Version
245+
}
246+
247+
// For dev builds, try to get VCS info from Go's build info
248+
info, ok := readBuildInfo()
249+
if !ok {
250+
return Version
251+
}
252+
253+
var revision, dirty string
254+
for _, setting := range info.Settings {
255+
switch setting.Key {
256+
case "vcs.revision":
257+
if len(setting.Value) >= 7 {
258+
revision = setting.Value[:7]
259+
} else {
260+
revision = setting.Value
261+
}
262+
case "vcs.modified":
263+
if setting.Value == "true" {
264+
dirty = "-dirty"
265+
}
266+
}
267+
}
268+
269+
if revision == "" {
270+
return Version
271+
}
272+
273+
return fmt.Sprintf("%s (%s%s)", Version, revision, dirty)
274+
}
275+
237276
// version prints the version information
238277
func version(w io.Writer) error {
239-
fmt.Fprintln(w, Version)
278+
fmt.Fprintln(w, versionString())
240279
return nil
241280
}
242281

main_test.go

Lines changed: 100 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"errors"
66
"os"
77
"path/filepath"
8+
"runtime/debug"
89
"strings"
910
"testing"
1011
)
@@ -647,15 +648,105 @@ func TestRun(t *testing.T) {
647648
}
648649

649650
func TestVersionFunc(t *testing.T) {
650-
var buf bytes.Buffer
651-
err := version(&buf)
652-
if err != nil {
653-
t.Errorf("version() returned error: %v", err)
654-
}
655-
output := buf.String()
656-
if output != Version+"\n" {
657-
t.Errorf("version() = %q, want %q", output, Version+"\n")
658-
}
651+
t.Run("basic output", func(t *testing.T) {
652+
var buf bytes.Buffer
653+
err := version(&buf)
654+
if err != nil {
655+
t.Errorf("version() returned error: %v", err)
656+
}
657+
output := buf.String()
658+
// Output should contain something (either version or dev with commit info)
659+
if output == "" {
660+
t.Error("version() returned empty output")
661+
}
662+
})
663+
}
664+
665+
func TestVersionString(t *testing.T) {
666+
origVersion := Version
667+
origReadBuildInfo := readBuildInfo
668+
defer func() {
669+
Version = origVersion
670+
readBuildInfo = origReadBuildInfo
671+
}()
672+
673+
t.Run("release version", func(t *testing.T) {
674+
Version = "v1.2.3"
675+
result := versionString()
676+
if result != "v1.2.3" {
677+
t.Errorf("versionString() = %q, want %q", result, "v1.2.3")
678+
}
679+
})
680+
681+
t.Run("dev with no build info", func(t *testing.T) {
682+
Version = "dev"
683+
readBuildInfo = func() (*debug.BuildInfo, bool) {
684+
return nil, false
685+
}
686+
result := versionString()
687+
if result != "dev" {
688+
t.Errorf("versionString() = %q, want %q", result, "dev")
689+
}
690+
})
691+
692+
t.Run("dev with build info but no vcs", func(t *testing.T) {
693+
Version = "dev"
694+
readBuildInfo = func() (*debug.BuildInfo, bool) {
695+
return &debug.BuildInfo{}, true
696+
}
697+
result := versionString()
698+
if result != "dev" {
699+
t.Errorf("versionString() = %q, want %q", result, "dev")
700+
}
701+
})
702+
703+
t.Run("dev with vcs revision", func(t *testing.T) {
704+
Version = "dev"
705+
readBuildInfo = func() (*debug.BuildInfo, bool) {
706+
return &debug.BuildInfo{
707+
Settings: []debug.BuildSetting{
708+
{Key: "vcs.revision", Value: "abc1234567890"},
709+
{Key: "vcs.modified", Value: "false"},
710+
},
711+
}, true
712+
}
713+
result := versionString()
714+
if result != "dev (abc1234)" {
715+
t.Errorf("versionString() = %q, want %q", result, "dev (abc1234)")
716+
}
717+
})
718+
719+
t.Run("dev with vcs revision dirty", func(t *testing.T) {
720+
Version = "dev"
721+
readBuildInfo = func() (*debug.BuildInfo, bool) {
722+
return &debug.BuildInfo{
723+
Settings: []debug.BuildSetting{
724+
{Key: "vcs.revision", Value: "abc1234567890"},
725+
{Key: "vcs.modified", Value: "true"},
726+
},
727+
}, true
728+
}
729+
result := versionString()
730+
if result != "dev (abc1234-dirty)" {
731+
t.Errorf("versionString() = %q, want %q", result, "dev (abc1234-dirty)")
732+
}
733+
})
734+
735+
t.Run("dev with short revision", func(t *testing.T) {
736+
Version = "dev"
737+
readBuildInfo = func() (*debug.BuildInfo, bool) {
738+
return &debug.BuildInfo{
739+
Settings: []debug.BuildSetting{
740+
{Key: "vcs.revision", Value: "abc"},
741+
{Key: "vcs.modified", Value: "false"},
742+
},
743+
}, true
744+
}
745+
result := versionString()
746+
if result != "dev (abc)" {
747+
t.Errorf("versionString() = %q, want %q", result, "dev (abc)")
748+
}
749+
})
659750
}
660751

661752
// TestMainFunc tests the main() function by mocking exitFn and os.Args

0 commit comments

Comments
 (0)