delve/cmd/dlv/cmds/helphelpers/help.go
Alessandro Arzilli caf6df0eb9
Documentation,cmd/dlv: clean up command line usage help (#3395)
Due to some very old mistakes too many of Delve's flags are declared as
persistent on cobra's root command. For example the headless flag is a
global flag but does not apply to connect, dap or trace; the backend
flag does not apply to replay, core and dap; etc.

Almost all global flags should have been declared as local flags on
individual subcommands. Unfortunately we can not change this without
breaking backwards compatibility, for example:

   dlv --headless debug

would not parse if headless was a flag of debug instead of a global
flag.

Instead we alter usage function and the markdown generation script to
strategically hide the flags that don't apply.

Fixes #2361
2023-08-09 10:37:55 -07:00

97 lines
2.5 KiB
Go

package helphelpers
import (
"github.com/spf13/cobra"
"github.com/spf13/pflag"
)
// Prepare prepares cmd flag set for the invocation of its usage function by
// hiding flags that we want cobra to parse but we don't want to show to the
// user.
// We do this because not all flags associated with the root command are
// valid for all subcommands but we don't want to move them out of the root
// command and into subcommands, since that would change how cobra parses
// the command line.
//
// For example:
//
// dlv --headless debug
//
// must parse successfully even though the headless flag is not applicable
// to the 'connect' subcommand.
//
// Prepare is a destructive command, cmd can not be reused after it has been
// called.
func Prepare(cmd *cobra.Command) {
switch cmd.Name() {
case "dlv", "help", "run", "version":
hideAllFlags(cmd)
case "attach":
hideFlag(cmd, "build-flags")
hideFlag(cmd, "disable-aslr")
hideFlag(cmd, "redirect")
hideFlag(cmd, "wd")
case "connect":
hideFlag(cmd, "accept-multiclient")
hideFlag(cmd, "allow-non-terminal-interactive")
hideFlag(cmd, "api-version")
hideFlag(cmd, "build-flags")
hideFlag(cmd, "check-go-version")
hideFlag(cmd, "disable-aslr")
hideFlag(cmd, "headless")
hideFlag(cmd, "listen")
hideFlag(cmd, "only-same-user")
hideFlag(cmd, "redirect")
hideFlag(cmd, "wd")
case "dap":
hideFlag(cmd, "headless")
hideFlag(cmd, "accept-multiclient")
hideFlag(cmd, "init")
hideFlag(cmd, "backend")
hideFlag(cmd, "build-flags")
hideFlag(cmd, "wd")
hideFlag(cmd, "redirect")
hideFlag(cmd, "api-version")
hideFlag(cmd, "allow-non-terminal-interactive")
case "debug", "test":
// All flags apply
case "exec":
hideFlag(cmd, "build-flags")
case "replay", "core":
hideFlag(cmd, "backend")
hideFlag(cmd, "build-flags")
hideFlag(cmd, "disable-aslr")
hideFlag(cmd, "redirect")
hideFlag(cmd, "wd")
case "trace":
hideFlag(cmd, "accept-multiclient")
hideFlag(cmd, "allow-non-terminal-interactive")
hideFlag(cmd, "api-version")
hideFlag(cmd, "headless")
hideFlag(cmd, "init")
hideFlag(cmd, "listen")
hideFlag(cmd, "only-same-user")
}
}
func hideAllFlags(cmd *cobra.Command) {
cmd.PersistentFlags().VisitAll(func(flag *pflag.Flag) {
flag.Hidden = true
})
cmd.Flags().VisitAll(func(flag *pflag.Flag) {
flag.Hidden = true
})
}
func hideFlag(cmd *cobra.Command, name string) {
if cmd == nil {
return
}
flag := cmd.Flags().Lookup(name)
if flag != nil {
flag.Hidden = true
return
}
hideFlag(cmd.Parent(), name)
}