diff --git a/Godeps/Godeps.json b/Godeps/Godeps.json index 9f00907ee08..3dd53ac8e64 100644 --- a/Godeps/Godeps.json +++ b/Godeps/Godeps.json @@ -217,7 +217,7 @@ }, { "ImportPath": "github.com/spf13/cobra", - "Rev": "e1e66f7b4e667751cf530ddb6e72b79d6eeb0235" + "Rev": "07a9dc0024fcc97a0dcb3117bdf8933367037f4e" }, { "ImportPath": "github.com/spf13/pflag", diff --git a/Godeps/_workspace/src/github.com/spf13/cobra/README.md b/Godeps/_workspace/src/github.com/spf13/cobra/README.md index 528233d3874..64c29ef1899 100644 --- a/Godeps/_workspace/src/github.com/spf13/cobra/README.md +++ b/Godeps/_workspace/src/github.com/spf13/cobra/README.md @@ -216,11 +216,11 @@ For a more complete example of a larger application, please checkout [Hugo](http ## The Help Command -Cobra automatically adds a help command to your application. +Cobra automatically adds a help command to your application when you have subcommands. This will be called when a user runs 'app help'. Additionally help will also support all other commands as input. Say for instance you have a command called 'create' without any additional configuration cobra will work when 'app help -create' is called. +create' is called. Every command will automatically have the '--help' flag added. ### Example 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 dd44812c570..5c98a6037a9 100644 --- a/Godeps/_workspace/src/github.com/spf13/cobra/cobra_test.go +++ b/Godeps/_workspace/src/github.com/spf13/cobra/cobra_test.go @@ -461,7 +461,7 @@ func TestRootHelp(t *testing.T) { x := fullSetupTest("--help") checkResultContains(t, x, "Available Commands:") - checkResultContains(t, x, "for more information about that command") + checkResultContains(t, x, "for more information about a command") if strings.Contains(x.Output, "unknown flag: --help") { t.Errorf("--help shouldn't trigger an error, Got: \n %s", x.Output) @@ -470,7 +470,7 @@ func TestRootHelp(t *testing.T) { x = fullSetupTest("echo --help") checkResultContains(t, x, "Available Commands:") - checkResultContains(t, x, "for more information about that command") + checkResultContains(t, x, "for more information about a command") if strings.Contains(x.Output, "unknown flag: --help") { t.Errorf("--help shouldn't trigger an error, Got: \n %s", x.Output) @@ -482,7 +482,7 @@ func TestRootNoCommandHelp(t *testing.T) { x := rootOnlySetupTest("--help") checkResultOmits(t, x, "Available Commands:") - checkResultOmits(t, x, "for more information about that command") + checkResultOmits(t, x, "for more information about a command") if strings.Contains(x.Output, "unknown flag: --help") { t.Errorf("--help shouldn't trigger an error, Got: \n %s", x.Output) @@ -491,7 +491,7 @@ func TestRootNoCommandHelp(t *testing.T) { x = rootOnlySetupTest("echo --help") checkResultOmits(t, x, "Available Commands:") - checkResultOmits(t, x, "for more information about that command") + checkResultOmits(t, x, "for more information about a command") if strings.Contains(x.Output, "unknown flag: --help") { t.Errorf("--help shouldn't trigger an error, Got: \n %s", x.Output) diff --git a/Godeps/_workspace/src/github.com/spf13/cobra/command.go b/Godeps/_workspace/src/github.com/spf13/cobra/command.go index a3a01ad59dc..bf6f3c793e8 100644 --- a/Godeps/_workspace/src/github.com/spf13/cobra/command.go +++ b/Godeps/_workspace/src/github.com/spf13/cobra/command.go @@ -40,9 +40,9 @@ type Command struct { Short string // The long message shown in the 'help ' output. Long string - // Set of flags specific to this command. + // Full set of flags flags *flag.FlagSet - // Set of flags children commands will inherit + // Set of flags childrens of this command will inherit pflags *flag.FlagSet // Run runs the command. // The args are the arguments after the command name. @@ -200,12 +200,14 @@ Aliases: Available Commands: {{range .Commands}}{{if .Runnable}} {{rpad .Use .UsagePadding }} {{.Short}}{{end}}{{end}} {{end}} -{{ if .HasFlags}} Available Flags: -{{.Flags.FlagUsages}}{{end}}{{if .HasParent}}{{if and (gt .Commands 0) (gt .Parent.Commands 1) }} +{{ if .HasLocalFlags}}Flags: +{{.LocalFlags.FlagUsages}}{{end}} +{{ if .HasAnyPersistentFlags}}Global Flags: +{{.AllPersistentFlags.FlagUsages}}{{end}}{{if .HasParent}}{{if and (gt .Commands 0) (gt .Parent.Commands 1) }} Additional help topics: {{if gt .Commands 0 }}{{range .Commands}}{{if not .Runnable}} {{rpad .CommandPath .CommandPathPadding}} {{.Short}}{{end}}{{end}}{{end}}{{if gt .Parent.Commands 1 }}{{range .Parent.Commands}}{{if .Runnable}}{{if not (eq .Name $cmd.Name) }}{{end}} {{rpad .CommandPath .CommandPathPadding}} {{.Short}}{{end}}{{end}}{{end}}{{end}} {{end}}{{ if .HasSubCommands }} -Use "{{.Root.Name}} help [command]" for more information about that command. +Use "{{.Root.Name}} help [command]" for more information about a command. {{end}}` } } @@ -682,7 +684,7 @@ func (c *Command) HasParent() bool { return c.parent != nil } -// Get the Commands FlagSet +// Get the complete FlagSet that applies to this command (local and persistent declared here and by all parents) func (c *Command) Flags() *flag.FlagSet { if c.flags == nil { c.flags = flag.NewFlagSet(c.Name(), flag.ContinueOnError) @@ -695,7 +697,23 @@ func (c *Command) Flags() *flag.FlagSet { return c.flags } -// Get the Commands Persistent FlagSet +// Get the local FlagSet specifically set in the current command +func (c *Command) LocalFlags() *flag.FlagSet { + c.mergePersistentFlags() + + local := flag.NewFlagSet(c.Name(), flag.ContinueOnError) + allPersistent := c.AllPersistentFlags() + + c.Flags().VisitAll(func(f *flag.Flag) { + if allPersistent.Lookup(f.Name) == nil { + local.AddFlag(f) + } + }) + + return local +} + +// Get the Persistent FlagSet specifically set in the current command func (c *Command) PersistentFlags() *flag.FlagSet { if c.pflags == nil { c.pflags = flag.NewFlagSet(c.Name(), flag.ContinueOnError) @@ -707,6 +725,29 @@ func (c *Command) PersistentFlags() *flag.FlagSet { return c.pflags } +// Get the Persistent FlagSet traversing the Command hierarchy +func (c *Command) AllPersistentFlags() *flag.FlagSet { + allPersistent := flag.NewFlagSet(c.Name(), flag.ContinueOnError) + + var visit func(x *Command) + visit = func(x *Command) { + if x.HasPersistentFlags() { + x.PersistentFlags().VisitAll(func(f *flag.Flag) { + if allPersistent.Lookup(f.Name) == nil { + allPersistent.AddFlag(f) + } + }) + } + if x.HasParent() { + visit(x.parent) + } + } + + visit(c) + + return allPersistent +} + // For use in testing func (c *Command) ResetFlags() { c.flagErrorBuf = new(bytes.Buffer) @@ -717,7 +758,7 @@ func (c *Command) ResetFlags() { c.pflags.SetOutput(c.flagErrorBuf) } -// Does the command contain flags (local not persistent) +// Does the command contain any flags (local plus persistent from the entire structure) func (c *Command) HasFlags() bool { return c.Flags().HasFlags() } @@ -727,6 +768,16 @@ func (c *Command) HasPersistentFlags() bool { return c.PersistentFlags().HasFlags() } +// Does the command hierarchy contain persistent flags +func (c *Command) HasAnyPersistentFlags() bool { + return c.AllPersistentFlags().HasFlags() +} + +// Does the command has flags specifically declared locally +func (c *Command) HasLocalFlags() bool { + return c.LocalFlags().HasFlags() +} + // Climbs up the command tree looking for matching flag func (c *Command) Flag(name string) (flag *flag.Flag) { flag = c.Flags().Lookup(name) @@ -766,6 +817,10 @@ func (c *Command) ParseFlags(args []string) (err error) { return nil } +func (c *Command) Parent() *Command { + return c.parent +} + func (c *Command) mergePersistentFlags() { var rmerge func(x *Command) @@ -784,7 +839,3 @@ func (c *Command) mergePersistentFlags() { rmerge(c) } - -func (c *Command) Parent() *Command { - return c.parent -} diff --git a/docs/kubectl.md b/docs/kubectl.md index 354ce068b1f..02580dc8642 100644 --- a/docs/kubectl.md +++ b/docs/kubectl.md @@ -11,12 +11,14 @@ Usage: ``` kubectl version [flags] - Available Flags: +Flags: + -c, --client=false: Client version only (no server required). + +Global Flags: --alsologtostderr=false: log to standard error as well as files --api-version="": The API version to use when talking to the server -a, --auth-path="": Path to the auth info file. If missing, prompt the user. Only used if using https. --certificate-authority="": Path to a cert. file for the certificate authority. - -c, --client=false: Client version only (no server required). --client-certificate="": Path to a client key file for TLS. --client-key="": Path to a client key file for TLS. --cluster="": The name of the kubeconfig cluster to use @@ -47,9 +49,14 @@ Usage: ``` kubectl proxy [flags] - Available Flags: - --alsologtostderr=false: log to standard error as well as files +Flags: --api-prefix="/api/": Prefix to serve the proxied API under. + -p, --port=8001: The port on which to run the proxy. + -w, --www="": Also serve static files from the given directory under the specified prefix. + -P, --www-prefix="/static/": Prefix to serve static files under, if static file directory is specified. + +Global Flags: + --alsologtostderr=false: log to standard error as well as files --api-version="": The API version to use when talking to the server -a, --auth-path="": Path to the auth info file. If missing, prompt the user. Only used if using https. --certificate-authority="": Path to a cert. file for the certificate authority. @@ -66,7 +73,6 @@ Usage: --logtostderr=true: log to standard error instead of files --match-server-version=false: Require server version to match client version --namespace="": If present, the namespace scope for this CLI request. - -p, --port=8001: The port on which to run the proxy. -s, --server="": The address of the Kubernetes API server --stderrthreshold=2: logs at or above this threshold go to stderr --token="": Bearer token for authentication to the API server. @@ -74,8 +80,6 @@ Usage: --v=0: log level for V logs --validate=false: If true, use a schema to validate the input before sending it --vmodule=: comma-separated list of pattern=N settings for file-filtered logging - -w, --www="": Also serve static files from the given directory under the specified prefix. - -P, --www-prefix="/static/": Prefix to serve static files under, if static file directory is specified. ``` @@ -109,7 +113,16 @@ Usage: ``` kubectl get [(-o|--output=)json|yaml|template|...] [] [flags] - Available Flags: +Flags: + --no-headers=false: When using the default output, don't print headers. + -o, --output="": Output format. One of: json|yaml|template|templatefile. + --output-version="": Output the formatted object with the given version (default api-version). + -l, --selector="": Selector (label query) to filter on + -t, --template="": Template string or path to template file to use when -o=template or -o=templatefile. + -w, --watch=false: After listing/getting the requested object, watch for changes. + --watch-only=false: Watch for changes to the requested object(s), without listing/getting first. + +Global Flags: --alsologtostderr=false: log to standard error as well as files --api-version="": The API version to use when talking to the server -a, --auth-path="": Path to the auth info file. If missing, prompt the user. Only used if using https. @@ -127,20 +140,13 @@ Usage: --logtostderr=true: log to standard error instead of files --match-server-version=false: Require server version to match client version --namespace="": If present, the namespace scope for this CLI request. - --no-headers=false: When using the default output, don't print headers. - -o, --output="": Output format. One of: json|yaml|template|templatefile. - --output-version="": Output the formatted object with the given version (default api-version). - -l, --selector="": Selector (label query) to filter on -s, --server="": The address of the Kubernetes API server --stderrthreshold=2: logs at or above this threshold go to stderr - -t, --template="": Template string or path to template file to use when -o=template or -o=templatefile. --token="": Bearer token for authentication to the API server. --user="": The name of the kubeconfig user to use --v=0: log level for V logs --validate=false: If true, use a schema to validate the input before sending it --vmodule=: comma-separated list of pattern=N settings for file-filtered logging - -w, --watch=false: After listing/getting the requested object, watch for changes. - --watch-only=false: Watch for changes to the requested object(s), without listing/getting first. ``` @@ -154,7 +160,8 @@ Usage: ``` kubectl describe [flags] - Available Flags: + +Global Flags: --alsologtostderr=false: log to standard error as well as files --api-version="": The API version to use when talking to the server -a, --auth-path="": Path to the auth info file. If missing, prompt the user. Only used if using https. @@ -163,6 +170,7 @@ Usage: --client-key="": Path to a client key file for TLS. --cluster="": The name of the kubeconfig cluster to use --context="": The name of the kubeconfig context to use + -h, --help=false: help for describe --insecure-skip-tls-verify=false: If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure. --kubeconfig="": Path to the kubeconfig file to use for CLI requests. --log_backtrace_at=:0: when logging hits line file:N, emit a stack trace @@ -198,7 +206,10 @@ Usage: ``` kubectl create -f filename [flags] - Available Flags: +Flags: + -f, --filename=[]: Filename, directory, or URL to file to use to create the resource + +Global Flags: --alsologtostderr=false: log to standard error as well as files --api-version="": The API version to use when talking to the server -a, --auth-path="": Path to the auth info file. If missing, prompt the user. Only used if using https. @@ -207,7 +218,6 @@ Usage: --client-key="": Path to a client key file for TLS. --cluster="": The name of the kubeconfig cluster to use --context="": The name of the kubeconfig context to use - -f, --filename=[]: Filename, directory, or URL to file to use to create the resource -h, --help=false: help for create --insecure-skip-tls-verify=false: If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure. --kubeconfig="": Path to the kubeconfig file to use for CLI requests. @@ -247,7 +257,11 @@ Usage: ``` kubectl update -f filename [flags] - Available Flags: +Flags: + -f, --filename=[]: Filename, directory, or URL to file to use to update the resource. + --patch="": A JSON document to override the existing resource. The resource is downloaded, patched with the JSON, then updated. + +Global Flags: --alsologtostderr=false: log to standard error as well as files --api-version="": The API version to use when talking to the server -a, --auth-path="": Path to the auth info file. If missing, prompt the user. Only used if using https. @@ -256,7 +270,6 @@ Usage: --client-key="": Path to a client key file for TLS. --cluster="": The name of the kubeconfig cluster to use --context="": The name of the kubeconfig context to use - -f, --filename=[]: Filename, directory, or URL to file to use to update the resource. -h, --help=false: help for update --insecure-skip-tls-verify=false: If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure. --kubeconfig="": Path to the kubeconfig file to use for CLI requests. @@ -266,7 +279,6 @@ Usage: --logtostderr=true: log to standard error instead of files --match-server-version=false: Require server version to match client version --namespace="": If present, the namespace scope for this CLI request. - --patch="": A JSON document to override the existing resource. The resource is downloaded, patched with the JSON, then updated. -s, --server="": The address of the Kubernetes API server --stderrthreshold=2: logs at or above this threshold go to stderr --token="": Bearer token for authentication to the API server. @@ -307,7 +319,11 @@ Usage: ``` kubectl delete ([-f filename] | ( [( | -l