From ac9eb28e032c59a16d662c31747d43a515b17394 Mon Sep 17 00:00:00 2001 From: kanywst Date: Mon, 13 Jul 2026 23:54:11 +0900 Subject: [PATCH 1/4] fix(cmd): register the --version flag Execute called SetVersionTemplate but never set RootCmd.Version, and cobra only registers the --version flag when Version is non-empty. So the template was dead code and both --version and -v failed: $ y509 --version Error: unknown flag: --version The man page, both shell completions, and scripts/brew-test.sh all advertise --version, so this was the documented interface and it did not exist. Only the version subcommand worked. --- internal/cmd/root.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/internal/cmd/root.go b/internal/cmd/root.go index c73f59a..5fc3dc5 100644 --- a/internal/cmd/root.go +++ b/internal/cmd/root.go @@ -49,6 +49,10 @@ var ( // Execute adds all child commands to the root command and sets flags appropriately. // This is called by main.main(). It only needs to happen once to the rootCmd. func Execute() { + // Cobra only registers the --version flag when Version is non-empty. + // Setting the template alone left --version and -v undefined, even though + // the man page and the shell completions both advertised them. + RootCmd.Version = version.GetVersion() RootCmd.SetVersionTemplate("y509 version {{.Version}}\nBuild: " + version.GetFullVersion() + "\n") if err := RootCmd.Execute(); err != nil { From 92110c4b2dafc76bd6d307e5c24a4d821879a694 Mon Sep 17 00:00:00 2001 From: kanywst Date: Mon, 13 Jul 2026 23:54:11 +0900 Subject: [PATCH 2/4] fix(version): report the real version on a go install build The version variables are populated by -ldflags at release time, but a `go install` build gets no ldflags and reported itself as "dev" forever. The toolchain has already stamped the module version and the VCS revision into the binary, so read them back out of debug.ReadBuildInfo when ldflags did not set anything. before: y509 version dev after: y509 version v0.12.1-0.20260706091141-6f91c879576a Build: ... (6f91c87) built on 2026-07-06T09:11:41Z An -ldflags build still wins: the fallback only runs while Version is still "dev". --- internal/version/version.go | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/internal/version/version.go b/internal/version/version.go index 1932dab..142b998 100644 --- a/internal/version/version.go +++ b/internal/version/version.go @@ -2,6 +2,7 @@ package version import ( + "runtime/debug" "strings" ) @@ -14,6 +15,35 @@ var ( BuildDate = "unknown" ) +// Release builds get these values from -ldflags. A `go install` build gets no +// ldflags at all, so it reported itself as "dev" forever -- even though the +// toolchain had already stamped the module version and the VCS revision into +// the binary. Read them back out. +func init() { + if Version != "dev" { + // -ldflags won; leave everything alone. + return + } + + info, ok := debug.ReadBuildInfo() + if !ok { + return + } + + // "(devel)" is what a build from a local working tree reports. + if info.Main.Version != "" && info.Main.Version != "(devel)" { + Version = info.Main.Version + } + for _, setting := range info.Settings { + switch setting.Key { + case "vcs.revision": + GitCommit = setting.Value + case "vcs.time": + BuildDate = setting.Value + } + } +} + // GetVersion returns the version string func GetVersion() string { return Version From 3fd855be98995633f208ea0b6d60fb4c45f25524 Mon Sep 17 00:00:00 2001 From: kanywst Date: Tue, 14 Jul 2026 23:34:56 +0900 Subject: [PATCH 3/4] fix(version): fall back on each build value independently Returning early when Version was already set meant a build that supplied only Version through -ldflags would skip the VCS revision and build time the toolchain had recorded, and report "unknown" for both. Let each value fall back on its own. --- internal/version/version.go | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/internal/version/version.go b/internal/version/version.go index 142b998..f63dba9 100644 --- a/internal/version/version.go +++ b/internal/version/version.go @@ -20,26 +20,30 @@ var ( // toolchain had already stamped the module version and the VCS revision into // the binary. Read them back out. func init() { - if Version != "dev" { - // -ldflags won; leave everything alone. - return - } - info, ok := debug.ReadBuildInfo() if !ok { return } - // "(devel)" is what a build from a local working tree reports. - if info.Main.Version != "" && info.Main.Version != "(devel)" { - Version = info.Main.Version + // Each value falls back on its own. A build that sets only Version through + // -ldflags should still pick up the commit and the build time the toolchain + // recorded, rather than being left reporting "unknown" for both. + if Version == "dev" { + // "(devel)" is what a build from a local working tree reports. + if info.Main.Version != "" && info.Main.Version != "(devel)" { + Version = info.Main.Version + } } for _, setting := range info.Settings { switch setting.Key { case "vcs.revision": - GitCommit = setting.Value + if GitCommit == "unknown" { + GitCommit = setting.Value + } case "vcs.time": - BuildDate = setting.Value + if BuildDate == "unknown" { + BuildDate = setting.Value + } } } } From cf1ac28a0b085abf8765a72642d311cef2ba42f3 Mon Sep 17 00:00:00 2001 From: kanywst Date: Wed, 15 Jul 2026 23:49:49 +0900 Subject: [PATCH 4/4] fix(version): do not let an empty VCS value overwrite "unknown" If the build info carried a vcs.revision or vcs.time setting with an empty value, it replaced the "unknown" default with "", which renders as "y509 version dev ()". Only take a non-empty value. --- internal/version/version.go | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/internal/version/version.go b/internal/version/version.go index f63dba9..4068e2e 100644 --- a/internal/version/version.go +++ b/internal/version/version.go @@ -37,11 +37,13 @@ func init() { for _, setting := range info.Settings { switch setting.Key { case "vcs.revision": - if GitCommit == "unknown" { + // An empty value must not overwrite "unknown" -- it would render as + // "y509 version dev ()". + if GitCommit == "unknown" && setting.Value != "" { GitCommit = setting.Value } case "vcs.time": - if BuildDate == "unknown" { + if BuildDate == "unknown" && setting.Value != "" { BuildDate = setting.Value } }