89 lines
2.4 KiB
Go
89 lines
2.4 KiB
Go
package command
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
"os/signal"
|
|
"syscall"
|
|
|
|
"github.com/mitchellh/cli"
|
|
)
|
|
|
|
// Factory is a function that returns a new instance of a CLI-sub command.
|
|
type Factory func(cli.Ui) (cli.Command, error)
|
|
|
|
// Register adds a new CLI sub-command to the registry.
|
|
func Register(name string, fn Factory) {
|
|
if registry == nil {
|
|
registry = make(map[string]Factory)
|
|
}
|
|
|
|
if registry[name] != nil {
|
|
panic(fmt.Errorf("Command %q is already registered", name))
|
|
}
|
|
registry[name] = fn
|
|
}
|
|
|
|
// RegisterHidden adds a new CLI sub-command to the registry that won't show up
|
|
// in help or autocomplete.
|
|
func RegisterHidden(name string, fn Factory) {
|
|
if hiddenRegistry == nil {
|
|
hiddenRegistry = make(map[string]Factory)
|
|
}
|
|
|
|
if hiddenRegistry[name] != nil {
|
|
panic(fmt.Errorf("Command %q is already registered", name))
|
|
}
|
|
hiddenRegistry[name] = fn
|
|
}
|
|
|
|
// Map returns a realized mapping of available CLI commands in a format that
|
|
// the CLI class can consume. This should be called after all registration is
|
|
// complete.
|
|
func Map(ui cli.Ui) map[string]cli.CommandFactory {
|
|
return makeCommands(ui, registry)
|
|
}
|
|
|
|
// Map returns a realized mapping of available but hidden CLI commands in a
|
|
// format that the CLI class can consume. This should be called after all
|
|
// registration is complete.
|
|
func MapHidden(ui cli.Ui) map[string]cli.CommandFactory {
|
|
return makeCommands(ui, hiddenRegistry)
|
|
}
|
|
|
|
func makeCommands(ui cli.Ui, reg map[string]Factory) map[string]cli.CommandFactory {
|
|
m := make(map[string]cli.CommandFactory)
|
|
for name, fn := range reg {
|
|
thisFn := fn
|
|
m[name] = func() (cli.Command, error) {
|
|
return thisFn(ui)
|
|
}
|
|
}
|
|
return m
|
|
}
|
|
|
|
// registry has an entry for each available CLI sub-command, indexed by sub
|
|
// command name. This should be populated at package init() time via Register().
|
|
var registry map[string]Factory
|
|
|
|
// hiddenRegistry behaves identically to registry but is for commands that are
|
|
// hidden - i.e. not publically documented in the help or autocomplete.
|
|
var hiddenRegistry map[string]Factory
|
|
|
|
// MakeShutdownCh returns a channel that can be used for shutdown notifications
|
|
// for commands. This channel will send a message for every interrupt or SIGTERM
|
|
// received.
|
|
func MakeShutdownCh() <-chan struct{} {
|
|
resultCh := make(chan struct{})
|
|
signalCh := make(chan os.Signal, 4)
|
|
signal.Notify(signalCh, os.Interrupt, syscall.SIGTERM)
|
|
go func() {
|
|
for {
|
|
<-signalCh
|
|
resultCh <- struct{}{}
|
|
}
|
|
}()
|
|
|
|
return resultCh
|
|
}
|