package cli import ( "context" "fmt" "os" "github.com/urfave/cli/v3" ) // BuildInfo carries version metadata baked in at build time via -ldflags // (see the Makefile's LDFLAGS/PRERELEASE variables and the release Gitea // Actions workflow, which sets PRERELEASE from the triggering release's // "prerelease" flag). Root stores the value it was given so versionCommand // and internal/ui's footer (via Build) can read it back without threading // it through every call site. type BuildInfo struct { Version string // git tag (or "dev" for untagged/local builds) Commit string Date string Prerelease bool } var build BuildInfo // Build returns the BuildInfo Root was constructed with. func Build() BuildInfo { return build } // String renders "1.2.3 (commit abc1234, built 2026-08-14T12:00:00Z)", // appending " [prerelease]" when the triggering Gitea release was marked // as a prerelease. func (b BuildInfo) String() string { s := fmt.Sprintf("%s (commit %s, built %s)", valueOr(b.Version, "dev"), valueOr(b.Commit, "none"), valueOr(b.Date, "unknown")) if b.Prerelease { s += " [prerelease]" } return s } // versionCommand prints build metadata. Unlike every other command it does // not touch a.Client/a.Store — see bootstrap's leaf-skip check, which keeps // `vault-tui version` from tripping the first-run config wizard. func versionCommand() *cli.Command { return &cli.Command{ Name: "version", Usage: "print version, commit, build date, and prerelease status", Flags: []cli.Flag{ &cli.BoolFlag{Name: "json"}, }, Action: func(ctx context.Context, cmd *cli.Command) error { b := Build() if cmd.Bool("json") { return printJSON(os.Stdout, map[string]any{ "version": b.Version, "commit": b.Commit, "date": b.Date, "prerelease": b.Prerelease, }) } fmt.Println(b.String()) return nil }, } }