mirror of
https://github.com/etcd-io/etcd.git
synced 2026-02-05 06:46:49 +01:00
etcdctl: organize etcdctl subcommand & delete template
Signed-off-by: hwdef <hwdefcom@outlook.com>
This commit is contained in:
@@ -26,8 +26,10 @@ import (
|
||||
// NewAlarmCommand returns the cobra command for "alarm".
|
||||
func NewAlarmCommand() *cobra.Command {
|
||||
ac := &cobra.Command{
|
||||
Use: "alarm <subcommand>",
|
||||
Short: "Alarm related commands",
|
||||
Use: "alarm <subcommand>",
|
||||
Short: "Alarm related commands. Use `etcdctl alarm --help` to see subcommands",
|
||||
Long: "Alarm related commands",
|
||||
GroupID: groupClusterMaintenanceID,
|
||||
}
|
||||
|
||||
ac.AddCommand(NewAlarmDisarmCommand())
|
||||
|
||||
@@ -27,8 +27,10 @@ import (
|
||||
// NewAuthCommand returns the cobra command for "auth".
|
||||
func NewAuthCommand() *cobra.Command {
|
||||
ac := &cobra.Command{
|
||||
Use: "auth <enable or disable>",
|
||||
Short: "Enable or disable authentication",
|
||||
Use: "auth <enable or disable>",
|
||||
Short: "Enable or disable authentication. Use `etcdctl auth --help` to see subcommands",
|
||||
Long: "Enable or disable authentication",
|
||||
GroupID: groupAuthenticationID,
|
||||
}
|
||||
|
||||
ac.AddCommand(newAuthEnableCommand())
|
||||
|
||||
@@ -107,8 +107,10 @@ var checkDatascaleCfgMap = map[string]checkDatascaleCfg{
|
||||
// NewCheckCommand returns the cobra command for "check".
|
||||
func NewCheckCommand() *cobra.Command {
|
||||
cc := &cobra.Command{
|
||||
Use: "check <subcommand>",
|
||||
Short: "commands for checking properties of the etcd cluster",
|
||||
Use: "check <subcommand>",
|
||||
Short: "commands for checking properties of the etcd cluster. Use `etcdctl check --help` to see subcommands",
|
||||
Long: "commands for checking properties of the etcd cluster",
|
||||
GroupID: groupUtilityID,
|
||||
}
|
||||
|
||||
cc.AddCommand(NewCheckPerfCommand())
|
||||
|
||||
@@ -29,9 +29,10 @@ var compactPhysical bool
|
||||
// NewCompactionCommand returns the cobra command for "compaction".
|
||||
func NewCompactionCommand() *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "compaction [options] <revision>",
|
||||
Short: "Compacts the event history in etcd",
|
||||
Run: compactionCommandFunc,
|
||||
Use: "compaction [options] <revision>",
|
||||
Short: "Compacts the event history in etcd",
|
||||
Run: compactionCommandFunc,
|
||||
GroupID: groupKVID,
|
||||
}
|
||||
cmd.Flags().BoolVar(&compactPhysical, "physical", false, "'true' to wait for compaction to physically remove all old revisions")
|
||||
return cmd
|
||||
|
||||
@@ -78,6 +78,7 @@ PowerShell:
|
||||
cmd.Root().GenPowerShellCompletionWithDesc(os.Stdout)
|
||||
}
|
||||
},
|
||||
GroupID: groupUtilityID,
|
||||
}
|
||||
|
||||
return cmd
|
||||
|
||||
@@ -27,9 +27,10 @@ import (
|
||||
// NewDefragCommand returns the cobra command for "Defrag".
|
||||
func NewDefragCommand() *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "defrag",
|
||||
Short: "Defragments the storage of the etcd members with given endpoints",
|
||||
Run: defragCommandFunc,
|
||||
Use: "defrag",
|
||||
Short: "Defragments the storage of the etcd members with given endpoints",
|
||||
Run: defragCommandFunc,
|
||||
GroupID: groupClusterMaintenanceID,
|
||||
}
|
||||
cmd.PersistentFlags().BoolVar(&epClusterEndpoints, "cluster", false, "use all endpoints from the cluster member list")
|
||||
return cmd
|
||||
|
||||
@@ -35,9 +35,10 @@ var (
|
||||
// NewDelCommand returns the cobra command for "del".
|
||||
func NewDelCommand() *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "del [options] <key> [range_end]",
|
||||
Short: "Removes the specified key or range of keys [key, range_end)",
|
||||
Run: delCommandFunc,
|
||||
Use: "del [options] <key> [range_end]",
|
||||
Short: "Removes the specified key or range of keys [key, range_end)",
|
||||
Run: delCommandFunc,
|
||||
GroupID: groupKVID,
|
||||
}
|
||||
|
||||
cmd.Flags().BoolVar(&delPrefix, "prefix", false, "delete keys with matching prefix")
|
||||
|
||||
@@ -26,8 +26,10 @@ import (
|
||||
// NewDowngradeCommand returns the cobra command for "downgrade".
|
||||
func NewDowngradeCommand() *cobra.Command {
|
||||
dc := &cobra.Command{
|
||||
Use: "downgrade <TARGET_VERSION>",
|
||||
Short: "Downgrade related commands",
|
||||
Use: "downgrade <TARGET_VERSION>",
|
||||
Short: "Downgrade related commands. Use `etcdctl downgrade --help` to see subcommands",
|
||||
Long: "Downgrade related commands",
|
||||
GroupID: groupClusterMaintenanceID,
|
||||
}
|
||||
|
||||
dc.AddCommand(NewDowngradeValidateCommand())
|
||||
|
||||
@@ -33,9 +33,10 @@ var electListen bool
|
||||
// NewElectCommand returns the cobra command for "elect".
|
||||
func NewElectCommand() *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "elect <election-name> [proposal]",
|
||||
Short: "Observes and participates in leader election",
|
||||
Run: electCommandFunc,
|
||||
Use: "elect <election-name> [proposal]",
|
||||
Short: "Observes and participates in leader election",
|
||||
Run: electCommandFunc,
|
||||
GroupID: groupConcurrencyID,
|
||||
}
|
||||
cmd.Flags().BoolVarP(&electListen, "listen", "l", false, "observation mode")
|
||||
return cmd
|
||||
|
||||
@@ -39,8 +39,10 @@ var (
|
||||
// NewEndpointCommand returns the cobra command for "endpoint".
|
||||
func NewEndpointCommand() *cobra.Command {
|
||||
ec := &cobra.Command{
|
||||
Use: "endpoint <subcommand>",
|
||||
Short: "Endpoint related commands",
|
||||
Use: "endpoint <subcommand>",
|
||||
Short: "Endpoint related commands. Use `etcdctl endpoint --help` to see subcommands",
|
||||
Long: "Endpoint related commands",
|
||||
GroupID: groupClusterMaintenanceID,
|
||||
}
|
||||
|
||||
ec.PersistentFlags().BoolVar(&epClusterEndpoints, "cluster", false, "use all endpoints from the cluster member list")
|
||||
|
||||
@@ -44,9 +44,10 @@ var (
|
||||
// NewGetCommand returns the cobra command for "get".
|
||||
func NewGetCommand() *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "get [options] <key> [range_end]",
|
||||
Short: "Gets the key or a range of keys",
|
||||
Run: getCommandFunc,
|
||||
Use: "get [options] <key> [range_end]",
|
||||
Short: "Gets the key or a range of keys",
|
||||
Run: getCommandFunc,
|
||||
GroupID: groupKVID,
|
||||
}
|
||||
|
||||
cmd.Flags().StringVar(&getConsistency, "consistency", "l", "Linearizable(l) or Serializable(s)")
|
||||
|
||||
60
etcdctl/ctlv3/command/groups.go
Normal file
60
etcdctl/ctlv3/command/groups.go
Normal file
@@ -0,0 +1,60 @@
|
||||
// Copyright 2025 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.
|
||||
|
||||
package command
|
||||
|
||||
import "github.com/spf13/cobra"
|
||||
|
||||
const (
|
||||
groupKVID = "kv"
|
||||
groupClusterMaintenanceID = "cluster maintenance"
|
||||
groupConcurrencyID = "concurrency"
|
||||
groupAuthenticationID = "authentication"
|
||||
groupUtilityID = "utility"
|
||||
)
|
||||
|
||||
func NewKVGroup() *cobra.Group {
|
||||
return &cobra.Group{
|
||||
ID: groupKVID,
|
||||
Title: "Key-value commands",
|
||||
}
|
||||
}
|
||||
|
||||
func NewClusterMaintenanceGroup() *cobra.Group {
|
||||
return &cobra.Group{
|
||||
ID: groupClusterMaintenanceID,
|
||||
Title: "Cluster maintenance commands",
|
||||
}
|
||||
}
|
||||
|
||||
func NewConcurrencyGroup() *cobra.Group {
|
||||
return &cobra.Group{
|
||||
ID: groupConcurrencyID,
|
||||
Title: "Concurrency commands",
|
||||
}
|
||||
}
|
||||
|
||||
func NewAuthenticationGroup() *cobra.Group {
|
||||
return &cobra.Group{
|
||||
ID: groupAuthenticationID,
|
||||
Title: "Authentication commands",
|
||||
}
|
||||
}
|
||||
|
||||
func NewUtilityGroup() *cobra.Group {
|
||||
return &cobra.Group{
|
||||
ID: groupUtilityID,
|
||||
Title: "Utility commands",
|
||||
}
|
||||
}
|
||||
21
etcdctl/ctlv3/command/help_command.go
Normal file
21
etcdctl/ctlv3/command/help_command.go
Normal file
@@ -0,0 +1,21 @@
|
||||
// Copyright 2025 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.
|
||||
|
||||
package command
|
||||
|
||||
import "github.com/spf13/cobra"
|
||||
|
||||
func SetHelpCmdGroup(rootCmd *cobra.Command) {
|
||||
rootCmd.SetHelpCommandGroupID(groupUtilityID)
|
||||
}
|
||||
@@ -28,8 +28,10 @@ import (
|
||||
// NewLeaseCommand returns the cobra command for "lease".
|
||||
func NewLeaseCommand() *cobra.Command {
|
||||
lc := &cobra.Command{
|
||||
Use: "lease <subcommand>",
|
||||
Short: "Lease related commands",
|
||||
Use: "lease <subcommand>",
|
||||
Short: "Lease related commands. Use `etcdctl lease --help` to see subcommands",
|
||||
Long: "Lease related commands",
|
||||
GroupID: groupKVID,
|
||||
}
|
||||
|
||||
lc.AddCommand(NewLeaseGrantCommand())
|
||||
|
||||
@@ -35,9 +35,10 @@ var lockTTL = 10
|
||||
// NewLockCommand returns the cobra command for "lock".
|
||||
func NewLockCommand() *cobra.Command {
|
||||
c := &cobra.Command{
|
||||
Use: "lock <lockname> [exec-command arg1 arg2 ...]",
|
||||
Short: "Acquires a named lock",
|
||||
Run: lockCommandFunc,
|
||||
Use: "lock <lockname> [exec-command arg1 arg2 ...]",
|
||||
Short: "Acquires a named lock",
|
||||
Run: lockCommandFunc,
|
||||
GroupID: groupConcurrencyID,
|
||||
}
|
||||
c.Flags().IntVarP(&lockTTL, "ttl", "", lockTTL, "timeout for session")
|
||||
return c
|
||||
|
||||
@@ -53,9 +53,10 @@ var (
|
||||
// NewMakeMirrorCommand returns the cobra command for "makeMirror".
|
||||
func NewMakeMirrorCommand() *cobra.Command {
|
||||
c := &cobra.Command{
|
||||
Use: "make-mirror [options] <destination>",
|
||||
Short: "Makes a mirror at the destination etcd cluster",
|
||||
Run: makeMirrorCommandFunc,
|
||||
Use: "make-mirror [options] <destination>",
|
||||
Short: "Makes a mirror at the destination etcd cluster",
|
||||
Run: makeMirrorCommandFunc,
|
||||
GroupID: groupUtilityID,
|
||||
}
|
||||
|
||||
c.Flags().StringVar(&mmprefix, "prefix", "", "Key-value prefix to mirror")
|
||||
|
||||
@@ -35,8 +35,10 @@ var (
|
||||
// NewMemberCommand returns the cobra command for "member".
|
||||
func NewMemberCommand() *cobra.Command {
|
||||
mc := &cobra.Command{
|
||||
Use: "member <subcommand>",
|
||||
Short: "Membership related commands",
|
||||
Use: "member <subcommand>",
|
||||
Short: "Membership related commands. Use `etcdctl member --help` to see subcommands",
|
||||
Long: "Membership related commands",
|
||||
GroupID: groupClusterMaintenanceID,
|
||||
}
|
||||
|
||||
mc.AddCommand(NewMemberAddCommand())
|
||||
|
||||
@@ -27,9 +27,10 @@ import (
|
||||
// NewMoveLeaderCommand returns the cobra command for "move-leader".
|
||||
func NewMoveLeaderCommand() *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "move-leader <transferee-member-id>",
|
||||
Short: "Transfers leadership to another etcd cluster member.",
|
||||
Run: transferLeadershipCommandFunc,
|
||||
Use: "move-leader <transferee-member-id>",
|
||||
Short: "Transfers leadership to another etcd cluster member.",
|
||||
Run: transferLeadershipCommandFunc,
|
||||
GroupID: groupClusterMaintenanceID,
|
||||
}
|
||||
return cmd
|
||||
}
|
||||
|
||||
@@ -56,7 +56,8 @@ For example,
|
||||
$ cat file | put <key>
|
||||
will store the content of the file to <key>.
|
||||
`,
|
||||
Run: putCommandFunc,
|
||||
Run: putCommandFunc,
|
||||
GroupID: groupKVID,
|
||||
}
|
||||
cmd.Flags().StringVar(&leaseStr, "lease", "0", "lease ID (in hexadecimal) to attach to the key")
|
||||
cmd.Flags().BoolVar(&putPrevKV, "prev-kv", false, "return the previous key-value pair before modification")
|
||||
|
||||
@@ -32,8 +32,10 @@ var (
|
||||
// NewRoleCommand returns the cobra command for "role".
|
||||
func NewRoleCommand() *cobra.Command {
|
||||
ac := &cobra.Command{
|
||||
Use: "role <subcommand>",
|
||||
Short: "Role related commands",
|
||||
Use: "role <subcommand>",
|
||||
Short: "Role related commands. Use `etcdctl role --help` to see subcommands",
|
||||
Long: "Role related commands",
|
||||
GroupID: groupAuthenticationID,
|
||||
}
|
||||
|
||||
ac.AddCommand(newRoleAddCommand())
|
||||
|
||||
@@ -52,6 +52,7 @@ func NewSnapshotCommand() *cobra.Command {
|
||||
Use: "snapshot <subcommand>",
|
||||
Short: "Manages etcd node snapshots",
|
||||
Example: snapshotExample,
|
||||
GroupID: groupClusterMaintenanceID,
|
||||
}
|
||||
cmd.AddCommand(NewSnapshotSaveCommand())
|
||||
return cmd
|
||||
|
||||
@@ -59,7 +59,8 @@ put key2 "some extra key"
|
||||
---
|
||||
|
||||
Refer to https://github.com/etcd-io/etcd/blob/main/etcdctl/README.md#txn-options.`,
|
||||
Run: txnCommandFunc,
|
||||
Run: txnCommandFunc,
|
||||
GroupID: groupKVID,
|
||||
}
|
||||
cmd.Flags().BoolVarP(&txnInteractive, "interactive", "i", false, "Input transaction in interactive mode")
|
||||
return cmd
|
||||
@@ -150,16 +151,19 @@ func parseRequestUnion(line string) (*clientv3.Op, error) {
|
||||
opc := make(chan clientv3.Op, 1)
|
||||
|
||||
put := NewPutCommand()
|
||||
put.GroupID = ""
|
||||
put.Run = func(cmd *cobra.Command, args []string) {
|
||||
key, value, opts := getPutOp(args)
|
||||
opc <- clientv3.OpPut(key, value, opts...)
|
||||
}
|
||||
get := NewGetCommand()
|
||||
get.GroupID = ""
|
||||
get.Run = func(cmd *cobra.Command, args []string) {
|
||||
key, opts := getGetOp(args)
|
||||
opc <- clientv3.OpGet(key, opts...)
|
||||
}
|
||||
del := NewDelCommand()
|
||||
del.GroupID = ""
|
||||
del.Run = func(cmd *cobra.Command, args []string) {
|
||||
key, opts := getDelOp(args)
|
||||
opc <- clientv3.OpDelete(key, opts...)
|
||||
|
||||
@@ -31,8 +31,10 @@ var userShowDetail bool
|
||||
// NewUserCommand returns the cobra command for "user".
|
||||
func NewUserCommand() *cobra.Command {
|
||||
ac := &cobra.Command{
|
||||
Use: "user <subcommand>",
|
||||
Short: "User related commands",
|
||||
Use: "user <subcommand>",
|
||||
Short: "User related commands. Use `etcdctl user --help` to see subcommands",
|
||||
Long: "User related commands",
|
||||
GroupID: groupAuthenticationID,
|
||||
}
|
||||
|
||||
ac.AddCommand(newUserAddCommand())
|
||||
|
||||
@@ -25,9 +25,10 @@ import (
|
||||
// NewVersionCommand prints out the version of etcd.
|
||||
func NewVersionCommand() *cobra.Command {
|
||||
return &cobra.Command{
|
||||
Use: "version",
|
||||
Short: "Prints the version of etcdctl",
|
||||
Run: versionCommandFunc,
|
||||
Use: "version",
|
||||
Short: "Prints the version of etcdctl",
|
||||
Run: versionCommandFunc,
|
||||
GroupID: groupUtilityID,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -47,9 +47,10 @@ var (
|
||||
// NewWatchCommand returns the cobra command for "watch".
|
||||
func NewWatchCommand() *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "watch [options] [key or prefix] [range_end] [--] [exec-command arg1 arg2 ...]",
|
||||
Short: "Watches events stream on keys or prefixes",
|
||||
Run: watchCommandFunc,
|
||||
Use: "watch [options] [key or prefix] [range_end] [--] [exec-command arg1 arg2 ...]",
|
||||
Short: "Watches events stream on keys or prefixes",
|
||||
Run: watchCommandFunc,
|
||||
GroupID: groupKVID,
|
||||
}
|
||||
|
||||
cmd.Flags().BoolVarP(&watchInteractive, "interactive", "i", false, "Interactive mode")
|
||||
|
||||
@@ -21,9 +21,7 @@ import (
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
"go.etcd.io/etcd/api/v3/version"
|
||||
"go.etcd.io/etcd/etcdctl/v3/ctlv3/command"
|
||||
"go.etcd.io/etcd/etcdctl/v3/util"
|
||||
"go.etcd.io/etcd/pkg/v3/cobrautl"
|
||||
)
|
||||
|
||||
@@ -76,6 +74,14 @@ func init() {
|
||||
rootCmd.PersistentFlags().StringVarP(&globalFlags.TLS.ServerName, "discovery-srv", "d", "", "domain name to query for SRV records describing cluster endpoints")
|
||||
rootCmd.PersistentFlags().StringVarP(&globalFlags.DNSClusterServiceName, "discovery-srv-name", "", "", "service name to query when using DNS discovery")
|
||||
|
||||
rootCmd.AddGroup(
|
||||
command.NewKVGroup(),
|
||||
command.NewClusterMaintenanceGroup(),
|
||||
command.NewConcurrencyGroup(),
|
||||
command.NewAuthenticationGroup(),
|
||||
command.NewUtilityGroup(),
|
||||
)
|
||||
|
||||
rootCmd.AddCommand(
|
||||
command.NewGetCommand(),
|
||||
command.NewPutCommand(),
|
||||
@@ -101,16 +107,11 @@ func init() {
|
||||
command.NewCompletionCommand(),
|
||||
command.NewDowngradeCommand(),
|
||||
)
|
||||
}
|
||||
|
||||
func usageFunc(c *cobra.Command) error {
|
||||
return util.UsageFunc(c, version.Version, version.APIVersion)
|
||||
command.SetHelpCmdGroup(rootCmd)
|
||||
}
|
||||
|
||||
func Start() error {
|
||||
rootCmd.SetUsageFunc(usageFunc)
|
||||
// Make help just show the usage
|
||||
rootCmd.SetHelpTemplate(`{{.UsageString}}`)
|
||||
return rootCmd.Execute()
|
||||
}
|
||||
|
||||
|
||||
@@ -1,180 +0,0 @@
|
||||
// Copyright 2025 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 util
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"strings"
|
||||
"text/tabwriter"
|
||||
"text/template"
|
||||
|
||||
"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, " ")
|
||||
},
|
||||
"indent": func(s string) string {
|
||||
pad := strings.Repeat(" ", 2)
|
||||
return pad + strings.Replace(s, "\n", "\n"+pad, -1)
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
func init() {
|
||||
commandUsage := `
|
||||
{{ $cmd := .Cmd }}\
|
||||
{{ $cmdname := cmdName .Cmd .Cmd.Root }}\
|
||||
NAME:
|
||||
{{if not .Cmd.HasParent}}\
|
||||
{{printf "%s - %s" .Cmd.Name .Cmd.Short | indent}}
|
||||
{{else}}\
|
||||
{{printf "%s - %s" $cmdname .Cmd.Short | indent}}
|
||||
{{end}}\
|
||||
|
||||
USAGE:
|
||||
{{printf "%s" .Cmd.UseLine | indent}}
|
||||
{{ if not .Cmd.HasParent }}\
|
||||
|
||||
VERSION:
|
||||
{{printf "%s" .Version | indent}}
|
||||
{{end}}\
|
||||
{{if .Cmd.HasSubCommands}}\
|
||||
|
||||
API VERSION:
|
||||
{{.APIVersion | indent}}
|
||||
{{end}}\
|
||||
{{if .Cmd.HasExample}}\
|
||||
|
||||
Examples:
|
||||
{{.Cmd.Example}}
|
||||
{{end}}\
|
||||
{{if .Cmd.HasSubCommands}}\
|
||||
|
||||
COMMANDS:
|
||||
{{range .SubCommands}}\
|
||||
{{ $cmdname := cmdName . $cmd }}\
|
||||
{{ if .Runnable }}\
|
||||
{{printf "%s\t%s" $cmdname .Short | indent}}
|
||||
{{end}}\
|
||||
{{end}}\
|
||||
{{end}}\
|
||||
{{ if .Cmd.Long }}\
|
||||
|
||||
DESCRIPTION:
|
||||
{{range $line := descToLines .Cmd.Long}}{{printf "%s" $line | indent}}
|
||||
{{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.ReplaceAll(commandUsage, "\\\n", "")))
|
||||
}
|
||||
|
||||
func etcdFlagUsages(flagSet *pflag.FlagSet) string {
|
||||
x := new(strings.Builder)
|
||||
|
||||
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, version, APIVersion string) 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,
|
||||
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
|
||||
}
|
||||
Reference in New Issue
Block a user