From 5af6fa9d2f4945632b00e3400000cf76bf86cf3c Mon Sep 17 00:00:00 2001 From: Tam Nhu Tran Date: Sat, 30 May 2026 13:21:50 -0400 Subject: [PATCH] fix: remove duplicate home discovery flag --- cmd/server/main.go | 1 - cmd/server/main_flags_test.go | 85 +++++++++++++++++++++++++++++++++++ 2 files changed, 85 insertions(+), 1 deletion(-) create mode 100644 cmd/server/main_flags_test.go diff --git a/cmd/server/main.go b/cmd/server/main.go index 57ece7dc..eeabda21 100644 --- a/cmd/server/main.go +++ b/cmd/server/main.go @@ -148,7 +148,6 @@ func main() { flag.StringVar(&password, "password", "", "") flag.StringVar(&homeJWT, "home-jwt", "", "Home control plane JWT for mTLS certificate bootstrap and connection") flag.BoolVar(&homeDisableClusterDiscovery, "home-disable-cluster-discovery", false, "Disable Home CLUSTER NODES discovery and keep using the configured Home address") - flag.BoolVar(&homeDisableClusterDiscovery, "home-disable-cluster-discovery", false, "Disable Home CLUSTER NODES discovery and keep using the configured -home-jwt address") flag.BoolVar(&tuiMode, "tui", false, "Start with terminal management UI") flag.BoolVar(&standalone, "standalone", false, "In TUI mode, start an embedded local server") flag.BoolVar(&localModel, "local-model", false, "Use embedded model catalog only, skip remote model fetching") diff --git a/cmd/server/main_flags_test.go b/cmd/server/main_flags_test.go new file mode 100644 index 00000000..8890a0ab --- /dev/null +++ b/cmd/server/main_flags_test.go @@ -0,0 +1,85 @@ +package main + +import ( + "go/ast" + "go/parser" + "go/token" + "strconv" + "testing" +) + +func TestServerFlagsAreRegisteredOnce(t *testing.T) { + fset := token.NewFileSet() + file, err := parser.ParseFile(fset, "main.go", nil, 0) + if err != nil { + t.Fatalf("parse main.go: %v", err) + } + + seen := make(map[string]token.Pos) + duplicates := make(map[string][2]token.Pos) + + ast.Inspect(file, func(node ast.Node) bool { + call, ok := node.(*ast.CallExpr) + if !ok || len(call.Args) < 2 { + return true + } + + selector, ok := call.Fun.(*ast.SelectorExpr) + if !ok || !isFlagRegistration(selector) { + return true + } + + name, ok := stringLiteral(call.Args[1]) + if !ok { + return true + } + + if first, exists := seen[name]; exists { + duplicates[name] = [2]token.Pos{first, call.Args[1].Pos()} + return true + } + seen[name] = call.Args[1].Pos() + return true + }) + + if len(duplicates) == 0 { + return + } + + for name, positions := range duplicates { + t.Errorf( + "flag %q registered more than once at %s and %s", + name, + fset.Position(positions[0]), + fset.Position(positions[1]), + ) + } +} + +func isFlagRegistration(selector *ast.SelectorExpr) bool { + ident, ok := selector.X.(*ast.Ident) + if !ok || ident.Name != "flag" { + return false + } + + switch selector.Sel.Name { + case "BoolVar", "DurationVar", "Float64Var", "Func", "Int64Var", "IntVar", + "StringVar", "TextVar", "Uint64Var", "UintVar", "Var": + return true + default: + return false + } +} + +func stringLiteral(expr ast.Expr) (string, bool) { + lit, ok := expr.(*ast.BasicLit) + if !ok || lit.Kind != token.STRING { + return "", false + } + + value, err := strconv.Unquote(lit.Value) + if err != nil { + return "", false + } + return value, true +}