flagkit

package
v0.19.0 Latest Latest
Warning

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

Go to latest
Published: Jul 6, 2026 License: MIT Imports: 7 Imported by: 0

Documentation

Overview

Package flagkit provides reusable, embeddable flag structs that standardize common CLI flag declarations for use with structcli.

Each type encapsulates a single flag with an opinionated name, type, default, and description matching industry conventions. This gives CLIs a consistent declaration surface. Agents and scripts can rely on --follow, --output, --timeout, etc. having predictable names and types across tools.

flagkit standardizes flag declarations, not behavioral semantics. How a command interprets --quiet or --dry-run is up to the consumer. The value is in the shared vocabulary: consistent names, types, and defaults that AI agents can recognize across CLIs built with structcli.

Design Principles

  • One struct per concern for maximum composability
  • Sensible, agent-friendly defaults (e.g., no auto-tailing, finite timeouts)
  • Standard flag names matching industry conventions
  • Works with all structcli features: env vars, config files, JSON Schema, shell completion, and doc generation

Taxonomy

Type           Flag          Default  Status
─────────────  ────────────  ───────  ────────
Follow         --follow/-f   false    available
LogLevel       --log-level   info     available
ZapLogLevel    --log-level   info     available
SlogLogLevel   --log-level   info     available
Output         --output/-o   text     available
Verbose        --verbose/-v  0        available
DryRun         --dry-run     false    available
Timeout        --timeout     30s      available
Quiet          --quiet/-q    false    available

Composition

Embed one or more flagkit types in your options struct:

type LogOptions struct {
    flagkit.Follow
    flagkit.LogLevel
    flagkit.Output
    flagkit.Quiet
    Service string `flag:"service" flagdescr:"Service name"`
}

func (o *LogOptions) Attach(c *cobra.Command) error {
    if err := structcli.Define(c, o); err != nil {
        return err
    }
    flagkit.AnnotateCommand(c)
    return nil
}

Naming Convention

Each type uses the flag name as the struct name: Follow for --follow, Output for --output, Timeout for --timeout, and so on. Inner fields use descriptive names (Enabled, Format, Duration, Level) so that embedded access reads naturally (e.g. opts.Output.Format, not opts.Output.Output).

Index

Constants

View Source
const FlagEnumAnnotation = "leodido/structcli/flag-enum"

FlagEnumAnnotation mirrors flagEnumAnnotation (unexported, in viper.go) from the root structcli package. Duplicated here to avoid an import cycle (flagkit → structcli → flagkit).

View Source
const FlagKitAnnotation = "leodido/structcli/flag-kit"

FlagKitAnnotation is the pflag annotation key set on flags defined by flagkit types. The generate package uses this to detect flagkit usage and emit development guidance in generated docs.

Variables

This section is empty.

Functions

func AnnotateCommand

func AnnotateCommand(c *cobra.Command)

AnnotateCommand marks all flagkit-owned flags on the command with the FlagKitAnnotation. Call this after structcli.Define when embedding flagkit types in a parent struct.

When using a flagkit type standalone via its Attach method, the annotation is set automatically and this call is not needed. For embedded usage, structcli.Define traverses into the embedded struct but does not call its Attach method, so AnnotateCommand must be called explicitly to set the annotation.

Matching is by flag name, not by type. If the command defines a non-flagkit flag whose name collides with a flagkit flag name (e.g. a custom --follow), it will be incorrectly annotated. Only call this on commands that embed flagkit types.

func RegisterOutputFormats

func RegisterOutputFormats(formats ...OutputFormat)

RegisterOutputFormats registers the given output formats for use with structcli's enum flag handling. Each format's string value is used as both the canonical name and the only accepted alias.

This is a process-global, one-time registration (like database/sql.Register). Register the superset of all formats your CLI supports. For per-command format subsets, use Output.ValidFormat in your command's RunE.

Call this in init() before any structcli.Define calls:

func init() {
    flagkit.RegisterOutputFormats(flagkit.OutputJSON, flagkit.OutputText, flagkit.OutputYAML)
}

