Documentation
¶
Overview ¶
Package exoskeleton allows you to create modern multi-CLI applications whose subcommands are external to them.
You use it by defining an Entrypoint and a list of paths where external subcommands may be found.
Here's an example:
Assuming we have two executables that respond to `--summary` like this:
$ ~/libexec/rm --summary
Remove directory entries
$ ~/libexec/ls --summary
List directory contents
And a binary, `example`, that is implemented like this:
package main
import (
"os"
"github.com/square/exoskeleton"
)
func main() {
exoskeleton.Exec([]string{os.Getenv("HOME") + "/libexec"})
}
Then our example program will behave like this:
$ ./example
USAGE
example <command> [<args>]
COMMANDS
ls List directory contents
rm Remove directory entries
Run example help <command> to print information on a specific command.
And running `example ls` will forward execution to `~/libexec/ls`.
Index ¶
- Constants
- func CompleteCommands(e *Entrypoint, args, env []string) ([]string, shellcomp.Directive, error)
- func CompleteExec(e *Entrypoint, args, env []string) error
- func CompleteFiles(e *Entrypoint, args, env []string) ([]string, shellcomp.Directive, error)
- func Exec(paths []string, options ...Option)
- func GenerateCompletionScript(name, shell string, w io.Writer) (err error)
- func HelpExec(e *Entrypoint, args, _ []string) error
- func IsEmbedded(command Command) bool
- func IsModule(command Command) bool
- func IsNull(command Command) bool
- func MenuFor(m Module, opts *MenuOptions) (string, []error)
- func Usage(cmd Command) string
- func UsageRelativeTo(cmd Command, m Module) string
- func WhichExec(e *Entrypoint, args, _ []string) error
- type AfterIdentifyFunc
- type Command
- type CommandDescribeError
- type CommandError
- type CommandHelpError
- type CommandNotFoundFunc
- type CommandSummaryError
- type Commands
- type CompleteFunc
- type DiscoveryError
- type EmbeddedCommand
- type EmbeddedModule
- type Entrypoint
- func (e *Entrypoint) Complete(_ *Entrypoint, args, _ []string) (completions []string, directive shellcomp.Directive, err error)
- func (e *Entrypoint) Exec(_ *Entrypoint, rawArgs, env []string) error
- func (e *Entrypoint) GenerateCompletionScript(shell string, w io.Writer) error
- func (e *Entrypoint) Help() (string, error)
- func (e *Entrypoint) Identify(args []string) (Command, []string, error)
- func (e *Entrypoint) Name() string
- func (e *Entrypoint) Parent() Module
- func (e *Entrypoint) Path() string
- func (e *Entrypoint) Subcommands() (Commands, error)
- func (e *Entrypoint) Summary() (string, error)
- type ErrorFunc
- type ExecFunc
- type Menu
- type MenuHeadingForFunc
- type MenuItem
- type MenuItems
- type MenuOptions
- type MenuSection
- type MenuSections
- type Module
- type Option
- func AfterIdentify(fn AfterIdentifyFunc) Option
- func AppendCommands(cmds ...interface{}) Option
- func OnCommandNotFound(fn CommandNotFoundFunc) Option
- func OnError(fn ErrorFunc) Option
- func PrependCommands(cmds ...interface{}) Option
- func WithMaxDepth(value int) Option
- func WithMenuHeadingFor(fn MenuHeadingForFunc) Option
- func WithMenuTemplate(value *template.Template) Option
- func WithModuleMetadataFilename(value string) Option
- func WithName(value string) Option
- type SummaryFunc
- type SymlinkError
Constants ¶
const CompleteHelp = `` /* 969-byte string literal not displayed */
CompleteHelp is the help text for the built-in 'complete' command.
const HelpHelp = `` /* 269-byte string literal not displayed */
HelpHelp is the help text for the built-in 'help' command.
const WhichHelp = `` /* 423-byte string literal not displayed */
WhichHelp is the help text for the built-in 'which' command.
Variables ¶
This section is empty.
Functions ¶
func CompleteCommands ¶
CompleteCommands is a CompleteFunc that provides completions for command names. It is used by commands like 'help' and 'which' which expect their arguments to be command names.
func CompleteExec ¶ added in v1.5.0
func CompleteExec(e *Entrypoint, args, env []string) error
CompleteExec implements the 'complete' command.
func CompleteFiles ¶ added in v1.1.1
CompleteFiles is a CompleteFunc that provides completions for files and paths.
func GenerateCompletionScript ¶
GenerateCompletionScript generates a completion script for the given shell ("bash" or "zsh") and writes it to the given writer.
func HelpExec ¶ added in v1.5.0
func HelpExec(e *Entrypoint, args, _ []string) error
HelpExec implements the 'help' command.
func IsEmbedded ¶ added in v1.1.1
IsEmbedded returns true if the given Command is built into the exoskeleton.
func IsModule ¶ added in v1.1.1
IsModule returns true if the given Command is a Module and false if it is not.
func MenuFor ¶ added in v1.6.0
func MenuFor(m Module, opts *MenuOptions) (string, []error)
MenuFor renders a menu of commands for a Module.
func Usage ¶
Usage returns the usage string for the given command. For example, given the Tidy command in the Go CLI, Usage(Tidy) would be 'go mod tidy'.
func UsageRelativeTo ¶
UsageRelativeTo returns the usage string for the given command relative to the given module. For example, given the Tidy command in the Go CLI ('go mod tidy'), UsageRelativeTo(Tidy, Mod) would be 'tidy' and UsageRelativeTo(Tidy, Go) would be 'mod tidy'.
func WhichExec ¶ added in v1.5.0
func WhichExec(e *Entrypoint, args, _ []string) error
WhichExec implements the 'which' command.
Types ¶
type AfterIdentifyFunc ¶ added in v1.6.0
type AfterIdentifyFunc func(*Entrypoint, Command, []string)
AfterIdentifyFunc is a function that is called after a command is identified. It accepts the Command and the remaining arguments that were not used to identify the command.
type Command ¶
type Command interface {
// Path returns the location of the executable that defines the command.
// For built-in commands, it returns the path to the entrypoint executable itself.
// It is used by the built-in command 'which'.
Path() string
// Name returns the name of the command.
Name() string
// Parent returns the module that contains the command.
//
// For unnamespaced commands, Parent returns the Entrypoint. For the Entrypoint,
// Parent returns nil.
//
// In the Go CLI, 'go test' and 'go mod tidy' are both commands. If modeled with
// Exoskeleton, 'tidy”s Parent would be the 'mod' Module and 'test”s Parent
// would be the entrypoint itself, 'go'.
Parent() Module
// Exec executes the command.
Exec(e *Entrypoint, args, env []string) error
// Complete asks the command to return completions.
// It is used by the built-in command 'complete' which provides shell completions.
Complete(e *Entrypoint, args, env []string) ([]string, shellcomp.Directive, error)
// Summary returns the (short!) description of the command to be displayed
// in menus.
//
// Returns a CommandError if the command does not fulfill the contract
// for providing its summary.
Summary() (string, error)
// Help returns the help text for the command.
//
// Returns a CommandError if the command does not fulfill the contract
// for providing its help.
Help() (string, error)
}
Command is a command in your CLI application.
In the Go CLI, 'go test' and 'go mod tidy' are both commands. Exoskeleton would model 'test' and 'tidy' as Commands. 'tidy' would be nested one level deeper than 'test', beneath a Module named 'mod'.
type CommandDescribeError ¶ added in v1.4.0
type CommandDescribeError struct{ CommandError }
CommandDescribeError indicates that an executable module did not properly respond to `--describe-commands`
type CommandError ¶
CommandError records an error that occurred with a command's implementation of its interface
func (CommandError) Error ¶
func (e CommandError) Error() string
func (CommandError) Unwrap ¶
func (e CommandError) Unwrap() error
type CommandHelpError ¶ added in v1.4.0
type CommandHelpError struct{ CommandError }
CommandHelpError indicates that a command did not properly implement the interface for providing help
type CommandNotFoundFunc ¶
type CommandNotFoundFunc func(*Entrypoint, Command)
CommandNotFoundFunc is a function that accepts a Null Command object. It is called when a command is not found.
type CommandSummaryError ¶ added in v1.4.0
type CommandSummaryError struct{ CommandError }
CommandSummaryError indicates that a command did not properly implement the interface for providing a summary
type Commands ¶
type Commands []Command
type CompleteFunc ¶
CompleteFunc is called when an built-in command is asked to supply shell completions.
type DiscoveryError ¶
DiscoveryError records an error that occurred while discovering commands in a directory.
func (DiscoveryError) Error ¶
func (e DiscoveryError) Error() string
func (DiscoveryError) Unwrap ¶
func (e DiscoveryError) Unwrap() error
type EmbeddedCommand ¶ added in v1.1.0
type EmbeddedCommand struct {
Name string
Summary string
Help string
Exec ExecFunc
Complete CompleteFunc
}
EmbeddedCommand defines a built-in command that can be added to an Entrypoint (as opposed to an executable external to the Entrypoint).
type EmbeddedModule ¶ added in v1.1.0
EmbeddedCommand defines a built-in module that can be added to an Entrypoint (as opposed to a directory external to the Entrypoint).
type Entrypoint ¶
type Entrypoint struct {
// contains filtered or unexported fields
}
Entrypoint is the root of an exoskeleton CLI application.
func New ¶
func New(paths []string, options ...Option) (*Entrypoint, error)
New searches the given paths and constructs an Entrypoint with a list of commands discovered in those paths. It also accepts options that can be used to customize the behavior of the Entrypoint.
func (*Entrypoint) Complete ¶
func (e *Entrypoint) Complete(_ *Entrypoint, args, _ []string) (completions []string, directive shellcomp.Directive, err error)
func (*Entrypoint) Exec ¶
func (e *Entrypoint) Exec(_ *Entrypoint, rawArgs, env []string) error
func (*Entrypoint) GenerateCompletionScript ¶
func (e *Entrypoint) GenerateCompletionScript(shell string, w io.Writer) error
GenerateCompletionScript generates a completion script for the given shell ("bash" or "zsh") and writes it to the given writer.
func (*Entrypoint) Help ¶
func (e *Entrypoint) Help() (string, error)
func (*Entrypoint) Identify ¶
func (e *Entrypoint) Identify(args []string) (Command, []string, error)
Identify identifies the command being invoked.
The function also returns any arguments that were not used to identify the command. For example, if the Go CLI were implemented with Exoskeleton, and we ran it with the rawArgs 'get -u github.com/square/exoskeleton', Identify would return the Get command and the arguments {'-u', 'github.com/square/exoskeleton'}.
If no command is identified, Identify invokes CommandNotFound callbacks and returns NullCommand.
Returns a CommandError if the command does not fulfill the contract for providing its subcommands.
func (*Entrypoint) Name ¶
func (e *Entrypoint) Name() string
func (*Entrypoint) Parent ¶
func (e *Entrypoint) Parent() Module
func (*Entrypoint) Path ¶
func (e *Entrypoint) Path() string
func (*Entrypoint) Subcommands ¶
func (e *Entrypoint) Subcommands() (Commands, error)
func (*Entrypoint) Summary ¶
func (e *Entrypoint) Summary() (string, error)
type ExecFunc ¶
type ExecFunc func(e *Entrypoint, args, env []string) error
ExecFunc is called when an built-in command is run.
type Menu ¶ added in v1.6.0
type Menu struct {
Usage string
HelpUsage string
Sections MenuSections
}
Menu is the data passed to MenuOptions.Template when it is executed.
type MenuHeadingForFunc ¶
MenuHeadingForFunc is a function that is expected to return the heading under which a command should be listed when it is printed in a menu. (The default value is "COMMANDS".)
It accepts the Module whose subcommands are being listed and the Command whose heading should be returned.
type MenuOptions ¶ added in v1.6.0
type MenuOptions struct {
// Depth describes how recursively a menu should be constructed. Its default
// value is 0, which indicates that the menu should list only the commands
// that are descendants of the module. A value of 1 would list descendants one
// level deep, a value of 2 would list descendants two levels deep, etc. A value
// -1 lists all descendants.
Depth int
// HeadingFor accepts a Command the Module the menu is being prepared for
// and returns a string to use as a section heading for the Command.
// The default function returns "COMMANDS".
HeadingFor MenuHeadingForFunc
// SummaryFor accepts a Command and returns its summary and, optionally, an error.
// The default function invokes Summary() on the provided Command.
SummaryFor SummaryFunc
// Template is executed with the constructed exoskeleton.Menu to render
// help content for a Module.
Template *template.Template
}
MenuOptions are the options that control how menus are constructed for modules.
type MenuSection ¶ added in v1.6.0
type MenuSections ¶ added in v1.6.0
type MenuSections []MenuSection
type Module ¶
type Module interface {
Command
// Subcommands returns the list of Commands that are contained by this module.
//
// For example, in the Go CLI, 'go mod' is a Module and its Subcommands would
// be 'download', 'edit', 'graph', 'init', 'tidy', 'vendor', 'verify', and 'why'.
//
// Returns a CommandError if the command does not fulfill the contract
// for providing its subcommands.
Subcommands() (Commands, error)
}
Module is a namespace of commands in your CLI application.
In the Go CLI, 'go mod tidy' is a command. Exoskeleton would module 'mod' as a Module and 'tidy' as a Command that's nested beneath it.
Executing a Module produces a menu of its subcommands.
type Option ¶
type Option interface {
Apply(*Entrypoint)
}
An Option applies optional changes to an Exoskeleton Entrypoint.
func AfterIdentify ¶ added in v1.6.0
func AfterIdentify(fn AfterIdentifyFunc) Option
AfterIdentify registers a callback (AfterIdentifyFunc) to be invoked with any command that is successfully identified.
func AppendCommands ¶ added in v1.1.0
func AppendCommands(cmds ...interface{}) Option
AppendCommands adds new embedded commands to the Entrypoint. The commands are added to the end of the list and will have the lowest precedence: an executable with the same name as one of these commands would override it.
func OnCommandNotFound ¶
func OnCommandNotFound(fn CommandNotFoundFunc) Option
OnCommandNotFound registers a callback (CommandNotFoundFunc) to be invoked when the command a user attempted to execute is not found. The callback is also invoked when the user asks for help on a command that can not be found.
func OnError ¶
OnError registers a callback (ErrorFunc) to be invoked when a nonfatal error occurs.
These are recoverable errors such as
- a broken symlink is encountered in one of the paths being searched
- a command exits unnsuccessfully when invoked with --summary or --help
func PrependCommands ¶ added in v1.1.0
func PrependCommands(cmds ...interface{}) Option
PrependCommands adds new embedded commands to the Entrypoint. The command are added to the front of the list and will have the highest precedence: an executable with the same name as one of these commands would be overridden by it.
func WithMaxDepth ¶
WithMaxDepth sets the maximum depth of the command tree.
A value of 0 prohibits any submodules. All subcommands are leaves of the Entrypoint. (i.e. If the Go CLI were an exoskeleton, 'go doc' would be allowed, 'go mod tidy' would not.)
A value of -1 (the default value) means there is no maximum depth.
func WithMenuHeadingFor ¶
func WithMenuHeadingFor(fn MenuHeadingForFunc) Option
WithMenuHeadingFor allows you to supply a function that determines the heading a Command should be listed under in the main menu.
func WithMenuTemplate ¶ added in v1.6.0
WithMenuTemplate sets the template that will be used to render help for modules. The template will be executed with an instance of exoskeleton.Menu as its data.
func WithModuleMetadataFilename ¶
WithModuleMetadataFilename sets the filename to use for module metadata. (Default: ".exoskeleton")
type SummaryFunc ¶ added in v1.6.0
SummaryFunc is a function that is expected to return the heading
type SymlinkError ¶
SymlinkError records an error that occurred while following a symlink.
func (SymlinkError) Error ¶
func (e SymlinkError) Error() string
func (SymlinkError) Unwrap ¶
func (e SymlinkError) Unwrap() error
Source Files
¶
- builtin_command.go
- builtin_module.go
- command.go
- commands.go
- complete_cmd.go
- completion_scripts.go
- completions.go
- contract.go
- directory_module.go
- discovery.go
- discovery_error.go
- doc.go
- entrypoint.go
- exec.go
- executable_command.go
- executable_module.go
- help_cmd.go
- identification.go
- menu.go
- module.go
- null_command.go
- options.go
- predicates.go
- suggestions.go
- symlink_error.go
- usage.go
- which_cmd.go