cmd: add a 'version' subcommand and flag to show the version
Some checks failed
CI / build-docker (push) Successful in 4s
CI / build-docker-bootstrap (push) Has been skipped
CI / release-test (push) Failing after 13s

This commit is contained in:
2026-09-19 21:36:31 -07:00
parent 741709623b
commit 171da4139b
4 changed files with 88 additions and 1 deletions

View File

@@ -5,6 +5,8 @@ import (
"os"
"github.com/spf13/cobra"
"git.offline-twitter.com/offline-labs/gas-stack/pkg/version"
)
const (
@@ -16,12 +18,16 @@ const (
func main() {
root_cmd := &cobra.Command{
Use: "gas",
Version: version.String(),
SilenceErrors: true,
SilenceUsage: true,
}
// Print a bare version string ("v0.0.4"), rather than cobra's "gas version v0.0.4".
root_cmd.SetVersionTemplate("{{.Version}}\n")
root_cmd.AddCommand(sqlite_lint)
root_cmd.AddCommand(cmd_init)
root_cmd.AddCommand(generate_model)
root_cmd.AddCommand(cmd_version)
if err := root_cmd.Execute(); err != nil {
fmt.Println(RED + err.Error() + RESET)
os.Exit(1)

19
cmd/subcmd_version.go Normal file
View File

@@ -0,0 +1,19 @@
package main
import (
"fmt"
"github.com/spf13/cobra"
"git.offline-twitter.com/offline-labs/gas-stack/pkg/version"
)
var cmd_version = &cobra.Command{
Use: "version",
Short: "Print the version of `gas`",
Args: cobra.NoArgs,
Run: func(cmd *cobra.Command, args []string) {
fmt.Println(version.String())
},
}

View File

@@ -1,3 +1,10 @@
#!/bin/sh
go build -tags fts5 -o gas ./cmd
# Stamp the version into the binary. `git describe` fails when this isn't a git checkout (e.g. a
# source export with no .git dir); in that case leave it empty, and pkg/version falls back to the
# build info that the Go toolchain embeds.
VERSION=$(git describe --tags --always --dirty 2>/dev/null)
go build -tags fts5 \
-ldflags "-X git.offline-twitter.com/offline-labs/gas-stack/pkg/version.Version=$VERSION" \
-o gas ./cmd

55
pkg/version/version.go Normal file
View File

@@ -0,0 +1,55 @@
package version
import (
"fmt"
"runtime/debug"
)
// Version is stamped in at compile time by `ops/compile.sh`, via:
//
// -ldflags "-X git.offline-twitter.com/offline-labs/gas-stack/pkg/version.Version=v0.0.4"
//
// It's empty for builds that don't go through that script-- most importantly
// `go install git.offline-twitter.com/offline-labs/gas-stack/cmd@v0.0.4`, which is the normal way
// to install `gas`. In that case, String() recovers the version from the build info that the Go
// toolchain embeds in every binary.
var Version = ""
// String returns the version of this binary, e.g. "v0.0.4".
func String() string {
if Version != "" {
return Version
}
info, ok := debug.ReadBuildInfo()
if !ok {
return "unknown"
}
// Set by `go install module@version`, and (as of Go 1.24) by `go build` in a git checkout
// that has the tags available. It's "(devel)" if the toolchain couldn't work out a version.
if info.Main.Version != "" && info.Main.Version != "(devel)" {
return info.Main.Version
}
// No module version, so fall back to the commit. This happens when building from a source
// tree with no usable VCS metadata: a git worktree, a `.git`-less export, or `-buildvcs=false`.
var revision, dirty string
for _, setting := range info.Settings {
switch setting.Key {
case "vcs.revision":
revision = setting.Value
case "vcs.modified":
if setting.Value == "true" {
dirty = "-dirty"
}
}
}
if revision == "" {
return "unknown"
}
if len(revision) > 12 {
revision = revision[:12]
}
return fmt.Sprintf("devel-%s%s", revision, dirty)
}