For custom aliases, use structcli.RegisterEnum directly instead.

Types

type DryRun

type DryRun struct {
	Enabled bool `flag:"dry-run" flagdescr:"Preview without making changes" default:"false" flagenv:"true"`
}

DryRun provides a --dry-run flag for safe previewing of operations.

The default is false. When true, commands should describe what they would do without making changes. This is agent-friendly: AI agents can preview destructive operations before committing.

Usage:

type Options struct {
    flagkit.DryRun
}

// In RunE:
if opts.DryRun.Enabled {
    fmt.Println("would delete", target)
    return nil
}

func (*DryRun) Attach

func (o *DryRun) Attach(c *cobra.Command) error

Attach implements structcli.Options.

type Follow

type Follow struct {
	Enabled bool `flag:"follow" flagshort:"f" flagdescr:"Stream output continuously" default:"false"`
}

Follow provides a --follow/-f boolean flag for opt-in streaming.

When false (the default), commands should print current output and exit. When true, commands should stream output continuously. This default is agent-friendly: AI agents and scripts won't hang on indefinite tailing.

Usage:

type LogOptions struct {
    flagkit.Follow
    Service string `flag:"service" flagdescr:"Service name"`
}

func (o *LogOptions) Attach(c *cobra.Command) error {
    if err := structcli.Define(c, o); err != nil {
        return err
    }
    flagkit.AnnotateCommand(c)
    return nil
}

// In RunE:
if opts.Follow.Enabled {
    streamLogs(ctx)
} else {
    printCurrentLogs()
}

func (*Follow) Attach

func (o *Follow) Attach(c *cobra.Command) error

Attach implements structcli.Options.

type LogLevel

type LogLevel = ZapLogLevel

LogLevel is the recommended log level type. It is an alias for ZapLogLevel.

Embed this in your options struct for the standard --log-level flag backed by zapcore.Level. Use SlogLogLevel if you prefer the stdlib slog package.

type Output

type Output struct {
	Format OutputFormat `flag:"output" flagshort:"o" flagdescr:"Output format" default:"text"`
	// contains filtered or unexported fields
}

Output provides a --output/-o flag for selecting output format.

The default is text. You must register the supported formats before use via RegisterOutputFormats or structcli.RegisterEnum.

For CLIs where different commands support different format subsets, register the superset globally, then call Output.RestrictFormats after Attach. RestrictFormats is the single source of truth: it narrows help, JSON Schema, and runtime validation in one call:

func init() {
    flagkit.RegisterOutputFormats(flagkit.OutputJSON, flagkit.OutputText, flagkit.OutputYAML)
}

opts.Attach(cmd)
opts.Output.RestrictFormats(cmd, flagkit.OutputJSON, flagkit.OutputYAML)

// In RunE (no args needed, uses the set from RestrictFormats):
if err := opts.Output.ValidFormat(); err != nil {
    return err
}

func (*Output) Attach

func (o *Output) Attach(c *cobra.Command) error

Attach implements structcli.Options.

Returns an error if the --output flag was not created, which typically means RegisterOutputFormats (or structcli.RegisterEnum) was not called before Attach.

func (*Output) RestrictFormats

func (o *Output) RestrictFormats(c *cobra.Command, allowed ...OutputFormat)

RestrictFormats narrows the --output flag's help text, enum annotation, and runtime validation to only the given formats. Call this after [Attach] or structcli.Define.

This is the single source of truth for per-command format subsets. After calling RestrictFormats, [ValidFormat] with no arguments enforces the same set, eliminating the need to repeat the allowed list.

Shell completion may still show the globally registered superset because cobra does not support overriding completion functions after registration.

opts.Attach(cmd)
opts.Output.RestrictFormats(cmd, flagkit.OutputJSON, flagkit.OutputText)

func (*Output) ValidFormat

func (o *Output) ValidFormat(allowed ...OutputFormat) error

ValidFormat returns nil if the current output format is allowed, or an error describing the mismatch.

