feat: add persistent CLI flag helpers
All checks were successful
Security Scan / security (push) Successful in 17s
All checks were successful
Security Scan / security (push) Successful in 17s
This commit is contained in:
parent
4c072f9463
commit
d84d8cc838
3 changed files with 131 additions and 0 deletions
|
|
@ -85,6 +85,11 @@ Persistent flags are inherited by all subcommands:
|
||||||
```go
|
```go
|
||||||
cli.PersistentStringFlag(parentCmd, &dbPath, "db", "d", "", "Database path")
|
cli.PersistentStringFlag(parentCmd, &dbPath, "db", "d", "", "Database path")
|
||||||
cli.PersistentBoolFlag(parentCmd, &debug, "debug", "", false, "Debug mode")
|
cli.PersistentBoolFlag(parentCmd, &debug, "debug", "", false, "Debug mode")
|
||||||
|
cli.PersistentIntFlag(parentCmd, &retries, "retries", "r", 3, "Retry count")
|
||||||
|
cli.PersistentInt64Flag(parentCmd, &seed, "seed", "", 0, "Seed value")
|
||||||
|
cli.PersistentFloat64Flag(parentCmd, &ratio, "ratio", "", 1.0, "Scaling ratio")
|
||||||
|
cli.PersistentDurationFlag(parentCmd, &timeout, "timeout", "t", 30*time.Second, "Timeout")
|
||||||
|
cli.PersistentStringSliceFlag(parentCmd, &tags, "tag", "", nil, "Tags")
|
||||||
```
|
```
|
||||||
|
|
||||||
## Args Validation
|
## Args Validation
|
||||||
|
|
|
||||||
|
|
@ -195,6 +195,51 @@ func PersistentBoolFlag(cmd *Command, ptr *bool, name, short string, def bool, u
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// PersistentIntFlag adds a persistent integer flag (inherited by subcommands).
|
||||||
|
func PersistentIntFlag(cmd *Command, ptr *int, name, short string, def int, usage string) {
|
||||||
|
if short != "" {
|
||||||
|
cmd.PersistentFlags().IntVarP(ptr, name, short, def, usage)
|
||||||
|
} else {
|
||||||
|
cmd.PersistentFlags().IntVar(ptr, name, def, usage)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// PersistentInt64Flag adds a persistent int64 flag (inherited by subcommands).
|
||||||
|
func PersistentInt64Flag(cmd *Command, ptr *int64, name, short string, def int64, usage string) {
|
||||||
|
if short != "" {
|
||||||
|
cmd.PersistentFlags().Int64VarP(ptr, name, short, def, usage)
|
||||||
|
} else {
|
||||||
|
cmd.PersistentFlags().Int64Var(ptr, name, def, usage)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// PersistentFloat64Flag adds a persistent float64 flag (inherited by subcommands).
|
||||||
|
func PersistentFloat64Flag(cmd *Command, ptr *float64, name, short string, def float64, usage string) {
|
||||||
|
if short != "" {
|
||||||
|
cmd.PersistentFlags().Float64VarP(ptr, name, short, def, usage)
|
||||||
|
} else {
|
||||||
|
cmd.PersistentFlags().Float64Var(ptr, name, def, usage)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// PersistentDurationFlag adds a persistent time.Duration flag (inherited by subcommands).
|
||||||
|
func PersistentDurationFlag(cmd *Command, ptr *time.Duration, name, short string, def time.Duration, usage string) {
|
||||||
|
if short != "" {
|
||||||
|
cmd.PersistentFlags().DurationVarP(ptr, name, short, def, usage)
|
||||||
|
} else {
|
||||||
|
cmd.PersistentFlags().DurationVar(ptr, name, def, usage)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// PersistentStringSliceFlag adds a persistent string slice flag (inherited by subcommands).
|
||||||
|
func PersistentStringSliceFlag(cmd *Command, ptr *[]string, name, short string, def []string, usage string) {
|
||||||
|
if short != "" {
|
||||||
|
cmd.PersistentFlags().StringSliceVarP(ptr, name, short, def, usage)
|
||||||
|
} else {
|
||||||
|
cmd.PersistentFlags().StringSliceVar(ptr, name, def, usage)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// ─────────────────────────────────────────────────────────────────────────────
|
// ─────────────────────────────────────────────────────────────────────────────
|
||||||
// Command Configuration
|
// Command Configuration
|
||||||
// ─────────────────────────────────────────────────────────────────────────────
|
// ─────────────────────────────────────────────────────────────────────────────
|
||||||
|
|
|
||||||
81
pkg/cli/command_test.go
Normal file
81
pkg/cli/command_test.go
Normal file
|
|
@ -0,0 +1,81 @@
|
||||||
|
package cli
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestPersistentFlagHelpers_Good(t *testing.T) {
|
||||||
|
t.Run("persistent flags inherit through subcommands", func(t *testing.T) {
|
||||||
|
parent := NewGroup("parent", "Parent", "")
|
||||||
|
|
||||||
|
var (
|
||||||
|
str string
|
||||||
|
b bool
|
||||||
|
i int
|
||||||
|
i64 int64
|
||||||
|
f64 float64
|
||||||
|
dur time.Duration
|
||||||
|
slice []string
|
||||||
|
)
|
||||||
|
|
||||||
|
PersistentStringFlag(parent, &str, "name", "n", "default", "Name")
|
||||||
|
PersistentBoolFlag(parent, &b, "debug", "d", false, "Debug")
|
||||||
|
PersistentIntFlag(parent, &i, "count", "c", 1, "Count")
|
||||||
|
PersistentInt64Flag(parent, &i64, "seed", "", 2, "Seed")
|
||||||
|
PersistentFloat64Flag(parent, &f64, "ratio", "", 3.5, "Ratio")
|
||||||
|
PersistentDurationFlag(parent, &dur, "timeout", "t", 4*time.Second, "Timeout")
|
||||||
|
PersistentStringSliceFlag(parent, &slice, "tag", "", nil, "Tags")
|
||||||
|
|
||||||
|
child := NewCommand("child", "Child", "", func(_ *Command, _ []string) error {
|
||||||
|
assert.Equal(t, "override", str)
|
||||||
|
assert.True(t, b)
|
||||||
|
assert.Equal(t, 9, i)
|
||||||
|
assert.Equal(t, int64(42), i64)
|
||||||
|
assert.InDelta(t, 7.25, f64, 1e-9)
|
||||||
|
assert.Equal(t, 15*time.Second, dur)
|
||||||
|
assert.Equal(t, []string{"alpha", "beta"}, slice)
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
parent.AddCommand(child)
|
||||||
|
|
||||||
|
parent.SetArgs([]string{
|
||||||
|
"child",
|
||||||
|
"--name", "override",
|
||||||
|
"--debug",
|
||||||
|
"--count", "9",
|
||||||
|
"--seed", "42",
|
||||||
|
"--ratio", "7.25",
|
||||||
|
"--timeout", "15s",
|
||||||
|
"--tag", "alpha",
|
||||||
|
"--tag", "beta",
|
||||||
|
})
|
||||||
|
|
||||||
|
require.NoError(t, parent.Execute())
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("persistent helpers use short flags when provided", func(t *testing.T) {
|
||||||
|
parent := NewGroup("parent", "Parent", "")
|
||||||
|
var value int
|
||||||
|
PersistentIntFlag(parent, &value, "count", "c", 1, "Count")
|
||||||
|
|
||||||
|
var seen bool
|
||||||
|
child := &cobra.Command{
|
||||||
|
Use: "child",
|
||||||
|
RunE: func(_ *cobra.Command, _ []string) error {
|
||||||
|
seen = true
|
||||||
|
assert.Equal(t, 5, value)
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
}
|
||||||
|
parent.AddCommand(child)
|
||||||
|
parent.SetArgs([]string{"child", "-c", "5"})
|
||||||
|
|
||||||
|
require.NoError(t, parent.Execute())
|
||||||
|
assert.True(t, seen)
|
||||||
|
})
|
||||||
|
}
|
||||||
Loading…
Add table
Reference in a new issue