vendor: Update cobra and vendor cobra/doc

This commit is contained in:
Derek Parker 2016-02-19 10:32:05 -08:00
parent 8d4d0871cf
commit 460f0c910c
21 changed files with 3099 additions and 538 deletions

31
Godeps/Godeps.json generated

@ -2,7 +2,34 @@
"ImportPath": "github.com/derekparker/delve", "ImportPath": "github.com/derekparker/delve",
"GoVersion": "go1.5", "GoVersion": "go1.5",
"Packages": [ "Packages": [
"./..." "github.com/derekparker/delve/cmd/dlv",
"github.com/derekparker/delve/cmd/dlv/cmds",
"github.com/derekparker/delve/config",
"github.com/derekparker/delve/dwarf/frame",
"github.com/derekparker/delve/dwarf/line",
"github.com/derekparker/delve/dwarf/op",
"github.com/derekparker/delve/dwarf/reader",
"github.com/derekparker/delve/dwarf/util",
"github.com/derekparker/delve/localtests/bf",
"github.com/derekparker/delve/localtests/changeme",
"github.com/derekparker/delve/localtests/defer",
"github.com/derekparker/delve/localtests/fc",
"github.com/derekparker/delve/localtests/fosdem/debug",
"github.com/derekparker/delve/localtests/fosdem/exec",
"github.com/derekparker/delve/localtests/fosdem/trace",
"github.com/derekparker/delve/localtests/step",
"github.com/derekparker/delve/localtests/stepbug",
"github.com/derekparker/delve/localtests/test-on",
"github.com/derekparker/delve/proc",
"github.com/derekparker/delve/proc/test",
"github.com/derekparker/delve/scripts",
"github.com/derekparker/delve/service",
"github.com/derekparker/delve/service/api",
"github.com/derekparker/delve/service/debugger",
"github.com/derekparker/delve/service/rpc",
"github.com/derekparker/delve/service/test",
"github.com/derekparker/delve/terminal",
"github.com/derekparker/delve/version"
], ],
"Deps": [ "Deps": [
{ {
@ -33,7 +60,7 @@
}, },
{ {
"ImportPath": "github.com/spf13/cobra", "ImportPath": "github.com/spf13/cobra",
"Rev": "d732ab3a34e6e9e6b5bdac80707c2b6bad852936" "Rev": "65a708cee0a4424f4e353d031ce440643e312f92"
}, },
{ {
"ImportPath": "github.com/spf13/pflag", "ImportPath": "github.com/spf13/pflag",

3
vendor/github.com/spf13/cobra/.mailmap generated vendored Normal file

@ -0,0 +1,3 @@
Steve Francia <steve.francia@gmail.com>
Bjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>
Fabiano Franz <ffranz@redhat.com> <contact@fabianofranz.com>

@ -5,5 +5,5 @@ go:
- 1.5.1 - 1.5.1
- tip - tip
script: script:
- go test ./... - go test -v ./...
- go build - go build

File diff suppressed because it is too large Load Diff

@ -1,8 +1,8 @@
package cobra package cobra
import ( import (
"bytes"
"fmt" "fmt"
"io"
"os" "os"
"sort" "sort"
"strings" "strings"
@ -16,9 +16,12 @@ const (
BashCompSubdirsInDir = "cobra_annotation_bash_completion_subdirs_in_dir" BashCompSubdirsInDir = "cobra_annotation_bash_completion_subdirs_in_dir"
) )
func preamble(out *bytes.Buffer) { func preamble(out io.Writer, name string) error {
fmt.Fprintf(out, `#!/bin/bash _, err := fmt.Fprintf(out, "# bash completion for %-36s -*- shell-script -*-\n", name)
if err != nil {
return err
}
_, err = fmt.Fprintf(out, `
__debug() __debug()
{ {
if [[ -n ${BASH_COMP_DEBUG_FILE} ]]; then if [[ -n ${BASH_COMP_DEBUG_FILE} ]]; then
@ -60,7 +63,9 @@ __handle_reply()
__debug "${FUNCNAME}" __debug "${FUNCNAME}"
case $cur in case $cur in
-*) -*)
compopt -o nospace if [[ $(type -t compopt) = "builtin" ]]; then
compopt -o nospace
fi
local allflags local allflags
if [ ${#must_have_one_flag[@]} -ne 0 ]; then if [ ${#must_have_one_flag[@]} -ne 0 ]; then
allflags=("${must_have_one_flag[@]}") allflags=("${must_have_one_flag[@]}")
@ -68,7 +73,9 @@ __handle_reply()
allflags=("${flags[*]} ${two_word_flags[*]}") allflags=("${flags[*]} ${two_word_flags[*]}")
fi fi
COMPREPLY=( $(compgen -W "${allflags[*]}" -- "$cur") ) COMPREPLY=( $(compgen -W "${allflags[*]}" -- "$cur") )
[[ $COMPREPLY == *= ]] || compopt +o nospace if [[ $(type -t compopt) = "builtin" ]]; then
[[ $COMPREPLY == *= ]] || compopt +o nospace
fi
return 0; return 0;
;; ;;
esac esac
@ -99,6 +106,8 @@ __handle_reply()
if [[ ${#COMPREPLY[@]} -eq 0 ]]; then if [[ ${#COMPREPLY[@]} -eq 0 ]]; then
declare -F __custom_func >/dev/null && __custom_func declare -F __custom_func >/dev/null && __custom_func
fi fi
__ltrim_colon_completions "$cur"
} }
# The arguments should be in the form "ext1|ext2|extn" # The arguments should be in the form "ext1|ext2|extn"
@ -120,8 +129,10 @@ __handle_flag()
# if a command required a flag, and we found it, unset must_have_one_flag() # if a command required a flag, and we found it, unset must_have_one_flag()
local flagname=${words[c]} local flagname=${words[c]}
local flagvalue
# if the word contained an = # if the word contained an =
if [[ ${words[c]} == *"="* ]]; then if [[ ${words[c]} == *"="* ]]; then
flagvalue=${flagname#*=} # take in as flagvalue after the =
flagname=${flagname%%=*} # strip everything after the = flagname=${flagname%%=*} # strip everything after the =
flagname="${flagname}=" # but put the = back flagname="${flagname}=" # but put the = back
fi fi
@ -130,6 +141,15 @@ __handle_flag()
must_have_one_flag=() must_have_one_flag=()
fi fi
# keep flag value with flagname as flaghash
if [ ${flagvalue} ] ; then
flaghash[${flagname}]=${flagvalue}
elif [ ${words[ $((c+1)) ]} ] ; then
flaghash[${flagname}]=${words[ $((c+1)) ]}
else
flaghash[${flagname}]="true" # pad "true" for bool flag
fi
# skip the argument to a two word flag # skip the argument to a two word flag
if __contains_word "${words[c]}" "${two_word_flags[@]}"; then if __contains_word "${words[c]}" "${two_word_flags[@]}"; then
c=$((c+1)) c=$((c+1))
@ -139,7 +159,6 @@ __handle_flag()
fi fi
fi fi
# skip the flag itself
c=$((c+1)) c=$((c+1))
} }
@ -162,9 +181,13 @@ __handle_command()
local next_command local next_command
if [[ -n ${last_command} ]]; then if [[ -n ${last_command} ]]; then
next_command="_${last_command}_${words[c]}" next_command="_${last_command}_${words[c]//:/__}"
else else
next_command="_${words[c]}" if [[ $c -eq 0 ]]; then
next_command="_$(basename ${words[c]//:/__})"
else
next_command="_${words[c]//:/__}"
fi
fi fi
c=$((c+1)) c=$((c+1))
__debug "${FUNCNAME}: looking for ${next_command}" __debug "${FUNCNAME}: looking for ${next_command}"
@ -175,13 +198,15 @@ __handle_word()
{ {
if [[ $c -ge $cword ]]; then if [[ $c -ge $cword ]]; then
__handle_reply __handle_reply
return return
fi fi
__debug "${FUNCNAME}: c is $c words[c] is ${words[c]}" __debug "${FUNCNAME}: c is $c words[c] is ${words[c]}"
if [[ "${words[c]}" == -* ]]; then if [[ "${words[c]}" == -* ]]; then
__handle_flag __handle_flag
elif __contains_word "${words[c]}" "${commands[@]}"; then elif __contains_word "${words[c]}" "${commands[@]}"; then
__handle_command __handle_command
elif [[ $c -eq 0 ]] && __contains_word "$(basename ${words[c]})" "${commands[@]}"; then
__handle_command
else else
__handle_noun __handle_noun
fi fi
@ -189,13 +214,19 @@ __handle_word()
} }
`) `)
return err
} }
func postscript(out *bytes.Buffer, name string) { func postscript(w io.Writer, name string) error {
fmt.Fprintf(out, "__start_%s()\n", name) name = strings.Replace(name, ":", "__", -1)
fmt.Fprintf(out, `{ _, err := fmt.Fprintf(w, "__start_%s()\n", name)
if err != nil {
return err
}
_, err = fmt.Fprintf(w, `{
local cur prev words cword local cur prev words cword
if declare -F _init_completions >/dev/null 2>&1; then declare -A flaghash 2>/dev/null || :
if declare -F _init_completion >/dev/null 2>&1; then
_init_completion -s || return _init_completion -s || return
else else
__my_init_completion || return __my_init_completion || return
@ -216,49 +247,77 @@ func postscript(out *bytes.Buffer, name string) {
} }
`, name) `, name)
fmt.Fprintf(out, "complete -F __start_%s %s\n", name, name) if err != nil {
fmt.Fprintf(out, "# ex: ts=4 sw=4 et filetype=sh\n") return err
}
_, err = fmt.Fprintf(w, `if [[ $(type -t compopt) = "builtin" ]]; then
complete -o default -F __start_%s %s
else
complete -o default -o nospace -F __start_%s %s
fi
`, name, name, name, name)
if err != nil {
return err
}
_, err = fmt.Fprintf(w, "# ex: ts=4 sw=4 et filetype=sh\n")
return err
} }
func writeCommands(cmd *Command, out *bytes.Buffer) { func writeCommands(cmd *Command, w io.Writer) error {
fmt.Fprintf(out, " commands=()\n") if _, err := fmt.Fprintf(w, " commands=()\n"); err != nil {
return err
}
for _, c := range cmd.Commands() { for _, c := range cmd.Commands() {
if !c.IsAvailableCommand() || c == cmd.helpCommand { if !c.IsAvailableCommand() || c == cmd.helpCommand {
continue continue
} }
fmt.Fprintf(out, " commands+=(%q)\n", c.Name()) if _, err := fmt.Fprintf(w, " commands+=(%q)\n", c.Name()); err != nil {
return err
}
} }
fmt.Fprintf(out, "\n") _, err := fmt.Fprintf(w, "\n")
return err
} }
func writeFlagHandler(name string, annotations map[string][]string, out *bytes.Buffer) { func writeFlagHandler(name string, annotations map[string][]string, w io.Writer) error {
for key, value := range annotations { for key, value := range annotations {
switch key { switch key {
case BashCompFilenameExt: case BashCompFilenameExt:
fmt.Fprintf(out, " flags_with_completion+=(%q)\n", name) _, err := fmt.Fprintf(w, " flags_with_completion+=(%q)\n", name)
if err != nil {
return err
}
if len(value) > 0 { if len(value) > 0 {
ext := "__handle_filename_extension_flag " + strings.Join(value, "|") ext := "__handle_filename_extension_flag " + strings.Join(value, "|")
fmt.Fprintf(out, " flags_completion+=(%q)\n", ext) _, err = fmt.Fprintf(w, " flags_completion+=(%q)\n", ext)
} else { } else {
ext := "_filedir" ext := "_filedir"
fmt.Fprintf(out, " flags_completion+=(%q)\n", ext) _, err = fmt.Fprintf(w, " flags_completion+=(%q)\n", ext)
}
if err != nil {
return err
} }
case BashCompSubdirsInDir: case BashCompSubdirsInDir:
fmt.Fprintf(out, " flags_with_completion+=(%q)\n", name) _, err := fmt.Fprintf(w, " flags_with_completion+=(%q)\n", name)
if len(value) == 1 { if len(value) == 1 {
ext := "__handle_subdirs_in_dir_flag " + value[0] ext := "__handle_subdirs_in_dir_flag " + value[0]
fmt.Fprintf(out, " flags_completion+=(%q)\n", ext) _, err = fmt.Fprintf(w, " flags_completion+=(%q)\n", ext)
} else { } else {
ext := "_filedir -d" ext := "_filedir -d"
fmt.Fprintf(out, " flags_completion+=(%q)\n", ext) _, err = fmt.Fprintf(w, " flags_completion+=(%q)\n", ext)
}
if err != nil {
return err
} }
} }
} }
return nil
} }
func writeShortFlag(flag *pflag.Flag, out *bytes.Buffer) { func writeShortFlag(flag *pflag.Flag, w io.Writer) error {
b := (flag.Value.Type() == "bool") b := (flag.Value.Type() == "bool")
name := flag.Shorthand name := flag.Shorthand
format := " " format := " "
@ -266,11 +325,13 @@ func writeShortFlag(flag *pflag.Flag, out *bytes.Buffer) {
format += "two_word_" format += "two_word_"
} }
format += "flags+=(\"-%s\")\n" format += "flags+=(\"-%s\")\n"
fmt.Fprintf(out, format, name) if _, err := fmt.Fprintf(w, format, name); err != nil {
writeFlagHandler("-"+name, flag.Annotations, out) return err
}
return writeFlagHandler("-"+name, flag.Annotations, w)
} }
func writeFlag(flag *pflag.Flag, out *bytes.Buffer) { func writeFlag(flag *pflag.Flag, w io.Writer) error {
b := (flag.Value.Type() == "bool") b := (flag.Value.Type() == "bool")
name := flag.Name name := flag.Name
format := " flags+=(\"--%s" format := " flags+=(\"--%s"
@ -278,30 +339,64 @@ func writeFlag(flag *pflag.Flag, out *bytes.Buffer) {
format += "=" format += "="
} }
format += "\")\n" format += "\")\n"
fmt.Fprintf(out, format, name) if _, err := fmt.Fprintf(w, format, name); err != nil {
writeFlagHandler("--"+name, flag.Annotations, out) return err
}
return writeFlagHandler("--"+name, flag.Annotations, w)
} }
func writeFlags(cmd *Command, out *bytes.Buffer) { func writeFlags(cmd *Command, w io.Writer) error {
fmt.Fprintf(out, ` flags=() _, err := fmt.Fprintf(w, ` flags=()
two_word_flags=() two_word_flags=()
flags_with_completion=() flags_with_completion=()
flags_completion=() flags_completion=()
`) `)
if err != nil {
return err
}
var visitErr error
cmd.NonInheritedFlags().VisitAll(func(flag *pflag.Flag) { cmd.NonInheritedFlags().VisitAll(func(flag *pflag.Flag) {
writeFlag(flag, out) if err := writeFlag(flag, w); err != nil {
visitErr = err
return
}
if len(flag.Shorthand) > 0 { if len(flag.Shorthand) > 0 {
writeShortFlag(flag, out) if err := writeShortFlag(flag, w); err != nil {
visitErr = err
return
}
} }
}) })
if visitErr != nil {
return visitErr
}
cmd.InheritedFlags().VisitAll(func(flag *pflag.Flag) {
if err := writeFlag(flag, w); err != nil {
visitErr = err
return
}
if len(flag.Shorthand) > 0 {
if err := writeShortFlag(flag, w); err != nil {
visitErr = err
return
}
}
})
if visitErr != nil {
return visitErr
}
fmt.Fprintf(out, "\n") _, err = fmt.Fprintf(w, "\n")
return err
} }
func writeRequiredFlag(cmd *Command, out *bytes.Buffer) { func writeRequiredFlag(cmd *Command, w io.Writer) error {
fmt.Fprintf(out, " must_have_one_flag=()\n") if _, err := fmt.Fprintf(w, " must_have_one_flag=()\n"); err != nil {
return err
}
flags := cmd.NonInheritedFlags() flags := cmd.NonInheritedFlags()
var visitErr error
flags.VisitAll(func(flag *pflag.Flag) { flags.VisitAll(func(flag *pflag.Flag) {
for key := range flag.Annotations { for key := range flag.Annotations {
switch key { switch key {
@ -312,67 +407,95 @@ func writeRequiredFlag(cmd *Command, out *bytes.Buffer) {
format += "=" format += "="
} }
format += "\")\n" format += "\")\n"
fmt.Fprintf(out, format, flag.Name) if _, err := fmt.Fprintf(w, format, flag.Name); err != nil {
visitErr = err
return
}
if len(flag.Shorthand) > 0 { if len(flag.Shorthand) > 0 {
fmt.Fprintf(out, " must_have_one_flag+=(\"-%s\")\n", flag.Shorthand) if _, err := fmt.Fprintf(w, " must_have_one_flag+=(\"-%s\")\n", flag.Shorthand); err != nil {
visitErr = err
return
}
} }
} }
} }
}) })
return visitErr
} }
func writeRequiredNoun(cmd *Command, out *bytes.Buffer) { func writeRequiredNoun(cmd *Command, w io.Writer) error {
fmt.Fprintf(out, " must_have_one_noun=()\n") if _, err := fmt.Fprintf(w, " must_have_one_noun=()\n"); err != nil {
return err
}
sort.Sort(sort.StringSlice(cmd.ValidArgs)) sort.Sort(sort.StringSlice(cmd.ValidArgs))
for _, value := range cmd.ValidArgs { for _, value := range cmd.ValidArgs {
fmt.Fprintf(out, " must_have_one_noun+=(%q)\n", value) if _, err := fmt.Fprintf(w, " must_have_one_noun+=(%q)\n", value); err != nil {
return err
}
} }
return nil
} }
func gen(cmd *Command, out *bytes.Buffer) { func gen(cmd *Command, w io.Writer) error {
for _, c := range cmd.Commands() { for _, c := range cmd.Commands() {
if !c.IsAvailableCommand() || c == cmd.helpCommand { if !c.IsAvailableCommand() || c == cmd.helpCommand {
continue continue
} }
gen(c, out) if err := gen(c, w); err != nil {
return err
}
} }
commandName := cmd.CommandPath() commandName := cmd.CommandPath()
commandName = strings.Replace(commandName, " ", "_", -1) commandName = strings.Replace(commandName, " ", "_", -1)
fmt.Fprintf(out, "_%s()\n{\n", commandName) commandName = strings.Replace(commandName, ":", "__", -1)
fmt.Fprintf(out, " last_command=%q\n", commandName) if _, err := fmt.Fprintf(w, "_%s()\n{\n", commandName); err != nil {
writeCommands(cmd, out) return err
writeFlags(cmd, out) }
writeRequiredFlag(cmd, out) if _, err := fmt.Fprintf(w, " last_command=%q\n", commandName); err != nil {
writeRequiredNoun(cmd, out) return err
fmt.Fprintf(out, "}\n\n") }
if err := writeCommands(cmd, w); err != nil {
return err
}
if err := writeFlags(cmd, w); err != nil {
return err
}
if err := writeRequiredFlag(cmd, w); err != nil {
return err
}
if err := writeRequiredNoun(cmd, w); err != nil {
return err
}
if _, err := fmt.Fprintf(w, "}\n\n"); err != nil {
return err
}
return nil
} }
func (cmd *Command) GenBashCompletion(out *bytes.Buffer) { func (cmd *Command) GenBashCompletion(w io.Writer) error {
preamble(out) if err := preamble(w, cmd.Name()); err != nil {
if len(cmd.BashCompletionFunction) > 0 { return err
fmt.Fprintf(out, "%s\n", cmd.BashCompletionFunction)
} }
gen(cmd, out) if len(cmd.BashCompletionFunction) > 0 {
postscript(out, cmd.Name()) if _, err := fmt.Fprintf(w, "%s\n", cmd.BashCompletionFunction); err != nil {
return err
}
}
if err := gen(cmd, w); err != nil {
return err
}
return postscript(w, cmd.Name())
} }
func (cmd *Command) GenBashCompletionFile(filename string) error { func (cmd *Command) GenBashCompletionFile(filename string) error {
out := new(bytes.Buffer)
cmd.GenBashCompletion(out)
outFile, err := os.Create(filename) outFile, err := os.Create(filename)
if err != nil { if err != nil {
return err return err
} }
defer outFile.Close() defer outFile.Close()
_, err = outFile.Write(out.Bytes()) return cmd.GenBashCompletion(outFile)
if err != nil {
return err
}
return nil
} }
// MarkFlagRequired adds the BashCompOneRequiredFlag annotation to the named flag, if it exists. // MarkFlagRequired adds the BashCompOneRequiredFlag annotation to the named flag, if it exists.
@ -380,6 +503,11 @@ func (cmd *Command) MarkFlagRequired(name string) error {
return MarkFlagRequired(cmd.Flags(), name) return MarkFlagRequired(cmd.Flags(), name)
} }
// MarkPersistentFlagRequired adds the BashCompOneRequiredFlag annotation to the named persistent flag, if it exists.
func (cmd *Command) MarkPersistentFlagRequired(name string) error {
return MarkFlagRequired(cmd.PersistentFlags(), name)
}
// MarkFlagRequired adds the BashCompOneRequiredFlag annotation to the named flag in the flag set, if it exists. // MarkFlagRequired adds the BashCompOneRequiredFlag annotation to the named flag in the flag set, if it exists.
func MarkFlagRequired(flags *pflag.FlagSet, name string) error { func MarkFlagRequired(flags *pflag.FlagSet, name string) error {
return flags.SetAnnotation(name, BashCompOneRequiredFlag, []string{"true"}) return flags.SetAnnotation(name, BashCompOneRequiredFlag, []string{"true"})
@ -391,6 +519,12 @@ func (cmd *Command) MarkFlagFilename(name string, extensions ...string) error {
return MarkFlagFilename(cmd.Flags(), name, extensions...) return MarkFlagFilename(cmd.Flags(), name, extensions...)
} }
// MarkPersistentFlagFilename adds the BashCompFilenameExt annotation to the named persistent flag, if it exists.
// Generated bash autocompletion will select filenames for the flag, limiting to named extensions if provided.
func (cmd *Command) MarkPersistentFlagFilename(name string, extensions ...string) error {
return MarkFlagFilename(cmd.PersistentFlags(), name, extensions...)
}
// MarkFlagFilename adds the BashCompFilenameExt annotation to the named flag in the flag set, if it exists. // MarkFlagFilename adds the BashCompFilenameExt annotation to the named flag in the flag set, if it exists.
// Generated bash autocompletion will select filenames for the flag, limiting to named extensions if provided. // Generated bash autocompletion will select filenames for the flag, limiting to named extensions if provided.
func MarkFlagFilename(flags *pflag.FlagSet, name string, extensions ...string) error { func MarkFlagFilename(flags *pflag.FlagSet, name string, extensions ...string) error {

@ -40,14 +40,6 @@ var initializers []func()
// Set this to true to enable it // Set this to true to enable it
var EnablePrefixMatching bool = false var EnablePrefixMatching bool = false
// enables an information splash screen on Windows if the CLI is started from explorer.exe.
var EnableWindowsMouseTrap bool = true
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 //AddTemplateFunc adds a template function that's available to Usage and Help
//template generation. //template generation.
func AddTemplateFunc(name string, tmplFunc interface{}) { func AddTemplateFunc(name string, tmplFunc interface{}) {

128
vendor/github.com/spf13/cobra/cobra/cmd/add.go generated vendored Normal file

@ -0,0 +1,128 @@
// Copyright © 2015 Steve Francia <spf@spf13.com>.
//
// 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 cmd
import (
"fmt"
"path/filepath"
"strings"
"github.com/spf13/cobra"
"github.com/spf13/viper"
)
func init() {
RootCmd.AddCommand(addCmd)
}
var pName string
// initialize Command
var addCmd = &cobra.Command{
Use: "add [command name]",
Aliases: []string{"command"},
Short: "Add a command to a Cobra Application",
Long: `Add (cobra add) will create a new command, with a license and
the appropriate structure for a Cobra-based CLI application,
and register it to its parent (default RootCmd).
If you want your command to be public, pass in the command name
with an initial uppercase letter.
Example: cobra add server -> resulting in a new cmd/server.go
`,
Run: func(cmd *cobra.Command, args []string) {
if len(args) != 1 {
er("add needs a name for the command")
}
guessProjectPath()
createCmdFile(args[0])
},
}
func init() {
addCmd.Flags().StringVarP(&pName, "parent", "p", "RootCmd", "name of parent command for this command")
}
func parentName() string {
if !strings.HasSuffix(strings.ToLower(pName), "cmd") {
return pName + "Cmd"
}
return pName
}
func createCmdFile(cmdName string) {
lic := getLicense()
template := `{{ comment .copyright }}
{{ comment .license }}
package cmd
import (
"fmt"
"github.com/spf13/cobra"
)
// {{.cmdName}}Cmd represents the {{.cmdName}} command
var {{ .cmdName }}Cmd = &cobra.Command{
Use: "{{ .cmdName }}",
Short: "A brief description of your command",
Long: ` + "`" + `A longer description that spans multiple lines and likely contains examples
and usage of using your command. For example:
Cobra is a CLI library for Go that empowers applications.
This application is a tool to generate the needed files
to quickly create a Cobra application.` + "`" + `,
Run: func(cmd *cobra.Command, args []string) {
// TODO: Work your own magic here
fmt.Println("{{ .cmdName }} called")
},
}
func init() {
{{ .parentName }}.AddCommand({{ .cmdName }}Cmd)
// Here you will define your flags and configuration settings.
// Cobra supports Persistent Flags which will work for this command
// and all subcommands, e.g.:
// {{.cmdName}}Cmd.PersistentFlags().String("foo", "", "A help for foo")
// Cobra supports local flags which will only run when this command
// is called directly, e.g.:
// {{.cmdName}}Cmd.Flags().BoolP("toggle", "t", false, "Help message for toggle")
}
`
var data map[string]interface{}
data = make(map[string]interface{})
data["copyright"] = copyrightLine()
data["license"] = lic.Header
data["appName"] = projectName()
data["viper"] = viper.GetBool("useViper")
data["parentName"] = parentName()
data["cmdName"] = cmdName
err := writeTemplateToFile(filepath.Join(ProjectPath(), guessCmdDir()), cmdName+".go", template, data)
if err != nil {
er(err)
}
fmt.Println(cmdName, "created at", filepath.Join(ProjectPath(), guessCmdDir(), cmdName+".go"))
}

347
vendor/github.com/spf13/cobra/cobra/cmd/helpers.go generated vendored Normal file

@ -0,0 +1,347 @@
// Copyright © 2015 Steve Francia <spf@spf13.com>.
//
// 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 cmd
import (
"bytes"
"fmt"
"io"
"os"
"path/filepath"
"strings"
"text/template"
"time"
"github.com/spf13/viper"
)
// var BaseDir = ""
// var AppName = ""
// var CommandDir = ""
var funcMap template.FuncMap
var projectPath = ""
var inputPath = ""
var projectBase = ""
// for testing only
var testWd = ""
var cmdDirs = []string{"cmd", "cmds", "command", "commands"}
func init() {
funcMap = template.FuncMap{
"comment": commentifyString,
}
}
func er(msg interface{}) {
fmt.Println("Error:", msg)
os.Exit(-1)
}
// Check if a file or directory exists.
func exists(path string) (bool, error) {
_, err := os.Stat(path)
if err == nil {
return true, nil
}
if os.IsNotExist(err) {
return false, nil
}
return false, err
}
func ProjectPath() string {
if projectPath == "" {
guessProjectPath()
}
return projectPath
}
// wrapper of the os package so we can test better
func getWd() (string, error) {
if testWd == "" {
return os.Getwd()
}
return testWd, nil
}
func guessCmdDir() string {
guessProjectPath()
if b, _ := isEmpty(projectPath); b {
return "cmd"
}
files, _ := filepath.Glob(projectPath + string(os.PathSeparator) + "c*")
for _, f := range files {
for _, c := range cmdDirs {
if f == c {
return c
}
}
}
return "cmd"
}
func guessImportPath() string {
guessProjectPath()
if !strings.HasPrefix(projectPath, getSrcPath()) {
er("Cobra only supports project within $GOPATH")
}
return filepath.ToSlash(filepath.Clean(strings.TrimPrefix(projectPath, getSrcPath())))
}
func getSrcPath() string {
return filepath.Join(os.Getenv("GOPATH"), "src") + string(os.PathSeparator)
}
func projectName() string {
return filepath.Base(ProjectPath())
}
func guessProjectPath() {
// if no path is provided... assume CWD.
if inputPath == "" {
x, err := getWd()
if err != nil {
er(err)
}
// inspect CWD
base := filepath.Base(x)
// if we are in the cmd directory.. back up
for _, c := range cmdDirs {
if base == c {
projectPath = filepath.Dir(x)
return
}
}
if projectPath == "" {
projectPath = filepath.Clean(x)
return
}
}
srcPath := getSrcPath()
// if provided, inspect for logical locations
if strings.ContainsRune(inputPath, os.PathSeparator) {
if filepath.IsAbs(inputPath) || filepath.HasPrefix(inputPath, string(os.PathSeparator)) {
// if Absolute, use it
projectPath = filepath.Clean(inputPath)
return
}
// If not absolute but contains slashes,
// assuming it means create it from $GOPATH
count := strings.Count(inputPath, string(os.PathSeparator))
switch count {
// If only one directory deep, assume "github.com"
case 1:
projectPath = filepath.Join(srcPath, "github.com", inputPath)
return
case 2:
projectPath = filepath.Join(srcPath, inputPath)
return
default:
er("Unknown directory")
}
} else {
// hardest case.. just a word.
if projectBase == "" {
x, err := getWd()
if err == nil {
projectPath = filepath.Join(x, inputPath)
return
}
er(err)
} else {
projectPath = filepath.Join(srcPath, projectBase, inputPath)
return
}
}
}
// isEmpty checks if a given path is empty.
func isEmpty(path string) (bool, error) {
if b, _ := exists(path); !b {
return false, fmt.Errorf("%q path does not exist", path)
}
fi, err := os.Stat(path)
if err != nil {
return false, err
}
if fi.IsDir() {
f, err := os.Open(path)
// FIX: Resource leak - f.close() should be called here by defer or is missed
// if the err != nil branch is taken.
defer f.Close()
if err != nil {
return false, err
}
list, err := f.Readdir(-1)
// f.Close() - see bug fix above
return len(list) == 0, nil
}
return fi.Size() == 0, nil
}
// isDir checks if a given path is a directory.
func isDir(path string) (bool, error) {
fi, err := os.Stat(path)
if err != nil {
return false, err
}
return fi.IsDir(), nil
}
// dirExists checks if a path exists and is a directory.
func dirExists(path string) (bool, error) {
fi, err := os.Stat(path)
if err == nil && fi.IsDir() {
return true, nil
}
if os.IsNotExist(err) {
return false, nil
}
return false, err
}
func writeTemplateToFile(path string, file string, template string, data interface{}) error {
filename := filepath.Join(path, file)
r, err := templateToReader(template, data)
if err != nil {
return err
}
err = safeWriteToDisk(filename, r)
if err != nil {
return err
}
return nil
}
func writeStringToFile(path, file, text string) error {
filename := filepath.Join(path, file)
r := strings.NewReader(text)
err := safeWriteToDisk(filename, r)
if err != nil {
return err
}
return nil
}
func templateToReader(tpl string, data interface{}) (io.Reader, error) {
tmpl := template.New("")
tmpl.Funcs(funcMap)
tmpl, err := tmpl.Parse(tpl)
if err != nil {
return nil, err
}
buf := new(bytes.Buffer)
err = tmpl.Execute(buf, data)
return buf, err
}
// Same as WriteToDisk but checks to see if file/directory already exists.
func safeWriteToDisk(inpath string, r io.Reader) (err error) {
dir, _ := filepath.Split(inpath)
ospath := filepath.FromSlash(dir)
if ospath != "" {
err = os.MkdirAll(ospath, 0777) // rwx, rw, r
if err != nil {
return
}
}
ex, err := exists(inpath)
if err != nil {
return
}
if ex {
return fmt.Errorf("%v already exists", inpath)
}
file, err := os.Create(inpath)
if err != nil {
return
}
defer file.Close()
_, err = io.Copy(file, r)
return
}
func getLicense() License {
l := whichLicense()
if l != "" {
if x, ok := Licenses[l]; ok {
return x
}
}
return Licenses["apache"]
}
func whichLicense() string {
// if explicitly flagged, use that
if userLicense != "" {
return matchLicense(userLicense)
}
// if already present in the project, use that
// TODO: Inspect project for existing license
// default to viper's setting
return matchLicense(viper.GetString("license"))
}
func copyrightLine() string {
author := viper.GetString("author")
year := time.Now().Format("2006")
return "Copyright © " + year + " " + author
}
func commentifyString(in string) string {
var newlines []string
lines := strings.Split(in, "\n")
for _, x := range lines {
if !strings.HasPrefix(x, "//") {
if x != "" {
newlines = append(newlines, "// "+x)
} else {
newlines = append(newlines, "//")
}
} else {
newlines = append(newlines, x)
}
}
return strings.Join(newlines, "\n")
}

226
vendor/github.com/spf13/cobra/cobra/cmd/init.go generated vendored Normal file

@ -0,0 +1,226 @@
// Copyright © 2015 Steve Francia <spf@spf13.com>.
//
// 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 cmd
import (
"fmt"
"os"
"strings"
"github.com/spf13/cobra"
"github.com/spf13/viper"
)
func init() {
RootCmd.AddCommand(initCmd)
}
// initialize Command
var initCmd = &cobra.Command{
Use: "init [name]",
Aliases: []string{"initialize", "initialise", "create"},
Short: "Initialize a Cobra Application",
Long: `Initialize (cobra init) will create a new application, with a license
and the appropriate structure for a Cobra-based CLI application.
* If a name is provided, it will be created in the current directory;
* If no name is provided, the current directory will be assumed;
* If a relative path is provided, it will be created inside $GOPATH
(e.g. github.com/spf13/hugo);
* If an absolute path is provided, it will be created;
* If the directory already exists but is empty, it will be used.
Init will not use an existing directory with contents.`,
Run: func(cmd *cobra.Command, args []string) {
switch len(args) {
case 0:
inputPath = ""
case 1:
inputPath = args[0]
default:
er("init doesn't support more than 1 parameter")
}
guessProjectPath()
initializePath(projectPath)
},
}
func initializePath(path string) {
b, err := exists(path)
if err != nil {
er(err)
}
if !b { // If path doesn't yet exist, create it
err := os.MkdirAll(path, os.ModePerm)
if err != nil {
er(err)
}
} else { // If path exists and is not empty don't use it
empty, err := exists(path)
if err != nil {
er(err)
}
if !empty {
er("Cobra will not create a new project in a non empty directory")
}
}
// We have a directory and it's empty.. Time to initialize it.
createLicenseFile()
createMainFile()
createRootCmdFile()
}
func createLicenseFile() {
lic := getLicense()
template := lic.Text
var data map[string]interface{}
data = make(map[string]interface{})
// Try to remove the email address, if any
data["copyright"] = strings.Split(copyrightLine(), " <")[0]
err := writeTemplateToFile(ProjectPath(), "LICENSE", template, data)
_ = err
// if err != nil {
// er(err)
// }
}
func createMainFile() {
lic := getLicense()
template := `{{ comment .copyright }}
{{ comment .license }}
package main
import "{{ .importpath }}"
func main() {
cmd.Execute()
}
`
var data map[string]interface{}
data = make(map[string]interface{})
data["copyright"] = copyrightLine()
data["license"] = lic.Header
data["importpath"] = guessImportPath() + "/" + guessCmdDir()
err := writeTemplateToFile(ProjectPath(), "main.go", template, data)
_ = err
// if err != nil {
// er(err)
// }
}
func createRootCmdFile() {
lic := getLicense()
template := `{{ comment .copyright }}
{{ comment .license }}
package cmd
import (
"fmt"
"os"
"github.com/spf13/cobra"
{{ if .viper }} "github.com/spf13/viper"
{{ end }})
{{if .viper}}
var cfgFile string
{{ end }}
// This represents the base command when called without any subcommands
var RootCmd = &cobra.Command{
Use: "{{ .appName }}",
Short: "A brief description of your application",
Long: ` + "`" + `A longer description that spans multiple lines and likely contains
examples and usage of using your application. For example:
Cobra is a CLI library for Go that empowers applications.
This application is a tool to generate the needed files
to quickly create a Cobra application.` + "`" + `,
// Uncomment the following line if your bare application
// has an action associated with it:
// Run: func(cmd *cobra.Command, args []string) { },
}
// Execute adds all child commands to the root command sets flags appropriately.
// This is called by main.main(). It only needs to happen once to the rootCmd.
func Execute() {
if err := RootCmd.Execute(); err != nil {
fmt.Println(err)
os.Exit(-1)
}
}
func init() {
{{ if .viper }} cobra.OnInitialize(initConfig)
{{ end }} // Here you will define your flags and configuration settings.
// Cobra supports Persistent Flags, which, if defined here,
// will be global for your application.
{{ if .viper }}
RootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file (default is $HOME/.{{ .appName }}.yaml)")
{{ else }}
// RootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file (default is $HOME/.{{ .appName }}.yaml)")
{{ end }} // Cobra also supports local flags, which will only run
// when this action is called directly.
RootCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle")
}
{{ if .viper }}
// initConfig reads in config file and ENV variables if set.
func initConfig() {
if cfgFile != "" { // enable ability to specify config file via flag
viper.SetConfigFile(cfgFile)
}
viper.SetConfigName(".{{ .appName }}") // name of config file (without extension)
viper.AddConfigPath("$HOME") // adding home directory as first search path
viper.AutomaticEnv() // read in environment variables that match
// If a config file is found, read it in.
if err := viper.ReadInConfig(); err == nil {
fmt.Println("Using config file:", viper.ConfigFileUsed())
}
}
{{ end }}`
var data map[string]interface{}
data = make(map[string]interface{})
data["copyright"] = copyrightLine()
data["license"] = lic.Header
data["appName"] = projectName()
data["viper"] = viper.GetBool("useViper")
err := writeTemplateToFile(ProjectPath()+string(os.PathSeparator)+guessCmdDir(), "root.go", template, data)
if err != nil {
er(err)
}
fmt.Println("Your Cobra application is ready at")
fmt.Println(ProjectPath())
fmt.Println("Give it a try by going there and running `go run main.go`")
fmt.Println("Add commands to it by running `cobra add [cmdname]`")
}

1133
vendor/github.com/spf13/cobra/cobra/cmd/licenses.go generated vendored Normal file

File diff suppressed because it is too large Load Diff

84
vendor/github.com/spf13/cobra/cobra/cmd/root.go generated vendored Normal file

@ -0,0 +1,84 @@
// Copyright © 2015 Steve Francia <spf@spf13.com>.
//
// 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 cmd
import (
"fmt"
"os"
"github.com/spf13/cobra"
"github.com/spf13/viper"
)
var cfgFile string
var userLicense string
// This represents the base command when called without any subcommands
var RootCmd = &cobra.Command{
Use: "cobra",
Short: "A generator for Cobra based Applications",
Long: `Cobra is a CLI library for Go that empowers applications.
This application is a tool to generate the needed files
to quickly create a Cobra application.`,
}
//Execute adds all child commands to the root command sets flags appropriately.
func Execute() {
if err := RootCmd.Execute(); err != nil {
fmt.Println(err)
os.Exit(-1)
}
}
func init() {
cobra.OnInitialize(initConfig)
RootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file (default is $HOME/.cobra.yaml)")
RootCmd.PersistentFlags().StringVarP(&projectBase, "projectbase", "b", "", "base project directory, e.g. github.com/spf13/")
RootCmd.PersistentFlags().StringP("author", "a", "YOUR NAME", "Author name for copyright attribution")
RootCmd.PersistentFlags().StringVarP(&userLicense, "license", "l", "", "Name of license for the project (can provide `licensetext` in config)")
RootCmd.PersistentFlags().Bool("viper", true, "Use Viper for configuration")
viper.BindPFlag("author", RootCmd.PersistentFlags().Lookup("author"))
viper.BindPFlag("projectbase", RootCmd.PersistentFlags().Lookup("projectbase"))
viper.BindPFlag("useViper", RootCmd.PersistentFlags().Lookup("viper"))
viper.SetDefault("author", "NAME HERE <EMAIL ADDRESS>")
viper.SetDefault("license", "apache")
viper.SetDefault("licenseText", `
// 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.
`)
}
// Read in config file and ENV variables if set.
func initConfig() {
if cfgFile != "" { // enable ability to specify config file via flag
viper.SetConfigFile(cfgFile)
}
viper.SetConfigName(".cobra") // name of config file (without extension)
viper.AddConfigPath("$HOME") // adding home directory as first search path
viper.AutomaticEnv() // read in environment variables that match
// If a config file is found, read it in.
if err := viper.ReadInConfig(); err == nil {
fmt.Println("Using config file:", viper.ConfigFileUsed())
}
}

20
vendor/github.com/spf13/cobra/cobra/main.go generated vendored Normal file

@ -0,0 +1,20 @@
// Copyright © 2015 Steve Francia <spf@spf13.com>.
//
// 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 main
import "github.com/spf13/cobra/cobra/cmd"
func main() {
cmd.Execute()
}

@ -20,11 +20,9 @@ import (
"fmt" "fmt"
"io" "io"
"os" "os"
"runtime" "path/filepath"
"strings" "strings"
"time"
"github.com/inconshreveable/mousetrap"
flag "github.com/spf13/pflag" flag "github.com/spf13/pflag"
) )
@ -61,6 +59,10 @@ type Command struct {
pflags *flag.FlagSet pflags *flag.FlagSet
// Flags that are declared specifically by this command (not inherited). // Flags that are declared specifically by this command (not inherited).
lflags *flag.FlagSet lflags *flag.FlagSet
// SilenceErrors is an option to quiet errors down stream
SilenceErrors bool
// Silence Usage is an option to silence usage when an error occurs.
SilenceUsage bool
// The *Run functions are executed in the following order: // The *Run functions are executed in the following order:
// * PersistentPreRun() // * PersistentPreRun()
// * PreRun() // * PreRun()
@ -88,6 +90,8 @@ type Command struct {
PersistentPostRun func(cmd *Command, args []string) PersistentPostRun func(cmd *Command, args []string)
// PersistentPostRunE: PersistentPostRun but returns an error // PersistentPostRunE: PersistentPostRun but returns an error
PersistentPostRunE func(cmd *Command, args []string) error PersistentPostRunE func(cmd *Command, args []string) error
// DisableAutoGenTag remove
DisableAutoGenTag bool
// Commands is the list of commands supported by this program. // Commands is the list of commands supported by this program.
commands []*Command commands []*Command
// Parent Command for this command // Parent Command for this command
@ -469,20 +473,38 @@ func (c *Command) SuggestionsFor(typedName string) []string {
return suggestions return suggestions
} }
func (c *Command) VisitParents(fn func(*Command)) {
var traverse func(*Command) *Command
traverse = func(x *Command) *Command {
if x != c {
fn(x)
}
if x.HasParent() {
return traverse(x.parent)
}
return x
}
traverse(c)
}
func (c *Command) Root() *Command { func (c *Command) Root() *Command {
var findRoot func(*Command) *Command var findRoot func(*Command) *Command
findRoot = func(x *Command) *Command { findRoot = func(x *Command) *Command {
if x.HasParent() { if x.HasParent() {
return findRoot(x.parent) return findRoot(x.parent)
} else {
return x
} }
return x
} }
return findRoot(c) return findRoot(c)
} }
// ArgsLenAtDash will return the length of f.Args at the moment when a -- was
// found during arg parsing. This allows your program to know which args were
// before the -- and which came after. (Description from
// https://godoc.org/github.com/spf13/pflag#FlagSet.ArgsLenAtDash).
func (c *Command) ArgsLenAtDash() int { func (c *Command) ArgsLenAtDash() int {
return c.Flags().ArgsLenAtDash() return c.Flags().ArgsLenAtDash()
} }
@ -589,19 +611,21 @@ func (c *Command) errorMsgFromParse() string {
// Call execute to use the args (os.Args[1:] by default) // Call execute to use the args (os.Args[1:] by default)
// and run through the command tree finding appropriate matches // and run through the command tree finding appropriate matches
// for commands and then corresponding flags. // for commands and then corresponding flags.
func (c *Command) Execute() (err error) { func (c *Command) Execute() error {
_, err := c.ExecuteC()
return err
}
func (c *Command) ExecuteC() (cmd *Command, err error) {
// Regardless of what command execute is called on, run on Root only // Regardless of what command execute is called on, run on Root only
if c.HasParent() { if c.HasParent() {
return c.Root().Execute() return c.Root().ExecuteC()
} }
if EnableWindowsMouseTrap && runtime.GOOS == "windows" { // windows hook
if mousetrap.StartedByExplorer() { if preExecHookFn != nil {
c.Print(MousetrapHelpText) preExecHookFn(c)
time.Sleep(5 * time.Second)
os.Exit(1)
}
} }
// initialize help as the last point possible to allow for user // initialize help as the last point possible to allow for user
@ -610,7 +634,8 @@ func (c *Command) Execute() (err error) {
var args []string var args []string
if len(c.args) == 0 { // Workaround FAIL with "go test -v" or "cobra.test -test.v", see #155
if c.args == nil && filepath.Base(os.Args[0]) != "cobra.test" {
args = os.Args[1:] args = os.Args[1:]
} else { } else {
args = c.args args = c.args
@ -622,22 +647,35 @@ func (c *Command) Execute() (err error) {
if cmd != nil { if cmd != nil {
c = cmd c = cmd
} }
c.Println("Error:", err.Error()) if !c.SilenceErrors {
c.Printf("Run '%v --help' for usage.\n", c.CommandPath()) c.Println("Error:", err.Error())
return err c.Printf("Run '%v --help' for usage.\n", c.CommandPath())
}
return c, err
} }
err = cmd.execute(flags) err = cmd.execute(flags)
if err != nil { if err != nil {
// Always show help if requested, even if SilenceErrors is in
// effect
if err == flag.ErrHelp { if err == flag.ErrHelp {
cmd.HelpFunc()(cmd, args) cmd.HelpFunc()(cmd, args)
return nil return cmd, nil
} }
c.Println(cmd.UsageString())
c.Println("Error:", err.Error())
}
return // If root command has SilentErrors flagged,
// all subcommands should respect it
if !cmd.SilenceErrors && !c.SilenceErrors {
c.Println("Error:", err.Error())
}
// If root command has SilentUsage flagged,
// all subcommands should respect it
if !cmd.SilenceUsage && !c.SilenceUsage {
c.Println(cmd.UsageString())
}
return cmd, err
}
return cmd, nil
} }
func (c *Command) initHelpFlag() { func (c *Command) initHelpFlag() {
@ -706,7 +744,7 @@ func (c *Command) AddCommand(cmds ...*Command) {
if nameLen > c.commandsMaxNameLen { if nameLen > c.commandsMaxNameLen {
c.commandsMaxNameLen = nameLen c.commandsMaxNameLen = nameLen
} }
// If glabal normalization function exists, update all children // If global normalization function exists, update all children
if c.globNormFunc != nil { if c.globNormFunc != nil {
x.SetGlobalNormalizationFunc(c.globNormFunc) x.SetGlobalNormalizationFunc(c.globNormFunc)
} }

5
vendor/github.com/spf13/cobra/command_notwin.go generated vendored Normal file

@ -0,0 +1,5 @@
// +build !windows
package cobra
var preExecHookFn func(*Command) = nil

26
vendor/github.com/spf13/cobra/command_win.go generated vendored Normal file

@ -0,0 +1,26 @@
// +build windows
package cobra
import (
"os"
"time"
"github.com/inconshreveable/mousetrap"
)
var preExecHookFn = preExecHook
// enables an information splash screen on Windows if the CLI is started from explorer.exe.
var MousetrapHelpText string = `This is a command line tool
You need to open cmd.exe and run it from there.
`
func preExecHook(c *Command) {
if mousetrap.StartedByExplorer() {
c.Print(MousetrapHelpText)
time.Sleep(5 * time.Second)
os.Exit(1)
}
}

@ -11,57 +11,58 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
package cobra package doc
import ( import (
"bytes" "bytes"
"fmt" "fmt"
"io"
"os" "os"
"path/filepath"
"sort" "sort"
"strings" "strings"
"time" "time"
mangen "github.com/cpuguy83/go-md2man/md2man" mangen "github.com/cpuguy83/go-md2man/md2man"
"github.com/spf13/cobra"
"github.com/spf13/pflag" "github.com/spf13/pflag"
) )
// GenManTree will call cmd.GenManTree(header, dir)
func GenManTree(cmd *Command, header *GenManHeader, dir string) {
cmd.GenManTree(header, dir)
}
// GenManTree will generate a man page for this command and all decendants // GenManTree will generate a man page for this command and all decendants
// in the directory given. The header may be nil. This function may not work // in the directory given. The header may be nil. This function may not work
// correctly if your command names have - in them. If you have `cmd` with two // correctly if your command names have - in them. If you have `cmd` with two
// subcmds, `sub` and `sub-third`. And `sub` has a subcommand called `third` // subcmds, `sub` and `sub-third`. And `sub` has a subcommand called `third`
// it is undefined which help output will be in the file `cmd-sub-third.1`. // it is undefined which help output will be in the file `cmd-sub-third.1`.
func (cmd *Command) GenManTree(header *GenManHeader, dir string) { func GenManTree(cmd *cobra.Command, header *GenManHeader, dir string) error {
if header == nil { if header == nil {
header = &GenManHeader{} header = &GenManHeader{}
} }
for _, c := range cmd.Commands() { for _, c := range cmd.Commands() {
if !c.IsAvailableCommand() || c == cmd.helpCommand { if !c.IsAvailableCommand() || c.IsHelpCommand() {
continue continue
} }
GenManTree(c, header, dir) if err := GenManTree(c, header, dir); err != nil {
return err
}
} }
out := new(bytes.Buffer) needToResetTitle := header.Title == ""
cmd.GenMan(header, out) basename := strings.Replace(cmd.CommandPath(), " ", "_", -1) + ".1"
filename := filepath.Join(dir, basename)
f, err := os.Create(filename)
if err != nil {
return err
}
defer f.Close()
filename := cmd.CommandPath() if err := GenMan(cmd, header, f); err != nil {
filename = dir + strings.Replace(filename, " ", "-", -1) + ".1" return err
outFile, err := os.Create(filename)
if err != nil {
fmt.Println(err)
os.Exit(1)
} }
defer outFile.Close()
_, err = outFile.Write(out.Bytes()) if needToResetTitle {
if err != nil { header.Title = ""
fmt.Println(err)
os.Exit(1)
} }
return nil
} }
// GenManHeader is a lot like the .TH header at the start of man pages. These // GenManHeader is a lot like the .TH header at the start of man pages. These
@ -77,25 +78,21 @@ type GenManHeader struct {
Manual string Manual string
} }
// GenMan will call cmd.GenMan(header, out) // GenMan will generate a man page for the given command and write it to
func GenMan(cmd *Command, header *GenManHeader, out *bytes.Buffer) { // w. The header argument may be nil, however obviously w may not.
cmd.GenMan(header, out) func GenMan(cmd *cobra.Command, header *GenManHeader, w io.Writer) error {
}
// GenMan will generate a man page for the given command in the out buffer.
// The header argument may be nil, however obviously out may not.
func (cmd *Command) GenMan(header *GenManHeader, out *bytes.Buffer) {
if header == nil { if header == nil {
header = &GenManHeader{} header = &GenManHeader{}
} }
buf := genMarkdown(cmd, header) b := genMan(cmd, header)
final := mangen.Render(buf) final := mangen.Render(b)
out.Write(final) _, err := w.Write(final)
return err
} }
func fillHeader(header *GenManHeader, name string) { func fillHeader(header *GenManHeader, name string) {
if header.Title == "" { if header.Title == "" {
header.Title = name header.Title = strings.ToUpper(strings.Replace(name, " ", "\\-", -1))
} }
if header.Section == "" { if header.Section == "" {
header.Section = "1" header.Section = "1"
@ -110,20 +107,21 @@ func fillHeader(header *GenManHeader, name string) {
} }
} }
func manPreamble(out *bytes.Buffer, header *GenManHeader, name, short, long string) { func manPreamble(out io.Writer, header *GenManHeader, name, short, long string) {
dashName := strings.Replace(name, " ", "-", -1)
fmt.Fprintf(out, `%% %s(%s)%s fmt.Fprintf(out, `%% %s(%s)%s
%% %s %% %s
%% %s %% %s
# NAME # NAME
`, header.Title, header.Section, header.date, header.Source, header.Manual) `, header.Title, header.Section, header.date, header.Source, header.Manual)
fmt.Fprintf(out, "%s \\- %s\n\n", name, short) fmt.Fprintf(out, "%s \\- %s\n\n", dashName, short)
fmt.Fprintf(out, "# SYNOPSIS\n") fmt.Fprintf(out, "# SYNOPSIS\n")
fmt.Fprintf(out, "**%s** [OPTIONS]\n\n", name) fmt.Fprintf(out, "**%s** [OPTIONS]\n\n", name)
fmt.Fprintf(out, "# DESCRIPTION\n") fmt.Fprintf(out, "# DESCRIPTION\n")
fmt.Fprintf(out, "%s\n\n", long) fmt.Fprintf(out, "%s\n\n", long)
} }
func manPrintFlags(out *bytes.Buffer, flags *pflag.FlagSet) { func manPrintFlags(out io.Writer, flags *pflag.FlagSet) {
flags.VisitAll(func(flag *pflag.Flag) { flags.VisitAll(func(flag *pflag.Flag) {
if len(flag.Deprecated) > 0 || flag.Hidden { if len(flag.Deprecated) > 0 || flag.Hidden {
return return
@ -151,7 +149,7 @@ func manPrintFlags(out *bytes.Buffer, flags *pflag.FlagSet) {
}) })
} }
func manPrintOptions(out *bytes.Buffer, command *Command) { func manPrintOptions(out io.Writer, command *cobra.Command) {
flags := command.NonInheritedFlags() flags := command.NonInheritedFlags()
if flags.HasFlags() { if flags.HasFlags() {
fmt.Fprintf(out, "# OPTIONS\n") fmt.Fprintf(out, "# OPTIONS\n")
@ -166,13 +164,14 @@ func manPrintOptions(out *bytes.Buffer, command *Command) {
} }
} }
func genMarkdown(cmd *Command, header *GenManHeader) []byte { func genMan(cmd *cobra.Command, header *GenManHeader) []byte {
fillHeader(header, cmd.Name())
// something like `rootcmd subcmd1 subcmd2` // something like `rootcmd subcmd1 subcmd2`
commandName := cmd.CommandPath() commandName := cmd.CommandPath()
// something like `rootcmd-subcmd1-subcmd2` // something like `rootcmd-subcmd1-subcmd2`
dashCommandName := strings.Replace(commandName, " ", "-", -1) dashCommandName := strings.Replace(commandName, " ", "-", -1)
fillHeader(header, commandName)
buf := new(bytes.Buffer) buf := new(bytes.Buffer)
short := cmd.Short short := cmd.Short
@ -183,31 +182,37 @@ func genMarkdown(cmd *Command, header *GenManHeader) []byte {
manPreamble(buf, header, commandName, short, long) manPreamble(buf, header, commandName, short, long)
manPrintOptions(buf, cmd) manPrintOptions(buf, cmd)
if len(cmd.Example) > 0 { if len(cmd.Example) > 0 {
fmt.Fprintf(buf, "# EXAMPLE\n") fmt.Fprintf(buf, "# EXAMPLE\n")
fmt.Fprintf(buf, "```\n%s\n```\n", cmd.Example) fmt.Fprintf(buf, "```\n%s\n```\n", cmd.Example)
} }
if hasSeeAlso(cmd) {
if cmd.hasSeeAlso() {
fmt.Fprintf(buf, "# SEE ALSO\n") fmt.Fprintf(buf, "# SEE ALSO\n")
if cmd.HasParent() { if cmd.HasParent() {
parentPath := cmd.Parent().CommandPath() parentPath := cmd.Parent().CommandPath()
dashParentPath := strings.Replace(parentPath, " ", "-", -1) dashParentPath := strings.Replace(parentPath, " ", "-", -1)
fmt.Fprintf(buf, "**%s(%s)**, ", dashParentPath, header.Section) fmt.Fprintf(buf, "**%s(%s)**", dashParentPath, header.Section)
cmd.VisitParents(func(c *cobra.Command) {
if c.DisableAutoGenTag {
cmd.DisableAutoGenTag = c.DisableAutoGenTag
}
})
} }
children := cmd.Commands() children := cmd.Commands()
sort.Sort(byName(children)) sort.Sort(byName(children))
for _, c := range children { for i, c := range children {
if !c.IsAvailableCommand() || c == cmd.helpCommand { if !c.IsAvailableCommand() || c.IsHelpCommand() {
continue continue
} }
fmt.Fprintf(buf, "**%s-%s(%s)**, ", dashCommandName, c.Name(), header.Section) if cmd.HasParent() || i > 0 {
fmt.Fprintf(buf, ", ")
}
fmt.Fprintf(buf, "**%s-%s(%s)**", dashCommandName, c.Name(), header.Section)
} }
fmt.Fprintf(buf, "\n") fmt.Fprintf(buf, "\n")
} }
if !cmd.DisableAutoGenTag {
fmt.Fprintf(buf, "# HISTORY\n%s Auto generated by spf13/cobra\n", header.Date.Format("2-Jan-2006")) fmt.Fprintf(buf, "# HISTORY\n%s Auto generated by spf13/cobra\n", header.Date.Format("2-Jan-2006"))
}
return buf.Bytes() return buf.Bytes()
} }

@ -1,12 +1,13 @@
# Generating Man Pages For Your Own cobra.Command # Generating Man Pages For Your Own cobra.Command
Generating bash completions from a cobra command is incredibly easy. An example is as follows: Generating man pages from a cobra command is incredibly easy. An example is as follows:
```go ```go
package main package main
import ( import (
"github.com/spf13/cobra" "github.com/spf13/cobra"
"github.com/spf13/cobra/doc"
) )
func main() { func main() {
@ -18,7 +19,7 @@ func main() {
Title: "MINE", Title: "MINE",
Section: "3", Section: "3",
} }
cmd.GenManTree(header, "/tmp") doc.GenManTree(cmd, header, "/tmp")
} }
``` ```

175
vendor/github.com/spf13/cobra/doc/md_docs.go generated vendored Normal file

@ -0,0 +1,175 @@
//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 doc
import (
"fmt"
"io"
"os"
"path/filepath"
"sort"
"strings"
"time"
"github.com/spf13/cobra"
)
func printOptions(w io.Writer, cmd *cobra.Command, name string) error {
flags := cmd.NonInheritedFlags()
flags.SetOutput(w)
if flags.HasFlags() {
if _, err := fmt.Fprintf(w, "### Options\n\n```\n"); err != nil {
return err
}
flags.PrintDefaults()
if _, err := fmt.Fprintf(w, "```\n\n"); err != nil {
return err
}
}
parentFlags := cmd.InheritedFlags()
parentFlags.SetOutput(w)
if parentFlags.HasFlags() {
if _, err := fmt.Fprintf(w, "### Options inherited from parent commands\n\n```\n"); err != nil {
return err
}
parentFlags.PrintDefaults()
if _, err := fmt.Fprintf(w, "```\n\n"); err != nil {
return err
}
}
return nil
}
func GenMarkdown(cmd *cobra.Command, w io.Writer) error {
return GenMarkdownCustom(cmd, w, func(s string) string { return s })
}
func GenMarkdownCustom(cmd *cobra.Command, w io.Writer, linkHandler func(string) string) error {
name := cmd.CommandPath()
short := cmd.Short
long := cmd.Long
if len(long) == 0 {
long = short
}
if _, err := fmt.Fprintf(w, "## %s\n\n", name); err != nil {
return err
}
if _, err := fmt.Fprintf(w, "%s\n\n", short); err != nil {
return err
}
if _, err := fmt.Fprintf(w, "### Synopsis\n\n"); err != nil {
return err
}
if _, err := fmt.Fprintf(w, "\n%s\n\n", long); err != nil {
return err
}
if cmd.Runnable() {
if _, err := fmt.Fprintf(w, "```\n%s\n```\n\n", cmd.UseLine()); err != nil {
return err
}
}
if len(cmd.Example) > 0 {
if _, err := fmt.Fprintf(w, "### Examples\n\n"); err != nil {
return err
}
if _, err := fmt.Fprintf(w, "```\n%s\n```\n\n", cmd.Example); err != nil {
return err
}
}
if err := printOptions(w, cmd, name); err != nil {
return err
}
if hasSeeAlso(cmd) {
if _, err := fmt.Fprintf(w, "### SEE ALSO\n"); err != nil {
return err
}
if cmd.HasParent() {
parent := cmd.Parent()
pname := parent.CommandPath()
link := pname + ".md"
link = strings.Replace(link, " ", "_", -1)
if _, err := fmt.Fprintf(w, "* [%s](%s)\t - %s\n", pname, linkHandler(link), parent.Short); err != nil {
return err
}
cmd.VisitParents(func(c *cobra.Command) {
if c.DisableAutoGenTag {
cmd.DisableAutoGenTag = c.DisableAutoGenTag
}
})
}
children := cmd.Commands()
sort.Sort(byName(children))
for _, child := range children {
if !child.IsAvailableCommand() || child.IsHelpCommand() {
continue
}
cname := name + " " + child.Name()
link := cname + ".md"
link = strings.Replace(link, " ", "_", -1)
if _, err := fmt.Fprintf(w, "* [%s](%s)\t - %s\n", cname, linkHandler(link), child.Short); err != nil {
return err
}
}
if _, err := fmt.Fprintf(w, "\n"); err != nil {
return err
}
}
if !cmd.DisableAutoGenTag {
if _, err := fmt.Fprintf(w, "###### Auto generated by spf13/cobra on %s\n", time.Now().Format("2-Jan-2006")); err != nil {
return err
}
}
return nil
}
func GenMarkdownTree(cmd *cobra.Command, dir string) error {
identity := func(s string) string { return s }
emptyStr := func(s string) string { return "" }
return GenMarkdownTreeCustom(cmd, dir, emptyStr, identity)
}
func GenMarkdownTreeCustom(cmd *cobra.Command, dir string, filePrepender, linkHandler func(string) string) error {
for _, c := range cmd.Commands() {
if !c.IsAvailableCommand() || c.IsHelpCommand() {
continue
}
if err := GenMarkdownTreeCustom(c, dir, filePrepender, linkHandler); err != nil {
return err
}
}
basename := strings.Replace(cmd.CommandPath(), " ", "_", -1) + ".md"
filename := filepath.Join(dir, basename)
f, err := os.Create(filename)
if err != nil {
return err
}
defer f.Close()
if _, err := io.WriteString(f, filePrepender(filename)); err != nil {
return err
}
if err := GenMarkdownCustom(cmd, f, linkHandler); err != nil {
return err
}
return nil
}

@ -1,5 +1,26 @@
# Generating Markdown Docs For Your Own cobra.Command # Generating Markdown Docs For Your Own cobra.Command
Generating man pages from a cobra command is incredibly easy. An example is as follows:
```go
package main
import (
"github.com/spf13/cobra"
"github.com/spf13/cobra/doc"
)
func main() {
cmd := &cobra.Command{
Use: "test",
Short: "my test program",
}
doc.GenMarkdownTree(cmd, "/tmp")
}
```
That will get you a Markdown document `/tmp/test.md`
## Generate markdown docs for the entire command tree ## Generate markdown docs for the entire command tree
This program can actually generate docs for the kubectl command in the kubernetes project This program can actually generate docs for the kubectl command in the kubernetes project
@ -11,13 +32,15 @@ import (
"io/ioutil" "io/ioutil"
"os" "os"
"github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl/cmd" kubectlcmd "k8s.io/kubernetes/pkg/kubectl/cmd"
"github.com/spf13/cobra" cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
"github.com/spf13/cobra/doc"
) )
func main() { func main() {
kubectl := cmd.NewFactory(nil).NewKubectlCommand(os.Stdin, ioutil.Discard, ioutil.Discard) cmd := kubectlcmd.NewKubectlCommand(cmdutil.NewFactory(nil), os.Stdin, ioutil.Discard, ioutil.Discard)
cobra.GenMarkdownTree(kubectl, "./") doc.GenMarkdownTree(cmd, "./")
} }
``` ```
@ -29,7 +52,7 @@ You may wish to have more control over the output, or only generate for a single
```go ```go
out := new(bytes.Buffer) out := new(bytes.Buffer)
cobra.GenMarkdown(cmd, out) doc.GenMarkdown(cmd, out)
``` ```
This will write the markdown doc for ONLY "cmd" into the out, buffer. This will write the markdown doc for ONLY "cmd" into the out, buffer.
@ -39,14 +62,14 @@ This will write the markdown doc for ONLY "cmd" into the out, buffer.
Both `GenMarkdown` and `GenMarkdownTree` have alternate versions with callbacks to get some control of the output: Both `GenMarkdown` and `GenMarkdownTree` have alternate versions with callbacks to get some control of the output:
```go ```go
func GenMarkdownTreeCustom(cmd *Command, dir string, filePrepender func(string) string, linkHandler func(string) string) { func GenMarkdownTreeCustom(cmd *Command, dir string, filePrepender, linkHandler func(string) string) error {
//... //...
} }
``` ```
```go ```go
func GenMarkdownCustom(cmd *Command, out *bytes.Buffer, linkHandler func(string) string) { func GenMarkdownCustom(cmd *Command, out *bytes.Buffer, linkHandler func(string) string) error {
//... //...
} }
``` ```
@ -78,4 +101,4 @@ linkHandler := func(name string) string {
return "/commands/" + strings.ToLower(base) + "/" return "/commands/" + strings.ToLower(base) + "/"
} }
``` ```

@ -11,24 +11,28 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
package cobra package doc
import "github.com/spf13/cobra"
// Test to see if we have a reason to print See Also information in docs // 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 // Basically this is a test for a parent commend or a subcommand which is
// both not deprecated and not the autogenerated help command. // both not deprecated and not the autogenerated help command.
func (cmd *Command) hasSeeAlso() bool { func hasSeeAlso(cmd *cobra.Command) bool {
if cmd.HasParent() { if cmd.HasParent() {
return true return true
} }
children := cmd.Commands() for _, c := range cmd.Commands() {
if len(children) == 0 { if !c.IsAvailableCommand() || c.IsHelpCommand() {
return false
}
for _, c := range children {
if !c.IsAvailableCommand() || c == cmd.helpCommand {
continue continue
} }
return true return true
} }
return false return false
} }
type byName []*cobra.Command
func (s byName) Len() int { return len(s) }
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() }

@ -1,157 +0,0 @@
//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"
)
func printOptions(out *bytes.Buffer, cmd *Command, name string) {
flags := cmd.NonInheritedFlags()
flags.SetOutput(out)
if flags.HasFlags() {
fmt.Fprintf(out, "### Options\n\n```\n")
flags.PrintDefaults()
fmt.Fprintf(out, "```\n\n")
}
parentFlags := cmd.InheritedFlags()
parentFlags.SetOutput(out)
if parentFlags.HasFlags() {
fmt.Fprintf(out, "### Options inherited from parent commands\n\n```\n")
parentFlags.PrintDefaults()
fmt.Fprintf(out, "```\n\n")
}
}
type byName []*Command
func (s byName) Len() int { return len(s) }
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) {
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
long := cmd.Long
if len(long) == 0 {
long = short
}
fmt.Fprintf(out, "## %s\n\n", name)
fmt.Fprintf(out, "%s\n\n", short)
fmt.Fprintf(out, "### Synopsis\n\n")
fmt.Fprintf(out, "\n%s\n\n", long)
if cmd.Runnable() {
fmt.Fprintf(out, "```\n%s\n```\n\n", cmd.UseLine())
}
if len(cmd.Example) > 0 {
fmt.Fprintf(out, "### Examples\n\n")
fmt.Fprintf(out, "```\n%s\n```\n\n", cmd.Example)
}
printOptions(out, cmd, name)
if cmd.hasSeeAlso() {
fmt.Fprintf(out, "### SEE ALSO\n")
if cmd.HasParent() {
parent := cmd.Parent()
pname := parent.CommandPath()
link := pname + ".md"
link = strings.Replace(link, " ", "_", -1)
fmt.Fprintf(out, "* [%s](%s)\t - %s\n", pname, linkHandler(link), parent.Short)
}
children := cmd.Commands()
sort.Sort(byName(children))
for _, child := range children {
if !child.IsAvailableCommand() || child == cmd.helpCommand {
continue
}
cname := name + " " + child.Name()
link := cname + ".md"
link = strings.Replace(link, " ", "_", -1)
fmt.Fprintf(out, "* [%s](%s)\t - %s\n", cname, linkHandler(link), child.Short)
}
fmt.Fprintf(out, "\n")
}
fmt.Fprintf(out, "###### Auto generated by spf13/cobra on %s\n", time.Now().Format("2-Jan-2006"))
}
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 "" }
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() {
if !c.IsAvailableCommand() || c == cmd.helpCommand {
continue
}
c.GenMarkdownTreeCustom(dir, filePrepender, linkHandler)
}
out := new(bytes.Buffer)
cmd.GenMarkdownCustom(out, linkHandler)
filename := cmd.CommandPath()
filename = dir + strings.Replace(filename, " ", "_", -1) + ".md"
outFile, err := os.Create(filename)
if err != nil {
fmt.Println(err)
os.Exit(1)
}
defer outFile.Close()
_, err = outFile.WriteString(filePrepender(filename))
if err != nil {
fmt.Println(err)
os.Exit(1)
}
_, err = outFile.Write(out.Bytes())
if err != nil {
fmt.Println(err)
os.Exit(1)
}
}