Add --version flag and enforce --long flags via pflag
Switches CLI flag parsing from Go's stdlib `flag` to spf13/pflag so `--project` (and the internal `--socket` / `--identity` / `--scenario` flags) are the only accepted form; single-hyphen long flags like `-project` are now rejected. Help output renders the canonical `--` form. Adds `patterm --version`, which prints the build version, short commit, and build date (e.g. `patterm v0.0.1 (commit abc1234, built 2026-05-14)`). The version string is injected at build time — `make patterm` derives it from `git describe --tags --always --dirty`, and the release workflow injects the pushed tag. Commit/date come from the Go toolchain's embedded VCS info via `runtime/debug.ReadBuildInfo`, so no manual bumping is required.
This commit is contained in:
@@ -2,10 +2,11 @@ package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"flag"
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
flag "github.com/spf13/pflag"
|
||||
|
||||
"github.com/hjbdev/patterm/internal/harness"
|
||||
)
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
//
|
||||
// patterm run in $PWD
|
||||
// patterm --project <dir> run in <dir>
|
||||
// patterm --version print version and exit
|
||||
// patterm mcp-stdio --socket S --identity I
|
||||
// internal: stdio MCP proxy spawned for
|
||||
// children, forwards JSON-RPC over S
|
||||
@@ -13,15 +14,22 @@ package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"flag"
|
||||
"fmt"
|
||||
"os"
|
||||
"runtime/debug"
|
||||
"time"
|
||||
|
||||
flag "github.com/spf13/pflag"
|
||||
|
||||
"github.com/hjbdev/patterm/internal/app"
|
||||
"github.com/hjbdev/patterm/internal/mcp"
|
||||
"github.com/hjbdev/patterm/internal/projectkey"
|
||||
)
|
||||
|
||||
// version is overridden at build time via `-ldflags "-X main.version=..."`.
|
||||
// Defaults to "dev" so source builds are still meaningful.
|
||||
var version = "dev"
|
||||
|
||||
func main() {
|
||||
// The mcp-stdio subcommand is a separate top-level mode: when an
|
||||
// agent CLI launches `patterm mcp-stdio --socket ...`, the same
|
||||
@@ -38,9 +46,17 @@ func main() {
|
||||
return
|
||||
}
|
||||
|
||||
var projectDir = flag.String("project", "", "project directory (default $PWD)")
|
||||
var (
|
||||
projectDir = flag.String("project", "", "project directory (default $PWD)")
|
||||
showVersion = flag.Bool("version", false, "print version and exit")
|
||||
)
|
||||
flag.Parse()
|
||||
|
||||
if *showVersion {
|
||||
fmt.Println(versionString())
|
||||
return
|
||||
}
|
||||
|
||||
cwd, err := os.Getwd()
|
||||
if err != nil {
|
||||
die("getwd: %v", err)
|
||||
@@ -80,6 +96,33 @@ func runMCPProxy() {
|
||||
}
|
||||
}
|
||||
|
||||
func versionString() string {
|
||||
commit, date := "unknown", "unknown"
|
||||
if info, ok := debug.ReadBuildInfo(); ok {
|
||||
dirty := false
|
||||
for _, s := range info.Settings {
|
||||
switch s.Key {
|
||||
case "vcs.revision":
|
||||
if len(s.Value) >= 7 {
|
||||
commit = s.Value[:7]
|
||||
} else if s.Value != "" {
|
||||
commit = s.Value
|
||||
}
|
||||
case "vcs.time":
|
||||
if t, err := time.Parse(time.RFC3339, s.Value); err == nil {
|
||||
date = t.Format("2006-01-02")
|
||||
}
|
||||
case "vcs.modified":
|
||||
dirty = s.Value == "true"
|
||||
}
|
||||
}
|
||||
if dirty && commit != "unknown" {
|
||||
commit += "-dirty"
|
||||
}
|
||||
}
|
||||
return fmt.Sprintf("patterm %s (commit %s, built %s)", version, commit, date)
|
||||
}
|
||||
|
||||
func die(format string, args ...any) {
|
||||
fmt.Fprintf(os.Stderr, "patterm: "+format+"\n", args...)
|
||||
os.Exit(1)
|
||||
|
||||
Reference in New Issue
Block a user