From c6ff44cf276c5b0068fbbcca834750d2d779ede6 Mon Sep 17 00:00:00 2001 From: Eric Paris Date: Thu, 3 Sep 2015 17:05:50 -0400 Subject: [PATCH] Godep: update github.com/spf13/cobra --- Godeps/Godeps.json | 2 +- .../src/github.com/spf13/cobra/README.md | 4 + .../spf13/cobra/bash_completions.go | 21 ++- .../src/github.com/spf13/cobra/cobra.go | 28 ++- .../src/github.com/spf13/cobra/cobra_test.go | 18 ++ .../src/github.com/spf13/cobra/command.go | 127 +++++++++----- .../src/github.com/spf13/cobra/doc_util.go | 36 ++++ .../src/github.com/spf13/cobra/man_docs.go | 164 ++++++++++++++++++ .../src/github.com/spf13/cobra/man_docs.md | 21 +++ .../github.com/spf13/cobra/man_docs_test.go | 71 ++++++++ .../src/github.com/spf13/cobra/md_docs.go | 31 +++- 11 files changed, 465 insertions(+), 58 deletions(-) create mode 100644 Godeps/_workspace/src/github.com/spf13/cobra/doc_util.go create mode 100644 Godeps/_workspace/src/github.com/spf13/cobra/man_docs.go create mode 100644 Godeps/_workspace/src/github.com/spf13/cobra/man_docs.md create mode 100644 Godeps/_workspace/src/github.com/spf13/cobra/man_docs_test.go diff --git a/Godeps/Godeps.json b/Godeps/Godeps.json index 3f48d15175e..4bb159e3fd5 100644 --- a/Godeps/Godeps.json +++ b/Godeps/Godeps.json @@ -512,7 +512,7 @@ }, { "ImportPath": "github.com/spf13/cobra", - "Rev": "db0518444643a7b170abb78164bbeaf5a2bb816f" + "Rev": "68f5a81a722d56241bd70faf6860ceb05eb27d64" }, { "ImportPath": "github.com/spf13/pflag", diff --git a/Godeps/_workspace/src/github.com/spf13/cobra/README.md b/Godeps/_workspace/src/github.com/spf13/cobra/README.md index b1fb0889ec1..5b97e021c25 100644 --- a/Godeps/_workspace/src/github.com/spf13/cobra/README.md +++ b/Godeps/_workspace/src/github.com/spf13/cobra/README.md @@ -422,6 +422,10 @@ func main() { Cobra can generate a markdown formatted document based on the subcommands, flags, etc. A simple example of how to do this for your command can be found in [Markdown Docs](md_docs.md) +## Generating man pages for your command + +Cobra can generate a man page based on the subcommands, flags, etc. A simple example of how to do this for your command can be found in [Man Docs](man_docs.md) + ## Generating bash completions for your command Cobra can generate a bash completions file. If you add more information to your command these completions can be amazingly powerful and flexible. Read more about [Bash Completions](bash_completions.md) diff --git a/Godeps/_workspace/src/github.com/spf13/cobra/bash_completions.go b/Godeps/_workspace/src/github.com/spf13/cobra/bash_completions.go index 82c4274a8e1..66efd719ab7 100644 --- a/Godeps/_workspace/src/github.com/spf13/cobra/bash_completions.go +++ b/Godeps/_workspace/src/github.com/spf13/cobra/bash_completions.go @@ -19,7 +19,6 @@ const ( func preamble(out *bytes.Buffer) { fmt.Fprintf(out, `#!/bin/bash - __debug() { if [[ -n ${BASH_COMP_DEBUG_FILE} ]]; then @@ -27,6 +26,14 @@ __debug() fi } +# Homebrew on Macs have version 1.3 of bash-completion which doesn't include +# _init_completion. This is a very minimal version of that function. +__my_init_completion() +{ + COMPREPLY=() + _get_comp_words_by_ref cur prev words cword +} + __index_of_word() { local w word=$1 @@ -188,7 +195,11 @@ func postscript(out *bytes.Buffer, name string) { fmt.Fprintf(out, "__start_%s()\n", name) fmt.Fprintf(out, `{ local cur prev words cword - _init_completion -s || return + if declare -F _init_completions >/dev/null 2>&1; then + _init_completion -s || return + else + __my_init_completion || return + fi local c=0 local flags=() @@ -212,7 +223,7 @@ func postscript(out *bytes.Buffer, name string) { func writeCommands(cmd *Command, out *bytes.Buffer) { fmt.Fprintf(out, " commands=()\n") for _, c := range cmd.Commands() { - if len(c.Deprecated) > 0 { + if len(c.Deprecated) > 0 || c == cmd.helpCommand { continue } fmt.Fprintf(out, " commands+=(%q)\n", c.Name()) @@ -292,7 +303,7 @@ func writeRequiredFlag(cmd *Command, out *bytes.Buffer) { fmt.Fprintf(out, " must_have_one_flag=()\n") flags := cmd.NonInheritedFlags() flags.VisitAll(func(flag *pflag.Flag) { - for key, _ := range flag.Annotations { + for key := range flag.Annotations { switch key { case BashCompOneRequiredFlag: format := " must_have_one_flag+=(\"--%s" @@ -321,7 +332,7 @@ func writeRequiredNoun(cmd *Command, out *bytes.Buffer) { func gen(cmd *Command, out *bytes.Buffer) { for _, c := range cmd.Commands() { - if len(c.Deprecated) > 0 { + if len(c.Deprecated) > 0 || c == cmd.helpCommand { continue } gen(c, out) diff --git a/Godeps/_workspace/src/github.com/spf13/cobra/cobra.go b/Godeps/_workspace/src/github.com/spf13/cobra/cobra.go index 78b92b0af3b..1d66a70eb56 100644 --- a/Godeps/_workspace/src/github.com/spf13/cobra/cobra.go +++ b/Godeps/_workspace/src/github.com/spf13/cobra/cobra.go @@ -25,6 +25,13 @@ import ( "text/template" ) +var templateFuncs template.FuncMap = template.FuncMap{ + "trim": strings.TrimSpace, + "rpad": rpad, + "gt": Gt, + "eq": Eq, +} + var initializers []func() // automatic prefix matching can be a dangerous thing to automatically enable in CLI tools. @@ -39,6 +46,20 @@ var MousetrapHelpText string = `This is a command line tool You need to open cmd.exe and run it from there. ` +//AddTemplateFunc adds a template function that's available to Usage and Help +//template generation. +func AddTemplateFunc(name string, tmplFunc interface{}) { + templateFuncs[name] = tmplFunc +} + +//AddTemplateFuncs adds multiple template functions availalble to Usage and +//Help template generation. +func AddTemplateFuncs(tmplFuncs template.FuncMap) { + for k, v := range tmplFuncs { + templateFuncs[k] = v + } +} + //OnInitialize takes a series of func() arguments and appends them to a slice of func(). func OnInitialize(y ...func()) { for _, x := range y { @@ -101,12 +122,7 @@ func rpad(s string, padding int) string { // tmpl executes the given template text on data, writing the result to w. func tmpl(w io.Writer, text string, data interface{}) error { t := template.New("top") - t.Funcs(template.FuncMap{ - "trim": strings.TrimSpace, - "rpad": rpad, - "gt": Gt, - "eq": Eq, - }) + t.Funcs(templateFuncs) template.Must(t.Parse(text)) return t.Execute(w, data) } diff --git a/Godeps/_workspace/src/github.com/spf13/cobra/cobra_test.go b/Godeps/_workspace/src/github.com/spf13/cobra/cobra_test.go index 4fc3b88b845..3aed7dd6466 100644 --- a/Godeps/_workspace/src/github.com/spf13/cobra/cobra_test.go +++ b/Godeps/_workspace/src/github.com/spf13/cobra/cobra_test.go @@ -8,6 +8,7 @@ import ( "runtime" "strings" "testing" + "text/template" "github.com/spf13/pflag" ) @@ -971,3 +972,20 @@ func TestFlagOnPflagCommandLine(t *testing.T) { checkResultContains(t, r, flagName) } + +func TestAddTemplateFunctions(t *testing.T) { + AddTemplateFunc("t", func() bool { return true }) + AddTemplateFuncs(template.FuncMap{ + "f": func() bool { return false }, + "h": func() string { return "Hello," }, + "w": func() string { return "world." }}) + + const usage = "Hello, world." + + c := &Command{} + c.SetUsageTemplate(`{{if t}}{{h}}{{end}}{{if f}}{{h}}{{end}} {{w}}`) + + if us := c.UsageString(); us != usage { + t.Errorf("c.UsageString() != \"%s\", is \"%s\"", usage, us) + } +} diff --git a/Godeps/_workspace/src/github.com/spf13/cobra/command.go b/Godeps/_workspace/src/github.com/spf13/cobra/command.go index cbbc3264f28..bf642b536ac 100644 --- a/Godeps/_workspace/src/github.com/spf13/cobra/command.go +++ b/Godeps/_workspace/src/github.com/spf13/cobra/command.go @@ -66,14 +66,24 @@ type Command struct { // All functions get the same args, the arguments after the command name // PersistentPreRun: children of this command will inherit and execute PersistentPreRun func(cmd *Command, args []string) + // PersistentPreRunE: PersistentPreRun but returns an error + PersistentPreRunE func(cmd *Command, args []string) error // PreRun: children of this command will not inherit. PreRun func(cmd *Command, args []string) + // PreRunE: PreRun but returns an error + PreRunE func(cmd *Command, args []string) error // Run: Typically the actual work function. Most commands will only implement this Run func(cmd *Command, args []string) + // RunE: Run but returns an error + RunE func(cmd *Command, args []string) error // PostRun: run after the Run command. PostRun func(cmd *Command, args []string) + // PostRunE: PostRun but returns an error + PostRunE func(cmd *Command, args []string) error // PersistentPostRun: children of this command will inherit and execute after PostRun PersistentPostRun func(cmd *Command, args []string) + // PersistentPostRunE: PersistentPostRun but returns an error + PersistentPostRunE func(cmd *Command, args []string) error // Commands is the list of commands supported by this program. commands []*Command // Parent Command for this command @@ -92,7 +102,6 @@ type Command struct { helpTemplate string // Can be defined by Application helpFunc func(*Command, []string) // Help can be defined by application helpCommand *Command // The help command - helpFlagVal bool // The global normalization function that we can use on every pFlag set and children commands globNormFunc func(f *flag.FlagSet, name string) flag.NormalizedName } @@ -179,32 +188,21 @@ func (c *Command) UsageFunc() (f func(*Command) error) { } } } + +// HelpFunc returns either the function set by SetHelpFunc for this command +// or a parent, or it returns a function which calls c.Help() func (c *Command) HelpFunc() func(*Command, []string) { - if c.helpFunc != nil { - return c.helpFunc + cmd := c + for cmd != nil { + if cmd.helpFunc != nil { + return cmd.helpFunc + } + cmd = cmd.parent } - - if c.HasParent() { - return c.parent.HelpFunc() - } else { - return func(c *Command, args []string) { - if len(args) == 0 { - // Help called without any topic, calling on root - c.Root().Help() - return - } - - cmd, _, e := c.Root().Find(args) - if cmd == nil || e != nil { - c.Printf("Unknown help topic %#q.", args) - - c.Root().Usage() - } else { - err := cmd.Help() - if err != nil { - c.Println(err) - } - } + return func(*Command, []string) { + err := c.Help() + if err != nil { + c.Println(err) } } } @@ -270,7 +268,7 @@ Global Flags: {{.InheritedFlags.FlagUsages}}{{end}}{{if .HasHelpSubCommands}} Additional help topics: {{range .Commands}}{{if .IsHelpCommand}} - {{rpad .CommandPath .CommandPathPadding}} {{.Short}}{{end}}}{{end}}{{end}}{{ if .HasSubCommands }} + {{rpad .CommandPath .CommandPathPadding}} {{.Short}}{{end}}{{end}}{{end}}{{ if .HasSubCommands }} Use "{{.CommandPath}} [command] --help" for more information about a command. {{end}}` @@ -450,13 +448,24 @@ func (c *Command) execute(a []string) (err error) { c.Printf("Command %q is deprecated, %s\n", c.Name(), c.Deprecated) } + // initialize help flag as the last point possible to allow for user + // overriding + c.initHelpFlag() + err = c.ParseFlags(a) if err != nil { return err } // If help is called, regardless of other flags, return we want help - // Also say we need help if c.Run is nil. - if c.helpFlagVal || !c.Runnable() { + // Also say we need help if the command isn't runnable. + helpVal, err := c.Flags().GetBool("help") + if err != nil { + // should be impossible to get here as we always declare a help + // flag in initHelpFlag() + c.Println("\"help\" flag declared as non-bool. Please correct your code") + return err + } + if helpVal || !c.Runnable() { return flag.ErrHelp } @@ -464,22 +473,45 @@ func (c *Command) execute(a []string) (err error) { argWoFlags := c.Flags().Args() for p := c; p != nil; p = p.Parent() { - if p.PersistentPreRun != nil { + if p.PersistentPreRunE != nil { + if err := p.PersistentPostRunE(c, argWoFlags); err != nil { + return err + } + break + } else if p.PersistentPreRun != nil { p.PersistentPreRun(c, argWoFlags) break } } - if c.PreRun != nil { + if c.PreRunE != nil { + if err := c.PreRunE(c, argWoFlags); err != nil { + return err + } + } else if c.PreRun != nil { c.PreRun(c, argWoFlags) } - c.Run(c, argWoFlags) - - if c.PostRun != nil { + if c.RunE != nil { + if err := c.RunE(c, argWoFlags); err != nil { + return err + } + } else { + c.Run(c, argWoFlags) + } + if c.PostRunE != nil { + if err := c.PostRunE(c, argWoFlags); err != nil { + return err + } + } else if c.PostRun != nil { c.PostRun(c, argWoFlags) } for p := c; p != nil; p = p.Parent() { - if p.PersistentPostRun != nil { + if p.PersistentPostRunE != nil { + if err := p.PersistentPostRunE(c, argWoFlags); err != nil { + return err + } + break + } else if p.PersistentPostRun != nil { p.PersistentPostRun(c, argWoFlags) break } @@ -526,7 +558,7 @@ func (c *Command) Execute() (err error) { // initialize help as the last point possible to allow for user // overriding - c.initHelp() + c.initHelpCmd() var args []string @@ -550,7 +582,7 @@ func (c *Command) Execute() (err error) { err = cmd.execute(flags) if err != nil { if err == flag.ErrHelp { - cmd.Help() + cmd.HelpFunc()(cmd, args) return nil } c.Println(cmd.UsageString()) @@ -560,7 +592,13 @@ func (c *Command) Execute() (err error) { return } -func (c *Command) initHelp() { +func (c *Command) initHelpFlag() { + if c.Flags().Lookup("help") == nil { + c.Flags().BoolP("help", "h", false, "help for "+c.Name()) + } +} + +func (c *Command) initHelpCmd() { if c.helpCommand == nil { if !c.HasSubCommands() { return @@ -571,9 +609,19 @@ func (c *Command) initHelp() { Short: "Help about any command", Long: `Help provides help for any command in the application. Simply type ` + c.Name() + ` help [path to command] for full details.`, - Run: c.HelpFunc(), PersistentPreRun: func(cmd *Command, args []string) {}, PersistentPostRun: func(cmd *Command, args []string) {}, + + Run: func(c *Command, args []string) { + cmd, _, e := c.Root().Find(args) + if cmd == nil || e != nil { + c.Printf("Unknown help topic %#q.", args) + c.Root().Usage() + } else { + helpFunc := cmd.HelpFunc() + helpFunc(cmd, args) + } + }, } } c.AddCommand(c.helpCommand) @@ -794,7 +842,7 @@ func (c *Command) HasExample() bool { // Determine if the command is itself runnable func (c *Command) Runnable() bool { - return c.Run != nil + return c.Run != nil || c.RunE != nil } // Determine if the command has children commands @@ -859,7 +907,6 @@ func (c *Command) Flags() *flag.FlagSet { c.flagErrorBuf = new(bytes.Buffer) } c.flags.SetOutput(c.flagErrorBuf) - c.PersistentFlags().BoolVarP(&c.helpFlagVal, "help", "h", false, "help for "+c.Name()) } return c.flags } diff --git a/Godeps/_workspace/src/github.com/spf13/cobra/doc_util.go b/Godeps/_workspace/src/github.com/spf13/cobra/doc_util.go new file mode 100644 index 00000000000..9c20bca84a6 --- /dev/null +++ b/Godeps/_workspace/src/github.com/spf13/cobra/doc_util.go @@ -0,0 +1,36 @@ +// Copyright 2015 Red Hat Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package cobra + +import () + +// Test to see if we have a reason to print See Also information in docs +// Basically this is a test for a parent commend or a subcommand which is +// both not deprecated and not the autogenerated help command. +func (cmd *Command) hasSeeAlso() bool { + if cmd.HasParent() { + return true + } + children := cmd.Commands() + if len(children) == 0 { + return false + } + for _, c := range children { + if len(c.Deprecated) != 0 || c == cmd.helpCommand { + continue + } + return true + } + return false +} diff --git a/Godeps/_workspace/src/github.com/spf13/cobra/man_docs.go b/Godeps/_workspace/src/github.com/spf13/cobra/man_docs.go new file mode 100644 index 00000000000..f260990e938 --- /dev/null +++ b/Godeps/_workspace/src/github.com/spf13/cobra/man_docs.go @@ -0,0 +1,164 @@ +// Copyright 2015 Red Hat Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package cobra + +import ( + "bytes" + "fmt" + "os" + "sort" + "strings" + "time" + + mangen "github.com/cpuguy83/go-md2man/md2man" + "github.com/spf13/pflag" +) + +func GenManTree(cmd *Command, projectName, dir string) { + cmd.GenManTree(projectName, dir) +} + +func (cmd *Command) GenManTree(projectName, dir string) { + for _, c := range cmd.Commands() { + if len(c.Deprecated) != 0 || c == cmd.helpCommand { + continue + } + GenManTree(c, projectName, dir) + } + out := new(bytes.Buffer) + + cmd.GenMan(projectName, out) + + filename := cmd.CommandPath() + filename = dir + strings.Replace(filename, " ", "-", -1) + ".1" + outFile, err := os.Create(filename) + if err != nil { + fmt.Println(err) + os.Exit(1) + } + defer outFile.Close() + _, err = outFile.Write(out.Bytes()) + if err != nil { + fmt.Println(err) + os.Exit(1) + } +} + +func GenMan(cmd *Command, projectName string, out *bytes.Buffer) { + cmd.GenMan(projectName, out) +} + +func (cmd *Command) GenMan(projectName string, out *bytes.Buffer) { + + buf := genMarkdown(cmd, projectName) + final := mangen.Render(buf) + out.Write(final) +} + +func manPreamble(out *bytes.Buffer, projectName, name, short, long string) { + fmt.Fprintf(out, `%% %s(1) +# NAME +`, projectName) + fmt.Fprintf(out, "%s \\- %s\n\n", name, short) + fmt.Fprintf(out, "# SYNOPSIS\n") + fmt.Fprintf(out, "**%s** [OPTIONS]\n\n", name) + fmt.Fprintf(out, "# DESCRIPTION\n") + fmt.Fprintf(out, "%s\n\n", long) +} + +func manPrintFlags(out *bytes.Buffer, flags *pflag.FlagSet) { + flags.VisitAll(func(flag *pflag.Flag) { + if len(flag.Deprecated) > 0 { + return + } + format := "" + if len(flag.Shorthand) > 0 { + format = "**-%s**, **--%s**" + } else { + format = "%s**--%s**" + } + if len(flag.NoOptDefVal) > 0 { + format = format + "[" + } + if flag.Value.Type() == "string" { + // put quotes on the value + format = format + "=%q" + } else { + format = format + "=%s" + } + if len(flag.NoOptDefVal) > 0 { + format = format + "]" + } + format = format + "\n\t%s\n\n" + fmt.Fprintf(out, format, flag.Shorthand, flag.Name, flag.DefValue, flag.Usage) + }) +} + +func manPrintOptions(out *bytes.Buffer, command *Command) { + flags := command.NonInheritedFlags() + if flags.HasFlags() { + fmt.Fprintf(out, "# OPTIONS\n") + manPrintFlags(out, flags) + fmt.Fprintf(out, "\n") + } + flags = command.InheritedFlags() + if flags.HasFlags() { + fmt.Fprintf(out, "# OPTIONS INHERITED FROM PARENT COMMANDS\n") + manPrintFlags(out, flags) + fmt.Fprintf(out, "\n") + } +} + +func genMarkdown(cmd *Command, projectName string) []byte { + // something like `rootcmd subcmd1 subcmd2` + commandName := cmd.CommandPath() + // something like `rootcmd-subcmd1-subcmd2` + dashCommandName := strings.Replace(commandName, " ", "-", -1) + + buf := new(bytes.Buffer) + + short := cmd.Short + long := cmd.Long + if len(long) == 0 { + long = short + } + + manPreamble(buf, projectName, commandName, short, long) + manPrintOptions(buf, cmd) + + if len(cmd.Example) > 0 { + fmt.Fprintf(buf, "# EXAMPLE\n") + fmt.Fprintf(buf, "```\n%s\n```\n", cmd.Example) + } + + if cmd.hasSeeAlso() { + fmt.Fprintf(buf, "# SEE ALSO\n") + if cmd.HasParent() { + fmt.Fprintf(buf, "**%s(1)**, ", cmd.Parent().CommandPath()) + } + + children := cmd.Commands() + sort.Sort(byName(children)) + for _, c := range children { + if len(c.Deprecated) != 0 || c == cmd.helpCommand { + continue + } + fmt.Fprintf(buf, "**%s-%s(1)**, ", dashCommandName, c.Name()) + } + fmt.Fprintf(buf, "\n") + } + + fmt.Fprintf(buf, "# HISTORY\n%s Auto generated by spf13/cobra\n", time.Now().UTC()) + return buf.Bytes() +} diff --git a/Godeps/_workspace/src/github.com/spf13/cobra/man_docs.md b/Godeps/_workspace/src/github.com/spf13/cobra/man_docs.md new file mode 100644 index 00000000000..3516d37cef4 --- /dev/null +++ b/Godeps/_workspace/src/github.com/spf13/cobra/man_docs.md @@ -0,0 +1,21 @@ +# Generating Man Pages For Your Own cobra.Command + +Generating bash completions from a cobra command is incredibly easy. An example is as follows: + +```go +package main + +import ( + "github.com/spf13/cobra" +) + +func main() { + cmd := &cobra.Command{ + Use: "test", + Short: "my test program", + } + cmd.GenManTree("/tmp") +} +``` + +That will get you a man page `/tmp/test.1` diff --git a/Godeps/_workspace/src/github.com/spf13/cobra/man_docs_test.go b/Godeps/_workspace/src/github.com/spf13/cobra/man_docs_test.go new file mode 100644 index 00000000000..6e31ab3b33b --- /dev/null +++ b/Godeps/_workspace/src/github.com/spf13/cobra/man_docs_test.go @@ -0,0 +1,71 @@ +package cobra + +import ( + "bytes" + "fmt" + "os" + "strings" + "testing" +) + +var _ = fmt.Println +var _ = os.Stderr + +func translate(in string) string { + return strings.Replace(in, "-", "\\-", -1) +} + +func TestGenManDoc(t *testing.T) { + c := initializeWithRootCmd() + // Need two commands to run the command alphabetical sort + cmdEcho.AddCommand(cmdTimes, cmdEchoSub, cmdDeprecated) + c.AddCommand(cmdPrint, cmdEcho) + cmdRootWithRun.PersistentFlags().StringVarP(&flags2a, "rootflag", "r", "two", strtwoParentHelp) + + out := new(bytes.Buffer) + + // We generate on a subcommand so we have both subcommands and parents + cmdEcho.GenMan("PROJECT", out) + found := out.String() + + // Our description + expected := translate(cmdEcho.Name()) + if !strings.Contains(found, expected) { + t.Errorf("Unexpected response.\nExpecting to contain: \n %q\nGot:\n %q\n", expected, found) + } + + // Better have our example + expected = translate(cmdEcho.Name()) + if !strings.Contains(found, expected) { + t.Errorf("Unexpected response.\nExpecting to contain: \n %q\nGot:\n %q\n", expected, found) + } + + // A local flag + expected = "boolone" + if !strings.Contains(found, expected) { + t.Errorf("Unexpected response.\nExpecting to contain: \n %q\nGot:\n %q\n", expected, found) + } + + // persistent flag on parent + expected = "rootflag" + if !strings.Contains(found, expected) { + t.Errorf("Unexpected response.\nExpecting to contain: \n %q\nGot:\n %q\n", expected, found) + } + + // We better output info about our parent + expected = translate(cmdRootWithRun.Name()) + if !strings.Contains(found, expected) { + t.Errorf("Unexpected response.\nExpecting to contain: \n %q\nGot:\n %q\n", expected, found) + } + + // And about subcommands + expected = translate(cmdEchoSub.Name()) + if !strings.Contains(found, expected) { + t.Errorf("Unexpected response.\nExpecting to contain: \n %q\nGot:\n %q\n", expected, found) + } + + unexpected := translate(cmdDeprecated.Name()) + if strings.Contains(found, unexpected) { + t.Errorf("Unexpected response.\nFound: %v\nBut should not have!!\n", unexpected) + } +} diff --git a/Godeps/_workspace/src/github.com/spf13/cobra/md_docs.go b/Godeps/_workspace/src/github.com/spf13/cobra/md_docs.go index 6092c85af68..dde5b114037 100644 --- a/Godeps/_workspace/src/github.com/spf13/cobra/md_docs.go +++ b/Godeps/_workspace/src/github.com/spf13/cobra/md_docs.go @@ -47,10 +47,18 @@ func (s byName) Swap(i, j int) { s[i], s[j] = s[j], s[i] } func (s byName) Less(i, j int) bool { return s[i].Name() < s[j].Name() } func GenMarkdown(cmd *Command, out *bytes.Buffer) { - GenMarkdownCustom(cmd, out, func(s string) string { return s }) + cmd.GenMarkdown(out) +} + +func (cmd *Command) GenMarkdown(out *bytes.Buffer) { + cmd.GenMarkdownCustom(out, func(s string) string { return s }) } func GenMarkdownCustom(cmd *Command, out *bytes.Buffer, linkHandler func(string) string) { + cmd.GenMarkdownCustom(out, linkHandler) +} + +func (cmd *Command) GenMarkdownCustom(out *bytes.Buffer, linkHandler func(string) string) { name := cmd.CommandPath() short := cmd.Short @@ -75,7 +83,7 @@ func GenMarkdownCustom(cmd *Command, out *bytes.Buffer, linkHandler func(string) printOptions(out, cmd, name) - if len(cmd.Commands()) > 0 || cmd.HasParent() { + if cmd.hasSeeAlso() { fmt.Fprintf(out, "### SEE ALSO\n") if cmd.HasParent() { parent := cmd.Parent() @@ -89,7 +97,7 @@ func GenMarkdownCustom(cmd *Command, out *bytes.Buffer, linkHandler func(string) sort.Sort(byName(children)) for _, child := range children { - if len(child.Deprecated) > 0 { + if len(child.Deprecated) > 0 || child == cmd.helpCommand { continue } cname := name + " " + child.Name() @@ -104,18 +112,29 @@ func GenMarkdownCustom(cmd *Command, out *bytes.Buffer, linkHandler func(string) } func GenMarkdownTree(cmd *Command, dir string) { + cmd.GenMarkdownTree(dir) +} + +func (cmd *Command) GenMarkdownTree(dir string) { identity := func(s string) string { return s } emptyStr := func(s string) string { return "" } - GenMarkdownTreeCustom(cmd, dir, emptyStr, identity) + cmd.GenMarkdownTreeCustom(dir, emptyStr, identity) } func GenMarkdownTreeCustom(cmd *Command, dir string, filePrepender func(string) string, linkHandler func(string) string) { + cmd.GenMarkdownTreeCustom(dir, filePrepender, linkHandler) +} + +func (cmd *Command) GenMarkdownTreeCustom(dir string, filePrepender func(string) string, linkHandler func(string) string) { for _, c := range cmd.Commands() { - GenMarkdownTreeCustom(c, dir, filePrepender, linkHandler) + if len(c.Deprecated) != 0 || c == cmd.helpCommand { + continue + } + c.GenMarkdownTreeCustom(dir, filePrepender, linkHandler) } out := new(bytes.Buffer) - GenMarkdownCustom(cmd, out, linkHandler) + cmd.GenMarkdownCustom(out, linkHandler) filename := cmd.CommandPath() filename = dir + strings.Replace(filename, " ", "_", -1) + ".md"