summaryrefslogtreecommitdiff
path: root/src/cli/subcommand_group.go
diff options
context:
space:
mode:
Diffstat (limited to 'src/cli/subcommand_group.go')
-rw-r--r--src/cli/subcommand_group.go56
1 files changed, 56 insertions, 0 deletions
diff --git a/src/cli/subcommand_group.go b/src/cli/subcommand_group.go
new file mode 100644
index 0000000..957e759
--- /dev/null
+++ b/src/cli/subcommand_group.go
@@ -0,0 +1,56 @@
+package cli
+
+import (
+ "errors"
+ "flag"
+ "fmt"
+ "io"
+ "strings"
+)
+
+var ErrUnknownCommand = errors.New("error: unknown command")
+
+type SubcommandFunc = func(*flag.FlagSet) error
+
+type Subcommand struct {
+ FlagSet *flag.FlagSet
+ Usage string
+ Func SubcommandFunc
+}
+
+type SubcommandGroup struct {
+ subcommands map[string]Subcommand
+ output io.Writer
+ errorHandling flag.ErrorHandling
+}
+
+func NewSubcommandGroup(output io.Writer, errorHandling flag.ErrorHandling) SubcommandGroup {
+ return SubcommandGroup{subcommands: make(map[string]Subcommand), output: output, errorHandling: errorHandling}
+}
+
+func (sg *SubcommandGroup) AddSubcommand(name string, usage string, fn SubcommandFunc) {
+ fs := flag.NewFlagSet(name, sg.errorHandling)
+ fs.SetOutput(sg.output)
+ sg.subcommands[name] = Subcommand{
+ FlagSet: fs,
+ Usage: usage,
+ Func: fn,
+ }
+}
+
+func (sg SubcommandGroup) ExecSubcommand(name string) error {
+ cmd, ok := sg.subcommands[name]
+ if !ok {
+ return ErrUnknownCommand
+ }
+ return cmd.Func(cmd.FlagSet)
+}
+
+func (sg SubcommandGroup) Usage() string {
+ var b strings.Builder
+ b.WriteString(" subcommands:\n")
+ for _, cmd := range sg.subcommands {
+ fmt.Fprintf(&b, " %s: %s\n", cmd.FlagSet.Name(), cmd.Usage)
+ }
+ return b.String()
+}