Documentation
¶
Overview ¶
cmder is a simple and flexible library for building command-line interfaces in Go. If you're coming from Cobra and have used it for any length of time, you have surely had your fair share of difficulties with the library. cmder will feel quite a bit more comfortable and easy to use, and the wide range of examples throughout the project should help you get started.
cmder takes a very opinionated approach to building command-line interfaces. The library will help you define, structure and execute your commands, but that's about it. cmder embraces simplicity because sometimes, less is better.
To define a new command, simply define a type that implements the Command interface. If you want your command to have additional behaviour like flags or subcommands, simply implement the appropriate interfaces.
- Bring your own types. cmder doens't force you to use special command structs. As long as you implement our narrow interfaces, you're good to go!
- cmder is unobtrustive. Define your command and execute it. Simplicity above all else!
- cmder is totally stateless making it super easy to unit test your commands. This isn't the case in other libraries.
- We take great pride in our documentation. If you find anything unclear, please let us know so we can fix it.
To get started, see Command and Execute.
For POSIX/GNU flag parsing, see package flag.
Index ¶
- Constants
- Variables
- func Execute(ctx context.Context, cmd Command, op ...ExecuteOption) error
- type BaseCommand
- func (c BaseCommand) Destroy(ctx context.Context, args []string) error
- func (c BaseCommand) ExampleText() string
- func (c BaseCommand) HelpText() string
- func (c BaseCommand) Hidden() bool
- func (c BaseCommand) Initialize(ctx context.Context, args []string) error
- func (c BaseCommand) InitializeFlags(fs *flag.FlagSet)
- func (c BaseCommand) Name() string
- func (c BaseCommand) Run(ctx context.Context, args []string) error
- func (c BaseCommand) ShortHelpText() string
- func (c BaseCommand) Subcommands() []Command
- func (c BaseCommand) UsageLine() string
- type Command
- type Documented
- type ExecuteOption
- type ExecuteOptions
- type FlagInitializer
- type RootCommand
- type Runnable
- type RunnableLifecycle
Examples ¶
Constants ¶
const CobraUsageTemplate = `` /* 1273-byte string literal not displayed */
Text template for rendering command usage information in a format similar to that of the popular github.com/spf13/cobra library.
const StdFlagUsageTemplate = `usage: {{ .Command.UsageLine }}
{{ flagusage . }}`
Text template for rendering command usage information in a minimal format similar to that of the flag library.
Variables ¶
var ( // Returned when a [Command] provided to [Execute] is illegal. ErrIllegalCommandConfiguration = errors.New("cmder: illegal command configuration") // Returned when an [ExecuteOption] provided to [Execute] is illegal. ErrIllegalExecuteOptions = errors.New("cmder: illegal command execution option") )
var UsageOutputWriter io.Writer = os.Stderr
The default writer for command usage information. Standard error is recommended, but you can override this if needed (particularly useful in tests).
var UsageTemplate = CobraUsageTemplate
The text template for rendering command usage information.
Functions ¶
func Execute ¶
func Execute(ctx context.Context, cmd Command, op ...ExecuteOption) error
Execute runs a Command.
Execution Lifecycle ¶
When executing a command, Execute will call the Runnable Run() routine of your command. If the command also implements RunnableLifecycle, the RunnableLifecycle Initialize() and Destroy() routines will be invoked before and after calling Run().
If the command implements RootCommand and a subcommand is invoked, Execute will invoke the RunnableLifecycle routines of parent and child commands:
- Root RunnableLifecycle Initialize()
- Child RunnableLifecycle Initialize()
- Child Runnable Run()
- Child RunnableLifecycle Destroy()
- Root RunnableLifecycle Destroy()
If a command implements RootCommand but the first argument passed to the command doesn't match a recognized child command Name(), the Run() routine will be executed.
Error Handling ¶
Whenever a lifecycle routine (Initialize(), Run(), Destroy()) returns a non-nil error, execution is aborted immediately and the error is returned at once. For example, returning an error from Run() will prevent execution of Destroy() of the current command and any parents.
Execute may return ErrIllegalCommandConfiguration or ErrIllegalExecuteOptions if a command is misconfigured or options are invalid.
Command Contexts ¶
A context.Context derived from ctx is passed to all lifecycle routines. The context is cancelled when Execute returns. Commands should use this context to manage their resources correctly.
Execution Options ¶
Execute accepts one or more ExecuteOption options. You can provide these options to tweak the behaviour of Execute.
Flag Initialization ¶
If the command also implements FlagInitializer, InitializeFlags() will be invoked to register additional command-line flags. Each command/subcommand is given a unique flag.FlagSet. Help flags ('-h', '--help') are configured automatically and must not be set by the application.
Usage and Help Texts ¶
Whenever the user provides the '-h' or '--help' flag at the command line, Execute will display command usage and exit. The format of the help text can be adjusted by configuring UsageTemplate. By default, usage information will be written to stderr, but this can be adjusted by setting UsageOutputWriter.
Types ¶
type BaseCommand ¶
type BaseCommand struct {
// The command name. See Name() in [Command].
CommandName string
// Optional function invoked by the default InitializeFlags() function.
InitFlagsFunc func(*flag.FlagSet)
// Optional function invoked by the default Initialize() function.
InitFunc func(context.Context, []string) error
// Optional function invoked by the default Run() function.
RunFunc func(context.Context, []string) error
// Optional function invoked by the default Destroy() function.
DestroyFunc func(context.Context, []string) error
// Subcommands for this command, if applicable. See [RootCommand].
Children []Command
// The usage line. See UsageLine() in [Documented].
Usage string
// The short help line. See ShortHelpText() in [Documented].
ShortHelp string
// Documentation for your command. See HelpText() in [Documented].
Help string
// Usage examples for your command. See ExampleText() in [Documented].
Examples string
// Whether this command is hidden in help and usage texts. See Hidden() in [Documented].
IsHidden bool
}
BaseCommand is an implementation of the Command, RunnableLifecycle, RootCommand and FlagInitializer interfaces and may be embedded in your command types to reduce boilerplate.
Example ¶
package main
import (
"context"
"fmt"
"github.com/brandon1024/cmder"
)
const BaseCommandExampleHelpText = `
'base-command' demonstrates how to build commands and subcommands with BaseCommand.
`
const BaseCommandExampleExamples = `
# broadcast hello to the world
base-command from cmder
`
type BaseCommandExample struct {
cmder.BaseCommand
}
func (c *BaseCommandExample) Run(ctx context.Context, args []string) error {
fmt.Printf("%s: %v\n", c.Name(), args)
return nil
}
func main() {
cmd := &BaseCommandExample{
BaseCommand: cmder.BaseCommand{
CommandName: "base-command",
Usage: "base-command [<args>...]",
ShortHelp: "Simple demonstration of BaseCommand",
Help: BaseCommandExampleHelpText,
Examples: BaseCommandExampleExamples,
Children: []cmder.Command{
&cmder.BaseCommand{
CommandName: "child",
Usage: "child [<args>...]",
ShortHelp: "A child command with simple behaviour",
Help: "I'm a simple subcommand with simple behaviour!",
RunFunc: func(ctx context.Context, args []string) error {
fmt.Printf("child: %v\n", args)
return nil
},
},
},
},
}
args := []string{"child", "cmder"}
if err := cmder.Execute(context.Background(), cmd, cmder.WithArgs(args)); err != nil {
fmt.Printf("unexpected error occurred: %v", err)
}
}
Output: child: [cmder]
func (BaseCommand) Destroy ¶
func (c BaseCommand) Destroy(ctx context.Context, args []string) error
Destroy runs BaseCommand DestroyFunc, if not nil.
See RunnableLifecycle.
func (BaseCommand) ExampleText ¶
func (c BaseCommand) ExampleText() string
ExampleText returns BaseCommand Examples.
See Documented.
func (BaseCommand) HelpText ¶
func (c BaseCommand) HelpText() string
HelpText returns BaseCommand Help.
See Documented.
func (BaseCommand) Hidden ¶
func (c BaseCommand) Hidden() bool
Hidden returns BaseCommand Hidden.
See Documented.
func (BaseCommand) Initialize ¶
func (c BaseCommand) Initialize(ctx context.Context, args []string) error
Initialize runs BaseCommand InitFunc, if not nil.
See RunnableLifecycle.
func (BaseCommand) InitializeFlags ¶
func (c BaseCommand) InitializeFlags(fs *flag.FlagSet)
InitializeFlags runs BaseCommand InitFlagsFunc, if not nil.
See FlagInitializer.
func (BaseCommand) Name ¶
func (c BaseCommand) Name() string
Name returns BaseCommand CommandName.
See Command.
func (BaseCommand) Run ¶
func (c BaseCommand) Run(ctx context.Context, args []string) error
Run runs BaseCommand RunFunc, if not nil.
See Runnable.
func (BaseCommand) ShortHelpText ¶
func (c BaseCommand) ShortHelpText() string
ShortHelpText returns BaseCommand ShortHelp.
See Documented.
func (BaseCommand) Subcommands ¶
func (c BaseCommand) Subcommands() []Command
Subcommands returns BaseCommand Children.
See RootCommand.
func (BaseCommand) UsageLine ¶
func (c BaseCommand) UsageLine() string
UsageLine returns BaseCommand Usage.
See Documented.
type Command ¶
type Command interface {
// All commands are [Runnable] and implement a Run routine.
Runnable
// Great tools come with great documentation. All commands need to provide documentation, which is used when
// rendering usage and help texts.
Documented
// Name returns the name of this command.
Name() string
}
Command is the fundamental interface implemented by types that are runnable commands or subcommands. Commands can be executed with Execute.
Concrete types can implement additional interfaces to configure additional behaviour, like setup/teardown routines, subcommands, command-line flags, and other behaviour:
- If you want to configure setup and teardown routines for a command, see RunnableLifecycle.
- If your command has subcommands, see RootCommand.
- If your command has command-life flags and switches, see FlagInitializer.
Example ¶
package main
import (
"context"
"fmt"
"github.com/brandon1024/cmder"
)
const HelloWorldCommandUsageLine = `hello-world [<args>...]`
const HelloWorldCommandShortHelpText = `Simple demonstration of cmder`
const HelloWorldCommandHelpText = `
'hello-world' demonstrates the simplest usage of cmder. This example defines a single command 'hello-world' that
implements the Runnable and Documented interfaces.
`
const HelloWorldCommandExamples = `
# broadcast hello to the world
hello-world from cmder
`
type HelloWorldCommand struct{}
func (c *HelloWorldCommand) Name() string {
return "hello-world"
}
func (c *HelloWorldCommand) Run(ctx context.Context, args []string) error {
fmt.Printf("%s: %v\n", c.Name(), args)
return nil
}
func (c *HelloWorldCommand) UsageLine() string {
return HelloWorldCommandUsageLine
}
func (c *HelloWorldCommand) ShortHelpText() string {
return HelloWorldCommandShortHelpText
}
func (c *HelloWorldCommand) HelpText() string {
return HelloWorldCommandHelpText
}
func (c *HelloWorldCommand) main() string {
return HelloWorldCommandExamples
}
func (c *HelloWorldCommand) Hidden() bool {
return false
}
func main() {
args := []string{"from", "cmder"}
cmd := &HelloWorldCommand{}
if err := cmder.Execute(context.Background(), cmd, cmder.WithArgs(args)); err != nil {
fmt.Printf("unexpected error occurred: %v", err)
}
}
Output: hello-world: [from cmder]
type Documented ¶
type Documented interface {
// UsageLine returns the usage line for your command. Generally, usage lines have a well accepted format:
//
// - [ ] identifies an optional argument or flag. Arguments that are not enclosed in brackets are required.
// - ... identifies arguments or flags that can be provided more than once.
// - | identifies mutually exclusive arguments or flags.
// - ( ) identifies groups of flags or arguments that are required together.
// - < > identifies argument(s) or flag(s).
//
// Here are a few examples:
//
// git add [<options>] [--] <pathspec>...
// kubectl get [(-o|--output=)json|yaml|wide] (TYPE[.VERSION][.GROUP] [NAME | -l label] | TYPE[.VERSION][.GROUP]/NAME ...) [flags] [options]
// crane index filter [flags]
UsageLine() string
// ShortHelpText returns a short-and-sweet one-line description of your command. This is mainly used to summarize
// available subcommands.
ShortHelpText() string
// HelpText returns long usage and help information for your users about this subcommand. Here you can describe the
// behaviour of your command, summarize usage of certain flags and arguments and provide hints on where to find
// additional information. This is akin to the "DESCRIPTION" section you would typically find in a man page.
//
// For a better viewing experience in terminals, consider maintaining consistent line length limits (120 is a good
// target).
HelpText() string
// ExampleText returns motivating usage examples for your command.
ExampleText() string
// Hidden returns a flag indicating whether to mark this command as hidden, preventing it from being rendered in
// help output.
Hidden() bool
}
Documented is implemented by all commands and provides help and usage information for your users.
type ExecuteOptions ¶
type ExecuteOptions struct {
// contains filtered or unexported fields
}
Options used to configure behaviour of Execute.
type FlagInitializer ¶
type FlagInitializer interface {
// InitializeFlags initializes flags. Invoked by [Execute] before any lifecycle routines.
//
// Help flags '-h' and '--help' are registered automatically and will instruct [Execute] to render usage information
// to the [UsageOutputWriter].
//
// See [Execute] for more information.
InitializeFlags(*flag.FlagSet)
}
FlagInitializer is an interface implemented by commands that need to register flags.
Example ¶
package main
import (
"context"
"fmt"
"github.com/brandon1024/cmder"
"github.com/brandon1024/cmder/flag"
)
// === PARENT COMMAND ===
const ParentFlagsCommandUsageLine = `parent-flags [<subcommand>] [<args>...]`
const ParentFlagsCommandShortHelpText = `Example of parent command with flags`
const ParentFlagsCommandHelpText = `
'parent-flags' demonstrates an example of a command with subcommands and flags. Commands can define flags by
implementing the FlagInitializer interface. During execution, flags are parsed at each level in the command tree and
can be accessed by the command's Run routine.
`
const ParentFlagsCommandExamples = `
# run the parent 'Run' routine with flags
parent-flags --option string
# run the child 'Run' routine with flags
parent-flags child-flags --count 1
# run with some additional args
parent-flags --option string hello-world
parent-flags --option string child-flags --count 1 hello-world
`
type ParentFlagsCommand struct {
cmder.BaseCommand
option string
}
func (c *ParentFlagsCommand) Initialize(ctx context.Context, args []string) error {
fmt.Printf("%s: init [%s] %v\n", c.Name(), c.option, args)
return nil
}
func (c *ParentFlagsCommand) Run(ctx context.Context, args []string) error {
fmt.Printf("%s: run [%s] %v\n", c.Name(), c.option, args)
return nil
}
func (c *ParentFlagsCommand) Destroy(ctx context.Context, args []string) error {
fmt.Printf("%s: destroy [%s] %v\n", c.Name(), c.option, args)
return nil
}
func (c *ParentFlagsCommand) InitializeFlags(fs *flag.FlagSet) {
fs.StringVar(&c.option, "option", "", "parent command option string argument")
}
func NewParentFlagsCommand() *ParentFlagsCommand {
return &ParentFlagsCommand{
BaseCommand: cmder.BaseCommand{
CommandName: "parent-flags",
Usage: ParentFlagsCommandUsageLine,
ShortHelp: ParentFlagsCommandShortHelpText,
Help: ParentFlagsCommandHelpText,
Examples: ParentFlagsCommandExamples,
Children: []cmder.Command{
NewChildFlagsCommand(),
},
},
}
}
// === CHILD COMMAND ===
const ChildFlagsCommandUsageLine = `child-flags [<args>...]`
const ChildFlagsCommandShortHelpText = `Example of child command`
const ChildFlagsCommandHelpText = `
'child-flags' is the subcommand of 'parent-flags'.
`
const ChildFlagsCommandExamples = `
# run the child 'Run' routine with flags
parent-flags child-flags --count 1
# run with some additional args
parent-flags --option string child-flags --count 1 hello-world
`
type ChildFlagsCommand struct {
cmder.BaseCommand
count int
}
func (c *ChildFlagsCommand) Initialize(ctx context.Context, args []string) error {
fmt.Printf("%s: init [%d] %v\n", c.Name(), c.count, args)
return nil
}
func (c *ChildFlagsCommand) Run(ctx context.Context, args []string) error {
fmt.Printf("%s: run [%d] %v\n", c.Name(), c.count, args)
return nil
}
func (c *ChildFlagsCommand) Destroy(ctx context.Context, args []string) error {
fmt.Printf("%s: destroy [%d] %v\n", c.Name(), c.count, args)
return nil
}
func (c *ChildFlagsCommand) InitializeFlags(fs *flag.FlagSet) {
fs.IntVar(&c.count, "count", 0, "child command count integer argument")
}
func NewChildFlagsCommand() *ChildFlagsCommand {
return &ChildFlagsCommand{
BaseCommand: cmder.BaseCommand{
CommandName: "child-flags",
Usage: ChildFlagsCommandUsageLine,
ShortHelp: ChildFlagsCommandShortHelpText,
Help: ChildFlagsCommandHelpText,
Examples: ChildFlagsCommandExamples,
},
}
}
// === EXAMPLE ===
func main() {
cmd := NewParentFlagsCommand()
args := []string{"--option", "test=1", "child-flags", "--count", "1", "hello-world"}
if err := cmder.Execute(context.Background(), cmd, cmder.WithArgs(args)); err != nil {
fmt.Printf("unexpected error occurred: %v", err)
}
}
Output: parent-flags: init [test=1] [child-flags --count 1 hello-world] child-flags: init [1] [hello-world] child-flags: run [1] [hello-world] child-flags: destroy [1] [hello-world] parent-flags: destroy [test=1] [child-flags --count 1 hello-world]
type RootCommand ¶
type RootCommand interface {
// Subcommands returns a slice of subcommands of this RootCommand. May return nil or an empty slice to treat this
// command as a leaf command.
Subcommands() []Command
}
RootCommand may be implemented by commands that have subcommands.
Example ¶
package main
import (
"context"
"fmt"
"github.com/brandon1024/cmder"
)
// === PARENT COMMAND ===
const ParentCommandUsageLine = `parent [<subcommand>] [<args>...]`
const ParentCommandShortHelpText = `Example of parent command`
const ParentCommandHelpText = `
'parent' demonstrates an example of a command with subcommands. When executed without any arguments, the parent's Run
routine is executed, but if the child subcommand is provided the child subcommand Run routine will be exeuted instead.
The parent implements RootCommand indicating that it is a root command with runnable subcommands. The child does not
implement RootCommand, indicating it is a leaf command.
In this example, the parent and child commands implement RunnableLifecycle, and their respective init/destroy routines
are invoked in this order:
1. parent Initialize
2. child Initialize
3. child Run
4. child Destroy
5. parent Destroy
`
const ParentCommandExamples = `
# run the parent 'Run' routine
parent
# run the child 'Run' routine
parent child
# run with some additional args
parent hello-world
parent child hello-world
`
type ParentCommand struct {
subcommands []cmder.Command
}
func (c *ParentCommand) Name() string {
return "parent"
}
func (c *ParentCommand) Initialize(ctx context.Context, args []string) error {
fmt.Printf("%s: init %v\n", c.Name(), args)
return nil
}
func (c *ParentCommand) Run(ctx context.Context, args []string) error {
fmt.Printf("%s: run %v\n", c.Name(), args)
return nil
}
func (c *ParentCommand) Destroy(ctx context.Context, args []string) error {
fmt.Printf("%s: destroy %v\n", c.Name(), args)
return nil
}
func (c *ParentCommand) UsageLine() string {
return ParentCommandUsageLine
}
func (c *ParentCommand) ShortHelpText() string {
return ParentCommandShortHelpText
}
func (c *ParentCommand) HelpText() string {
return ParentCommandHelpText
}
func (c *ParentCommand) main() string {
return ParentCommandExamples
}
func (c *ParentCommand) Hidden() bool {
return false
}
func (c *ParentCommand) Subcommands() []cmder.Command {
return c.subcommands
}
// === CHILD COMMAND ===
const ChildCommandUsageLine = `child [<args>...]`
const ChildCommandShortHelpText = `Example of child command`
const ChildCommandHelpText = `
'child' is the subcommand of 'parent'.
`
const ChildCommandExamples = `
# run the child 'Run' routine
parent child
# run with some additional args
parent child hello-world
`
type ChildCommand struct{}
func (c *ChildCommand) Name() string {
return "child"
}
func (c *ChildCommand) Initialize(ctx context.Context, args []string) error {
fmt.Printf("%s: init %v\n", c.Name(), args)
return nil
}
func (c *ChildCommand) Run(ctx context.Context, args []string) error {
fmt.Printf("%s: run %v\n", c.Name(), args)
return nil
}
func (c *ChildCommand) Destroy(ctx context.Context, args []string) error {
fmt.Printf("%s: destroy %v\n", c.Name(), args)
return nil
}
func (c *ChildCommand) UsageLine() string {
return ChildCommandUsageLine
}
func (c *ChildCommand) ShortHelpText() string {
return ChildCommandShortHelpText
}
func (c *ChildCommand) HelpText() string {
return ChildCommandHelpText
}
func (c *ChildCommand) main() string {
return ChildCommandExamples
}
func (c *ChildCommand) Hidden() bool {
return false
}
// === EXAMPLE ===
func main() {
cmd := &ParentCommand{
subcommands: []cmder.Command{&ChildCommand{}},
}
args := []string{"child", "hello-world"}
if err := cmder.Execute(context.Background(), cmd, cmder.WithArgs(args)); err != nil {
fmt.Printf("unexpected error occurred: %v", err)
}
}
Output: parent: init [child hello-world] child: init [hello-world] child: run [hello-world] child: destroy [hello-world] parent: destroy [child hello-world]
type Runnable ¶
type Runnable interface {
// Run is the main body of your command executed by [Execute].
//
// The given [context.Context] is derived from the context provided to Execute() and is cancelled when Execute()
// returns. Use this context to cleanup resources.
//
// The second argument is the list of command-line arguments and switches that remain after parsing flags.
Run(context.Context, []string) error
}
Runnable is a fundamental interface implemented by commands. The Run routine is what carries out the work of your command.
Concrete types can also implement RunnableLifecycle to carry out any initialization and teardown necessary for your Run() routine.
type RunnableLifecycle ¶
type RunnableLifecycle interface {
// Initialize carries out any initialization needed for this [Command]. Errors returned by Initialize will abort
// execution of the command lifecycle (Run()/Destroy() of this command and parent command(s)).
Initialize(context.Context, []string) error
// Destroy carries out any teardown needed for this [Command]. Errors returned by Destroy will abort execution of
// the command lifecycle (Destroy of this command and parent command(s)).
Destroy(context.Context, []string) error
}
RunnableLifecycle may be implemented by commands that need to do some work before and after the Runnable Run() routine is invoked.
When executing subcommands, the Initialize() and Destroy() routines of parent commands are also invoked. For instance, if executing subcommand 'child' of command 'parent', lifecycle routines are invoked in this order:
- parent: Initialize()
- child: Initialize()
- child: Run()
- child: Destroy()
- parent: Destroy()
When executing subcommands, the arguments provided to the Initialize() and Destroy() routines of parent commands will include the unprocessed args and flags of child commands. For example:
$ parent --option test child --count 1 arg-1 arg-2
will execute lifecycle routines with the arguments:
- parent: Initialize [child --count 1 arg-1 arg-2]
- child: Initialize [arg-1 arg-2]
- child: Run [arg-1 arg-2]
- child: Destroy [arg-1 arg-2]
- parent: Destroy [child --count 1 arg-1 arg-2]
Example ¶
package main
import (
"context"
"fmt"
"github.com/brandon1024/cmder"
)
const LifecycleCommandUsageLine = `lifecycle [<args>...]`
const LifecycleCommandShortHelpText = `Example command with lifecycle routines`
const LifecycleCommandHelpText = `
'lifecycle' demonstrates a command that implements the RunnableLifecycle interface, defining initialization and
destroy routines.
`
const LifecycleCommandExamples = `
# demonstrate initialization and teardown
lifecycle
`
type LifecycleCommand struct{}
func (c *LifecycleCommand) Name() string {
return "lifecycle"
}
func (c *LifecycleCommand) Initialize(ctx context.Context, args []string) error {
fmt.Println("lifecycle: initializing")
return nil
}
func (c *LifecycleCommand) Run(ctx context.Context, args []string) error {
fmt.Println("lifecycle: running")
return nil
}
func (c *LifecycleCommand) Destroy(ctx context.Context, args []string) error {
fmt.Println("lifecycle: shutting down")
return nil
}
func (c *LifecycleCommand) UsageLine() string {
return LifecycleCommandUsageLine
}
func (c *LifecycleCommand) ShortHelpText() string {
return LifecycleCommandShortHelpText
}
func (c *LifecycleCommand) HelpText() string {
return LifecycleCommandHelpText
}
func (c *LifecycleCommand) main() string {
return LifecycleCommandExamples
}
func (c *LifecycleCommand) Hidden() bool {
return false
}
func main() {
args := []string{}
cmd := &LifecycleCommand{}
if err := cmder.Execute(context.Background(), cmd, cmder.WithArgs(args)); err != nil {
fmt.Printf("unexpected error occurred: %v", err)
}
}
Output: lifecycle: initializing lifecycle: running lifecycle: shutting down
Directories
¶
| Path | Synopsis |
|---|---|
|
examples
|
|
|
hello-world
command
|
|
|
http
command
|
|
|
Package flag is an alternative to the standard library package of the same name.
|
Package flag is an alternative to the standard library package of the same name. |