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.