diff --git a/Godeps/Godeps.json b/Godeps/Godeps.json index 9326bece6b3..52f38b40fa4 100644 --- a/Godeps/Godeps.json +++ b/Godeps/Godeps.json @@ -484,11 +484,11 @@ }, { "ImportPath": "github.com/spf13/cobra", - "Rev": "9cb5e8502924a8ff1cce18a9348b61995d7b4fde" + "Rev": "69e5f196b5d30673deb07a2221d89cf62e4b74ae" }, { "ImportPath": "github.com/spf13/pflag", - "Rev": "60d4c375939ff7ba397a84117d5281256abb298f" + "Rev": "d4ebabf889f7b016ffcb5f74c350e1e5424b2094" }, { "ImportPath": "github.com/stretchr/objx", diff --git a/Godeps/_workspace/src/github.com/spf13/cobra/README.md b/Godeps/_workspace/src/github.com/spf13/cobra/README.md index 1b29a86e528..95e91324755 100644 --- a/Godeps/_workspace/src/github.com/spf13/cobra/README.md +++ b/Godeps/_workspace/src/github.com/spf13/cobra/README.md @@ -145,9 +145,9 @@ A flag can also be assigned locally which will only apply to that specific comma ### Remove a command from its parent -Removing a command is not a common action is simple program but it allows 3rd parties to customize an existing command tree. +Removing a command is not a common action in simple programs but it allows 3rd parties to customize an existing command tree. -In this exemple, we remove the existing `VersionCmd` command of an existing root command, and we replace it by our own version. +In this example, we remove the existing `VersionCmd` command of an existing root command, and we replace it by our own version. mainlib.RootCmd.RemoveCommand(mainlib.VersionCmd) mainlib.RootCmd.AddCommand(versionCmd) diff --git a/Godeps/_workspace/src/github.com/spf13/cobra/cobra_test.go b/Godeps/_workspace/src/github.com/spf13/cobra/cobra_test.go index a258508947f..6feb8e56fb2 100644 --- a/Godeps/_workspace/src/github.com/spf13/cobra/cobra_test.go +++ b/Godeps/_workspace/src/github.com/spf13/cobra/cobra_test.go @@ -483,6 +483,32 @@ func TestInvalidSubCommandFlags(t *testing.T) { } +func TestSubCommandArgEvaluation(t *testing.T) { + cmd := initializeWithRootCmd() + + first := &Command{ + Use: "first", + Run: func(cmd *Command, args []string) { + }, + } + cmd.AddCommand(first) + + second := &Command{ + Use: "second", + Run: func(cmd *Command, args []string) { + fmt.Fprintf(cmd.Out(), "%v", args) + }, + } + first.AddCommand(second) + + result := simpleTester(cmd, "first second first third") + + expectedOutput := fmt.Sprintf("%v", []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") diff --git a/Godeps/_workspace/src/github.com/spf13/cobra/command.go b/Godeps/_workspace/src/github.com/spf13/cobra/command.go index 59654c25cb4..ef802c6704f 100644 --- a/Godeps/_workspace/src/github.com/spf13/cobra/command.go +++ b/Godeps/_workspace/src/github.com/spf13/cobra/command.go @@ -328,15 +328,18 @@ func stripFlags(args []string, c *Command) []string { return commands } -func argsMinusX(args []string, x string) []string { - newargs := []string{} - - for _, y := range args { - if x != y { - newargs = append(newargs, y) +// argsMinusFirstX removes only the first x from args. Otherwise, commands that look like +// openshift admin policy add-role-to-user admin my-user, lose the admin argument (arg[4]). +func argsMinusFirstX(args []string, x string) []string { + for i, y := range args { + if x == y { + ret := []string{} + ret = append(ret, args[:i]...) + ret = append(ret, args[i+1:]...) + return ret } } - return newargs + return args } // find the target command given the args and command tree @@ -359,7 +362,7 @@ func (c *Command) Find(arrs []string) (*Command, []string, error) { matches := make([]*Command, 0) for _, cmd := range c.commands { if cmd.Name() == argsWOflags[0] || cmd.HasAlias(argsWOflags[0]) { // exact name or alias match - return innerfind(cmd, argsMinusX(args, argsWOflags[0])) + return innerfind(cmd, argsMinusFirstX(args, argsWOflags[0])) } else if EnablePrefixMatching { if strings.HasPrefix(cmd.Name(), argsWOflags[0]) { // prefix match matches = append(matches, cmd) @@ -374,7 +377,7 @@ func (c *Command) Find(arrs []string) (*Command, []string, error) { // only accept a single prefix match - multiple matches would be ambiguous if len(matches) == 1 { - return innerfind(matches[0], argsMinusX(args, argsWOflags[0])) + return innerfind(matches[0], argsMinusFirstX(args, argsWOflags[0])) } } } diff --git a/Godeps/_workspace/src/github.com/spf13/cobra/md_docs.go b/Godeps/_workspace/src/github.com/spf13/cobra/md_docs.go index 71bc8d5bd96..ab5188e7540 100644 --- a/Godeps/_workspace/src/github.com/spf13/cobra/md_docs.go +++ b/Godeps/_workspace/src/github.com/spf13/cobra/md_docs.go @@ -34,7 +34,7 @@ func printOptions(out *bytes.Buffer, cmd *Command, name string) { parentFlags := cmd.InheritedFlags() parentFlags.SetOutput(out) if parentFlags.HasFlags() { - fmt.Fprintf(out, "### Options inherrited from parent commands\n\n```\n") + fmt.Fprintf(out, "### Options inherited from parent commands\n\n```\n") parentFlags.PrintDefaults() fmt.Fprintf(out, "```\n\n") } diff --git a/Godeps/_workspace/src/github.com/spf13/cobra/md_docs_test.go b/Godeps/_workspace/src/github.com/spf13/cobra/md_docs_test.go index 33613af3a2b..fd11ad321d5 100644 --- a/Godeps/_workspace/src/github.com/spf13/cobra/md_docs_test.go +++ b/Godeps/_workspace/src/github.com/spf13/cobra/md_docs_test.go @@ -59,6 +59,4 @@ func TestGenMdDoc(t *testing.T) { if !strings.Contains(found, expected) { t.Errorf("Unexpected response.\nExpecting to contain: \n %q\nGot:\n %q\n", expected, found) } - - fmt.Fprintf(os.Stdout, "%s\n", found) } diff --git a/Godeps/_workspace/src/github.com/spf13/pflag/bool_test.go b/Godeps/_workspace/src/github.com/spf13/pflag/bool_test.go index fe45b8d6e6a..20735907fa6 100644 --- a/Godeps/_workspace/src/github.com/spf13/pflag/bool_test.go +++ b/Godeps/_workspace/src/github.com/spf13/pflag/bool_test.go @@ -156,7 +156,8 @@ func TestImplicitFalse(t *testing.T) { func TestInvalidValue(t *testing.T) { var tristate triStateValue f := setUpFlagSet(&tristate) - err := f.Parse([]string{"--tristate=invalid"}) + args := []string{"--tristate=invalid"} + _, err := parseReturnStderr(t, f, args) if err == nil { t.Fatal("expected an error but did not get any, tristate has value", tristate) } diff --git a/Godeps/_workspace/src/github.com/spf13/pflag/flag.go b/Godeps/_workspace/src/github.com/spf13/pflag/flag.go index 33db47c63b0..55594df40d3 100644 --- a/Godeps/_workspace/src/github.com/spf13/pflag/flag.go +++ b/Godeps/_workspace/src/github.com/spf13/pflag/flag.go @@ -120,9 +120,9 @@ const ( PanicOnError ) -// normalizedName is a flag name that has been normalized according to rules +// NormalizedName is a flag name that has been normalized according to rules // for the FlagSet (e.g. making '-' and '_' equivalent). -type normalizedName string +type NormalizedName string // A FlagSet represents a set of defined flags. type FlagSet struct { @@ -131,17 +131,17 @@ type FlagSet struct { // a custom error handler. Usage func() - name string - parsed bool - actual map[normalizedName]*Flag - formal map[normalizedName]*Flag - shorthands map[byte]*Flag - args []string // arguments after flags - exitOnError bool // does the program exit if there's an error? - errorHandling ErrorHandling - output io.Writer // nil means stderr; use out() accessor - interspersed bool // allow interspersed option/non-option args - wordSeparators []string + name string + parsed bool + actual map[NormalizedName]*Flag + formal map[NormalizedName]*Flag + shorthands map[byte]*Flag + args []string // arguments after flags + exitOnError bool // does the program exit if there's an error? + errorHandling ErrorHandling + output io.Writer // nil means stderr; use out() accessor + interspersed bool // allow interspersed option/non-option args + normalizeNameFunc func(f *FlagSet, name string) NormalizedName } // A Flag represents the state of a flag. @@ -152,6 +152,7 @@ type Flag struct { Value Value // value as set DefValue string // default value (as text); for usage message Changed bool // If the user set the value (or if left to default) + Deprecated string // If this flag is deprecated, this string is the new or now thing to use Annotations map[string][]string // used by cobra.Command bash autocomple code } @@ -164,7 +165,7 @@ type Value interface { } // sortFlags returns the flags as a slice in lexicographical sorted order. -func sortFlags(flags map[normalizedName]*Flag) []*Flag { +func sortFlags(flags map[NormalizedName]*Flag) []*Flag { list := make(sort.StringSlice, len(flags)) i := 0 for k := range flags { @@ -174,18 +175,29 @@ func sortFlags(flags map[normalizedName]*Flag) []*Flag { list.Sort() result := make([]*Flag, len(list)) for i, name := range list { - result[i] = flags[normalizedName(name)] + result[i] = flags[NormalizedName(name)] } return result } -func (f *FlagSet) normalizeFlagName(name string) normalizedName { - result := name - for _, sep := range f.wordSeparators { - result = strings.Replace(result, sep, "-", -1) +func (f *FlagSet) SetNormalizeFunc(n func(f *FlagSet, name string) NormalizedName) { + f.normalizeNameFunc = n + for k, v := range f.formal { + delete(f.formal, k) + f.formal[f.normalizeFlagName(string(k))] = v } - // Type convert to indicate normalization has been done. - return normalizedName(result) +} + +func (f *FlagSet) GetNormalizeFunc() func(f *FlagSet, name string) NormalizedName { + if f.normalizeNameFunc != nil { + return f.normalizeNameFunc + } + return func(f *FlagSet, name string) NormalizedName { return NormalizedName(name) } +} + +func (f *FlagSet) normalizeFlagName(name string) NormalizedName { + n := f.GetNormalizeFunc() + return n(f, name) } func (f *FlagSet) out() io.Writer { @@ -239,10 +251,20 @@ func (f *FlagSet) Lookup(name string) *Flag { } // lookup returns the Flag structure of the named flag, returning nil if none exists. -func (f *FlagSet) lookup(name normalizedName) *Flag { +func (f *FlagSet) lookup(name NormalizedName) *Flag { return f.formal[name] } +// Mark a flag deprecated in your program +func (f *FlagSet) MarkDeprecated(name string, usageMessage string) error { + flag := f.Lookup(name) + if flag == nil { + return fmt.Errorf("flag %q does not exist", name) + } + flag.Deprecated = usageMessage + return nil +} + // Lookup returns the Flag structure of the named command-line flag, // returning nil if none exists. func Lookup(name string) *Flag { @@ -261,10 +283,13 @@ func (f *FlagSet) Set(name, value string) error { return err } if f.actual == nil { - f.actual = make(map[normalizedName]*Flag) + f.actual = make(map[NormalizedName]*Flag) } f.actual[normalName] = flag - f.lookup(normalName).Changed = true + flag.Changed = true + if len(flag.Deprecated) > 0 { + fmt.Fprintf(os.Stderr, "Flag --%s has been deprecated, %s\n", flag.Name, flag.Deprecated) + } return nil } @@ -277,6 +302,9 @@ func Set(name, value string) error { // otherwise, the default values of all defined flags in the set. func (f *FlagSet) PrintDefaults() { f.VisitAll(func(flag *Flag) { + if len(flag.Deprecated) > 0 { + return + } format := "--%s=%s: %s\n" if _, ok := flag.Value.(*stringValue); ok { // put quotes on the value @@ -295,6 +323,9 @@ func (f *FlagSet) FlagUsages() string { x := new(bytes.Buffer) f.VisitAll(func(flag *Flag) { + if len(flag.Deprecated) > 0 { + return + } format := "--%s=%s: %s\n" if _, ok := flag.Value.(*stringValue); ok { // put quotes on the value @@ -397,7 +428,7 @@ func (f *FlagSet) AddFlag(flag *Flag) { panic(msg) // Happens only if flags are declared with identical names } if f.formal == nil { - f.formal = make(map[normalizedName]*Flag) + f.formal = make(map[NormalizedName]*Flag) } f.formal[f.normalizeFlagName(flag.Name)] = flag @@ -462,10 +493,13 @@ func (f *FlagSet) setFlag(flag *Flag, value string, origArg string) error { } // mark as visited for Visit() if f.actual == nil { - f.actual = make(map[normalizedName]*Flag) + f.actual = make(map[NormalizedName]*Flag) } f.actual[f.normalizeFlagName(flag.Name)] = flag flag.Changed = true + if len(flag.Deprecated) > 0 { + fmt.Fprintf(os.Stderr, "Flag --%s has been deprecated, %s\n", flag.Name, flag.Deprecated) + } return nil } @@ -625,19 +659,6 @@ func SetInterspersed(interspersed bool) { CommandLine.SetInterspersed(interspersed) } -// SetWordSeparators sets a list of strings to be considerered as word -// separators and normalized for the pruposes of lookups. For example, if this -// is set to {"-", "_", "."} then --foo_bar, --foo-bar, and --foo.bar are -// considered equivalent flags. This must be called before flags are parsed, -// and may only be called once. -func (f *FlagSet) SetWordSeparators(separators []string) { - f.wordSeparators = separators - for k, v := range f.formal { - delete(f.formal, k) - f.formal[f.normalizeFlagName(string(k))] = v - } -} - // Parsed returns true if the command-line flags have been parsed. func Parsed() bool { return CommandLine.Parsed() diff --git a/Godeps/_workspace/src/github.com/spf13/pflag/flag_test.go b/Godeps/_workspace/src/github.com/spf13/pflag/flag_test.go index c4055ed96b8..f552a2f5da3 100644 --- a/Godeps/_workspace/src/github.com/spf13/pflag/flag_test.go +++ b/Godeps/_workspace/src/github.com/spf13/pflag/flag_test.go @@ -7,6 +7,7 @@ package pflag_test import ( "bytes" "fmt" + "io" "io/ioutil" "os" "sort" @@ -238,14 +239,29 @@ func TestFlagSetParse(t *testing.T) { testParse(NewFlagSet("test", ContinueOnError), t) } -func testNormalizedNames(args []string, t *testing.T) { +func replaceSeparators(name string, from []string, to string) string { + result := name + for _, sep := range from { + result = strings.Replace(result, sep, to, -1) + } + // Type convert to indicate normalization has been done. + return result +} + +func wordSepNormalizeFunc(f *FlagSet, name string) NormalizedName { + seps := []string{"-", "_"} + name = replaceSeparators(name, seps, ".") + return NormalizedName(name) +} + +func testWordSepNormalizedNames(args []string, t *testing.T) { f := NewFlagSet("normalized", ContinueOnError) if f.Parsed() { t.Error("f.Parse() = true before Parse") } withDashFlag := f.Bool("with-dash-flag", false, "bool value") // Set this after some flags have been added and before others. - f.SetWordSeparators([]string{"-", "_"}) + f.SetNormalizeFunc(wordSepNormalizeFunc) withUnderFlag := f.Bool("with_under_flag", false, "bool value") withBothFlag := f.Bool("with-both_flag", false, "bool value") if err := f.Parse(args); err != nil { @@ -265,27 +281,66 @@ func testNormalizedNames(args []string, t *testing.T) { } } -func TestNormalizedNames(t *testing.T) { +func TestWordSepNormalizedNames(t *testing.T) { args := []string{ "--with-dash-flag", "--with-under-flag", "--with-both-flag", } - testNormalizedNames(args, t) + testWordSepNormalizedNames(args, t) args = []string{ "--with_dash_flag", "--with_under_flag", "--with_both_flag", } - testNormalizedNames(args, t) + testWordSepNormalizedNames(args, t) args = []string{ "--with-dash_flag", "--with-under_flag", "--with-both_flag", } - testNormalizedNames(args, t) + testWordSepNormalizedNames(args, t) +} + +func aliasAndWordSepFlagNames(f *FlagSet, name string) NormalizedName { + seps := []string{"-", "_"} + + oldName := replaceSeparators("old-valid_flag", seps, ".") + newName := replaceSeparators("valid-flag", seps, ".") + + name = replaceSeparators(name, seps, ".") + switch name { + case oldName: + name = newName + break + } + + return NormalizedName(name) +} + +func TestCustomNormalizedNames(t *testing.T) { + f := NewFlagSet("normalized", ContinueOnError) + if f.Parsed() { + t.Error("f.Parse() = true before Parse") + } + + validFlag := f.Bool("valid-flag", false, "bool value") + f.SetNormalizeFunc(aliasAndWordSepFlagNames) + someOtherFlag := f.Bool("some-other-flag", false, "bool value") + + args := []string{"--old_valid_flag", "--some-other_flag"} + if err := f.Parse(args); err != nil { + t.Fatal(err) + } + + if *validFlag != true { + t.Errorf("validFlag is %v even though we set the alias --old_valid_falg", *validFlag) + } + if *someOtherFlag != true { + t.Error("someOtherFlag should be true, is ", *someOtherFlag) + } } // Declare a user-defined flag type. @@ -445,3 +500,74 @@ func TestTermination(t *testing.T) { t.Errorf("expected argument %q got %q", arg2, f.Args()[1]) } } + +func TestDeprecatedFlagInDocs(t *testing.T) { + f := NewFlagSet("bob", ContinueOnError) + f.Bool("badflag", true, "always true") + f.MarkDeprecated("badflag", "use --good-flag instead") + + out := new(bytes.Buffer) + f.SetOutput(out) + f.PrintDefaults() + + if strings.Contains(out.String(), "badflag") { + t.Errorf("found deprecated flag in usage!") + } +} + +func parseReturnStderr(t *testing.T, f *FlagSet, args []string) (string, error) { + oldStderr := os.Stderr + r, w, _ := os.Pipe() + os.Stderr = w + + err := f.Parse(args) + + outC := make(chan string) + // copy the output in a separate goroutine so printing can't block indefinitely + go func() { + var buf bytes.Buffer + io.Copy(&buf, r) + outC <- buf.String() + }() + + w.Close() + os.Stderr = oldStderr + out := <-outC + + return out, err +} + +func TestDeprecatedFlagUsage(t *testing.T) { + f := NewFlagSet("bob", ContinueOnError) + f.Bool("badflag", true, "always true") + usageMsg := "use --good-flag instead" + f.MarkDeprecated("badflag", usageMsg) + + args := []string{"--badflag"} + out, err := parseReturnStderr(t, f, args) + if err != nil { + t.Fatal("expected no error; got ", err) + } + + if !strings.Contains(out, usageMsg) { + t.Errorf("usageMsg not printed when using a deprecated flag!") + } +} + +func TestDeprecatedFlagUsageNormalized(t *testing.T) { + f := NewFlagSet("bob", ContinueOnError) + f.Bool("bad-double_flag", true, "always true") + f.SetNormalizeFunc(wordSepNormalizeFunc) + usageMsg := "use --good-flag instead" + f.MarkDeprecated("bad_double-flag", usageMsg) + + args := []string{"--bad_double_flag"} + out, err := parseReturnStderr(t, f, args) + if err != nil { + t.Fatal("expected no error; got ", err) + } + + if !strings.Contains(out, usageMsg) { + t.Errorf("usageMsg not printed when using a deprecated flag!") + } +} diff --git a/cmd/hyperkube/hyperkube.go b/cmd/hyperkube/hyperkube.go index 1d5511787c6..de65b3fea74 100644 --- a/cmd/hyperkube/hyperkube.go +++ b/cmd/hyperkube/hyperkube.go @@ -70,7 +70,7 @@ func (hk *HyperKube) Flags() *pflag.FlagSet { if hk.baseFlags == nil { hk.baseFlags = pflag.NewFlagSet(hk.Name, pflag.ContinueOnError) hk.baseFlags.SetOutput(ioutil.Discard) - hk.baseFlags.SetWordSeparators([]string{"-", "_"}) + hk.baseFlags.SetNormalizeFunc(util.WordSepNormalizeFunc) hk.baseFlags.BoolVarP(&hk.helpFlagVal, "help", "h", false, "help for "+hk.Name) // These will add all of the "global" flags (defined with both the diff --git a/cmd/hyperkube/server.go b/cmd/hyperkube/server.go index 4bf5422f3ad..68ec7e663ef 100644 --- a/cmd/hyperkube/server.go +++ b/cmd/hyperkube/server.go @@ -68,7 +68,7 @@ func (s *Server) Flags() *pflag.FlagSet { if s.flags == nil { s.flags = pflag.NewFlagSet(s.Name(), pflag.ContinueOnError) s.flags.SetOutput(ioutil.Discard) - s.flags.SetWordSeparators([]string{"-", "_"}) + s.flags.SetNormalizeFunc(util.WordSepNormalizeFunc) } return s.flags } diff --git a/cmd/kube-version-change/version.go b/cmd/kube-version-change/version.go index 9e6936ea80b..b466c6b299b 100644 --- a/cmd/kube-version-change/version.go +++ b/cmd/kube-version-change/version.go @@ -31,6 +31,7 @@ import ( _ "github.com/GoogleCloudPlatform/kubernetes/pkg/api/v1beta1" _ "github.com/GoogleCloudPlatform/kubernetes/pkg/api/v1beta2" _ "github.com/GoogleCloudPlatform/kubernetes/pkg/api/v1beta3" + "github.com/GoogleCloudPlatform/kubernetes/pkg/util" "github.com/ghodss/yaml" flag "github.com/spf13/pflag" @@ -55,7 +56,7 @@ func isYAML(data []byte) bool { func main() { runtime.GOMAXPROCS(runtime.NumCPU()) - flag.CommandLine.SetWordSeparators([]string{"-", "_"}) + flag.CommandLine.SetNormalizeFunc(util.WordSepNormalizeFunc) flag.Parse() if *rewrite != "" { diff --git a/docs/kubectl_api-versions.md b/docs/kubectl_api-versions.md index 19eff6d3d15..0693e3deabc 100644 --- a/docs/kubectl_api-versions.md +++ b/docs/kubectl_api-versions.md @@ -17,7 +17,7 @@ kubectl api-versions -h, --help=false: help for api-versions ``` -### Options inherrited from parent commands +### Options inherited from parent commands ``` --alsologtostderr=false: log to standard error as well as files @@ -50,4 +50,4 @@ kubectl api-versions ### SEE ALSO * [kubectl](kubectl.md) - kubectl controls the Kubernetes cluster manager -###### Auto generated by spf13/cobra at 2015-04-28 03:34:57.179420324 +0000 UTC +###### Auto generated by spf13/cobra at 2015-04-29 15:25:11.036328233 +0000 UTC diff --git a/docs/kubectl_cluster-info.md b/docs/kubectl_cluster-info.md index fa6ec4201b9..c3beff78a15 100644 --- a/docs/kubectl_cluster-info.md +++ b/docs/kubectl_cluster-info.md @@ -17,7 +17,7 @@ kubectl cluster-info -h, --help=false: help for cluster-info ``` -### Options inherrited from parent commands +### Options inherited from parent commands ``` --alsologtostderr=false: log to standard error as well as files @@ -50,4 +50,4 @@ kubectl cluster-info ### SEE ALSO * [kubectl](kubectl.md) - kubectl controls the Kubernetes cluster manager -###### Auto generated by spf13/cobra at 2015-04-28 03:34:57.179075262 +0000 UTC +###### Auto generated by spf13/cobra at 2015-04-29 15:25:11.036176301 +0000 UTC diff --git a/docs/kubectl_config.md b/docs/kubectl_config.md index 9f93f5d1778..11e8856df0e 100644 --- a/docs/kubectl_config.md +++ b/docs/kubectl_config.md @@ -24,7 +24,7 @@ kubectl config SUBCOMMAND --kubeconfig="": use a particular kubeconfig file ``` -### Options inherrited from parent commands +### Options inherited from parent commands ``` --alsologtostderr=false: log to standard error as well as files @@ -63,4 +63,4 @@ kubectl config SUBCOMMAND * [kubectl config use-context](kubectl_config_use-context.md) - Sets the current-context in a kubeconfig file * [kubectl config view](kubectl_config_view.md) - displays Merged kubeconfig settings or a specified kubeconfig file. -###### Auto generated by spf13/cobra at 2015-04-28 03:34:57.178743093 +0000 UTC +###### Auto generated by spf13/cobra at 2015-04-29 15:25:11.036002047 +0000 UTC diff --git a/docs/kubectl_config_set-cluster.md b/docs/kubectl_config_set-cluster.md index 8233db05dbf..d422fc3d023 100644 --- a/docs/kubectl_config_set-cluster.md +++ b/docs/kubectl_config_set-cluster.md @@ -36,7 +36,7 @@ $ kubectl config set-cluster e2e --insecure-skip-tls-verify=true --server=: server for the cluster entry in kubeconfig ``` -### Options inherrited from parent commands +### Options inherited from parent commands ``` --alsologtostderr=false: log to standard error as well as files @@ -65,4 +65,4 @@ $ kubectl config set-cluster e2e --insecure-skip-tls-verify=true ### SEE ALSO * [kubectl config](kubectl_config.md) - config modifies kubeconfig files -###### Auto generated by spf13/cobra at 2015-04-28 03:34:57.176632377 +0000 UTC +###### Auto generated by spf13/cobra at 2015-04-29 15:25:11.034991096 +0000 UTC diff --git a/docs/kubectl_config_set-context.md b/docs/kubectl_config_set-context.md index 42122c02227..df4fe0ebba1 100644 --- a/docs/kubectl_config_set-context.md +++ b/docs/kubectl_config_set-context.md @@ -28,7 +28,7 @@ $ kubectl config set-context gce --user=cluster-admin --user=: user for the context entry in kubeconfig ``` -### Options inherrited from parent commands +### Options inherited from parent commands ``` --alsologtostderr=false: log to standard error as well as files @@ -58,4 +58,4 @@ $ kubectl config set-context gce --user=cluster-admin ### SEE ALSO * [kubectl config](kubectl_config.md) - config modifies kubeconfig files -###### Auto generated by spf13/cobra at 2015-04-28 03:34:57.177351504 +0000 UTC +###### Auto generated by spf13/cobra at 2015-04-29 15:25:11.035371239 +0000 UTC diff --git a/docs/kubectl_config_set-credentials.md b/docs/kubectl_config_set-credentials.md index 3be48988ecd..cafc71ced1e 100644 --- a/docs/kubectl_config_set-credentials.md +++ b/docs/kubectl_config_set-credentials.md @@ -51,7 +51,7 @@ $ kubectl set-credentials cluster-admin --client-certificate=~/.kube/admin.crt - --username=: username for the user entry in kubeconfig ``` -### Options inherrited from parent commands +### Options inherited from parent commands ``` --alsologtostderr=false: log to standard error as well as files @@ -78,4 +78,4 @@ $ kubectl set-credentials cluster-admin --client-certificate=~/.kube/admin.crt - ### SEE ALSO * [kubectl config](kubectl_config.md) - config modifies kubeconfig files -###### Auto generated by spf13/cobra at 2015-04-28 03:34:57.176997115 +0000 UTC +###### Auto generated by spf13/cobra at 2015-04-29 15:25:11.035167812 +0000 UTC diff --git a/docs/kubectl_config_set.md b/docs/kubectl_config_set.md index d01f5990f86..57c9dc8640d 100644 --- a/docs/kubectl_config_set.md +++ b/docs/kubectl_config_set.md @@ -19,7 +19,7 @@ kubectl config set PROPERTY_NAME PROPERTY_VALUE -h, --help=false: help for set ``` -### Options inherrited from parent commands +### Options inherited from parent commands ``` --alsologtostderr=false: log to standard error as well as files @@ -52,4 +52,4 @@ kubectl config set PROPERTY_NAME PROPERTY_VALUE ### SEE ALSO * [kubectl config](kubectl_config.md) - config modifies kubeconfig files -###### Auto generated by spf13/cobra at 2015-04-28 03:34:57.177697607 +0000 UTC +###### Auto generated by spf13/cobra at 2015-04-29 15:25:11.035532103 +0000 UTC diff --git a/docs/kubectl_config_unset.md b/docs/kubectl_config_unset.md index d19f2750cab..cd01819cec0 100644 --- a/docs/kubectl_config_unset.md +++ b/docs/kubectl_config_unset.md @@ -18,7 +18,7 @@ kubectl config unset PROPERTY_NAME -h, --help=false: help for unset ``` -### Options inherrited from parent commands +### Options inherited from parent commands ``` --alsologtostderr=false: log to standard error as well as files @@ -51,4 +51,4 @@ kubectl config unset PROPERTY_NAME ### SEE ALSO * [kubectl config](kubectl_config.md) - config modifies kubeconfig files -###### Auto generated by spf13/cobra at 2015-04-28 03:34:57.178014311 +0000 UTC +###### Auto generated by spf13/cobra at 2015-04-29 15:25:11.035684858 +0000 UTC diff --git a/docs/kubectl_config_use-context.md b/docs/kubectl_config_use-context.md index 2f699fc3d53..22d52d39b2d 100644 --- a/docs/kubectl_config_use-context.md +++ b/docs/kubectl_config_use-context.md @@ -17,7 +17,7 @@ kubectl config use-context CONTEXT_NAME -h, --help=false: help for use-context ``` -### Options inherrited from parent commands +### Options inherited from parent commands ``` --alsologtostderr=false: log to standard error as well as files @@ -50,4 +50,4 @@ kubectl config use-context CONTEXT_NAME ### SEE ALSO * [kubectl config](kubectl_config.md) - config modifies kubeconfig files -###### Auto generated by spf13/cobra at 2015-04-28 03:34:57.178387488 +0000 UTC +###### Auto generated by spf13/cobra at 2015-04-29 15:25:11.035835782 +0000 UTC diff --git a/docs/kubectl_config_view.md b/docs/kubectl_config_view.md index 4c5c551f3dc..de82f1cec80 100644 --- a/docs/kubectl_config_view.md +++ b/docs/kubectl_config_view.md @@ -40,7 +40,7 @@ $ kubectl config view -o template --template='{{range .users}}{{ if eq .name "e2 -t, --template="": Template string or path to template file to use when -o=template or -o=templatefile. The template format is golang templates [http://golang.org/pkg/text/template/#pkg-overview] ``` -### Options inherrited from parent commands +### Options inherited from parent commands ``` --alsologtostderr=false: log to standard error as well as files @@ -73,4 +73,4 @@ $ kubectl config view -o template --template='{{range .users}}{{ if eq .name "e2 ### SEE ALSO * [kubectl config](kubectl_config.md) - config modifies kubeconfig files -###### Auto generated by spf13/cobra at 2015-04-28 03:34:57.176300117 +0000 UTC +###### Auto generated by spf13/cobra at 2015-04-29 15:25:11.034809963 +0000 UTC diff --git a/docs/kubectl_create.md b/docs/kubectl_create.md index 8f4a8e9c81f..6369bbbd605 100644 --- a/docs/kubectl_create.md +++ b/docs/kubectl_create.md @@ -30,7 +30,7 @@ $ cat pod.json | kubectl create -f - -h, --help=false: help for create ``` -### Options inherrited from parent commands +### Options inherited from parent commands ``` --alsologtostderr=false: log to standard error as well as files @@ -63,4 +63,4 @@ $ cat pod.json | kubectl create -f - ### SEE ALSO * [kubectl](kubectl.md) - kubectl controls the Kubernetes cluster manager -###### Auto generated by spf13/cobra at 2015-04-28 03:34:57.169347287 +0000 UTC +###### Auto generated by spf13/cobra at 2015-04-29 15:25:11.030664101 +0000 UTC diff --git a/docs/kubectl_delete.md b/docs/kubectl_delete.md index e191d70c668..eb36fe0684f 100644 --- a/docs/kubectl_delete.md +++ b/docs/kubectl_delete.md @@ -49,7 +49,7 @@ $ kubectl delete pods --all -l, --selector="": Selector (label query) to filter on ``` -### Options inherrited from parent commands +### Options inherited from parent commands ``` --alsologtostderr=false: log to standard error as well as files @@ -82,4 +82,4 @@ $ kubectl delete pods --all ### SEE ALSO * [kubectl](kubectl.md) - kubectl controls the Kubernetes cluster manager -###### Auto generated by spf13/cobra at 2015-04-28 03:34:57.170113984 +0000 UTC +###### Auto generated by spf13/cobra at 2015-04-29 15:25:11.031169223 +0000 UTC diff --git a/docs/kubectl_describe.md b/docs/kubectl_describe.md index 4e7fe4d6079..907341b2d65 100644 --- a/docs/kubectl_describe.md +++ b/docs/kubectl_describe.md @@ -30,7 +30,7 @@ $ kubectl describe pods/nginx -h, --help=false: help for describe ``` -### Options inherrited from parent commands +### Options inherited from parent commands ``` --alsologtostderr=false: log to standard error as well as files @@ -63,4 +63,4 @@ $ kubectl describe pods/nginx ### SEE ALSO * [kubectl](kubectl.md) - kubectl controls the Kubernetes cluster manager -###### Auto generated by spf13/cobra at 2015-04-28 03:34:57.168905946 +0000 UTC +###### Auto generated by spf13/cobra at 2015-04-29 15:25:11.030447061 +0000 UTC diff --git a/docs/kubectl_exec.md b/docs/kubectl_exec.md index 30eb75a7e0b..eddb9dfb314 100644 --- a/docs/kubectl_exec.md +++ b/docs/kubectl_exec.md @@ -31,7 +31,7 @@ $ kubectl exec -p 123456-7890 -c ruby-container -i -t -- bash -il -t, --tty=false: Stdin is a TTY ``` -### Options inherrited from parent commands +### Options inherited from parent commands ``` --alsologtostderr=false: log to standard error as well as files @@ -64,4 +64,4 @@ $ kubectl exec -p 123456-7890 -c ruby-container -i -t -- bash -il ### SEE ALSO * [kubectl](kubectl.md) - kubectl controls the Kubernetes cluster manager -###### Auto generated by spf13/cobra at 2015-04-28 03:34:57.173193785 +0000 UTC +###### Auto generated by spf13/cobra at 2015-04-29 15:25:11.032352238 +0000 UTC diff --git a/docs/kubectl_expose.md b/docs/kubectl_expose.md index 3dd54f3d8f8..e548130cb11 100644 --- a/docs/kubectl_expose.md +++ b/docs/kubectl_expose.md @@ -49,7 +49,7 @@ $ kubectl expose streamer --port=4100 --protocol=udp --service-name=video-stream -t, --template="": Template string or path to template file to use when -o=template or -o=templatefile. The template format is golang templates [http://golang.org/pkg/text/template/#pkg-overview] ``` -### Options inherrited from parent commands +### Options inherited from parent commands ``` --alsologtostderr=false: log to standard error as well as files @@ -82,4 +82,4 @@ $ kubectl expose streamer --port=4100 --protocol=udp --service-name=video-stream ### SEE ALSO * [kubectl](kubectl.md) - kubectl controls the Kubernetes cluster manager -###### Auto generated by spf13/cobra at 2015-04-28 03:34:57.175492324 +0000 UTC +###### Auto generated by spf13/cobra at 2015-04-29 15:25:11.03436108 +0000 UTC diff --git a/docs/kubectl_get.md b/docs/kubectl_get.md index f6af6c5f2e9..76230f04238 100644 --- a/docs/kubectl_get.md +++ b/docs/kubectl_get.md @@ -52,7 +52,7 @@ $ kubectl get rc/web service/frontend pods/web-pod-13je7 --watch-only=false: Watch for changes to the requested object(s), without listing/getting first. ``` -### Options inherrited from parent commands +### Options inherited from parent commands ``` --alsologtostderr=false: log to standard error as well as files @@ -85,4 +85,4 @@ $ kubectl get rc/web service/frontend pods/web-pod-13je7 ### SEE ALSO * [kubectl](kubectl.md) - kubectl controls the Kubernetes cluster manager -###### Auto generated by spf13/cobra at 2015-04-28 03:34:57.168465048 +0000 UTC +###### Auto generated by spf13/cobra at 2015-04-29 15:25:11.030165061 +0000 UTC diff --git a/docs/kubectl_label.md b/docs/kubectl_label.md index 900d47bc664..81fcad3f4b7 100644 --- a/docs/kubectl_label.md +++ b/docs/kubectl_label.md @@ -48,7 +48,7 @@ $ kubectl label pods foo bar- -t, --template="": Template string or path to template file to use when -o=template or -o=templatefile. The template format is golang templates [http://golang.org/pkg/text/template/#pkg-overview] ``` -### Options inherrited from parent commands +### Options inherited from parent commands ``` --alsologtostderr=false: log to standard error as well as files @@ -81,4 +81,4 @@ $ kubectl label pods foo bar- ### SEE ALSO * [kubectl](kubectl.md) - kubectl controls the Kubernetes cluster manager -###### Auto generated by spf13/cobra at 2015-04-28 03:34:57.175924183 +0000 UTC +###### Auto generated by spf13/cobra at 2015-04-29 15:25:11.03459192 +0000 UTC diff --git a/docs/kubectl_log.md b/docs/kubectl_log.md index 77ddbb5ef16..def67609563 100644 --- a/docs/kubectl_log.md +++ b/docs/kubectl_log.md @@ -29,7 +29,7 @@ $ kubectl log -f 123456-7890 ruby-container --interactive=true: If true, prompt the user for input when required. Default true. ``` -### Options inherrited from parent commands +### Options inherited from parent commands ``` --alsologtostderr=false: log to standard error as well as files @@ -62,4 +62,4 @@ $ kubectl log -f 123456-7890 ruby-container ### SEE ALSO * [kubectl](kubectl.md) - kubectl controls the Kubernetes cluster manager -###### Auto generated by spf13/cobra at 2015-04-28 03:34:57.170843937 +0000 UTC +###### Auto generated by spf13/cobra at 2015-04-29 15:25:11.031591306 +0000 UTC diff --git a/docs/kubectl_namespace.md b/docs/kubectl_namespace.md index 4c88ea908a0..3800ce3dfd6 100644 --- a/docs/kubectl_namespace.md +++ b/docs/kubectl_namespace.md @@ -20,7 +20,7 @@ kubectl namespace [namespace] -h, --help=false: help for namespace ``` -### Options inherrited from parent commands +### Options inherited from parent commands ``` --alsologtostderr=false: log to standard error as well as files @@ -53,4 +53,4 @@ kubectl namespace [namespace] ### SEE ALSO * [kubectl](kubectl.md) - kubectl controls the Kubernetes cluster manager -###### Auto generated by spf13/cobra at 2015-04-28 03:34:57.170473143 +0000 UTC +###### Auto generated by spf13/cobra at 2015-04-29 15:25:11.031378018 +0000 UTC diff --git a/docs/kubectl_port-forward.md b/docs/kubectl_port-forward.md index c55506242f1..93946c39783 100644 --- a/docs/kubectl_port-forward.md +++ b/docs/kubectl_port-forward.md @@ -35,7 +35,7 @@ $ kubectl port-forward -p mypod 0:5000 -p, --pod="": Pod name ``` -### Options inherrited from parent commands +### Options inherited from parent commands ``` --alsologtostderr=false: log to standard error as well as files @@ -68,4 +68,4 @@ $ kubectl port-forward -p mypod 0:5000 ### SEE ALSO * [kubectl](kubectl.md) - kubectl controls the Kubernetes cluster manager -###### Auto generated by spf13/cobra at 2015-04-28 03:34:57.173592919 +0000 UTC +###### Auto generated by spf13/cobra at 2015-04-29 15:25:11.032575511 +0000 UTC diff --git a/docs/kubectl_proxy.md b/docs/kubectl_proxy.md index b1152ae451c..7cda4cea0f2 100644 --- a/docs/kubectl_proxy.md +++ b/docs/kubectl_proxy.md @@ -32,7 +32,7 @@ $ kubectl proxy --api-prefix=k8s-api -P, --www-prefix="/static/": Prefix to serve static files under, if static file directory is specified. ``` -### Options inherrited from parent commands +### Options inherited from parent commands ``` --alsologtostderr=false: log to standard error as well as files @@ -65,4 +65,4 @@ $ kubectl proxy --api-prefix=k8s-api ### SEE ALSO * [kubectl](kubectl.md) - kubectl controls the Kubernetes cluster manager -###### Auto generated by spf13/cobra at 2015-04-28 03:34:57.173961813 +0000 UTC +###### Auto generated by spf13/cobra at 2015-04-29 15:25:11.032792489 +0000 UTC diff --git a/docs/kubectl_resize.md b/docs/kubectl_resize.md index 0f066936abd..d90f8fa3bda 100644 --- a/docs/kubectl_resize.md +++ b/docs/kubectl_resize.md @@ -35,7 +35,7 @@ $ kubectl resize --current-replicas=2 --replicas=3 replicationcontrollers foo --resource-version="": Precondition for resource version. Requires that the current resource version match this value in order to resize. ``` -### Options inherrited from parent commands +### Options inherited from parent commands ``` --alsologtostderr=false: log to standard error as well as files @@ -68,4 +68,4 @@ $ kubectl resize --current-replicas=2 --replicas=3 replicationcontrollers foo ### SEE ALSO * [kubectl](kubectl.md) - kubectl controls the Kubernetes cluster manager -###### Auto generated by spf13/cobra at 2015-04-28 03:34:57.171613369 +0000 UTC +###### Auto generated by spf13/cobra at 2015-04-29 15:25:11.032100141 +0000 UTC diff --git a/docs/kubectl_rolling-update.md b/docs/kubectl_rolling-update.md index 6a09bf6e31c..7f4dd7c98a4 100644 --- a/docs/kubectl_rolling-update.md +++ b/docs/kubectl_rolling-update.md @@ -50,7 +50,7 @@ $ kubectl rolling-update frontend --image=image:v2 --update-period="1m0s": Time to wait between updating pods. Valid time units are "ns", "us" (or "µs"), "ms", "s", "m", "h". ``` -### Options inherrited from parent commands +### Options inherited from parent commands ``` --alsologtostderr=false: log to standard error as well as files @@ -83,4 +83,4 @@ $ kubectl rolling-update frontend --image=image:v2 ### SEE ALSO * [kubectl](kubectl.md) - kubectl controls the Kubernetes cluster manager -###### Auto generated by spf13/cobra at 2015-04-28 21:28:37.951011185 +0000 UTC +###### Auto generated by spf13/cobra at 2015-04-29 15:25:11.031878187 +0000 UTC diff --git a/docs/kubectl_run-container.md b/docs/kubectl_run-container.md index 1f99745b4bd..2f3c783edd0 100644 --- a/docs/kubectl_run-container.md +++ b/docs/kubectl_run-container.md @@ -45,7 +45,7 @@ $ kubectl run-container nginx --image=nginx --overrides='{ "apiVersion": "v1beta -t, --template="": Template string or path to template file to use when -o=template or -o=templatefile. The template format is golang templates [http://golang.org/pkg/text/template/#pkg-overview] ``` -### Options inherrited from parent commands +### Options inherited from parent commands ``` --alsologtostderr=false: log to standard error as well as files @@ -78,4 +78,4 @@ $ kubectl run-container nginx --image=nginx --overrides='{ "apiVersion": "v1beta ### SEE ALSO * [kubectl](kubectl.md) - kubectl controls the Kubernetes cluster manager -###### Auto generated by spf13/cobra at 2015-04-28 03:34:57.174507457 +0000 UTC +###### Auto generated by spf13/cobra at 2015-04-29 15:25:11.0330734 +0000 UTC diff --git a/docs/kubectl_stop.md b/docs/kubectl_stop.md index 3b1fdd1a345..a6f0ed61306 100644 --- a/docs/kubectl_stop.md +++ b/docs/kubectl_stop.md @@ -39,7 +39,7 @@ $ kubectl stop -f path/to/resources -l, --selector="": Selector (label query) to filter on ``` -### Options inherrited from parent commands +### Options inherited from parent commands ``` --alsologtostderr=false: log to standard error as well as files @@ -72,4 +72,4 @@ $ kubectl stop -f path/to/resources ### SEE ALSO * [kubectl](kubectl.md) - kubectl controls the Kubernetes cluster manager -###### Auto generated by spf13/cobra at 2015-04-28 03:34:57.174999749 +0000 UTC +###### Auto generated by spf13/cobra at 2015-04-29 15:25:11.033329682 +0000 UTC diff --git a/docs/kubectl_update.md b/docs/kubectl_update.md index d171c2585f0..666f2d376b6 100644 --- a/docs/kubectl_update.md +++ b/docs/kubectl_update.md @@ -34,7 +34,7 @@ $ kubectl update pods my-pod --patch='{ "apiVersion": "v1beta1", "desiredState": --patch="": A JSON document to override the existing resource. The resource is downloaded, patched with the JSON, then updated. ``` -### Options inherrited from parent commands +### Options inherited from parent commands ``` --alsologtostderr=false: log to standard error as well as files @@ -67,4 +67,4 @@ $ kubectl update pods my-pod --patch='{ "apiVersion": "v1beta1", "desiredState": ### SEE ALSO * [kubectl](kubectl.md) - kubectl controls the Kubernetes cluster manager -###### Auto generated by spf13/cobra at 2015-04-28 03:34:57.16972972 +0000 UTC +###### Auto generated by spf13/cobra at 2015-04-29 15:25:11.030922954 +0000 UTC diff --git a/docs/kubectl_version.md b/docs/kubectl_version.md index 9f01f8fb175..be1a2946964 100644 --- a/docs/kubectl_version.md +++ b/docs/kubectl_version.md @@ -18,7 +18,7 @@ kubectl version -h, --help=false: help for version ``` -### Options inherrited from parent commands +### Options inherited from parent commands ``` --alsologtostderr=false: log to standard error as well as files @@ -51,4 +51,4 @@ kubectl version ### SEE ALSO * [kubectl](kubectl.md) - kubectl controls the Kubernetes cluster manager -###### Auto generated by spf13/cobra at 2015-04-28 03:34:57.179736961 +0000 UTC +###### Auto generated by spf13/cobra at 2015-04-29 15:25:11.036492866 +0000 UTC diff --git a/pkg/kubectl/cmd/util/factory.go b/pkg/kubectl/cmd/util/factory.go index 312230b395c..eb7b4bbd448 100644 --- a/pkg/kubectl/cmd/util/factory.go +++ b/pkg/kubectl/cmd/util/factory.go @@ -86,7 +86,7 @@ func NewFactory(optionalClientConfig clientcmd.ClientConfig) *Factory { mapper := kubectl.ShortcutExpander{latest.RESTMapper} flags := pflag.NewFlagSet("", pflag.ContinueOnError) - flags.SetWordSeparators([]string{"-", "_"}) + flags.SetNormalizeFunc(util.WordSepNormalizeFunc) clientConfig := optionalClientConfig if optionalClientConfig == nil { diff --git a/pkg/util/flags.go b/pkg/util/flags.go index 87c3f38e1ea..c22ea1d581c 100644 --- a/pkg/util/flags.go +++ b/pkg/util/flags.go @@ -16,11 +16,23 @@ limitations under the License. package util +import "strings" + import "github.com/spf13/pflag" +func WordSepNormalizeFunc(f *pflag.FlagSet, name string) pflag.NormalizedName { + from := []string{"-", "_"} + to := "." + for _, sep := range from { + name = strings.Replace(name, sep, to, -1) + } + // Type convert to indicate normalization has been done. + return pflag.NormalizedName(name) +} + // InitFlags normalizes and parses the command line flags func InitFlags() { - pflag.CommandLine.SetWordSeparators([]string{"-", "_"}) + pflag.CommandLine.SetNormalizeFunc(WordSepNormalizeFunc) AddAllFlagsToPFlags() pflag.Parse() }