From 206529730a2a132c548e41e7c1ba773adc49c930 Mon Sep 17 00:00:00 2001 From: Jakub Sztandera Date: Wed, 1 Jun 2016 20:15:24 +0200 Subject: [PATCH] Add Synopsis autogenerator Generates synopsis automagically License: MIT Signed-off-by: Jakub Sztandera --- commands/cli/helptext.go | 44 +++++++++++++++++++++++++++ commands/command.go | 7 +++-- test/sharness/t0010-basic-commands.sh | 2 +- test/sharness/t0040-add-and-cat.sh | 18 ++--------- 4 files changed, 52 insertions(+), 19 deletions(-) diff --git a/commands/cli/helptext.go b/commands/cli/helptext.go index cceb3f90f..8ab06a11d 100644 --- a/commands/cli/helptext.go +++ b/commands/cli/helptext.go @@ -163,6 +163,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 +209,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 +222,44 @@ 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 i == 0 { + 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/command.go b/commands/command.go index d0f452ebd..d172f53e7 100644 --- a/commands/command.go +++ b/commands/command.go @@ -36,9 +36,9 @@ type MarshalerMap map[EncodingType]Marshaler // text follows formats similar to man pages, but not exactly the same. type HelpText struct { // required - Tagline string // used in - ShortDescription string // used in DESCRIPTION - Synopsis string // showcasing the cmd + Tagline string // used in + ShortDescription string // used in DESCRIPTION + SynopsisOptionsValues map[string]string // mappings for synopsis generator // optional - whole section overrides Usage string // overrides USAGE section @@ -46,6 +46,7 @@ type HelpText struct { Options string // overrides OPTIONS section Arguments string // overrides ARGUMENTS section Subcommands string // overrides SUBCOMMANDS section + Synopsis string // overrides SYNOPSIS field } // Command is a runnable command, with input arguments and options (flags). diff --git a/test/sharness/t0010-basic-commands.sh b/test/sharness/t0010-basic-commands.sh index 69cccef6d..4b05c99b6 100755 --- a/test/sharness/t0010-basic-commands.sh +++ b/test/sharness/t0010-basic-commands.sh @@ -35,7 +35,7 @@ test_expect_success "ipfs help succeeds" ' test_expect_success "ipfs help output looks good" ' egrep -i "^Usage" help.txt >/dev/null && - egrep "ipfs .* " help.txt >/dev/null || + egrep "ipfs " help.txt >/dev/null || test_fsh cat help.txt ' diff --git a/test/sharness/t0040-add-and-cat.sh b/test/sharness/t0040-add-and-cat.sh index 1f972a00c..b7e28d4ec 100755 --- a/test/sharness/t0040-add-and-cat.sh +++ b/test/sharness/t0040-add-and-cat.sh @@ -8,19 +8,6 @@ test_description="Test add and cat commands" . lib/test-lib.sh -client_err_add() { - printf "$@\n\n" - echo 'USAGE - ipfs add ... - Add a file to ipfs. - - Adds contents of to ipfs. Use -r to add directories. - Note that directories are added recursively, to form the ipfs - MerkleDAG. - -Use '"'"'ipfs add --help'"'"' for more information about this command. -' -} - test_add_cat_file() { test_expect_success "ipfs add succeeds" ' echo "Hello Worlds!" >mountdir/hello.txt && @@ -176,9 +163,10 @@ test_add_named_pipe() { test_expect_success "useful error message when adding a named pipe" ' mkfifo named-pipe && test_expect_code 1 ipfs add named-pipe 2>actual && - client_err_add "Error: Unrecognized file type for named-pipe: $(generic_stat named-pipe)" >expected && rm named-pipe && - test_cmp expected actual + grep "Error: Unrecognized file type for named-pipe: $(generic_stat named-pipe)" actual && + grep USAGE actual && + grep "ipfs add" actual ' test_expect_success "useful error message when recursively adding a named pipe" '