Report the module version for a go install build (closes #18)
check / check (push) Successful in 1m41s

keyfunc --version printed dev for any binary not built with make build. When no version was stamped at build time, the tool now reports the module version recorded in the binary's build info, which go install fills in. A stamped version still wins, and a local build with neither still prints dev.

Model: opus-4-8 (implementation); fable-5-1 (summary)
This commit was merged in pull request #26.
This commit is contained in:
2026-09-21 09:39:38 +02:00
parent 860e590114
commit e6ddf49acc
3 changed files with 66 additions and 4 deletions
+2 -1
View File
@@ -55,7 +55,8 @@ refuses and exits with status 1. A mnemonic that fails the BIP-39 checksum is
refused with a message saying so. refused with a message saying so.
Every command takes `--index` / `-n` and `--mnemonic-command`, and has `--help`. Every command takes `--index` / `-n` and `--mnemonic-command`, and has `--help`.
`keyfunc --version` prints the version set at build time. `keyfunc --version` prints the version. `make build` stamps it; a binary
installed with `go install` reports the module version instead.
## SSH keys: `keyfunc ssh` ## SSH keys: `keyfunc ssh`
+27 -3
View File
@@ -5,6 +5,7 @@ import (
"errors" "errors"
"fmt" "fmt"
"os" "os"
"runtime/debug"
"git.eeqj.de/sneak/keyfunc/internal/cli/age" "git.eeqj.de/sneak/keyfunc/internal/cli/age"
"git.eeqj.de/sneak/keyfunc/internal/cli/mnemonic" "git.eeqj.de/sneak/keyfunc/internal/cli/mnemonic"
@@ -13,20 +14,43 @@ import (
"github.com/spf13/cobra" "github.com/spf13/cobra"
) )
// Version is what --version prints. The build sets it. // devVersion is what Version holds until a build stamps a real one.
const devVersion = "dev"
// Version is what --version prints. make build stamps it with -ldflags.
// //
//nolint:gochecknoglobals // set at build time with -ldflags //nolint:gochecknoglobals // set at build time with -ldflags
var Version = "dev" var Version = devVersion
// resolveVersion chooses what --version reports. A value stamped at
// build time wins. Otherwise, for a binary from go install, the module
// version recorded in the build info is used, unless that is empty or
// the "(devel)" of a local build. When neither names a version, the
// "dev" fallback stays.
func resolveVersion(stamped string, info *debug.BuildInfo) string {
if stamped != devVersion {
return stamped
}
if info != nil && info.Main.Version != "" &&
info.Main.Version != "(devel)" {
return info.Main.Version
}
return devVersion
}
// Root returns the whole command tree. // Root returns the whole command tree.
func Root() *cobra.Command { func Root() *cobra.Command {
info, _ := debug.ReadBuildInfo()
root := &cobra.Command{ root := &cobra.Command{
Use: "keyfunc", Use: "keyfunc",
Short: "derive key pairs from a BIP-39 mnemonic", Short: "derive key pairs from a BIP-39 mnemonic",
Long: "keyfunc turns a BIP-39 mnemonic into key pairs that can " + Long: "keyfunc turns a BIP-39 mnemonic into key pairs that can " +
"be recreated from that mnemonic at any time. The same " + "be recreated from that mnemonic at any time. The same " +
"mnemonic, key type and index always give the same key.", "mnemonic, key type and index always give the same key.",
Version: Version, Version: resolveVersion(Version, info),
SilenceUsage: true, SilenceUsage: true,
SilenceErrors: true, SilenceErrors: true,
} }
+37
View File
@@ -0,0 +1,37 @@
package cli
import (
"runtime/debug"
"testing"
"github.com/stretchr/testify/require"
)
func TestResolveVersion(t *testing.T) {
t.Parallel()
release := &debug.BuildInfo{Main: debug.Module{Version: "v1.2.3"}}
local := &debug.BuildInfo{Main: debug.Module{Version: "(devel)"}}
empty := &debug.BuildInfo{}
t.Run("stamped value wins over build info", func(t *testing.T) {
t.Parallel()
require.Equal(t, "v0.1.0", resolveVersion("v0.1.0", release))
})
t.Run("go install reports the module version", func(t *testing.T) {
t.Parallel()
require.Equal(t, "v1.2.3", resolveVersion(devVersion, release))
})
t.Run("a local build stays dev", func(t *testing.T) {
t.Parallel()
require.Equal(t, devVersion, resolveVersion(devVersion, local))
})
t.Run("no version anywhere stays dev", func(t *testing.T) {
t.Parallel()
require.Equal(t, devVersion, resolveVersion(devVersion, empty))
require.Equal(t, devVersion, resolveVersion(devVersion, nil))
})
}