banger/internal/cli/bangerd.go
Thales Maciel 775525b592
cli,doctor: --version flag + CLI/install drift check
Two pre-release polish items on the version-display surface.

  * --version on both binaries: cobra's Version field on the banger
    and bangerd roots renders a one-line summary (banger v0.1.0
    (commit abcd1234, built 2026-04-28T20:45:50Z)). The
    SetVersionTemplate override drops cobra's "{{.Name}} version"
    prefix — our string is already a complete sentence. The
    multi-line `banger version` subcommand is unchanged for callers
    that want the full SHA / built_at on separate lines.
  * Doctor "banger version" row: prints the running CLI's version +
    short commit + built-at, plus what /etc/banger/install.toml
    recorded at install time. Disagreement is the most common
    version-skew pitfall (stale CLI against fresh daemon, or vice
    versa) and a one-line warn is friendlier than tracking that down
    from a launch failure.
    Drift detection is suppressed when either side is dev/unknown
    (untagged build) — comparing a dev CLI against a tagged install
    is the developer-machine case, not a real problem.

formatVersionLine is in internal/cli (banger.go) and reused by
bangerd.go via a strings.Replace because bangerd's version line
should say "bangerd" not "banger". Slightly tilt-feeling but cheaper
than parameterising the helper for one caller.

Tests: TestVersionsDriftToleratesDevAndUnknown pins the four
branches (match, version diff, commit diff, dev-suppression). The
existing version-format test already runs through formatVersionLine
indirectly.

Live exercise:
  $ banger --version
  banger dev (commit 1c1ca7d6, built 2026-04-28T20:52:33Z)
  $ bangerd --version
  bangerd dev (commit 1c1ca7d6, built 2026-04-28T20:52:33Z)
  $ banger doctor | head
  ...
  PASS	banger version
    - CLI dev (commit 1c1ca7d6, built 2026-04-28T20:52:33Z)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-28 17:53:32 -03:00

53 lines
1.3 KiB
Go

package cli
import (
"errors"
"strings"
"banger/internal/buildinfo"
"banger/internal/daemon"
"banger/internal/roothelper"
"github.com/spf13/cobra"
)
func NewBangerdCommand() *cobra.Command {
var systemMode bool
var rootHelperMode bool
cmd := &cobra.Command{
Use: "bangerd",
Version: strings.Replace(formatVersionLine(buildinfo.Current()), "banger ", "bangerd ", 1),
Short: "Run the banger daemon",
SilenceUsage: true,
SilenceErrors: true,
Args: noArgsUsage("usage: bangerd"),
RunE: func(cmd *cobra.Command, args []string) error {
if systemMode && rootHelperMode {
return errors.New("choose only one of --system or --root-helper")
}
if rootHelperMode {
server, err := roothelper.Open()
if err != nil {
return err
}
defer server.Close()
return server.Serve(cmd.Context())
}
open := daemon.Open
if systemMode {
open = daemon.OpenSystem
}
d, err := open(cmd.Context())
if err != nil {
return err
}
defer d.Close()
return d.Serve(cmd.Context())
},
}
cmd.Flags().BoolVar(&systemMode, "system", false, "run as the owner-user system service")
cmd.Flags().BoolVar(&rootHelperMode, "root-helper", false, "run as the privileged root helper service")
cmd.SetVersionTemplate("{{.Version}}\n")
cmd.CompletionOptions.DisableDefaultCmd = true
return cmd
}