Beautify kubectl help flag commands
Kubernetes-commit: 1c031d4fa8450550fa9a6bd5abe7fac45816156e
This commit is contained in:
parent
9e4cf278d1
commit
6a5a78c26b
|
@ -105,7 +105,7 @@ func NewCmdAPIResources(f cmdutil.Factory, ioStreams genericclioptions.IOStreams
|
|||
}
|
||||
|
||||
cmd.Flags().BoolVar(&o.NoHeaders, "no-headers", o.NoHeaders, "When using the default or custom-column output format, don't print headers (default print headers).")
|
||||
cmd.Flags().StringVarP(&o.Output, "output", "o", o.Output, "Output format. One of: wide|name.")
|
||||
cmd.Flags().StringVarP(&o.Output, "output", "o", o.Output, `Output format. One of: (wide, name).`)
|
||||
|
||||
cmd.Flags().StringVar(&o.APIGroup, "api-group", o.APIGroup, "Limit to resources in the specified API group.")
|
||||
cmd.Flags().BoolVar(&o.Namespaced, "namespaced", o.Namespaced, "If false, non-namespaced resources will be returned, otherwise returning namespaced resources by default.")
|
||||
|
|
|
@ -85,7 +85,7 @@ func NewCmdApplyViewLastApplied(f cmdutil.Factory, ioStreams genericclioptions.I
|
|||
},
|
||||
}
|
||||
|
||||
cmd.Flags().StringVarP(&options.OutputFormat, "output", "o", options.OutputFormat, "Output format. Must be one of yaml|json")
|
||||
cmd.Flags().StringVarP(&options.OutputFormat, "output", "o", options.OutputFormat, `Output format. Must be one of (yaml, json)`)
|
||||
cmd.Flags().BoolVar(&options.All, "all", options.All, "Select all resources in the namespace of the specified resource types")
|
||||
usage := "that contains the last-applied-configuration annotations"
|
||||
cmdutil.AddFilenameOptionFlags(cmd, &options.FilenameOptions, usage)
|
||||
|
|
|
@ -80,7 +80,7 @@ func NewCmdConfigGetContexts(streams genericclioptions.IOStreams, configAccess c
|
|||
}
|
||||
|
||||
cmd.Flags().Bool("no-headers", false, "When using the default or custom-column output format, don't print headers (default print headers).")
|
||||
cmd.Flags().StringP("output", "o", "", "Output format. One of: name")
|
||||
cmd.Flags().StringP("output", "o", "", `Output format. One of: (name).`)
|
||||
return cmd
|
||||
}
|
||||
|
||||
|
|
|
@ -162,7 +162,7 @@ func (f *PrintFlags) AddFlags(cmd *cobra.Command) {
|
|||
f.CustomColumnsFlags.AddFlags(cmd)
|
||||
|
||||
if f.OutputFormat != nil {
|
||||
cmd.Flags().StringVarP(f.OutputFormat, "output", "o", *f.OutputFormat, fmt.Sprintf("Output format. One of: %s See custom columns [https://kubernetes.io/docs/reference/kubectl/overview/#custom-columns], golang template [http://golang.org/pkg/text/template/#pkg-overview] and jsonpath template [https://kubernetes.io/docs/reference/kubectl/jsonpath/].", strings.Join(f.AllowedFormats(), "|")))
|
||||
cmd.Flags().StringVarP(f.OutputFormat, "output", "o", *f.OutputFormat, fmt.Sprintf(`Output format. One of: (%s). See custom columns [https://kubernetes.io/docs/reference/kubectl/overview/#custom-columns], golang template [http://golang.org/pkg/text/template/#pkg-overview] and jsonpath template [https://kubernetes.io/docs/reference/kubectl/jsonpath/].`, strings.Join(f.AllowedFormats(), ", ")))
|
||||
util.CheckErr(cmd.RegisterFlagCompletionFunc(
|
||||
"output",
|
||||
func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
|
||||
|
|
|
@ -0,0 +1,76 @@
|
|||
/*
|
||||
Copyright 2022 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"
|
||||
"io"
|
||||
"strings"
|
||||
|
||||
"github.com/mitchellh/go-wordwrap"
|
||||
flag "github.com/spf13/pflag"
|
||||
)
|
||||
|
||||
const offset = 10
|
||||
|
||||
// HelpFlagPrinter is a printer that
|
||||
// processes the help flag and print
|
||||
// it to i/o writer
|
||||
type HelpFlagPrinter struct {
|
||||
wrapLimit uint
|
||||
out io.Writer
|
||||
}
|
||||
|
||||
// NewHelpFlagPrinter will initialize a HelpFlagPrinter given the
|
||||
// i/o writer
|
||||
func NewHelpFlagPrinter(out io.Writer, wrapLimit uint) *HelpFlagPrinter {
|
||||
return &HelpFlagPrinter{
|
||||
wrapLimit: wrapLimit,
|
||||
out: out,
|
||||
}
|
||||
}
|
||||
|
||||
// PrintHelpFlag will beautify the help flags and print it out to p.out
|
||||
func (p *HelpFlagPrinter) PrintHelpFlag(flag *flag.Flag) {
|
||||
formatBuf := new(bytes.Buffer)
|
||||
writeFlag(formatBuf, flag)
|
||||
|
||||
wrappedStr := formatBuf.String()
|
||||
flagAndUsage := strings.Split(formatBuf.String(), "\n")
|
||||
flagStr := flagAndUsage[0]
|
||||
|
||||
// if the flag usage is longer than one line, wrap it again
|
||||
if len(flagAndUsage) > 1 {
|
||||
nextLines := strings.Join(flagAndUsage[1:], " ")
|
||||
wrappedUsages := wordwrap.WrapString(nextLines, p.wrapLimit-offset)
|
||||
wrappedStr = flagStr + "\n" + wrappedUsages
|
||||
}
|
||||
appendTabStr := strings.ReplaceAll(wrappedStr, "\n", "\n\t")
|
||||
|
||||
fmt.Fprintf(p.out, appendTabStr+"\n\n")
|
||||
}
|
||||
|
||||
// writeFlag will output the help flag based
|
||||
// on the format provided by getFlagFormat to i/o writer
|
||||
func writeFlag(out io.Writer, f *flag.Flag) {
|
||||
deprecated := ""
|
||||
if f.Deprecated != "" {
|
||||
deprecated = fmt.Sprintf(" (DEPRECATED: %s)", f.Deprecated)
|
||||
}
|
||||
fmt.Fprintf(out, getFlagFormat(f), f.Shorthand, f.Name, f.DefValue, f.Usage, deprecated)
|
||||
}
|
|
@ -23,10 +23,10 @@ import (
|
|||
"text/template"
|
||||
"unicode"
|
||||
|
||||
"k8s.io/kubectl/pkg/util/term"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
flag "github.com/spf13/pflag"
|
||||
|
||||
"k8s.io/kubectl/pkg/util/term"
|
||||
)
|
||||
|
||||
type FlagExposer interface {
|
||||
|
@ -160,7 +160,7 @@ func (t *templater) cmdGroupsString(c *cobra.Command) string {
|
|||
cmds := []string{cmdGroup.Message}
|
||||
for _, cmd := range cmdGroup.Commands {
|
||||
if cmd.IsAvailableCommand() {
|
||||
cmds = append(cmds, " "+rpad(cmd.Name(), cmd.NamePadding())+" "+cmd.Short)
|
||||
cmds = append(cmds, " "+rpad(cmd.Name(), cmd.NamePadding())+" "+cmd.Short)
|
||||
}
|
||||
}
|
||||
groups = append(groups, strings.Join(cmds, "\n"))
|
||||
|
@ -218,34 +218,40 @@ func (t *templater) usageLine(c *cobra.Command) string {
|
|||
return usage
|
||||
}
|
||||
|
||||
func flagsUsages(f *flag.FlagSet) string {
|
||||
x := new(bytes.Buffer)
|
||||
// flagsUsages will print out the kubectl help flags
|
||||
func flagsUsages(f *flag.FlagSet) (string, error) {
|
||||
flagBuf := new(bytes.Buffer)
|
||||
wrapLimit, err := term.GetWordWrapperLimit()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
printer := NewHelpFlagPrinter(flagBuf, wrapLimit)
|
||||
|
||||
f.VisitAll(func(flag *flag.Flag) {
|
||||
if flag.Hidden {
|
||||
return
|
||||
}
|
||||
format := "--%s=%s: %s%s\n"
|
||||
|
||||
if flag.Value.Type() == "string" {
|
||||
format = "--%s='%s': %s%s\n"
|
||||
}
|
||||
|
||||
if len(flag.Shorthand) > 0 {
|
||||
format = " -%s, " + format
|
||||
} else {
|
||||
format = " %s " + format
|
||||
}
|
||||
|
||||
deprecated := ""
|
||||
if flag.Deprecated != "" {
|
||||
deprecated = fmt.Sprintf(" (DEPRECATED: %s)", flag.Deprecated)
|
||||
}
|
||||
|
||||
fmt.Fprintf(x, format, flag.Shorthand, flag.Name, flag.DefValue, flag.Usage, deprecated)
|
||||
printer.PrintHelpFlag(flag)
|
||||
})
|
||||
|
||||
return x.String()
|
||||
return flagBuf.String(), nil
|
||||
}
|
||||
|
||||
// getFlagFormat will output the flag format
|
||||
func getFlagFormat(f *flag.Flag) string {
|
||||
var format string
|
||||
format = "--%s=%s:\n%s%s"
|
||||
if f.Value.Type() == "string" {
|
||||
format = "--%s='%s':\n%s%s"
|
||||
}
|
||||
|
||||
if len(f.Shorthand) > 0 {
|
||||
format = " -%s, " + format
|
||||
} else {
|
||||
format = " %s" + format
|
||||
}
|
||||
|
||||
return format
|
||||
}
|
||||
|
||||
func rpad(s string, padding int) string {
|
||||
|
|
|
@ -17,11 +17,14 @@ limitations under the License.
|
|||
package term
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"io"
|
||||
"os"
|
||||
|
||||
wordwrap "github.com/mitchellh/go-wordwrap"
|
||||
"github.com/moby/term"
|
||||
|
||||
"k8s.io/client-go/tools/remotecommand"
|
||||
)
|
||||
|
||||
type wordWrapWriter struct {
|
||||
|
@ -51,16 +54,7 @@ func NewResponsiveWriter(w io.Writer) io.Writer {
|
|||
if terminalSize == nil {
|
||||
return w
|
||||
}
|
||||
|
||||
var limit uint
|
||||
switch {
|
||||
case terminalSize.Width >= 120:
|
||||
limit = 120
|
||||
case terminalSize.Width >= 100:
|
||||
limit = 100
|
||||
case terminalSize.Width >= 80:
|
||||
limit = 80
|
||||
}
|
||||
limit := getTerminalLimitWidth(terminalSize)
|
||||
|
||||
return NewWordWrapWriter(w, limit)
|
||||
}
|
||||
|
@ -74,6 +68,32 @@ func NewWordWrapWriter(w io.Writer, limit uint) io.Writer {
|
|||
}
|
||||
}
|
||||
|
||||
func getTerminalLimitWidth(terminalSize *remotecommand.TerminalSize) uint {
|
||||
var limit uint
|
||||
switch {
|
||||
case terminalSize.Width >= 120:
|
||||
limit = 120
|
||||
case terminalSize.Width >= 100:
|
||||
limit = 100
|
||||
case terminalSize.Width >= 80:
|
||||
limit = 80
|
||||
}
|
||||
return limit
|
||||
}
|
||||
|
||||
func GetWordWrapperLimit() (uint, error) {
|
||||
stdout := os.Stdout
|
||||
fd := stdout.Fd()
|
||||
if !term.IsTerminal(fd) {
|
||||
return 0, errors.New("file descriptor is not a terminal")
|
||||
}
|
||||
terminalSize := GetSize(fd)
|
||||
if terminalSize == nil {
|
||||
return 0, errors.New("terminal size is nil")
|
||||
}
|
||||
return getTerminalLimitWidth(terminalSize), nil
|
||||
}
|
||||
|
||||
func (w wordWrapWriter) Write(p []byte) (nn int, err error) {
|
||||
if w.limit == 0 {
|
||||
return w.writer.Write(p)
|
||||
|
|
Loading…
Reference in New Issue