@cryptotaxi247 / kubo / commits / 4970d8b5a

commands/cli: Use template for helptext generation

Matt Bell committed Nov 11, 2014 at 21:57 UTC 4970d8b5a3f61f4055f3bca0065487e053212a0e
2 files changed +89 -49
cmd/ipfs2/main.go
+4 -10
@@ -107,11 +107,9 @@ func createRequest(args []string) (cmds.Request, *cmds.Command, error) {
107 }
108
109 // generate the help text for the command the user was trying to call (or root)
110 - helpText, htErr := cmdsCli.HelpText("ipfs", root, path)
110 + htErr := cmdsCli.LongHelp("ipfs", root, path, os.Stdout)
111 if htErr != nil {
112 fmt.Println(htErr)
113 - } else {
114 - fmt.Println(helpText)
113 }
114 return nil, nil, err
115 }
@@ -150,12 +148,10 @@ func handleHelpOption(req cmds.Request, root *cmds.Command) (helpTextDisplayed b
148 if !help {
149 return false, nil
150 }
153 - helpText, err := cmdsCli.HelpText("ipfs", root, req.Path())
151 + err = cmdsCli.LongHelp("ipfs", root, req.Path(), os.Stdout)
152 if err != nil {
153 return false, err
154 }
157 - fmt.Println(helpText)
158 -
155 return true, nil
156 }
157
@@ -214,11 +210,9 @@ func outputResponse(res cmds.Response, root *cmds.Command) error {
210
211 // if this is a client error, we try to display help text
212 if res.Error().Code == cmds.ErrClient {
217 - helpText, err := cmdsCli.HelpText("ipfs", root, res.Request().Path())
213 + err := cmdsCli.LongHelp("ipfs", root, res.Request().Path(), os.Stdout)
214 if err != nil {
219 - fmt.Println(err.Error())
220 - } else {
221 - fmt.Println(helpText)
215 + fmt.Println(err)
216 }
217 }
218
commands/cli/helptext.go
+85 -39
@@ -2,7 +2,9 @@ package cli
2
3 import (
4 "fmt"
5 + "io"
6 "strings"
7 + "text/template"
8
9 cmds "github.com/jbenet/go-ipfs/commands"
10 )
@@ -15,60 +17,104 @@ const (
17 optionType = "(%v)"
18
19 whitespace = "\r\n\t "
20 +
21 + indentStr = " "
22 )
23
20 -// HelpText returns a formatted CLI helptext string, generated for the given command
21 -func HelpText(rootName string, root *cmds.Command, path []string) (string, error) {
22 - cmd, err := root.Get(path)
24 +type helpFields struct {
25 + Indent string
26 + Path string
27 + ArgUsage string
28 + Tagline string
29 + Arguments string
30 + Options string
31 + Subcommands string
32 + Description string
33 +}
34 +
35 +const usageFormat = "{{.Path}}{{if .ArgUsage}} {{.ArgUsage}}{{end}} - {{.Tagline}}"
36 +
37 +const longHelpFormat = `
38 +{{.Indent}}{{template "usage" .}}
39 +
40 +{{if .Arguments}}ARGUMENTS:
41 +
42 +{{.Indent}}{{.Arguments}}
43 +
44 +{{end}}{{if .Options}}OPTIONS:
45 +
46 +{{.Indent}}{{.Options}}
47 +
48 +{{end}}{{if .Subcommands}}SUBCOMMANDS:
49 +
50 +{{.Indent}}{{.Subcommands}}
51 +
52 +{{.Indent}}Use '{{.Path}} <subcmd> --help' for more information about each command.
53 +
54 +{{end}}{{if .Description}}DESCRIPTION:
55 +
56 +{{.Indent}}{{.Description}}
57 +
58 +{{end}}
59 +`
60 +
61 +var longHelpTemplate *template.Template
62 +var usageTemplate *template.Template
63 +
64 +func init() {
65 + tmpl, err := template.New("usage").Parse(usageFormat)
66 if err != nil {
24 - return "", err
67 + panic(err)
68 }
69 + usageTemplate = tmpl
70
27 - s := ""
28 - usage := usageText(cmd)
29 - if len(usage) > 0 {
30 - usage += " "
71 + tmpl, err = usageTemplate.New("longHelp").Parse(longHelpFormat)
72 + if err != nil {
73 + panic(err)
74 }
32 - s += fmt.Sprintf("%v %v %v- %v\n\n", rootName, strings.Join(path, " "), usage, cmd.Description)
75 + longHelpTemplate = tmpl
76 +}
77
34 - if len(cmd.Help) > 0 {
35 - s += fmt.Sprintf("%v\n\n", strings.Trim(cmd.Help, whitespace))
78 +// LongHelp returns a formatted CLI helptext string, generated for the given command
79 +func LongHelp(rootName string, root *cmds.Command, path []string, out io.Writer) error {
80 + cmd, err := root.Get(path)
81 + if err != nil {
82 + return err
83 }
84
38 - if cmd.Arguments != nil {
39 - if len(cmd.ArgumentHelp) > 0 {
40 - s += cmd.ArgumentHelp
41 - } else {
42 - section := strings.Join(indent(argumentText(cmd), " "), "\n")
43 - s += fmt.Sprintf("Arguments:\n%v", section)
44 - }
45 -
46 - s += "\n\n"
85 + pathStr := rootName
86 + if len(path) > 0 {
87 + pathStr += " " + strings.Join(path, " ")
88 }
89
49 - if cmd.Subcommands != nil {
50 - if len(cmd.SubcommandHelp) > 0 {
51 - s += cmd.SubcommandHelp
52 - } else {
53 - section := strings.Join(indent(subcommandText(cmd, rootName, path), " "), "\n")
54 - s += fmt.Sprintf("Subcommands:\n%v", section)
55 - }
56 -
57 - s += "\n\n"
90 + fields := helpFields{
91 + Indent: indentStr,
92 + Path: pathStr,
93 + ArgUsage: usageText(cmd),
94 + Tagline: cmd.Description,
95 + Arguments: cmd.ArgumentHelp,
96 + Options: cmd.OptionHelp,
97 + Subcommands: cmd.SubcommandHelp,
98 + Description: cmd.Help,
99 }
100
60 - if cmd.Options != nil {
61 - if len(cmd.OptionHelp) > 0 {
62 - s += cmd.OptionHelp
63 - } else {
64 - section := strings.Join(indent(optionText(cmd), " "), "\n")
65 - s += fmt.Sprintf("Options:\n%v", section)
66 - }
67 -
68 - s += "\n\n"
101 + // autogen fields that are empty
102 + if len(cmd.ArgumentHelp) == 0 {
103 + fields.Arguments = strings.Join(argumentText(cmd), "\n")
104 + }
105 + if len(cmd.OptionHelp) == 0 {
106 + fields.Options = strings.Join(optionText(cmd), "\n")
107 }
108 + if len(cmd.SubcommandHelp) == 0 {
109 + fields.Subcommands = strings.Join(subcommandText(cmd, rootName, path), "\n")
110 + }
111 +
112 + fields.Arguments = indentString(fields.Arguments, indentStr)
113 + fields.Options = indentString(fields.Options, indentStr)
114 + fields.Subcommands = indentString(fields.Subcommands, indentStr)
115 + fields.Description = indentString(fields.Description, indentStr)
116
71 - return s, nil
117 + return longHelpTemplate.Execute(out, fields)
118 }
119
120 func argumentText(cmd *cmds.Command) []string {