From 96eab1202717e073782ec399a4e0820cae15b1bb Mon Sep 17 00:00:00 2001 From: Christopher Speller Date: Thu, 17 Aug 2017 17:19:06 -0700 Subject: Updating server dependancies. (#7246) --- vendor/github.com/spf13/cobra/.travis.yml | 4 +- vendor/github.com/spf13/cobra/README.md | 30 ++++++ vendor/github.com/spf13/cobra/args.go | 98 ++++++++++++++++++ .../spf13/cobra/bash_completions_test.go | 2 + vendor/github.com/spf13/cobra/cobra/cmd/add.go | 4 +- .../github.com/spf13/cobra/cobra/cmd/add_test.go | 15 ++- .../spf13/cobra/cobra/cmd/golden_test.go | 4 +- .../github.com/spf13/cobra/cobra/cmd/init_test.go | 11 +- .../spf13/cobra/cobra/cmd/license_agpl.go | 3 +- .../spf13/cobra/cobra/cmd/license_apache_2.go | 3 +- .../spf13/cobra/cobra/cmd/license_bsd_clause_2.go | 3 +- .../spf13/cobra/cobra/cmd/license_bsd_clause_3.go | 3 +- .../spf13/cobra/cobra/cmd/license_gpl_2.go | 27 +++-- .../spf13/cobra/cobra/cmd/license_gpl_3.go | 3 +- .../spf13/cobra/cobra/cmd/license_lgpl.go | 3 +- .../spf13/cobra/cobra/cmd/license_mit.go | 2 +- .../github.com/spf13/cobra/cobra/cmd/licenses.go | 6 +- vendor/github.com/spf13/cobra/cobra/cmd/root.go | 4 +- .../spf13/cobra/cobra/cmd/testdata/main.go.golden | 1 + .../spf13/cobra/cobra/cmd/testdata/root.go.golden | 1 + .../spf13/cobra/cobra/cmd/testdata/test.go.golden | 1 + vendor/github.com/spf13/cobra/cobra_test.go | 77 +++++++++++++- vendor/github.com/spf13/cobra/command.go | 51 +++++---- vendor/github.com/spf13/cobra/zsh_completions.go | 114 +++++++++++++++++++++ .../github.com/spf13/cobra/zsh_completions_test.go | 88 ++++++++++++++++ vendor/github.com/spf13/viper/.travis.yml | 1 + vendor/github.com/spf13/viper/README.md | 46 ++++++--- vendor/github.com/spf13/viper/flags_test.go | 1 - vendor/github.com/spf13/viper/remote/remote.go | 17 ++- vendor/github.com/spf13/viper/util_test.go | 1 - vendor/github.com/spf13/viper/viper.go | 24 ++--- 31 files changed, 548 insertions(+), 100 deletions(-) create mode 100644 vendor/github.com/spf13/cobra/args.go create mode 100644 vendor/github.com/spf13/cobra/zsh_completions.go create mode 100644 vendor/github.com/spf13/cobra/zsh_completions_test.go (limited to 'vendor/github.com/spf13') diff --git a/vendor/github.com/spf13/cobra/.travis.yml b/vendor/github.com/spf13/cobra/.travis.yml index cb2bf0d5c..68efa1363 100644 --- a/vendor/github.com/spf13/cobra/.travis.yml +++ b/vendor/github.com/spf13/cobra/.travis.yml @@ -2,8 +2,8 @@ language: go matrix: include: - - go: 1.7.5 - - go: 1.8.1 + - go: 1.7.6 + - go: 1.8.3 - 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 e249c1bcb..a38137b25 100644 --- a/vendor/github.com/spf13/cobra/README.md +++ b/vendor/github.com/spf13/cobra/README.md @@ -485,6 +485,36 @@ when the `--author` flag is not provided by user. More in [viper documentation](https://github.com/spf13/viper#working-with-flags). +## Positional and Custom Arguments + +Validation of positional arguments can be specified using the `Args` field. + +The follow validators are built in: + +- `NoArgs` - the command will report an error if there are any positional args. +- `ArbitraryArgs` - the command will accept any args. +- `OnlyValidArgs` - the command will report an error if there are any positional args that are not in the ValidArgs list. +- `MinimumNArgs(int)` - the command will report an error if there are not at least N positional args. +- `MaximumNArgs(int)` - the command will report an error if there are more than N positional args. +- `ExactArgs(int)` - the command will report an error if there are not exactly N positional args. +- `RangeArgs(min, max)` - the command will report an error if the number of args is not between the minimum and maximum number of expected args. + +A custom validator can be provided like this: + +```go + +Args: func validColorArgs(cmd *cobra.Command, args []string) error { + if err := cli.RequiresMinArgs(1)(cmd, args); err != nil { + return err + } + if myapp.IsValidColor(args[0]) { + return nil + } + return fmt.Errorf("Invalid color specified: %s", args[0]) +} + +``` + ## Example In the example below, we have defined three commands. Two are at the top level diff --git a/vendor/github.com/spf13/cobra/args.go b/vendor/github.com/spf13/cobra/args.go new file mode 100644 index 000000000..94a6ca273 --- /dev/null +++ b/vendor/github.com/spf13/cobra/args.go @@ -0,0 +1,98 @@ +package cobra + +import ( + "fmt" +) + +type PositionalArgs func(cmd *Command, args []string) error + +// Legacy arg validation has the following behaviour: +// - root commands with no subcommands can take arbitrary arguments +// - root commands with subcommands will do subcommand validity checking +// - subcommands will always accept arbitrary arguments +func legacyArgs(cmd *Command, args []string) error { + // no subcommand, always take args + if !cmd.HasSubCommands() { + return nil + } + + // root command with subcommands, do subcommand checking + if !cmd.HasParent() && len(args) > 0 { + return fmt.Errorf("unknown command %q for %q%s", args[0], cmd.CommandPath(), cmd.findSuggestions(args[0])) + } + return nil +} + +// NoArgs returns an error if any args are included +func NoArgs(cmd *Command, args []string) error { + if len(args) > 0 { + return fmt.Errorf("unknown command %q for %q", args[0], cmd.CommandPath()) + } + return nil +} + +// OnlyValidArgs returns an error if any args are not in the list of ValidArgs +func OnlyValidArgs(cmd *Command, args []string) error { + if len(cmd.ValidArgs) > 0 { + for _, v := range args { + if !stringInSlice(v, cmd.ValidArgs) { + return fmt.Errorf("invalid argument %q for %q%s", v, cmd.CommandPath(), cmd.findSuggestions(args[0])) + } + } + } + return nil +} + +func stringInSlice(a string, list []string) bool { + for _, b := range list { + if b == a { + return true + } + } + return false +} + +// ArbitraryArgs never returns an error +func ArbitraryArgs(cmd *Command, args []string) error { + return nil +} + +// MinimumNArgs returns an error if there is not at least N args +func MinimumNArgs(n int) PositionalArgs { + return func(cmd *Command, args []string) error { + if len(args) < n { + return fmt.Errorf("requires at least %d arg(s), only received %d", n, len(args)) + } + return nil + } +} + +// MaximumNArgs returns an error if there are more than N args +func MaximumNArgs(n int) PositionalArgs { + return func(cmd *Command, args []string) error { + if len(args) > n { + return fmt.Errorf("accepts at most %d arg(s), received %d", n, len(args)) + } + return nil + } +} + +// ExactArgs returns an error if there are not exactly n args +func ExactArgs(n int) PositionalArgs { + return func(cmd *Command, args []string) error { + if len(args) != n { + return fmt.Errorf("accepts %d arg(s), received %d", n, len(args)) + } + return nil + } +} + +// RangeArgs returns an error if the number of args is not within the expected range +func RangeArgs(min int, max int) PositionalArgs { + return func(cmd *Command, args []string) error { + if len(args) < min || len(args) > max { + return fmt.Errorf("accepts between %d and %d arg(s), received %d", min, max, len(args)) + } + return nil + } +} diff --git a/vendor/github.com/spf13/cobra/bash_completions_test.go b/vendor/github.com/spf13/cobra/bash_completions_test.go index 7511376ae..071a6a2a2 100644 --- a/vendor/github.com/spf13/cobra/bash_completions_test.go +++ b/vendor/github.com/spf13/cobra/bash_completions_test.go @@ -117,6 +117,8 @@ func TestBashCompletions(t *testing.T) { // check for filename extension flags check(t, str, `flags_completion+=("_filedir")`) // check for filename extension flags + check(t, str, `must_have_one_noun+=("three")`) + // check for filename extention flags check(t, str, `flags_completion+=("__handle_filename_extension_flag json|yaml|yml")`) // check for custom flags check(t, str, `flags_completion+=("__complete_custom")`) diff --git a/vendor/github.com/spf13/cobra/cobra/cmd/add.go b/vendor/github.com/spf13/cobra/cobra/cmd/add.go index 45f00bb54..993ae16f0 100644 --- a/vendor/github.com/spf13/cobra/cobra/cmd/add.go +++ b/vendor/github.com/spf13/cobra/cobra/cmd/add.go @@ -24,7 +24,7 @@ import ( func init() { addCmd.Flags().StringVarP(&packageName, "package", "t", "", "target package name (e.g. github.com/spf13/hugo)") - addCmd.Flags().StringVarP(&parentName, "parent", "p", "RootCmd", "name of parent command for this command") + addCmd.Flags().StringVarP(&parentName, "parent", "p", "RootCmd", "variable name of parent command for this command") } var packageName, parentName string @@ -121,7 +121,7 @@ func validateCmdName(source string) string { func createCmdFile(license License, path, cmdName string) { template := `{{comment .copyright}} -{{comment .license}} +{{if .license}}{{comment .license}}{{end}} package {{.cmdPackage}} diff --git a/vendor/github.com/spf13/cobra/cobra/cmd/add_test.go b/vendor/github.com/spf13/cobra/cobra/cmd/add_test.go index dacbe838a..b920e2b9d 100644 --- a/vendor/github.com/spf13/cobra/cobra/cmd/add_test.go +++ b/vendor/github.com/spf13/cobra/cobra/cmd/add_test.go @@ -6,6 +6,8 @@ import ( "os" "path/filepath" "testing" + + "github.com/spf13/viper" ) // TestGoldenAddCmd initializes the project "github.com/spf13/testproject" @@ -16,10 +18,17 @@ import ( func TestGoldenAddCmd(t *testing.T) { projectName := "github.com/spf13/testproject" project := NewProject(projectName) + defer os.RemoveAll(project.AbsPath()) - // Initialize the project at first. + viper.Set("author", "NAME HERE ") + viper.Set("license", "apache") + viper.Set("year", 2017) + defer viper.Set("author", nil) + defer viper.Set("license", nil) + defer viper.Set("year", nil) + + // Initialize the project first. initializeProject(project) - defer os.RemoveAll(project.AbsPath()) // Then add the "test" command. cmdName := "test" @@ -48,7 +57,7 @@ func TestGoldenAddCmd(t *testing.T) { goldenPath := filepath.Join("testdata", filepath.Base(path)+".golden") switch relPath { - // Know directories. + // Known directories. case ".": return nil // Known files. diff --git a/vendor/github.com/spf13/cobra/cobra/cmd/golden_test.go b/vendor/github.com/spf13/cobra/cobra/cmd/golden_test.go index 0ac7e8935..59a5a1c9f 100644 --- a/vendor/github.com/spf13/cobra/cobra/cmd/golden_test.go +++ b/vendor/github.com/spf13/cobra/cobra/cmd/golden_test.go @@ -39,11 +39,11 @@ func compareFiles(pathA, pathB string) error { // Don't execute diff if it can't be found. return nil } - diffCmd := exec.Command(diffPath, pathA, pathB) + diffCmd := exec.Command(diffPath, "-u", pathA, pathB) diffCmd.Stdout = output diffCmd.Stderr = output - output.WriteString("$ diff " + pathA + " " + pathB + "\n") + output.WriteString("$ diff -u " + pathA + " " + pathB + "\n") if err := diffCmd.Run(); err != nil { output.WriteString("\n" + err.Error()) } diff --git a/vendor/github.com/spf13/cobra/cobra/cmd/init_test.go b/vendor/github.com/spf13/cobra/cobra/cmd/init_test.go index 9a918b9b4..40eb4038e 100644 --- a/vendor/github.com/spf13/cobra/cobra/cmd/init_test.go +++ b/vendor/github.com/spf13/cobra/cobra/cmd/init_test.go @@ -6,6 +6,8 @@ import ( "os" "path/filepath" "testing" + + "github.com/spf13/viper" ) // TestGoldenInitCmd initializes the project "github.com/spf13/testproject" @@ -17,6 +19,13 @@ func TestGoldenInitCmd(t *testing.T) { project := NewProject(projectName) defer os.RemoveAll(project.AbsPath()) + viper.Set("author", "NAME HERE ") + viper.Set("license", "apache") + viper.Set("year", 2017) + defer viper.Set("author", nil) + defer viper.Set("license", nil) + defer viper.Set("year", nil) + os.Args = []string{"cobra", "init", projectName} if err := rootCmd.Execute(); err != nil { t.Fatal("Error by execution:", err) @@ -44,7 +53,7 @@ func TestGoldenInitCmd(t *testing.T) { goldenPath := filepath.Join("testdata", filepath.Base(path)+".golden") switch relPath { - // Know directories. + // Known directories. case ".", "cmd": return nil // Known files. diff --git a/vendor/github.com/spf13/cobra/cobra/cmd/license_agpl.go b/vendor/github.com/spf13/cobra/cobra/cmd/license_agpl.go index 4ea036ede..bc22e9732 100644 --- a/vendor/github.com/spf13/cobra/cobra/cmd/license_agpl.go +++ b/vendor/github.com/spf13/cobra/cobra/cmd/license_agpl.go @@ -4,8 +4,7 @@ func initAgpl() { Licenses["agpl"] = License{ Name: "GNU Affero General Public License", PossibleMatches: []string{"agpl", "affero gpl", "gnu agpl"}, - Header: `{{.copyright}} - + Header: ` 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 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 3f330867d..38393d541 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,7 +19,8 @@ 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"); + 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 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 f2982dab3..4a847e04a 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 @@ -20,8 +20,7 @@ func initBsdClause2() { Name: "Simplified BSD License", PossibleMatches: []string{"freebsd", "simpbsd", "simple bsd", "2-clause bsd", "2 clause bsd", "simplified bsd license"}, - Header: ` -All rights reserved. + Header: `All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 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 39c9571f2..c7476b31f 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 @@ -19,8 +19,7 @@ func initBsdClause3() { Licenses["bsd"] = License{ Name: "NewBSD", PossibleMatches: []string{"bsd", "newbsd", "3 clause bsd", "3-clause bsd"}, - Header: ` -All rights reserved. + Header: `All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 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 054b470f1..03e05b3a7 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 @@ -19,20 +19,19 @@ func initGpl2() { Licenses["gpl2"] = License{ Name: "GNU General Public License 2.0", PossibleMatches: []string{"gpl2", "gnu gpl2", "gplv2"}, - Header: `{{.copyright}} - - 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 Lesser General Public License - along with this program. If not, see .`, + Header: ` +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 Lesser General Public License +along with this program. If not, see .`, Text: ` GNU GENERAL PUBLIC LICENSE Version 2, June 1991 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 d1ef656a7..ce07679c7 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 @@ -19,8 +19,7 @@ func initGpl3() { Licenses["gpl3"] = License{ Name: "GNU General Public License 3.0", PossibleMatches: []string{"gpl3", "gplv3", "gpl", "gnu gpl3", "gnu gpl"}, - Header: `{{.copyright}} - + Header: ` 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 diff --git a/vendor/github.com/spf13/cobra/cobra/cmd/license_lgpl.go b/vendor/github.com/spf13/cobra/cobra/cmd/license_lgpl.go index 75fd043b8..0f8b96cad 100644 --- a/vendor/github.com/spf13/cobra/cobra/cmd/license_lgpl.go +++ b/vendor/github.com/spf13/cobra/cobra/cmd/license_lgpl.go @@ -4,8 +4,7 @@ func initLgpl() { Licenses["lgpl"] = License{ Name: "GNU Lesser General Public License", PossibleMatches: []string{"lgpl", "lesser gpl", "gnu lgpl"}, - Header: `{{.copyright}} - + Header: ` 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 diff --git a/vendor/github.com/spf13/cobra/cobra/cmd/license_mit.go b/vendor/github.com/spf13/cobra/cobra/cmd/license_mit.go index 4ff5a4cdf..bd2d0c4fa 100644 --- a/vendor/github.com/spf13/cobra/cobra/cmd/license_mit.go +++ b/vendor/github.com/spf13/cobra/cobra/cmd/license_mit.go @@ -17,7 +17,7 @@ package cmd func initMit() { Licenses["mit"] = License{ - Name: "Mit", + Name: "MIT License", PossibleMatches: []string{"mit"}, Header: ` Permission is hereby granted, free of charge, to any person obtaining a copy diff --git a/vendor/github.com/spf13/cobra/cobra/cmd/licenses.go b/vendor/github.com/spf13/cobra/cobra/cmd/licenses.go index d73e6fb35..cf2a6b7af 100644 --- a/vendor/github.com/spf13/cobra/cobra/cmd/licenses.go +++ b/vendor/github.com/spf13/cobra/cobra/cmd/licenses.go @@ -77,7 +77,11 @@ func getLicense() License { func copyrightLine() string { author := viper.GetString("author") - year := time.Now().Format("2006") + + year := viper.GetString("year") // For tests. + if year == "" { + year = time.Now().Format("2006") + } return "Copyright © " + year + " " + author } diff --git a/vendor/github.com/spf13/cobra/cobra/cmd/root.go b/vendor/github.com/spf13/cobra/cobra/cmd/root.go index 1c5e69078..19568f980 100644 --- a/vendor/github.com/spf13/cobra/cobra/cmd/root.go +++ b/vendor/github.com/spf13/cobra/cobra/cmd/root.go @@ -40,7 +40,7 @@ func Execute() { } func init() { - initViper() + cobra.OnInitialize(initConfig) rootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file (default is $HOME/.cobra.yaml)") rootCmd.PersistentFlags().StringP("author", "a", "YOUR NAME", "author name for copyright attribution") @@ -55,7 +55,7 @@ func init() { rootCmd.AddCommand(initCmd) } -func initViper() { +func initConfig() { if cfgFile != "" { // Use config file from the flag. viper.SetConfigFile(cfgFile) 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 index 69ecbd48e..cdbe38d70 100644 --- a/vendor/github.com/spf13/cobra/cobra/cmd/testdata/main.go.golden +++ b/vendor/github.com/spf13/cobra/cobra/cmd/testdata/main.go.golden @@ -1,4 +1,5 @@ // Copyright © 2017 NAME HERE +// // 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 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 index ecc876012..8eeeae89e 100644 --- a/vendor/github.com/spf13/cobra/cobra/cmd/testdata/root.go.golden +++ b/vendor/github.com/spf13/cobra/cobra/cmd/testdata/root.go.golden @@ -1,4 +1,5 @@ // Copyright © 2017 NAME HERE +// // 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 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 index c8319d1dd..584056802 100644 --- a/vendor/github.com/spf13/cobra/cobra/cmd/testdata/test.go.golden +++ b/vendor/github.com/spf13/cobra/cobra/cmd/testdata/test.go.golden @@ -1,4 +1,5 @@ // Copyright © 2017 NAME HERE +// // 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 diff --git a/vendor/github.com/spf13/cobra/cobra_test.go b/vendor/github.com/spf13/cobra/cobra_test.go index 576c97d36..d5df951e6 100644 --- a/vendor/github.com/spf13/cobra/cobra_test.go +++ b/vendor/github.com/spf13/cobra/cobra_test.go @@ -36,6 +36,7 @@ var cmdHidden = &Command{ var cmdPrint = &Command{ Use: "print [string to print]", + Args: MinimumNArgs(1), Short: "Print anything to the screen", Long: `an absolutely utterly useless command for testing.`, Run: func(cmd *Command, args []string) { @@ -75,6 +76,7 @@ var cmdDeprecated = &Command{ Deprecated: "Please use echo instead", Run: func(cmd *Command, args []string) { }, + Args: NoArgs, } var cmdTimes = &Command{ @@ -88,6 +90,8 @@ var cmdTimes = &Command{ Run: func(cmd *Command, args []string) { tt = args }, + Args: OnlyValidArgs, + ValidArgs: []string{"one", "two", "three", "four"}, } var cmdRootNoRun = &Command{ @@ -105,6 +109,16 @@ var cmdRootSameName = &Command{ Long: "The root description for help", } +var cmdRootTakesArgs = &Command{ + Use: "root-with-args [random args]", + Short: "The root can run it's own function and takes args!", + Long: "The root description for help, and some args", + Run: func(cmd *Command, args []string) { + tr = args + }, + Args: ArbitraryArgs, +} + var cmdRootWithRun = &Command{ Use: "cobra-test", Short: "The root can run its own function", @@ -458,6 +472,63 @@ func TestUsage(t *testing.T) { checkResultOmits(t, x, cmdCustomFlags.Use+" [flags]") } +func TestRootTakesNoArgs(t *testing.T) { + c := initializeWithSameName() + c.AddCommand(cmdPrint, cmdEcho) + result := simpleTester(c, "illegal") + + if result.Error == nil { + t.Fatal("Expected an error") + } + + expectedError := `unknown command "illegal" for "print"` + if !strings.Contains(result.Error.Error(), expectedError) { + t.Errorf("exptected %v, got %v", expectedError, result.Error.Error()) + } +} + +func TestRootTakesArgs(t *testing.T) { + c := cmdRootTakesArgs + result := simpleTester(c, "legal") + + if result.Error != nil { + t.Errorf("expected no error, but got %v", result.Error) + } +} + +func TestSubCmdTakesNoArgs(t *testing.T) { + result := fullSetupTest("deprecated", "illegal") + + if result.Error == nil { + t.Fatal("Expected an error") + } + + expectedError := `unknown command "illegal" for "cobra-test deprecated"` + if !strings.Contains(result.Error.Error(), expectedError) { + t.Errorf("expected %v, got %v", expectedError, result.Error.Error()) + } +} + +func TestSubCmdTakesArgs(t *testing.T) { + noRRSetupTest("echo", "times", "one", "two") + if strings.Join(tt, " ") != "one two" { + t.Error("Command didn't parse correctly") + } +} + +func TestCmdOnlyValidArgs(t *testing.T) { + result := noRRSetupTest("echo", "times", "one", "two", "five") + + if result.Error == nil { + t.Fatal("Expected an error") + } + + expectedError := `invalid argument "five"` + if !strings.Contains(result.Error.Error(), expectedError) { + t.Errorf("expected %v, got %v", expectedError, result.Error.Error()) + } +} + func TestFlagLong(t *testing.T) { noRRSetupTest("echo", "--intone=13", "something", "--", "here") @@ -672,9 +743,9 @@ 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", "one", "two") - if strings.Join(tt, " ") != "test here" { + if strings.Join(tt, " ") != "one two" { t.Errorf("flags didn't leave proper args remaining. %s given", tt) } @@ -1095,7 +1166,7 @@ func TestGlobalNormFuncPropagation(t *testing.T) { rootCmd := initialize() rootCmd.SetGlobalNormalizationFunc(normFunc) - if reflect.ValueOf(normFunc) != reflect.ValueOf(rootCmd.GlobalNormalizationFunc()) { + if reflect.ValueOf(normFunc).Pointer() != reflect.ValueOf(rootCmd.GlobalNormalizationFunc()).Pointer() { t.Error("rootCmd seems to have a wrong normalization function") } diff --git a/vendor/github.com/spf13/cobra/command.go b/vendor/github.com/spf13/cobra/command.go index c3e16b1d1..4f65d7708 100644 --- a/vendor/github.com/spf13/cobra/command.go +++ b/vendor/github.com/spf13/cobra/command.go @@ -59,6 +59,8 @@ type Command struct { // but accepted if entered manually. ArgAliases []string + // Expected arguments + Args PositionalArgs // BashCompletionFunction is custom functions used by the bash autocompletion generator. BashCompletionFunction string @@ -513,31 +515,27 @@ func (c *Command) Find(args []string) (*Command, []string, error) { } commandFound, a := innerfind(c, args) - argsWOflags := stripFlags(a, commandFound) - - // no subcommand, always take args - if !commandFound.HasSubCommands() { - return commandFound, a, nil + if commandFound.Args == nil { + return commandFound, a, legacyArgs(commandFound, stripFlags(a, commandFound)) } + return commandFound, a, nil +} - // root command with subcommands, do subcommand checking - if commandFound == c && len(argsWOflags) > 0 { - suggestionsString := "" - if !c.DisableSuggestions { - if c.SuggestionsMinimumDistance <= 0 { - c.SuggestionsMinimumDistance = 2 - } - if suggestions := c.SuggestionsFor(argsWOflags[0]); len(suggestions) > 0 { - suggestionsString += "\n\nDid you mean this?\n" - for _, s := range suggestions { - suggestionsString += fmt.Sprintf("\t%v\n", s) - } - } +func (c *Command) findSuggestions(arg string) string { + if c.DisableSuggestions { + return "" + } + if c.SuggestionsMinimumDistance <= 0 { + c.SuggestionsMinimumDistance = 2 + } + suggestionsString := "" + if suggestions := c.SuggestionsFor(arg); len(suggestions) > 0 { + suggestionsString += "\n\nDid you mean this?\n" + for _, s := range suggestions { + suggestionsString += fmt.Sprintf("\t%v\n", s) } - return commandFound, a, fmt.Errorf("unknown command %q for %q%s", argsWOflags[0], commandFound.CommandPath(), suggestionsString) } - - return commandFound, a, nil + return suggestionsString } // SuggestionsFor provides suggestions for the typedName. @@ -624,6 +622,10 @@ func (c *Command) execute(a []string) (err error) { argWoFlags = a } + if err := c.ValidateArgs(argWoFlags); err != nil { + return err + } + for p := c; p != nil; p = p.Parent() { if p.PersistentPreRunE != nil { if err := p.PersistentPreRunE(c, argWoFlags); err != nil { @@ -747,6 +749,13 @@ func (c *Command) ExecuteC() (cmd *Command, err error) { return cmd, err } +func (c *Command) ValidateArgs(args []string) error { + if c.Args == nil { + return nil + } + return c.Args(c, args) +} + // 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. diff --git a/vendor/github.com/spf13/cobra/zsh_completions.go b/vendor/github.com/spf13/cobra/zsh_completions.go new file mode 100644 index 000000000..b350aeeca --- /dev/null +++ b/vendor/github.com/spf13/cobra/zsh_completions.go @@ -0,0 +1,114 @@ +package cobra + +import ( + "bytes" + "fmt" + "io" + "strings" +) + +// GenZshCompletion generates a zsh completion file and writes to the passed writer. +func (cmd *Command) GenZshCompletion(w io.Writer) error { + buf := new(bytes.Buffer) + + writeHeader(buf, cmd) + maxDepth := maxDepth(cmd) + writeLevelMapping(buf, maxDepth) + writeLevelCases(buf, maxDepth, cmd) + + _, err := buf.WriteTo(w) + return err +} + +func writeHeader(w io.Writer, cmd *Command) { + fmt.Fprintf(w, "#compdef %s\n\n", cmd.Name()) +} + +func maxDepth(c *Command) int { + if len(c.Commands()) == 0 { + return 0 + } + maxDepthSub := 0 + for _, s := range c.Commands() { + subDepth := maxDepth(s) + if subDepth > maxDepthSub { + maxDepthSub = subDepth + } + } + return 1 + maxDepthSub +} + +func writeLevelMapping(w io.Writer, numLevels int) { + fmt.Fprintln(w, `_arguments \`) + for i := 1; i <= numLevels; i++ { + fmt.Fprintf(w, ` '%d: :->level%d' \`, i, i) + fmt.Fprintln(w) + } + fmt.Fprintf(w, ` '%d: :%s'`, numLevels+1, "_files") + fmt.Fprintln(w) +} + +func writeLevelCases(w io.Writer, maxDepth int, root *Command) { + fmt.Fprintln(w, "case $state in") + defer fmt.Fprintln(w, "esac") + + for i := 1; i <= maxDepth; i++ { + fmt.Fprintf(w, " level%d)\n", i) + writeLevel(w, root, i) + fmt.Fprintln(w, " ;;") + } + fmt.Fprintln(w, " *)") + fmt.Fprintln(w, " _arguments '*: :_files'") + fmt.Fprintln(w, " ;;") +} + +func writeLevel(w io.Writer, root *Command, i int) { + fmt.Fprintf(w, " case $words[%d] in\n", i) + defer fmt.Fprintln(w, " esac") + + commands := filterByLevel(root, i) + byParent := groupByParent(commands) + + for p, c := range byParent { + names := names(c) + fmt.Fprintf(w, " %s)\n", p) + fmt.Fprintf(w, " _arguments '%d: :(%s)'\n", i, strings.Join(names, " ")) + fmt.Fprintln(w, " ;;") + } + fmt.Fprintln(w, " *)") + fmt.Fprintln(w, " _arguments '*: :_files'") + fmt.Fprintln(w, " ;;") + +} + +func filterByLevel(c *Command, l int) []*Command { + cs := make([]*Command, 0) + if l == 0 { + cs = append(cs, c) + return cs + } + for _, s := range c.Commands() { + cs = append(cs, filterByLevel(s, l-1)...) + } + return cs +} + +func groupByParent(commands []*Command) map[string][]*Command { + m := make(map[string][]*Command) + for _, c := range commands { + parent := c.Parent() + if parent == nil { + continue + } + m[parent.Name()] = append(m[parent.Name()], c) + } + return m +} + +func names(commands []*Command) []string { + ns := make([]string, len(commands)) + for i, c := range commands { + ns[i] = c.Name() + } + return ns +} diff --git a/vendor/github.com/spf13/cobra/zsh_completions_test.go b/vendor/github.com/spf13/cobra/zsh_completions_test.go new file mode 100644 index 000000000..08b851591 --- /dev/null +++ b/vendor/github.com/spf13/cobra/zsh_completions_test.go @@ -0,0 +1,88 @@ +package cobra + +import ( + "bytes" + "strings" + "testing" +) + +func TestZshCompletion(t *testing.T) { + tcs := []struct { + name string + root *Command + expectedExpressions []string + }{ + { + name: "trivial", + root: &Command{Use: "trivialapp"}, + expectedExpressions: []string{"#compdef trivial"}, + }, + { + name: "linear", + root: func() *Command { + r := &Command{Use: "linear"} + + sub1 := &Command{Use: "sub1"} + r.AddCommand(sub1) + + sub2 := &Command{Use: "sub2"} + sub1.AddCommand(sub2) + + sub3 := &Command{Use: "sub3"} + sub2.AddCommand(sub3) + return r + }(), + expectedExpressions: []string{"sub1", "sub2", "sub3"}, + }, + { + name: "flat", + root: func() *Command { + r := &Command{Use: "flat"} + r.AddCommand(&Command{Use: "c1"}) + r.AddCommand(&Command{Use: "c2"}) + return r + }(), + expectedExpressions: []string{"(c1 c2)"}, + }, + { + name: "tree", + root: func() *Command { + r := &Command{Use: "tree"} + + sub1 := &Command{Use: "sub1"} + r.AddCommand(sub1) + + sub11 := &Command{Use: "sub11"} + sub12 := &Command{Use: "sub12"} + + sub1.AddCommand(sub11) + sub1.AddCommand(sub12) + + sub2 := &Command{Use: "sub2"} + r.AddCommand(sub2) + + sub21 := &Command{Use: "sub21"} + sub22 := &Command{Use: "sub22"} + + sub2.AddCommand(sub21) + sub2.AddCommand(sub22) + + return r + }(), + expectedExpressions: []string{"(sub11 sub12)", "(sub21 sub22)"}, + }, + } + + for _, tc := range tcs { + t.Run(tc.name, func(t *testing.T) { + buf := new(bytes.Buffer) + tc.root.GenZshCompletion(buf) + completion := buf.String() + for _, expectedExpression := range tc.expectedExpressions { + if !strings.Contains(completion, expectedExpression) { + t.Errorf("expected completion to contain '%v' somewhere; got '%v'", expectedExpression, completion) + } + } + }) + } +} diff --git a/vendor/github.com/spf13/viper/.travis.yml b/vendor/github.com/spf13/viper/.travis.yml index d4c2559c2..f1deac3d7 100644 --- a/vendor/github.com/spf13/viper/.travis.yml +++ b/vendor/github.com/spf13/viper/.travis.yml @@ -17,6 +17,7 @@ matrix: script: - go install ./... + - diff -u <(echo -n) <(gofmt -d .) - go test -v ./... after_success: diff --git a/vendor/github.com/spf13/viper/README.md b/vendor/github.com/spf13/viper/README.md index 577088fbb..848d92d6b 100644 --- a/vendor/github.com/spf13/viper/README.md +++ b/vendor/github.com/spf13/viper/README.md @@ -6,18 +6,19 @@ Many Go projects are built using Viper including: * [Hugo](http://gohugo.io) * [EMC RexRay](http://rexray.readthedocs.org/en/stable/) -* [Imgur's Incus](https://github.com/Imgur/incus) +* [Imgur’s Incus](https://github.com/Imgur/incus) * [Nanobox](https://github.com/nanobox-io/nanobox)/[Nanopack](https://github.com/nanopack) * [Docker Notary](https://github.com/docker/Notary) * [BloomApi](https://www.bloomapi.com/) * [doctl](https://github.com/digitalocean/doctl) +* [Clairctl](https://github.com/jgsqware/clairctl) [![Build Status](https://travis-ci.org/spf13/viper.svg)](https://travis-ci.org/spf13/viper) [![Join the chat at https://gitter.im/spf13/viper](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/spf13/viper?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![GoDoc](https://godoc.org/github.com/spf13/viper?status.svg)](https://godoc.org/github.com/spf13/viper) ## What is Viper? -Viper is a complete configuration solution for go applications including 12 factor apps. It is designed +Viper is a complete configuration solution for Go applications including 12-Factor apps. It is designed to work within an application, and can handle all types of configuration needs and formats. It supports: @@ -68,7 +69,7 @@ Viper configuration keys are case insensitive. ### Establishing Defaults A good configuration system will support default values. A default value is not -required for a key, but it's useful in the event that a key hasn’t been set via +required for a key, but it’s useful in the event that a key hasn’t been set via config file, environment variable, remote configuration or flag. Examples: @@ -116,10 +117,10 @@ Optionally you can provide a function for Viper to run each time a change occurs **Make sure you add all of the configPaths prior to calling `WatchConfig()`** ```go - viper.WatchConfig() - viper.OnConfigChange(func(e fsnotify.Event) { - fmt.Println("Config file changed:", e.Name) - }) +viper.WatchConfig() +viper.OnConfigChange(func(e fsnotify.Event) { + fmt.Println("Config file changed:", e.Name) +}) ``` ### Reading Config from io.Reader @@ -236,7 +237,7 @@ Like `BindEnv`, the value is not set when the binding method is called, but when it is accessed. This means you can bind as early as you want, even in an `init()` function. -The `BindPFlag()` method provides this functionality. +For individual flags, the `BindPFlag()` method provides this functionality. Example: @@ -245,6 +246,19 @@ serverCmd.Flags().Int("port", 1138, "Port to run Application server on") viper.BindPFlag("port", serverCmd.Flags().Lookup("port")) ``` +You can also bind an existing set of pflags (pflag.FlagSet): + +Example: + +```go +pflag.Int("flagname", 1234, "help message for flagname") + +pflag.Parse() +viper.BindPFlags(pflag.CommandLine) + +i := viper.GetInt("flagname") // retrieve values from viper instead of pflag +``` + The use of [pflag](https://github.com/spf13/pflag/) in Viper does not preclude the use of other packages that use the [flag](https://golang.org/pkg/flag/) package from the standard library. The pflag package can handle the flags @@ -263,15 +277,23 @@ import ( ) func main() { + + // using standard library "flag" package + flag.Int("flagname", 1234, "help message for flagname") + pflag.CommandLine.AddGoFlagSet(flag.CommandLine) pflag.Parse() - ... + viper.BindPFlags(pflag.CommandLine) + + i := viper.GetInt("flagname") // retrieve value from viper + + ... } ``` #### Flag interfaces -Viper provides two Go interfaces to bind other flag systems if you don't use `Pflags`. +Viper provides two Go interfaces to bind other flag systems if you don’t use `Pflags`. `FlagValue` represents a single flag. This is a very simple example on how to implement this interface: @@ -401,7 +423,7 @@ go func(){ ## Getting Values From Viper -In Viper, there are a few ways to get a value depending on the value's type. +In Viper, there are a few ways to get a value depending on the value’s type. The following functions and methods exist: * `Get(key string) : interface{}` @@ -531,7 +553,7 @@ func NewCache(cfg *Viper) *Cache {...} ``` which creates a cache based on config information formatted as `subv`. -Now it's easy to create these 2 caches separately as: +Now it’s easy to create these 2 caches separately as: ```go cfg1 := viper.Sub("app.cache1") diff --git a/vendor/github.com/spf13/viper/flags_test.go b/vendor/github.com/spf13/viper/flags_test.go index 5bffca36c..0b976b605 100644 --- a/vendor/github.com/spf13/viper/flags_test.go +++ b/vendor/github.com/spf13/viper/flags_test.go @@ -62,5 +62,4 @@ func TestBindFlagValue(t *testing.T) { flag.Changed = true //hack for pflag usage assert.Equal(t, "testing_mutate", Get("testvalue")) - } diff --git a/vendor/github.com/spf13/viper/remote/remote.go b/vendor/github.com/spf13/viper/remote/remote.go index f100a9c7f..68a35d692 100644 --- a/vendor/github.com/spf13/viper/remote/remote.go +++ b/vendor/github.com/spf13/viper/remote/remote.go @@ -33,13 +33,14 @@ func (rc remoteConfigProvider) Watch(rp viper.RemoteProvider) (io.Reader, error) if err != nil { return nil, err } - resp,err := cm.Get(rp.Path()) + resp, err := cm.Get(rp.Path()) if err != nil { return nil, err } return bytes.NewReader(resp), nil } + func (rc remoteConfigProvider) WatchChannel(rp viper.RemoteProvider) (<-chan *viper.RemoteResponse, chan bool) { cm, err := getConfigManager(rp) if err != nil { @@ -47,13 +48,13 @@ func (rc remoteConfigProvider) WatchChannel(rp viper.RemoteProvider) (<-chan *vi } quit := make(chan bool) quitwc := make(chan bool) - viperResponsCh := make(chan *viper.RemoteResponse) + viperResponsCh := make(chan *viper.RemoteResponse) cryptoResponseCh := cm.Watch(rp.Path(), quit) // need this function to convert the Channel response form crypt.Response to viper.Response - go func(cr <-chan *crypt.Response,vr chan<- *viper.RemoteResponse, quitwc <-chan bool, quit chan<- bool) { + go func(cr <-chan *crypt.Response, vr chan<- *viper.RemoteResponse, quitwc <-chan bool, quit chan<- bool) { for { select { - case <- quitwc: + case <-quitwc: quit <- true return case resp := <-cr: @@ -65,15 +66,12 @@ func (rc remoteConfigProvider) WatchChannel(rp viper.RemoteProvider) (<-chan *vi } } - }(cryptoResponseCh,viperResponsCh,quitwc,quit) - - return viperResponsCh,quitwc + }(cryptoResponseCh, viperResponsCh, quitwc, quit) + return viperResponsCh, quitwc } - func getConfigManager(rp viper.RemoteProvider) (crypt.ConfigManager, error) { - var cm crypt.ConfigManager var err error @@ -99,7 +97,6 @@ func getConfigManager(rp viper.RemoteProvider) (crypt.ConfigManager, error) { return nil, err } return cm, nil - } func init() { diff --git a/vendor/github.com/spf13/viper/util_test.go b/vendor/github.com/spf13/viper/util_test.go index 5949e09e4..0af80bb63 100644 --- a/vendor/github.com/spf13/viper/util_test.go +++ b/vendor/github.com/spf13/viper/util_test.go @@ -16,7 +16,6 @@ import ( ) func TestCopyAndInsensitiviseMap(t *testing.T) { - var ( given = map[string]interface{}{ "Foo": 32, diff --git a/vendor/github.com/spf13/viper/viper.go b/vendor/github.com/spf13/viper/viper.go index 39a3c06f5..2a221e53c 100644 --- a/vendor/github.com/spf13/viper/viper.go +++ b/vendor/github.com/spf13/viper/viper.go @@ -69,8 +69,7 @@ func (str UnsupportedConfigError) Error() string { } // UnsupportedRemoteProviderError denotes encountering an unsupported remote -// provider. Currently only etcd and Consul are -// supported. +// provider. Currently only etcd and Consul are supported. type UnsupportedRemoteProviderError string // Error returns the formatted remote provider error. @@ -283,8 +282,8 @@ func (v *Viper) WatchConfig() { }() } -// SetConfigFile explicitly defines the path, name and extension of the config file -// Viper will use this and not check any of the config paths +// SetConfigFile explicitly defines the path, name and extension of the config file. +// Viper will use this and not check any of the config paths. func SetConfigFile(in string) { v.SetConfigFile(in) } func (v *Viper) SetConfigFile(in string) { if in != "" { @@ -293,8 +292,8 @@ func (v *Viper) SetConfigFile(in string) { } // SetEnvPrefix defines a prefix that ENVIRONMENT variables will use. -// E.g. if your prefix is "spf", the env registry -// will look for env. variables that start with "SPF_" +// E.g. if your prefix is "spf", the env registry will look for env +// variables that start with "SPF_". func SetEnvPrefix(in string) { v.SetEnvPrefix(in) } func (v *Viper) SetEnvPrefix(in string) { if in != "" { @@ -312,11 +311,11 @@ func (v *Viper) mergeWithEnvPrefix(in string) string { // TODO: should getEnv logic be moved into find(). Can generalize the use of // rewriting keys many things, Ex: Get('someKey') -> some_key -// (cammel case to snake case for JSON keys perhaps) +// (camel case to snake case for JSON keys perhaps) // getEnv is a wrapper around os.Getenv which replaces characters in the original -// key. This allows env vars which have different keys then the config object -// keys +// key. This allows env vars which have different keys than the config object +// keys. func (v *Viper) getEnv(key string) string { if v.envKeyReplacer != nil { key = v.envKeyReplacer.Replace(key) @@ -324,7 +323,7 @@ func (v *Viper) getEnv(key string) string { return os.Getenv(key) } -// ConfigFileUsed returns the file used to populate the config registry +// ConfigFileUsed returns the file used to populate the config registry. func ConfigFileUsed() string { return v.ConfigFileUsed() } func (v *Viper) ConfigFileUsed() string { return v.configFile } @@ -815,7 +814,7 @@ func (v *Viper) BindFlagValues(flags FlagValueSet) (err error) { } // BindFlagValue binds a specific key to a FlagValue. -// Example(where serverCmd is a Cobra instance): +// Example (where serverCmd is a Cobra instance): // // serverCmd.Flags().Int("port", 1138, "Port to run Application server on") // Viper.BindFlagValue("port", serverCmd.Flags().Lookup("port")) @@ -1288,7 +1287,7 @@ func (v *Viper) WatchRemoteConfigOnChannel() error { return v.watchKeyValueConfigOnChannel() } -// Unmarshall a Reader into a map. +// Unmarshal a Reader into a map. // Should probably be an unexported function. func unmarshalReader(in io.Reader, c map[string]interface{}) error { return v.unmarshalReader(in, c) @@ -1547,7 +1546,6 @@ func (v *Viper) searchInPath(in string) (filename string) { // Search all configPaths for any config file. // Returns the first path that exists (and is a config file). func (v *Viper) findConfigFile() (string, error) { - jww.INFO.Println("Searching for config in ", v.configPaths) for _, cp := range v.configPaths { -- cgit v1.2.3-1-g7c22