When called with no arguments, it validates against the set stored by [RestrictFormats]. When called with explicit arguments, it validates against those instead (and ignores any stored restriction).

If neither RestrictFormats was called nor explicit arguments are provided, ValidFormat returns nil (all formats accepted).

type OutputFormat

type OutputFormat string

OutputFormat is a string enum for output format selection.

flagkit provides common constants but does NOT auto-register them. Call RegisterOutputFormats or structcli.RegisterEnum in your init() to declare the CLI-wide format vocabulary.

const (
	OutputJSON  OutputFormat = "json"
	OutputJSONL OutputFormat = "jsonl"
	OutputText  OutputFormat = "text"
	OutputYAML  OutputFormat = "yaml"
)

type Quiet

type Quiet struct {
	Enabled bool `flag:"quiet" flagshort:"q" flagdescr:"Suppress non-essential output" default:"false"`
}

Quiet provides a --quiet/-q flag for suppressing non-essential output.

The default is false. When true, commands should only emit machine-readable output (e.g., IDs, status codes) and suppress progress messages, banners, and decorative formatting.

Usage:

type Options struct {
    flagkit.Quiet
}

// In RunE:
if !opts.Quiet.Enabled {
    fmt.Println("Deploying to production...")
}

func (*Quiet) Attach

func (o *Quiet) Attach(c *cobra.Command) error

Attach implements structcli.Options.

type SlogLogLevel

type SlogLogLevel struct {
	LogLevel slog.Level `flag:"log-level" flagdescr:"Set log level" default:"info" flagenv:"true" flaggroup:"Logging"`
}

SlogLogLevel provides a --log-level flag backed by slog.Level (stdlib).

The default is info. slog.Level is handled by structcli's built-in hooks, so no additional registration is needed.

Usage:

type Options struct {
    flagkit.SlogLogLevel
}

func (*SlogLogLevel) Attach

func (o *SlogLogLevel) Attach(c *cobra.Command) error

Attach implements structcli.Options.

type Timeout

type Timeout struct {
	Duration time.Duration `flag:"timeout" flagdescr:"Operation timeout" default:"30s" flagenv:"true"`
}

Timeout provides a --timeout flag for operation deadlines.

The default is 30s. Accepts any value parseable by time.ParseDuration. This is agent-friendly: operations won't hang indefinitely.

Usage:

type Options struct {
    flagkit.Timeout
}

// In RunE:
ctx, cancel := context.WithTimeout(ctx, opts.Timeout.Duration)
defer cancel()

func (*Timeout) Attach

func (o *Timeout) Attach(c *cobra.Command) error

Attach implements structcli.Options.

type Verbose

type Verbose struct {
	Level int `flag:"verbose" flagshort:"v" flagtype:"count" flagdescr:"Increase verbosity (-v, -vv, -vvv)" default:"0"`
}

Verbose provides a --verbose/-v count flag for verbosity levels.

The default is 0 (quiet). Each -v increments the count: -v is 1, -vv is 2, -vvv is 3. This is the standard Unix convention for verbosity.

Usage:

type Options struct {
    flagkit.Verbose
}

// In RunE:
if opts.Verbose.Level > 1 {
    // extra debug output
}

func (*Verbose) Attach

func (o *Verbose) Attach(c *cobra.Command) error

Attach implements structcli.Options.

type ZapLogLevel

type ZapLogLevel struct {
	LogLevel zapcore.Level `flag:"log-level" flagdescr:"Set log level" default:"info" flagenv:"true" flaggroup:"Logging"`
}

ZapLogLevel provides a --log-level flag backed by zapcore.Level.

The default is info. zapcore.Level is registered as an integer enum by structcli's built-in init(), so no additional registration is needed.

Usage:

type Options struct {
    flagkit.ZapLogLevel
    Host string `flag:"host" flagdescr:"Server host"`
}

func (*ZapLogLevel) Attach

func (o *ZapLogLevel) Attach(c *cobra.Command) error

Attach implements structcli.Options.

Jump to

Keyboard shortcuts

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