[teamai] Push 87 resource(s) from XingfenD
This commit is contained in:
@@ -0,0 +1,125 @@
|
||||
# Cobra Flags Reference
|
||||
|
||||
Cobra delegates all flag parsing to `github.com/spf13/pflag`. `cobra.Command` exposes two `*pflag.FlagSet`s:
|
||||
|
||||
- `cmd.Flags()` — local flags, only available on this command.
|
||||
- `cmd.PersistentFlags()` — inherited by all subcommands.
|
||||
|
||||
## Common flag types
|
||||
|
||||
```go
|
||||
// String
|
||||
cmd.Flags().String("name", "default", "description")
|
||||
cmd.Flags().StringP("name", "n", "default", "description") // with shorthand
|
||||
|
||||
// With pointer binding (no Lookup needed later)
|
||||
var name string
|
||||
cmd.Flags().StringVar(&name, "name", "default", "description")
|
||||
cmd.Flags().StringVarP(&name, "name", "n", "default", "description")
|
||||
|
||||
// Other types follow the same pattern:
|
||||
cmd.Flags().Int / IntVar / IntVarP
|
||||
cmd.Flags().Bool / BoolVar / BoolVarP
|
||||
cmd.Flags().Float64 / Float64Var
|
||||
cmd.Flags().Duration / DurationVar // parses "1h30m", "500ms"
|
||||
cmd.Flags().StringSlice / StringSliceVar // comma-separated or repeated flags
|
||||
cmd.Flags().StringArray / StringArrayVar // repeated flags only (no comma splitting)
|
||||
cmd.Flags().IntSlice / IntSliceVar
|
||||
cmd.Flags().StringToString // --label key=value --label k2=v2
|
||||
```
|
||||
|
||||
## StringSlice vs StringArray
|
||||
|
||||
| Flag type | Input | Result |
|
||||
| ------------- | --------------------- | --------------------------------- |
|
||||
| `StringSlice` | `--tags a,b --tags c` | `["a", "b", "c"]` — commas split |
|
||||
| `StringArray` | `--tags a,b --tags c` | `["a,b", "c"]` — commas NOT split |
|
||||
|
||||
Use `StringArray` when values may legitimately contain commas.
|
||||
|
||||
## Flag constraints
|
||||
|
||||
```go
|
||||
// Fail if flag not provided
|
||||
cmd.MarkFlagRequired("output")
|
||||
|
||||
// Fail if both provided
|
||||
cmd.MarkFlagsMutuallyExclusive("json", "yaml", "table")
|
||||
|
||||
// Fail if none provided
|
||||
cmd.MarkFlagsOneRequired("file", "stdin")
|
||||
|
||||
// Require flag only if another flag is set
|
||||
cmd.MarkFlagsMutuallyExclusive("tls", "no-tls")
|
||||
```
|
||||
|
||||
## Persistent flag patterns
|
||||
|
||||
```go
|
||||
func init() {
|
||||
// global flags on root
|
||||
rootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file (default: $HOME/.myapp.yaml)")
|
||||
rootCmd.PersistentFlags().StringVar(&logLevel, "log-level", "info", "log level (debug, info, warn, error)")
|
||||
|
||||
// bind to viper immediately after defining
|
||||
viper.BindPFlag("config", rootCmd.PersistentFlags().Lookup("config"))
|
||||
viper.BindPFlag("log-level", rootCmd.PersistentFlags().Lookup("log-level"))
|
||||
}
|
||||
```
|
||||
|
||||
## Custom flag value types
|
||||
|
||||
Implement `pflag.Value` to parse arbitrary types:
|
||||
|
||||
```go
|
||||
type enumValue struct {
|
||||
val string
|
||||
allowed []string
|
||||
}
|
||||
|
||||
func (e *enumValue) String() string { return e.val }
|
||||
func (e *enumValue) Type() string { return "enum" }
|
||||
func (e *enumValue) Set(s string) error {
|
||||
for _, a := range e.allowed {
|
||||
if s == a {
|
||||
e.val = s
|
||||
return nil
|
||||
}
|
||||
}
|
||||
return fmt.Errorf("must be one of %v", e.allowed)
|
||||
}
|
||||
|
||||
var outputFmt = &enumValue{val: "table", allowed: []string{"table", "json", "yaml"}}
|
||||
cmd.Flags().Var(outputFmt, "output", "output format (table, json, yaml)")
|
||||
```
|
||||
|
||||
## Flag groups (required together)
|
||||
|
||||
Mark a set of flags that must all be provided if any one of them is provided:
|
||||
|
||||
```go
|
||||
cmd.Flags().String("tls-cert", "", "TLS certificate file")
|
||||
cmd.Flags().String("tls-key", "", "TLS key file")
|
||||
cmd.MarkFlagsRequiredTogether("tls-cert", "tls-key")
|
||||
```
|
||||
|
||||
## Accessing flag values
|
||||
|
||||
Prefer pointer binding (`StringVar`, `IntVar`, etc.) for type-safe access. When you need the flag post-parse:
|
||||
|
||||
```go
|
||||
port, err := cmd.Flags().GetInt("port")
|
||||
name, err := cmd.Flags().GetString("name")
|
||||
tags, err := cmd.Flags().GetStringSlice("tags")
|
||||
```
|
||||
|
||||
## Flag changed vs default
|
||||
|
||||
```go
|
||||
if cmd.Flags().Changed("port") {
|
||||
// user explicitly provided --port
|
||||
// useful when distinguishing "user set 0" from "flag not provided"
|
||||
}
|
||||
```
|
||||
|
||||
`Changed()` is also how viper knows which flags are explicit overrides — it only promotes a flag to the highest precedence layer if `Changed()` is true.
|
||||
Reference in New Issue
Block a user