1 Command Builders
Virgil edited this page 2026-02-23 04:54:00 +00:00

Command Builders & Flag Helpers

Command Types

NewCommand — Standard command (returns error)

cmd := cli.NewCommand("build", "Build the project", "", func(cmd *cli.Command, args []string) error {
    // Business logic here
    return nil // or return fmt.Errorf("failed: %w", err)
})

NewGroup — Parent command (no handler, only subcommands)

scoreCmd := cli.NewGroup("score", "Scoring commands", "")
scoreCmd.AddCommand(grammarCmd, attentionCmd, tierCmd)
root.AddCommand(scoreCmd)

NewRun — Simple command (no error return)

cmd := cli.NewRun("version", "Show version", "", func(cmd *cli.Command, args []string) {
    cli.Println("v1.0.0")
})

Flag Helpers

All flag helpers follow the same signature: (cmd, ptr, name, short, default, usage).

var cfg struct {
    Model    string
    Verbose  bool
    Count    int
    Score    float64
    Seed     int64
    Timeout  time.Duration
    Tags     []string
}

cli.StringFlag(cmd, &cfg.Model, "model", "m", "", "Model path")
cli.BoolFlag(cmd, &cfg.Verbose, "verbose", "v", false, "Verbose output")
cli.IntFlag(cmd, &cfg.Count, "count", "n", 10, "Item count")
cli.Float64Flag(cmd, &cfg.Score, "score", "s", 0.0, "Min score")
cli.Int64Flag(cmd, &cfg.Seed, "seed", "", 0, "Random seed")
cli.DurationFlag(cmd, &cfg.Timeout, "timeout", "t", 30*time.Second, "Timeout")
cli.StringSliceFlag(cmd, &cfg.Tags, "tag", "", nil, "Tags")

Persistent Flags (inherited by subcommands)

cli.PersistentStringFlag(parentCmd, &dbPath, "db", "d", "", "Database path")
cli.PersistentBoolFlag(parentCmd, &debug, "debug", "", false, "Debug mode")

Args Validation

cmd := cli.NewCommand("deploy", "Deploy to env", "", deployFn)
cli.WithArgs(cmd, cli.ExactArgs(1))    // Exactly 1 arg
cli.WithArgs(cmd, cli.MinimumNArgs(1)) // At least 1
cli.WithArgs(cmd, cli.NoArgs())        // No args allowed
cli.WithArgs(cmd, cli.ArbitraryArgs()) // Any args

Re-exports

  • cli.Command = cobra.Command (no need to import cobra)
  • cli.PositionalArgs = cobra.PositionalArgs

Pattern: Config Struct + Flags

The idiomatic pattern for commands with many flags:

type DistillOpts struct {
    Model    string
    Probes   string
    Runs     int
    DryRun   bool
}

func addDistillCommand(parent *cli.Command) {
    var cfg DistillOpts

    cmd := cli.NewCommand("distill", "Run distillation", "", func(cmd *cli.Command, args []string) error {
        return RunDistill(cfg)
    })

    cli.StringFlag(cmd, &cfg.Model, "model", "m", "", "Model config path")
    cli.StringFlag(cmd, &cfg.Probes, "probes", "p", "", "Probe set name")
    cli.IntFlag(cmd, &cfg.Runs, "runs", "r", 3, "Runs per probe")
    cli.BoolFlag(cmd, &cfg.DryRun, "dry-run", "", false, "Preview without executing")

    parent.AddCommand(cmd)
}