123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175 |
- // Copyright 2015 The etcd 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.
- // copied from https://github.com/rkt/rkt/blob/master/rkt/help.go
- package runner
- import (
- "bytes"
- "fmt"
- "io"
- "os"
- "strings"
- "text/tabwriter"
- "text/template"
- "github.com/coreos/etcd/version"
- "github.com/spf13/cobra"
- "github.com/spf13/pflag"
- )
- var (
- commandUsageTemplate *template.Template
- templFuncs = template.FuncMap{
- "descToLines": func(s string) []string {
- // trim leading/trailing whitespace and split into slice of lines
- return strings.Split(strings.Trim(s, "\n\t "), "\n")
- },
- "cmdName": func(cmd *cobra.Command, startCmd *cobra.Command) string {
- parts := []string{cmd.Name()}
- for cmd.HasParent() && cmd.Parent().Name() != startCmd.Name() {
- cmd = cmd.Parent()
- parts = append([]string{cmd.Name()}, parts...)
- }
- return strings.Join(parts, " ")
- },
- }
- )
- func init() {
- commandUsage := `
- {{ $cmd := .Cmd }}\
- {{ $cmdname := cmdName .Cmd .Cmd.Root }}\
- NAME:
- {{ if not .Cmd.HasParent }}\
- {{printf "\t%s - %s" .Cmd.Name .Cmd.Short}}
- {{else}}\
- {{printf "\t%s - %s" $cmdname .Cmd.Short}}
- {{end}}\
- USAGE:
- {{printf "\t%s" .Cmd.UseLine}}
- {{ if not .Cmd.HasParent }}\
- VERSION:
- {{printf "\t%s" .Version}}
- {{end}}\
- {{if .Cmd.HasSubCommands}}\
- API VERSION:
- {{printf "\t%s" .APIVersion}}
- {{end}}\
- {{if .Cmd.HasSubCommands}}\
- COMMANDS:
- {{range .SubCommands}}\
- {{ $cmdname := cmdName . $cmd }}\
- {{ if .Runnable }}\
- {{printf "\t%s\t%s" $cmdname .Short}}
- {{end}}\
- {{end}}\
- {{end}}\
- {{ if .Cmd.Long }}\
- DESCRIPTION:
- {{range $line := descToLines .Cmd.Long}}{{printf "\t%s" $line}}
- {{end}}\
- {{end}}\
- {{if .Cmd.HasLocalFlags}}\
- OPTIONS:
- {{.LocalFlags}}\
- {{end}}\
- {{if .Cmd.HasInheritedFlags}}\
- GLOBAL OPTIONS:
- {{.GlobalFlags}}\
- {{end}}
- `[1:]
- commandUsageTemplate = template.Must(template.New("command_usage").Funcs(templFuncs).Parse(strings.Replace(commandUsage, "\\\n", "", -1)))
- }
- func etcdFlagUsages(flagSet *pflag.FlagSet) string {
- x := new(bytes.Buffer)
- flagSet.VisitAll(func(flag *pflag.Flag) {
- if len(flag.Deprecated) > 0 {
- return
- }
- var format string
- if len(flag.Shorthand) > 0 {
- format = " -%s, --%s"
- } else {
- format = " %s --%s"
- }
- if len(flag.NoOptDefVal) > 0 {
- format = format + "["
- }
- if flag.Value.Type() == "string" {
- // put quotes on the value
- format = format + "=%q"
- } else {
- format = format + "=%s"
- }
- if len(flag.NoOptDefVal) > 0 {
- format = format + "]"
- }
- format = format + "\t%s\n"
- shorthand := flag.Shorthand
- fmt.Fprintf(x, format, shorthand, flag.Name, flag.DefValue, flag.Usage)
- })
- return x.String()
- }
- func getSubCommands(cmd *cobra.Command) []*cobra.Command {
- var subCommands []*cobra.Command
- for _, subCmd := range cmd.Commands() {
- subCommands = append(subCommands, subCmd)
- subCommands = append(subCommands, getSubCommands(subCmd)...)
- }
- return subCommands
- }
- func usageFunc(cmd *cobra.Command) error {
- subCommands := getSubCommands(cmd)
- tabOut := getTabOutWithWriter(os.Stdout)
- commandUsageTemplate.Execute(tabOut, struct {
- Cmd *cobra.Command
- LocalFlags string
- GlobalFlags string
- SubCommands []*cobra.Command
- Version string
- APIVersion string
- }{
- cmd,
- etcdFlagUsages(cmd.LocalFlags()),
- etcdFlagUsages(cmd.InheritedFlags()),
- subCommands,
- version.Version,
- version.APIVersion,
- })
- tabOut.Flush()
- return nil
- }
- func getTabOutWithWriter(writer io.Writer) *tabwriter.Writer {
- aTabOut := new(tabwriter.Writer)
- aTabOut.Init(writer, 0, 8, 1, '\t', 0)
- return aTabOut
- }
|