cmds2: fixed show help on root + noncallable
Juan Batiz-Benet committed
Nov 12, 2014 at 19:21 UTC
3352aeee15e2c2e703e89c639bc548e003cd74be
5 files changed
+30
-40
cmd/ipfs2/ipfs.go
+2
-2
@@ -6,8 +6,8 @@ import (
6
)
7
8
var Root = &cmds.Command{
9
- Options: commands.Root.Options,
10
- Help: commands.Root.Help,
9
+ Options: commands.Root.Options,
10
+ Helptext: commands.Root.Helptext,
11
}
12
13
var rootSubcommands = map[string]*cmds.Command{
cmd/ipfs2/main.go
+12
-11
@@ -68,7 +68,7 @@ func main() {
68
}
69
70
// parse the commandline into a command invocation
71
- err = invoc.Parse(os.Args[1:])
71
+ parseErr := invoc.Parse(os.Args[1:])
72
73
// BEFORE handling the parse error, if we have enough information
74
// AND the user requested help, print it out and exit
@@ -84,10 +84,18 @@ func main() {
84
}
85
}
86
87
- // ok now handle handle parse error (which means cli input was wrong,
87
+ // here we handle the cases where
88
+ // - commands with no Run func are invoked directly.
89
+ // - the main command is invoked.
90
+ if invoc.cmd == nil || invoc.cmd.Run == nil {
91
+ printHelp(false)
92
+ os.Exit(0)
93
+ }
94
+
95
+ // ok now handle parse error (which means cli input was wrong,
96
// e.g. incorrect number of args, or nonexistent subcommand)
89
- if err != nil {
90
- printErr(err)
97
+ if parseErr != nil {
98
+ printErr(parseErr)
99
100
// this was a user error, print help.
101
if invoc.cmd != nil {
@@ -248,13 +256,6 @@ func isClientError(err error) bool {
256
if !ok {
257
return false
258
}
251
-
252
- // here we handle the case where commands with
253
- // no Run func are invoked directly. As help requests.
254
- if err == cmds.ErrNotCallable {
255
- return true
256
- }
257
-
259
return cmdErr.Code == cmds.ErrClient
260
}
261
commands/cli/helptext.go
+5
@@ -195,6 +195,11 @@ func ShortHelp(rootName string, root *cmds.Command, path []string, out io.Writer
195
return err
196
}
197
198
+ // default cmd to root if there is no path
199
+ if path == nil && cmd == nil {
200
+ cmd = root
201
+ }
202
+
203
pathStr := rootName
204
if len(path) > 0 {
205
pathStr += " " + strings.Join(path, " ")
commands/cli/parse.go
+6
-24
@@ -14,36 +14,18 @@ var ErrInvalidSubcmd = errors.New("subcommand not found")
14
15
// Parse parses the input commandline string (cmd, flags, and args).
16
// returns the corresponding command Request object.
17
-// Multiple root commands are supported:
17
// Parse will search each root to find the one that best matches the requested subcommand.
18
// TODO: get rid of extraneous return values (e.g. we ended up not needing the root value anymore)
19
// TODO: get rid of multiple-root support, we should only need one now
21
-func Parse(input []string, roots ...*cmds.Command) (cmds.Request, *cmds.Command, *cmds.Command, []string, error) {
22
- var root, cmd *cmds.Command
23
- var path, stringArgs []string
24
- var opts map[string]interface{}
25
-
20
+func Parse(input []string, root *cmds.Command) (cmds.Request, *cmds.Command, *cmds.Command, []string, error) {
21
// use the root that matches the longest path (most accurately matches request)
27
- maxLength := 0
28
- for _, root2 := range roots {
29
- path2, input2, cmd2 := parsePath(input, root2)
30
- opts2, stringArgs2, err := parseOptions(input2)
31
- if err != nil {
32
- return nil, root, cmd2, path2, err
33
- }
34
-
35
- length := len(path2)
36
- if length > maxLength {
37
- maxLength = length
38
- root = root2
39
- path = path2
40
- cmd = cmd2
41
- opts = opts2
42
- stringArgs = stringArgs2
43
- }
22
+ path, input, cmd := parsePath(input, root)
23
+ opts, stringArgs, err := parseOptions(input)
24
+ if err != nil {
25
+ return nil, root, cmd, path, err
26
}
27
46
- if maxLength == 0 {
28
+ if len(path) == 0 {
29
return nil, root, nil, path, ErrInvalidSubcmd
30
}
31
core/commands2/root.go
+5
-3
@@ -13,8 +13,10 @@ type TestOutput struct {
13
}
14
15
var Root = &cmds.Command{
16
- Description: "Global P2P Merkle-DAG filesystem",
17
- SubcommandHelp: `Basic commands:
16
+ Helptext: cmds.HelpText{
17
+ Tagline: "Global P2P Merkle-DAG filesystem",
18
+ ShortDescription: `
19
+Basic commands:
20
21
init Initialize ipfs local configurationx
22
add <path> Add an object to ipfs
@@ -39,7 +41,7 @@ Plumbing commands:
41
block Interact with raw blocks in the datastore
42
object Interact with raw dag nodes
43
`,
42
-
44
+ },
45
Options: []cmds.Option{
46
cmds.StringOption("config", "c", "Path to the configuration file to use"),
47
cmds.BoolOption("debug", "D", "Operate in debug mode"),