-
Notifications
You must be signed in to change notification settings - Fork 0
/
commands.go
111 lines (98 loc) · 2.58 KB
/
commands.go
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
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
// Package commands implements the ipfs command interface
//
// Using github.com/ipfs/go-ipfs/commands to define the command line and HTTP
// APIs. This is the interface available to folks using IPFS from outside of
// the Go language.
package commands
import (
"bytes"
"io"
"sort"
"strings"
cmds "github.com/ipfs/go-ipfs/commands"
)
type Command struct {
Name string
Subcommands []Command
Options []Option
}
type Option struct {
Names []string
}
const (
flagsOptionName = "flags"
)
// CommandsCmd takes in a root command,
// and returns a command that lists the subcommands in that root
func CommandsCmd(root *cmds.Command) *cmds.Command {
return &cmds.Command{
Helptext: cmds.HelpText{
Tagline: "List all available commands.",
ShortDescription: `Lists all available commands (and subcommands) and exits.`,
},
Options: []cmds.Option{
cmds.BoolOption(flagsOptionName, "f", "Show command flags").Default(false),
},
Run: func(req cmds.Request, res cmds.Response) {
rootCmd := cmd2outputCmd("ipfs", root)
res.SetOutput(&rootCmd)
},
Marshalers: cmds.MarshalerMap{
cmds.Text: func(res cmds.Response) (io.Reader, error) {
v := res.Output().(*Command)
showOptions, _, _ := res.Request().Option(flagsOptionName).Bool()
buf := new(bytes.Buffer)
for _, s := range cmdPathStrings(v, showOptions) {
buf.Write([]byte(s + "\n"))
}
return buf, nil
},
},
Type: Command{},
}
}
func cmd2outputCmd(name string, cmd *cmds.Command) Command {
opts := make([]Option, len(cmd.Options))
for i, opt := range cmd.Options {
opts[i] = Option{opt.Names()}
}
output := Command{
Name: name,
Subcommands: make([]Command, len(cmd.Subcommands)),
Options: opts,
}
i := 0
for name, sub := range cmd.Subcommands {
output.Subcommands[i] = cmd2outputCmd(name, sub)
i++
}
return output
}
func cmdPathStrings(cmd *Command, showOptions bool) []string {
var cmds []string
var recurse func(prefix string, cmd *Command)
recurse = func(prefix string, cmd *Command) {
newPrefix := prefix + cmd.Name
cmds = append(cmds, newPrefix)
if prefix != "" && showOptions {
for _, options := range cmd.Options {
var cmdOpts []string
for _, flag := range options.Names {
if len(flag) == 1 {
flag = "-" + flag
} else {
flag = "--" + flag
}
cmdOpts = append(cmdOpts, newPrefix+" "+flag)
}
cmds = append(cmds, strings.Join(cmdOpts, " / "))
}
}
for _, sub := range cmd.Subcommands {
recurse(newPrefix+" ", &sub)
}
}
recurse("", cmd)
sort.Sort(sort.StringSlice(cmds))
return cmds
}