
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
97 lines
2.5 KiB
Go
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)
|
|
}
|