flagutil

package
v0.1.4 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 18, 2026 License: MIT Imports: 16 Imported by: 0

Documentation

Overview

Package flagutil provides utilities for working with Cobra flags, particularly for handling persistent flags and the Changed() pattern.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func AnyFlagsChanged

func AnyFlagsChanged(cmd *cobra.Command, flagNames []string) bool

AnyFlagsChanged checks if any of the given flags were changed. This is useful for checking if any request-shaping flags were set (for stdin mutual exclusion).

func BuildRequest

func BuildRequest[T any](cmd *cobra.Command, meta []FlagMeta, bodyFieldPath string, bodyFlagName string) (*T, error)

BuildRequest reads all flags described by meta, validates them, and populates a new T. Returns a pointer to the populated struct. Union fields are handled automatically via their embedded UnionMeta.

bodyFieldPath identifies which field on T contains the request body (e.g. "BaseUser"). When the --body flag or stdin is piped, the JSON is unmarshaled into that sub-field first, then individual flags override specific fields (merge behavior). Empty string means the entire struct is the body (IsRequestBody path) or there is no body field (params-only).

bodyFlagName is the name of the whole-body JSON flag (e.g. "body"). When non-empty and the flag is set, its value takes priority over stdin. Individual flags always override both.

func BuildRequestBody

func BuildRequestBody[T any](cmd *cobra.Command, flagName string, annotations string, isRequired bool) (*T, error)

BuildRequestBody reads a request body from a flag or stdin, unmarshals JSON, and returns *T. This handles the IsRequestBody pattern where the entire body is a single JSON blob. When isRequired is false and no input is provided, returns (nil, nil) instead of an error.

func DerefOrZero

func DerefOrZero[T any](p *T) T

DerefOrZero safely dereferences a pointer, returning the zero value if nil. Used for optional request bodies with reference types ([]byte, slices, maps) where BuildRequestBody returns *T but the SDK method takes T.

func FlagChanged

func FlagChanged(cmd *cobra.Command, name string) bool

FlagChanged checks if a flag was explicitly set by the user. This correctly handles both local flags and inherited persistent flags. IMPORTANT: Use this instead of cmd.Flags().Changed() which doesn't reliably detect changes on inherited persistent flags.

func GetBoolFlag

func GetBoolFlag(cmd *cobra.Command, name string) (bool, bool)

GetBoolFlag returns the value of a bool flag and whether it was changed. This correctly handles both local flags and inherited persistent flags.

func GetFloat64Flag

func GetFloat64Flag(cmd *cobra.Command, name string) (float64, bool)

GetFloat64Flag returns the value of a float64 flag and whether it was changed. This correctly handles both local flags and inherited persistent flags.

func GetInt64Flag

func GetInt64Flag(cmd *cobra.Command, name string) (int64, bool)

GetInt64Flag returns the value of an int64 flag and whether it was changed. This correctly handles both local flags and inherited persistent flags.

func GetIntFlag

func GetIntFlag(cmd *cobra.Command, name string) (int, bool)

GetIntFlag returns the value of an int flag and whether it was changed. This correctly handles both local flags and inherited persistent flags.

func GetStringArrayFlag

func GetStringArrayFlag(cmd *cobra.Command, name string) ([]string, bool)

GetStringArrayFlag returns the value of a string array flag and whether it was changed. This correctly handles both local flags and inherited persistent flags.

func GetStringFlag

func GetStringFlag(cmd *cobra.Command, name string) (string, bool)

GetStringFlag returns the value of a string flag and whether it was changed. This correctly handles both local flags and inherited persistent flags.

func GetStringSliceFlag

func GetStringSliceFlag(cmd *cobra.Command, name string) ([]string, bool)

GetStringSliceFlag returns the value of a string slice flag and whether it was changed. This correctly handles both local flags and inherited persistent flags. StringSlice supports both comma-separated ("a,b") and repeated ("--f a --f b") syntax.

func HasAnyFlagWithPrefix

func HasAnyFlagWithPrefix(cmd *cobra.Command, prefix string) bool

HasAnyFlagWithPrefix checks if any flag with the given prefix was changed. This is useful for detecting if any field in a nested object or union variant was set.

func HasStdinInput

func HasStdinInput(cmd *cobra.Command) bool

HasStdinInput checks if there is data available on stdin. It accepts a cobra.Command to support cmd.SetIn() for testing, falling back to os.Stdin.Stat() for production pipe detection.

func RegisterFlags

