veyron/lib/cmdline: Add help topics, and minor cleanups.
Help topics provide more details for particular topics, so that
users can get all the documentation that they need directly from
our cmdline tools. I've updated the vdl tool with a "packages"
topic, and plan to add another for "vdlpath" in the future.
Also some minor cleanups of the cmdline implementation. In
particular create some flag.FlagSet helper functions, and replace
prefixErrorWriter with a more standard error-handling strategy.
I haven't updated all the doc comments for our tools yet; I'm
planning on adding simple support using "go generate" in a future
change.
Change-Id: Iea584a72b3ba345a41dba4f3c5a270ef1314e775
diff --git a/lib/cmdline/cmdline.go b/lib/cmdline/cmdline.go
index 82c032c..74245f2 100644
--- a/lib/cmdline/cmdline.go
+++ b/lib/cmdline/cmdline.go
@@ -18,6 +18,7 @@
"flag"
"fmt"
"io"
+ "io/ioutil"
"os"
"strings"
)
@@ -51,6 +52,9 @@
// child's name, and call Run on the first matching child.
Children []*Command
+ // Topics that provide additional info via the default help command.
+ Topics []Topic
+
// Run is a function that runs cmd with args. If both Children and Run are
// specified, Run will only be called if none of the children match. It is an
// error if neither is specified. The special ErrExitCode error may be
@@ -76,6 +80,14 @@
// Alias map[string]string
}
+// Topic represents an additional help topic that is accessed via the default
+// help command.
+type Topic struct {
+ Name string // Name of the topic.
+ Short string // Short description, shown in help for the command.
+ Long string // Long description, shown in help for this topic.
+}
+
// style describes the formatting style for usage descriptions.
type style int
@@ -126,106 +138,123 @@
fmt.Fprint(cmd.stderr, "ERROR: ")
fmt.Fprintf(cmd.stderr, format, v...)
fmt.Fprint(cmd.stderr, "\n\n")
- cmd.usage(cmd.stderr, styleText, true)
+ cmd.usage(cmd.stderr, true)
return ErrUsage
}
-// usage prints the usage of cmd to the writer, with the given style. The
-// firstCall boolean is set to false when printing usage for multiple commands,
-// and is used to avoid printing redundant information (e.g. section headers,
-// global flags).
-func (cmd *Command) usage(w io.Writer, style style, firstCall bool) {
- var names []string
- for c := cmd; c != nil; c = c.parent {
- names = append([]string{c.Name}, names...)
- }
- namestr := strings.Join(names, " ")
- if !firstCall && style == styleGoDoc {
- // Title-case names so that godoc recognizes it as a section header.
- fmt.Fprintf(w, "%s\n\n", strings.Title(namestr))
- }
- // Long description.
- fmt.Fprint(w, strings.Trim(cmd.Long, "\n"))
- fmt.Fprintln(w)
+// usage prints the usage of cmd to the writer. The firstCall boolean is set to
+// false when printing usage for multiple commands, and is used to avoid
+// printing redundant information (e.g. help command, global flags).
+func (cmd *Command) usage(w io.Writer, firstCall bool) {
+ printLong(w, cmd.Long)
// Usage line.
- hasFlags := false
- cmd.Flags.VisitAll(func(*flag.Flag) {
- hasFlags = true
- })
+ hasFlags := numFlags(&cmd.Flags) > 0
fmt.Fprintf(w, "\nUsage:\n")
- nameflags := " " + namestr
+ path := namePath(cmd)
+ pathf := " " + path
if hasFlags {
- nameflags += " [flags]"
+ pathf += " [flags]"
}
if len(cmd.Children) > 0 {
- fmt.Fprintf(w, "%s <command>\n", nameflags)
+ fmt.Fprintf(w, "%s <command>\n", pathf)
}
if cmd.Run != nil {
if cmd.ArgsName != "" {
- fmt.Fprintf(w, "%s %s\n", nameflags, cmd.ArgsName)
+ fmt.Fprintf(w, "%s %s\n", pathf, cmd.ArgsName)
} else {
- fmt.Fprintf(w, "%s\n", nameflags)
+ fmt.Fprintf(w, "%s\n", pathf)
}
}
if len(cmd.Children) == 0 && cmd.Run == nil {
// This is a specification error.
- fmt.Fprintf(w, "%s [ERROR: neither Children nor Run is specified]\n", nameflags)
+ fmt.Fprintf(w, "%s [ERROR: neither Children nor Run is specified]\n", pathf)
}
// Commands.
if len(cmd.Children) > 0 {
fmt.Fprintf(w, "\nThe %s commands are:\n", cmd.Name)
for _, child := range cmd.Children {
- if !firstCall && child.isDefaultHelp {
- continue // don't repeatedly list default help command
+ // Don't repeatedly list default help command.
+ if !child.isDefaultHelp || firstCall {
+ fmt.Fprintf(w, " %-11s %s\n", child.Name, child.Short)
}
- fmt.Fprintf(w, " %-11s %s\n", child.Name, child.Short)
+ }
+ if firstCall {
+ fmt.Fprintf(w, "Run \"%s help [command]\" for command usage.\n", path)
}
}
// Args.
if cmd.Run != nil && cmd.ArgsLong != "" {
- fmt.Fprintf(w, "\n")
- fmt.Fprint(w, strings.Trim(cmd.ArgsLong, "\n"))
- fmt.Fprintf(w, "\n")
+ fmt.Fprintln(w)
+ printLong(w, cmd.ArgsLong)
+ }
+ // Help topics.
+ if len(cmd.Topics) > 0 {
+ fmt.Fprintf(w, "\nThe %s additional help topics are:\n", cmd.Name)
+ for _, topic := range cmd.Topics {
+ fmt.Fprintf(w, " %-11s %s\n", topic.Name, topic.Short)
+ }
+ if firstCall {
+ fmt.Fprintf(w, "Run \"%s help [topic]\" for topic details.\n", path)
+ }
}
// Flags.
if hasFlags {
fmt.Fprintf(w, "\nThe %s flags are:\n", cmd.Name)
- cmd.Flags.VisitAll(func(f *flag.Flag) {
- fmt.Fprintf(w, " -%s=%s: %s\n", f.Name, f.DefValue, f.Usage)
- })
+ printFlags(w, &cmd.Flags)
}
// Global flags.
- hasGlobalFlags := false
- flag.VisitAll(func(*flag.Flag) {
- hasGlobalFlags = true
- })
- if firstCall && hasGlobalFlags {
+ if numFlags(flag.CommandLine) > 0 && firstCall {
fmt.Fprintf(w, "\nThe global flags are:\n")
- flag.VisitAll(func(f *flag.Flag) {
- fmt.Fprintf(w, " -%s=%s: %s\n", f.Name, f.DefValue, f.Usage)
- })
+ printFlags(w, flag.CommandLine)
}
}
+// namePath returns the path of command names up to cmd.
+func namePath(cmd *Command) string {
+ var path []string
+ for ; cmd != nil; cmd = cmd.parent {
+ path = append([]string{cmd.Name}, path...)
+ }
+ return strings.Join(path, " ")
+}
+
+func printLong(w io.Writer, long string) {
+ fmt.Fprint(w, strings.Trim(long, "\n"))
+ fmt.Fprintln(w)
+}
+
+func numFlags(set *flag.FlagSet) (num int) {
+ set.VisitAll(func(*flag.Flag) {
+ num++
+ })
+ return
+}
+
+func printFlags(w io.Writer, set *flag.FlagSet) {
+ set.VisitAll(func(f *flag.Flag) {
+ fmt.Fprintf(w, " -%s=%s: %s\n", f.Name, f.DefValue, f.Usage)
+ })
+}
+
// newDefaultHelp creates a new default help command. We need to create new
// instances since the parent for each help command is different.
func newDefaultHelp() *Command {
helpStyle := styleText
help := &Command{
Name: helpName,
- Short: "Display help for commands",
+ Short: "Display help for commands or topics",
Long: `
-Help displays usage descriptions for this command, or usage descriptions for
-sub-commands.
+Help with no args displays the usage of the parent command.
+Help with args displays the usage of the specified sub-command or help topic.
+"help ..." recursively displays help for all commands and topics.
`,
- ArgsName: "[command ...]",
+ ArgsName: "[command/topic ...]",
ArgsLong: `
-[command ...] is an optional sequence of commands to display detailed usage.
-The special-case "help ..." recursively displays help for all commands.
+[command/topic ...] optionally identifies a specific sub-command or help topic.
`,
Run: func(cmd *Command, args []string) error {
// Help applies to its parent - e.g. "foo help" applies to the foo command.
- return runHelp(cmd.parent, args, helpStyle)
+ return runHelp(cmd.stdout, cmd.parent, args, helpStyle)
},
isDefaultHelp: true,
}
@@ -236,57 +265,63 @@
const helpName = "help"
// runHelp runs the "help" command.
-func runHelp(cmd *Command, args []string, style style) error {
+func runHelp(w io.Writer, cmd *Command, args []string, style style) error {
if len(args) == 0 {
- cmd.usage(cmd.stdout, style, true)
+ cmd.usage(w, true)
return nil
}
if args[0] == "..." {
- recursiveHelp(cmd, style, true)
+ recursiveHelp(w, cmd, style, true)
return nil
}
- // Find the subcommand to display help.
- subName := args[0]
- subArgs := args[1:]
+ // Try to display help for the subcommand.
+ subName, subArgs := args[0], args[1:]
for _, child := range cmd.Children {
if child.Name == subName {
- return runHelp(child, subArgs, style)
+ return runHelp(w, child, subArgs, style)
}
}
- return cmd.UsageErrorf("%s: unknown command %q", cmd.Name, subName)
+ // Try to display help for the help topic.
+ for _, topic := range cmd.Topics {
+ if topic.Name == subName {
+ printLong(w, topic.Long)
+ return nil
+ }
+ }
+ return cmd.UsageErrorf("%s: unknown command or topic %q", cmd.Name, subName)
}
// recursiveHelp prints help recursively via DFS from this cmd onward.
-func recursiveHelp(cmd *Command, style style, firstCall bool) {
- cmd.usage(cmd.stdout, style, firstCall)
+func recursiveHelp(w io.Writer, cmd *Command, style style, firstCall bool) {
+ if !firstCall {
+ // Title-case required for godoc to recognize this as a section header.
+ header := strings.Title(namePath(cmd))
+ lineBreak(w, style)
+ fmt.Fprintf(w, "%s\n\n", header)
+ }
+ cmd.usage(w, firstCall)
+ for _, child := range cmd.Children {
+ // Don't repeatedly print default help command.
+ if !child.isDefaultHelp || firstCall {
+ recursiveHelp(w, child, style, false)
+ }
+ }
+ for _, topic := range cmd.Topics {
+ // Title-case required for godoc to recognize this as a section header.
+ header := strings.Title(namePath(cmd) + " " + topic.Name + " (Help Topic)")
+ lineBreak(w, style)
+ fmt.Fprintf(w, "%s\n\n", header)
+ printLong(w, topic.Long)
+ }
+}
+
+func lineBreak(w io.Writer, style style) {
switch style {
case styleText:
- fmt.Fprintln(cmd.stdout, strings.Repeat("=", 80))
+ fmt.Fprintln(w, strings.Repeat("=", 80))
case styleGoDoc:
- fmt.Fprintln(cmd.stdout)
+ fmt.Fprintln(w)
}
- for _, child := range cmd.Children {
- if !firstCall && child.isDefaultHelp {
- continue // don't repeatedly print default help command
- }
- recursiveHelp(child, style, false)
- }
-}
-
-// prefixErrorWriter simply wraps a regular io.Writer and adds an "ERROR: "
-// prefix if Write is ever called. It's used to ensure errors are clearly
-// marked when flag.FlagSet.Parse encounters errors.
-type prefixErrorWriter struct {
- writer io.Writer
- prefixWritten bool
-}
-
-func (p *prefixErrorWriter) Write(b []byte) (int, error) {
- if !p.prefixWritten {
- io.WriteString(p.writer, "ERROR: ")
- p.prefixWritten = true
- }
- return p.writer.Write(b)
}
// Init initializes all nodes in the command tree rooted at cmd. Init must be
@@ -306,38 +341,48 @@
if !hasHelp && cmd.Name != helpName && len(cmd.Children) > 0 {
cmd.Children = append(cmd.Children, newDefaultHelp())
}
- // Merge command-specific and global flags into parseFlags.
+ // Merge command-specific and global flags into parseFlags. We want to handle
+ // all error output ourselves, so we:
+ // 1) Set flag.ContinueOnError so that Parse() doesn't exit or panic.
+ // 2) Discard all output (can't be nil, that means stderr).
+ // 3) Set an empty Usage function (can't be nil, that means default).
cmd.parseFlags = flag.NewFlagSet(cmd.Name, flag.ContinueOnError)
- cmd.parseFlags.SetOutput(&prefixErrorWriter{writer: stderr})
- cmd.parseFlags.Usage = func() {
- cmd.usage(stderr, styleText, true)
- }
- flagMerger := func(f *flag.Flag) {
- if cmd.parseFlags.Lookup(f.Name) == nil {
- cmd.parseFlags.Var(f.Value, f.Name, f.Usage)
- }
- }
- cmd.Flags.VisitAll(flagMerger)
- flag.VisitAll(flagMerger)
+ cmd.parseFlags.SetOutput(ioutil.Discard)
+ cmd.parseFlags.Usage = emptyUsage
+ mergeFlags(cmd.parseFlags, &cmd.Flags)
+ mergeFlags(cmd.parseFlags, flag.CommandLine)
// Call children recursively.
for _, child := range cmd.Children {
child.Init(cmd, stdout, stderr)
}
}
+func mergeFlags(dst, src *flag.FlagSet) {
+ src.VisitAll(func(f *flag.Flag) {
+ if dst.Lookup(f.Name) == nil {
+ dst.Var(f.Value, f.Name, f.Usage)
+ }
+ })
+}
+
+func emptyUsage() {}
+
// Execute the command with the given args. The returned error is ErrUsage if
// there are usage errors, otherwise it is whatever the leaf command returns
// from its Run function.
func (cmd *Command) Execute(args []string) error {
// Parse the merged flags.
if err := cmd.parseFlags.Parse(args); err != nil {
- return ErrUsage
+ if err == flag.ErrHelp {
+ cmd.usage(cmd.stdout, true)
+ return nil
+ }
+ return cmd.UsageErrorf(err.Error())
}
args = cmd.parseFlags.Args()
// Look for matching children.
if len(args) > 0 {
- subName := args[0]
- subArgs := args[1:]
+ subName, subArgs := args[0], args[1:]
for _, child := range cmd.Children {
if child.Name == subName {
return child.Execute(subArgs)
@@ -349,9 +394,8 @@
if cmd.ArgsName == "" && len(args) > 0 {
if len(cmd.Children) > 0 {
return cmd.UsageErrorf("%s: unknown command %q", cmd.Name, args[0])
- } else {
- return cmd.UsageErrorf("%s doesn't take any arguments", cmd.Name)
}
+ return cmd.UsageErrorf("%s doesn't take any arguments", cmd.Name)
}
return cmd.Run(cmd, args)
}
@@ -374,9 +418,8 @@
if err := cmd.Execute(os.Args[1:]); err != nil {
if code, ok := err.(ErrExitCode); ok {
os.Exit(int(code))
- } else {
- fmt.Fprintf(os.Stderr, "ERROR: %v\n", err)
- os.Exit(2)
}
+ fmt.Fprintf(os.Stderr, "ERROR: %v\n", err)
+ os.Exit(2)
}
}
diff --git a/lib/cmdline/cmdline_test.go b/lib/cmdline/cmdline_test.go
index f4a424c..255f1d5 100644
--- a/lib/cmdline/cmdline_test.go
+++ b/lib/cmdline/cmdline_test.go
@@ -177,7 +177,8 @@
The onecmd commands are:
echo Print strings on stdout
- help Display help for commands
+ help Display help for commands or topics
+Run "onecmd help [command]" for command usage.
The global flags are:
-global1=: global test flag 1
@@ -196,7 +197,8 @@
The onecmd commands are:
echo Print strings on stdout
- help Display help for commands
+ help Display help for commands or topics
+Run "onecmd help [command]" for command usage.
The global flags are:
-global1=: global test flag 1
@@ -212,7 +214,8 @@
The onecmd commands are:
echo Print strings on stdout
- help Display help for commands
+ help Display help for commands or topics
+Run "onecmd help [command]" for command usage.
The global flags are:
-global1=: global test flag 1
@@ -235,14 +238,14 @@
},
{
Args: []string{"help", "help"},
- Stdout: `Help displays usage descriptions for this command, or usage descriptions for
-sub-commands.
+ Stdout: `Help with no args displays the usage of the parent command.
+Help with args displays the usage of the specified sub-command or help topic.
+"help ..." recursively displays help for all commands and topics.
Usage:
- onecmd help [flags] [command ...]
+ onecmd help [flags] [command/topic ...]
-[command ...] is an optional sequence of commands to display detailed usage.
-The special-case "help ..." recursively displays help for all commands.
+[command/topic ...] optionally identifies a specific sub-command or help topic.
The help flags are:
-style=text: The formatting style for help output, either "text" or "godoc".
@@ -261,12 +264,15 @@
The onecmd commands are:
echo Print strings on stdout
- help Display help for commands
+ help Display help for commands or topics
+Run "onecmd help [command]" for command usage.
The global flags are:
-global1=: global test flag 1
-global2=0: global test flag 2
================================================================================
+Onecmd Echo
+
Echo prints any strings passed in to stdout.
Usage:
@@ -274,24 +280,25 @@
[strings] are arbitrary strings that will be echoed.
================================================================================
-Help displays usage descriptions for this command, or usage descriptions for
-sub-commands.
+Onecmd Help
+
+Help with no args displays the usage of the parent command.
+Help with args displays the usage of the specified sub-command or help topic.
+"help ..." recursively displays help for all commands and topics.
Usage:
- onecmd help [flags] [command ...]
+ onecmd help [flags] [command/topic ...]
-[command ...] is an optional sequence of commands to display detailed usage.
-The special-case "help ..." recursively displays help for all commands.
+[command/topic ...] optionally identifies a specific sub-command or help topic.
The help flags are:
-style=text: The formatting style for help output, either "text" or "godoc".
-================================================================================
`,
},
{
Args: []string{"help", "foo"},
Err: ErrUsage,
- Stderr: `ERROR: onecmd: unknown command "foo"
+ Stderr: `ERROR: onecmd: unknown command or topic "foo"
Onecmd only has the echo command.
@@ -300,7 +307,8 @@
The onecmd commands are:
echo Print strings on stdout
- help Display help for commands
+ help Display help for commands or topics
+Run "onecmd help [command]" for command usage.
The global flags are:
-global1=: global test flag 1
@@ -383,7 +391,8 @@
The multi commands are:
echo Print strings on stdout
echoopt Print strings on stdout, with opts
- help Display help for commands
+ help Display help for commands or topics
+Run "multi help [command]" for command usage.
The multi flags are:
-extra=false: Print an extra arg
@@ -403,7 +412,8 @@
The multi commands are:
echo Print strings on stdout
echoopt Print strings on stdout, with opts
- help Display help for commands
+ help Display help for commands or topics
+Run "multi help [command]" for command usage.
The multi flags are:
-extra=false: Print an extra arg
@@ -423,7 +433,8 @@
The multi commands are:
echo Print strings on stdout
echoopt Print strings on stdout, with opts
- help Display help for commands
+ help Display help for commands or topics
+Run "multi help [command]" for command usage.
The multi flags are:
-extra=false: Print an extra arg
@@ -432,6 +443,8 @@
-global1=: global test flag 1
-global2=0: global test flag 2
================================================================================
+Multi Echo
+
Echo prints any strings passed in to stdout.
Usage:
@@ -439,6 +452,8 @@
[strings] are arbitrary strings that will be echoed.
================================================================================
+Multi Echoopt
+
Echoopt prints any args passed in to stdout.
Usage:
@@ -449,18 +464,19 @@
The echoopt flags are:
-n=false: Do not output trailing newline
================================================================================
-Help displays usage descriptions for this command, or usage descriptions for
-sub-commands.
+Multi Help
+
+Help with no args displays the usage of the parent command.
+Help with args displays the usage of the specified sub-command or help topic.
+"help ..." recursively displays help for all commands and topics.
Usage:
- multi help [flags] [command ...]
+ multi help [flags] [command/topic ...]
-[command ...] is an optional sequence of commands to display detailed usage.
-The special-case "help ..." recursively displays help for all commands.
+[command/topic ...] optionally identifies a specific sub-command or help topic.
The help flags are:
-style=text: The formatting style for help output, either "text" or "godoc".
-================================================================================
`,
},
{
@@ -497,7 +513,7 @@
{
Args: []string{"help", "foo"},
Err: ErrUsage,
- Stderr: `ERROR: multi: unknown command "foo"
+ Stderr: `ERROR: multi: unknown command or topic "foo"
Multi has two variants of echo.
@@ -507,7 +523,8 @@
The multi commands are:
echo Print strings on stdout
echoopt Print strings on stdout, with opts
- help Display help for commands
+ help Display help for commands or topics
+Run "multi help [command]" for command usage.
The multi flags are:
-extra=false: Print an extra arg
@@ -569,6 +586,7 @@
Args: []string{"echo", "-n", "foo", "bar"},
Err: ErrUsage,
Stderr: `ERROR: flag provided but not defined: -n
+
Echo prints any strings passed in to stdout.
Usage:
@@ -585,6 +603,7 @@
Args: []string{"-nosuchflag", "echo", "foo", "bar"},
Err: ErrUsage,
Stderr: `ERROR: flag provided but not defined: -nosuchflag
+
Multi has two variants of echo.
Usage:
@@ -593,7 +612,8 @@
The multi commands are:
echo Print strings on stdout
echoopt Print strings on stdout, with opts
- help Display help for commands
+ help Display help for commands or topics
+Run "multi help [command]" for command usage.
The multi flags are:
-extra=false: Print an extra arg
@@ -646,6 +666,9 @@
Short: "Set of echo commands",
Long: "Echoprog has two variants of echo.",
Children: []*Command{cmdEcho, cmdEchoOpt},
+ Topics: []Topic{
+ {Name: "topic3", Short: "Help topic 3 short", Long: "Help topic 3 long."},
+ },
}
echoProg.Flags.BoolVar(&flagExtra, "extra", false, "Print an extra arg")
prog := &Command{
@@ -653,6 +676,10 @@
Short: "Top level prog",
Long: "Toplevelprog has the echo subprogram and the hello command.",
Children: []*Command{echoProg, cmdHello},
+ Topics: []Topic{
+ {Name: "topic1", Short: "Help topic 1 short", Long: "Help topic 1 long."},
+ {Name: "topic2", Short: "Help topic 2 short", Long: "Help topic 2 long."},
+ },
}
prog.Flags.BoolVar(&flagTopLevelExtra, "tlextra", false, "Print an extra arg for all commands")
@@ -670,7 +697,13 @@
The toplevelprog commands are:
echoprog Set of echo commands
hello Print strings on stdout preceded by "Hello"
- help Display help for commands
+ help Display help for commands or topics
+Run "toplevelprog help [command]" for command usage.
+
+The toplevelprog additional help topics are:
+ topic1 Help topic 1 short
+ topic2 Help topic 2 short
+Run "toplevelprog help [topic]" for topic details.
The toplevelprog flags are:
-tlextra=false: Print an extra arg for all commands
@@ -690,7 +723,13 @@
The toplevelprog commands are:
echoprog Set of echo commands
hello Print strings on stdout preceded by "Hello"
- help Display help for commands
+ help Display help for commands or topics
+Run "toplevelprog help [command]" for command usage.
+
+The toplevelprog additional help topics are:
+ topic1 Help topic 1 short
+ topic2 Help topic 2 short
+Run "toplevelprog help [topic]" for topic details.
The toplevelprog flags are:
-tlextra=false: Print an extra arg for all commands
@@ -710,7 +749,13 @@
The toplevelprog commands are:
echoprog Set of echo commands
hello Print strings on stdout preceded by "Hello"
- help Display help for commands
+ help Display help for commands or topics
+Run "toplevelprog help [command]" for command usage.
+
+The toplevelprog additional help topics are:
+ topic1 Help topic 1 short
+ topic2 Help topic 2 short
+Run "toplevelprog help [topic]" for topic details.
The toplevelprog flags are:
-tlextra=false: Print an extra arg for all commands
@@ -719,6 +764,8 @@
-global1=: global test flag 1
-global2=0: global test flag 2
================================================================================
+Toplevelprog Echoprog
+
Echoprog has two variants of echo.
Usage:
@@ -728,9 +775,14 @@
echo Print strings on stdout
echoopt Print strings on stdout, with opts
+The echoprog additional help topics are:
+ topic3 Help topic 3 short
+
The echoprog flags are:
-extra=false: Print an extra arg
================================================================================
+Toplevelprog Echoprog Echo
+
Echo prints any strings passed in to stdout.
Usage:
@@ -738,6 +790,8 @@
[strings] are arbitrary strings that will be echoed.
================================================================================
+Toplevelprog Echoprog Echoopt
+
Echoopt prints any args passed in to stdout.
Usage:
@@ -748,6 +802,12 @@
The echoopt flags are:
-n=false: Do not output trailing newline
================================================================================
+Toplevelprog Echoprog Topic3 (Help Topic)
+
+Help topic 3 long.
+================================================================================
+Toplevelprog Hello
+
Hello prints any strings passed in to stdout preceded by "Hello".
Usage:
@@ -755,18 +815,27 @@
[strings] are arbitrary strings that will be printed.
================================================================================
-Help displays usage descriptions for this command, or usage descriptions for
-sub-commands.
+Toplevelprog Help
+
+Help with no args displays the usage of the parent command.
+Help with args displays the usage of the specified sub-command or help topic.
+"help ..." recursively displays help for all commands and topics.
Usage:
- toplevelprog help [flags] [command ...]
+ toplevelprog help [flags] [command/topic ...]
-[command ...] is an optional sequence of commands to display detailed usage.
-The special-case "help ..." recursively displays help for all commands.
+[command/topic ...] optionally identifies a specific sub-command or help topic.
The help flags are:
-style=text: The formatting style for help output, either "text" or "godoc".
================================================================================
+Toplevelprog Topic1 (Help Topic)
+
+Help topic 1 long.
+================================================================================
+Toplevelprog Topic2 (Help Topic)
+
+Help topic 2 long.
`,
},
{
@@ -779,7 +848,12 @@
The echoprog commands are:
echo Print strings on stdout
echoopt Print strings on stdout, with opts
- help Display help for commands
+ help Display help for commands or topics
+Run "toplevelprog echoprog help [command]" for command usage.
+
+The echoprog additional help topics are:
+ topic3 Help topic 3 short
+Run "toplevelprog echoprog help [topic]" for topic details.
The echoprog flags are:
-extra=false: Print an extra arg
@@ -790,6 +864,16 @@
`,
},
{
+ Args: []string{"help", "topic1"},
+ Stdout: `Help topic 1 long.
+`,
+ },
+ {
+ Args: []string{"help", "topic2"},
+ Stdout: `Help topic 2 long.
+`,
+ },
+ {
Args: []string{"echoprog", "help", "..."},
Stdout: `Echoprog has two variants of echo.
@@ -799,7 +883,12 @@
The echoprog commands are:
echo Print strings on stdout
echoopt Print strings on stdout, with opts
- help Display help for commands
+ help Display help for commands or topics
+Run "toplevelprog echoprog help [command]" for command usage.
+
+The echoprog additional help topics are:
+ topic3 Help topic 3 short
+Run "toplevelprog echoprog help [topic]" for topic details.
The echoprog flags are:
-extra=false: Print an extra arg
@@ -808,6 +897,8 @@
-global1=: global test flag 1
-global2=0: global test flag 2
================================================================================
+Toplevelprog Echoprog Echo
+
Echo prints any strings passed in to stdout.
Usage:
@@ -815,6 +906,8 @@
[strings] are arbitrary strings that will be echoed.
================================================================================
+Toplevelprog Echoprog Echoopt
+
Echoopt prints any args passed in to stdout.
Usage:
@@ -825,18 +918,23 @@
The echoopt flags are:
-n=false: Do not output trailing newline
================================================================================
-Help displays usage descriptions for this command, or usage descriptions for
-sub-commands.
+Toplevelprog Echoprog Help
+
+Help with no args displays the usage of the parent command.
+Help with args displays the usage of the specified sub-command or help topic.
+"help ..." recursively displays help for all commands and topics.
Usage:
- toplevelprog echoprog help [flags] [command ...]
+ toplevelprog echoprog help [flags] [command/topic ...]
-[command ...] is an optional sequence of commands to display detailed usage.
-The special-case "help ..." recursively displays help for all commands.
+[command/topic ...] optionally identifies a specific sub-command or help topic.
The help flags are:
-style=text: The formatting style for help output, either "text" or "godoc".
================================================================================
+Toplevelprog Echoprog Topic3 (Help Topic)
+
+Help topic 3 long.
`,
},
{
@@ -857,6 +955,16 @@
`,
},
{
+ Args: []string{"help", "echoprog", "topic3"},
+ Stdout: `Help topic 3 long.
+`,
+ },
+ {
+ Args: []string{"echoprog", "help", "topic3"},
+ Stdout: `Help topic 3 long.
+`,
+ },
+ {
Args: []string{"help", "hello"},
Stdout: `Hello prints any strings passed in to stdout preceded by "Hello".
@@ -873,7 +981,7 @@
{
Args: []string{"help", "foo"},
Err: ErrUsage,
- Stderr: `ERROR: toplevelprog: unknown command "foo"
+ Stderr: `ERROR: toplevelprog: unknown command or topic "foo"
Toplevelprog has the echo subprogram and the hello command.
@@ -883,7 +991,13 @@
The toplevelprog commands are:
echoprog Set of echo commands
hello Print strings on stdout preceded by "Hello"
- help Display help for commands
+ help Display help for commands or topics
+Run "toplevelprog help [command]" for command usage.
+
+The toplevelprog additional help topics are:
+ topic1 Help topic 1 short
+ topic2 Help topic 2 short
+Run "toplevelprog help [topic]" for topic details.
The toplevelprog flags are:
-tlextra=false: Print an extra arg for all commands
@@ -941,6 +1055,7 @@
Args: []string{"hello", "--extra", "foo", "bar"},
Err: ErrUsage,
Stderr: `ERROR: flag provided but not defined: -extra
+
Hello prints any strings passed in to stdout preceded by "Hello".
Usage:
@@ -957,6 +1072,7 @@
Args: []string{"-extra", "echoprog", "echoopt", "foo", "bar"},
Err: ErrUsage,
Stderr: `ERROR: flag provided but not defined: -extra
+
Toplevelprog has the echo subprogram and the hello command.
Usage:
@@ -965,7 +1081,13 @@
The toplevelprog commands are:
echoprog Set of echo commands
hello Print strings on stdout preceded by "Hello"
- help Display help for commands
+ help Display help for commands or topics
+Run "toplevelprog help [command]" for command usage.
+
+The toplevelprog additional help topics are:
+ topic1 Help topic 1 short
+ topic2 Help topic 2 short
+Run "toplevelprog help [topic]" for topic details.
The toplevelprog flags are:
-tlextra=false: Print an extra arg for all commands
@@ -1074,7 +1196,8 @@
hello11 Print strings on stdout preceded by "Hello"
hello12 Print strings on stdout preceded by "Hello"
prog2 Set of hello commands
- help Display help for commands
+ help Display help for commands or topics
+Run "prog1 help [command]" for command usage.
The global flags are:
-global1=: global test flag 1
@@ -1092,7 +1215,8 @@
hello11 Print strings on stdout preceded by "Hello"
hello12 Print strings on stdout preceded by "Hello"
prog2 Set of hello commands
- help Display help for commands
+ help Display help for commands or topics
+Run "prog1 help [command]" for command usage.
The global flags are:
-global1=: global test flag 1
@@ -1110,12 +1234,15 @@
hello11 Print strings on stdout preceded by "Hello"
hello12 Print strings on stdout preceded by "Hello"
prog2 Set of hello commands
- help Display help for commands
+ help Display help for commands or topics
+Run "prog1 help [command]" for command usage.
The global flags are:
-global1=: global test flag 1
-global2=0: global test flag 2
================================================================================
+Prog1 Hello11
+
Hello prints any strings passed in to stdout preceded by "Hello".
Usage:
@@ -1123,6 +1250,8 @@
[strings] are arbitrary strings that will be printed.
================================================================================
+Prog1 Hello12
+
Hello prints any strings passed in to stdout preceded by "Hello".
Usage:
@@ -1130,6 +1259,8 @@
[strings] are arbitrary strings that will be printed.
================================================================================
+Prog1 Prog2
+
Prog2 has two variants of hello and a subprogram prog3.
Usage:
@@ -1140,6 +1271,8 @@
prog3 Set of hello commands
hello22 Print strings on stdout preceded by "Hello"
================================================================================
+Prog1 Prog2 Hello21
+
Hello prints any strings passed in to stdout preceded by "Hello".
Usage:
@@ -1147,6 +1280,8 @@
[strings] are arbitrary strings that will be printed.
================================================================================
+Prog1 Prog2 Prog3
+
Prog3 has two variants of hello.
Usage:
@@ -1156,6 +1291,8 @@
hello31 Print strings on stdout preceded by "Hello"
hello32 Print strings on stdout preceded by "Hello"
================================================================================
+Prog1 Prog2 Prog3 Hello31
+
Hello prints any strings passed in to stdout preceded by "Hello".
Usage:
@@ -1163,6 +1300,8 @@
[strings] are arbitrary strings that will be printed.
================================================================================
+Prog1 Prog2 Prog3 Hello32
+
Hello prints any strings passed in to stdout preceded by "Hello".
Usage:
@@ -1170,6 +1309,8 @@
[strings] are arbitrary strings that will be printed.
================================================================================
+Prog1 Prog2 Hello22
+
Hello prints any strings passed in to stdout preceded by "Hello".
Usage:
@@ -1177,18 +1318,19 @@
[strings] are arbitrary strings that will be printed.
================================================================================
-Help displays usage descriptions for this command, or usage descriptions for
-sub-commands.
+Prog1 Help
+
+Help with no args displays the usage of the parent command.
+Help with args displays the usage of the specified sub-command or help topic.
+"help ..." recursively displays help for all commands and topics.
Usage:
- prog1 help [flags] [command ...]
+ prog1 help [flags] [command/topic ...]
-[command ...] is an optional sequence of commands to display detailed usage.
-The special-case "help ..." recursively displays help for all commands.
+[command/topic ...] optionally identifies a specific sub-command or help topic.
The help flags are:
-style=text: The formatting style for help output, either "text" or "godoc".
-================================================================================
`,
},
{
@@ -1202,12 +1344,15 @@
hello21 Print strings on stdout preceded by "Hello"
prog3 Set of hello commands
hello22 Print strings on stdout preceded by "Hello"
- help Display help for commands
+ help Display help for commands or topics
+Run "prog1 prog2 help [command]" for command usage.
The global flags are:
-global1=: global test flag 1
-global2=0: global test flag 2
================================================================================
+Prog1 Prog2 Hello21
+
Hello prints any strings passed in to stdout preceded by "Hello".
Usage:
@@ -1215,6 +1360,8 @@
[strings] are arbitrary strings that will be printed.
================================================================================
+Prog1 Prog2 Prog3
+
Prog3 has two variants of hello.
Usage:
@@ -1224,6 +1371,8 @@
hello31 Print strings on stdout preceded by "Hello"
hello32 Print strings on stdout preceded by "Hello"
================================================================================
+Prog1 Prog2 Prog3 Hello31
+
Hello prints any strings passed in to stdout preceded by "Hello".
Usage:
@@ -1231,6 +1380,8 @@
[strings] are arbitrary strings that will be printed.
================================================================================
+Prog1 Prog2 Prog3 Hello32
+
Hello prints any strings passed in to stdout preceded by "Hello".
Usage:
@@ -1238,6 +1389,8 @@
[strings] are arbitrary strings that will be printed.
================================================================================
+Prog1 Prog2 Hello22
+
Hello prints any strings passed in to stdout preceded by "Hello".
Usage:
@@ -1245,18 +1398,19 @@
[strings] are arbitrary strings that will be printed.
================================================================================
-Help displays usage descriptions for this command, or usage descriptions for
-sub-commands.
+Prog1 Prog2 Help
+
+Help with no args displays the usage of the parent command.
+Help with args displays the usage of the specified sub-command or help topic.
+"help ..." recursively displays help for all commands and topics.
Usage:
- prog1 prog2 help [flags] [command ...]
+ prog1 prog2 help [flags] [command/topic ...]
-[command ...] is an optional sequence of commands to display detailed usage.
-The special-case "help ..." recursively displays help for all commands.
+[command/topic ...] optionally identifies a specific sub-command or help topic.
The help flags are:
-style=text: The formatting style for help output, either "text" or "godoc".
-================================================================================
`,
},
{
@@ -1269,12 +1423,15 @@
The prog3 commands are:
hello31 Print strings on stdout preceded by "Hello"
hello32 Print strings on stdout preceded by "Hello"
- help Display help for commands
+ help Display help for commands or topics
+Run "prog1 prog2 prog3 help [command]" for command usage.
The global flags are:
-global1=: global test flag 1
-global2=0: global test flag 2
================================================================================
+Prog1 Prog2 Prog3 Hello31
+
Hello prints any strings passed in to stdout preceded by "Hello".
Usage:
@@ -1282,6 +1439,8 @@
[strings] are arbitrary strings that will be printed.
================================================================================
+Prog1 Prog2 Prog3 Hello32
+
Hello prints any strings passed in to stdout preceded by "Hello".
Usage:
@@ -1289,18 +1448,19 @@
[strings] are arbitrary strings that will be printed.
================================================================================
-Help displays usage descriptions for this command, or usage descriptions for
-sub-commands.
+Prog1 Prog2 Prog3 Help
+
+Help with no args displays the usage of the parent command.
+Help with args displays the usage of the specified sub-command or help topic.
+"help ..." recursively displays help for all commands and topics.
Usage:
- prog1 prog2 prog3 help [flags] [command ...]
+ prog1 prog2 prog3 help [flags] [command/topic ...]
-[command ...] is an optional sequence of commands to display detailed usage.
-The special-case "help ..." recursively displays help for all commands.
+[command/topic ...] optionally identifies a specific sub-command or help topic.
The help flags are:
-style=text: The formatting style for help output, either "text" or "godoc".
-================================================================================
`,
},
{
@@ -1313,12 +1473,15 @@
The prog3 commands are:
hello31 Print strings on stdout preceded by "Hello"
hello32 Print strings on stdout preceded by "Hello"
- help Display help for commands
+ help Display help for commands or topics
+Run "prog1 prog2 prog3 help [command]" for command usage.
The global flags are:
-global1=: global test flag 1
-global2=0: global test flag 2
================================================================================
+Prog1 Prog2 Prog3 Hello31
+
Hello prints any strings passed in to stdout preceded by "Hello".
Usage:
@@ -1326,6 +1489,8 @@
[strings] are arbitrary strings that will be printed.
================================================================================
+Prog1 Prog2 Prog3 Hello32
+
Hello prints any strings passed in to stdout preceded by "Hello".
Usage:
@@ -1333,18 +1498,19 @@
[strings] are arbitrary strings that will be printed.
================================================================================
-Help displays usage descriptions for this command, or usage descriptions for
-sub-commands.
+Prog1 Prog2 Prog3 Help
+
+Help with no args displays the usage of the parent command.
+Help with args displays the usage of the specified sub-command or help topic.
+"help ..." recursively displays help for all commands and topics.
Usage:
- prog1 prog2 prog3 help [flags] [command ...]
+ prog1 prog2 prog3 help [flags] [command/topic ...]
-[command ...] is an optional sequence of commands to display detailed usage.
-The special-case "help ..." recursively displays help for all commands.
+[command/topic ...] optionally identifies a specific sub-command or help topic.
The help flags are:
-style=text: The formatting style for help output, either "text" or "godoc".
-================================================================================
`,
},
{
@@ -1358,7 +1524,8 @@
hello11 Print strings on stdout preceded by "Hello"
hello12 Print strings on stdout preceded by "Hello"
prog2 Set of hello commands
- help Display help for commands
+ help Display help for commands or topics
+Run "prog1 help [command]" for command usage.
The global flags are:
-global1=: global test flag 1
@@ -1443,18 +1610,17 @@
Prog1 Help
-Help displays usage descriptions for this command, or usage descriptions for
-sub-commands.
+Help with no args displays the usage of the parent command.
+Help with args displays the usage of the specified sub-command or help topic.
+"help ..." recursively displays help for all commands and topics.
Usage:
- prog1 help [flags] [command ...]
+ prog1 help [flags] [command/topic ...]
-[command ...] is an optional sequence of commands to display detailed usage.
-The special-case "help ..." recursively displays help for all commands.
+[command/topic ...] optionally identifies a specific sub-command or help topic.
The help flags are:
-style=text: The formatting style for help output, either "text" or "godoc".
-
`,
},
}
@@ -1503,7 +1669,8 @@
The cmdargs commands are:
echo Print strings on stdout
- help Display help for commands
+ help Display help for commands or topics
+Run "cmdargs help [command]" for command usage.
[strings] are arbitrary strings that will be printed.
@@ -1536,7 +1703,8 @@
The cmdargs commands are:
echo Print strings on stdout
- help Display help for commands
+ help Display help for commands or topics
+Run "cmdargs help [command]" for command usage.
[strings] are arbitrary strings that will be printed.
@@ -1544,6 +1712,8 @@
-global1=: global test flag 1
-global2=0: global test flag 2
================================================================================
+Cmdargs Echo
+
Echo prints any strings passed in to stdout.
Usage:
@@ -1551,24 +1721,25 @@
[strings] are arbitrary strings that will be echoed.
================================================================================
-Help displays usage descriptions for this command, or usage descriptions for
-sub-commands.
+Cmdargs Help
+
+Help with no args displays the usage of the parent command.
+Help with args displays the usage of the specified sub-command or help topic.
+"help ..." recursively displays help for all commands and topics.
Usage:
- cmdargs help [flags] [command ...]
+ cmdargs help [flags] [command/topic ...]
-[command ...] is an optional sequence of commands to display detailed usage.
-The special-case "help ..." recursively displays help for all commands.
+[command/topic ...] optionally identifies a specific sub-command or help topic.
The help flags are:
-style=text: The formatting style for help output, either "text" or "godoc".
-================================================================================
`,
},
{
Args: []string{"help", "foo"},
Err: ErrUsage,
- Stderr: `ERROR: cmdargs: unknown command "foo"
+ Stderr: `ERROR: cmdargs: unknown command or topic "foo"
Cmdargs has the echo command and a Run function with args.
@@ -1578,7 +1749,8 @@
The cmdargs commands are:
echo Print strings on stdout
- help Display help for commands
+ help Display help for commands or topics
+Run "cmdargs help [command]" for command usage.
[strings] are arbitrary strings that will be printed.
@@ -1654,7 +1826,8 @@
The cmdrun commands are:
echo Print strings on stdout
- help Display help for commands
+ help Display help for commands or topics
+Run "cmdrun help [command]" for command usage.
The global flags are:
-global1=: global test flag 1
@@ -1671,7 +1844,8 @@
The cmdrun commands are:
echo Print strings on stdout
- help Display help for commands
+ help Display help for commands or topics
+Run "cmdrun help [command]" for command usage.
The global flags are:
-global1=: global test flag 1
@@ -1702,12 +1876,15 @@
The cmdrun commands are:
echo Print strings on stdout
- help Display help for commands
+ help Display help for commands or topics
+Run "cmdrun help [command]" for command usage.
The global flags are:
-global1=: global test flag 1
-global2=0: global test flag 2
================================================================================
+Cmdrun Echo
+
Echo prints any strings passed in to stdout.
Usage:
@@ -1715,24 +1892,25 @@
[strings] are arbitrary strings that will be echoed.
================================================================================
-Help displays usage descriptions for this command, or usage descriptions for
-sub-commands.
+Cmdrun Help
+
+Help with no args displays the usage of the parent command.
+Help with args displays the usage of the specified sub-command or help topic.
+"help ..." recursively displays help for all commands and topics.
Usage:
- cmdrun help [flags] [command ...]
+ cmdrun help [flags] [command/topic ...]
-[command ...] is an optional sequence of commands to display detailed usage.
-The special-case "help ..." recursively displays help for all commands.
+[command/topic ...] optionally identifies a specific sub-command or help topic.
The help flags are:
-style=text: The formatting style for help output, either "text" or "godoc".
-================================================================================
`,
},
{
Args: []string{"help", "foo"},
Err: ErrUsage,
- Stderr: `ERROR: cmdrun: unknown command "foo"
+ Stderr: `ERROR: cmdrun: unknown command or topic "foo"
Cmdrun has the echo command and a Run function with no args.
@@ -1742,7 +1920,8 @@
The cmdrun commands are:
echo Print strings on stdout
- help Display help for commands
+ help Display help for commands or topics
+Run "cmdrun help [command]" for command usage.
The global flags are:
-global1=: global test flag 1