Repository: urfave/cli
Pull request #1937 (2024-06-28 17:42:35)

adjust tests for HideDefault
<!--
  This template provides some ideas of things to include in your PR description.
  To start, try providing a short summary of your changes in the Title above.
  If a section of the PR template does not apply to this PR, then delete that section.
 -->

## What type of PR is this?

- feature

## What this PR does / why we need it:

It gives the option to hide default values from help output.

It also suppresses the `(default: false)` from the standard `--version` and `--help` as those make absolutely no sense.

## Which issue(s) this PR fixes:

#1925 

## Testing

<!--
  Describe how you tested this change.
-->

I changed all standard tests to account for the new help output.

## Release Notes

Default values for the automatic help texts of `--help` and `--version` will be suppressed.

It's also possible to suppress output of a flag's default value by setting the flag's `HideDefault` to `true`.

```release-note

```



Patch:
diff --git a/flag.go b/flag.go
index 8a87ac4..f7c64c8 100644
--- a/flag.go
+++ b/flag.go
@@ -35,18 +35,20 @@ var GenerateShellCompletionFlag Flag = &BoolFlag{
 
 // VersionFlag prints the version for the application
 var VersionFlag Flag = &BoolFlag{
-	Name:    "version",
-	Aliases: []string{"v"},
-	Usage:   "print the version",
+	Name:        "version",
+	Aliases:     []string{"v"},
+	Usage:       "print the version",
+	HideDefault: true,
 }
 
 // HelpFlag prints the help for all commands and subcommands.
 // Set to nil to disable the flag.  The subcommand
 // will still be added unless HideHelp or HideHelpCommand is set to true.
 var HelpFlag Flag = &BoolFlag{
-	Name:    "help",
-	Aliases: []string{"h"},
-	Usage:   "show help",
+	Name:        "help",
+	Aliases:     []string{"h"},
+	Usage:       "show help",
+	HideDefault: true,
 }
 
 // FlagStringer converts a flag definition to a string. This is used by help
@@ -135,6 +137,10 @@ type DocGenerationFlag interface {
 
 	// GetEnvVars returns the env vars for this flag
 	GetEnvVars() []string
+
+	// IsDefaultVisible returns whether the default value should be shown in
+	// help text
+	IsDefaultVisible() bool
 }
 
 // DocGenerationMultiValueFlag extends DocGenerationFlag for slice/map based flags.
@@ -173,6 +179,11 @@ type PersistentFlag interface {
 	IsPersistent() bool
 }
 
+// IsDefaultVisible returns true if the flag is not hidden, otherwise false
+func (f *FlagBase[T, C, V]) IsDefaultVisible() bool {
+	return !f.HideDefault
+}
+
 func newFlagSet(name string, flags []Flag) (*flag.FlagSet, error) {
 	set := flag.NewFlagSet(name, flag.ContinueOnError)
 
@@ -349,7 +360,8 @@ func stringifyFlag(f Flag) string {
 
 	// don't print default text for required flags
 	if rf, ok := f.(RequiredFlag); !ok || !rf.IsRequired() {
-		if s := df.GetDefaultText(); s != "" {
+		isVisible := df.IsDefaultVisible()
+		if s := df.GetDefaultText(); isVisible && s != "" {
 			defaultValueString = fmt.Sprintf(formatDefault("%s"), s)
 		}
 	}
diff --git a/flag_impl.go b/flag_impl.go
index 36edcc9..a6de390 100644
--- a/flag_impl.go
+++ b/flag_impl.go
@@ -72,6 +72,7 @@ type FlagBase[T any, C any, VC ValueCreator[T, C]] struct {
 	Name        string                                   `json:"name"`         // name of the flag
 	Category    string                                   `json:"category"`     // category of the flag, if any
 	DefaultText string                                   `json:"defaultText"`  // default text of the flag for usage purposes
+	HideDefault bool                                     `json:"hideDefault"`  // whether to hide the default value in output
 	Usage       string                                   `json:"usage"`        // usage string for help output
 	Sources     ValueSourceChain                         `json:"-"`            // sources to load flag value from
 	Required    bool                                     `json:"required"`     // whether the flag is required or not
diff --git a/godoc-current.txt b/godoc-current.txt
index 70b692a..07bd07e 100644
--- a/godoc-current.txt
+++ b/godoc-current.txt
@@ -557,6 +557,10 @@ type DocGenerationFlag interface {
 
 	// GetEnvVars returns the env vars for this flag
 	GetEnvVars() []string
+
+	// IsDefaultVisible returns whether the default value should be shown in
+	// help text
+	IsDefaultVisible() bool
 }
     DocGenerationFlag is an interface that allows documentation generation for
     the flag
@@ -620,18 +624,20 @@ var GenerateShellCompletionFlag Flag = &BoolFlag{
     GenerateShellCompletionFlag enables shell completion
 
 var HelpFlag Flag = &BoolFlag{
-	Name:    "help",
-	Aliases: []string{"h"},
-	Usage:   "show help",
+	Name:        "help",
+	Aliases:     []string{"h"},
+	Usage:       "show help",
+	HideDefault: true,
 }
     HelpFlag prints the help for all commands and subcommands. Set to nil to
     disable the flag. The subcommand will still be added unless HideHelp or
     HideHelpCommand is set to true.
 
 var VersionFlag Flag = &BoolFlag{
-	Name:    "version",
-	Aliases: []string{"v"},
-	Usage:   "print the version",
+	Name:        "version",
+	Aliases:     []string{"v"},
+	Usage:       "print the version",
+	HideDefault: true,
 }
     VersionFlag prints the version for the application
 
@@ -639,6 +645,7 @@ type FlagBase[T any, C any, VC ValueCreator[T, C]] struct {
 	Name        string                                   `json:"name"`         // name of the flag
 	Category    string                                   `json:"category"`     // category of the flag, if any
 	DefaultText string                                   `json:"defaultText"`  // default text of the flag for usage purposes
+	HideDefault bool                                     `json:"hideDefault"`  // whether to hide the default value in output
 	Usage       string                                   `json:"usage"`        // usage string for help output
 	Sources     ValueSourceChain                         `json:"-"`            // sources to load flag value from
 	Required    bool                                     `json:"required"`     // whether the flag is required or not
@@ -684,6 +691,9 @@ func (f *FlagBase[T, C, V]) GetValue() string
     GetValue returns the flags value as string representation and an empty
     string if the flag takes no value at all.
 
+func (f *FlagBase[T, C, V]) IsDefaultVisible() bool
+    IsDefaultVisible returns true if the flag is not hidden, otherwise false
+
 func (f *FlagBase[T, C, VC]) IsMultiValueFlag() bool
     IsMultiValueFlag returns true if the value type T can take multiple values
     from cmd line. This is true for slice and map type flags


Test patch:
diff --git a/command_test.go b/command_test.go
index 094bfec..20abfb7 100644
--- a/command_test.go
+++ b/command_test.go
@@ -3919,6 +3919,7 @@ func TestJSONExportCommand(t *testing.T) {
 					"usage": "",
 					"required": false,
 					"hidden": false,
+					"hideDefault": false,
 					"persistent": false,
 					"defaultValue": "",
 					"aliases": [
@@ -3938,6 +3939,7 @@ func TestJSONExportCommand(t *testing.T) {
 					"usage": "some usage text",
 					"required": false,
 					"hidden": false,
+					"hideDefault": false,
 					"persistent": false,
 					"defaultValue": false,
 					"aliases": [
@@ -3977,6 +3979,7 @@ func TestJSONExportCommand(t *testing.T) {
 				"usage": "",
 				"required": false,
 				"hidden": false,
+				"hideDefault": false,
 				"persistent": false,
 				"defaultValue": "",
 				"aliases": [
@@ -3996,6 +3999,7 @@ func TestJSONExportCommand(t *testing.T) {
 				"usage": "another usage text",
 				"required": false,
 				"hidden": false,
+				"hideDefault": false,
 				"persistent": false,
 				"defaultValue": false,
 				"aliases": [
@@ -4153,6 +4157,7 @@ func TestJSONExportCommand(t *testing.T) {
 					"usage": "some usage text",
 					"required": false,
 					"hidden": false,
+					"hideDefault": false,
 					"persistent": false,
 					"defaultValue": false,
 					"aliases": [
@@ -4192,6 +4197,7 @@ func TestJSONExportCommand(t *testing.T) {
 				"usage": "",
 				"required": false,
 				"hidden": false,
+				"hideDefault": false,
 				"persistent": false,
 				"defaultValue": "",
 				"aliases": [
@@ -4211,6 +4217,7 @@ func TestJSONExportCommand(t *testing.T) {
 				"usage": "another usage text",
 				"required": false,
 				"hidden": false,
+				"hideDefault": false,
 				"persistent": false,
 				"defaultValue": false,
 				"aliases": [
@@ -4250,6 +4257,7 @@ func TestJSONExportCommand(t *testing.T) {
 			"usage": "some 'usage' text",
 			"required": false,
 			"hidden": false,
+			"hideDefault": false,
 			"persistent": false,
 			"defaultValue": "value",
 			"aliases": [
@@ -4268,6 +4276,7 @@ func TestJSONExportCommand(t *testing.T) {
 			"usage": "",
 			"required": false,
 			"hidden": false,
+			"hideDefault": false,
 			"persistent": false,
 			"defaultValue": "",
 			"aliases": [
@@ -4287,6 +4296,7 @@ func TestJSONExportCommand(t *testing.T) {
 			"usage": "another usage text",
 			"required": false,
 			"hidden": false,
+			"hideDefault": false,
 			"persistent": false,
 			"defaultValue": false,
 			"aliases": [
@@ -4305,6 +4315,7 @@ func TestJSONExportCommand(t *testing.T) {
 			"usage": "",
 			"required": false,
 			"hidden": true,
+			"hideDefault": false,
 			"persistent": false,
 			"defaultValue": false,
 			"aliases": null,
diff --git a/examples_test.go b/examples_test.go
index b7050b8..8802d54 100644
--- a/examples_test.go
+++ b/examples_test.go
@@ -143,8 +143,8 @@ func ExampleCommand_Run_appHelp() {
 	//
 	// GLOBAL OPTIONS:
 	//    --name value   a name to say (default: "bob")
-	//    --help, -h     show help (default: false)
-	//    --version, -v  print the version (default: false)
+	//    --help, -h     show help
+	//    --version, -v  print the version
 }
 
 func ExampleCommand_Run_commandHelp() {
@@ -190,7 +190,7 @@ func ExampleCommand_Run_commandHelp() {
 	//    help, h  Shows a list of commands or help for one command
 	//
 	// OPTIONS:
-	//    --help, -h  show help (default: false)
+	//    --help, -h  show help
 }
 
 func ExampleCommand_Run_noAction() {
@@ -211,7 +211,7 @@ func ExampleCommand_Run_noAction() {
 	//    help, h  Shows a list of commands or help for one command
 	//
 	// GLOBAL OPTIONS:
-	//    --help, -h  show help (default: false)
+	//    --help, -h  show help
 }
 
 func ExampleCommand_Run_subcommandNoAction() {
@@ -243,7 +243,7 @@ func ExampleCommand_Run_subcommandNoAction() {
 	//    This is how we describe describeit the function
 	//
 	// OPTIONS:
-	//    --help, -h  show help (default: false)
+	//    --help, -h  show help
 }
 
 func ExampleCommand_Run_shellComplete_bash_withShortFlag() {
diff --git a/help_test.go b/help_test.go
index f5d8b82..fe5157c 100644
--- a/help_test.go
+++ b/help_test.go
@@ -88,7 +88,7 @@ COMMANDS:
 
 GLOBAL OPTIONS:
    --foo value, -f value  
-   --help, -h             show help (default: false)
+   --help, -h             show help
 `
 
 	assert.Contains(t, output.String(), expected,
@@ -1428,8 +1428,7 @@ COMMANDS:
             for one command
 
 OPTIONS:
-   --help, -h show help
-      (default: false)
+   --help, -h  show help
 `,
 		output.String(),
 	)
@@ -1494,8 +1493,7 @@ USAGE:
    even more
 
 OPTIONS:
-   --help, -h show help
-      (default: false)
+   --help, -h  show help
 `
 
 	assert.Equal(t, expected, output.String(), "Unexpected wrapping")
@@ -1575,8 +1573,7 @@ COMMANDS:
 OPTIONS:
    --test-f value my test
       usage
-   --help, -h show help
-      (default: false)
+   --help, -h  show help
 `,
 		output.String(),
 	)
@@ -1654,7 +1651,7 @@ COMMANDS:
             for one command
 
 GLOBAL OPTIONS:
-   --help, -h    show help (default: false)
+   --help, -h    show help
    --m2 value    
    --strd value  
 
diff --git a/testdata/godoc-v3.x.txt b/testdata/godoc-v3.x.txt
index 70b692a..07bd07e 100644
--- a/testdata/godoc-v3.x.txt
+++ b/testdata/godoc-v3.x.txt
@@ -557,6 +557,10 @@ type DocGenerationFlag interface {
 
 	// GetEnvVars returns the env vars for this flag
 	GetEnvVars() []string
+
+	// IsDefaultVisible returns whether the default value should be shown in
+	// help text
+	IsDefaultVisible() bool
 }
     DocGenerationFlag is an interface that allows documentation generation for
     the flag
@@ -620,18 +624,20 @@ var GenerateShellCompletionFlag Flag = &BoolFlag{
     GenerateShellCompletionFlag enables shell completion
 
 var HelpFlag Flag = &BoolFlag{
-	Name:    "help",
-	Aliases: []string{"h"},
-	Usage:   "show help",
+	Name:        "help",
+	Aliases:     []string{"h"},
+	Usage:       "show help",
+	HideDefault: true,
 }
     HelpFlag prints the help for all commands and subcommands. Set to nil to
     disable the flag. The subcommand will still be added unless HideHelp or
     HideHelpCommand is set to true.
 
 var VersionFlag Flag = &BoolFlag{
-	Name:    "version",
-	Aliases: []string{"v"},
-	Usage:   "print the version",
+	Name:        "version",
+	Aliases:     []string{"v"},
+	Usage:       "print the version",
+	HideDefault: true,
 }
     VersionFlag prints the version for the application
 
@@ -639,6 +645,7 @@ type FlagBase[T any, C any, VC ValueCreator[T, C]] struct {
 	Name        string                                   `json:"name"`         // name of the flag
 	Category    string                                   `json:"category"`     // category of the flag, if any
 	DefaultText string                                   `json:"defaultText"`  // default text of the flag for usage purposes
+	HideDefault bool                                     `json:"hideDefault"`  // whether to hide the default value in output
 	Usage       string                                   `json:"usage"`        // usage string for help output
 	Sources     ValueSourceChain                         `json:"-"`            // sources to load flag value from
 	Required    bool                                     `json:"required"`     // whether the flag is required or not
@@ -684,6 +691,9 @@ func (f *FlagBase[T, C, V]) GetValue() string
     GetValue returns the flags value as string representation and an empty
     string if the flag takes no value at all.
 
+func (f *FlagBase[T, C, V]) IsDefaultVisible() bool
+    IsDefaultVisible returns true if the flag is not hidden, otherwise false
+
 func (f *FlagBase[T, C, VC]) IsMultiValueFlag() bool
     IsMultiValueFlag returns true if the value type T can take multiple values
     from cmd line. This is true for slice and map type flags