feat(build-time-versioning): xcecli --version via Cobra rootCmd.Version

Adds GitCommit/BuildTime vars to xcecli's main.go. Cobra's rootCmd is
declared unexported in router.go (a different file than the task's
original main.go-only boundary), so main.go can't reach it directly --
resolved by extending router.go's sole exported entry point,
Execute(cm, version), to accept the composed version string and set
rootCmd.Version before rootCmd.Execute() runs. Cobra then auto-registers
--version/-v natively once rootCmd.Version is non-empty (confirmed via
reading Cobra v1.9.1 source directly) -- zero additional flag-parsing
code, as designed.

Live-verified via both build paths (meson xce-build.sh and make
build-cli): real commit id (matching git rev-parse --short HEAD plus
dirty suffix) and build time, exit 0.

xcecli's startup log deliberately not extended -- Requirement 3 scopes
that to the four daemons only; xcecli is a one-shot CLI. Corrects a
stale design.md line that had assumed otherwise.

Task 4.5/13 -- closes out the Go binary version display phase (tasks
4.1-4.5).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
Rongsong Shen 2026-08-20 14:07:38 +00:00
parent 17e837b196
commit fb09afe6be
No known key found for this signature in database
GPG key ID: 5BCDAAE0123E9FE2
4 changed files with 27 additions and 10 deletions

View file

@ -36,6 +36,19 @@ import (
"go.uber.org/zap"
)
// GitCommit and BuildTime are injected at link time via
// `-ldflags "-X main.GitCommit=... -X main.BuildTime=..."` (see
// src/tools/go_build and src/frontend/Makefile's build-cli target). The
// "unknown" defaults matter: a bare `go build`/`go run` that bypasses that
// ldflags injection must still report "unknown" rather than an empty
// string, matching this feature's unknown-fallback requirement (see
// xce_version_field() in src/lib/utils.c for the equivalent C-side
// convention).
var (
GitCommit = "unknown"
BuildTime = "unknown"
)
func main() {
// init logger
@ -59,7 +72,8 @@ func main() {
}
// execute the command
if err := cmd.Execute(configManager); err != nil {
version := fmt.Sprintf("%s built %s", GitCommit, BuildTime)
if err := cmd.Execute(configManager, version); err != nil {
fmt.Println(strings.ToLower(err.Error()))
os.Exit(1)
}

View file

@ -26,11 +26,12 @@ var (
)
// execute the root command
func Execute(cm *config.ConfigManager) error {
func Execute(cm *config.ConfigManager, version string) error {
if cm == nil {
return fmt.Errorf("the config manager is not initialized")
}
configManager = cm
rootCmd.Version = version
rootCmd.CompletionOptions.DisableDefaultCmd = true
rootCmd.SilenceErrors = true
rootCmd.SilenceUsage = true