mirror of https://github.com/k3s-io/k3s
update kubectl help output for better organization
parent
6faa91dfb1
commit
b411fe217f
|
@ -51,6 +51,7 @@ docs/man/man1/kubectl-get.1
|
|||
docs/man/man1/kubectl-label.1
|
||||
docs/man/man1/kubectl-logs.1
|
||||
docs/man/man1/kubectl-namespace.1
|
||||
docs/man/man1/kubectl-options.1
|
||||
docs/man/man1/kubectl-patch.1
|
||||
docs/man/man1/kubectl-port-forward.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_logs.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_port-forward.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_logs.yaml
|
||||
docs/yaml/kubectl/kubectl_namespace.yaml
|
||||
docs/yaml/kubectl/kubectl_options.yaml
|
||||
docs/yaml/kubectl/kubectl_patch.yaml
|
||||
docs/yaml/kubectl/kubectl_port-forward.yaml
|
||||
docs/yaml/kubectl/kubectl_proxy.yaml
|
||||
|
|
|
@ -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.
|
|
@ -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 -->
|
||||
[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/user-guide/kubectl/kubectl_options.md?pixel)]()
|
||||
<!-- END MUNGE: GENERATED_ANALYTICS -->
|
|
@ -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
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
|
||||
"github.com/golang/glog"
|
||||
"k8s.io/kubernetes/pkg/client/unversioned/clientcmd"
|
||||
cmdconfig "k8s.io/kubernetes/pkg/kubectl/cmd/config"
|
||||
"k8s.io/kubernetes/pkg/kubectl/cmd/rollout"
|
||||
"k8s.io/kubernetes/pkg/kubectl/cmd/set"
|
||||
"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
|
||||
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
||||
"k8s.io/kubernetes/pkg/util/flag"
|
||||
|
||||
"github.com/golang/glog"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
|
@ -222,59 +224,89 @@ Find more information at https://github.com/kubernetes/kubernetes.`,
|
|||
Run: runHelp,
|
||||
BashCompletionFunction: bash_completion_func,
|
||||
}
|
||||
cmds.SetHelpTemplate(help_template)
|
||||
cmds.SetUsageTemplate(usage_template)
|
||||
|
||||
f.BindFlags(cmds.PersistentFlags())
|
||||
f.BindExternalFlags(cmds.PersistentFlags())
|
||||
|
||||
cmds.SetHelpCommand(NewCmdHelp(f, out))
|
||||
|
||||
// From this point and forward we get warnings on flags that contain "_" separators
|
||||
cmds.SetGlobalNormalizationFunc(flag.WarnWordSepNormalizeFunc)
|
||||
|
||||
cmds.AddCommand(NewCmdGet(f, out, err))
|
||||
cmds.AddCommand(set.NewCmdSet(f, out))
|
||||
cmds.AddCommand(NewCmdDescribe(f, out))
|
||||
cmds.AddCommand(NewCmdCreate(f, out))
|
||||
cmds.AddCommand(NewCmdReplace(f, out))
|
||||
cmds.AddCommand(NewCmdPatch(f, out))
|
||||
cmds.AddCommand(NewCmdDelete(f, out))
|
||||
cmds.AddCommand(NewCmdEdit(f, out, err))
|
||||
cmds.AddCommand(NewCmdApply(f, out))
|
||||
groups := templates.CommandGroups{
|
||||
{
|
||||
Message: "Basic Commands (Beginner):",
|
||||
Commands: []*cobra.Command{
|
||||
NewCmdCreate(f, out),
|
||||
NewCmdExposeService(f, out),
|
||||
NewCmdRun(f, in, out, err),
|
||||
set.NewCmdSet(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))
|
||||
cmds.AddCommand(NewCmdLogs(f, out))
|
||||
cmds.AddCommand(NewCmdRollingUpdate(f, out))
|
||||
cmds.AddCommand(NewCmdScale(f, out))
|
||||
cmds.AddCommand(NewCmdCordon(f, out))
|
||||
cmds.AddCommand(NewCmdDrain(f, out))
|
||||
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))
|
||||
filters := []string{
|
||||
"options",
|
||||
Deprecated("kubectl", "delete", cmds, NewCmdStop(f, out)),
|
||||
Deprecated("kubectl", "config set-context", cmds, NewCmdNamespace(out)),
|
||||
}
|
||||
templates.ActsAsRootCommand(cmds, filters, groups...)
|
||||
|
||||
if cmds.Flag("namespace") != 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
|
||||
}
|
||||
|
||||
|
@ -296,3 +333,10 @@ func runHelp(cmd *cobra.Command, args []string) {
|
|||
func printDeprecationWarning(command, alias string) {
|
||||
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()
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
|
@ -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
|
||||
}
|
|
@ -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