diff options
Diffstat (limited to 'vendor/github.com/spf13/cobra')
35 files changed, 2663 insertions, 954 deletions
diff --git a/vendor/github.com/spf13/cobra/.travis.yml b/vendor/github.com/spf13/cobra/.travis.yml index 42d1f57d3..cb2bf0d5c 100644 --- a/vendor/github.com/spf13/cobra/.travis.yml +++ b/vendor/github.com/spf13/cobra/.travis.yml @@ -2,12 +2,8 @@ language: go matrix: include: - - go: 1.4.3 - env: NOVET=true # No bundled vet. - - go: 1.5.4 - - go: 1.6.4 - go: 1.7.5 - - go: 1.8 + - go: 1.8.1 - go: tip allow_failures: - go: tip diff --git a/vendor/github.com/spf13/cobra/README.md b/vendor/github.com/spf13/cobra/README.md index 7d4d68b50..4563c211d 100644 --- a/vendor/github.com/spf13/cobra/README.md +++ b/vendor/github.com/spf13/cobra/README.md @@ -8,7 +8,7 @@ Many of the most widely used Go projects are built using Cobra including: * [Hugo](http://gohugo.io) * [rkt](https://github.com/coreos/rkt) * [etcd](https://github.com/coreos/etcd) -* [Docker](https://github.com/docker/docker) +* [Moby (former Docker)](https://github.com/moby/moby) * [Docker (distribution)](https://github.com/docker/distribution) * [OpenShift](https://www.openshift.com/) * [Delve](https://github.com/derekparker/delve) @@ -40,7 +40,7 @@ Cobra provides: * Fully POSIX-compliant flags (including short & long versions) * Nested subcommands * Global, local and cascading flags -* Easy generation of applications & commands with `cobra create appname` & `cobra add cmdname` +* Easy generation of applications & commands with `cobra init appname` & `cobra add cmdname` * Intelligent suggestions (`app srver`... did you mean `app server`?) * Automatic help generation for commands and flags * Automatic detailed help for `app help [command]` @@ -48,7 +48,7 @@ Cobra provides: * Automatically generated bash autocomplete for your application * Automatically generated man pages for your application * Command aliases so you can change things without breaking them -* The flexibilty to define your own help, usage, etc. +* The flexibility to define your own help, usage, etc. * Optional tight integration with [viper](http://github.com/spf13/viper) for 12-factor apps Cobra has an exceptionally clean interface and simple design without needless @@ -79,11 +79,11 @@ A few good real world examples may better illustrate this point. In the following example, 'server' is a command, and 'port' is a flag: - > hugo server --port=1313 + hugo server --port=1313 In this command we are telling Git to clone the url bare. - > git clone URL --bare + git clone URL --bare ## Commands @@ -114,7 +114,7 @@ and flags that are only available to that command. In the example above, 'port' is the flag. Flag functionality is provided by the [pflag -library](https://github.com/ogier/pflag), a fork of the flag standard library +library](https://github.com/spf13/pflag), a fork of the flag standard library which maintains the same interface while adding POSIX compliance. ## Usage @@ -130,7 +130,7 @@ Using Cobra is easy. First, use `go get` to install the latest version of the library. This command will install the `cobra` generator executible along with the library: - > go get -v github.com/spf13/cobra/cobra + go get -v github.com/spf13/cobra/cobra Next, include Cobra in your application: @@ -180,7 +180,7 @@ commands you want. It's the easiest way to incorporate Cobra into your applicati In order to use the cobra command, compile it using the following command: - > go get github.com/spf13/cobra/cobra + go get github.com/spf13/cobra/cobra This will create the cobra executable under your `$GOPATH/bin` directory. @@ -215,6 +215,10 @@ cobra add config cobra add create -p 'configCmd' ``` +*Note: Use camelCase (not snake_case/snake-case) for command names. +Otherwise, you will become unexpected errors. +For example, `cobra add add-user` is incorrect, but `cobra add addUser` is valid.* + Once you have run these three commands you would have an app structure that would look like: ``` @@ -260,6 +264,9 @@ license: master my life. ``` +You can also use built-in licenses. For example, **GPLv2**, **GPLv3**, **LGPL**, +**AGPL**, **MIT**, **2-Clause BSD** or **3-Clause BSD**. + ## Manually implementing Cobra To manually implement cobra you need to create a bare main.go file and a RootCmd file. @@ -853,39 +860,12 @@ out everything Cobra knows about the flags for each command. command.DebugFlags() ``` -## Release Notes -* **0.9.0** June 17, 2014 - * flags can appears anywhere in the args (provided they are unambiguous) - * --help prints usage screen for app or command - * Prefix matching for commands - * Cleaner looking help and usage output - * Extensive test suite -* **0.8.0** Nov 5, 2013 - * Reworked interface to remove commander completely - * Command now primary structure - * No initialization needed - * Usage & Help templates & functions definable at any level - * Updated Readme -* **0.7.0** Sept 24, 2013 - * Needs more eyes - * Test suite - * Support for automatic error messages - * Support for help command - * Support for printing to any io.Writer instead of os.Stderr - * Support for persistent flags which cascade down tree - * Ready for integration into Hugo -* **0.1.0** Sept 3, 2013 - * Implement first draft - ## Extensions Libraries for extending Cobra: * [cmdns](https://github.com/gosuri/cmdns): Enables name spacing a command's immediate children. It provides an alternative way to structure subcommands, similar to `heroku apps:create` and `ovrclk clusters:launch`. -## ToDo -* Launch proper documentation site - ## Contributing 1. Fork it @@ -905,6 +885,3 @@ Names in no particular order: ## License Cobra is released under the Apache 2.0 license. See [LICENSE.txt](https://github.com/spf13/cobra/blob/master/LICENSE.txt) - - -[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/spf13/cobra/trend.png)](https://bitdeli.com/free "Bitdeli Badge") diff --git a/vendor/github.com/spf13/cobra/bash_completions.md b/vendor/github.com/spf13/cobra/bash_completions.md index 7fa970fa2..52bd39ddb 100644 --- a/vendor/github.com/spf13/cobra/bash_completions.md +++ b/vendor/github.com/spf13/cobra/bash_completions.md @@ -106,7 +106,7 @@ node pod replicationcontroller service If your nouns have a number of aliases, you can define them alongside `ValidArgs` using `ArgAliases`: -```go` +```go argAliases []string = { "pods", "nodes", "services", "svc", "replicationcontrollers", "rc" } cmd := &cobra.Command{ diff --git a/vendor/github.com/spf13/cobra/cobra.go b/vendor/github.com/spf13/cobra/cobra.go index 25473a706..2726d19e4 100644 --- a/vendor/github.com/spf13/cobra/cobra.go +++ b/vendor/github.com/spf13/cobra/cobra.go @@ -27,12 +27,13 @@ import ( ) var templateFuncs = template.FuncMap{ - "trim": strings.TrimSpace, - "trimRightSpace": trimRightSpace, - "appendIfNotPresent": appendIfNotPresent, - "rpad": rpad, - "gt": Gt, - "eq": Eq, + "trim": strings.TrimSpace, + "trimRightSpace": trimRightSpace, + "trimTrailingWhitespaces": trimRightSpace, + "appendIfNotPresent": appendIfNotPresent, + "rpad": rpad, + "gt": Gt, + "eq": Eq, } var initializers []func() @@ -65,6 +66,8 @@ func OnInitialize(y ...func()) { initializers = append(initializers, y...) } +// FIXME Gt is unused by cobra and should be removed in a version 2. It exists only for compatibility with users of cobra. + // Gt takes two types and checks whether the first type is greater than the second. In case of types Arrays, Chans, // Maps and Slices, Gt will compare their lengths. Ints are compared directly while strings are first parsed as // ints and then compared. @@ -95,6 +98,8 @@ func Gt(a interface{}, b interface{}) bool { return left > right } +// FIXME Eq is unused by cobra and should be removed in a version 2. It exists only for compatibility with users of cobra. + // Eq takes two types and checks whether they are equal. Supported types are int and string. Unsupported types will panic. func Eq(a interface{}, b interface{}) bool { av := reflect.ValueOf(a) @@ -115,6 +120,8 @@ func trimRightSpace(s string) string { return strings.TrimRightFunc(s, unicode.IsSpace) } +// FIXME appendIfNotPresent is unused by cobra and should be removed in a version 2. It exists only for compatibility with users of cobra. + // appendIfNotPresent will append stringToAppend to the end of s, but only if it's not yet present in s. func appendIfNotPresent(s, stringToAppend string) string { if strings.Contains(s, stringToAppend) { diff --git a/vendor/github.com/spf13/cobra/cobra/cmd/add.go b/vendor/github.com/spf13/cobra/cobra/cmd/add.go index b89d4c474..8897f8ff0 100644 --- a/vendor/github.com/spf13/cobra/cobra/cmd/add.go +++ b/vendor/github.com/spf13/cobra/cobra/cmd/add.go @@ -15,20 +15,19 @@ package cmd import ( "fmt" + "os" "path/filepath" - "strings" + "unicode" "github.com/spf13/cobra" - "github.com/spf13/viper" ) func init() { - RootCmd.AddCommand(addCmd) + addCmd.Flags().StringVarP(&parentName, "parent", "p", "RootCmd", "name of parent command for this command") } -var pName string +var parentName string -// initialize Command var addCmd = &cobra.Command{ Use: "add [command name]", Aliases: []string{"command"}, @@ -40,37 +39,84 @@ 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 - `, +Example: cobra add server -> resulting in a new cmd/server.go`, Run: func(cmd *cobra.Command, args []string) { - if len(args) != 1 { + if len(args) < 1 { er("add needs a name for the command") } - guessProjectPath() - createCmdFile(args[0]) + wd, err := os.Getwd() + if err != nil { + er(err) + } + project := NewProjectFromPath(wd) + + cmdName := validateCmdName(args[0]) + cmdPath := filepath.Join(project.CmdPath(), cmdName+".go") + createCmdFile(project.License(), cmdPath, cmdName) + + fmt.Fprintln(cmd.OutOrStdout(), cmdName, "created at", cmdPath) }, } -func init() { - addCmd.Flags().StringVarP(&pName, "parent", "p", "RootCmd", "name of parent command for this command") -} +// validateCmdName returns source without any dashes and underscore. +// If there will be dash or underscore, next letter will be uppered. +// It supports only ASCII (1-byte character) strings. +// https://github.com/spf13/cobra/issues/269 +func validateCmdName(source string) string { + i := 0 + l := len(source) + // The output is initialized on demand, then first dash or underscore + // occurs. + var output string + + for i < l { + if source[i] == '-' || source[i] == '_' { + if output == "" { + output = source[:i] + } + + // If it's last rune and it's dash or underscore, + // don't add it output and break the loop. + if i == l-1 { + break + } + + // If next character is dash or underscore, + // just skip the current character. + if source[i+1] == '-' || source[i+1] == '_' { + i++ + continue + } + + // If the current character is dash or underscore, + // upper next letter and add to output. + output += string(unicode.ToUpper(rune(source[i+1]))) + // We know, what source[i] is dash or underscore and source[i+1] is + // uppered character, so make i = i+2. + i += 2 + continue + } -func parentName() string { - if !strings.HasSuffix(strings.ToLower(pName), "cmd") { - return pName + "Cmd" + // If the current character isn't dash or underscore, + // just add it. + if output != "" { + output += string(source[i]) + } + i++ } - return pName + if output == "" { + return source // source is initially valid name. + } + return output } -func createCmdFile(cmdName string) { - lic := getLicense() +func createCmdFile(license License, path, cmdName string) { + template := `{{comment .copyright}} +{{comment .license}} - template := `{{ comment .copyright }} -{{ comment .license }} - -package cmd +package {{.cmdPackage}} import ( "fmt" @@ -79,8 +125,8 @@ import ( ) // {{.cmdName}}Cmd represents the {{.cmdName}} command -var {{ .cmdName }}Cmd = &cobra.Command{ - Use: "{{ .cmdName }}", +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: @@ -89,13 +135,12 @@ 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") + fmt.Println("{{.cmdName}} called") }, } func init() { - {{ .parentName }}.AddCommand({{ .cmdName }}Cmd) + {{.parentName}}.AddCommand({{.cmdName}}Cmd) // Here you will define your flags and configuration settings. @@ -106,23 +151,22 @@ func init() { // 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 := make(map[string]interface{}) data["copyright"] = copyrightLine() - data["license"] = lic.Header - data["appName"] = projectName() - data["viper"] = viper.GetBool("useViper") - data["parentName"] = parentName() + data["license"] = license.Header + data["cmdPackage"] = filepath.Base(filepath.Dir(path)) // last dir of path + data["parentName"] = parentName data["cmdName"] = cmdName - err := writeTemplateToFile(filepath.Join(ProjectPath(), guessCmdDir()), cmdName+".go", template, data) + cmdScript, err := executeTemplate(template, data) + if err != nil { + er(err) + } + err = writeStringToFile(path, cmdScript) if err != nil { er(err) } - fmt.Println(cmdName, "created at", filepath.Join(ProjectPath(), guessCmdDir(), cmdName+".go")) } diff --git a/vendor/github.com/spf13/cobra/cobra/cmd/add_test.go b/vendor/github.com/spf13/cobra/cobra/cmd/add_test.go new file mode 100644 index 000000000..dacbe838a --- /dev/null +++ b/vendor/github.com/spf13/cobra/cobra/cmd/add_test.go @@ -0,0 +1,100 @@ +package cmd + +import ( + "errors" + "io/ioutil" + "os" + "path/filepath" + "testing" +) + +// TestGoldenAddCmd initializes the project "github.com/spf13/testproject" +// in GOPATH, adds "test" command +// and compares the content of all files in cmd directory of testproject +// with appropriate golden files. +// Use -update to update existing golden files. +func TestGoldenAddCmd(t *testing.T) { + projectName := "github.com/spf13/testproject" + project := NewProject(projectName) + + // Initialize the project at first. + initializeProject(project) + defer os.RemoveAll(project.AbsPath()) + + // Then add the "test" command. + cmdName := "test" + cmdPath := filepath.Join(project.CmdPath(), cmdName+".go") + createCmdFile(project.License(), cmdPath, cmdName) + + expectedFiles := []string{".", "root.go", "test.go"} + gotFiles := []string{} + + // Check project file hierarchy and compare the content of every single file + // with appropriate golden file. + err := filepath.Walk(project.CmdPath(), func(path string, info os.FileInfo, err error) error { + if err != nil { + return err + } + + // Make path relative to project.CmdPath(). + // E.g. path = "/home/user/go/src/github.com/spf13/testproject/cmd/root.go" + // then it returns just "root.go". + relPath, err := filepath.Rel(project.CmdPath(), path) + if err != nil { + return err + } + relPath = filepath.ToSlash(relPath) + gotFiles = append(gotFiles, relPath) + goldenPath := filepath.Join("testdata", filepath.Base(path)+".golden") + + switch relPath { + // Know directories. + case ".": + return nil + // Known files. + case "root.go", "test.go": + if *update { + got, err := ioutil.ReadFile(path) + if err != nil { + return err + } + ioutil.WriteFile(goldenPath, got, 0644) + } + return compareFiles(path, goldenPath) + } + // Unknown file. + return errors.New("unknown file: " + path) + }) + if err != nil { + t.Fatal(err) + } + + // Check if some files lack. + if err := checkLackFiles(expectedFiles, gotFiles); err != nil { + t.Fatal(err) + } +} + +func TestValidateCmdName(t *testing.T) { + testCases := []struct { + input string + expected string + }{ + {"cmdName", "cmdName"}, + {"cmd_name", "cmdName"}, + {"cmd-name", "cmdName"}, + {"cmd______Name", "cmdName"}, + {"cmd------Name", "cmdName"}, + {"cmd______name", "cmdName"}, + {"cmd------name", "cmdName"}, + {"cmdName-----", "cmdName"}, + {"cmdname-", "cmdname"}, + } + + for _, testCase := range testCases { + got := validateCmdName(testCase.input) + if testCase.expected != got { + t.Errorf("Expected %q, got %q", testCase.expected, got) + } + } +} diff --git a/vendor/github.com/spf13/cobra/cobra/cmd/golden_test.go b/vendor/github.com/spf13/cobra/cobra/cmd/golden_test.go new file mode 100644 index 000000000..0ac7e8935 --- /dev/null +++ b/vendor/github.com/spf13/cobra/cobra/cmd/golden_test.go @@ -0,0 +1,77 @@ +package cmd + +import ( + "bytes" + "errors" + "flag" + "fmt" + "io/ioutil" + "os/exec" +) + +var update = flag.Bool("update", false, "update .golden files") + +func init() { + // Mute commands. + addCmd.SetOutput(new(bytes.Buffer)) + initCmd.SetOutput(new(bytes.Buffer)) +} + +// compareFiles compares the content of files with pathA and pathB. +// If contents are equal, it returns nil. +// If not, it returns which files are not equal +// and diff (if system has diff command) between these files. +func compareFiles(pathA, pathB string) error { + contentA, err := ioutil.ReadFile(pathA) + if err != nil { + return err + } + contentB, err := ioutil.ReadFile(pathB) + if err != nil { + return err + } + if !bytes.Equal(contentA, contentB) { + output := new(bytes.Buffer) + output.WriteString(fmt.Sprintf("%q and %q are not equal!\n\n", pathA, pathB)) + + diffPath, err := exec.LookPath("diff") + if err != nil { + // Don't execute diff if it can't be found. + return nil + } + diffCmd := exec.Command(diffPath, pathA, pathB) + diffCmd.Stdout = output + diffCmd.Stderr = output + + output.WriteString("$ diff " + pathA + " " + pathB + "\n") + if err := diffCmd.Run(); err != nil { + output.WriteString("\n" + err.Error()) + } + return errors.New(output.String()) + } + return nil +} + +// checkLackFiles checks if all elements of expected are in got. +func checkLackFiles(expected, got []string) error { + lacks := make([]string, 0, len(expected)) + for _, ev := range expected { + if !stringInStringSlice(ev, got) { + lacks = append(lacks, ev) + } + } + if len(lacks) > 0 { + return fmt.Errorf("Lack %v file(s): %v", len(lacks), lacks) + } + return nil +} + +// stringInStringSlice checks if s is an element of slice. +func stringInStringSlice(s string, slice []string) bool { + for _, v := range slice { + if s == v { + return true + } + } + return false +} diff --git a/vendor/github.com/spf13/cobra/cobra/cmd/helpers.go b/vendor/github.com/spf13/cobra/cobra/cmd/helpers.go index 7cd3be18b..6114227db 100644 --- a/vendor/github.com/spf13/cobra/cobra/cmd/helpers.go +++ b/vendor/github.com/spf13/cobra/cobra/cmd/helpers.go @@ -21,335 +21,119 @@ import ( "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"} +var cmdDirs = [...]string{"cmd", "cmds", "command", "commands"} +var srcPaths []string func init() { - funcMap = template.FuncMap{ - "comment": commentifyString, + // Initialize srcPaths. + envGoPath := os.Getenv("GOPATH") + goPaths := filepath.SplitList(envGoPath) + if len(goPaths) == 0 { + er("$GOPATH is not set") + } + srcPaths = make([]string, 0, len(goPaths)) + for _, goPath := range goPaths { + srcPaths = append(srcPaths, filepath.Join(goPath, "src")) } } 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 - } - } + os.Exit(1) } // 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) - } +func isEmpty(path string) bool { fi, err := os.Stat(path) if err != nil { - return false, err + er(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 + er(err) } - list, _ := f.Readdir(-1) - // f.Close() - see bug fix above - return len(list) == 0, nil + defer f.Close() + dirs, err := f.Readdirnames(1) + if err != nil && err != io.EOF { + er(err) + } + return len(dirs) == 0 } - return fi.Size() == 0, nil + return fi.Size() == 0 } -// 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 +// exists checks if a file or directory exists. +func exists(path string) bool { + if path == "" { + return false } - 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 := os.Stat(path) + if err == nil { + return true } - - err = safeWriteToDisk(filename, r) - - if err != nil { - return err + if !os.IsNotExist(err) { + er(err) } - return nil + return false } -func writeStringToFile(path, file, text string) error { - filename := filepath.Join(path, file) - - r := strings.NewReader(text) - err := safeWriteToDisk(filename, r) - +func executeTemplate(tmplStr string, data interface{}) (string, error) { + tmpl, err := template.New("").Funcs(template.FuncMap{"comment": commentifyString}).Parse(tmplStr) if err != nil { - return err + 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 + return buf.String(), 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) +func writeStringToFile(path string, s string) error { + return writeToFile(path, strings.NewReader(s)) +} - if ospath != "" { - err = os.MkdirAll(ospath, 0777) // rwx, rw, r - if err != nil { - return - } +// writeToFile writes r to file with path only +// if file/directory on given path doesn't exist. +// If file/directory exists on given path, then +// it terminates app and prints an appropriate error. +func writeToFile(path string, r io.Reader) error { + if exists(path) { + return fmt.Errorf("%v already exists", path) } - ex, err := exists(inpath) - if err != nil { - return - } - if ex { - return fmt.Errorf("%v already exists", inpath) + dir := filepath.Dir(path) + if dir != "" { + if err := os.MkdirAll(dir, 0777); err != nil { + return err + } } - file, err := os.Create(inpath) + file, err := os.Create(path) if err != nil { - return + return err } 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 - - if viper.IsSet("license.header") || viper.IsSet("license.text") { - if custom, ok := Licenses["custom"]; ok { - custom.Header = viper.GetString("license.header") - custom.Text = viper.GetString("license.text") - Licenses["custom"] = custom - return "custom" - } - } - - return matchLicense(viper.GetString("license")) -} - -func copyrightLine() string { - author := viper.GetString("author") - year := time.Now().Format("2006") - - return "Copyright © " + year + " " + author + return err } +// commentfyString comments every line of in. 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 { + for _, line := range lines { + if strings.HasPrefix(line, "//") { + newlines = append(newlines, line) + } else { + if line == "" { newlines = append(newlines, "//") + } else { + newlines = append(newlines, "// "+line) } - } else { - newlines = append(newlines, x) } } return strings.Join(newlines, "\n") diff --git a/vendor/github.com/spf13/cobra/cobra/cmd/helpers_test.go b/vendor/github.com/spf13/cobra/cobra/cmd/helpers_test.go deleted file mode 100644 index bd0f75951..000000000 --- a/vendor/github.com/spf13/cobra/cobra/cmd/helpers_test.go +++ /dev/null @@ -1,40 +0,0 @@ -package cmd - -import ( - "fmt" - "os" - "path/filepath" - "testing" -) - -var _ = fmt.Println -var _ = os.Stderr - -func checkGuess(t *testing.T, wd, input, expected string) { - testWd = wd - inputPath = input - guessProjectPath() - - if projectPath != expected { - t.Errorf("Unexpected Project Path. \n Got: %q\nExpected: %q\n", projectPath, expected) - } - - reset() -} - -func reset() { - testWd = "" - inputPath = "" - projectPath = "" -} - -func TestProjectPath(t *testing.T) { - checkGuess(t, "", filepath.Join("github.com", "spf13", "hugo"), filepath.Join(getSrcPath(), "github.com", "spf13", "hugo")) - checkGuess(t, "", filepath.Join("spf13", "hugo"), filepath.Join(getSrcPath(), "github.com", "spf13", "hugo")) - checkGuess(t, "", filepath.Join("/", "bar", "foo"), filepath.Join("/", "bar", "foo")) - checkGuess(t, "/bar/foo", "baz", filepath.Join("/", "bar", "foo", "baz")) - checkGuess(t, "/bar/foo/cmd", "", filepath.Join("/", "bar", "foo")) - checkGuess(t, "/bar/foo/command", "", filepath.Join("/", "bar", "foo")) - checkGuess(t, "/bar/foo/commands", "", filepath.Join("/", "bar", "foo")) - checkGuess(t, "github.com/spf13/hugo/../hugo", "", filepath.Join("github.com", "spf13", "hugo")) -} diff --git a/vendor/github.com/spf13/cobra/cobra/cmd/init.go b/vendor/github.com/spf13/cobra/cobra/cmd/init.go index b77c98645..0e2b22aa0 100644 --- a/vendor/github.com/spf13/cobra/cobra/cmd/init.go +++ b/vendor/github.com/spf13/cobra/cobra/cmd/init.go @@ -14,20 +14,15 @@ package cmd import ( - "bytes" "fmt" "os" - "strings" + "path" + "path/filepath" "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"}, @@ -45,79 +40,75 @@ and the appropriate structure for a Cobra-based CLI application. 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] + wd, err := os.Getwd() + if err != nil { + er(err) + } - default: - er("init doesn't support more than 1 parameter") + var project *Project + if len(args) == 0 { + project = NewProjectFromPath(wd) + } else if len(args) == 1 { + arg := args[0] + if arg[0] == '.' { + arg = filepath.Join(wd, arg) + } + if filepath.IsAbs(arg) { + project = NewProjectFromPath(arg) + } else { + project = NewProject(arg) + } + } else { + er("please enter the name") } - guessProjectPath() - initializePath(projectPath) + + initializeProject(project) + + fmt.Fprintln(cmd.OutOrStdout(), `Your Cobra application is ready at +`+project.AbsPath()+`. + +Give it a try by going there and running `+"`go run main.go`."+` +Add commands to it by running `+"`cobra add [cmdname]`.") }, } -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) +func initializeProject(project *Project) { + if !exists(project.AbsPath()) { // If path doesn't yet exist, create it + err := os.MkdirAll(project.AbsPath(), 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") - } + } else if !isEmpty(project.AbsPath()) { // If path exists and is not empty don't use it + er("Cobra will not create a new project in a non empty directory: " + project.AbsPath()) } - // We have a directory and it's empty.. Time to initialize it. - createLicenseFile() - createMainFile() - createRootCmdFile() + // We have a directory and it's empty. Time to initialize it. + createLicenseFile(project.License(), project.AbsPath()) + createMainFile(project) + createRootCmdFile(project) } -func createLicenseFile() { - lic := getLicense() - - // Don't bother writing a LICENSE file if there is no text. - if lic.Text != "" { - data := make(map[string]interface{}) - - // Try to remove the email address, if any - data["copyright"] = strings.Split(copyrightLine(), " <")[0] - - data["appName"] = projectName() +func createLicenseFile(license License, path string) { + data := make(map[string]interface{}) + data["copyright"] = copyrightLine() - // Generate license template from text and data. - r, _ := templateToReader(lic.Text, data) - buf := new(bytes.Buffer) - buf.ReadFrom(r) + // Generate license template from text and data. + text, err := executeTemplate(license.Text, data) + if err != nil { + er(err) + } - err := writeTemplateToFile(ProjectPath(), "LICENSE", buf.String(), data) - _ = err - // if err != nil { - // er(err) - // } + // Write license text to LICENSE file. + err = writeStringToFile(filepath.Join(path, "LICENSE"), text) + if err != nil { + er(err) } } -func createMainFile() { - lic := getLicense() +func createMainFile(project *Project) { + mainTemplate := `{{ comment .copyright }} +{{if .license}}{{ comment .license }}{{end}} - template := `{{ comment .copyright }} -{{if .license}}{{ comment .license }} -{{end}} package main import "{{ .importpath }}" @@ -127,46 +118,41 @@ func main() { } ` data := make(map[string]interface{}) - data["copyright"] = copyrightLine() - data["appName"] = projectName() - - // Generate license template from header and data. - r, _ := templateToReader(lic.Header, data) - buf := new(bytes.Buffer) - buf.ReadFrom(r) - data["license"] = buf.String() + data["license"] = project.License().Header + data["importpath"] = path.Join(project.Name(), filepath.Base(project.CmdPath())) - data["importpath"] = guessImportPath() + "/" + guessCmdDir() + mainScript, err := executeTemplate(mainTemplate, data) + if err != nil { + er(err) + } - err := writeTemplateToFile(ProjectPath(), "main.go", template, data) - _ = err - // if err != nil { - // er(err) - // } + err = writeStringToFile(filepath.Join(project.AbsPath(), "main.go"), mainScript) + if err != nil { + er(err) + } } -func createRootCmdFile() { - lic := getLicense() +func createRootCmdFile(project *Project) { + template := `{{comment .copyright}} +{{if .license}}{{comment .license}}{{end}} - template := `{{ comment .copyright }} -{{if .license}}{{ comment .license }} -{{end}} package cmd import ( "fmt" "os" + homedir "github.com/mitchellh/go-homedir" "github.com/spf13/cobra" -{{ if .viper }} "github.com/spf13/viper" -{{ end }}) -{{if .viper}} -var cfgFile string -{{ end }} +{{if .viper}} "github.com/spf13/viper"{{end}} +) + +{{if .viper}}var cfgFile string{{end}} + // RootCmd represents the base command when called without any subcommands var RootCmd = &cobra.Command{ - Use: "{{ .appName }}", + 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: @@ -174,9 +160,9 @@ 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) { }, + // 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. @@ -184,62 +170,65 @@ to quickly create a Cobra application.` + "`" + `, func Execute() { if err := RootCmd.Execute(); err != nil { fmt.Println(err) - os.Exit(-1) + 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 +{{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 }} +}{{ if .viper }} + // initConfig reads in config file and ENV variables if set. func initConfig() { - if cfgFile != "" { // enable ability to specify config file via flag + if cfgFile != "" { + // Use config file from the flag. viper.SetConfigFile(cfgFile) + } else { + // Find home directory. + home, err := homedir.Dir() + if err != nil { + fmt.Println(err) + os.Exit(1) + } + + // Search config in home directory with name ".{{ .appName }}" (without extension). + viper.AddConfigPath(home) + viper.SetConfigName(".{{ .appName }}") } - viper.SetConfigName(".{{ .appName }}") // name of config file (without extension) - viper.AddConfigPath(os.Getenv("HOME")) // adding home directory as first search path - viper.AutomaticEnv() // read in environment variables that match + 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 }}` +}{{ end }} +` data := make(map[string]interface{}) - data["copyright"] = copyrightLine() - data["appName"] = projectName() - - // Generate license template from header and data. - r, _ := templateToReader(lic.Header, data) - buf := new(bytes.Buffer) - buf.ReadFrom(r) - data["license"] = buf.String() - data["viper"] = viper.GetBool("useViper") + data["license"] = project.License().Header + data["appName"] = path.Base(project.Name()) + + rootCmdScript, err := executeTemplate(template, data) + if err != nil { + er(err) + } - err := writeTemplateToFile(ProjectPath()+string(os.PathSeparator)+guessCmdDir(), "root.go", template, data) + err = writeStringToFile(filepath.Join(project.CmdPath(), "root.go"), rootCmdScript) 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]`") } diff --git a/vendor/github.com/spf13/cobra/cobra/cmd/init_test.go b/vendor/github.com/spf13/cobra/cobra/cmd/init_test.go new file mode 100644 index 000000000..9a918b9b4 --- /dev/null +++ b/vendor/github.com/spf13/cobra/cobra/cmd/init_test.go @@ -0,0 +1,74 @@ +package cmd + +import ( + "errors" + "io/ioutil" + "os" + "path/filepath" + "testing" +) + +// TestGoldenInitCmd initializes the project "github.com/spf13/testproject" +// in GOPATH and compares the content of files in initialized project with +// appropriate golden files ("testdata/*.golden"). +// Use -update to update existing golden files. +func TestGoldenInitCmd(t *testing.T) { + projectName := "github.com/spf13/testproject" + project := NewProject(projectName) + defer os.RemoveAll(project.AbsPath()) + + os.Args = []string{"cobra", "init", projectName} + if err := rootCmd.Execute(); err != nil { + t.Fatal("Error by execution:", err) + } + + expectedFiles := []string{".", "cmd", "LICENSE", "main.go", "cmd/root.go"} + gotFiles := []string{} + + // Check project file hierarchy and compare the content of every single file + // with appropriate golden file. + err := filepath.Walk(project.AbsPath(), func(path string, info os.FileInfo, err error) error { + if err != nil { + return err + } + + // Make path relative to project.AbsPath(). + // E.g. path = "/home/user/go/src/github.com/spf13/testproject/cmd/root.go" + // then it returns just "cmd/root.go". + relPath, err := filepath.Rel(project.AbsPath(), path) + if err != nil { + return err + } + relPath = filepath.ToSlash(relPath) + gotFiles = append(gotFiles, relPath) + goldenPath := filepath.Join("testdata", filepath.Base(path)+".golden") + + switch relPath { + // Know directories. + case ".", "cmd": + return nil + // Known files. + case "LICENSE", "main.go", "cmd/root.go": + if *update { + got, err := ioutil.ReadFile(path) + if err != nil { + return err + } + if err := ioutil.WriteFile(goldenPath, got, 0644); err != nil { + t.Fatal("Error while updating file:", err) + } + } + return compareFiles(path, goldenPath) + } + // Unknown file. + return errors.New("unknown file: " + path) + }) + if err != nil { + t.Fatal(err) + } + + // Check if some files lack. + if err := checkLackFiles(expectedFiles, gotFiles); err != nil { + t.Fatal(err) + } +} diff --git a/vendor/github.com/spf13/cobra/cobra/cmd/license_agpl.go b/vendor/github.com/spf13/cobra/cobra/cmd/license_agpl.go new file mode 100644 index 000000000..4ea036ede --- /dev/null +++ b/vendor/github.com/spf13/cobra/cobra/cmd/license_agpl.go @@ -0,0 +1,684 @@ +package cmd + +func initAgpl() { + Licenses["agpl"] = License{ + Name: "GNU Affero General Public License", + PossibleMatches: []string{"agpl", "affero gpl", "gnu agpl"}, + Header: `{{.copyright}} + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see <http://www.gnu.org/licenses/>.`, + Text: ` GNU AFFERO GENERAL PUBLIC LICENSE + Version 3, 19 November 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/> + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU Affero General Public License is a free, copyleft license for +software and other kinds of works, specifically designed to ensure +cooperation with the community in the case of network server software. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +our General Public Licenses are intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + Developers that use our General Public Licenses protect your rights +with two steps: (1) assert copyright on the software, and (2) offer +you this License which gives you legal permission to copy, distribute +and/or modify the software. + + A secondary benefit of defending all users' freedom is that +improvements made in alternate versions of the program, if they +receive widespread use, become available for other developers to +incorporate. Many developers of free software are heartened and +encouraged by the resulting cooperation. However, in the case of +software used on network servers, this result may fail to come about. +The GNU General Public License permits making a modified version and +letting the public access it on a server without ever releasing its +source code to the public. + + The GNU Affero General Public License is designed specifically to +ensure that, in such cases, the modified source code becomes available +to the community. It requires the operator of a network server to +provide the source code of the modified version running there to the +users of that server. Therefore, public use of a modified version, on +a publicly accessible server, gives the public access to the source +code of the modified version. + + An older license, called the Affero General Public License and +published by Affero, was designed to accomplish similar goals. This is +a different license, not a version of the Affero GPL, but Affero has +released a new version of the Affero GPL which permits relicensing under +this license. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU Affero General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Remote Network Interaction; Use with the GNU General Public License. + + Notwithstanding any other provision of this License, if you modify the +Program, your modified version must prominently offer all users +interacting with it remotely through a computer network (if your version +supports such interaction) an opportunity to receive the Corresponding +Source of your version by providing access to the Corresponding Source +from a network server at no charge, through some standard or customary +means of facilitating copying of software. This Corresponding Source +shall include the Corresponding Source for any work covered by version 3 +of the GNU General Public License that is incorporated pursuant to the +following paragraph. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the work with which it is combined will remain governed by version +3 of the GNU General Public License. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU Affero General Public License from time to time. Such new versions +will be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU Affero General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU Affero General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU Affero General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + <one line to give the program's name and a brief idea of what it does.> + Copyright (C) <year> <name of author> + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + +Also add information on how to contact you by electronic and paper mail. + + If your software can interact with users remotely through a computer +network, you should also make sure that it provides a way for users to +get its source. For example, if your program is a web application, its +interface could display a "Source" link that leads users to an archive +of the code. There are many ways you could offer source, and different +solutions will be better for different programs; see section 13 for the +specific requirements. + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU AGPL, see +<http://www.gnu.org/licenses/>. +`, + } +} diff --git a/vendor/github.com/spf13/cobra/cobra/cmd/license_apache_2.go b/vendor/github.com/spf13/cobra/cobra/cmd/license_apache_2.go index 878e1d936..3f330867d 100644 --- a/vendor/github.com/spf13/cobra/cobra/cmd/license_apache_2.go +++ b/vendor/github.com/spf13/cobra/cobra/cmd/license_apache_2.go @@ -19,18 +19,17 @@ func initApache2() { Licenses["apache"] = License{ Name: "Apache 2.0", PossibleMatches: []string{"apache", "apache20", "apache 2.0", "apache2.0", "apache-2.0"}, - Header: ` -// 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.`, + Header: `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.`, Text: ` Apache License Version 2.0, January 2004 diff --git a/vendor/github.com/spf13/cobra/cobra/cmd/license_bsd_clause_2.go b/vendor/github.com/spf13/cobra/cobra/cmd/license_bsd_clause_2.go index 26bc775a9..f2982dab3 100644 --- a/vendor/github.com/spf13/cobra/cobra/cmd/license_bsd_clause_2.go +++ b/vendor/github.com/spf13/cobra/cobra/cmd/license_bsd_clause_2.go @@ -17,8 +17,9 @@ package cmd func initBsdClause2() { Licenses["freebsd"] = License{ - Name: "Simplified BSD License", - PossibleMatches: []string{"freebsd", "simpbsd", "simple bsd", "2 clause bsd"}, + Name: "Simplified BSD License", + PossibleMatches: []string{"freebsd", "simpbsd", "simple bsd", "2-clause bsd", + "2 clause bsd", "simplified bsd license"}, Header: ` All rights reserved. diff --git a/vendor/github.com/spf13/cobra/cobra/cmd/license_bsd_clause_3.go b/vendor/github.com/spf13/cobra/cobra/cmd/license_bsd_clause_3.go index 062c11528..39c9571f2 100644 --- a/vendor/github.com/spf13/cobra/cobra/cmd/license_bsd_clause_3.go +++ b/vendor/github.com/spf13/cobra/cobra/cmd/license_bsd_clause_3.go @@ -18,7 +18,7 @@ package cmd func initBsdClause3() { Licenses["bsd"] = License{ Name: "NewBSD", - PossibleMatches: []string{"bsd", "newbsd", "3 clause bsd"}, + PossibleMatches: []string{"bsd", "newbsd", "3 clause bsd", "3-clause bsd"}, Header: ` All rights reserved. diff --git a/vendor/github.com/spf13/cobra/cobra/cmd/license_gpl_2.go b/vendor/github.com/spf13/cobra/cobra/cmd/license_gpl_2.go index b361dd734..054b470f1 100644 --- a/vendor/github.com/spf13/cobra/cobra/cmd/license_gpl_2.go +++ b/vendor/github.com/spf13/cobra/cobra/cmd/license_gpl_2.go @@ -18,21 +18,21 @@ package cmd func initGpl2() { Licenses["gpl2"] = License{ Name: "GNU General Public License 2.0", - PossibleMatches: []string{"gpl2", "gnu gpl2"}, - Header: `{{ .copyright }} + PossibleMatches: []string{"gpl2", "gnu gpl2", "gplv2"}, + Header: `{{.copyright}} - {{ .appName }} is free software; you can redistribute it and/or + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. - {{ .appName }} is distributed in the hope that it will be useful, + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU Lesser General Public License - along with {{ .appName }}. If not, see <http://www.gnu.org/licenses/>.`, + along with this program. If not, see <http://www.gnu.org/licenses/>.`, Text: ` GNU GENERAL PUBLIC LICENSE Version 2, June 1991 @@ -313,6 +313,65 @@ PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + <one line to give the program's name and a brief idea of what it does.> + Copyright (C) <year> <name of author> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type 'show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type 'show c' for details. + +The hypothetical commands 'show w' and 'show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than 'show w' and 'show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + 'Gnomovision' (which makes passes at compilers) written by James Hacker. + + <signature of Ty Coon>, 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. `, } } diff --git a/vendor/github.com/spf13/cobra/cobra/cmd/license_gpl_3.go b/vendor/github.com/spf13/cobra/cobra/cmd/license_gpl_3.go index 5810276b2..d1ef656a7 100644 --- a/vendor/github.com/spf13/cobra/cobra/cmd/license_gpl_3.go +++ b/vendor/github.com/spf13/cobra/cobra/cmd/license_gpl_3.go @@ -18,23 +18,21 @@ package cmd func initGpl3() { Licenses["gpl3"] = License{ Name: "GNU General Public License 3.0", - PossibleMatches: []string{"gpl3", "gpl", "gnu gpl3", "gnu gpl"}, - Header: ` -This file is part of {{ .appName }}. + PossibleMatches: []string{"gpl3", "gplv3", "gpl", "gnu gpl3", "gnu gpl"}, + Header: `{{.copyright}} -{{ .appName }} is free software: you can redistribute it and/or modify -it under the terms of the GNU Lesser General Public License as published by +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. -{{ .appName }} is distributed in the hope that it will be useful, +This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU Lesser General Public License for more details. +GNU General Public License for more details. -You should have received a copy of the GNU Lesser General Public License -along with {{ .appName }}. If not, see <http://www.gnu.org/licenses/>. - `, +You should have received a copy of the GNU General Public License +along with this program. If not, see <http://www.gnu.org/licenses/>.`, Text: ` GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 @@ -656,6 +654,59 @@ Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee. END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + <one line to give the program's name and a brief idea of what it does.> + Copyright (C) <year> <name of author> + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + <program> Copyright (C) <year> <name of author> + This program comes with ABSOLUTELY NO WARRANTY; for details type 'show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type 'show c' for details. + +The hypothetical commands 'show w' and 'show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +<http://www.gnu.org/licenses/>. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +<http://www.gnu.org/philosophy/why-not-lgpl.html>. `, } } diff --git a/vendor/github.com/spf13/cobra/cobra/cmd/license_lgpl.go b/vendor/github.com/spf13/cobra/cobra/cmd/license_lgpl.go new file mode 100644 index 000000000..75fd043b8 --- /dev/null +++ b/vendor/github.com/spf13/cobra/cobra/cmd/license_lgpl.go @@ -0,0 +1,187 @@ +package cmd + +func initLgpl() { + Licenses["lgpl"] = License{ + Name: "GNU Lesser General Public License", + PossibleMatches: []string{"lgpl", "lesser gpl", "gnu lgpl"}, + Header: `{{.copyright}} + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with this program. If not, see <http://www.gnu.org/licenses/>.`, + Text: ` GNU LESSER GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/> + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + + This version of the GNU Lesser General Public License incorporates +the terms and conditions of version 3 of the GNU General Public +License, supplemented by the additional permissions listed below. + + 0. Additional Definitions. + + As used herein, "this License" refers to version 3 of the GNU Lesser +General Public License, and the "GNU GPL" refers to version 3 of the GNU +General Public License. + + "The Library" refers to a covered work governed by this License, +other than an Application or a Combined Work as defined below. + + An "Application" is any work that makes use of an interface provided +by the Library, but which is not otherwise based on the Library. +Defining a subclass of a class defined by the Library is deemed a mode +of using an interface provided by the Library. + + A "Combined Work" is a work produced by combining or linking an +Application with the Library. The particular version of the Library +with which the Combined Work was made is also called the "Linked +Version". + + The "Minimal Corresponding Source" for a Combined Work means the +Corresponding Source for the Combined Work, excluding any source code +for portions of the Combined Work that, considered in isolation, are +based on the Application, and not on the Linked Version. + + The "Corresponding Application Code" for a Combined Work means the +object code and/or source code for the Application, including any data +and utility programs needed for reproducing the Combined Work from the +Application, but excluding the System Libraries of the Combined Work. + + 1. Exception to Section 3 of the GNU GPL. + + You may convey a covered work under sections 3 and 4 of this License +without being bound by section 3 of the GNU GPL. + + 2. Conveying Modified Versions. + + If you modify a copy of the Library, and, in your modifications, a +facility refers to a function or data to be supplied by an Application +that uses the facility (other than as an argument passed when the +facility is invoked), then you may convey a copy of the modified +version: + + a) under this License, provided that you make a good faith effort to + ensure that, in the event an Application does not supply the + function or data, the facility still operates, and performs + whatever part of its purpose remains meaningful, or + + b) under the GNU GPL, with none of the additional permissions of + this License applicable to that copy. + + 3. Object Code Incorporating Material from Library Header Files. + + The object code form of an Application may incorporate material from +a header file that is part of the Library. You may convey such object +code under terms of your choice, provided that, if the incorporated +material is not limited to numerical parameters, data structure +layouts and accessors, or small macros, inline functions and templates +(ten or fewer lines in length), you do both of the following: + + a) Give prominent notice with each copy of the object code that the + Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the object code with a copy of the GNU GPL and this license + document. + + 4. Combined Works. + + You may convey a Combined Work under terms of your choice that, +taken together, effectively do not restrict modification of the +portions of the Library contained in the Combined Work and reverse +engineering for debugging such modifications, if you also do each of +the following: + + a) Give prominent notice with each copy of the Combined Work that + the Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the Combined Work with a copy of the GNU GPL and this license + document. + + c) For a Combined Work that displays copyright notices during + execution, include the copyright notice for the Library among + these notices, as well as a reference directing the user to the + copies of the GNU GPL and this license document. + + d) Do one of the following: + + 0) Convey the Minimal Corresponding Source under the terms of this + License, and the Corresponding Application Code in a form + suitable for, and under terms that permit, the user to + recombine or relink the Application with a modified version of + the Linked Version to produce a modified Combined Work, in the + manner specified by section 6 of the GNU GPL for conveying + Corresponding Source. + + 1) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (a) uses at run time + a copy of the Library already present on the user's computer + system, and (b) will operate properly with a modified version + of the Library that is interface-compatible with the Linked + Version. + + e) Provide Installation Information, but only if you would otherwise + be required to provide such information under section 6 of the + GNU GPL, and only to the extent that such information is + necessary to install and execute a modified version of the + Combined Work produced by recombining or relinking the + Application with a modified version of the Linked Version. (If + you use option 4d0, the Installation Information must accompany + the Minimal Corresponding Source and Corresponding Application + Code. If you use option 4d1, you must provide the Installation + Information in the manner specified by section 6 of the GNU GPL + for conveying Corresponding Source.) + + 5. Combined Libraries. + + You may place library facilities that are a work based on the +Library side by side in a single library together with other library +facilities that are not Applications and are not covered by this +License, and convey such a combined library under terms of your +choice, if you do both of the following: + + a) Accompany the combined library with a copy of the same work based + on the Library, uncombined with any other library facilities, + conveyed under the terms of this License. + + b) Give prominent notice with the combined library that part of it + is a work based on the Library, and explaining where to find the + accompanying uncombined form of the same work. + + 6. Revised Versions of the GNU Lesser General Public License. + + The Free Software Foundation may publish revised and/or new versions +of the GNU Lesser General Public License from time to time. Such new +versions will be similar in spirit to the present version, but may +differ in detail to address new problems or concerns. + + Each version is given a distinguishing version number. If the +Library as you received it specifies that a certain numbered version +of the GNU Lesser General Public License "or any later version" +applies to it, you have the option of following the terms and +conditions either of that published version or of any later version +published by the Free Software Foundation. If the Library as you +received it does not specify a version number of the GNU Lesser +General Public License, you may choose any version of the GNU Lesser +General Public License ever published by the Free Software Foundation. + + If the Library as you received it specifies that a proxy can decide +whether future versions of the GNU Lesser General Public License shall +apply, that proxy's public statement of acceptance of any version is +permanent authorization for you to choose that version for the +Library.`, + } +} diff --git a/vendor/github.com/spf13/cobra/cobra/cmd/licenses.go b/vendor/github.com/spf13/cobra/cobra/cmd/licenses.go index 5b3cb7293..d73e6fb35 100644 --- a/vendor/github.com/spf13/cobra/cobra/cmd/licenses.go +++ b/vendor/github.com/spf13/cobra/cobra/cmd/licenses.go @@ -15,13 +15,18 @@ package cmd -import "strings" +import ( + "strings" + "time" -//Licenses contains all possible licenses a user can chose from -var Licenses map[string]License + "github.com/spf13/viper" +) -//License represents a software license agreement, containing the Name of -// the license, its possible matches (on the command line as given to cobra) +// Licenses contains all possible licenses a user can choose from. +var Licenses = make(map[string]License) + +// License represents a software license agreement, containing the Name of +// the license, its possible matches (on the command line as given to cobra), // the header to be used with each file on the file's creating, and the text // of the license type License struct { @@ -31,45 +36,79 @@ type License struct { Header string // License header for source files } -// given a license name (in), try to match the license indicated -func matchLicense(in string) string { - for key, lic := range Licenses { - for _, match := range lic.PossibleMatches { - if strings.EqualFold(in, match) { - return key - } - } - } - return "" -} - func init() { - Licenses = make(map[string]License) - // Allows a user to not use a license. Licenses["none"] = License{"None", []string{"none", "false"}, "", ""} - // Allows a user to use config for a custom license. - Licenses["custom"] = License{"Custom", []string{}, "", ""} - initApache2() - initMit() - initBsdClause3() - initBsdClause2() - initGpl2() - initGpl3() + initLgpl() + initAgpl() +} - // Licenses["apache20"] = License{ - // Name: "Apache 2.0", - // PossibleMatches: []string{"apache", "apache20", ""}, - // Header: ` - // `, - // Text: ` - // `, - // } +// getLicense returns license specified by user in flag or in config. +// If user didn't specify the license, it returns Apache License 2.0. +// +// TODO: Inspect project for existing license +func getLicense() License { + // If explicitly flagged, use that. + if userLicense != "" { + return findLicense(userLicense) + } + + // If user wants to have custom license, use that. + if viper.IsSet("license.header") || viper.IsSet("license.text") { + return License{Header: viper.GetString("license.header"), + Text: "license.text"} + } + + // If user wants to have built-in license, use that. + if viper.IsSet("license") { + return findLicense(viper.GetString("license")) + } + + // If user didn't set any license, use Apache 2.0 by default. + return Licenses["apache"] +} + +func copyrightLine() string { + author := viper.GetString("author") + year := time.Now().Format("2006") + + return "Copyright © " + year + " " + author +} + +// findLicense looks for License object of built-in licenses. +// If it didn't find license, then the app will be terminated and +// error will be printed. +func findLicense(name string) License { + found := matchLicense(name) + if found == "" { + er("unknown license: " + name) + } + return Licenses[found] +} + +// matchLicense compares the given a license name +// to PossibleMatches of all built-in licenses. +// It returns blank string, if name is blank string or it didn't find +// then appropriate match to name. +func matchLicense(name string) string { + if name == "" { + return "" + } + + for key, lic := range Licenses { + for _, match := range lic.PossibleMatches { + if strings.EqualFold(name, match) { + return key + } + } + } + + return "" } diff --git a/vendor/github.com/spf13/cobra/cobra/cmd/project.go b/vendor/github.com/spf13/cobra/cobra/cmd/project.go new file mode 100644 index 000000000..de1168a13 --- /dev/null +++ b/vendor/github.com/spf13/cobra/cobra/cmd/project.go @@ -0,0 +1,195 @@ +package cmd + +import ( + "os" + "path/filepath" + "runtime" + "strings" +) + +// Project contains name, license and paths to projects. +type Project struct { + absPath string + cmdPath string + srcPath string + license License + name string +} + +// NewProject returns Project with specified project name. +// If projectName is blank string, it returns nil. +func NewProject(projectName string) *Project { + if projectName == "" { + return nil + } + + p := new(Project) + p.name = projectName + + // 1. Find already created protect. + p.absPath = findPackage(projectName) + + // 2. If there are no created project with this path, and user is in GOPATH, + // then use GOPATH/src/projectName. + if p.absPath == "" { + wd, err := os.Getwd() + if err != nil { + er(err) + } + for _, srcPath := range srcPaths { + goPath := filepath.Dir(srcPath) + if filepathHasPrefix(wd, goPath) { + p.absPath = filepath.Join(srcPath, projectName) + break + } + } + } + + // 3. If user is not in GOPATH, then use (first GOPATH)/src/projectName. + if p.absPath == "" { + p.absPath = filepath.Join(srcPaths[0], projectName) + } + + return p +} + +// findPackage returns full path to existing go package in GOPATHs. +// findPackage returns "", if it can't find path. +// If packageName is "", findPackage returns "". +func findPackage(packageName string) string { + if packageName == "" { + return "" + } + + for _, srcPath := range srcPaths { + packagePath := filepath.Join(srcPath, packageName) + if exists(packagePath) { + return packagePath + } + } + + return "" +} + +// NewProjectFromPath returns Project with specified absolute path to +// package. +// If absPath is blank string or if absPath is not actually absolute, +// it returns nil. +func NewProjectFromPath(absPath string) *Project { + if absPath == "" || !filepath.IsAbs(absPath) { + return nil + } + + p := new(Project) + p.absPath = absPath + p.absPath = strings.TrimSuffix(p.absPath, findCmdDir(p.absPath)) + p.name = filepath.ToSlash(trimSrcPath(p.absPath, p.SrcPath())) + return p +} + +// trimSrcPath trims at the beginning of absPath the srcPath. +func trimSrcPath(absPath, srcPath string) string { + relPath, err := filepath.Rel(srcPath, absPath) + if err != nil { + er("Cobra supports project only within $GOPATH: " + err.Error()) + } + return relPath +} + +// License returns the License object of project. +func (p *Project) License() License { + if p.license.Text == "" && p.license.Name != "None" { + p.license = getLicense() + } + + return p.license +} + +// Name returns the name of project, e.g. "github.com/spf13/cobra" +func (p Project) Name() string { + return p.name +} + +// CmdPath returns absolute path to directory, where all commands are located. +// +// CmdPath returns blank string, only if p.AbsPath() is a blank string. +func (p *Project) CmdPath() string { + if p.absPath == "" { + return "" + } + if p.cmdPath == "" { + p.cmdPath = filepath.Join(p.absPath, findCmdDir(p.absPath)) + } + return p.cmdPath +} + +// findCmdDir checks if base of absPath is cmd dir and returns it or +// looks for existing cmd dir in absPath. +// If the cmd dir doesn't exist, empty, or cannot be found, +// it returns "cmd". +func findCmdDir(absPath string) string { + if !exists(absPath) || isEmpty(absPath) { + return "cmd" + } + + if isCmdDir(absPath) { + return filepath.Base(absPath) + } + + files, _ := filepath.Glob(filepath.Join(absPath, "c*")) + for _, file := range files { + if isCmdDir(file) { + return filepath.Base(file) + } + } + + return "cmd" +} + +// isCmdDir checks if base of name is one of cmdDir. +func isCmdDir(name string) bool { + name = filepath.Base(name) + for _, cmdDir := range cmdDirs { + if name == cmdDir { + return true + } + } + return false +} + +// AbsPath returns absolute path of project. +func (p Project) AbsPath() string { + return p.absPath +} + +// SrcPath returns absolute path to $GOPATH/src where project is located. +func (p *Project) SrcPath() string { + if p.srcPath != "" { + return p.srcPath + } + if p.absPath == "" { + p.srcPath = srcPaths[0] + return p.srcPath + } + + for _, srcPath := range srcPaths { + if filepathHasPrefix(p.absPath, srcPath) { + p.srcPath = srcPath + break + } + } + + return p.srcPath +} + +func filepathHasPrefix(path string, prefix string) bool { + if len(path) <= len(prefix) { + return false + } + if runtime.GOOS == "windows" { + // Paths in windows are case-insensitive. + return strings.EqualFold(path[0:len(prefix)], prefix) + } + return path[0:len(prefix)] == prefix + +} diff --git a/vendor/github.com/spf13/cobra/cobra/cmd/project_test.go b/vendor/github.com/spf13/cobra/cobra/cmd/project_test.go new file mode 100644 index 000000000..037f7c554 --- /dev/null +++ b/vendor/github.com/spf13/cobra/cobra/cmd/project_test.go @@ -0,0 +1,24 @@ +package cmd + +import ( + "testing" +) + +func TestFindExistingPackage(t *testing.T) { + path := findPackage("github.com/spf13/cobra") + if path == "" { + t.Fatal("findPackage didn't find the existing package") + } + if !hasGoPathPrefix(path) { + t.Fatalf("%q is not in GOPATH, but must be", path) + } +} + +func hasGoPathPrefix(path string) bool { + for _, srcPath := range srcPaths { + if filepathHasPrefix(path, srcPath) { + return true + } + } + return false +} diff --git a/vendor/github.com/spf13/cobra/cobra/cmd/root.go b/vendor/github.com/spf13/cobra/cobra/cmd/root.go index 32386ace4..cfc785221 100644 --- a/vendor/github.com/spf13/cobra/cobra/cmd/root.go +++ b/vendor/github.com/spf13/cobra/cobra/cmd/root.go @@ -15,57 +15,69 @@ package cmd import ( "fmt" - "os" + homedir "github.com/mitchellh/go-homedir" "github.com/spf13/cobra" "github.com/spf13/viper" ) -var cfgFile string -var userLicense string +var ( + // Used for flags. + cfgFile, projectBase, userLicense string -// RootCmd 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. + 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. +// Execute executes the root command. func Execute() { - if err := RootCmd.Execute(); err != nil { - fmt.Println(err) - os.Exit(-1) + if err := rootCmd.Execute(); err != nil { + er(err) } } 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 `license` 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")) + initViper() + + 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 `license` 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") + + rootCmd.AddCommand(initCmd) + rootCmd.AddCommand(addCmd) + } -// Read in config file and ENV variables if set. -func initConfig() { - if cfgFile != "" { // enable ability to specify config file via flag +func initViper() { + if cfgFile != "" { + // Use config file from the flag. viper.SetConfigFile(cfgFile) + } else { + // Find home directory. + home, err := homedir.Dir() + if err != nil { + er(err) + } + + // Search config in home directory with name ".cobra" (without extension). + viper.AddConfigPath(home) + viper.SetConfigName(".cobra") } - viper.SetConfigName(".cobra") // name of config file (without extension) - viper.AddConfigPath(os.Getenv("HOME")) // adding home directory as first search path - viper.AutomaticEnv() // read in environment variables that match + viper.AutomaticEnv() - // If a config file is found, read it in. if err := viper.ReadInConfig(); err == nil { fmt.Println("Using config file:", viper.ConfigFileUsed()) } diff --git a/vendor/github.com/spf13/cobra/cobra/cmd/testdata/LICENSE.golden b/vendor/github.com/spf13/cobra/cobra/cmd/testdata/LICENSE.golden new file mode 100644 index 000000000..d64569567 --- /dev/null +++ b/vendor/github.com/spf13/cobra/cobra/cmd/testdata/LICENSE.golden @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + 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. diff --git a/vendor/github.com/spf13/cobra/cobra/cmd/testdata/main.go.golden b/vendor/github.com/spf13/cobra/cobra/cmd/testdata/main.go.golden new file mode 100644 index 000000000..69ecbd48e --- /dev/null +++ b/vendor/github.com/spf13/cobra/cobra/cmd/testdata/main.go.golden @@ -0,0 +1,20 @@ +// Copyright © 2017 NAME HERE <EMAIL ADDRESS> +// 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/testproject/cmd" + +func main() { + cmd.Execute() +} diff --git a/vendor/github.com/spf13/cobra/cobra/cmd/testdata/root.go.golden b/vendor/github.com/spf13/cobra/cobra/cmd/testdata/root.go.golden new file mode 100644 index 000000000..13e9a7760 --- /dev/null +++ b/vendor/github.com/spf13/cobra/cobra/cmd/testdata/root.go.golden @@ -0,0 +1,88 @@ +// Copyright © 2017 NAME HERE <EMAIL ADDRESS> +// 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" + + homedir "github.com/mitchellh/go-homedir" + "github.com/spf13/cobra" + "github.com/spf13/viper" +) + +var cfgFile string + +// RootCmd represents the base command when called without any subcommands +var RootCmd = &cobra.Command{ + Use: "testproject", + 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() { + cobra.OnInitialize(initConfig) + + // Here you will define your flags and configuration settings. + // Cobra supports persistent flags, which, if defined here, + // will be global for your application. + RootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file (default is $HOME/.testproject.yaml)") + + // 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") +} + +// initConfig reads in config file and ENV variables if set. +func initConfig() { + if cfgFile != "" { + // Use config file from the flag. + viper.SetConfigFile(cfgFile) + } else { + // Find home directory. + home, err := homedir.Dir() + if err != nil { + fmt.Println(err) + os.Exit(1) + } + + // Search config in home directory with name ".testproject" (without extension). + viper.AddConfigPath(home) + viper.SetConfigName(".testproject") + } + + 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()) + } +} diff --git a/vendor/github.com/spf13/cobra/cobra/cmd/testdata/test.go.golden b/vendor/github.com/spf13/cobra/cobra/cmd/testdata/test.go.golden new file mode 100644 index 000000000..c8319d1dd --- /dev/null +++ b/vendor/github.com/spf13/cobra/cobra/cmd/testdata/test.go.golden @@ -0,0 +1,49 @@ +// Copyright © 2017 NAME HERE <EMAIL ADDRESS> +// 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" + + "github.com/spf13/cobra" +) + +// testCmd represents the test command +var testCmd = &cobra.Command{ + Use: "test", + 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) { + fmt.Println("test called") + }, +} + +func init() { + RootCmd.AddCommand(testCmd) + + // Here you will define your flags and configuration settings. + + // Cobra supports Persistent Flags which will work for this command + // and all subcommands, e.g.: + // testCmd.PersistentFlags().String("foo", "", "A help for foo") + + // Cobra supports local flags which will only run when this command + // is called directly, e.g.: + // testCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle") +} diff --git a/vendor/github.com/spf13/cobra/cobra_test.go b/vendor/github.com/spf13/cobra/cobra_test.go index d6593a539..576c97d36 100644 --- a/vendor/github.com/spf13/cobra/cobra_test.go +++ b/vendor/github.com/spf13/cobra/cobra_test.go @@ -3,6 +3,7 @@ package cobra import ( "bytes" "fmt" + "os" "reflect" "runtime" "strings" @@ -12,13 +13,12 @@ import ( "github.com/spf13/pflag" ) -var tp, te, tt, t1, tr []string +var tp, te, tt, tr []string var rootPersPre, echoPre, echoPersPre, timesPersPre []string var flagb1, flagb2, flagb3, flagbr, flagbp bool var flags1, flags2a, flags2b, flags3, outs string var flagi1, flagi2, flagi3, flagi4, flagir int -var globalFlag1 bool -var flagEcho, rootcalled bool +var rootcalled bool var versionUsed int const strtwoParentHelp = "help message for parent flag strtwo" @@ -226,36 +226,36 @@ type resulter struct { Command *Command } -func fullSetupTest(input string) resulter { +func fullSetupTest(args ...string) resulter { c := initializeWithRootCmd() - return fullTester(c, input) + return fullTester(c, args...) } -func noRRSetupTestSilenced(input string) resulter { +func noRRSetupTestSilenced(args ...string) resulter { c := initialize() c.SilenceErrors = true c.SilenceUsage = true - return fullTester(c, input) + return fullTester(c, args...) } -func noRRSetupTest(input string) resulter { +func noRRSetupTest(args ...string) resulter { c := initialize() - return fullTester(c, input) + return fullTester(c, args...) } -func rootOnlySetupTest(input string) resulter { +func rootOnlySetupTest(args ...string) resulter { c := initializeWithRootCmd() - return simpleTester(c, input) + return simpleTester(c, args...) } -func simpleTester(c *Command, input string) resulter { +func simpleTester(c *Command, args ...string) resulter { buf := new(bytes.Buffer) // Testing flag with invalid input c.SetOutput(buf) - c.SetArgs(strings.Split(input, " ")) + c.SetArgs(args) err := c.Execute() output := buf.String() @@ -263,11 +263,11 @@ func simpleTester(c *Command, input string) resulter { return resulter{err, output, c} } -func simpleTesterC(c *Command, input string) resulter { +func simpleTesterC(c *Command, args ...string) resulter { buf := new(bytes.Buffer) // Testing flag with invalid input c.SetOutput(buf) - c.SetArgs(strings.Split(input, " ")) + c.SetArgs(args) cmd, err := c.ExecuteC() output := buf.String() @@ -275,13 +275,13 @@ func simpleTesterC(c *Command, input string) resulter { return resulter{err, output, cmd} } -func fullTester(c *Command, input string) resulter { +func fullTester(c *Command, args ...string) resulter { buf := new(bytes.Buffer) // Testing flag with invalid input c.SetOutput(buf) cmdEcho.AddCommand(cmdTimes) c.AddCommand(cmdPrint, cmdEcho, cmdSubNoRun, cmdCustomFlags, cmdDeprecated) - c.SetArgs(strings.Split(input, " ")) + c.SetArgs(args) err := c.Execute() output := buf.String() @@ -331,7 +331,7 @@ func checkOutputContains(t *testing.T, c *Command, check string) { } func TestSingleCommand(t *testing.T) { - noRRSetupTest("print one two") + noRRSetupTest("print", "one", "two") if te != nil || tt != nil { t.Error("Wrong command called") @@ -345,7 +345,7 @@ func TestSingleCommand(t *testing.T) { } func TestChildCommand(t *testing.T) { - noRRSetupTest("echo times one two") + noRRSetupTest("echo", "times", "one", "two") if te != nil || tp != nil { t.Error("Wrong command called") @@ -359,7 +359,7 @@ func TestChildCommand(t *testing.T) { } func TestCommandAlias(t *testing.T) { - noRRSetupTest("say times one two") + noRRSetupTest("say", "times", "one", "two") if te != nil || tp != nil { t.Error("Wrong command called") @@ -374,7 +374,7 @@ func TestCommandAlias(t *testing.T) { func TestPrefixMatching(t *testing.T) { EnablePrefixMatching = true - noRRSetupTest("ech times one two") + noRRSetupTest("ech", "times", "one", "two") if te != nil || tp != nil { t.Error("Wrong command called") @@ -392,7 +392,7 @@ func TestPrefixMatching(t *testing.T) { func TestNoPrefixMatching(t *testing.T) { EnablePrefixMatching = false - noRRSetupTest("ech times one two") + noRRSetupTest("ech", "times", "one", "two") if !(tt == nil && te == nil && tp == nil) { t.Error("Wrong command called") @@ -401,7 +401,7 @@ func TestNoPrefixMatching(t *testing.T) { func TestAliasPrefixMatching(t *testing.T) { EnablePrefixMatching = true - noRRSetupTest("sa times one two") + noRRSetupTest("sa", "times", "one", "two") if te != nil || tp != nil { t.Error("Wrong command called") @@ -418,7 +418,7 @@ func TestAliasPrefixMatching(t *testing.T) { func TestChildSameName(t *testing.T) { c := initializeWithSameName() c.AddCommand(cmdPrint, cmdEcho) - c.SetArgs(strings.Split("print one two", " ")) + c.SetArgs([]string{"print", "one", "two"}) c.Execute() if te != nil || tt != nil { @@ -436,7 +436,7 @@ func TestGrandChildSameName(t *testing.T) { c := initializeWithSameName() cmdTimes.AddCommand(cmdPrint) c.AddCommand(cmdTimes) - c.SetArgs(strings.Split("times print one two", " ")) + c.SetArgs([]string{"times", "print", "one", "two"}) c.Execute() if te != nil || tt != nil { @@ -453,13 +453,13 @@ func TestGrandChildSameName(t *testing.T) { func TestUsage(t *testing.T) { x := fullSetupTest("help") checkResultContains(t, x, cmdRootWithRun.Use+" [flags]") - x = fullSetupTest("help customflags") + x = fullSetupTest("help", "customflags") checkResultContains(t, x, cmdCustomFlags.Use) checkResultOmits(t, x, cmdCustomFlags.Use+" [flags]") } func TestFlagLong(t *testing.T) { - noRRSetupTest("echo --intone=13 something -- here") + noRRSetupTest("echo", "--intone=13", "something", "--", "here") if cmdEcho.ArgsLenAtDash() != 1 { t.Errorf("expected argsLenAtDash: %d but got %d", 1, cmdRootNoRun.ArgsLenAtDash()) @@ -476,7 +476,7 @@ func TestFlagLong(t *testing.T) { } func TestFlagShort(t *testing.T) { - noRRSetupTest("echo -i13 -- something here") + noRRSetupTest("echo", "-i13", "--", "something", "here") if cmdEcho.ArgsLenAtDash() != 0 { t.Errorf("expected argsLenAtDash: %d but got %d", 0, cmdRootNoRun.ArgsLenAtDash()) @@ -491,7 +491,7 @@ func TestFlagShort(t *testing.T) { t.Errorf("default flag value changed, 234 expected, %d given", flagi2) } - noRRSetupTest("echo -i 13 something here") + noRRSetupTest("echo", "-i", "13", "something", "here") if strings.Join(te, " ") != "something here" { t.Errorf("flags didn't leave proper args remaining..%s given", te) @@ -503,7 +503,7 @@ func TestFlagShort(t *testing.T) { t.Errorf("default flag value changed, 234 expected, %d given", flagi2) } - noRRSetupTest("print -i99 one two") + noRRSetupTest("print", "-i99", "one", "two") if strings.Join(tp, " ") != "one two" { t.Errorf("flags didn't leave proper args remaining..%s given", tp) @@ -517,14 +517,14 @@ func TestFlagShort(t *testing.T) { } func TestChildCommandFlags(t *testing.T) { - noRRSetupTest("echo times -j 99 one two") + noRRSetupTest("echo", "times", "-j", "99", "one", "two") if strings.Join(tt, " ") != "one two" { t.Errorf("flags didn't leave proper args remaining..%s given", tt) } // Testing with flag that shouldn't be persistent - r := noRRSetupTest("echo times -j 99 -i77 one two") + r := noRRSetupTest("echo", "times", "-j", "99", "-i77", "one", "two") if r.Error == nil { t.Errorf("invalid flag should generate error") @@ -543,7 +543,7 @@ func TestChildCommandFlags(t *testing.T) { } // Testing with flag only existing on child - r = noRRSetupTest("echo -j 99 -i77 one two") + r = noRRSetupTest("echo", "-j", "99", "-i77", "one", "two") if r.Error == nil { t.Errorf("invalid flag should generate error") @@ -553,7 +553,7 @@ func TestChildCommandFlags(t *testing.T) { } // Testing with persistent flag overwritten by child - noRRSetupTest("echo times --strtwo=child one two") + noRRSetupTest("echo", "times", "--strtwo=child", "one", "two") if flags2b != "child" { t.Errorf("flag value should be child, %s given", flags2b) @@ -564,7 +564,7 @@ func TestChildCommandFlags(t *testing.T) { } // Testing flag with invalid input - r = noRRSetupTest("echo -i10E") + r = noRRSetupTest("echo", "-i10E") if r.Error == nil { t.Errorf("invalid input should generate error") @@ -575,7 +575,7 @@ func TestChildCommandFlags(t *testing.T) { } func TestTrailingCommandFlags(t *testing.T) { - x := fullSetupTest("echo two -x") + x := fullSetupTest("echo", "two", "-x") if x.Error == nil { t.Errorf("invalid flag should generate error") @@ -586,7 +586,7 @@ func TestInvalidSubcommandFlags(t *testing.T) { cmd := initializeWithRootCmd() cmd.AddCommand(cmdTimes) - result := simpleTester(cmd, "times --inttwo=2 --badflag=bar") + result := simpleTester(cmd, "times", "--inttwo=2", "--badflag=bar") // given that we are not checking here result.Error we check for // stock usage message checkResultContains(t, result, "cobra-test times [# times]") @@ -616,14 +616,14 @@ func TestSubcommandExecuteC(t *testing.T) { cmd.AddCommand(double, echo) - result := simpleTesterC(cmd, "double hello world") + result := simpleTesterC(cmd, "double", "hello", "world") checkResultContains(t, result, "hello world hello world") if result.Command.Name() != "double" { t.Errorf("invalid cmd returned from ExecuteC: should be 'double' but got %s", result.Command.Name()) } - result = simpleTesterC(cmd, "echo msg to be echoed") + result = simpleTesterC(cmd, "echo", "msg", "to", "be", "echoed") checkResultContains(t, result, "msg to be echoed") if result.Command.Name() != "echo" { @@ -649,16 +649,16 @@ func TestSubcommandArgEvaluation(t *testing.T) { } first.AddCommand(second) - result := simpleTester(cmd, "first second first third") + result := simpleTester(cmd, "first", "second", "first", "third") - expectedOutput := fmt.Sprintf("%v", []string{"first third"}) + expectedOutput := fmt.Sprint([]string{"first third"}) if result.Output != expectedOutput { t.Errorf("exptected %v, got %v", expectedOutput, result.Output) } } func TestPersistentFlags(t *testing.T) { - fullSetupTest("echo -s something -p more here") + fullSetupTest("echo", "-s", "something", "-p", "more", "here") // persistentFlag should act like normal flag on its own command if strings.Join(te, " ") != "more here" { @@ -672,7 +672,7 @@ func TestPersistentFlags(t *testing.T) { } // persistentFlag should act like normal flag on its own command - fullSetupTest("echo times -s again -c -p test here") + fullSetupTest("echo", "times", "-s", "again", "-c", "-p", "test", "here") if strings.Join(tt, " ") != "test here" { t.Errorf("flags didn't leave proper args remaining. %s given", tt) @@ -694,17 +694,17 @@ func TestHelpCommand(t *testing.T) { x := fullSetupTest("help") checkResultContains(t, x, cmdRootWithRun.Long) - x = fullSetupTest("help echo") + x = fullSetupTest("help", "echo") checkResultContains(t, x, cmdEcho.Long) - x = fullSetupTest("help echo times") + x = fullSetupTest("help", "echo", "times") checkResultContains(t, x, cmdTimes.Long) } func TestChildCommandHelp(t *testing.T) { - c := noRRSetupTest("print --help") + c := noRRSetupTest("print", "--help") checkResultContains(t, c, strtwoParentHelp) - r := noRRSetupTest("echo times --help") + r := noRRSetupTest("echo", "times", "--help") checkResultContains(t, r, strtwoChildHelp) } @@ -716,7 +716,7 @@ func TestNonRunChildHelp(t *testing.T) { func TestRunnableRootCommand(t *testing.T) { x := fullSetupTest("") - if rootcalled != true { + if !rootcalled { t.Errorf("Root Function was not called\n out:%v", x.Error) } } @@ -750,7 +750,6 @@ func TestVisitParents(t *testing.T) { } func TestRunnableRootCommandNilInput(t *testing.T) { - var emptyArg []string c := initializeWithRootCmd() buf := new(bytes.Buffer) @@ -758,23 +757,20 @@ func TestRunnableRootCommandNilInput(t *testing.T) { c.SetOutput(buf) cmdEcho.AddCommand(cmdTimes) c.AddCommand(cmdPrint, cmdEcho) - c.SetArgs(emptyArg) + c.SetArgs([]string{}) err := c.Execute() if err != nil { t.Errorf("Execute() failed with %v", err) } - if rootcalled != true { + if !rootcalled { t.Errorf("Root Function was not called") } } func TestRunnableRootCommandEmptyInput(t *testing.T) { - args := make([]string, 3) - args[0] = "" - args[1] = "--introot=12" - args[2] = "" + args := []string{"", "--introot=12", ""} c := initializeWithRootCmd() buf := new(bytes.Buffer) @@ -786,13 +782,13 @@ func TestRunnableRootCommandEmptyInput(t *testing.T) { c.Execute() - if rootcalled != true { - t.Errorf("Root Function was not called.\n\nOutput was:\n\n%s\n", buf) + if !rootcalled { + t.Errorf("Root Function was not called.\nOutput was:\n%s\n", buf) } } func TestInvalidSubcommandWhenArgsAllowed(t *testing.T) { - fullSetupTest("echo invalid-sub") + fullSetupTest("echo", "invalid-sub") if te[0] != "invalid-sub" { t.Errorf("Subcommand didn't work...") @@ -800,9 +796,9 @@ func TestInvalidSubcommandWhenArgsAllowed(t *testing.T) { } func TestRootFlags(t *testing.T) { - fullSetupTest("-i 17 -b") + fullSetupTest("-i", "17", "-b") - if flagbr != true { + if !flagbr { t.Errorf("flag value should be true, %v given", flagbr) } @@ -825,7 +821,7 @@ func TestRootHelp(t *testing.T) { t.Errorf("--help shouldn't display subcommand's usage, Got: \n %s", x.Output) } - x = fullSetupTest("echo --help") + x = fullSetupTest("echo", "--help") if strings.Contains(x.Output, cmdTimes.Use) { t.Errorf("--help shouldn't display subsubcommand's usage, Got: \n %s", x.Output) @@ -860,7 +856,6 @@ func TestFlagAccess(t *testing.T) { } func TestNoNRunnableRootCommandNilInput(t *testing.T) { - var args []string c := initialize() buf := new(bytes.Buffer) @@ -868,7 +863,7 @@ func TestNoNRunnableRootCommandNilInput(t *testing.T) { c.SetOutput(buf) cmdEcho.AddCommand(cmdTimes) c.AddCommand(cmdPrint, cmdEcho) - c.SetArgs(args) + c.SetArgs([]string{}) c.Execute() @@ -887,7 +882,7 @@ func TestRootNoCommandHelp(t *testing.T) { t.Errorf("--help shouldn't trigger an error, Got: \n %s", x.Output) } - x = rootOnlySetupTest("echo --help") + x = rootOnlySetupTest("echo", "--help") checkResultOmits(t, x, "Available Commands:") checkResultOmits(t, x, "for more information about a command") @@ -905,7 +900,7 @@ func TestRootUnknownCommand(t *testing.T) { t.Errorf("Unexpected response.\nExpecting to be:\n %q\nGot:\n %q\n", s, r.Output) } - r = noRRSetupTest("--strtwo=a bogus") + r = noRRSetupTest("--strtwo=a", "bogus") if r.Output != s { t.Errorf("Unexpected response.\nExpecting to be:\n %q\nGot:\n %q\n", s, r.Output) } @@ -918,7 +913,7 @@ func TestRootUnknownCommandSilenced(t *testing.T) { t.Errorf("Unexpected response.\nExpecting to be: \n\"\"\n Got:\n %q\n", r.Output) } - r = noRRSetupTestSilenced("--strtwo=a bogus") + r = noRRSetupTestSilenced("--strtwo=a", "bogus") if r.Output != "" { t.Errorf("Unexpected response.\nExpecting to be:\n\"\"\nGot:\n %q\n", r.Output) } @@ -965,56 +960,27 @@ func TestRootSuggestions(t *testing.T) { func TestFlagsBeforeCommand(t *testing.T) { // short without space - x := fullSetupTest("-i10 echo") + x := fullSetupTest("-i10", "echo") if x.Error != nil { t.Errorf("Valid Input shouldn't have errors, got:\n %q", x.Error) } - // short (int) with equals - // It appears that pflags doesn't support this... - // Commenting out until support can be added - - //x = noRRSetupTest("echo -i=10") - //if x.Error != nil { - //t.Errorf("Valid Input shouldn't have errors, got:\n %s", x.Error) - //} + x = noRRSetupTest("echo", "-i=10") + if x.Error != nil { + t.Errorf("Valid Input shouldn't have errors, got:\n %s", x.Error) + } // long with equals - x = noRRSetupTest("--intone=123 echo one two") + x = noRRSetupTest("--intone=123", "echo", "one", "two") if x.Error != nil { t.Errorf("Valid Input shouldn't have errors, got:\n %s", x.Error) } // With parsing error properly reported - x = fullSetupTest("-i10E echo") + x = fullSetupTest("-i10E", "echo") if !strings.Contains(x.Error.Error(), "invalid syntax") { t.Errorf("Wrong error message displayed, \n %s", x.Error) } - - //With quotes - x = fullSetupTest("-s=\"walking\" echo") - if x.Error != nil { - t.Errorf("Valid Input shouldn't have errors, got:\n %q", x.Error) - } - - //With quotes and space - x = fullSetupTest("-s=\"walking fast\" echo") - if x.Error != nil { - t.Errorf("Valid Input shouldn't have errors, got:\n %q", x.Error) - } - - //With inner quote - x = fullSetupTest("-s=\"walking \\\"Inner Quote\\\" fast\" echo") - if x.Error != nil { - t.Errorf("Valid Input shouldn't have errors, got:\n %q", x.Error) - } - - //With quotes and space - x = fullSetupTest("-s=\"walking \\\"Inner Quote\\\" fast\" echo") - if x.Error != nil { - t.Errorf("Valid Input shouldn't have errors, got:\n %q", x.Error) - } - } func TestRemoveCommand(t *testing.T) { @@ -1080,7 +1046,7 @@ func TestDeprecatedSub(t *testing.T) { } func TestPreRun(t *testing.T) { - noRRSetupTest("echo one two") + noRRSetupTest("echo", "one", "two") if echoPre == nil || echoPersPre == nil { t.Error("PreRun or PersistentPreRun not called") } @@ -1088,7 +1054,7 @@ func TestPreRun(t *testing.T) { t.Error("Wrong *Pre functions called!") } - noRRSetupTest("echo times one two") + noRRSetupTest("echo", "times", "one", "two") if timesPersPre == nil { t.Error("PreRun or PersistentPreRun not called") } @@ -1096,7 +1062,7 @@ func TestPreRun(t *testing.T) { t.Error("Wrong *Pre functions called!") } - noRRSetupTest("print one two") + noRRSetupTest("print", "one", "two") if rootPersPre == nil { t.Error("Parent PersistentPreRun not called but should not have been") } @@ -1114,10 +1080,10 @@ func TestPeristentPreRunPropagation(t *testing.T) { // Now add cmdPrint to rootCmd rootCmd.AddCommand(cmdPrint) - rootCmd.SetArgs(strings.Split("print echosub lala", " ")) + rootCmd.SetArgs([]string{"print", "echosub", "lala"}) rootCmd.Execute() - if rootPersPre == nil || len(rootPersPre) == 0 || rootPersPre[0] != "lala" { + if len(rootPersPre) == 0 || rootPersPre[0] != "lala" { t.Error("RootCmd PersistentPreRun not called but should have been") } } @@ -1149,10 +1115,13 @@ func TestGlobalNormFuncPropagation(t *testing.T) { func TestFlagOnPflagCommandLine(t *testing.T) { flagName := "flagOnCommandLine" - pflag.CommandLine.String(flagName, "", "about my flag") + pflag.String(flagName, "", "about my flag") r := fullSetupTest("--help") checkResultContains(t, r, flagName) + + // Reset pflag.CommandLine flagset. + pflag.CommandLine = pflag.NewFlagSet(os.Args[0], pflag.ExitOnError) } func TestAddTemplateFunctions(t *testing.T) { diff --git a/vendor/github.com/spf13/cobra/command.go b/vendor/github.com/spf13/cobra/command.go index f4705f970..01d9683ea 100644 --- a/vendor/github.com/spf13/cobra/command.go +++ b/vendor/github.com/spf13/cobra/command.go @@ -11,8 +11,8 @@ // See the License for the specific language governing permissions and // limitations under the License. -//Package cobra is a commander providing a simple interface to create powerful modern CLI interfaces. -//In addition to providing an interface, Cobra simultaneously provides a controller to organize your application code. +// Package cobra is a commander providing a simple interface to create powerful modern CLI interfaces. +// In addition to providing an interface, Cobra simultaneously provides a controller to organize your application code. package cobra import ( @@ -28,110 +28,147 @@ import ( ) // Command is just that, a command for your application. -// eg. 'go run' ... 'run' is the command. Cobra requires +// E.g. 'go run ...' - 'run' is the command. Cobra requires // you to define the usage and description as part of your command // definition to ensure usability. type Command struct { - // Name is the command name, usually the executable's name. - name string - // The one-line usage message. + // Use is the one-line usage message. Use string - // An array of aliases that can be used instead of the first word in Use. + + // Aliases is an array of aliases that can be used instead of the first word in Use. Aliases []string - // An array of command names for which this command will be suggested - similar to aliases but only suggests. + + // SuggestFor is an array of command names for which this command will be suggested - + // similar to aliases but only suggests. SuggestFor []string - // The short description shown in the 'help' output. + + // Short is the short description shown in the 'help' output. Short string - // The long message shown in the 'help <this-command>' output. + + // Long is the long message shown in the 'help <this-command>' output. Long string - // Examples of how to use the command + + // Example is examples of how to use the command. Example string - // List of all valid non-flag arguments that are accepted in bash completions + + // ValidArgs is list of all valid non-flag arguments that are accepted in bash completions ValidArgs []string - // List of aliases for ValidArgs. These are not suggested to the user in the bash - // completion, but accepted if entered manually. + + // ArgAliases is List of aliases for ValidArgs. + // These are not suggested to the user in the bash completion, + // but accepted if entered manually. ArgAliases []string - // Custom functions used by the bash autocompletion generator + + // BashCompletionFunction is custom functions used by the bash autocompletion generator. BashCompletionFunction string - // Is this command deprecated and should print this string when used? + + // Deprecated defines, if this command is deprecated and should print this string when used. Deprecated string - // Is this command hidden and should NOT show up in the list of available commands? + + // Hidden defines, if this command is hidden and should NOT show up in the list of available commands. Hidden bool + // Annotations are key/value pairs that can be used by applications to identify or - // group commands + // group commands. Annotations map[string]string - // Full set of flags - flags *flag.FlagSet - // Set of flags childrens of this command will inherit - pflags *flag.FlagSet - // Flags that are declared specifically by this command (not inherited). - lflags *flag.FlagSet - // Inherited flags. - iflags *flag.FlagSet - // All persistent flags of cmd's parents. - parentsPflags *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: // * PersistentPreRun() // * PreRun() // * Run() // * PostRun() // * PersistentPostRun() - // All functions get the same args, the arguments after the command name - // PersistentPreRun: children of this command will inherit and execute + // 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: 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: 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: Typically the actual work function. Most commands will only implement this. Run func(cmd *Command, args []string) - // RunE: Run but returns an error + // 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: PostRun but returns an error. PostRunE func(cmd *Command, args []string) error - // PersistentPostRun: children of this command will inherit and execute after PostRun + // PersistentPostRun: children of this command will inherit and execute after PostRun. 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 - // DisableAutoGenTag remove + + // SilenceErrors is an option to quiet errors down stream. + SilenceErrors bool + + // SilenceUsage is an option to silence usage when an error occurs. + SilenceUsage bool + + // DisableFlagParsing disables the flag parsing. + // If this is true all flags will be passed to the command as arguments. + DisableFlagParsing bool + + // DisableAutoGenTag defines, if gen tag ("Auto generated by spf13/cobra...") + // will be printed by generating docs for this command. DisableAutoGenTag bool - // Commands is the list of commands supported by this program. + + // DisableSuggestions disables the suggestions based on Levenshtein distance + // that go along with 'unknown command' messages. + DisableSuggestions bool + // SuggestionsMinimumDistance defines minimum levenshtein distance to display suggestions. + // Must be > 0. + SuggestionsMinimumDistance int + + // name is the command name, usually the executable's name. + name string + // commands is the list of commands supported by this program. commands []*Command - // Parent Command for this command + // parent is a parent command for this command. parent *Command - // max lengths of commands' string lengths for use in padding + // Max lengths of commands' string lengths for use in padding. commandsMaxUseLen int commandsMaxCommandPathLen int commandsMaxNameLen int - // is commands slice are sorted or not + // commandsAreSorted defines, if command slice are sorted or not. commandsAreSorted bool - args []string // actual args parsed from flags - output io.Writer // out writer if set in SetOutput(w) - usageFunc func(*Command) error // Usage can be defined by application - usageTemplate string // Can be defined by Application - flagErrorFunc func(*Command, error) error - helpTemplate string // Can be defined by Application - helpFunc func(*Command, []string) // Help can be defined by application - helpCommand *Command // The help command - // The global normalization function that we can use on every pFlag set and children commands + // args is actual args parsed from flags. + args []string + // flagErrorBuf contains all error messages from pflag. + flagErrorBuf *bytes.Buffer + // flags is full set of flags. + flags *flag.FlagSet + // pflags contains persistent flags. + pflags *flag.FlagSet + // lflags contains local flags. + lflags *flag.FlagSet + // iflags contains inherited flags. + iflags *flag.FlagSet + // parentsPflags is all persistent flags of cmd's parents. + parentsPflags *flag.FlagSet + // globNormFunc is the global normalization function + // that we can use on every pflag set and children commands globNormFunc func(f *flag.FlagSet, name string) flag.NormalizedName - // Disable the suggestions based on Levenshtein distance that go along with 'unknown command' messages - DisableSuggestions bool - // If displaying suggestions, allows to set the minimum levenshtein distance to display, must be > 0 - SuggestionsMinimumDistance int - - // Disable the flag parsing. If this is true all flags will be passed to the command as arguments. - DisableFlagParsing bool + // output is an output writer defined by user. + output io.Writer + // usageFunc is usage func defined by user. + usageFunc func(*Command) error + // usageTemplate is usage template defined by user. + usageTemplate string + // flagErrorFunc is func defined by user and it's called when the parsing of + // flags returns an error. + flagErrorFunc func(*Command, error) error + // helpTemplate is help template defined by user. + helpTemplate string + // helpFunc is help func defined by user. + helpFunc func(*Command, []string) + // helpCommand is command with usage 'help'. If it's not defined by user, + // cobra uses default help command. + helpCommand *Command } // SetArgs sets arguments for the command. It is set to os.Args[1:] by default, if desired, can be overridden @@ -327,23 +364,23 @@ func (c *Command) UsageTemplate() string { return c.parent.UsageTemplate() } return `Usage:{{if .Runnable}} - {{if .HasAvailableFlags}}{{appendIfNotPresent .UseLine "[flags]"}}{{else}}{{.UseLine}}{{end}}{{end}}{{if .HasAvailableSubCommands}} - {{ .CommandPath}} [command]{{end}}{{if gt .Aliases 0}} + {{.UseLine}}{{end}}{{if .HasAvailableSubCommands}} + {{.CommandPath}} [command]{{end}}{{if gt (len .Aliases) 0}} Aliases: {{.NameAndAliases}}{{end}}{{if .HasExample}} Examples: -{{ .Example }}{{end}}{{if .HasAvailableSubCommands}} +{{.Example}}{{end}}{{if .HasAvailableSubCommands}} Available Commands:{{range .Commands}}{{if (or .IsAvailableCommand (eq .Name "help"))}} {{rpad .Name .NamePadding }} {{.Short}}{{end}}{{end}}{{end}}{{if .HasAvailableLocalFlags}} Flags: -{{.LocalFlags.FlagUsages | trimRightSpace}}{{end}}{{if .HasAvailableInheritedFlags}} +{{.LocalFlags.FlagUsages | trimTrailingWhitespaces}}{{end}}{{if .HasAvailableInheritedFlags}} Global Flags: -{{.InheritedFlags.FlagUsages | trimRightSpace}}{{end}}{{if .HasHelpSubCommands}} +{{.InheritedFlags.FlagUsages | trimTrailingWhitespaces}}{{end}}{{if .HasHelpSubCommands}} Additional help topics:{{range .Commands}}{{if .IsAdditionalHelpTopicCommand}} {{rpad .CommandPath .CommandPathPadding}} {{.Short}}{{end}}{{end}}{{end}}{{if .HasAvailableSubCommands}} @@ -361,13 +398,13 @@ func (c *Command) HelpTemplate() string { if c.HasParent() { return c.parent.HelpTemplate() } - return `{{with or .Long .Short }}{{. | trim}} + return `{{with (or .Long .Short)}}{{. | trimTrailingWhitespaces}} {{end}}{{if or .Runnable .HasSubCommands}}{{.UsageString}}{{end}}` } -func hasNoOptDefVal(name string, f *flag.FlagSet) bool { - flag := f.Lookup(name) +func hasNoOptDefVal(name string, fs *flag.FlagSet) bool { + flag := fs.Lookup(name) if flag == nil { return false } @@ -375,14 +412,15 @@ func hasNoOptDefVal(name string, f *flag.FlagSet) bool { } func shortHasNoOptDefVal(name string, fs *flag.FlagSet) bool { - result := false - fs.VisitAll(func(flag *flag.Flag) { - if flag.Shorthand == name && flag.NoOptDefVal != "" { - result = true - return - } - }) - return result + if len(name) == 0 { + return false + } + + flag := fs.ShorthandLookup(name[:1]) + if flag == nil { + return false + } + return flag.NoOptDefVal != "" } func stripFlags(args []string, c *Command) []string { @@ -392,37 +430,28 @@ func stripFlags(args []string, c *Command) []string { c.mergePersistentFlags() commands := []string{} - inQuote := false flags := c.Flags() Loop: for len(args) > 0 { s := args[0] args = args[1:] - if !inQuote { - switch { - case strings.HasPrefix(s, "\"") || strings.Contains(s, "=\""): - inQuote = true - case strings.HasPrefix(s, "--") && !strings.Contains(s, "=") && !hasNoOptDefVal(s[2:], flags): - // If '--flag arg' then - // delete arg from args. - fallthrough // (do the same as below) - case strings.HasPrefix(s, "-") && !strings.Contains(s, "=") && len(s) == 2 && !shortHasNoOptDefVal(s[1:], flags): - // If '-f arg' then - // delete 'arg' from args or break the loop if len(args) <= 1. - if len(args) <= 1 { - break Loop - } else { - args = args[1:] - continue - } - case s != "" && !strings.HasPrefix(s, "-"): - commands = append(commands, s) + switch { + case strings.HasPrefix(s, "--") && !strings.Contains(s, "=") && !hasNoOptDefVal(s[2:], flags): + // If '--flag arg' then + // delete arg from args. + fallthrough // (do the same as below) + case strings.HasPrefix(s, "-") && !strings.Contains(s, "=") && len(s) == 2 && !shortHasNoOptDefVal(s[1:], flags): + // If '-f arg' then + // delete 'arg' from args or break the loop if len(args) <= 1. + if len(args) <= 1 { + break Loop + } else { + args = args[1:] + continue } - } - - if strings.HasSuffix(s, "\"") && !strings.HasSuffix(s, "\\\"") { - inQuote = false + case s != "" && !strings.HasPrefix(s, "-"): + commands = append(commands, s) } } @@ -567,18 +596,19 @@ func (c *Command) execute(a []string) (err error) { // initialize help flag as the last point possible to allow for user // overriding - c.initHelpFlag() + c.InitDefaultHelpFlag() err = c.ParseFlags(a) if err != nil { return c.FlagErrorFunc()(c, err) } - // If help is called, regardless of other flags, return we want help + + // If help is called, regardless of other flags, return we want help. // 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() + // flag in InitDefaultHelpFlag() c.Println("\"help\" flag declared as non-bool. Please correct your code") return err } @@ -718,10 +748,19 @@ func (c *Command) ExecuteC() (cmd *Command, err error) { return cmd, nil } -func (c *Command) initHelpFlag() { +// InitDefaultHelpFlag adds default help flag to c. +// It is called automatically by executing the c or by calling help and usage. +// If c already has help flag, it will do nothing. +func (c *Command) InitDefaultHelpFlag() { c.mergePersistentFlags() if c.Flags().Lookup("help") == nil { - c.Flags().BoolP("help", "h", false, "help for "+c.Name()) + usage := "help for " + if c.Name() == "" { + usage += "this command" + } else { + usage += c.Name() + } + c.Flags().BoolP("help", "h", false, usage) } } @@ -745,6 +784,7 @@ func (c *Command) initHelpCmd() { c.Printf("Unknown help topic %#q\n", args) c.Root().Usage() } else { + cmd.InitDefaultHelpFlag() // make possible 'help' flag to be shown cmd.Help() } }, @@ -848,34 +888,34 @@ func (c *Command) Print(i ...interface{}) { // Println is a convenience method to Println to the defined output, fallback to Stderr if not set. func (c *Command) Println(i ...interface{}) { - str := fmt.Sprintln(i...) - c.Print(str) + c.Print(fmt.Sprintln(i...)) } // Printf is a convenience method to Printf to the defined output, fallback to Stderr if not set. func (c *Command) Printf(format string, i ...interface{}) { - str := fmt.Sprintf(format, i...) - c.Print(str) + c.Print(fmt.Sprintf(format, i...)) } // CommandPath returns the full path to this command. func (c *Command) CommandPath() string { - str := c.Name() - x := c - for x.HasParent() { - str = x.parent.Name() + " " + str - x = x.parent + if c.HasParent() { + return c.Parent().CommandPath() + " " + c.Name() } - return str + return c.Name() } // UseLine puts out the full usage for a given command (including parents). func (c *Command) UseLine() string { - str := "" + var useline string if c.HasParent() { - str = c.parent.CommandPath() + " " + useline = c.parent.CommandPath() + " " + c.Use + } else { + useline = c.Use + } + if c.HasAvailableFlags() && !strings.Contains(useline, "[flags]") { + useline += " [flags]" } - return str + c.Use + return useline } // DebugFlags used to determine which flags have been assigned to which commands @@ -908,6 +948,7 @@ func (c *Command) DebugFlags() { } }) } + c.Println(x.flagErrorBuf) if x.HasSubCommands() { for _, y := range x.commands { debugflags(y) @@ -920,15 +961,14 @@ func (c *Command) DebugFlags() { // Name returns the command's name: the first word in the use line. func (c *Command) Name() string { - if c.name != "" { - return c.name - } - name := c.Use - i := strings.Index(name, " ") - if i >= 0 { - name = name[:i] + if c.name == "" { + name := c.Use + i := strings.Index(name, " ") + if i >= 0 { + name = name[:i] + } + c.name = name } - c.name = name return c.name } @@ -1048,7 +1088,10 @@ func (c *Command) GlobalNormalizationFunc() func(f *flag.FlagSet, name string) f func (c *Command) Flags() *flag.FlagSet { if c.flags == nil { c.flags = flag.NewFlagSet(c.Name(), flag.ContinueOnError) - c.flags.SetOutput(c.OutOrStderr()) + if c.flagErrorBuf == nil { + c.flagErrorBuf = new(bytes.Buffer) + } + c.flags.SetOutput(c.flagErrorBuf) } return c.flags @@ -1073,7 +1116,10 @@ func (c *Command) LocalFlags() *flag.FlagSet { if c.lflags == nil { c.lflags = flag.NewFlagSet(c.Name(), flag.ContinueOnError) - c.lflags.SetOutput(c.OutOrStderr()) + if c.flagErrorBuf == nil { + c.flagErrorBuf = new(bytes.Buffer) + } + c.lflags.SetOutput(c.flagErrorBuf) } c.lflags.SortFlags = c.Flags().SortFlags @@ -1093,6 +1139,10 @@ func (c *Command) InheritedFlags() *flag.FlagSet { if c.iflags == nil { c.iflags = flag.NewFlagSet(c.Name(), flag.ContinueOnError) + if c.flagErrorBuf == nil { + c.flagErrorBuf = new(bytes.Buffer) + } + c.iflags.SetOutput(c.flagErrorBuf) } local := c.LocalFlags() @@ -1113,17 +1163,22 @@ func (c *Command) NonInheritedFlags() *flag.FlagSet { func (c *Command) PersistentFlags() *flag.FlagSet { if c.pflags == nil { c.pflags = flag.NewFlagSet(c.Name(), flag.ContinueOnError) - c.pflags.SetOutput(c.OutOrStderr()) + if c.flagErrorBuf == nil { + c.flagErrorBuf = new(bytes.Buffer) + } + c.pflags.SetOutput(c.flagErrorBuf) } return c.pflags } // ResetFlags is used in testing. func (c *Command) ResetFlags() { + c.flagErrorBuf = new(bytes.Buffer) + c.flagErrorBuf.Reset() c.flags = flag.NewFlagSet(c.Name(), flag.ContinueOnError) - c.flags.SetOutput(c.OutOrStderr()) + c.flags.SetOutput(c.flagErrorBuf) c.pflags = flag.NewFlagSet(c.Name(), flag.ContinueOnError) - c.pflags.SetOutput(c.OutOrStderr()) + c.pflags.SetOutput(c.flagErrorBuf) } // HasFlags checks if the command contains any flags (local plus persistent from the entire structure). @@ -1211,8 +1266,8 @@ func (c *Command) Parent() *Command { // mergePersistentFlags merges c.PersistentFlags() to c.Flags() // and adds missing persistent flags of all parents. func (c *Command) mergePersistentFlags() { - c.Flags().AddFlagSet(c.PersistentFlags()) c.updateParentsPflags() + c.Flags().AddFlagSet(c.PersistentFlags()) c.Flags().AddFlagSet(c.parentsPflags) } @@ -1222,7 +1277,7 @@ func (c *Command) mergePersistentFlags() { func (c *Command) updateParentsPflags() { if c.parentsPflags == nil { c.parentsPflags = flag.NewFlagSet(c.Name(), flag.ContinueOnError) - c.parentsPflags.SetOutput(c.OutOrStderr()) + c.parentsPflags.SetOutput(c.flagErrorBuf) c.parentsPflags.SortFlags = false } diff --git a/vendor/github.com/spf13/cobra/command_test.go b/vendor/github.com/spf13/cobra/command_test.go index 3921a0be7..978bacc52 100644 --- a/vendor/github.com/spf13/cobra/command_test.go +++ b/vendor/github.com/spf13/cobra/command_test.go @@ -5,6 +5,7 @@ import ( "fmt" "os" "reflect" + "strings" "testing" "github.com/spf13/pflag" @@ -118,7 +119,7 @@ func TestStripFlags(t *testing.T) { } } -func Test_DisableFlagParsing(t *testing.T) { +func TestDisableFlagParsing(t *testing.T) { as := []string{"-v", "-race", "-file", "foo.go"} targs := []string{} cmdPrint := &Command{ @@ -145,7 +146,7 @@ func TestInitHelpFlagMergesFlags(t *testing.T) { cmd := Command{Use: "do"} baseCmd.AddCommand(&cmd) - cmd.initHelpFlag() + cmd.InitDefaultHelpFlag() actual := cmd.Flags().Lookup("help").Usage if actual != usage { t.Fatalf("Expected the help flag from the base command with usage '%s', but got the default with usage '%s'", usage, actual) @@ -226,7 +227,7 @@ func TestFlagErrorFunc(t *testing.T) { // TestSortedFlags checks, // if cmd.LocalFlags() is unsorted when cmd.Flags().SortFlags set to false. -// https://github.com/spf13/cobra/issues/404 +// Related to https://github.com/spf13/cobra/issues/404. func TestSortedFlags(t *testing.T) { cmd := &Command{} cmd.Flags().SortFlags = false @@ -240,7 +241,7 @@ func TestSortedFlags(t *testing.T) { if i == len(names) { return } - if contains(f.Name, names) { + if isStringInStringSlice(f.Name, names) { if names[i] != f.Name { t.Errorf("Incorrect order. Expected %v, got %v", names[i], f.Name) } @@ -250,7 +251,7 @@ func TestSortedFlags(t *testing.T) { } // contains checks, if s is in ss. -func contains(s string, ss []string) bool { +func isStringInStringSlice(s string, ss []string) bool { for _, v := range ss { if v == s { return true @@ -258,3 +259,42 @@ func contains(s string, ss []string) bool { } return false } + +// TestHelpFlagInHelp checks, +// if '--help' flag is shown in help for child (executing `parent help child`), +// that has no other flags. +// Related to https://github.com/spf13/cobra/issues/302. +func TestHelpFlagInHelp(t *testing.T) { + output := new(bytes.Buffer) + parent := &Command{Use: "parent", Run: func(*Command, []string) {}} + parent.SetOutput(output) + + child := &Command{Use: "child", Run: func(*Command, []string) {}} + parent.AddCommand(child) + + parent.SetArgs([]string{"help", "child"}) + err := parent.Execute() + if err != nil { + t.Fatal(err) + } + + if !strings.Contains(output.String(), "[flags]") { + t.Errorf("\nExpecting to contain: %v\nGot: %v", "[flags]", output.String()) + } +} + +// TestMergeCommandLineToFlags checks, +// if pflag.CommandLine is correctly merged to c.Flags() after first call +// of c.mergePersistentFlags. +// Related to https://github.com/spf13/cobra/issues/443. +func TestMergeCommandLineToFlags(t *testing.T) { + pflag.Bool("boolflag", false, "") + c := &Command{Use: "c", Run: func(*Command, []string) {}} + c.mergePersistentFlags() + if c.Flags().Lookup("boolflag") == nil { + t.Fatal("Expecting to have flag from CommandLine in c.Flags()") + } + + // Reset pflag.CommandLine flagset. + pflag.CommandLine = pflag.NewFlagSet(os.Args[0], pflag.ExitOnError) +} diff --git a/vendor/github.com/spf13/cobra/doc/man_docs.go b/vendor/github.com/spf13/cobra/doc/man_docs.go index 1f90c44f1..74b284d2d 100644 --- a/vendor/github.com/spf13/cobra/doc/man_docs.go +++ b/vendor/github.com/spf13/cobra/doc/man_docs.go @@ -23,7 +23,7 @@ import ( "strings" "time" - mangen "github.com/cpuguy83/go-md2man/md2man" + "github.com/cpuguy83/go-md2man/md2man" "github.com/spf13/cobra" "github.com/spf13/pflag" ) @@ -77,6 +77,8 @@ func GenManTreeFromOpts(cmd *cobra.Command, opts GenManTreeOptions) error { return GenMan(cmd, &headerCopy, f) } +// GenManTreeOptions is the options for generating the man pages. +// Used only in GenManTreeFromOpts. type GenManTreeOptions struct { Header *GenManHeader Path string @@ -105,7 +107,7 @@ func GenMan(cmd *cobra.Command, header *GenManHeader, w io.Writer) error { fillHeader(header, cmd.CommandPath()) b := genMan(cmd, header) - _, err := w.Write(mangen.Render(b)) + _, err := w.Write(md2man.Render(b)) return err } @@ -126,25 +128,25 @@ func fillHeader(header *GenManHeader, name string) { } } -func manPreamble(out io.Writer, header *GenManHeader, cmd *cobra.Command, dashedName string) { +func manPreamble(buf *bytes.Buffer, header *GenManHeader, cmd *cobra.Command, dashedName string) { description := cmd.Long if len(description) == 0 { description = cmd.Short } - fmt.Fprintf(out, `%% %s(%s)%s + buf.WriteString(fmt.Sprintf(`%% %s(%s)%s %% %s %% %s # NAME -`, header.Title, header.Section, header.date, header.Source, header.Manual) - fmt.Fprintf(out, "%s \\- %s\n\n", dashedName, cmd.Short) - fmt.Fprintf(out, "# SYNOPSIS\n") - fmt.Fprintf(out, "**%s**\n\n", cmd.UseLine()) - fmt.Fprintf(out, "# DESCRIPTION\n") - fmt.Fprintf(out, "%s\n\n", description) +`, header.Title, header.Section, header.date, header.Source, header.Manual)) + buf.WriteString(fmt.Sprintf("%s \\- %s\n\n", dashedName, cmd.Short)) + buf.WriteString("# SYNOPSIS\n") + buf.WriteString(fmt.Sprintf("**%s**\n\n", cmd.UseLine())) + buf.WriteString("# DESCRIPTION\n") + buf.WriteString(description + "\n\n") } -func manPrintFlags(out io.Writer, flags *pflag.FlagSet) { +func manPrintFlags(buf *bytes.Buffer, flags *pflag.FlagSet) { flags.VisitAll(func(flag *pflag.Flag) { if len(flag.Deprecated) > 0 || flag.Hidden { return @@ -156,34 +158,34 @@ func manPrintFlags(out io.Writer, flags *pflag.FlagSet) { format = fmt.Sprintf("**--%s**", flag.Name) } if len(flag.NoOptDefVal) > 0 { - format = format + "[" + format += "[" } if flag.Value.Type() == "string" { // put quotes on the value - format = format + "=%q" + format += "=%q" } else { - format = format + "=%s" + format += "=%s" } if len(flag.NoOptDefVal) > 0 { - format = format + "]" + format += "]" } - format = format + "\n\t%s\n\n" - fmt.Fprintf(out, format, flag.DefValue, flag.Usage) + format += "\n\t%s\n\n" + buf.WriteString(fmt.Sprintf(format, flag.DefValue, flag.Usage)) }) } -func manPrintOptions(out io.Writer, command *cobra.Command) { +func manPrintOptions(buf *bytes.Buffer, command *cobra.Command) { flags := command.NonInheritedFlags() if flags.HasFlags() { - fmt.Fprintf(out, "# OPTIONS\n") - manPrintFlags(out, flags) - fmt.Fprintf(out, "\n") + buf.WriteString("# OPTIONS\n") + manPrintFlags(buf, flags) + buf.WriteString("\n") } flags = command.InheritedFlags() if flags.HasFlags() { - fmt.Fprintf(out, "# OPTIONS INHERITED FROM PARENT COMMANDS\n") - manPrintFlags(out, flags) - fmt.Fprintf(out, "\n") + buf.WriteString("# OPTIONS INHERITED FROM PARENT COMMANDS\n") + manPrintFlags(buf, flags) + buf.WriteString("\n") } } @@ -196,11 +198,11 @@ func genMan(cmd *cobra.Command, header *GenManHeader) []byte { manPreamble(buf, header, cmd, dashCommandName) manPrintOptions(buf, cmd) if len(cmd.Example) > 0 { - fmt.Fprintf(buf, "# EXAMPLE\n") - fmt.Fprintf(buf, "```\n%s\n```\n", cmd.Example) + buf.WriteString("# EXAMPLE\n") + buf.WriteString(fmt.Sprintf("```\n%s\n```\n", cmd.Example)) } if hasSeeAlso(cmd) { - fmt.Fprintf(buf, "# SEE ALSO\n") + buf.WriteString("# SEE ALSO\n") seealsos := make([]string, 0) if cmd.HasParent() { parentPath := cmd.Parent().CommandPath() @@ -222,10 +224,10 @@ func genMan(cmd *cobra.Command, header *GenManHeader) []byte { seealso := fmt.Sprintf("**%s-%s(%s)**", dashCommandName, c.Name(), header.Section) seealsos = append(seealsos, seealso) } - fmt.Fprintf(buf, "%s\n", strings.Join(seealsos, ", ")) + buf.WriteString(strings.Join(seealsos, ", ") + "\n") } if !cmd.DisableAutoGenTag { - fmt.Fprintf(buf, "# HISTORY\n%s Auto generated by spf13/cobra\n", header.Date.Format("2-Jan-2006")) + buf.WriteString(fmt.Sprintf("# HISTORY\n%s Auto generated by spf13/cobra\n", header.Date.Format("2-Jan-2006"))) } return buf.Bytes() } diff --git a/vendor/github.com/spf13/cobra/doc/man_docs_test.go b/vendor/github.com/spf13/cobra/doc/man_docs_test.go index 9b272917d..87991063e 100644 --- a/vendor/github.com/spf13/cobra/doc/man_docs_test.go +++ b/vendor/github.com/spf13/cobra/doc/man_docs_test.go @@ -197,3 +197,20 @@ func AssertNextLineEquals(scanner *bufio.Scanner, expectedLine string) error { return fmt.Errorf("AssertNextLineEquals: hit EOF before finding %#v", expectedLine) } + +func BenchmarkGenManToFile(b *testing.B) { + c := initializeWithRootCmd() + file, err := ioutil.TempFile("", "") + if err != nil { + b.Fatal(err) + } + defer os.Remove(file.Name()) + defer file.Close() + + b.ResetTimer() + for i := 0; i < b.N; i++ { + if err := GenMan(c, nil, file); err != nil { + b.Fatal(err) + } + } +} diff --git a/vendor/github.com/spf13/cobra/doc/md_docs.go b/vendor/github.com/spf13/cobra/doc/md_docs.go index 408d2f74b..9bbfa36ff 100644 --- a/vendor/github.com/spf13/cobra/doc/md_docs.go +++ b/vendor/github.com/spf13/cobra/doc/md_docs.go @@ -14,6 +14,7 @@ package doc import ( + "bytes" "fmt" "io" "os" @@ -25,29 +26,21 @@ import ( "github.com/spf13/cobra" ) -func printOptions(w io.Writer, cmd *cobra.Command, name string) error { +func printOptions(buf *bytes.Buffer, cmd *cobra.Command, name string) error { flags := cmd.NonInheritedFlags() - flags.SetOutput(w) + flags.SetOutput(buf) if flags.HasFlags() { - if _, err := fmt.Fprintf(w, "### Options\n\n```\n"); err != nil { - return err - } + buf.WriteString("### Options\n\n```\n") flags.PrintDefaults() - if _, err := fmt.Fprintf(w, "```\n\n"); err != nil { - return err - } + buf.WriteString("```\n\n") } parentFlags := cmd.InheritedFlags() - parentFlags.SetOutput(w) + parentFlags.SetOutput(buf) if parentFlags.HasFlags() { - if _, err := fmt.Fprintf(w, "### Options inherited from parent commands\n\n```\n"); err != nil { - return err - } + buf.WriteString("### Options inherited from parent commands\n\n```\n") parentFlags.PrintDefaults() - if _, err := fmt.Fprintf(w, "```\n\n"); err != nil { - return err - } + buf.WriteString("```\n\n") } return nil } @@ -59,6 +52,7 @@ func GenMarkdown(cmd *cobra.Command, w io.Writer) error { // GenMarkdownCustom creates custom markdown output. func GenMarkdownCustom(cmd *cobra.Command, w io.Writer, linkHandler func(string) string) error { + buf := new(bytes.Buffer) name := cmd.CommandPath() short := cmd.Short @@ -67,49 +61,31 @@ func GenMarkdownCustom(cmd *cobra.Command, w io.Writer, linkHandler func(string) 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 - } + buf.WriteString("## " + name + "\n\n") + buf.WriteString(short + "\n\n") + buf.WriteString("### Synopsis\n\n") + buf.WriteString("\n" + long + "\n\n") if cmd.Runnable() { - if _, err := fmt.Fprintf(w, "```\n%s\n```\n\n", cmd.UseLine()); err != nil { - return err - } + buf.WriteString(fmt.Sprintf("```\n%s\n```\n\n", cmd.UseLine())) } 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 - } + buf.WriteString("### Examples\n\n") + buf.WriteString(fmt.Sprintf("```\n%s\n```\n\n", cmd.Example)) } - if err := printOptions(w, cmd, name); err != nil { + if err := printOptions(buf, cmd, name); err != nil { return err } if hasSeeAlso(cmd) { - if _, err := fmt.Fprintf(w, "### SEE ALSO\n"); err != nil { - return err - } + buf.WriteString("### SEE ALSO\n") 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 - } + buf.WriteString(fmt.Sprintf("* [%s](%s)\t - %s\n", pname, linkHandler(link), parent.Short)) cmd.VisitParents(func(c *cobra.Command) { if c.DisableAutoGenTag { cmd.DisableAutoGenTag = c.DisableAutoGenTag @@ -127,20 +103,15 @@ func GenMarkdownCustom(cmd *cobra.Command, w io.Writer, linkHandler func(string) 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 + buf.WriteString(fmt.Sprintf("* [%s](%s)\t - %s\n", cname, linkHandler(link), child.Short)) } + buf.WriteString("\n") } 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 - } + buf.WriteString("###### Auto generated by spf13/cobra on " + time.Now().Format("2-Jan-2006") + "\n") } - return nil + _, err := buf.WriteTo(w) + return err } // GenMarkdownTree will generate a markdown page for this command and all @@ -155,6 +126,8 @@ func GenMarkdownTree(cmd *cobra.Command, dir string) error { return GenMarkdownTreeCustom(cmd, dir, emptyStr, identity) } +// GenMarkdownTreeCustom is the the same as GenMarkdownTree, but +// with custom filePrepender and linkHandler. func GenMarkdownTreeCustom(cmd *cobra.Command, dir string, filePrepender, linkHandler func(string) string) error { for _, c := range cmd.Commands() { if !c.IsAvailableCommand() || c.IsAdditionalHelpTopicCommand() { diff --git a/vendor/github.com/spf13/cobra/doc/md_docs_test.go b/vendor/github.com/spf13/cobra/doc/md_docs_test.go index f4f3bc149..ba6b9a46e 100644 --- a/vendor/github.com/spf13/cobra/doc/md_docs_test.go +++ b/vendor/github.com/spf13/cobra/doc/md_docs_test.go @@ -105,3 +105,20 @@ func TestGenMdTree(t *testing.T) { t.Fatalf("Expected file 'do.md' to exist") } } + +func BenchmarkGenMarkdownToFile(b *testing.B) { + c := initializeWithRootCmd() + file, err := ioutil.TempFile("", "") + if err != nil { + b.Fatal(err) + } + defer os.Remove(file.Name()) + defer file.Close() + + b.ResetTimer() + for i := 0; i < b.N; i++ { + if err := GenMarkdown(c, file); err != nil { + b.Fatal(err) + } + } +} diff --git a/vendor/github.com/spf13/cobra/doc/yaml_docs.go b/vendor/github.com/spf13/cobra/doc/yaml_docs.go index f5cd5a329..54c244d45 100644 --- a/vendor/github.com/spf13/cobra/doc/yaml_docs.go +++ b/vendor/github.com/spf13/cobra/doc/yaml_docs.go @@ -130,7 +130,8 @@ func GenYamlCustom(cmd *cobra.Command, w io.Writer, linkHandler func(string) str fmt.Println(err) os.Exit(1) } - if _, err := fmt.Fprintf(w, string(final)); err != nil { + + if _, err := w.Write(final); err != nil { return err } return nil diff --git a/vendor/github.com/spf13/cobra/doc/yaml_docs_test.go b/vendor/github.com/spf13/cobra/doc/yaml_docs_test.go index fb969da22..29e985e40 100644 --- a/vendor/github.com/spf13/cobra/doc/yaml_docs_test.go +++ b/vendor/github.com/spf13/cobra/doc/yaml_docs_test.go @@ -106,3 +106,20 @@ func TestGenYamlTree(t *testing.T) { t.Fatalf("Expected file 'do.yaml' to exist") } } + +func BenchmarkGenYamlToFile(b *testing.B) { + c := initializeWithRootCmd() + file, err := ioutil.TempFile("", "") + if err != nil { + b.Fatal(err) + } + defer os.Remove(file.Name()) + defer file.Close() + + b.ResetTimer() + for i := 0; i < b.N; i++ { + if err := GenYaml(c, file); err != nil { + b.Fatal(err) + } + } +} |