Documentation
¶
Overview ¶
Package cleo provides a modern, plugin-based command-line interface framework.
Cleo allows building CLI applications with:
- Hierarchical command structures with sub-commands
- Plugin-based extensibility for custom functionality
- Flexible I/O and filesystem abstraction
- Context-aware execution for cancellation and deadlines
- Structured logging with slog integration
- Memory-efficient operations using object pooling
- Modern Go idioms including functional options pattern
Basic Usage ¶
Create a new command using the functional options pattern:
cmd, err := cleo.NewCmd("myapp",
cleo.WithStdio(iox.Default()),
cleo.WithFS(os.DirFS(".")),
cleo.WithDescription("My awesome CLI app"),
cleo.WithAliases("ma", "myapp"),
)
if err != nil {
log.Fatal(err)
}
Initialize the command with context:
ctx := context.Background()
if err := cmd.InitWithContext(ctx); err != nil {
log.Fatal(err)
}
Plugin System ¶
Cleo supports a flexible plugin system. Plugins can implement various interfaces to provide functionality:
- Exiter: Handle exit operations
- plugins.FSSetable: Receive filesystem instances
- plugins.IOSetable: Receive I/O configurations
- plugins.Needer: Receive plugin collections
Context Support ¶
All major operations support context for cancellation, deadlines, and tracing:
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
defer cancel()
err := cmd.MainWithContext(ctx, "/current/dir", []string{"arg1", "arg2"})
Structured Logging ¶
Cleo integrates with Go's structured logging (slog) package:
logger := slog.New(slog.NewJSONHandler(os.Stdout, nil))
cmd, err := cleo.NewCmd("myapp", cleo.WithLogger(logger))
Memory Efficiency ¶
Cleo uses object pooling internally to reduce garbage collection pressure when dealing with plugin collections and other frequently allocated objects.
Error Handling ¶
Cleo provides typed errors for common conditions:
if errors.Is(err, cleo.ErrNilCommand) {
// Handle nil command error
}
Available error types:
- ErrNilCommand: Command is nil
- ErrNilFS: Filesystem is nil
- ErrEmptyCommandName: Command name is empty
- ErrNilSubCommand: Sub-command is nil
- ErrNoCommand: No command specified
- ErrNoCommands: No commands registered
- ErrUnknownCommand: Unknown command specified
Index ¶
- Variables
- func Exit(cmd plugins.Stdioer, code int, err error)
- type Aliaser
- type Cmd
- func (cmd *Cmd) CmdAliases() []string
- func (cmd *Cmd) CmdName() string
- func (cmd *Cmd) Description() string
- func (cmd *Cmd) Exit(code int) error
- func (cmd *Cmd) ExitWithContext(ctx context.Context, code int) error
- func (cmd *Cmd) FileSystem() (fs.FS, error)
- func (cmd *Cmd) Init() error
- func (cmd *Cmd) InitWithContext(ctx context.Context) error
- func (cmd *Cmd) Logger() *slog.Logger
- func (cmd *Cmd) Main(ctx context.Context, pwd string, args []string) error
- func (cmd *Cmd) MainWithContext(ctx context.Context, pwd string, args []string) error
- func (cmd *Cmd) MarshalJSON() ([]byte, error)
- func (cmd *Cmd) PluginFeeder() plugins.FeederFn
- func (cmd *Cmd) PluginName() string
- func (cmd *Cmd) ScopedPlugins() plugins.Plugins
- func (cmd *Cmd) SetFileSystem(cab fs.FS) error
- func (cmd *Cmd) SetStdio(oi iox.IO) error
- func (cmd *Cmd) Stdio() iox.IO
- func (cmd *Cmd) String() string
- func (cmd *Cmd) SubCommands() []Commander
- type Commander
- type ContextualCommander
- type ContextualExiter
- type ContextualInitializer
- type Describer
- type Env
- type ErrUnknownCommand
- type Exiter
- type Logger
- type ModernCommander
- type Namer
- type Option
- func WithAliases(aliases ...string) Option
- func WithDescription(desc string) Option
- func WithExitFunction(exitFn func(int) error) Option
- func WithFS(filesystem fs.FS) Option
- func WithLogger(logger *slog.Logger) Option
- func WithPluginFeeder(feeder plugins.FeederFn) Option
- func WithStdio(io iox.IO) Option
- func WithSubCommand(name string, subcmd Commander) Option
Constants ¶
This section is empty.
Variables ¶
var ( ErrNoCommand = errors.New("no command specified") ErrNoCommands = errors.New("no commands registered") ErrNilCommand = errors.New("nil command") ErrNilFS = errors.New("fs.FS is nil") ErrEmptyCommandName = errors.New("empty command name") ErrNilSubCommand = errors.New("nil sub-command") )
Common errors
Functions ¶
Types ¶
type Aliaser ¶
type Aliaser interface {
CmdAliases() []string
}
Aliaser provides command aliasing functionality.
type Cmd ¶
type Cmd struct {
iox.IO // IO to be used by the command
fs.FS // FS to be used by the command
Aliases []string // Aliases for the command
Commands map[string]Commander // Sub commands for the command
Feeder plugins.FeederFn // Plugins for the command
Name string // Name of the command
Desc string // Description of the command
ExitFn func(int) error // ExitFn is used by the Exit method.
// contains filtered or unexported fields
}
func (*Cmd) CmdAliases ¶
CmdAliases returns the aliases for the command.
func (*Cmd) Description ¶
func (*Cmd) ExitWithContext ¶
ExitWithContext exits the command with the given code, using the provided context.
func (*Cmd) Init ¶
Init will initialize the command. It should be called before the command is used.
func (*Cmd) InitWithContext ¶
InitWithContext will initialize the command with the given context. It should be called before the command is used.
func (*Cmd) MainWithContext ¶
MainWithContext is the main entry point for the command with context support. NEEDS TO BE IMPLEMENTED
func (*Cmd) MarshalJSON ¶
MarshalJSON returns a JSON representation of the command.
func (*Cmd) PluginFeeder ¶
Plugins will provider a single FeederFn that will return all of the plugins that are available to the command.
func (*Cmd) ScopedPlugins ¶
ScopedPlugins returns the plugins scoped to the command. If the plugins include the current command, it will be removed from the returned list.
func (*Cmd) SubCommands ¶
SubCommands returns the sub-commands for the command.
type ContextualCommander ¶
type ContextualCommander interface {
plugcmd.Commander
MainWithContext(ctx context.Context, pwd string, args []string) error
}
ContextualCommander extends the base Commander with context support.
type ContextualExiter ¶
ContextualExiter provides context-aware exit functionality.
type ContextualInitializer ¶
ContextualInitializer provides context-aware initialization.
type Describer ¶
type Describer interface {
Description() string
}
Describer provides command description functionality.
type ErrUnknownCommand ¶
type ErrUnknownCommand string
func (ErrUnknownCommand) Error ¶
func (e ErrUnknownCommand) Error() string
type ModernCommander ¶
type ModernCommander interface {
Namer
Aliaser
Describer
Logger
ContextualCommander
ContextualExiter
ContextualInitializer
}
ModernCommander combines all the modern interfaces for a full-featured command.
type Option ¶
Option represents a functional option for configuring a Cmd.
func WithAliases ¶
WithAliases sets the aliases for the command.
func WithDescription ¶
WithDescription sets the description for the command.
func WithExitFunction ¶
WithExitFunction sets the exit function for the command.
func WithLogger ¶
WithLogger sets the logger for the command.
func WithPluginFeeder ¶
WithPluginFeeder sets the plugin feeder for the command.
func WithSubCommand ¶
WithSubCommand adds a sub-command to the command.