diff --git a/commands/cli/helptext.go b/commands/cli/helptext.go index cceb3f90f63..cd399a04c76 100644 --- a/commands/cli/helptext.go +++ b/commands/cli/helptext.go @@ -78,7 +78,6 @@ const longHelpFormat = `USAGE {{.Indent}}{{template "usage" .}} {{if .Synopsis}}SYNOPSIS - {{.Synopsis}} {{end}}{{if .Arguments}}ARGUMENTS @@ -163,6 +162,9 @@ func LongHelp(rootName string, root *cmds.Command, path []string, out io.Writer) if len(fields.Subcommands) == 0 { fields.Subcommands = strings.Join(subcommandText(cmd, rootName, path), "\n") } + if len(fields.Synopsis) == 0 { + fields.Synopsis = generateSynopsis(cmd, pathStr) + } // trim the extra newlines (see TrimNewlines doc) fields.TrimNewlines() @@ -206,6 +208,9 @@ func ShortHelp(rootName string, root *cmds.Command, path []string, out io.Writer if len(fields.Subcommands) == 0 { fields.Subcommands = strings.Join(subcommandText(cmd, rootName, path), "\n") } + if len(fields.Synopsis) == 0 { + fields.Synopsis = generateSynopsis(cmd, pathStr) + } // trim the extra newlines (see TrimNewlines doc) fields.TrimNewlines() @@ -216,6 +221,54 @@ func ShortHelp(rootName string, root *cmds.Command, path []string, out io.Writer return shortHelpTemplate.Execute(out, fields) } +func generateSynopsis(cmd *cmds.Command, path string) string { + res := path + for _, opt := range cmd.Options { + valopt, ok := cmd.Helptext.SynopsisOptionsValues[opt.Names()[0]] + if !ok { + valopt = opt.Names()[0] + } + sopt := "" + for i, n := range opt.Names() { + pre := "-" + if len(n) > 1 { + pre = "--" + } + if opt.Type() == cmds.Bool && opt.DefaultVal() == true { + pre = "--" + sopt = fmt.Sprintf("%s%s=false", pre, n) + break + } else { + if i == 0 { + if opt.Type() == cmds.Bool { + sopt = fmt.Sprintf("%s%s", pre, n) + } else { + sopt = fmt.Sprintf("%s%s=<%s>", pre, n, valopt) + } + } else { + sopt = fmt.Sprintf("%s | %s%s", sopt, pre, n) + } + } + } + res = fmt.Sprintf("%s [%s]", res, sopt) + } + if len(cmd.Arguments) > 0 { + res = fmt.Sprintf("%s [--]", res) + } + for _, arg := range cmd.Arguments { + sarg := fmt.Sprintf("<%s>", arg.Name) + if arg.Variadic { + sarg = sarg + "..." + } + + if !arg.Required { + sarg = fmt.Sprintf("[%s]", sarg) + } + res = fmt.Sprintf("%s %s", res, sarg) + } + return strings.Trim(res, " ") +} + func argumentText(cmd *cmds.Command) []string { lines := make([]string, len(cmd.Arguments)) diff --git a/commands/cli/helptext_test.go b/commands/cli/helptext_test.go new file mode 100644 index 00000000000..aa8361f9955 --- /dev/null +++ b/commands/cli/helptext_test.go @@ -0,0 +1,45 @@ +package cli + +import ( + "strings" + "testing" + + cmds "github.com/ipfs/go-ipfs/commands" +) + +func TestSynopsisGenerator(t *testing.T) { + command := &cmds.Command{ + Arguments: []cmds.Argument{ + cmds.StringArg("required", true, false, ""), + cmds.StringArg("variadic", false, true, ""), + }, + Options: []cmds.Option{ + cmds.StringOption("opt", "o", "Option"), + }, + Helptext: cmds.HelpText{ + SynopsisOptionsValues: map[string]string{ + "opt": "OPTION", + }, + }, + } + syn := generateSynopsis(command, "cmd") + t.Logf("Synopsis is: %s", syn) + if !strings.HasPrefix(syn, "cmd ") { + t.Fatal("Synopsis should start with command name") + } + if !strings.Contains(syn, "[--opt=