command

package module
v0.2.4 Latest Latest
Warning

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

Go to latest
Published: Mar 20, 2026 License: Unlicense Imports: 12 Imported by: 0

README

seahax.com/go/command

Parse, decode, and validate command line arguments.

Documentation

Index

Constants

This section is empty.

Variables

Functions

func FieldIterator

func FieldIterator(structType reflect.Type) iter.Seq[Field]

Return a new Seq that yields each visable and exported struct field that is tagged with the "flag" tag.

func RunAndExit

func RunAndExit[T any](name string, description string, action func(opts *T) error, modifiers ...Modifier)

Run a command with the process arguments and exit with an appropriate status code.

func RunArgsAndExit

func RunArgsAndExit[T any](name string, description string, action func(opts *T) error, args []string, modifiers ...Modifier)

Run a command with the provided arguments and exit with an appropriate status code.

Types

type Command

type Command[T any] struct {
	// contains filtered or unexported fields
}

Command definition including the struct type, action to run, subcommands, help texts, etc.

func Namespace added in v0.2.0

func Namespace(name string, summary string, modifiers ...Modifier) Command[namespaceOpts]

Create a new Command that does not have an action and requires a subcommand.

func New

func New[T any](name string, summary string, action func(opts *T) error, modifiers ...Modifier) Command[T]

Create a new Command.

func (*Command[T]) AddEpilogue added in v0.1.0

func (c *Command[T]) AddEpilogue(epilogue string)

func (*Command[T]) AddPrologue added in v0.1.0

func (c *Command[T]) AddPrologue(prologue string)

func (*Command[T]) AddSubcommand added in v0.1.0

func (c *Command[T]) AddSubcommand(subcommand Subcommand)

func (*Command[T]) AddUsage added in v0.1.0

func (c *Command[T]) AddUsage(usage string)

func (Command[T]) Decoder

func (c Command[T]) Decoder() Decoder

func (Command[T]) Epilogue

func (c Command[T]) Epilogue() iter.Seq[string]

func (Command[T]) Fullname

func (c Command[T]) Fullname() string

Full name of the command, including all parent commands.

func (Command[T]) Helper

func (c Command[T]) Helper() Helper

func (Command[T]) Modify added in v0.1.0

func (c Command[T]) Modify(parent CommandMutable)

Add this command as a subcommand to the provided parent command.

func (Command[T]) Name

func (c Command[T]) Name() string

func (Command[T]) Names added in v0.2.4

func (c Command[T]) Names() iter.Seq[string]

func (Command[T]) Output

func (c Command[T]) Output() io.Writer

Get the non-nil Output writer, defaulting to os.Stderr if no writer is explicitly set.

func (Command[T]) Parent added in v0.1.0

func (c Command[T]) Parent() CommandImmutable

func (Command[T]) PrintHelp

func (c Command[T]) PrintHelp()

Print command help text to the output writer.

func (Command[T]) Prologue

func (c Command[T]) Prologue() iter.Seq[string]

func (Command[T]) Run

func (c Command[T]) Run() *Error

Run the command with the process arguments.

func (Command[T]) RunAndExit

func (c Command[T]) RunAndExit()

Run the command with the process arguments and exit with an appropriate status code.

func (Command[T]) RunArgs

func (c Command[T]) RunArgs(args []string) *Error

Run the command with the provided arguments.

func (Command[T]) RunArgsAndExit

func (c Command[T]) RunArgsAndExit(args []string)

Run the command with the provided arguments and exit with an appropriate status code.

func (Command[T]) RunAsSubcommand

func (c Command[T]) RunAsSubcommand(parent CommandImmutable, args []string) *Error

Run the command as a subcommand, inheriting the parent command's output writer and name.

func (*Command[T]) SetDecoder added in v0.1.0

func (c *Command[T]) SetDecoder(decoder Decoder)

func (*Command[T]) SetEpilogue added in v0.1.0

func (c *Command[T]) SetEpilogue(epilogue ...string)

func (*Command[T]) SetHelper added in v0.1.0

func (c *Command[T]) SetHelper(helper Helper)

func (*Command[T]) SetName added in v0.1.0

func (c *Command[T]) SetName(name string)

func (*Command[T]) SetOutput added in v0.1.0

func (c *Command[T]) SetOutput(output io.Writer)

func (*Command[T]) SetPrologue added in v0.1.0

func (c *Command[T]) SetPrologue(prologue ...string)

func (*Command[T]) SetSubcommands added in v0.1.0

func (c *Command[T]) SetSubcommands(subcommands ...Subcommand)

func (*Command[T]) SetSummary added in v0.1.0

func (c *Command[T]) SetSummary(summary string)

func (*Command[T]) SetUsage added in v0.1.0

func (c *Command[T]) SetUsage(usage ...string)

func (*Command[T]) SetValidator added in v0.1.0

func (c *Command[T]) SetValidator(validator Validator)

func (Command[T]) String

func (c Command[T]) String() string

Get command help text.

func (Command[T]) Subcommands

func (c Command[T]) Subcommands() iter.Seq[CommandImmutable]

func (Command[T]) Summary

func (c Command[T]) Summary() string

func (Command[T]) Type added in v0.1.0

func (c Command[T]) Type() reflect.Type

func (Command[T]) Usage

func (c Command[T]) Usage() iter.Seq[string]

func (Command[T]) Validator

func (c Command[T]) Validator() Validator

type CommandImmutable added in v0.1.0

type CommandImmutable interface {
	Type() reflect.Type
	Parent() CommandImmutable
	Name() string
	Names() iter.Seq[string]
	Fullname() string
	Summary() string
	Usage() iter.Seq[string]
	Prologue() iter.Seq[string]
	Epilogue() iter.Seq[string]
	Subcommands() iter.Seq[CommandImmutable]
	PrintHelp()
	String() string
	Output() io.Writer
	Helper() Helper
	Decoder() Decoder
	Validator() Validator
}

type CommandMutable added in v0.1.0

type CommandMutable interface {
	CommandImmutable

	SetName(name string)
	SetSummary(summary string)

	SetUsage(usage ...string)
	AddUsage(usage string)

	SetPrologue(prologue ...string)
	AddPrologue(prologue string)

	SetEpilogue(epilogue ...string)
	AddEpilogue(epilogue string)

	SetSubcommands(subcommands ...Subcommand)
	AddSubcommand(subcommand Subcommand)

	SetOutput(output io.Writer)
	SetHelper(helper Helper)
	SetDecoder(decoder Decoder)
	SetValidator(validator Validator)
}

type Decode

type Decode func(value string, targetType reflect.Type) (decodedValue any, err error)

Convert a string to a value of the given type.

func (Decode) Decode

func (d Decode) Decode(value string, targetType reflect.Type) (decodedValue any, err error)

type Decoder

type Decoder interface {
	// Convert a string to a value of the given type.
	Decode(value string, targetType reflect.Type) (decodedValue any, err error)
}

Convert a string to a value of the given type.

var DecoderDefault Decoder = Decode(func(value string, targetType reflect.Type) (any, error) {
	return shorthand.Decode(value, targetType)
})

Default decoder.

type Error

type Error struct {
	IsParseFailure bool
	// contains filtered or unexported fields
}

Error returned by Command.Run and Command.RunArgs.

func NewError

func NewError(err error, isParseFailure bool) *Error

Create a new Error.

func Run

func Run[T any](name string, description string, action func(opts *T) error, modifiers ...Modifier) *Error

Run a command with the process arguments.

func RunArgs

func RunArgs[T any](name string, description string, action func(opts *T) error, args []string, modifiers ...Modifier) *Error

Run a command with the provided arguments.

func (*Error) Command added in v0.2.1

func (e *Error) Command() CommandImmutable

func (*Error) Unwrap

func (e *Error) Unwrap() error

Unwrap the error to get the original error (ie. the cause).

type Field

type Field struct {
	// contains filtered or unexported fields
}

Field represents a struct field tagged with the "flag" tag.

func NewField

func NewField(structPtrType reflect.Type, field reflect.StructField) Field

Create a new Field.

func (Field) DecodeType

func (f Field) DecodeType() reflect.Type

Get the element type of the struct field. If the struct field is a slice, return the slice element type. This is the type used to decode individual values.

func (Field) Flag

func (f Field) Flag() string

Get the flag usage (the value of the "flag" tag).

func (Field) FlagNames

func (f Field) FlagNames() iter.Seq[string]

Parse named flag (Field.IsNamedFlag) names from the flag usage (Field.Flag).

func (Field) Help

func (f Field) Help() string

Get the flag help text (the value of the "help" tag).

func (Field) IsNamedFlag

func (f Field) IsNamedFlag() bool

True if the flag usage (Field.Flag) starts with a hyphen, indicating a named flag.

func (Field) IsSlice

func (f Field) IsSlice() bool

True if the struct field is a slice.

func (Field) Set

func (f Field) Set(target reflect.Value, value any)

Set the value of the target struct field. If the struct field is a slice, append the value to the slice.

type Help

type Help func(command CommandImmutable) string

Return a help string for the given CommandImmutable.

func (Help) Help

func (h Help) Help(command CommandImmutable) string

type Helper

type Helper interface {
	// Return a help string for the given [CommandImmutable].
	Help(command CommandImmutable) string
}

Help string factory.

var HelperDefault Helper = Help(func(command CommandImmutable) string {
	b := NewHelperBuilder()
	hasOptions := false
	hasArguments := false
	hasCommands := false

	b.WriteParagraph(command.Summary())

	for prologue := range command.Prologue() {
		b.WriteParagraph(prologue)
	}

	b.WriteListHeading("Options:")
	positionals := []Field{}

	for field := range FieldIterator(command.Type()) {
		help := field.Help()

		if help == "" {

			continue
		}

		if !field.IsNamedFlag() {
			positionals = append(positionals, field)
			continue
		}

		b.WriteListItem(field.Flag(), help)
		hasOptions = true
	}

	b.WriteListHeading("Arguments:")

	for _, field := range positionals {
		b.WriteListItem(field.Flag(), field.Help())
		hasArguments = true
	}

	b.WriteListHeading("Commands:")

	for subcommand := range command.Subcommands() {
		summary := subcommand.Summary()

		if summary != "" {
			hasCommands = true
			b.WriteListItem(subcommand.Name(), summary)
		}
	}

	for usage := range command.Usage() {
		b.WriteUsage(usage)
	}

	if !b.HasUsage() {
		if hasOptions && hasArguments {
			b.WriteUsage(fmt.Sprintf("Usage: %s <options> <arguments>", command.Fullname()))
		} else if hasOptions {
			b.WriteUsage(fmt.Sprintf("Usage: %s <options>", command.Fullname()))
		} else if hasArguments {
			b.WriteUsage(fmt.Sprintf("Usage: %s <arguments>", command.Fullname()))
		}

		if hasCommands {
			b.WriteUsage(fmt.Sprintf("Usage: %s <command> ...", command.Fullname()))
		}
	}

	if !b.HasUsage() {
		b.WriteUsage(fmt.Sprintf("Usage: %s", command.Fullname()))
	}

	for epilogue := range command.Epilogue() {
		b.WriteParagraph(epilogue)
	}

	return b.String()
})

Default help string factory.

type HelperBuilder

type HelperBuilder struct {
	// contains filtered or unexported fields
}

Help string builder.

func NewHelperBuilder

func NewHelperBuilder() HelperBuilder

Create a new HelperBuilder.

func (*HelperBuilder) HasUsage added in v0.1.0

func (h *HelperBuilder) HasUsage() bool

func (*HelperBuilder) String

func (h *HelperBuilder) String() string

Get the result and reset the builder.

func (*HelperBuilder) WriteListHeading

func (h *HelperBuilder) WriteListHeading(s string)

Write a list heading. Deferred until at least one list item is written.

func (*HelperBuilder) WriteListItem

func (h *HelperBuilder) WriteListItem(key string, s string)

Write a list item.

func (*HelperBuilder) WriteParagraph

func (h *HelperBuilder) WriteParagraph(s string)

Write a paragraph.

func (*HelperBuilder) WriteUsage

func (h *HelperBuilder) WriteUsage(s string)

Write a usage line.

type Modifier added in v0.1.0

type Modifier interface {
	Modify(command CommandMutable)
}

type Modify added in v0.1.0

type Modify func(command CommandMutable)

func (Modify) Modify added in v0.1.0

func (m Modify) Modify(command CommandMutable)

type Parser

type Parser struct {
	StructType reflect.Type
	Decoder    Decoder
}

Parse command line arguments defined by struct field tags.

func NewParser

func NewParser(structType reflect.Type, decoder Decoder) Parser

Create a new Parser.

func (Parser) Parse

func (p Parser) Parse(args []string) (parsedPtr any, err error)

Parse the command line arguments and return a new instance of the parser type with the parsed values.

type PlaygroundValidationErrors added in v0.1.0

type PlaygroundValidationErrors validator.ValidationErrors

func (PlaygroundValidationErrors) Error added in v0.1.0

func (PlaygroundValidationErrors) Unwrap added in v0.1.0

func (e PlaygroundValidationErrors) Unwrap() []error

type Subcommand

type Subcommand interface {
	CommandImmutable
	RunAsSubcommand(parent CommandImmutable, args []string) *Error
}

Subcommand interface. All commands are also inherently subcommands.

type Validate

type Validate func(value any) error

Return an error if the value struct is invalid.

func (Validate) Validate

func (v Validate) Validate(value any) error

type Validator

type Validator interface {
	Validate(value any) error
}

Return an error if the value struct is invalid.

var PlaygroundValidator Validator = Validate(func(value any) error {
	if err := PlaygroundValidate.Struct(value); err != nil {
		return PlaygroundValidationErrors(err.(validator.ValidationErrors))
	}

	return nil
})

Validator based on github.com/go-playground/validator/v10. Validation configuration can be applied to the PlaygroundValidate singleton instance that is used by this function.

Jump to

Keyboard shortcuts

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