func RegisterFlags(cmd *cobra.Command, meta []FlagMeta)

RegisterFlags registers Cobra flags from metadata, including union flags. Flags that already exist as inherited persistent flags (e.g., global security credentials) are skipped to prevent local flags from shadowing them.

func ValidateMeta

func ValidateMeta[T any](meta []FlagMeta) error

ValidateMeta checks that all FieldPaths in meta resolve to valid fields on T. Call from RegisterFlags or init() to catch template generation bugs at startup rather than at CLI runtime.

Types

type FlagKind

type FlagKind int

FlagKind describes what kind of value a flag carries.

const (
	FlagKindString      FlagKind = iota // string flag → string field
	FlagKindBool                        // bool flag → bool field
	FlagKindInt64                       // int64 flag → int64 field
	FlagKindFloat64                     // float64 flag → float64 field
	FlagKindStringArray                 // string array flag → []string field
	FlagKindDateTime                    // string flag → validated as RFC3339, stored as time.Time or string
	FlagKindDate                        // string flag → validated as date, stored as types.Date or string
	FlagKindEnum                        // string flag → named enum type (reflect.Convert)
	FlagKindIntEnum                     // string flag → parse int → named int enum type
	FlagKindJSON                        // string flag → unmarshal into struct
	FlagKindUnion                       // union field — handled via UnionMeta
	FlagKindFile                        // string flag (file path) → read file → populate Content/FileName struct
	FlagKindFileArray                   // string flag (comma-separated file paths) → read files → populate []FileStruct
	FlagKindBytes                       // string flag → "file:<path>" reads file, "b64:<data>" base64-decodes, else raw UTF-8 bytes → []byte field
)

type FlagMeta

type FlagMeta struct {
	// Flag identity
	FlagName  string   // Cobra flag name, e.g. "request-body.emoji"
	Shorthand string   // Single-letter shorthand for Cobra (e.g. "s" for -s), empty if none
	FieldPath string   // Dot-delimited Go struct path, e.g. "RequestBody.Emoji"
	Kind      FlagKind // What type of flag this is

	// Flag behavior
	Optional   bool // true if Go field is a pointer type
	Required   bool // true if user must provide this flag
	HasDefault bool // true if optional+has-default (always wrap in pointer, even when unchanged)

	// Validation
	EnumValues []string // valid values for enum validation; nil if not enum

	// JSON unmarshal
	Annotations string // struct tag for JSON unmarshal, e.g. `request:"mediaType=application/json"`

	// Union support
	Union *UnionMeta // non-nil when Kind == FlagKindUnion

	// Registration (used by RegisterFlags)
	Description  string  // help text for Cobra
	DefaultStr   string  // default for String/Enum/DateTime/JSON flags
	DefaultBool  bool    // default for Bool flags
	DefaultInt   int64   // default for Int64 flags
	DefaultFloat float64 // default for Float64 flags

	// Display grouping (used by help template)
	Group string // optional group label for organizing flags in --help output

	// Value resolution (used by interactive prompting to skip already-resolved flags)
	EnvVar    string // environment variable name, e.g. "MYAPP_API_KEY"; empty if none
	ConfigKey string // config file key, e.g. "api_key"; empty if none
}

FlagMeta describes a single CLI flag and how it maps to a request struct field. This is the single source of truth — used for both Cobra flag registration (RegisterFlags) and request building (BuildRequest). This code is designed for CLI startup, not hot paths.

type UnionMeta

type UnionMeta struct {
	Discriminated    bool               // true for discriminated, false for non-discriminated
	DiscriminatorKey string             // Go field name for discriminator on variant structs (e.g. "Type")
	Optional         bool               // true if the union field itself is *T (pointer)
	TypeDescription  string             // help text for top-level JSON flag
	Variants         []UnionVariantMeta // variant definitions (empty for non-discriminated)
}

UnionMeta describes a union field's structure for metadata-driven registration and parsing.

type UnionVariantMeta

type UnionVariantMeta struct {
	DiscriminatorValue string     // discriminator value, e.g. "circle"
	FlagName           string     // full flag name, e.g. "shape-request.shape.circle"
	FieldName          string     // Go field name on union struct, e.g. "Circle"
	CanExpand          bool       // whether variant has expanded field flags
	Description        string     // help text for variant JSON flag
	Fields             []FlagMeta // variant leaf fields (FieldPath relative to variant struct)
}

UnionVariantMeta describes a single variant within a discriminated union.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL