Documentation ¶
Overview ¶
Package clino provides a simple way to create CLI (command-line interface) tools.
You can create commands to use with this package by implementing its interfaces. It supports the Unix -flag style.
The Command interface contains only a name. However, if you try to run a command that doesn't implement any of the Runnable, Longer, Parent, or Footer interfaces, you are going to get a "missing implementation" error message.
For working with flags, you need to implement the FlagSet interface to a given command. If you need global flags, you can do so by defining Program.GlobalFlags. You can use it for a -verbose, -config, or other application-wide state flags. In example/complex you can see how to use global flags easily.
Example ¶
package main import ( "context" "flag" "fmt" "os" "github.com/henvic/clino" ) // RootCommand is the entrypoint of the application. type RootCommand struct { name string } // Name of the application. func (rc *RootCommand) Name() string { return "app" } // Long description of the application. func (rc *RootCommand) Long() string { return "Example application." } // Flags of the command. func (rc *RootCommand) Flags(flags *flag.FlagSet) { flags.StringVar(&rc.name, "name", "World", "your name") } // Run command. func (rc *RootCommand) Run(ctx context.Context, args ...string) error { fmt.Printf("Hello, %s!\n", rc.name) return nil } func main() { p := clino.Program{ Root: &RootCommand{}, } if err := p.Run(context.Background(), "-name", "Gopher"); err != nil { fmt.Fprintf(os.Stderr, "%+v\n", err) os.Exit(clino.ExitCode(err)) } }
Output: Hello, Gopher!
Index ¶
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func ExitCode ¶
ExitCode from the command for the process to use when exiting. It returns 0 if the error is nil. If the error comes from *exec.Cmd Run, the same child process exit code is used. If the error is ExitError, it returns the Code field. Otherwise, return exit code 1.
func main() { p := clino.Program{ Root: &RootCommand{}, } if err := p.Run(context.Background(), os.Args[1:]...); err != nil { fmt.Fprintf(os.Stderr, "%+v\n", err) os.Exit(clino.ExitCode(err)) } }
Types ¶
type Command ¶
type Command interface {
Name() string
}
Command contains the minimal interface for a command: its name (usage).
You usually want to implement the Runnable interface, except for help-only commands, or when your command has subcommands (implements Parent).
type ExitError ¶
ExitError wraps the error, adding an exit code.
You can use it to exit the process gracefully with a specific exit code when something goes wrong. You should only wrap error when err != nil. You don't need to wrap it if the exit code is *exec.ExitError.
type FlagSet ¶
FlagSet you want to use on your command.
// Flags of the "hello" command. func (hc *HelloCommand) Flags(flags *flag.FlagSet) { flags.StringVar(&hc.name, "name", "World", "your name") }
You need to implement a Flags function like shown and set any flags you want your commands to parse.
type Footer ¶
type Footer interface {
}Footer of a command shown in the "help <command>" output. It is useful for things like printing examples.
type Longer ¶
type Longer interface {
Long() string
}
Longer description or help message for your command. The help command prints the returned value of the Long function as the "help" output of a command.
type Parent ¶
type Parent interface {
Commands() []Command
}
Parent contains all subcommands of a given command.
type PersistentFlagSet ¶ added in v0.0.2
PersistentFlagSet is similar to FlagSet, but flags are inherited by the next commands.
// PersistentFlags of the "main" command. func (mc *MainCommand) PersistentFlags(flags *flag.FlagSet) { flags.BoolVar(&hc.verbose, "verbose", false, "verbose mode") }
You need to implement a Flags function like shown and set any flags you want your commands to parse.
type Program ¶
type Program struct { // Root command is the entrypoint of the program. Root Command // GlobalFlags are flags available to all commands. // // Deprecated: Use PersistentFlags instead. GlobalFlags func(flags *flag.FlagSet) // Output is the default output function to the application. // // If not set when calling Run, os.Stdout is set. // You probably only want to set this for testing. Output io.Writer // contains filtered or unexported fields }
Program you want to run.
You should call the Run function, passing the context, root command, and process arguments.
func (*Program) Run ¶
Run program by processing arguments and executing the invoked command.
Context is passed down to the command to simplify testing and cancelation. Arguments should be the process arguments (os.Args[1:]...) when you call it from main().
Example:
p := clino.Program{ Root: &RootCommand{}, }
if err := p.Run(context.Background(), os.Args[1:]...); err != nil { fmt.Fprintf(os.Stderr, "%+v\n", err) os.Exit(clino.ExitCode(err)) }
type Runnable ¶
Runnable commands are commands that implement the Run function, and you can run it from the command-line. It should receive a context and the command arguments, after parsing any flags. A context is required as we want cancelation to be a first-class citizen. You can rely on the context for canceling long tasks during tests.