2017-11-28 20:44:01 +00:00
|
|
|
package command
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
"os"
|
|
|
|
"os/signal"
|
|
|
|
"syscall"
|
|
|
|
|
2021-06-03 16:16:45 +00:00
|
|
|
mcli "github.com/mitchellh/cli"
|
|
|
|
|
|
|
|
"github.com/hashicorp/consul/command/cli"
|
2017-11-28 20:44:01 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
// 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
|
|
|
|
}
|
|
|
|
|
2021-06-03 16:16:45 +00:00
|
|
|
// CommandsFromRegistry returns a realized mapping of available CLI commands in a format that
|
2017-11-28 20:44:01 +00:00
|
|
|
// the CLI class can consume. This should be called after all registration is
|
|
|
|
// complete.
|
2021-06-03 16:16:45 +00:00
|
|
|
func CommandsFromRegistry(ui cli.Ui) map[string]mcli.CommandFactory {
|
|
|
|
m := make(map[string]mcli.CommandFactory)
|
2017-11-28 20:44:01 +00:00
|
|
|
for name, fn := range registry {
|
|
|
|
thisFn := fn
|
2021-06-03 16:16:45 +00:00
|
|
|
m[name] = func() (mcli.Command, error) {
|
2017-11-28 20:44:01 +00:00
|
|
|
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
|
|
|
|
|
|
|
|
// 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
|
|
|
|
}
|