// Copyright (c) 2026, Pim van Pelt package main import ( "context" "flag" "fmt" "os" "strings" "google.golang.org/grpc" "google.golang.org/grpc/credentials/insecure" buildinfo "git.ipng.ch/ipng/vpp-maglev/cmd" "git.ipng.ch/ipng/vpp-maglev/internal/grpcapi" ) func main() { if err := run(); err != nil { fmt.Fprintf(os.Stderr, "%s\n", formatError(err)) os.Exit(1) } } func run() error { defaultServer := "localhost:9090" if v := os.Getenv("MAGLEV_SERVER"); v != "" { defaultServer = v } serverAddr := flag.String("server", defaultServer, "maglev server address (env: MAGLEV_SERVER)") color := flag.Bool("color", true, "colorize static labels in output (defaults to false in one-shot mode)") printVersion := flag.Bool("version", false, "print version and exit") flag.Parse() if *printVersion { fmt.Printf("maglevc %s (commit %s, built %s)\n", buildinfo.Version(), buildinfo.Commit(), buildinfo.Date()) return nil } // Detect whether -color was explicitly set so we can pick a // mode-aware default: color is useful in the interactive shell but // noise (ANSI escapes) when piping one-shot output into scripts. colorExplicit := false flag.Visit(func(f *flag.Flag) { if f.Name == "color" { colorExplicit = true } }) conn, err := grpc.NewClient(*serverAddr, grpc.WithTransportCredentials(insecure.NewCredentials())) if err != nil { return fmt.Errorf("connect %s: %w", *serverAddr, err) } defer func() { _ = conn.Close() }() client := grpcapi.NewMaglevClient(conn) ctx := context.Background() args := flag.Args() if len(args) == 0 { // Interactive shell: color defaults to true. if colorExplicit { colorEnabled = *color } else { colorEnabled = true } fmt.Printf("maglevc %s (commit %s, built %s)\n", buildinfo.Version(), buildinfo.Commit(), buildinfo.Date()) return runShell(ctx, client) } // One-shot command from CLI arguments: color defaults to false so // output is script-safe. Operators wanting color can still pass // -color=true explicitly. if colorExplicit { colorEnabled = *color } else { colorEnabled = false } root := buildTree() tokens := splitTokens(strings.Join(args, " ")) return dispatch(ctx, root, client, tokens) }