summaryrefslogtreecommitdiff
path: root/src/cli/subcommand_group.go
blob: 957e759ddb63aa76d287adbc3b62e0f52ec92468 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
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()
}