Artifact 61cae01647670d52c69e9735d4ba7e44eb5d0d699809c14f1508a363be00b65f:
- File
cmd/libfossil/main.go
— part of check-in
[725c694cb9]
at
2026-07-19 23:33:37
on branch trunk
— Add libfossil version command (#99)
* Add libfossil version command
Sources the version string from runtime/debug.ReadBuildInfo (module version for go-install/tagged builds, falling back to a short VCS commit), with a -ldflags override for release builds where BuildInfo alone would collapse to "(devel)". Output is a fixed, single-line, four-field shape ("libfossil <version> <go version> <os>/<arch>") so a caller can rely on strings.Fields(Version()) unconditionally -- the motivating consumer stamps this into every emitted benchmark record.
No global --version flag: repo extract already owns --version as a command-scoped flag (source version to extract), and kong's global flags are visible in every subcommand's context, so a root-level --version would collide with it. version is a subcommand only.
Verified kong's existing parse-error path already exits non-zero (exitUsageError, 80) for unrecognized commands and flags against the pinned kong version -- added regression tests locking that in rather than changing behavior that was already correct.
* Reject malformed -ldflags version overrides at startup
buildVersion was used verbatim with no validation, so a whitespace- or newline-containing -X override silently broke Version()'s promised single-line, four-field contract: a space produced six fields instead of four, and a newline broke the single-line guarantee outright. The stated consumer is a benchmark harness parsing this line as a stable record, so a corrupted version field silently corrupts every record from that build in exactly the field meant to identify it.
A bad -X value is a build-time operator mistake, not a runtime condition, so it's rejected at package init rather than sanitized or worked around: sanitizing would silently mangle the operator's intent, and falling back to build info would report a version that is confidently wrong. Both would hide the mistake in the one field whose job is to be trustworthy. Failing the whole binary at startup surfaces a bad build the first time it runs, for any command, not just when someone happens to run `version`.
Also simplified versionFromBuildInfo: verified empirically (go1.26, `go build .` inside this checkout, with and without -buildvcs and inside/outside a VCS checkout) that Main.Version is only ever the uninformative "(devel)" in exactly the cases where vcs.revision is also absent from BuildInfo.Settings -- whenever a VCS revision is available, Go has already folded it into Main.Version as a pseudo-version. The separate vcs.revision fallback loop was dead code that could only ever duplicate a hash already present in Main.Version; removed it along with the now-unused shortCommit helper. (user: [email protected], size: 956) [annotate] [blame] [check-ins using]
package main import ( "github.com/alecthomas/kong" "github.com/danmestas/libfossil/cli" _ "github.com/danmestas/libfossil/db/driver/modernc" ) // CLI is the top-level command structure. // // Version is deliberately a subcommand only, not also a global --version // flag: `repo extract` already has its own --version flag (the source // version to extract from), and kong's global flags are visible in every // subcommand's context, so a root-level --version would collide with it. // Renaming that existing, unrelated flag to make room isn't part of this // change. type CLI struct { cli.Globals Repo cli.RepoCmd `cmd:"" help:"Repository operations"` Version cli.VersionCmd `cmd:"" help:"Print version information"` } func main() { var c CLI ctx := kong.Parse(&c, kong.Name("libfossil"), kong.Description("Fossil-compatible repository tool (pure Go)"), kong.UsageOnError(), ) err := ctx.Run(&c.Globals) ctx.FatalIfErrorf(err) }