mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-23 11:50:44 +00:00
update kubectl help output for better organization
This commit is contained in:
parent
6faa91dfb1
commit
b411fe217f
@ -51,6 +51,7 @@ docs/man/man1/kubectl-get.1
|
|||||||
docs/man/man1/kubectl-label.1
|
docs/man/man1/kubectl-label.1
|
||||||
docs/man/man1/kubectl-logs.1
|
docs/man/man1/kubectl-logs.1
|
||||||
docs/man/man1/kubectl-namespace.1
|
docs/man/man1/kubectl-namespace.1
|
||||||
|
docs/man/man1/kubectl-options.1
|
||||||
docs/man/man1/kubectl-patch.1
|
docs/man/man1/kubectl-patch.1
|
||||||
docs/man/man1/kubectl-port-forward.1
|
docs/man/man1/kubectl-port-forward.1
|
||||||
docs/man/man1/kubectl-proxy.1
|
docs/man/man1/kubectl-proxy.1
|
||||||
@ -120,6 +121,7 @@ docs/user-guide/kubectl/kubectl_get.md
|
|||||||
docs/user-guide/kubectl/kubectl_label.md
|
docs/user-guide/kubectl/kubectl_label.md
|
||||||
docs/user-guide/kubectl/kubectl_logs.md
|
docs/user-guide/kubectl/kubectl_logs.md
|
||||||
docs/user-guide/kubectl/kubectl_namespace.md
|
docs/user-guide/kubectl/kubectl_namespace.md
|
||||||
|
docs/user-guide/kubectl/kubectl_options.md
|
||||||
docs/user-guide/kubectl/kubectl_patch.md
|
docs/user-guide/kubectl/kubectl_patch.md
|
||||||
docs/user-guide/kubectl/kubectl_port-forward.md
|
docs/user-guide/kubectl/kubectl_port-forward.md
|
||||||
docs/user-guide/kubectl/kubectl_proxy.md
|
docs/user-guide/kubectl/kubectl_proxy.md
|
||||||
@ -164,6 +166,7 @@ docs/yaml/kubectl/kubectl_get.yaml
|
|||||||
docs/yaml/kubectl/kubectl_label.yaml
|
docs/yaml/kubectl/kubectl_label.yaml
|
||||||
docs/yaml/kubectl/kubectl_logs.yaml
|
docs/yaml/kubectl/kubectl_logs.yaml
|
||||||
docs/yaml/kubectl/kubectl_namespace.yaml
|
docs/yaml/kubectl/kubectl_namespace.yaml
|
||||||
|
docs/yaml/kubectl/kubectl_options.yaml
|
||||||
docs/yaml/kubectl/kubectl_patch.yaml
|
docs/yaml/kubectl/kubectl_patch.yaml
|
||||||
docs/yaml/kubectl/kubectl_port-forward.yaml
|
docs/yaml/kubectl/kubectl_port-forward.yaml
|
||||||
docs/yaml/kubectl/kubectl_proxy.yaml
|
docs/yaml/kubectl/kubectl_proxy.yaml
|
||||||
|
3
docs/man/man1/kubectl-options.1
Normal file
3
docs/man/man1/kubectl-options.1
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
This file is autogenerated, but we've stopped checking such files into the
|
||||||
|
repository to reduce the need for rebases. Please run hack/generate-docs.sh to
|
||||||
|
populate this file.
|
36
docs/user-guide/kubectl/kubectl_options.md
Normal file
36
docs/user-guide/kubectl/kubectl_options.md
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
<!-- BEGIN MUNGE: UNVERSIONED_WARNING -->
|
||||||
|
|
||||||
|
<!-- BEGIN STRIP_FOR_RELEASE -->
|
||||||
|
|
||||||
|
<img src="http://kubernetes.io/kubernetes/img/warning.png" alt="WARNING"
|
||||||
|
width="25" height="25">
|
||||||
|
<img src="http://kubernetes.io/kubernetes/img/warning.png" alt="WARNING"
|
||||||
|
width="25" height="25">
|
||||||
|
<img src="http://kubernetes.io/kubernetes/img/warning.png" alt="WARNING"
|
||||||
|
width="25" height="25">
|
||||||
|
<img src="http://kubernetes.io/kubernetes/img/warning.png" alt="WARNING"
|
||||||
|
width="25" height="25">
|
||||||
|
<img src="http://kubernetes.io/kubernetes/img/warning.png" alt="WARNING"
|
||||||
|
width="25" height="25">
|
||||||
|
|
||||||
|
<h2>PLEASE NOTE: This document applies to the HEAD of the source tree</h2>
|
||||||
|
|
||||||
|
If you are using a released version of Kubernetes, you should
|
||||||
|
refer to the docs that go with that version.
|
||||||
|
|
||||||
|
Documentation for other releases can be found at
|
||||||
|
[releases.k8s.io](http://releases.k8s.io).
|
||||||
|
</strong>
|
||||||
|
--
|
||||||
|
|
||||||
|
<!-- END STRIP_FOR_RELEASE -->
|
||||||
|
|
||||||
|
<!-- END MUNGE: UNVERSIONED_WARNING -->
|
||||||
|
|
||||||
|
This file is autogenerated, but we've stopped checking such files into the
|
||||||
|
repository to reduce the need for rebases. Please run hack/generate-docs.sh to
|
||||||
|
populate this file.
|
||||||
|
|
||||||
|
<!-- BEGIN MUNGE: GENERATED_ANALYTICS -->
|
||||||
|
[]()
|
||||||
|
<!-- END MUNGE: GENERATED_ANALYTICS -->
|
3
docs/yaml/kubectl/kubectl_options.yaml
Normal file
3
docs/yaml/kubectl/kubectl_options.yaml
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
This file is autogenerated, but we've stopped checking such files into the
|
||||||
|
repository to reduce the need for rebases. Please run hack/generate-docs.sh to
|
||||||
|
populate this file.
|
@ -17,16 +17,18 @@ limitations under the License.
|
|||||||
package cmd
|
package cmd
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
|
||||||
"github.com/golang/glog"
|
|
||||||
"k8s.io/kubernetes/pkg/client/unversioned/clientcmd"
|
"k8s.io/kubernetes/pkg/client/unversioned/clientcmd"
|
||||||
cmdconfig "k8s.io/kubernetes/pkg/kubectl/cmd/config"
|
cmdconfig "k8s.io/kubernetes/pkg/kubectl/cmd/config"
|
||||||
"k8s.io/kubernetes/pkg/kubectl/cmd/rollout"
|
"k8s.io/kubernetes/pkg/kubectl/cmd/rollout"
|
||||||
"k8s.io/kubernetes/pkg/kubectl/cmd/set"
|
"k8s.io/kubernetes/pkg/kubectl/cmd/set"
|
||||||
|
"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
|
||||||
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
||||||
"k8s.io/kubernetes/pkg/util/flag"
|
"k8s.io/kubernetes/pkg/util/flag"
|
||||||
|
|
||||||
|
"github.com/golang/glog"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -222,59 +224,89 @@ Find more information at https://github.com/kubernetes/kubernetes.`,
|
|||||||
Run: runHelp,
|
Run: runHelp,
|
||||||
BashCompletionFunction: bash_completion_func,
|
BashCompletionFunction: bash_completion_func,
|
||||||
}
|
}
|
||||||
cmds.SetHelpTemplate(help_template)
|
|
||||||
cmds.SetUsageTemplate(usage_template)
|
|
||||||
|
|
||||||
f.BindFlags(cmds.PersistentFlags())
|
f.BindFlags(cmds.PersistentFlags())
|
||||||
f.BindExternalFlags(cmds.PersistentFlags())
|
f.BindExternalFlags(cmds.PersistentFlags())
|
||||||
|
|
||||||
cmds.SetHelpCommand(NewCmdHelp(f, out))
|
|
||||||
|
|
||||||
// From this point and forward we get warnings on flags that contain "_" separators
|
// From this point and forward we get warnings on flags that contain "_" separators
|
||||||
cmds.SetGlobalNormalizationFunc(flag.WarnWordSepNormalizeFunc)
|
cmds.SetGlobalNormalizationFunc(flag.WarnWordSepNormalizeFunc)
|
||||||
|
|
||||||
cmds.AddCommand(NewCmdGet(f, out, err))
|
groups := templates.CommandGroups{
|
||||||
cmds.AddCommand(set.NewCmdSet(f, out))
|
{
|
||||||
cmds.AddCommand(NewCmdDescribe(f, out))
|
Message: "Basic Commands (Beginner):",
|
||||||
cmds.AddCommand(NewCmdCreate(f, out))
|
Commands: []*cobra.Command{
|
||||||
cmds.AddCommand(NewCmdReplace(f, out))
|
NewCmdCreate(f, out),
|
||||||
cmds.AddCommand(NewCmdPatch(f, out))
|
NewCmdExposeService(f, out),
|
||||||
cmds.AddCommand(NewCmdDelete(f, out))
|
NewCmdRun(f, in, out, err),
|
||||||
cmds.AddCommand(NewCmdEdit(f, out, err))
|
set.NewCmdSet(f, out),
|
||||||
cmds.AddCommand(NewCmdApply(f, out))
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Message: "Basic Commands (Intermediate):",
|
||||||
|
Commands: []*cobra.Command{
|
||||||
|
NewCmdGet(f, out, err),
|
||||||
|
NewCmdExplain(f, out),
|
||||||
|
NewCmdEdit(f, out, err),
|
||||||
|
NewCmdDelete(f, out),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Message: "Deploy Commands:",
|
||||||
|
Commands: []*cobra.Command{
|
||||||
|
rollout.NewCmdRollout(f, out),
|
||||||
|
NewCmdRollingUpdate(f, out),
|
||||||
|
NewCmdScale(f, out),
|
||||||
|
NewCmdAutoscale(f, out),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Message: "Cluster Management Commands:",
|
||||||
|
Commands: []*cobra.Command{
|
||||||
|
NewCmdClusterInfo(f, out),
|
||||||
|
NewCmdTop(f, out),
|
||||||
|
NewCmdCordon(f, out),
|
||||||
|
NewCmdUncordon(f, out),
|
||||||
|
NewCmdDrain(f, out),
|
||||||
|
NewCmdTaint(f, out),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Message: "Troubleshooting and Debugging Commands:",
|
||||||
|
Commands: []*cobra.Command{
|
||||||
|
NewCmdDescribe(f, out),
|
||||||
|
NewCmdLogs(f, out),
|
||||||
|
NewCmdAttach(f, in, out, err),
|
||||||
|
NewCmdExec(f, in, out, err),
|
||||||
|
NewCmdPortForward(f, out, err),
|
||||||
|
NewCmdProxy(f, out),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Message: "Advanced Commands:",
|
||||||
|
Commands: []*cobra.Command{
|
||||||
|
NewCmdApply(f, out),
|
||||||
|
NewCmdPatch(f, out),
|
||||||
|
NewCmdReplace(f, out),
|
||||||
|
NewCmdConvert(f, out),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Message: "Settings Commands:",
|
||||||
|
Commands: []*cobra.Command{
|
||||||
|
NewCmdLabel(f, out),
|
||||||
|
NewCmdAnnotate(f, out),
|
||||||
|
NewCmdCompletion(f, out),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
groups.Add(cmds)
|
||||||
|
|
||||||
cmds.AddCommand(NewCmdNamespace(out))
|
filters := []string{
|
||||||
cmds.AddCommand(NewCmdLogs(f, out))
|
"options",
|
||||||
cmds.AddCommand(NewCmdRollingUpdate(f, out))
|
Deprecated("kubectl", "delete", cmds, NewCmdStop(f, out)),
|
||||||
cmds.AddCommand(NewCmdScale(f, out))
|
Deprecated("kubectl", "config set-context", cmds, NewCmdNamespace(out)),
|
||||||
cmds.AddCommand(NewCmdCordon(f, out))
|
}
|
||||||
cmds.AddCommand(NewCmdDrain(f, out))
|
templates.ActsAsRootCommand(cmds, filters, groups...)
|
||||||
cmds.AddCommand(NewCmdUncordon(f, out))
|
|
||||||
|
|
||||||
cmds.AddCommand(NewCmdAttach(f, in, out, err))
|
|
||||||
cmds.AddCommand(NewCmdExec(f, in, out, err))
|
|
||||||
cmds.AddCommand(NewCmdPortForward(f, out, err))
|
|
||||||
cmds.AddCommand(NewCmdProxy(f, out))
|
|
||||||
|
|
||||||
cmds.AddCommand(NewCmdRun(f, in, out, err))
|
|
||||||
cmds.AddCommand(NewCmdStop(f, out))
|
|
||||||
cmds.AddCommand(NewCmdExposeService(f, out))
|
|
||||||
cmds.AddCommand(NewCmdAutoscale(f, out))
|
|
||||||
cmds.AddCommand(rollout.NewCmdRollout(f, out))
|
|
||||||
|
|
||||||
cmds.AddCommand(NewCmdLabel(f, out))
|
|
||||||
cmds.AddCommand(NewCmdAnnotate(f, out))
|
|
||||||
cmds.AddCommand(NewCmdTaint(f, out))
|
|
||||||
|
|
||||||
cmds.AddCommand(cmdconfig.NewCmdConfig(clientcmd.NewDefaultPathOptions(), out))
|
|
||||||
cmds.AddCommand(NewCmdClusterInfo(f, out))
|
|
||||||
cmds.AddCommand(NewCmdApiVersions(f, out))
|
|
||||||
cmds.AddCommand(NewCmdVersion(f, out))
|
|
||||||
cmds.AddCommand(NewCmdExplain(f, out))
|
|
||||||
cmds.AddCommand(NewCmdConvert(f, out))
|
|
||||||
cmds.AddCommand(NewCmdCompletion(f, out))
|
|
||||||
|
|
||||||
cmds.AddCommand(NewCmdTop(f, out))
|
|
||||||
|
|
||||||
if cmds.Flag("namespace") != nil {
|
if cmds.Flag("namespace") != nil {
|
||||||
if cmds.Flag("namespace").Annotations == nil {
|
if cmds.Flag("namespace").Annotations == nil {
|
||||||
@ -286,6 +318,11 @@ Find more information at https://github.com/kubernetes/kubernetes.`,
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cmds.AddCommand(cmdconfig.NewCmdConfig(clientcmd.NewDefaultPathOptions(), out))
|
||||||
|
cmds.AddCommand(NewCmdVersion(f, out))
|
||||||
|
cmds.AddCommand(NewCmdApiVersions(f, out))
|
||||||
|
cmds.AddCommand(NewCmdOptions(out))
|
||||||
|
|
||||||
return cmds
|
return cmds
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -296,3 +333,10 @@ func runHelp(cmd *cobra.Command, args []string) {
|
|||||||
func printDeprecationWarning(command, alias string) {
|
func printDeprecationWarning(command, alias string) {
|
||||||
glog.Warningf("%s is DEPRECATED and will be removed in a future version. Use %s instead.", alias, command)
|
glog.Warningf("%s is DEPRECATED and will be removed in a future version. Use %s instead.", alias, command)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func Deprecated(baseName, to string, parent, cmd *cobra.Command) string {
|
||||||
|
cmd.Long = fmt.Sprintf("Deprecated: This command is deprecated, all its functionalities are covered by \"%s %s\"", baseName, to)
|
||||||
|
cmd.Short = fmt.Sprintf("Deprecated: %s", to)
|
||||||
|
parent.AddCommand(cmd)
|
||||||
|
return cmd.Name()
|
||||||
|
}
|
||||||
|
39
pkg/kubectl/cmd/options.go
Normal file
39
pkg/kubectl/cmd/options.go
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2016 The Kubernetes Authors.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package cmd
|
||||||
|
|
||||||
|
import (
|
||||||
|
"io"
|
||||||
|
|
||||||
|
"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
|
||||||
|
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
)
|
||||||
|
|
||||||
|
// NewCmdOptions implements the options command
|
||||||
|
func NewCmdOptions(out io.Writer) *cobra.Command {
|
||||||
|
cmd := &cobra.Command{
|
||||||
|
Use: "options",
|
||||||
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
|
cmd.Usage()
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
templates.UseOptionsTemplates(cmd)
|
||||||
|
|
||||||
|
return cmd
|
||||||
|
}
|
300
pkg/kubectl/cmd/templates/templater.go
Normal file
300
pkg/kubectl/cmd/templates/templater.go
Normal file
@ -0,0 +1,300 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2016 The Kubernetes Authors.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package templates
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
"text/template"
|
||||||
|
"unicode"
|
||||||
|
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
flag "github.com/spf13/pflag"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Content of this package was borrowed from openshift/origin.
|
||||||
|
|
||||||
|
type CommandGroup struct {
|
||||||
|
Message string
|
||||||
|
Commands []*cobra.Command
|
||||||
|
}
|
||||||
|
|
||||||
|
type CommandGroups []CommandGroup
|
||||||
|
|
||||||
|
func (g CommandGroups) Add(c *cobra.Command) {
|
||||||
|
for _, group := range g {
|
||||||
|
for _, command := range group.Commands {
|
||||||
|
c.AddCommand(command)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (g CommandGroups) Has(c *cobra.Command) bool {
|
||||||
|
for _, group := range g {
|
||||||
|
for _, command := range group.Commands {
|
||||||
|
if command == c {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func AddAdditionalCommands(g CommandGroups, message string, cmds []*cobra.Command) CommandGroups {
|
||||||
|
group := CommandGroup{Message: message}
|
||||||
|
for _, c := range cmds {
|
||||||
|
// Don't show commands that has no short description
|
||||||
|
if !g.Has(c) && len(c.Short) != 0 {
|
||||||
|
group.Commands = append(group.Commands, c)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if len(group.Commands) == 0 {
|
||||||
|
return g
|
||||||
|
}
|
||||||
|
return append(g, group)
|
||||||
|
}
|
||||||
|
|
||||||
|
func filter(cmds []*cobra.Command, names ...string) []*cobra.Command {
|
||||||
|
out := []*cobra.Command{}
|
||||||
|
for _, c := range cmds {
|
||||||
|
if c.Hidden {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
skip := false
|
||||||
|
for _, name := range names {
|
||||||
|
if name == c.Name() {
|
||||||
|
skip = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if skip {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
out = append(out, c)
|
||||||
|
}
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
|
type FlagExposer interface {
|
||||||
|
ExposeFlags(cmd *cobra.Command, flags ...string) FlagExposer
|
||||||
|
}
|
||||||
|
|
||||||
|
func ActsAsRootCommand(cmd *cobra.Command, filters []string, groups ...CommandGroup) FlagExposer {
|
||||||
|
if cmd == nil {
|
||||||
|
panic("nil root command")
|
||||||
|
}
|
||||||
|
cmd.SetHelpTemplate(MainHelpTemplate())
|
||||||
|
templater := &templater{
|
||||||
|
RootCmd: cmd,
|
||||||
|
UsageTemplate: MainUsageTemplate(),
|
||||||
|
CommandGroups: groups,
|
||||||
|
Filtered: filters,
|
||||||
|
}
|
||||||
|
cmd.SetUsageFunc(templater.UsageFunc())
|
||||||
|
return templater
|
||||||
|
}
|
||||||
|
|
||||||
|
func UseOptionsTemplates(cmd *cobra.Command) {
|
||||||
|
cmd.SetHelpTemplate(OptionsHelpTemplate())
|
||||||
|
templater := &templater{
|
||||||
|
UsageTemplate: OptionsUsageTemplate(),
|
||||||
|
}
|
||||||
|
cmd.SetUsageFunc(templater.UsageFunc())
|
||||||
|
}
|
||||||
|
|
||||||
|
type templater struct {
|
||||||
|
UsageTemplate string
|
||||||
|
RootCmd *cobra.Command
|
||||||
|
CommandGroups
|
||||||
|
Filtered []string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (templater *templater) ExposeFlags(cmd *cobra.Command, flags ...string) FlagExposer {
|
||||||
|
cmd.SetUsageFunc(templater.UsageFunc(flags...))
|
||||||
|
return templater
|
||||||
|
}
|
||||||
|
|
||||||
|
func (templater *templater) UsageFunc(exposedFlags ...string) func(*cobra.Command) error {
|
||||||
|
return func(c *cobra.Command) error {
|
||||||
|
t := template.New("custom")
|
||||||
|
|
||||||
|
t.Funcs(template.FuncMap{
|
||||||
|
"trim": strings.TrimSpace,
|
||||||
|
"trimRight": func(s string) string { return strings.TrimRightFunc(s, unicode.IsSpace) },
|
||||||
|
"trimLeft": func(s string) string { return strings.TrimLeftFunc(s, unicode.IsSpace) },
|
||||||
|
"gt": cobra.Gt,
|
||||||
|
"eq": cobra.Eq,
|
||||||
|
"rpad": rpad,
|
||||||
|
"appendIfNotPresent": appendIfNotPresent,
|
||||||
|
"flagsNotIntersected": flagsNotIntersected,
|
||||||
|
"visibleFlags": visibleFlags,
|
||||||
|
"flagsUsages": flagsUsages,
|
||||||
|
"indentLines": indentLines,
|
||||||
|
"cmdGroups": templater.cmdGroups,
|
||||||
|
"rootCmd": templater.rootCmdName,
|
||||||
|
"isRootCmd": templater.isRootCmd,
|
||||||
|
"optionsCmdFor": templater.optionsCmdFor,
|
||||||
|
"usageLine": templater.usageLine,
|
||||||
|
"exposed": func(c *cobra.Command) *flag.FlagSet {
|
||||||
|
exposed := flag.NewFlagSet("exposed", flag.ContinueOnError)
|
||||||
|
if len(exposedFlags) > 0 {
|
||||||
|
for _, name := range exposedFlags {
|
||||||
|
if flag := c.Flags().Lookup(name); flag != nil {
|
||||||
|
exposed.AddFlag(flag)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return exposed
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
template.Must(t.Parse(templater.UsageTemplate))
|
||||||
|
return t.Execute(c.OutOrStdout(), c)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (templater *templater) cmdGroups(c *cobra.Command, all []*cobra.Command) []CommandGroup {
|
||||||
|
if len(templater.CommandGroups) > 0 && c == templater.RootCmd {
|
||||||
|
all = filter(all, templater.Filtered...)
|
||||||
|
return AddAdditionalCommands(templater.CommandGroups, "Other Commands:", all)
|
||||||
|
}
|
||||||
|
all = filter(all, "options")
|
||||||
|
return []CommandGroup{
|
||||||
|
{
|
||||||
|
Message: "Available Commands:",
|
||||||
|
Commands: all,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *templater) rootCmdName(c *cobra.Command) string {
|
||||||
|
return t.rootCmd(c).CommandPath()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *templater) isRootCmd(c *cobra.Command) bool {
|
||||||
|
return t.rootCmd(c) == c
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *templater) parents(c *cobra.Command) []*cobra.Command {
|
||||||
|
parents := []*cobra.Command{c}
|
||||||
|
for current := c; !t.isRootCmd(current) && current.HasParent(); {
|
||||||
|
current = current.Parent()
|
||||||
|
parents = append(parents, current)
|
||||||
|
}
|
||||||
|
return parents
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *templater) rootCmd(c *cobra.Command) *cobra.Command {
|
||||||
|
if c != nil && !c.HasParent() {
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
if t.RootCmd == nil {
|
||||||
|
panic("nil root cmd")
|
||||||
|
}
|
||||||
|
return t.RootCmd
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *templater) optionsCmdFor(c *cobra.Command) string {
|
||||||
|
if !c.Runnable() {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
rootCmdStructure := t.parents(c)
|
||||||
|
for i := len(rootCmdStructure) - 1; i >= 0; i-- {
|
||||||
|
cmd := rootCmdStructure[i]
|
||||||
|
if _, _, err := cmd.Find([]string{"options"}); err == nil {
|
||||||
|
return cmd.CommandPath() + " options"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *templater) usageLine(c *cobra.Command) string {
|
||||||
|
usage := c.UseLine()
|
||||||
|
suffix := "[options]"
|
||||||
|
if c.HasFlags() && !strings.Contains(usage, suffix) {
|
||||||
|
usage += " " + suffix
|
||||||
|
}
|
||||||
|
return usage
|
||||||
|
}
|
||||||
|
|
||||||
|
func flagsUsages(f *flag.FlagSet) string {
|
||||||
|
x := new(bytes.Buffer)
|
||||||
|
|
||||||
|
f.VisitAll(func(flag *flag.Flag) {
|
||||||
|
if flag.Hidden {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
format := "--%s=%s: %s\n"
|
||||||
|
|
||||||
|
if flag.Value.Type() == "string" {
|
||||||
|
format = "--%s='%s': %s\n"
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(flag.Shorthand) > 0 {
|
||||||
|
format = " -%s, " + format
|
||||||
|
} else {
|
||||||
|
format = " %s " + format
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Fprintf(x, format, flag.Shorthand, flag.Name, flag.DefValue, flag.Usage)
|
||||||
|
})
|
||||||
|
|
||||||
|
return x.String()
|
||||||
|
}
|
||||||
|
|
||||||
|
func rpad(s string, padding int) string {
|
||||||
|
template := fmt.Sprintf("%%-%ds", padding)
|
||||||
|
return fmt.Sprintf(template, s)
|
||||||
|
}
|
||||||
|
|
||||||
|
func indentLines(s string, indentation int) string {
|
||||||
|
r := []string{}
|
||||||
|
for _, line := range strings.Split(s, "\n") {
|
||||||
|
indented := strings.Repeat(" ", indentation) + line
|
||||||
|
r = append(r, indented)
|
||||||
|
}
|
||||||
|
return strings.Join(r, "\n")
|
||||||
|
}
|
||||||
|
|
||||||
|
func appendIfNotPresent(s, stringToAppend string) string {
|
||||||
|
if strings.Contains(s, stringToAppend) {
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
return s + " " + stringToAppend
|
||||||
|
}
|
||||||
|
|
||||||
|
func flagsNotIntersected(l *flag.FlagSet, r *flag.FlagSet) *flag.FlagSet {
|
||||||
|
f := flag.NewFlagSet("notIntersected", flag.ContinueOnError)
|
||||||
|
l.VisitAll(func(flag *flag.Flag) {
|
||||||
|
if r.Lookup(flag.Name) == nil {
|
||||||
|
f.AddFlag(flag)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
return f
|
||||||
|
}
|
||||||
|
|
||||||
|
func visibleFlags(l *flag.FlagSet) *flag.FlagSet {
|
||||||
|
hidden := "help"
|
||||||
|
f := flag.NewFlagSet("visible", flag.ContinueOnError)
|
||||||
|
l.VisitAll(func(flag *flag.Flag) {
|
||||||
|
if flag.Name != hidden {
|
||||||
|
f.AddFlag(flag)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
return f
|
||||||
|
}
|
99
pkg/kubectl/cmd/templates/templates.go
Normal file
99
pkg/kubectl/cmd/templates/templates.go
Normal file
@ -0,0 +1,99 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2016 The Kubernetes Authors.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package templates
|
||||||
|
|
||||||
|
import "strings"
|
||||||
|
|
||||||
|
func MainHelpTemplate() string {
|
||||||
|
return decorate(mainHelpTemplate, false)
|
||||||
|
}
|
||||||
|
|
||||||
|
func MainUsageTemplate() string {
|
||||||
|
return decorate(mainUsageTemplate, true) + "\n"
|
||||||
|
}
|
||||||
|
|
||||||
|
func OptionsHelpTemplate() string {
|
||||||
|
return decorate(optionsHelpTemplate, false)
|
||||||
|
}
|
||||||
|
|
||||||
|
func OptionsUsageTemplate() string {
|
||||||
|
return decorate(optionsUsageTemplate, false)
|
||||||
|
}
|
||||||
|
|
||||||
|
func decorate(template string, trim bool) string {
|
||||||
|
if trim && len(strings.Trim(template, " ")) > 0 {
|
||||||
|
template = strings.Trim(template, "\n")
|
||||||
|
}
|
||||||
|
return template
|
||||||
|
}
|
||||||
|
|
||||||
|
const (
|
||||||
|
vars = `{{$isRootCmd := isRootCmd .}}` +
|
||||||
|
`{{$rootCmd := rootCmd .}}` +
|
||||||
|
`{{$visibleFlags := visibleFlags (flagsNotIntersected .LocalFlags .PersistentFlags)}}` +
|
||||||
|
`{{$explicitlyExposedFlags := exposed .}}` +
|
||||||
|
`{{$optionsCmdFor := optionsCmdFor .}}` +
|
||||||
|
`{{$usageLine := usageLine .}}`
|
||||||
|
|
||||||
|
mainHelpTemplate = `{{with or .Long .Short }}{{. | trim}}{{end}}{{if or .Runnable .HasSubCommands}}{{.UsageString}}{{end}}`
|
||||||
|
|
||||||
|
mainUsageTemplate = vars +
|
||||||
|
// ALIASES
|
||||||
|
`{{if gt .Aliases 0}}
|
||||||
|
|
||||||
|
Aliases:
|
||||||
|
{{.NameAndAliases}}{{end}}` +
|
||||||
|
|
||||||
|
// EXAMPLES
|
||||||
|
`{{if .HasExample}}
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
{{ indentLines (.Example | trimLeft) 2 }}{{end}}` +
|
||||||
|
|
||||||
|
// SUBCOMMANDS
|
||||||
|
`{{ if .HasAvailableSubCommands}}
|
||||||
|
{{range cmdGroups . .Commands}}
|
||||||
|
{{.Message}}
|
||||||
|
{{range .Commands}}{{if .Runnable}} {{rpad .Name .NamePadding }} {{.Short}}
|
||||||
|
{{end}}{{end}}{{end}}{{end}}` +
|
||||||
|
|
||||||
|
// VISIBLE FLAGS
|
||||||
|
`{{ if or $visibleFlags.HasFlags $explicitlyExposedFlags.HasFlags}}
|
||||||
|
|
||||||
|
Options:
|
||||||
|
{{ if $visibleFlags.HasFlags}}{{flagsUsages $visibleFlags}}{{end}}{{ if $explicitlyExposedFlags.HasFlags}}{{flagsUsages $explicitlyExposedFlags}}{{end}}{{end}}` +
|
||||||
|
|
||||||
|
// USAGE LINE
|
||||||
|
`{{if and .Runnable (ne .UseLine "") (ne .UseLine $rootCmd)}}
|
||||||
|
Usage:
|
||||||
|
{{$usageLine}}
|
||||||
|
{{end}}` +
|
||||||
|
|
||||||
|
// TIPS: --help
|
||||||
|
`{{ if .HasSubCommands }}
|
||||||
|
Use "{{$rootCmd}} <command> --help" for more information about a given command.{{end}}` +
|
||||||
|
|
||||||
|
// TIPS: global options
|
||||||
|
`{{ if $optionsCmdFor}}
|
||||||
|
Use "{{$optionsCmdFor}}" for a list of global command-line options (applies to all commands).{{end}}`
|
||||||
|
|
||||||
|
optionsHelpTemplate = ``
|
||||||
|
|
||||||
|
optionsUsageTemplate = `{{ if .HasInheritedFlags}}The following options can be passed to any command:
|
||||||
|
|
||||||
|
{{flagsUsages .InheritedFlags}}{{end}}`
|
||||||
|
)
|
Loading…
Reference in New Issue
Block a user