Merge pull request #53631 from dixudx/enforce_cobra_required_flags

Automatic merge from submit-queue. If you want to cherry-pick this change to another branch, please follow the instructions <a href="https://github.com/kubernetes/community/blob/master/contributors/devel/cherry-picks.md">here</a>.

update vendor spf13/cobra to enforce required flags

**What this PR does / why we need it**:

spf13/cobra#502 has enforced checking flags that marked as required, an error will be raised if unset.

**Which issue this PR fixes** *(optional, in `fixes #<issue number>(, fixes #<issue_number>, ...)` format, will close that issue when PR gets merged)*:fixes #54855
xref #48400
fixes kubernetes/kubectl#121 

**Special notes for your reviewer**:
/assign @liggitt @eparis 

**Release note**:

```release-note
kubectl now enforces required flags at a more fundamental level
```
This commit is contained in:
Kubernetes Submit Queue 2018-01-18 02:00:27 -08:00 committed by GitHub
commit 048757b8a5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
117 changed files with 2544 additions and 1503 deletions

6
Godeps/Godeps.json generated
View File

@ -2568,11 +2568,11 @@
},
{
"ImportPath": "github.com/spf13/cobra",
"Rev": "f62e98d28ab7ad31d707ba837a966378465c7b57"
"Rev": "19e54c4a2b8a78c9d54b2bed61b1a6c5e1bfcf6f"
},
{
"ImportPath": "github.com/spf13/cobra/doc",
"Rev": "f62e98d28ab7ad31d707ba837a966378465c7b57"
"Rev": "19e54c4a2b8a78c9d54b2bed61b1a6c5e1bfcf6f"
},
{
"ImportPath": "github.com/spf13/jwalterweatherman",
@ -2580,7 +2580,7 @@
},
{
"ImportPath": "github.com/spf13/pflag",
"Rev": "9ff6c6923cfffbcd502984b8e0c80539a94968b7"
"Rev": "4c012f6dcd9546820e378d0bdda4d8fc772cdfea"
},
{
"ImportPath": "github.com/spf13/viper",

View File

@ -27,7 +27,7 @@ import (
// MarkdownPostProcessing goes though the generated files
func MarkdownPostProcessing(cmd *cobra.Command, dir string, processor func(string) string) error {
for _, c := range cmd.Commands() {
if !c.IsAvailableCommand() || c.IsHelpCommand() {
if !c.IsAvailableCommand() || c.IsAdditionalHelpTopicCommand() {
continue
}
if err := MarkdownPostProcessing(c, dir, processor); err != nil {

View File

@ -111,7 +111,7 @@ func NewCmdJoin(out io.Writer) *cobra.Command {
var ignorePreflightErrors []string
cmd := &cobra.Command{
Use: "join [flags]",
Use: "join",
Short: "Run this on any machine you wish to join an existing cluster",
Long: joinLongDescription,
Run: func(cmd *cobra.Command, args []string) {

View File

@ -102,7 +102,8 @@ func NewCmdToken(out io.Writer, errW io.Writer) *cobra.Command {
var description string
var printJoinCommand bool
createCmd := &cobra.Command{
Use: "create [token]",
Use: "create [token]",
DisableFlagsInUseLine: true,
Short: "Create bootstrap tokens on the server.",
Long: dedent.Dedent(`
This command will create a bootstrap token for you.
@ -156,7 +157,8 @@ func NewCmdToken(out io.Writer, errW io.Writer) *cobra.Command {
tokenCmd.AddCommand(listCmd)
deleteCmd := &cobra.Command{
Use: "delete [token-value]",
Use: "delete [token-value]",
DisableFlagsInUseLine: true,
Short: "Delete bootstrap tokens on the server.",
Long: dedent.Dedent(`
This command will delete a given bootstrap token for you.

View File

@ -69,7 +69,8 @@ func NewCmdApply(parentFlags *cmdUpgradeFlags) *cobra.Command {
}
cmd := &cobra.Command{
Use: "apply [version]",
Use: "apply [version]",
DisableFlagsInUseLine: true,
Short: "Upgrade your Kubernetes cluster to the specified version.",
Run: func(cmd *cobra.Command, args []string) {
var err error

View File

@ -113,7 +113,8 @@ func NewCmdAnnotate(f cmdutil.Factory, out io.Writer) *cobra.Command {
}
cmd := &cobra.Command{
Use: "annotate [--overwrite] (-f FILENAME | TYPE NAME) KEY_1=VAL_1 ... KEY_N=VAL_N [--resource-version=version]",
Use: "annotate [--overwrite] (-f FILENAME | TYPE NAME) KEY_1=VAL_1 ... KEY_N=VAL_N [--resource-version=version]",
DisableFlagsInUseLine: true,
Short: i18n.T("Update the annotations on a resource"),
Long: annotateLong + "\n\n" + cmdutil.ValidResourceTypeList(f),
Example: annotateExample,

View File

@ -105,7 +105,8 @@ func NewCmdApply(baseName string, f cmdutil.Factory, out, errOut io.Writer) *cob
options.cmdBaseName = baseName
cmd := &cobra.Command{
Use: "apply -f FILENAME",
Use: "apply -f FILENAME",
DisableFlagsInUseLine: true,
Short: i18n.T("Apply a configuration to a resource by filename or stdin"),
Long: applyLong,
Example: applyExample,

View File

@ -76,7 +76,8 @@ func NewCmdApplyEditLastApplied(f cmdutil.Factory, out, errOut io.Writer) *cobra
}
cmd := &cobra.Command{
Use: "edit-last-applied (RESOURCE/NAME | -f FILENAME)",
Use: "edit-last-applied (RESOURCE/NAME | -f FILENAME)",
DisableFlagsInUseLine: true,
Short: "Edit latest last-applied-configuration annotations of a resource/object",
Long: applyEditLastAppliedLong,
Example: applyEditLastAppliedExample,

View File

@ -84,7 +84,8 @@ var (
func NewCmdApplySetLastApplied(f cmdutil.Factory, out, err io.Writer) *cobra.Command {
options := &SetLastAppliedOptions{Out: out, ErrOut: err}
cmd := &cobra.Command{
Use: "set-last-applied -f FILENAME",
Use: "set-last-applied -f FILENAME",
DisableFlagsInUseLine: true,
Short: i18n.T("Set the last-applied-configuration annotation on a live object to match the contents of a file."),
Long: applySetLastAppliedLong,
Example: applySetLastAppliedExample,

View File

@ -60,7 +60,8 @@ var (
func NewCmdApplyViewLastApplied(f cmdutil.Factory, out, err io.Writer) *cobra.Command {
options := &ViewLastAppliedOptions{Out: out, ErrOut: err}
cmd := &cobra.Command{
Use: "view-last-applied (TYPE [NAME | -l label] | TYPE/NAME | -f FILENAME)",
Use: "view-last-applied (TYPE [NAME | -l label] | TYPE/NAME | -f FILENAME)",
DisableFlagsInUseLine: true,
Short: i18n.T("View latest last-applied-configuration annotations of a resource/object"),
Long: applyViewLastAppliedLong,
Example: applyViewLastAppliedExample,

View File

@ -71,7 +71,8 @@ func NewCmdAttach(f cmdutil.Factory, cmdIn io.Reader, cmdOut, cmdErr io.Writer)
Attach: &DefaultRemoteAttach{},
}
cmd := &cobra.Command{
Use: "attach (POD | TYPE/NAME) -c CONTAINER",
Use: "attach (POD | TYPE/NAME) -c CONTAINER",
DisableFlagsInUseLine: true,
Short: i18n.T("Attach to a running container"),
Long: "Attach to a process that is already running inside an existing container.",
Example: attachExample,

View File

@ -88,7 +88,8 @@ func NewCmdCanI(f cmdutil.Factory, out, err io.Writer) *cobra.Command {
}
cmd := &cobra.Command{
Use: "can-i VERB [TYPE | TYPE/NAME | NONRESOURCEURL]",
Use: "can-i VERB [TYPE | TYPE/NAME | NONRESOURCEURL]",
DisableFlagsInUseLine: true,
Short: "Check whether an action is allowed",
Long: canILong,
Example: canIExample,

View File

@ -64,7 +64,8 @@ func NewCmdReconcile(f cmdutil.Factory, out, err io.Writer) *cobra.Command {
}
cmd := &cobra.Command{
Use: "reconcile -f FILENAME",
Use: "reconcile -f FILENAME",
DisableFlagsInUseLine: true,
Short: "Reconciles rules for RBAC Role, RoleBinding, ClusterRole, and ClusterRole binding objects",
Long: reconcileLong,
Example: reconcileExample,

View File

@ -52,7 +52,8 @@ func NewCmdAutoscale(f cmdutil.Factory, out io.Writer) *cobra.Command {
argAliases := kubectl.ResourceAliases(validArgs)
cmd := &cobra.Command{
Use: "autoscale (-f FILENAME | TYPE NAME | TYPE/NAME) [--min=MINPODS] --max=MAXPODS [--cpu-percent=CPU] [flags]",
Use: "autoscale (-f FILENAME | TYPE NAME | TYPE/NAME) [--min=MINPODS] --max=MAXPODS [--cpu-percent=CPU]",
DisableFlagsInUseLine: true,
Short: i18n.T("Auto-scale a Deployment, ReplicaSet, or ReplicationController"),
Long: autoscaleLong,
Example: autoscaleExample,

View File

@ -32,7 +32,8 @@ import (
func NewCmdCertificate(f cmdutil.Factory, out io.Writer) *cobra.Command {
cmd := &cobra.Command{
Use: "certificate SUBCOMMAND",
Use: "certificate SUBCOMMAND",
DisableFlagsInUseLine: true,
Short: i18n.T("Modify certificate resources."),
Long: "Modify certificate resources.",
Run: func(cmd *cobra.Command, args []string) {
@ -68,7 +69,8 @@ func (options *CertificateOptions) Validate() error {
func NewCmdCertificateApprove(f cmdutil.Factory, out io.Writer) *cobra.Command {
options := CertificateOptions{}
cmd := &cobra.Command{
Use: "approve (-f FILENAME | NAME)",
Use: "approve (-f FILENAME | NAME)",
DisableFlagsInUseLine: true,
Short: i18n.T("Approve a certificate signing request"),
Long: templates.LongDesc(`
Approve a certificate signing request.
@ -118,7 +120,8 @@ func (options *CertificateOptions) RunCertificateApprove(f cmdutil.Factory, out
func NewCmdCertificateDeny(f cmdutil.Factory, out io.Writer) *cobra.Command {
options := CertificateOptions{}
cmd := &cobra.Command{
Use: "deny (-f FILENAME | NAME)",
Use: "deny (-f FILENAME | NAME)",
DisableFlagsInUseLine: true,
Short: i18n.T("Deny a certificate signing request"),
Long: templates.LongDesc(`
Deny a certificate signing request.

View File

@ -97,7 +97,8 @@ func NewCmdCompletion(out io.Writer, boilerPlate string) *cobra.Command {
}
cmd := &cobra.Command{
Use: "completion SHELL",
Use: "completion SHELL",
DisableFlagsInUseLine: true,
Short: i18n.T("Output shell completion code for the specified shell (bash or zsh)"),
Long: completion_long,
Example: completion_example,

View File

@ -37,7 +37,8 @@ func NewCmdConfig(f cmdutil.Factory, pathOptions *clientcmd.PathOptions, out, er
}
cmd := &cobra.Command{
Use: "config SUBCOMMAND",
Use: "config SUBCOMMAND",
DisableFlagsInUseLine: true,
Short: i18n.T("Modify kubeconfig files"),
Long: templates.LongDesc(`
Modify kubeconfig files using subcommands like "kubectl config set current-context my-context"

View File

@ -100,7 +100,8 @@ func NewCmdConfigSetAuthInfo(out io.Writer, configAccess clientcmd.ConfigAccess)
func newCmdConfigSetAuthInfo(out io.Writer, options *createAuthInfoOptions) *cobra.Command {
cmd := &cobra.Command{
Use: fmt.Sprintf("set-credentials NAME [--%v=path/to/certfile] [--%v=path/to/keyfile] [--%v=bearer_token] [--%v=basic_user] [--%v=basic_password] [--%v=provider_name] [--%v=key=value]", clientcmd.FlagCertFile, clientcmd.FlagKeyFile, clientcmd.FlagBearerToken, clientcmd.FlagUsername, clientcmd.FlagPassword, flagAuthProvider, flagAuthProviderArg),
Use: fmt.Sprintf("set-credentials NAME [--%v=path/to/certfile] [--%v=path/to/keyfile] [--%v=bearer_token] [--%v=basic_user] [--%v=basic_password] [--%v=provider_name] [--%v=key=value]", clientcmd.FlagCertFile, clientcmd.FlagKeyFile, clientcmd.FlagBearerToken, clientcmd.FlagUsername, clientcmd.FlagPassword, flagAuthProvider, flagAuthProviderArg),
DisableFlagsInUseLine: true,
Short: i18n.T("Sets a user entry in kubeconfig"),
Long: create_authinfo_long,
Example: create_authinfo_example,

View File

@ -63,7 +63,8 @@ func NewCmdConfigSetCluster(out io.Writer, configAccess clientcmd.ConfigAccess)
options := &createClusterOptions{configAccess: configAccess}
cmd := &cobra.Command{
Use: fmt.Sprintf("set-cluster NAME [--%v=server] [--%v=path/to/certificate/authority] [--%v=true]", clientcmd.FlagAPIServer, clientcmd.FlagCAFile, clientcmd.FlagInsecure),
Use: fmt.Sprintf("set-cluster NAME [--%v=server] [--%v=path/to/certificate/authority] [--%v=true]", clientcmd.FlagAPIServer, clientcmd.FlagCAFile, clientcmd.FlagInsecure),
DisableFlagsInUseLine: true,
Short: i18n.T("Sets a cluster entry in kubeconfig"),
Long: create_cluster_long,
Example: create_cluster_example,

View File

@ -54,7 +54,8 @@ func NewCmdConfigSetContext(out io.Writer, configAccess clientcmd.ConfigAccess)
options := &createContextOptions{configAccess: configAccess}
cmd := &cobra.Command{
Use: fmt.Sprintf("set-context NAME [--%v=cluster_nickname] [--%v=user_nickname] [--%v=namespace]", clientcmd.FlagClusterName, clientcmd.FlagAuthInfoName, clientcmd.FlagNamespace),
Use: fmt.Sprintf("set-context NAME [--%v=cluster_nickname] [--%v=user_nickname] [--%v=namespace]", clientcmd.FlagClusterName, clientcmd.FlagAuthInfoName, clientcmd.FlagNamespace),
DisableFlagsInUseLine: true,
Short: i18n.T("Sets a context entry in kubeconfig"),
Long: create_context_long,
Example: create_context_example,

View File

@ -35,7 +35,8 @@ var (
func NewCmdConfigDeleteCluster(out io.Writer, configAccess clientcmd.ConfigAccess) *cobra.Command {
cmd := &cobra.Command{
Use: "delete-cluster NAME",
Use: "delete-cluster NAME",
DisableFlagsInUseLine: true,
Short: i18n.T("Delete the specified cluster from the kubeconfig"),
Long: "Delete the specified cluster from the kubeconfig",
Example: delete_cluster_example,

View File

@ -35,7 +35,8 @@ var (
func NewCmdConfigDeleteContext(out, errOut io.Writer, configAccess clientcmd.ConfigAccess) *cobra.Command {
cmd := &cobra.Command{
Use: "delete-context NAME",
Use: "delete-context NAME",
DisableFlagsInUseLine: true,
Short: i18n.T("Delete the specified context from the kubeconfig"),
Long: "Delete the specified context from the kubeconfig",
Example: delete_context_example,

View File

@ -61,7 +61,8 @@ func NewCmdConfigGetContexts(out io.Writer, configAccess clientcmd.ConfigAccess)
options := &GetContextsOptions{configAccess: configAccess}
cmd := &cobra.Command{
Use: "get-contexts [(-o|--output=)name)]",
Use: "get-contexts [(-o|--output=)name)]",
DisableFlagsInUseLine: true,
Short: i18n.T("Describe one or many contexts"),
Long: getContextsLong,
Example: getContextsExample,

View File

@ -61,7 +61,8 @@ func NewCmdConfigRenameContext(out io.Writer, configAccess clientcmd.ConfigAcces
options := &RenameContextOptions{configAccess: configAccess}
cmd := &cobra.Command{
Use: renameContextUse,
Use: renameContextUse,
DisableFlagsInUseLine: true,
Short: renameContextShort,
Long: renameContextLong,
Example: renameContextExample,

View File

@ -56,7 +56,8 @@ func NewCmdConfigSet(out io.Writer, configAccess clientcmd.ConfigAccess) *cobra.
options := &setOptions{configAccess: configAccess}
cmd := &cobra.Command{
Use: "set PROPERTY_NAME PROPERTY_VALUE",
Use: "set PROPERTY_NAME PROPERTY_VALUE",
DisableFlagsInUseLine: true,
Short: i18n.T("Sets an individual value in a kubeconfig file"),
Long: set_long,
Run: func(cmd *cobra.Command, args []string) {

View File

@ -44,7 +44,8 @@ func NewCmdConfigUnset(out io.Writer, configAccess clientcmd.ConfigAccess) *cobr
options := &unsetOptions{configAccess: configAccess}
cmd := &cobra.Command{
Use: "unset PROPERTY_NAME",
Use: "unset PROPERTY_NAME",
DisableFlagsInUseLine: true,
Short: i18n.T("Unsets an individual value in a kubeconfig file"),
Long: unset_long,
Run: func(cmd *cobra.Command, args []string) {

View File

@ -45,7 +45,8 @@ func NewCmdConfigUseContext(out io.Writer, configAccess clientcmd.ConfigAccess)
options := &useContextOptions{configAccess: configAccess}
cmd := &cobra.Command{
Use: "use-context CONTEXT_NAME",
Use: "use-context CONTEXT_NAME",
DisableFlagsInUseLine: true,
Short: i18n.T("Sets the current-context in a kubeconfig file"),
Aliases: []string{"use"},
Long: `Sets the current-context in a kubeconfig file`,

View File

@ -65,7 +65,8 @@ func NewCmdConvert(f cmdutil.Factory, out io.Writer) *cobra.Command {
options := &ConvertOptions{}
cmd := &cobra.Command{
Use: "convert -f FILENAME",
Use: "convert -f FILENAME",
DisableFlagsInUseLine: true,
Short: i18n.T("Convert config files between different API versions"),
Long: convert_long,
Example: convert_example,

View File

@ -64,7 +64,8 @@ var (
// NewCmdCp creates a new Copy command.
func NewCmdCp(f cmdutil.Factory, cmdOut, cmdErr io.Writer) *cobra.Command {
cmd := &cobra.Command{
Use: "cp <file-spec-src> <file-spec-dest>",
Use: "cp <file-spec-src> <file-spec-dest>",
DisableFlagsInUseLine: true,
Short: i18n.T("Copy files and directories to and from containers."),
Long: "Copy files and directories to and from containers.",
Example: cpExample,

View File

@ -65,7 +65,8 @@ func NewCmdCreate(f cmdutil.Factory, out, errOut io.Writer) *cobra.Command {
var options CreateOptions
cmd := &cobra.Command{
Use: "create -f FILENAME",
Use: "create -f FILENAME",
DisableFlagsInUseLine: true,
Short: i18n.T("Create a resource from a file or from stdin."),
Long: createLong,
Example: createExample,

View File

@ -66,7 +66,8 @@ func NewCmdCreateClusterRole(f cmdutil.Factory, cmdOut io.Writer) *cobra.Command
},
}
cmd := &cobra.Command{
Use: "clusterrole NAME --verb=verb --resource=resource.group [--resource-name=resourcename] [--dry-run]",
Use: "clusterrole NAME --verb=verb --resource=resource.group [--resource-name=resourcename] [--dry-run]",
DisableFlagsInUseLine: true,
Short: clusterRoleLong,
Long: clusterRoleLong,
Example: clusterRoleExample,

View File

@ -39,7 +39,8 @@ var (
// ClusterRoleBinding is a command to ease creating ClusterRoleBindings.
func NewCmdCreateClusterRoleBinding(f cmdutil.Factory, cmdOut io.Writer) *cobra.Command {
cmd := &cobra.Command{
Use: "clusterrolebinding NAME --clusterrole=NAME [--user=username] [--group=groupname] [--serviceaccount=namespace:serviceaccountname] [--dry-run]",
Use: "clusterrolebinding NAME --clusterrole=NAME [--user=username] [--group=groupname] [--serviceaccount=namespace:serviceaccountname] [--dry-run]",
DisableFlagsInUseLine: true,
Short: i18n.T("Create a ClusterRoleBinding for a particular ClusterRole"),
Long: clusterRoleBindingLong,
Example: clusterRoleBindingExample,

View File

@ -60,11 +60,12 @@ var (
// ConfigMap is a command to ease creating ConfigMaps.
func NewCmdCreateConfigMap(f cmdutil.Factory, cmdOut io.Writer) *cobra.Command {
cmd := &cobra.Command{
Use: "configmap NAME [--from-file=[key=]source] [--from-literal=key1=value1] [--dry-run]",
Aliases: []string{"cm"},
Short: i18n.T("Create a configmap from a local file, directory or literal value"),
Long: configMapLong,
Example: configMapExample,
Use: "configmap NAME [--from-file=[key=]source] [--from-literal=key1=value1] [--dry-run]",
DisableFlagsInUseLine: true,
Aliases: []string{"cm"},
Short: i18n.T("Create a configmap from a local file, directory or literal value"),
Long: configMapLong,
Example: configMapExample,
Run: func(cmd *cobra.Command, args []string) {
err := CreateConfigMap(f, cmdOut, cmd, args)
cmdutil.CheckErr(err)

View File

@ -41,11 +41,12 @@ var (
// Note that this command overlaps significantly with the `kubectl run` command.
func NewCmdCreateDeployment(f cmdutil.Factory, cmdOut, cmdErr io.Writer) *cobra.Command {
cmd := &cobra.Command{
Use: "deployment NAME --image=image [--dry-run]",
Aliases: []string{"deploy"},
Short: i18n.T("Create a deployment with the specified name."),
Long: deploymentLong,
Example: deploymentExample,
Use: "deployment NAME --image=image [--dry-run]",
DisableFlagsInUseLine: true,
Aliases: []string{"deploy"},
Short: i18n.T("Create a deployment with the specified name."),
Long: deploymentLong,
Example: deploymentExample,
Run: func(cmd *cobra.Command, args []string) {
err := createDeployment(f, cmdOut, cmdErr, cmd, args)
cmdutil.CheckErr(err)

View File

@ -39,11 +39,12 @@ var (
// NewCmdCreateNamespace is a macro command to create a new namespace
func NewCmdCreateNamespace(f cmdutil.Factory, cmdOut io.Writer) *cobra.Command {
cmd := &cobra.Command{
Use: "namespace NAME [--dry-run]",
Aliases: []string{"ns"},
Short: i18n.T("Create a namespace with the specified name"),
Long: namespaceLong,
Example: namespaceExample,
Use: "namespace NAME [--dry-run]",
DisableFlagsInUseLine: true,
Aliases: []string{"ns"},
Short: i18n.T("Create a namespace with the specified name"),
Long: namespaceLong,
Example: namespaceExample,
Run: func(cmd *cobra.Command, args []string) {
err := CreateNamespace(f, cmdOut, cmd, args)
cmdutil.CheckErr(err)

View File

@ -44,11 +44,12 @@ var (
// NewCmdCreatePodDisruptionBudget is a macro command to create a new pod disruption budget.
func NewCmdCreatePodDisruptionBudget(f cmdutil.Factory, cmdOut io.Writer) *cobra.Command {
cmd := &cobra.Command{
Use: "poddisruptionbudget NAME --selector=SELECTOR --min-available=N [--dry-run]",
Aliases: []string{"pdb"},
Short: i18n.T("Create a pod disruption budget with the specified name."),
Long: pdbLong,
Example: pdbExample,
Use: "poddisruptionbudget NAME --selector=SELECTOR --min-available=N [--dry-run]",
DisableFlagsInUseLine: true,
Aliases: []string{"pdb"},
Short: i18n.T("Create a pod disruption budget with the specified name."),
Long: pdbLong,
Example: pdbExample,
Run: func(cmd *cobra.Command, args []string) {
err := CreatePodDisruptionBudget(f, cmdOut, cmd, args)
cmdutil.CheckErr(err)

View File

@ -42,11 +42,12 @@ var (
// NewCmdCreatePriorityClass is a macro command to create a new priorityClass.
func NewCmdCreatePriorityClass(f cmdutil.Factory, cmdOut io.Writer) *cobra.Command {
cmd := &cobra.Command{
Use: "priorityclass NAME --value=VALUE --global-default=BOOL [--dry-run]",
Aliases: []string{"pc"},
Short: i18n.T("Create a priorityclass with the specified name."),
Long: pcLong,
Example: pcExample,
Use: "priorityclass NAME --value=VALUE --global-default=BOOL [--dry-run]",
DisableFlagsInUseLine: true,
Aliases: []string{"pc"},
Short: i18n.T("Create a priorityclass with the specified name."),
Long: pcLong,
Example: pcExample,
Run: func(cmd *cobra.Command, args []string) {
cmdutil.CheckErr(CreatePriorityClass(f, cmdOut, cmd, args))
},

View File

@ -42,11 +42,12 @@ var (
// NewCmdCreateQuota is a macro command to create a new quota
func NewCmdCreateQuota(f cmdutil.Factory, cmdOut io.Writer) *cobra.Command {
cmd := &cobra.Command{
Use: "quota NAME [--hard=key1=value1,key2=value2] [--scopes=Scope1,Scope2] [--dry-run=bool]",
Aliases: []string{"resourcequota"},
Short: i18n.T("Create a quota with the specified name."),
Long: quotaLong,
Example: quotaExample,
Use: "quota NAME [--hard=key1=value1,key2=value2] [--scopes=Scope1,Scope2] [--dry-run=bool]",
DisableFlagsInUseLine: true,
Aliases: []string{"resourcequota"},
Short: i18n.T("Create a quota with the specified name."),
Long: quotaLong,
Example: quotaExample,
Run: func(cmd *cobra.Command, args []string) {
err := CreateQuota(f, cmdOut, cmd, args)
cmdutil.CheckErr(err)

View File

@ -121,7 +121,8 @@ func NewCmdCreateRole(f cmdutil.Factory, cmdOut io.Writer) *cobra.Command {
Out: cmdOut,
}
cmd := &cobra.Command{
Use: "role NAME --verb=verb --resource=resource.group/subresource [--resource-name=resourcename] [--dry-run]",
Use: "role NAME --verb=verb --resource=resource.group/subresource [--resource-name=resourcename] [--dry-run]",
DisableFlagsInUseLine: true,
Short: roleLong,
Long: roleLong,
Example: roleExample,

View File

@ -39,7 +39,8 @@ var (
// RoleBinding is a command to ease creating RoleBindings.
func NewCmdCreateRoleBinding(f cmdutil.Factory, cmdOut io.Writer) *cobra.Command {
cmd := &cobra.Command{
Use: "rolebinding NAME --clusterrole=NAME|--role=NAME [--user=username] [--group=groupname] [--serviceaccount=namespace:serviceaccountname] [--dry-run]",
Use: "rolebinding NAME --clusterrole=NAME|--role=NAME [--user=username] [--group=groupname] [--serviceaccount=namespace:serviceaccountname] [--dry-run]",
DisableFlagsInUseLine: true,
Short: i18n.T("Create a RoleBinding for a particular Role or ClusterRole"),
Long: roleBindingLong,
Example: roleBindingExample,

View File

@ -76,7 +76,8 @@ var (
// NewCmdCreateSecretGeneric is a command to create generic secrets from files, directories, or literal values
func NewCmdCreateSecretGeneric(f cmdutil.Factory, cmdOut io.Writer) *cobra.Command {
cmd := &cobra.Command{
Use: "generic NAME [--type=string] [--from-file=[key=]source] [--from-literal=key1=value1] [--dry-run]",
Use: "generic NAME [--type=string] [--from-file=[key=]source] [--from-literal=key1=value1] [--dry-run]",
DisableFlagsInUseLine: true,
Short: i18n.T("Create a secret from a local file, directory or literal value"),
Long: secretLong,
Example: secretExample,
@ -149,7 +150,8 @@ var (
// NewCmdCreateSecretDockerRegistry is a macro command for creating secrets to work with Docker registries
func NewCmdCreateSecretDockerRegistry(f cmdutil.Factory, cmdOut io.Writer) *cobra.Command {
cmd := &cobra.Command{
Use: "docker-registry NAME --docker-username=user --docker-password=password --docker-email=email [--docker-server=string] [--from-literal=key1=value1] [--dry-run]",
Use: "docker-registry NAME --docker-username=user --docker-password=password --docker-email=email [--docker-server=string] [--from-literal=key1=value1] [--dry-run]",
DisableFlagsInUseLine: true,
Short: i18n.T("Create a secret for use with a Docker registry"),
Long: secretForDockerRegistryLong,
Example: secretForDockerRegistryExample,
@ -223,7 +225,8 @@ var (
// NewCmdCreateSecretTLS is a macro command for creating secrets to work with Docker registries
func NewCmdCreateSecretTLS(f cmdutil.Factory, cmdOut io.Writer) *cobra.Command {
cmd := &cobra.Command{
Use: "tls NAME --cert=path/to/cert/file --key=path/to/key/file [--dry-run]",
Use: "tls NAME --cert=path/to/cert/file --key=path/to/key/file [--dry-run]",
DisableFlagsInUseLine: true,
Short: i18n.T("Create a TLS secret"),
Long: secretForTLSLong,
Example: secretForTLSExample,

View File

@ -64,7 +64,8 @@ func addPortFlags(cmd *cobra.Command) {
// NewCmdCreateServiceClusterIP is a command to create a ClusterIP service
func NewCmdCreateServiceClusterIP(f cmdutil.Factory, cmdOut io.Writer) *cobra.Command {
cmd := &cobra.Command{
Use: "clusterip NAME [--tcp=<port>:<targetPort>] [--dry-run]",
Use: "clusterip NAME [--tcp=<port>:<targetPort>] [--dry-run]",
DisableFlagsInUseLine: true,
Short: i18n.T("Create a ClusterIP service."),
Long: serviceClusterIPLong,
Example: serviceClusterIPExample,
@ -124,7 +125,8 @@ var (
// NewCmdCreateServiceNodePort is a macro command for creating a NodePort service
func NewCmdCreateServiceNodePort(f cmdutil.Factory, cmdOut io.Writer) *cobra.Command {
cmd := &cobra.Command{
Use: "nodeport NAME [--tcp=port:targetPort] [--dry-run]",
Use: "nodeport NAME [--tcp=port:targetPort] [--dry-run]",
DisableFlagsInUseLine: true,
Short: i18n.T("Create a NodePort service."),
Long: serviceNodePortLong,
Example: serviceNodePortExample,
@ -181,7 +183,8 @@ var (
// NewCmdCreateServiceLoadBalancer is a macro command for creating a LoadBalancer service
func NewCmdCreateServiceLoadBalancer(f cmdutil.Factory, cmdOut io.Writer) *cobra.Command {
cmd := &cobra.Command{
Use: "loadbalancer NAME [--tcp=port:targetPort] [--dry-run]",
Use: "loadbalancer NAME [--tcp=port:targetPort] [--dry-run]",
DisableFlagsInUseLine: true,
Short: i18n.T("Create a LoadBalancer service."),
Long: serviceLoadBalancerLong,
Example: serviceLoadBalancerExample,
@ -240,7 +243,8 @@ var (
// NewCmdCreateServiceExternalName is a macro command for creating an ExternalName service
func NewCmdCreateServiceExternalName(f cmdutil.Factory, cmdOut io.Writer) *cobra.Command {
cmd := &cobra.Command{
Use: "externalname NAME --external-name external.name [--dry-run]",
Use: "externalname NAME --external-name external.name [--dry-run]",
DisableFlagsInUseLine: true,
Short: i18n.T("Create an ExternalName service."),
Long: serviceExternalNameLong,
Example: serviceExternalNameExample,

View File

@ -39,11 +39,12 @@ var (
// NewCmdCreateServiceAccount is a macro command to create a new service account
func NewCmdCreateServiceAccount(f cmdutil.Factory, cmdOut io.Writer) *cobra.Command {
cmd := &cobra.Command{
Use: "serviceaccount NAME [--dry-run]",
Aliases: []string{"sa"},
Short: i18n.T("Create a service account with the specified name"),
Long: serviceAccountLong,
Example: serviceAccountExample,
Use: "serviceaccount NAME [--dry-run]",
DisableFlagsInUseLine: true,
Aliases: []string{"sa"},
Short: i18n.T("Create a service account with the specified name"),
Long: serviceAccountLong,
Example: serviceAccountExample,
Run: func(cmd *cobra.Command, args []string) {
err := CreateServiceAccount(f, cmdOut, cmd, args)
cmdutil.CheckErr(err)

View File

@ -127,7 +127,8 @@ func NewCmdDelete(f cmdutil.Factory, out, errOut io.Writer) *cobra.Command {
}
cmd := &cobra.Command{
Use: "delete ([-f FILENAME] | TYPE [(NAME | -l label | --all)])",
Use: "delete ([-f FILENAME] | TYPE [(NAME | -l label | --all)])",
DisableFlagsInUseLine: true,
Short: i18n.T("Delete resources by filenames, stdin, resources and names, or by resources and label selector"),
Long: delete_long,
Example: delete_example,

View File

@ -44,6 +44,7 @@ var unstructuredSerializer = dynamic.ContentConfig().NegotiatedSerializer
var fakecmd = &cobra.Command{
Use: "delete ([-f FILENAME] | TYPE [(NAME | -l label | --all)])",
DisableFlagsInUseLine: true,
Run: func(cmd *cobra.Command, args []string) {
cmdutil.CheckErr(cmdutil.ValidateOutputArgs(cmd))
},

View File

@ -79,7 +79,8 @@ func NewCmdDescribe(f cmdutil.Factory, out, cmdErr io.Writer) *cobra.Command {
argAliases := kubectl.ResourceAliases(validArgs)
cmd := &cobra.Command{
Use: "describe (-f FILENAME | TYPE [NAME_PREFIX | -l label] | TYPE/NAME)",
Use: "describe (-f FILENAME | TYPE [NAME_PREFIX | -l label] | TYPE/NAME)",
DisableFlagsInUseLine: true,
Short: i18n.T("Show details of a specific resource or group of resources"),
Long: describeLong + "\n\n" + cmdutil.ValidResourceTypeList(f),
Example: describeExample,

View File

@ -20,6 +20,7 @@ import (
"bytes"
"fmt"
"net/http"
"strings"
"testing"
"k8s.io/client-go/rest/fake"
@ -168,3 +169,30 @@ func TestDescribeObjectSkipEvents(t *testing.T) {
t.Errorf("ShowEvents = false expected, got ShowEvents = %v", d.Settings.ShowEvents)
}
}
func TestDescribeHelpMessage(t *testing.T) {
f, _, _, _ := cmdtesting.NewAPIFactory()
buf := bytes.NewBuffer([]byte{})
buferr := bytes.NewBuffer([]byte{})
cmd := NewCmdDescribe(f, buf, buferr)
cmd.SetArgs([]string{"-h"})
cmd.SetOutput(buf)
_, err := cmd.ExecuteC()
if err != nil {
t.Fatalf("Unexpected error: %v", err)
}
got := buf.String()
expected := `describe (-f FILENAME | TYPE [NAME_PREFIX | -l label] | TYPE/NAME)`
if !strings.Contains(got, expected) {
t.Errorf("Expected to contain: \n %v\nGot:\n %v\n", expected, got)
}
unexpected := `describe (-f FILENAME | TYPE [NAME_PREFIX | -l label] | TYPE/NAME) [flags]`
if strings.Contains(got, unexpected) {
t.Errorf("Expected not to contain: \n %v\nGot:\n %v\n", unexpected, got)
}
}

View File

@ -109,7 +109,8 @@ func NewCmdDiff(f cmdutil.Factory, stdout, stderr io.Writer) *cobra.Command {
Stderr: stderr,
}
cmd := &cobra.Command{
Use: "diff -f FILENAME",
Use: "diff -f FILENAME",
DisableFlagsInUseLine: true,
Short: i18n.T("Diff different versions of configurations"),
Long: diffLong,
Example: diffExample,

View File

@ -105,7 +105,8 @@ func NewCmdCordon(f cmdutil.Factory, out io.Writer) *cobra.Command {
options := &DrainOptions{Factory: f, Out: out}
cmd := &cobra.Command{
Use: "cordon NODE",
Use: "cordon NODE",
DisableFlagsInUseLine: true,
Short: i18n.T("Mark node as unschedulable"),
Long: cordon_long,
Example: cordon_example,
@ -132,7 +133,8 @@ func NewCmdUncordon(f cmdutil.Factory, out io.Writer) *cobra.Command {
options := &DrainOptions{Factory: f, Out: out}
cmd := &cobra.Command{
Use: "uncordon NODE",
Use: "uncordon NODE",
DisableFlagsInUseLine: true,
Short: i18n.T("Mark node as schedulable"),
Long: uncordon_long,
Example: uncordon_example,
@ -184,7 +186,8 @@ func NewCmdDrain(f cmdutil.Factory, out, errOut io.Writer) *cobra.Command {
options := &DrainOptions{Factory: f, Out: out, ErrOut: errOut, backOff: clockwork.NewRealClock()}
cmd := &cobra.Command{
Use: "drain NODE",
Use: "drain NODE",
DisableFlagsInUseLine: true,
Short: i18n.T("Drain node in preparation for maintenance"),
Long: drain_long,
Example: drain_example,

View File

@ -87,7 +87,8 @@ func NewCmdEdit(f cmdutil.Factory, out, errOut io.Writer) *cobra.Command {
}
cmd := &cobra.Command{
Use: "edit (RESOURCE/NAME | -f FILENAME)",
Use: "edit (RESOURCE/NAME | -f FILENAME)",
DisableFlagsInUseLine: true,
Short: i18n.T("Edit a resource on the server"),
Long: editLong,
Example: fmt.Sprintf(editExample),

View File

@ -73,7 +73,8 @@ func NewCmdExec(f cmdutil.Factory, cmdIn io.Reader, cmdOut, cmdErr io.Writer) *c
Executor: &DefaultRemoteExecutor{},
}
cmd := &cobra.Command{
Use: "exec POD [-c CONTAINER] -- COMMAND [args...]",
Use: "exec POD [-c CONTAINER] -- COMMAND [args...]",
DisableFlagsInUseLine: true,
Short: i18n.T("Execute a command in a container"),
Long: "Execute a command in a container.",
Example: exec_example,

View File

@ -53,7 +53,8 @@ var (
// NewCmdExplain returns a cobra command for swagger docs
func NewCmdExplain(f cmdutil.Factory, out, cmdErr io.Writer) *cobra.Command {
cmd := &cobra.Command{
Use: "explain RESOURCE",
Use: "explain RESOURCE",
DisableFlagsInUseLine: true,
Short: i18n.T("Documentation of resources"),
Long: explainLong + "\n\n" + cmdutil.ValidResourceTypeList(f),
Example: explainExamples,

View File

@ -83,7 +83,8 @@ func NewCmdExposeService(f cmdutil.Factory, out io.Writer) *cobra.Command {
}
cmd := &cobra.Command{
Use: "expose (-f FILENAME | TYPE NAME) [--port=port] [--protocol=TCP|UDP] [--target-port=number-or-name] [--name=name] [--external-ip=external-ip-of-service] [--type=type]",
Use: "expose (-f FILENAME | TYPE NAME) [--port=port] [--protocol=TCP|UDP] [--target-port=number-or-name] [--name=name] [--external-ip=external-ip-of-service] [--type=type]",
DisableFlagsInUseLine: true,
Short: i18n.T("Take a replication controller, service, deployment or pod and expose it as a new Kubernetes Service"),
Long: exposeLong,
Example: exposeExample,

View File

@ -31,7 +31,8 @@ var helpLong = templates.LongDesc(i18n.T(`
func NewCmdHelp() *cobra.Command {
cmd := &cobra.Command{
Use: "help [command] | STRING_TO_SEARCH",
Use: "help [command] | STRING_TO_SEARCH",
DisableFlagsInUseLine: true,
Short: i18n.T("Help about any command"),
Long: helpLong,

View File

@ -111,7 +111,8 @@ func NewCmdLabel(f cmdutil.Factory, out io.Writer) *cobra.Command {
}
cmd := &cobra.Command{
Use: "label [--overwrite] (-f FILENAME | TYPE NAME) KEY_1=VAL_1 ... KEY_N=VAL_N [--resource-version=version]",
Use: "label [--overwrite] (-f FILENAME | TYPE NAME) KEY_1=VAL_1 ... KEY_N=VAL_N [--resource-version=version]",
DisableFlagsInUseLine: true,
Short: i18n.T("Update the labels on a resource"),
Long: fmt.Sprintf(labelLong, validation.LabelValueMaxLength),
Example: labelExample,

View File

@ -89,7 +89,8 @@ type LogsOptions struct {
func NewCmdLogs(f cmdutil.Factory, out io.Writer) *cobra.Command {
o := &LogsOptions{}
cmd := &cobra.Command{
Use: "logs [-f] [-p] (POD | TYPE/NAME) [-c CONTAINER]",
Use: "logs [-f] [-p] (POD | TYPE/NAME) [-c CONTAINER]",
DisableFlagsInUseLine: true,
Short: i18n.T("Print the logs for a container in a pod"),
Long: "Print the logs for a container in a pod or specified resource. If the pod has only one container, the container name is optional.",
Example: logsExample,

View File

@ -95,7 +95,8 @@ func NewCmdPatch(f cmdutil.Factory, out io.Writer) *cobra.Command {
}
cmd := &cobra.Command{
Use: "patch (-f FILENAME | TYPE NAME) -p PATCH",
Use: "patch (-f FILENAME | TYPE NAME) -p PATCH",
DisableFlagsInUseLine: true,
Short: i18n.T("Update field(s) of a resource using strategic merge patch"),
Long: patchLong,
Example: patchExample,

View File

@ -50,7 +50,8 @@ func NewCmdPlugin(f cmdutil.Factory, in io.Reader, out, err io.Writer) *cobra.Co
}
cmd := &cobra.Command{
Use: "plugin NAME",
Use: "plugin NAME",
DisableFlagsInUseLine: true,
Short: i18n.T("Runs a command-line plugin"),
Long: plugin_long,
Run: func(cmd *cobra.Command, args []string) {

View File

@ -70,7 +70,8 @@ func NewCmdPortForward(f cmdutil.Factory, cmdOut, cmdErr io.Writer) *cobra.Comma
},
}
cmd := &cobra.Command{
Use: "port-forward POD [LOCAL_PORT:]REMOTE_PORT [...[LOCAL_PORT_N:]REMOTE_PORT_N]",
Use: "port-forward POD [LOCAL_PORT:]REMOTE_PORT [...[LOCAL_PORT_N:]REMOTE_PORT_N]",
DisableFlagsInUseLine: true,
Short: i18n.T("Forward one or more local ports to a pod"),
Long: "Forward one or more local ports to a pod.",
Example: portforwardExample,

View File

@ -71,7 +71,8 @@ var (
func NewCmdProxy(f cmdutil.Factory, out io.Writer) *cobra.Command {
cmd := &cobra.Command{
Use: "proxy [--port=PORT] [--www=static-dir] [--www-prefix=prefix] [--api-prefix=prefix]",
Use: "proxy [--port=PORT] [--www=static-dir] [--www-prefix=prefix] [--api-prefix=prefix]",
DisableFlagsInUseLine: true,
Short: i18n.T("Run a proxy to the Kubernetes API server"),
Long: proxyLong,
Example: proxyExample,

View File

@ -64,7 +64,8 @@ func NewCmdReplace(f cmdutil.Factory, out io.Writer) *cobra.Command {
options := &resource.FilenameOptions{}
cmd := &cobra.Command{
Use: "replace -f FILENAME",
Use: "replace -f FILENAME",
DisableFlagsInUseLine: true,
Short: i18n.T("Replace a resource by filename or stdin"),
Long: replaceLong,
Example: replaceExample,

View File

@ -143,7 +143,8 @@ func NewCmdGet(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.Comman
}
cmd := &cobra.Command{
Use: "get [(-o|--output=)json|yaml|wide|custom-columns=...|custom-columns-file=...|go-template=...|go-template-file=...|jsonpath=...|jsonpath-file=...] (TYPE [NAME | -l label] | TYPE/NAME ...) [flags]",
Use: "get [(-o|--output=)json|yaml|wide|custom-columns=...|custom-columns-file=...|go-template=...|go-template-file=...|jsonpath=...|jsonpath-file=...] (TYPE [NAME | -l label] | TYPE/NAME ...) [flags]",
DisableFlagsInUseLine: true,
Short: i18n.T("Display one or many resources"),
Long: getLong + "\n\n" + cmdutil.ValidResourceTypeList(f),
Example: getExample,

View File

@ -79,7 +79,8 @@ func NewCmdRollingUpdate(f cmdutil.Factory, out io.Writer) *cobra.Command {
options := &resource.FilenameOptions{}
cmd := &cobra.Command{
Use: "rolling-update OLD_CONTROLLER_NAME ([NEW_CONTROLLER_NAME] --image=NEW_CONTAINER_IMAGE | -f NEW_CONTROLLER_SPEC)",
Use: "rolling-update OLD_CONTROLLER_NAME ([NEW_CONTROLLER_NAME] --image=NEW_CONTAINER_IMAGE | -f NEW_CONTROLLER_SPEC)",
DisableFlagsInUseLine: true,
Short: i18n.T("Perform a rolling update of the given ReplicationController"),
Long: rollingUpdateLong,
Example: rollingUpdateExample,
@ -93,9 +94,7 @@ func NewCmdRollingUpdate(f cmdutil.Factory, out io.Writer) *cobra.Command {
cmd.Flags().Duration("timeout", timeout, `Max time to wait for a replication controller to update before giving up. Valid time units are "ns", "us" (or "µs"), "ms", "s", "m", "h".`)
usage := "Filename or URL to file to use to create the new replication controller."
kubectl.AddJsonFilenameFlag(cmd, &options.Filenames, usage)
cmd.MarkFlagRequired("filename")
cmd.Flags().String("image", "", i18n.T("Image to use for upgrading the replication controller. Must be distinct from the existing image (either new image or new image tag). Can not be used with --filename/-f"))
cmd.MarkFlagRequired("image")
cmd.Flags().String("deployment-label-key", "deployment", i18n.T("The key to use to differentiate between two different controllers, default 'deployment'. Only relevant when --image is specified, ignored otherwise"))
cmd.Flags().String("container", "", i18n.T("Container name which will have its image upgraded. Only relevant when --image is specified, ignored otherwise. Required when using --image on a multi-container pod"))
cmd.Flags().String("image-pull-policy", "", i18n.T("Explicit policy for when to pull container images. Required when --image is same as existing image, ignored otherwise."))

View File

@ -49,7 +49,8 @@ var (
func NewCmdRollout(f cmdutil.Factory, out, errOut io.Writer) *cobra.Command {
cmd := &cobra.Command{
Use: "rollout SUBCOMMAND",
Use: "rollout SUBCOMMAND",
DisableFlagsInUseLine: true,
Short: i18n.T("Manage the rollout of a resource"),
Long: rollout_long,
Example: rollout_example,

View File

@ -48,7 +48,8 @@ func NewCmdRolloutHistory(f cmdutil.Factory, out io.Writer) *cobra.Command {
argAliases := kubectl.ResourceAliases(validArgs)
cmd := &cobra.Command{
Use: "history (TYPE NAME | TYPE/NAME) [flags]",
Use: "history (TYPE NAME | TYPE/NAME) [flags]",
DisableFlagsInUseLine: true,
Short: i18n.T("View rollout history"),
Long: history_long,
Example: history_example,

View File

@ -71,7 +71,8 @@ func NewCmdRolloutPause(f cmdutil.Factory, out io.Writer) *cobra.Command {
argAliases := kubectl.ResourceAliases(validArgs)
cmd := &cobra.Command{
Use: "pause RESOURCE",
Use: "pause RESOURCE",
DisableFlagsInUseLine: true,
Short: i18n.T("Mark the provided resource as paused"),
Long: pause_long,
Example: pause_example,

View File

@ -69,7 +69,8 @@ func NewCmdRolloutResume(f cmdutil.Factory, out io.Writer) *cobra.Command {
argAliases := kubectl.ResourceAliases(validArgs)
cmd := &cobra.Command{
Use: "resume RESOURCE",
Use: "resume RESOURCE",
DisableFlagsInUseLine: true,
Short: i18n.T("Resume a paused resource"),
Long: resume_long,
Example: resume_example,

View File

@ -54,7 +54,8 @@ func NewCmdRolloutStatus(f cmdutil.Factory, out io.Writer) *cobra.Command {
argAliases := kubectl.ResourceAliases(validArgs)
cmd := &cobra.Command{
Use: "status (TYPE NAME | TYPE/NAME) [flags]",
Use: "status (TYPE NAME | TYPE/NAME) [flags]",
DisableFlagsInUseLine: true,
Short: i18n.T("Show the status of the rollout"),
Long: status_long,
Example: status_example,

View File

@ -69,7 +69,8 @@ func NewCmdRolloutUndo(f cmdutil.Factory, out io.Writer) *cobra.Command {
argAliases := kubectl.ResourceAliases(validArgs)
cmd := &cobra.Command{
Use: "undo (TYPE NAME | TYPE/NAME) [flags]",
Use: "undo (TYPE NAME | TYPE/NAME) [flags]",
DisableFlagsInUseLine: true,
Short: i18n.T("Undo a previous rollout"),
Long: undo_long,
Example: undo_example,

View File

@ -96,7 +96,8 @@ type RunObject struct {
func NewCmdRun(f cmdutil.Factory, cmdIn io.Reader, cmdOut, cmdErr io.Writer) *cobra.Command {
cmd := &cobra.Command{
Use: "run NAME --image=image [--env=\"key=value\"] [--port=port] [--replicas=replicas] [--dry-run=bool] [--overrides=inline-json] [--command] -- [COMMAND] [args...]",
Use: "run NAME --image=image [--env=\"key=value\"] [--port=port] [--replicas=replicas] [--dry-run=bool] [--overrides=inline-json] [--command] -- [COMMAND] [args...]",
DisableFlagsInUseLine: true,
Short: i18n.T("Run a particular image on the cluster"),
Long: runLong,
Example: runExample,

View File

@ -64,7 +64,8 @@ func NewCmdScale(f cmdutil.Factory, out io.Writer) *cobra.Command {
argAliases := kubectl.ResourceAliases(validArgs)
cmd := &cobra.Command{
Use: "scale [--resource-version=version] [--current-replicas=count] --replicas=COUNT (-f FILENAME | TYPE NAME)",
Use: "scale [--resource-version=version] [--current-replicas=count] --replicas=COUNT (-f FILENAME | TYPE NAME)",
DisableFlagsInUseLine: true,
Short: i18n.T("Set a new size for a Deployment, ReplicaSet, Replication Controller, or Job"),
Long: scaleLong,
Example: scaleExample,

View File

@ -34,7 +34,8 @@ var (
func NewCmdSet(f cmdutil.Factory, in io.Reader, out, err io.Writer) *cobra.Command {
cmd := &cobra.Command{
Use: "set SUBCOMMAND",
Use: "set SUBCOMMAND",
DisableFlagsInUseLine: true,
Short: i18n.T("Set specific features on objects"),
Long: set_long,
Run: cmdutil.DefaultSubCommandRun(err),

View File

@ -135,7 +135,8 @@ func NewCmdEnv(f cmdutil.Factory, in io.Reader, out, errout io.Writer) *cobra.Co
In: in,
}
cmd := &cobra.Command{
Use: "env RESOURCE/NAME KEY_1=VAL_1 ... KEY_N=VAL_N",
Use: "env RESOURCE/NAME KEY_1=VAL_1 ... KEY_N=VAL_N",
DisableFlagsInUseLine: true,
Short: "Update environment variables on a pod template",
Long: envLong,
Example: fmt.Sprintf(envExample),

View File

@ -92,7 +92,8 @@ func NewCmdImage(f cmdutil.Factory, out, err io.Writer) *cobra.Command {
}
cmd := &cobra.Command{
Use: "image (-f FILENAME | TYPE NAME) CONTAINER_NAME_1=CONTAINER_IMAGE_1 ... CONTAINER_NAME_N=CONTAINER_IMAGE_N",
Use: "image (-f FILENAME | TYPE NAME) CONTAINER_NAME_1=CONTAINER_IMAGE_1 ... CONTAINER_NAME_N=CONTAINER_IMAGE_N",
DisableFlagsInUseLine: true,
Short: i18n.T("Update image of a pod template"),
Long: image_long,
Example: image_example,

View File

@ -98,7 +98,8 @@ func NewCmdResources(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.
}
cmd := &cobra.Command{
Use: "resources (-f FILENAME | TYPE NAME) ([--limits=LIMITS & --requests=REQUESTS]",
Use: "resources (-f FILENAME | TYPE NAME) ([--limits=LIMITS & --requests=REQUESTS]",
DisableFlagsInUseLine: true,
Short: i18n.T("Update resource requests/limits on objects with pod templates"),
Long: fmt.Sprintf(resources_long, strings.Join(resourceTypesWithPodTemplate, ", ")),
Example: resources_example,

View File

@ -79,7 +79,8 @@ func NewCmdSelector(f cmdutil.Factory, out io.Writer) *cobra.Command {
}
cmd := &cobra.Command{
Use: "selector (-f FILENAME | TYPE NAME) EXPRESSIONS [--resource-version=version]",
Use: "selector (-f FILENAME | TYPE NAME) EXPRESSIONS [--resource-version=version]",
DisableFlagsInUseLine: true,
Short: i18n.T("Set the selector on a resource"),
Long: fmt.Sprintf(selectorLong, validation.LabelValueMaxLength),
Example: selectorExample,

View File

@ -83,11 +83,12 @@ func NewCmdServiceAccount(f cmdutil.Factory, out, err io.Writer) *cobra.Command
}
cmd := &cobra.Command{
Use: "serviceaccount (-f FILENAME | TYPE NAME) SERVICE_ACCOUNT",
Aliases: []string{"sa"},
Short: i18n.T("Update ServiceAccount of a resource"),
Long: serviceaccountLong,
Example: serviceaccountExample,
Use: "serviceaccount (-f FILENAME | TYPE NAME) SERVICE_ACCOUNT",
DisableFlagsInUseLine: true,
Aliases: []string{"sa"},
Short: i18n.T("Update ServiceAccount of a resource"),
Long: serviceaccountLong,
Example: serviceaccountExample,
Run: func(cmd *cobra.Command, args []string) {
cmdutil.CheckErr(saConfig.Complete(f, cmd, args))
cmdutil.CheckErr(saConfig.Run())

View File

@ -84,7 +84,8 @@ func NewCmdSubject(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.Co
}
cmd := &cobra.Command{
Use: "subject (-f FILENAME | TYPE NAME) [--user=username] [--group=groupname] [--serviceaccount=namespace:serviceaccountname] [--dry-run]",
Use: "subject (-f FILENAME | TYPE NAME) [--user=username] [--group=groupname] [--serviceaccount=namespace:serviceaccountname] [--dry-run]",
DisableFlagsInUseLine: true,
Short: i18n.T("Update User, Group or ServiceAccount in a RoleBinding/ClusterRoleBinding"),
Long: subject_long,
Example: subject_example,

View File

@ -85,7 +85,8 @@ func NewCmdTaint(f cmdutil.Factory, out io.Writer) *cobra.Command {
argAliases := kubectl.ResourceAliases(validArgs)
cmd := &cobra.Command{
Use: "taint NODE NAME KEY_1=VAL_1:TAINT_EFFECT_1 ... KEY_N=VAL_N:TAINT_EFFECT_N",
Use: "taint NODE NAME KEY_1=VAL_1:TAINT_EFFECT_1 ... KEY_N=VAL_N:TAINT_EFFECT_N",
DisableFlagsInUseLine: true,
Short: i18n.T("Update the taints on one or more nodes"),
Long: fmt.Sprintf(taintLong, validation.DNS1123SubdomainMaxLength, validation.LabelValueMaxLength),
Example: taintExample,

View File

@ -89,7 +89,8 @@ func NewCmdTopNode(f cmdutil.Factory, options *TopNodeOptions, out io.Writer) *c
}
cmd := &cobra.Command{
Use: "node [NAME | -l label]",
Use: "node [NAME | -l label]",
DisableFlagsInUseLine: true,
Short: i18n.T("Display Resource (CPU/Memory/Storage) usage of nodes"),
Long: topNodeLong,
Example: topNodeExample,

View File

@ -78,7 +78,8 @@ func NewCmdTopPod(f cmdutil.Factory, options *TopPodOptions, out io.Writer) *cob
}
cmd := &cobra.Command{
Use: "pod [NAME | -l label]",
Use: "pod [NAME | -l label]",
DisableFlagsInUseLine: true,
Short: i18n.T("Display Resource (CPU/Memory/Storage) usage of pods"),
Long: topPodLong,
Example: topPodExample,

View File

@ -24,7 +24,7 @@
},
{
"ImportPath": "github.com/spf13/pflag",
"Rev": "9ff6c6923cfffbcd502984b8e0c80539a94968b7"
"Rev": "4c012f6dcd9546820e378d0bdda4d8fc772cdfea"
},
{
"ImportPath": "golang.org/x/net/http2",

View File

@ -292,11 +292,11 @@
},
{
"ImportPath": "github.com/spf13/cobra",
"Rev": "f62e98d28ab7ad31d707ba837a966378465c7b57"
"Rev": "19e54c4a2b8a78c9d54b2bed61b1a6c5e1bfcf6f"
},
{
"ImportPath": "github.com/spf13/pflag",
"Rev": "9ff6c6923cfffbcd502984b8e0c80539a94968b7"
"Rev": "4c012f6dcd9546820e378d0bdda4d8fc772cdfea"
},
{
"ImportPath": "github.com/stretchr/testify/assert",

View File

@ -108,7 +108,7 @@
},
{
"ImportPath": "github.com/spf13/pflag",
"Rev": "9ff6c6923cfffbcd502984b8e0c80539a94968b7"
"Rev": "4c012f6dcd9546820e378d0bdda4d8fc772cdfea"
},
{
"ImportPath": "github.com/stretchr/testify/assert",

View File

@ -620,7 +620,7 @@
},
{
"ImportPath": "github.com/spf13/pflag",
"Rev": "9ff6c6923cfffbcd502984b8e0c80539a94968b7"
"Rev": "4c012f6dcd9546820e378d0bdda4d8fc772cdfea"
},
{
"ImportPath": "github.com/stretchr/testify/assert",

View File

@ -196,7 +196,7 @@
},
{
"ImportPath": "github.com/spf13/pflag",
"Rev": "9ff6c6923cfffbcd502984b8e0c80539a94968b7"
"Rev": "4c012f6dcd9546820e378d0bdda4d8fc772cdfea"
},
{
"ImportPath": "github.com/stretchr/testify/assert",

View File

@ -156,7 +156,7 @@
},
{
"ImportPath": "github.com/spf13/pflag",
"Rev": "9ff6c6923cfffbcd502984b8e0c80539a94968b7"
"Rev": "4c012f6dcd9546820e378d0bdda4d8fc772cdfea"
},
{
"ImportPath": "golang.org/x/net/idna",

View File

@ -272,11 +272,11 @@
},
{
"ImportPath": "github.com/spf13/cobra",
"Rev": "f62e98d28ab7ad31d707ba837a966378465c7b57"
"Rev": "19e54c4a2b8a78c9d54b2bed61b1a6c5e1bfcf6f"
},
{
"ImportPath": "github.com/spf13/pflag",
"Rev": "9ff6c6923cfffbcd502984b8e0c80539a94968b7"
"Rev": "4c012f6dcd9546820e378d0bdda4d8fc772cdfea"
},
{
"ImportPath": "github.com/stretchr/testify/assert",

View File

@ -68,7 +68,7 @@
},
{
"ImportPath": "github.com/spf13/pflag",
"Rev": "9ff6c6923cfffbcd502984b8e0c80539a94968b7"
"Rev": "4c012f6dcd9546820e378d0bdda4d8fc772cdfea"
},
{
"ImportPath": "golang.org/x/net/http2",

View File

@ -260,11 +260,11 @@
},
{
"ImportPath": "github.com/spf13/cobra",
"Rev": "f62e98d28ab7ad31d707ba837a966378465c7b57"
"Rev": "19e54c4a2b8a78c9d54b2bed61b1a6c5e1bfcf6f"
},
{
"ImportPath": "github.com/spf13/pflag",
"Rev": "9ff6c6923cfffbcd502984b8e0c80539a94968b7"
"Rev": "4c012f6dcd9546820e378d0bdda4d8fc772cdfea"
},
{
"ImportPath": "github.com/ugorji/go/codec",

View File

@ -92,7 +92,7 @@
},
{
"ImportPath": "github.com/spf13/pflag",
"Rev": "9ff6c6923cfffbcd502984b8e0c80539a94968b7"
"Rev": "4c012f6dcd9546820e378d0bdda4d8fc772cdfea"
},
{
"ImportPath": "golang.org/x/crypto/ssh/terminal",

View File

@ -1,11 +1,10 @@
language: go
go:
- 1.4.3
- 1.5.4
- 1.6.3
- tip
matrix:
include:
- go: 1.7.6
- go: 1.8.3
- go: tip
allow_failures:
- go: tip
@ -16,3 +15,7 @@ before_install:
script:
- PATH=$PATH:$PWD/bin go test -v ./...
- go build
- diff -u <(echo -n) <(gofmt -d -s .)
- if [ -z $NOVET ]; then
diff -u <(echo -n) <(go tool vet . 2>&1 | grep -vE 'ExampleCommand|bash_completions.*Fprint');
fi

View File

@ -3,9 +3,11 @@ load("@io_bazel_rules_go//go:def.bzl", "go_library")
go_library(
name = "go_default_library",
srcs = [
"args.go",
"bash_completions.go",
"cobra.go",
"command.go",
"zsh_completions.go",
] + select({
"@io_bazel_rules_go//go/platform:android": [
"command_notwin.go",

File diff suppressed because it is too large Load Diff

89
vendor/github.com/spf13/cobra/args.go generated vendored Normal file
View File

@ -0,0 +1,89 @@
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
}
// 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
}
}

View File

@ -1,6 +1,7 @@
package cobra
import (
"bytes"
"fmt"
"io"
"os"
@ -10,19 +11,17 @@ import (
"github.com/spf13/pflag"
)
// Annotations for Bash completion.
const (
BashCompFilenameExt = "cobra_annotation_bash_completion_filename_extentions"
BashCompFilenameExt = "cobra_annotation_bash_completion_filename_extensions"
BashCompCustom = "cobra_annotation_bash_completion_custom"
BashCompOneRequiredFlag = "cobra_annotation_bash_completion_one_required_flag"
BashCompSubdirsInDir = "cobra_annotation_bash_completion_subdirs_in_dir"
)
func preamble(out io.Writer, name string) error {
_, err := fmt.Fprintf(out, "# bash completion for %-36s -*- shell-script -*-\n", name)
if err != nil {
return err
}
_, err = fmt.Fprint(out, `
func writePreamble(buf *bytes.Buffer, name string) {
buf.WriteString(fmt.Sprintf("# bash completion for %-36s -*- shell-script -*-\n", name))
buf.WriteString(`
__debug()
{
if [[ -n ${BASH_COMP_DEBUG_FILE} ]]; then
@ -87,13 +86,13 @@ __handle_reply()
local index flag
flag="${cur%%=*}"
__index_of_word "${flag}" "${flags_with_completion[@]}"
COMPREPLY=()
if [[ ${index} -ge 0 ]]; then
COMPREPLY=()
PREFIX=""
cur="${cur#*=}"
${flags_completion[${index}]}
if [ -n "${ZSH_VERSION}" ]; then
# zfs completion needs --flag= prefix
# zsh completion needs --flag= prefix
eval "COMPREPLY=( \"\${COMPREPLY[@]/#/${flag}=}\" )"
fi
fi
@ -133,7 +132,10 @@ __handle_reply()
declare -F __custom_func >/dev/null && __custom_func
fi
__ltrim_colon_completions "$cur"
# available in bash-completion >= 2, not always present on macOS
if declare -F __ltrim_colon_completions >/dev/null; then
__ltrim_colon_completions "$cur"
fi
}
# The arguments should be in the form "ext1|ext2|extn"
@ -224,7 +226,7 @@ __handle_command()
fi
c=$((c+1))
__debug "${FUNCNAME[0]}: looking for ${next_command}"
declare -F $next_command >/dev/null && $next_command
declare -F "$next_command" >/dev/null && $next_command
}
__handle_word()
@ -247,16 +249,12 @@ __handle_word()
}
`)
return err
}
func postscript(w io.Writer, name string) error {
func writePostscript(buf *bytes.Buffer, name string) {
name = strings.Replace(name, ":", "__", -1)
_, err := fmt.Fprintf(w, "__start_%s()\n", name)
if err != nil {
return err
}
_, err = fmt.Fprintf(w, `{
buf.WriteString(fmt.Sprintf("__start_%s()\n", name))
buf.WriteString(fmt.Sprintf(`{
local cur prev words cword
declare -A flaghash 2>/dev/null || :
if declare -F _init_completion >/dev/null 2>&1; then
@ -280,318 +278,227 @@ func postscript(w io.Writer, name string) error {
__handle_word
}
`, name)
if err != nil {
return err
}
_, err = fmt.Fprintf(w, `if [[ $(type -t compopt) = "builtin" ]]; then
`, name))
buf.WriteString(fmt.Sprintf(`if [[ $(type -t compopt) = "builtin" ]]; then
complete -o default -F __start_%s %s
else
complete -o default -o nospace -F __start_%s %s
fi
`, name, name, name, name)
if err != nil {
return err
}
_, err = fmt.Fprintf(w, "# ex: ts=4 sw=4 et filetype=sh\n")
return err
`, name, name, name, name))
buf.WriteString("# ex: ts=4 sw=4 et filetype=sh\n")
}
func writeCommands(cmd *Command, w io.Writer) error {
if _, err := fmt.Fprintf(w, " commands=()\n"); err != nil {
return err
}
func writeCommands(buf *bytes.Buffer, cmd *Command) {
buf.WriteString(" commands=()\n")
for _, c := range cmd.Commands() {
if !c.IsAvailableCommand() || c == cmd.helpCommand {
continue
}
if _, err := fmt.Fprintf(w, " commands+=(%q)\n", c.Name()); err != nil {
return err
}
buf.WriteString(fmt.Sprintf(" commands+=(%q)\n", c.Name()))
}
_, err := fmt.Fprintf(w, "\n")
return err
buf.WriteString("\n")
}
func writeFlagHandler(name string, annotations map[string][]string, w io.Writer) error {
func writeFlagHandler(buf *bytes.Buffer, name string, annotations map[string][]string) {
for key, value := range annotations {
switch key {
case BashCompFilenameExt:
_, err := fmt.Fprintf(w, " flags_with_completion+=(%q)\n", name)
if err != nil {
return err
}
buf.WriteString(fmt.Sprintf(" flags_with_completion+=(%q)\n", name))
var ext string
if len(value) > 0 {
ext := "__handle_filename_extension_flag " + strings.Join(value, "|")
_, err = fmt.Fprintf(w, " flags_completion+=(%q)\n", ext)
ext = "__handle_filename_extension_flag " + strings.Join(value, "|")
} else {
ext := "_filedir"
_, err = fmt.Fprintf(w, " flags_completion+=(%q)\n", ext)
}
if err != nil {
return err
ext = "_filedir"
}
buf.WriteString(fmt.Sprintf(" flags_completion+=(%q)\n", ext))
case BashCompCustom:
_, err := fmt.Fprintf(w, " flags_with_completion+=(%q)\n", name)
if err != nil {
return err
}
buf.WriteString(fmt.Sprintf(" flags_with_completion+=(%q)\n", name))
if len(value) > 0 {
handlers := strings.Join(value, "; ")
_, err = fmt.Fprintf(w, " flags_completion+=(%q)\n", handlers)
buf.WriteString(fmt.Sprintf(" flags_completion+=(%q)\n", handlers))
} else {
_, err = fmt.Fprintf(w, " flags_completion+=(:)\n")
}
if err != nil {
return err
buf.WriteString(" flags_completion+=(:)\n")
}
case BashCompSubdirsInDir:
_, err := fmt.Fprintf(w, " flags_with_completion+=(%q)\n", name)
buf.WriteString(fmt.Sprintf(" flags_with_completion+=(%q)\n", name))
var ext string
if len(value) == 1 {
ext := "__handle_subdirs_in_dir_flag " + value[0]
_, err = fmt.Fprintf(w, " flags_completion+=(%q)\n", ext)
ext = "__handle_subdirs_in_dir_flag " + value[0]
} else {
ext := "_filedir -d"
_, err = fmt.Fprintf(w, " flags_completion+=(%q)\n", ext)
}
if err != nil {
return err
ext = "_filedir -d"
}
buf.WriteString(fmt.Sprintf(" flags_completion+=(%q)\n", ext))
}
}
return nil
}
func writeShortFlag(flag *pflag.Flag, w io.Writer) error {
b := (len(flag.NoOptDefVal) > 0)
func writeShortFlag(buf *bytes.Buffer, flag *pflag.Flag) {
name := flag.Shorthand
format := " "
if !b {
if len(flag.NoOptDefVal) == 0 {
format += "two_word_"
}
format += "flags+=(\"-%s\")\n"
if _, err := fmt.Fprintf(w, format, name); err != nil {
return err
}
return writeFlagHandler("-"+name, flag.Annotations, w)
buf.WriteString(fmt.Sprintf(format, name))
writeFlagHandler(buf, "-"+name, flag.Annotations)
}
func writeFlag(flag *pflag.Flag, w io.Writer) error {
b := (len(flag.NoOptDefVal) > 0)
func writeFlag(buf *bytes.Buffer, flag *pflag.Flag) {
name := flag.Name
format := " flags+=(\"--%s"
if !b {
if len(flag.NoOptDefVal) == 0 {
format += "="
}
format += "\")\n"
if _, err := fmt.Fprintf(w, format, name); err != nil {
return err
}
return writeFlagHandler("--"+name, flag.Annotations, w)
buf.WriteString(fmt.Sprintf(format, name))
writeFlagHandler(buf, "--"+name, flag.Annotations)
}
func writeLocalNonPersistentFlag(flag *pflag.Flag, w io.Writer) error {
b := (len(flag.NoOptDefVal) > 0)
func writeLocalNonPersistentFlag(buf *bytes.Buffer, flag *pflag.Flag) {
name := flag.Name
format := " local_nonpersistent_flags+=(\"--%s"
if !b {
if len(flag.NoOptDefVal) == 0 {
format += "="
}
format += "\")\n"
if _, err := fmt.Fprintf(w, format, name); err != nil {
return err
}
return nil
buf.WriteString(fmt.Sprintf(format, name))
}
func writeFlags(cmd *Command, w io.Writer) error {
_, err := fmt.Fprintf(w, ` flags=()
func writeFlags(buf *bytes.Buffer, cmd *Command) {
buf.WriteString(` flags=()
two_word_flags=()
local_nonpersistent_flags=()
flags_with_completion=()
flags_completion=()
`)
if err != nil {
return err
}
localNonPersistentFlags := cmd.LocalNonPersistentFlags()
var visitErr error
cmd.NonInheritedFlags().VisitAll(func(flag *pflag.Flag) {
if err := writeFlag(flag, w); err != nil {
visitErr = err
if nonCompletableFlag(flag) {
return
}
writeFlag(buf, flag)
if len(flag.Shorthand) > 0 {
if err := writeShortFlag(flag, w); err != nil {
visitErr = err
return
}
writeShortFlag(buf, flag)
}
if localNonPersistentFlags.Lookup(flag.Name) != nil {
if err := writeLocalNonPersistentFlag(flag, w); err != nil {
visitErr = err
return
}
writeLocalNonPersistentFlag(buf, flag)
}
})
if visitErr != nil {
return visitErr
}
cmd.InheritedFlags().VisitAll(func(flag *pflag.Flag) {
if err := writeFlag(flag, w); err != nil {
visitErr = err
if nonCompletableFlag(flag) {
return
}
writeFlag(buf, flag)
if len(flag.Shorthand) > 0 {
if err := writeShortFlag(flag, w); err != nil {
visitErr = err
return
}
writeShortFlag(buf, flag)
}
})
if visitErr != nil {
return visitErr
}
_, err = fmt.Fprintf(w, "\n")
return err
buf.WriteString("\n")
}
func writeRequiredFlag(cmd *Command, w io.Writer) error {
if _, err := fmt.Fprintf(w, " must_have_one_flag=()\n"); err != nil {
return err
}
func writeRequiredFlag(buf *bytes.Buffer, cmd *Command) {
buf.WriteString(" must_have_one_flag=()\n")
flags := cmd.NonInheritedFlags()
var visitErr error
flags.VisitAll(func(flag *pflag.Flag) {
if nonCompletableFlag(flag) {
return
}
for key := range flag.Annotations {
switch key {
case BashCompOneRequiredFlag:
format := " must_have_one_flag+=(\"--%s"
b := (flag.Value.Type() == "bool")
if !b {
if flag.Value.Type() != "bool" {
format += "="
}
format += "\")\n"
if _, err := fmt.Fprintf(w, format, flag.Name); err != nil {
visitErr = err
return
}
buf.WriteString(fmt.Sprintf(format, flag.Name))
if len(flag.Shorthand) > 0 {
if _, err := fmt.Fprintf(w, " must_have_one_flag+=(\"-%s\")\n", flag.Shorthand); err != nil {
visitErr = err
return
}
buf.WriteString(fmt.Sprintf(" must_have_one_flag+=(\"-%s\")\n", flag.Shorthand))
}
}
}
})
return visitErr
}
func writeRequiredNouns(cmd *Command, w io.Writer) error {
if _, err := fmt.Fprintf(w, " must_have_one_noun=()\n"); err != nil {
return err
}
func writeRequiredNouns(buf *bytes.Buffer, cmd *Command) {
buf.WriteString(" must_have_one_noun=()\n")
sort.Sort(sort.StringSlice(cmd.ValidArgs))
for _, value := range cmd.ValidArgs {
if _, err := fmt.Fprintf(w, " must_have_one_noun+=(%q)\n", value); err != nil {
return err
}
buf.WriteString(fmt.Sprintf(" must_have_one_noun+=(%q)\n", value))
}
return nil
}
func writeArgAliases(cmd *Command, w io.Writer) error {
if _, err := fmt.Fprintf(w, " noun_aliases=()\n"); err != nil {
return err
}
func writeArgAliases(buf *bytes.Buffer, cmd *Command) {
buf.WriteString(" noun_aliases=()\n")
sort.Sort(sort.StringSlice(cmd.ArgAliases))
for _, value := range cmd.ArgAliases {
if _, err := fmt.Fprintf(w, " noun_aliases+=(%q)\n", value); err != nil {
return err
}
buf.WriteString(fmt.Sprintf(" noun_aliases+=(%q)\n", value))
}
return nil
}
func gen(cmd *Command, w io.Writer) error {
func gen(buf *bytes.Buffer, cmd *Command) {
for _, c := range cmd.Commands() {
if !c.IsAvailableCommand() || c == cmd.helpCommand {
continue
}
if err := gen(c, w); err != nil {
return err
}
gen(buf, c)
}
commandName := cmd.CommandPath()
commandName = strings.Replace(commandName, " ", "_", -1)
commandName = strings.Replace(commandName, ":", "__", -1)
if _, err := fmt.Fprintf(w, "_%s()\n{\n", commandName); err != nil {
return err
}
if _, err := fmt.Fprintf(w, " last_command=%q\n", commandName); err != nil {
return err
}
if err := writeCommands(cmd, w); err != nil {
return err
}
if err := writeFlags(cmd, w); err != nil {
return err
}
if err := writeRequiredFlag(cmd, w); err != nil {
return err
}
if err := writeRequiredNouns(cmd, w); err != nil {
return err
}
if err := writeArgAliases(cmd, w); err != nil {
return err
}
if _, err := fmt.Fprintf(w, "}\n\n"); err != nil {
return err
}
return nil
buf.WriteString(fmt.Sprintf("_%s()\n{\n", commandName))
buf.WriteString(fmt.Sprintf(" last_command=%q\n", commandName))
writeCommands(buf, cmd)
writeFlags(buf, cmd)
writeRequiredFlag(buf, cmd)
writeRequiredNouns(buf, cmd)
writeArgAliases(buf, cmd)
buf.WriteString("}\n\n")
}
func (cmd *Command) GenBashCompletion(w io.Writer) error {
if err := preamble(w, cmd.Name()); err != nil {
return err
// GenBashCompletion generates bash completion file and writes to the passed writer.
func (c *Command) GenBashCompletion(w io.Writer) error {
buf := new(bytes.Buffer)
writePreamble(buf, c.Name())
if len(c.BashCompletionFunction) > 0 {
buf.WriteString(c.BashCompletionFunction + "\n")
}
if len(cmd.BashCompletionFunction) > 0 {
if _, err := fmt.Fprintf(w, "%s\n", cmd.BashCompletionFunction); err != nil {
return err
}
}
if err := gen(cmd, w); err != nil {
return err
}
return postscript(w, cmd.Name())
gen(buf, c)
writePostscript(buf, c.Name())
_, err := buf.WriteTo(w)
return err
}
func (cmd *Command) GenBashCompletionFile(filename string) error {
func nonCompletableFlag(flag *pflag.Flag) bool {
return flag.Hidden || len(flag.Deprecated) > 0
}
// GenBashCompletionFile generates bash completion file.
func (c *Command) GenBashCompletionFile(filename string) error {
outFile, err := os.Create(filename)
if err != nil {
return err
}
defer outFile.Close()
return cmd.GenBashCompletion(outFile)
return c.GenBashCompletion(outFile)
}
// MarkFlagRequired adds the BashCompOneRequiredFlag annotation to the named flag, if it exists.
func (cmd *Command) MarkFlagRequired(name string) error {
return MarkFlagRequired(cmd.Flags(), name)
func (c *Command) MarkFlagRequired(name string) error {
return MarkFlagRequired(c.Flags(), name)
}
// MarkPersistentFlagRequired adds the BashCompOneRequiredFlag annotation to the named persistent flag, if it exists.
func (cmd *Command) MarkPersistentFlagRequired(name string) error {
return MarkFlagRequired(cmd.PersistentFlags(), name)
func (c *Command) MarkPersistentFlagRequired(name string) error {
return MarkFlagRequired(c.PersistentFlags(), name)
}
// MarkFlagRequired adds the BashCompOneRequiredFlag annotation to the named flag in the flag set, if it exists.
@ -601,20 +508,20 @@ func MarkFlagRequired(flags *pflag.FlagSet, name string) error {
// MarkFlagFilename adds the BashCompFilenameExt annotation to the named flag, if it exists.
// Generated bash autocompletion will select filenames for the flag, limiting to named extensions if provided.
func (cmd *Command) MarkFlagFilename(name string, extensions ...string) error {
return MarkFlagFilename(cmd.Flags(), name, extensions...)
func (c *Command) MarkFlagFilename(name string, extensions ...string) error {
return MarkFlagFilename(c.Flags(), name, extensions...)
}
// MarkFlagCustom adds the BashCompCustom annotation to the named flag, if it exists.
// Generated bash autocompletion will call the bash function f for the flag.
func (cmd *Command) MarkFlagCustom(name string, f string) error {
return MarkFlagCustom(cmd.Flags(), name, f)
func (c *Command) MarkFlagCustom(name string, f string) error {
return MarkFlagCustom(c.Flags(), name, f)
}
// MarkPersistentFlagFilename adds the BashCompFilenameExt annotation to the named persistent flag, if it exists.
// Generated bash autocompletion will select filenames for the flag, limiting to named extensions if provided.
func (cmd *Command) MarkPersistentFlagFilename(name string, extensions ...string) error {
return MarkFlagFilename(cmd.PersistentFlags(), name, extensions...)
func (c *Command) MarkPersistentFlagFilename(name string, extensions ...string) error {
return MarkFlagFilename(c.PersistentFlags(), name, extensions...)
}
// MarkFlagFilename adds the BashCompFilenameExt annotation to the named flag in the flag set, if it exists.

View File

@ -18,7 +18,7 @@ func main() {
}
```
That will get you completions of subcommands and flags. If you make additional annotations to your code, you can get even more intelligent and flexible behavior.
`out.sh` will get you completions of subcommands and flags. Copy it to `/etc/bash_completion.d/` as described [here](https://debian-administration.org/article/316/An_introduction_to_bash_completion_part_1) and reset your terminal to use autocompletion. If you make additional annotations to your code, you can get even more intelligent and flexible behavior.
## Creating your own custom functions
@ -106,7 +106,7 @@ node pod replicationcontroller service
If your nouns have a number of aliases, you can define them alongside `ValidArgs` using `ArgAliases`:
```go`
```go
argAliases []string = { "pods", "nodes", "services", "svc", "replicationcontrollers", "rc" }
cmd := &cobra.Command{

View File

@ -27,48 +27,59 @@ import (
)
var templateFuncs = template.FuncMap{
"trim": strings.TrimSpace,
"trimRightSpace": trimRightSpace,
"appendIfNotPresent": appendIfNotPresent,
"rpad": rpad,
"gt": Gt,
"eq": Eq,
"trim": strings.TrimSpace,
"trimRightSpace": trimRightSpace,
"trimTrailingWhitespaces": trimRightSpace,
"appendIfNotPresent": appendIfNotPresent,
"rpad": rpad,
"gt": Gt,
"eq": Eq,
}
var initializers []func()
// automatic prefix matching can be a dangerous thing to automatically enable in CLI tools.
// Set this to true to enable it
// EnablePrefixMatching allows to set automatic prefix matching. Automatic prefix matching can be a dangerous thing
// to automatically enable in CLI tools.
// Set this to true to enable it.
var EnablePrefixMatching = false
//EnableCommandSorting controls sorting of the slice of commands, which is turned on by default.
//To disable sorting, set it to false.
// EnableCommandSorting controls sorting of the slice of commands, which is turned on by default.
// To disable sorting, set it to false.
var EnableCommandSorting = true
//AddTemplateFunc adds a template function that's available to Usage and Help
//template generation.
// MousetrapHelpText enables an information splash screen on Windows
// if the CLI is started from explorer.exe.
// To disable the mousetrap, just set this variable to blank string ("").
// Works only on Microsoft Windows.
var MousetrapHelpText string = `This is a command line tool.
You need to open cmd.exe and run it from there.
`
// AddTemplateFunc adds a template function that's available to Usage and Help
// template generation.
func AddTemplateFunc(name string, tmplFunc interface{}) {
templateFuncs[name] = tmplFunc
}
//AddTemplateFuncs adds multiple template functions availalble to Usage and
//Help template generation.
// AddTemplateFuncs adds multiple template functions that are available to Usage and
// Help template generation.
func AddTemplateFuncs(tmplFuncs template.FuncMap) {
for k, v := range tmplFuncs {
templateFuncs[k] = v
}
}
//OnInitialize takes a series of func() arguments and appends them to a slice of func().
// OnInitialize takes a series of func() arguments and appends them to a slice of func().
func OnInitialize(y ...func()) {
for _, x := range y {
initializers = append(initializers, x)
}
initializers = append(initializers, y...)
}
//Gt takes two types and checks whether the first type is greater than the second. In case of types Arrays, Chans,
//Maps and Slices, Gt will compare their lengths. Ints are compared directly while strings are first parsed as
//ints and then compared.
// FIXME Gt is unused by cobra and should be removed in a version 2. It exists only for compatibility with users of cobra.
// Gt takes two types and checks whether the first type is greater than the second. In case of types Arrays, Chans,
// Maps and Slices, Gt will compare their lengths. Ints are compared directly while strings are first parsed as
// ints and then compared.
func Gt(a interface{}, b interface{}) bool {
var left, right int64
av := reflect.ValueOf(a)
@ -96,7 +107,9 @@ func Gt(a interface{}, b interface{}) bool {
return left > right
}
//Eq takes two types and checks whether they are equal. Supported types are int and string. Unsupported types will panic.
// FIXME Eq is unused by cobra and should be removed in a version 2. It exists only for compatibility with users of cobra.
// Eq takes two types and checks whether they are equal. Supported types are int and string. Unsupported types will panic.
func Eq(a interface{}, b interface{}) bool {
av := reflect.ValueOf(a)
bv := reflect.ValueOf(b)
@ -116,7 +129,9 @@ func trimRightSpace(s string) string {
return strings.TrimRightFunc(s, unicode.IsSpace)
}
// appendIfNotPresent will append stringToAppend to the end of s, but only if it's not yet present in s
// FIXME appendIfNotPresent is unused by cobra and should be removed in a version 2. It exists only for compatibility with users of cobra.
// appendIfNotPresent will append stringToAppend to the end of s, but only if it's not yet present in s.
func appendIfNotPresent(s, stringToAppend string) string {
if strings.Contains(s, stringToAppend) {
return s
@ -124,7 +139,7 @@ func appendIfNotPresent(s, stringToAppend string) string {
return s + " " + stringToAppend
}
//rpad adds padding to the right of a string
// rpad adds padding to the right of a string.
func rpad(s string, padding int) string {
template := fmt.Sprintf("%%-%ds", padding)
return fmt.Sprintf(template, s)
@ -138,7 +153,7 @@ func tmpl(w io.Writer, text string, data interface{}) error {
return t.Execute(w, data)
}
// ld compares two strings and returns the levenshtein distance between them
// ld compares two strings and returns the levenshtein distance between them.
func ld(s, t string, ignoreCase bool) int {
if ignoreCase {
s = strings.ToLower(s)
@ -173,3 +188,12 @@ func ld(s, t string, ignoreCase bool) int {
}
return d[len(s)][len(t)]
}
func stringInSlice(a string, list []string) bool {
for _, b := range list {
if b == a {
return true
}
}
return false
}

File diff suppressed because it is too large Load Diff

View File

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

Some files were not shown because too many files have changed in this diff Show More