Repository: urfave/cli
Pull request #1471 (2022-09-05 02:52:16)

Collapse flag interface
<!--
  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?

_(REQUIRED)_

<!--
  Delete any of the following that do not apply:
 -->

- cleanup

## What this PR does / why we need it:

_(REQUIRED)_

<!--
  What goal is this change working towards?
  Provide a bullet pointed summary of how each file was changed.
  Briefly explain any decisions you made with respect to the changes.
  Include anything here that you didn't include in *Release Notes*
  above, such as changes to CI or changes to internal methods.
-->

Collapse all the flag interfaces into a single consistent interface

## Which issue(s) this PR fixes:

_(REQUIRED)_

<!--
If this PR fixes one of more issues, list them here.
One line each, like so:

Fixes #123
Fixes #39
-->

## Special notes for your reviewer:

_(fill-in or delete this section)_

<!--
   Is there any particular feedback you would / wouldn't like?
   Which parts of the code should reviewers focus on?
-->

## Testing

_(fill-in or delete this section)_

<!--
  Describe how you tested this change.
-->

go test ./...

## Release Notes

_(REQUIRED)_
<!--
  If this PR makes user facing changes, please describe them here. This
  description will be copied into the release notes/changelog, whenever the
  next version is released. Keep this section short, and focus on high level
  changes.

  Put your text between the block. To omit notes, use NONE within the block.
-->

```release-note

```



Patch:
diff --git a/app.go b/app.go
index 7e64c2d..834873a 100644
--- a/app.go
+++ b/app.go
@@ -227,9 +227,7 @@ func (a *App) Setup() {
 
 	a.flagCategories = newFlagCategories()
 	for _, fl := range a.Flags {
-		if cf, ok := fl.(CategorizableFlag); ok {
-			a.flagCategories.AddFlag(cf.GetCategory(), cf)
-		}
+		a.flagCategories.AddFlag(fl.GetCategory(), fl)
 	}
 
 	if a.Metadata == nil {
diff --git a/category.go b/category.go
index 8bf325e..188937d 100644
--- a/category.go
+++ b/category.go
@@ -101,9 +101,7 @@ func newFlagCategories() FlagCategories {
 func newFlagCategoriesFromFlags(fs []Flag) FlagCategories {
 	fc := newFlagCategories()
 	for _, fl := range fs {
-		if cf, ok := fl.(CategorizableFlag); ok {
-			fc.AddFlag(cf.GetCategory(), cf)
-		}
+		fc.AddFlag(fl.GetCategory(), fl)
 	}
 
 	return fc
@@ -138,7 +136,7 @@ type VisibleFlagCategory interface {
 	// Name returns the category name string
 	Name() string
 	// Flags returns a slice of VisibleFlag sorted by name
-	Flags() []VisibleFlag
+	Flags() []Flag
 }
 
 type defaultVisibleFlagCategory struct {
@@ -150,21 +148,19 @@ func (fc *defaultVisibleFlagCategory) Name() string {
 	return fc.name
 }
 
-func (fc *defaultVisibleFlagCategory) Flags() []VisibleFlag {
+func (fc *defaultVisibleFlagCategory) Flags() []Flag {
 	vfNames := []string{}
 	for flName, fl := range fc.m {
-		if vf, ok := fl.(VisibleFlag); ok {
-			if vf.IsVisible() {
-				vfNames = append(vfNames, flName)
-			}
+		if fl.IsVisible() {
+			vfNames = append(vfNames, flName)
 		}
 	}
 
 	sort.Strings(vfNames)
 
-	ret := make([]VisibleFlag, len(vfNames))
+	ret := make([]Flag, len(vfNames))
 	for i, flName := range vfNames {
-		ret[i] = fc.m[flName].(VisibleFlag)
+		ret[i] = fc.m[flName]
 	}
 
 	return ret
diff --git a/context.go b/context.go
index 6b497ed..216e958 100644
--- a/context.go
+++ b/context.go
@@ -165,7 +165,7 @@ func (cCtx *Context) lookupFlagSet(name string) *flag.FlagSet {
 func (cCtx *Context) checkRequiredFlags(flags []Flag) requiredFlagsErr {
 	var missingFlags []string
 	for _, f := range flags {
-		if rf, ok := f.(RequiredFlag); ok && rf.IsRequired() {
+		if f.IsRequired() {
 			var flagPresent bool
 			var flagName string
 
diff --git a/docs.go b/docs.go
index 8b1c9c8..5a8be0a 100644
--- a/docs.go
+++ b/docs.go
@@ -116,11 +116,7 @@ func prepareFlags(
 	addDetails bool,
 ) []string {
 	args := []string{}
-	for _, f := range flags {
-		flag, ok := f.(DocGenerationFlag)
-		if !ok {
-			continue
-		}
+	for _, flag := range flags {
 		modifiedArg := opener
 
 		for _, s := range flag.Names() {
@@ -151,7 +147,7 @@ func prepareFlags(
 }
 
 // flagDetails returns a string containing the flags metadata
-func flagDetails(flag DocGenerationFlag) string {
+func flagDetails(flag Flag) string {
 	description := flag.GetUsage()
 	value := flag.GetValue()
 	if value != "" {
diff --git a/fish.go b/fish.go
index eec3253..70946e1 100644
--- a/fish.go
+++ b/fish.go
@@ -114,12 +114,7 @@ func (a *App) prepareFishCommands(commands []*Command, allCommands *[]string, pr
 
 func (a *App) prepareFishFlags(flags []Flag, previousCommands []string) []string {
 	completions := []string{}
-	for _, f := range flags {
-		flag, ok := f.(DocGenerationFlag)
-		if !ok {
-			continue
-		}
-
+	for _, flag := range flags {
 		completion := &strings.Builder{}
 		completion.WriteString(fmt.Sprintf(
 			"complete -c %s -n '%s'",
@@ -127,7 +122,7 @@ func (a *App) prepareFishFlags(flags []Flag, previousCommands []string) []string
 			a.fishSubcommandHelper(previousCommands),
 		))
 
-		fishAddFileFlag(f, completion)
+		fishAddFileFlag(flag, completion)
 
 		for idx, opt := range flag.Names() {
 			if idx == 0 {
diff --git a/flag-spec.yaml b/flag-spec.yaml
index 45f054d..3fa2d10 100644
--- a/flag-spec.yaml
+++ b/flag-spec.yaml
@@ -3,7 +3,8 @@
 # `genflags.Spec` type that maps to this file structure.
 
 flag_types:
-  bool: {}
+  bool: 
+    no_default_text: true
   float64: {}
   int64: {}
   int: {}
@@ -12,12 +13,14 @@ flag_types:
   uint: {}
 
   string:
+    no_default_text: true
     struct_fields:
       - { name: TakesFile, type: bool }
   Generic:
     struct_fields:
       - { name: TakesFile, type: bool }
   Path:
+    no_default_text: true
     struct_fields:
       - { name: TakesFile, type: bool }
 
diff --git a/flag.go b/flag.go
index dbed577..a0b9834 100644
--- a/flag.go
+++ b/flag.go
@@ -89,55 +89,40 @@ func (f FlagsByName) Swap(i, j int) {
 // this interface be implemented.
 type Flag interface {
 	fmt.Stringer
+
 	// Apply Flag settings to the given flag set
 	Apply(*flag.FlagSet) error
+
+	// All possible names for this flag
 	Names() []string
-	IsSet() bool
-}
 
-// RequiredFlag is an interface that allows us to mark flags as required
-// it allows flags required flags to be backwards compatible with the Flag interface
-type RequiredFlag interface {
-	Flag
+	// Whether the flag has been set or not
+	IsSet() bool
 
+	// whether the flag is a required flag or not
 	IsRequired() bool
-}
 
-// DocGenerationFlag is an interface that allows documentation generation for the flag
-type DocGenerationFlag interface {
-	Flag
+	// IsVisible returns true if the flag is not hidden, otherwise false
+	IsVisible() bool
 
-	// TakesValue returns true if the flag takes a value, otherwise false
-	TakesValue() bool
+	// Returns the category of the flag
+	GetCategory() string
 
 	// GetUsage returns the usage string for the flag
 	GetUsage() string
 
-	// GetValue returns the flags value as string representation and an empty
-	// string if the flag takes no value at all.
-	GetValue() string
-
-	// GetDefaultText returns the default text for this flag
-	GetDefaultText() string
-
 	// GetEnvVars returns the env vars for this flag
 	GetEnvVars() []string
-}
 
-// VisibleFlag is an interface that allows to check if a flag is visible
-type VisibleFlag interface {
-	Flag
-
-	// IsVisible returns true if the flag is not hidden, otherwise false
-	IsVisible() bool
-}
+	// TakesValue returns true if the flag takes a value, otherwise false
+	TakesValue() bool
 
-// CategorizableFlag is an interface that allows us to potentially
-// use a flag in a categorized representation.
-type CategorizableFlag interface {
-	VisibleFlag
+	// GetDefaultText returns the default text for this flag
+	GetDefaultText() string
 
-	GetCategory() string
+	// GetValue returns the flags value as string representation and an empty
+	// string if the flag takes no value at all.
+	GetValue() string
 }
 
 func flagSet(name string, flags []Flag) (*flag.FlagSet, error) {
@@ -197,7 +182,7 @@ func normalizeFlags(flags []Flag, set *flag.FlagSet) error {
 func visibleFlags(fl []Flag) []Flag {
 	var visible []Flag
 	for _, f := range fl {
-		if vf, ok := f.(VisibleFlag); ok && vf.IsVisible() {
+		if f.IsVisible() {
 			visible = append(visible, f)
 		}
 	}
@@ -293,14 +278,8 @@ func formatDefault(format string) string {
 }
 
 func stringifyFlag(f Flag) string {
-	// enforce DocGeneration interface on flags to avoid reflection
-	df, ok := f.(DocGenerationFlag)
-	if !ok {
-		return ""
-	}
-
-	placeholder, usage := unquoteUsage(df.GetUsage())
-	needsPlaceholder := df.TakesValue()
+	placeholder, usage := unquoteUsage(f.GetUsage())
+	needsPlaceholder := f.TakesValue()
 
 	if needsPlaceholder && placeholder == "" {
 		placeholder = defaultPlaceholder
@@ -308,14 +287,14 @@ func stringifyFlag(f Flag) string {
 
 	defaultValueString := ""
 
-	if s := df.GetDefaultText(); s != "" {
+	if s := f.GetDefaultText(); s != "" {
 		defaultValueString = fmt.Sprintf(formatDefault("%s"), s)
 	}
 
 	usageWithDefault := strings.TrimSpace(usage + defaultValueString)
 
-	return withEnvHint(df.GetEnvVars(),
-		fmt.Sprintf("%s\t%s", prefixedNames(df.Names(), placeholder), usageWithDefault))
+	return withEnvHint(f.GetEnvVars(),
+		fmt.Sprintf("%s\t%s", prefixedNames(f.Names(), placeholder), usageWithDefault))
 }
 
 func stringifyIntSliceFlag(f *IntSliceFlag) string {
diff --git a/flag_bool.go b/flag_bool.go
index b21d516..c8a01bb 100644
--- a/flag_bool.go
+++ b/flag_bool.go
@@ -6,21 +6,6 @@ import (
 	"strconv"
 )
 
-// TakesValue returns true of the flag takes a value, otherwise false
-func (f *BoolFlag) TakesValue() bool {
-	return false
-}
-
-// GetUsage returns the usage string for the flag
-func (f *BoolFlag) GetUsage() string {
-	return f.Usage
-}
-
-// GetCategory returns the category for the flag
-func (f *BoolFlag) GetCategory() string {
-	return f.Category
-}
-
 // GetValue returns the flags value as string representation and an empty
 // string if the flag takes no value at all.
 func (f *BoolFlag) GetValue() string {
@@ -35,11 +20,6 @@ func (f *BoolFlag) GetDefaultText() string {
 	return fmt.Sprintf("%v", f.Value)
 }
 
-// GetEnvVars returns the env vars for this flag
-func (f *BoolFlag) GetEnvVars() []string {
-	return f.EnvVars
-}
-
 // Apply populates the flag given the flag set and environment
 func (f *BoolFlag) Apply(set *flag.FlagSet) error {
 	if val, source, found := flagFromEnvOrFile(f.EnvVars, f.FilePath); found {
diff --git a/flag_duration.go b/flag_duration.go
index 5178c6a..35b376d 100644
--- a/flag_duration.go
+++ b/flag_duration.go
@@ -6,40 +6,12 @@ import (
 	"time"
 )
 
-// TakesValue returns true of the flag takes a value, otherwise false
-func (f *DurationFlag) TakesValue() bool {
-	return true
-}
-
-// GetUsage returns the usage string for the flag
-func (f *DurationFlag) GetUsage() string {
-	return f.Usage
-}
-
-// GetCategory returns the category for the flag
-func (f *DurationFlag) GetCategory() string {
-	return f.Category
-}
-
 // GetValue returns the flags value as string representation and an empty
 // string if the flag takes no value at all.
 func (f *DurationFlag) GetValue() string {
 	return f.Value.String()
 }
 
-// GetDefaultText returns the default text for this flag
-func (f *DurationFlag) GetDefaultText() string {
-	if f.DefaultText != "" {
-		return f.DefaultText
-	}
-	return f.GetValue()
-}
-
-// GetEnvVars returns the env vars for this flag
-func (f *DurationFlag) GetEnvVars() []string {
-	return f.EnvVars
-}
-
 // Apply populates the flag given the flag set and environment
 func (f *DurationFlag) Apply(set *flag.FlagSet) error {
 	if val, source, found := flagFromEnvOrFile(f.EnvVars, f.FilePath); found {
diff --git a/flag_float64.go b/flag_float64.go
index 2d31739..b7b8044 100644
--- a/flag_float64.go
+++ b/flag_float64.go
@@ -6,40 +6,12 @@ import (
 	"strconv"
 )
 
-// TakesValue returns true of the flag takes a value, otherwise false
-func (f *Float64Flag) TakesValue() bool {
-	return true
-}
-
-// GetUsage returns the usage string for the flag
-func (f *Float64Flag) GetUsage() string {
-	return f.Usage
-}
-
-// GetCategory returns the category for the flag
-func (f *Float64Flag) GetCategory() string {
-	return f.Category
-}
-
 // GetValue returns the flags value as string representation and an empty
 // string if the flag takes no value at all.
 func (f *Float64Flag) GetValue() string {
 	return fmt.Sprintf("%v", f.Value)
 }
 
-// GetDefaultText returns the default text for this flag
-func (f *Float64Flag) GetDefaultText() string {
-	if f.DefaultText != "" {
-		return f.DefaultText
-	}
-	return f.GetValue()
-}
-
-// GetEnvVars returns the env vars for this flag
-func (f *Float64Flag) GetEnvVars() []string {
-	return f.EnvVars
-}
-
 // Apply populates the flag given the flag set and environment
 func (f *Float64Flag) Apply(set *flag.FlagSet) error {
 	if val, source, found := flagFromEnvOrFile(f.EnvVars, f.FilePath); found {
diff --git a/flag_float64_slice.go b/flag_float64_slice.go
index 031ec1d..56745c1 100644
--- a/flag_float64_slice.go
+++ b/flag_float64_slice.go
@@ -86,21 +86,6 @@ func (f *Float64SliceFlag) String() string {
 	return withEnvHint(f.GetEnvVars(), stringifyFloat64SliceFlag(f))
 }
 
-// TakesValue returns true if the flag takes a value, otherwise false
-func (f *Float64SliceFlag) TakesValue() bool {
-	return true
-}
-
-// GetUsage returns the usage string for the flag
-func (f *Float64SliceFlag) GetUsage() string {
-	return f.Usage
-}
-
-// GetCategory returns the category for the flag
-func (f *Float64SliceFlag) GetCategory() string {
-	return f.Category
-}
-
 // GetValue returns the flags value as string representation and an empty
 // string if the flag takes no value at all.
 func (f *Float64SliceFlag) GetValue() string {
@@ -110,19 +95,6 @@ func (f *Float64SliceFlag) GetValue() string {
 	return ""
 }
 
-// GetDefaultText returns the default text for this flag
-func (f *Float64SliceFlag) GetDefaultText() string {
-	if f.DefaultText != "" {
-		return f.DefaultText
-	}
-	return f.GetValue()
-}
-
-// GetEnvVars returns the env vars for this flag
-func (f *Float64SliceFlag) GetEnvVars() []string {
-	return f.EnvVars
-}
-
 // Apply populates the flag given the flag set and environment
 func (f *Float64SliceFlag) Apply(set *flag.FlagSet) error {
 	// apply any default
diff --git a/flag_generic.go b/flag_generic.go
index 680eeb9..cb20486 100644
--- a/flag_generic.go
+++ b/flag_generic.go
@@ -11,21 +11,6 @@ type Generic interface {
 	String() string
 }
 
-// TakesValue returns true of the flag takes a value, otherwise false
-func (f *GenericFlag) TakesValue() bool {
-	return true
-}
-
-// GetUsage returns the usage string for the flag
-func (f *GenericFlag) GetUsage() string {
-	return f.Usage
-}
-
-// GetCategory returns the category for the flag
-func (f *GenericFlag) GetCategory() string {
-	return f.Category
-}
-
 // GetValue returns the flags value as string representation and an empty
 // string if the flag takes no value at all.
 func (f *GenericFlag) GetValue() string {
@@ -35,19 +20,6 @@ func (f *GenericFlag) GetValue() string {
 	return ""
 }
 
-// GetDefaultText returns the default text for this flag
-func (f *GenericFlag) GetDefaultText() string {
-	if f.DefaultText != "" {
-		return f.DefaultText
-	}
-	return f.GetValue()
-}
-
-// GetEnvVars returns the env vars for this flag
-func (f *GenericFlag) GetEnvVars() []string {
-	return f.EnvVars
-}
-
 // Apply takes the flagset and calls Set on the generic flag with the value
 // provided by the user for parsing by the flag
 func (f GenericFlag) Apply(set *flag.FlagSet) error {
diff --git a/flag_int.go b/flag_int.go
index c70b889..908e076 100644
--- a/flag_int.go
+++ b/flag_int.go
@@ -6,40 +6,12 @@ import (
 	"strconv"
 )
 
-// TakesValue returns true of the flag takes a value, otherwise false
-func (f *IntFlag) TakesValue() bool {
-	return true
-}
-
-// GetUsage returns the usage string for the flag
-func (f *IntFlag) GetUsage() string {
-	return f.Usage
-}
-
-// GetCategory returns the category for the flag
-func (f *IntFlag) GetCategory() string {
-	return f.Category
-}
-
 // GetValue returns the flags value as string representation and an empty
 // string if the flag takes no value at all.
 func (f *IntFlag) GetValue() string {
 	return fmt.Sprintf("%d", f.Value)
 }
 
-// GetDefaultText returns the default text for this flag
-func (f *IntFlag) GetDefaultText() string {
-	if f.DefaultText != "" {
-		return f.DefaultText
-	}
-	return f.GetValue()
-}
-
-// GetEnvVars returns the env vars for this flag
-func (f *IntFlag) GetEnvVars() []string {
-	return f.EnvVars
-}
-
 // Apply populates the flag given the flag set and environment
 func (f *IntFlag) Apply(set *flag.FlagSet) error {
 	if val, source, found := flagFromEnvOrFile(f.EnvVars, f.FilePath); found {
diff --git a/flag_int64.go b/flag_int64.go
index 5e7038c..9f07d79 100644
--- a/flag_int64.go
+++ b/flag_int64.go
@@ -6,40 +6,12 @@ import (
 	"strconv"
 )
 
-// TakesValue returns true of the flag takes a value, otherwise false
-func (f *Int64Flag) TakesValue() bool {
-	return true
-}
-
-// GetUsage returns the usage string for the flag
-func (f *Int64Flag) GetUsage() string {
-	return f.Usage
-}
-
-// GetCategory returns the category for the flag
-func (f *Int64Flag) GetCategory() string {
-	return f.Category
-}
-
 // GetValue returns the flags value as string representation and an empty
 // string if the flag takes no value at all.
 func (f *Int64Flag) GetValue() string {
 	return fmt.Sprintf("%d", f.Value)
 }
 
-// GetDefaultText returns the default text for this flag
-func (f *Int64Flag) GetDefaultText() string {
-	if f.DefaultText != "" {
-		return f.DefaultText
-	}
-	return f.GetValue()
-}
-
-// GetEnvVars returns the env vars for this flag
-func (f *Int64Flag) GetEnvVars() []string {
-	return f.EnvVars
-}
-
 // Apply populates the flag given the flag set and environment
 func (f *Int64Flag) Apply(set *flag.FlagSet) error {
 	if val, source, found := flagFromEnvOrFile(f.EnvVars, f.FilePath); found {
diff --git a/flag_int64_slice.go b/flag_int64_slice.go
index 657aaaa..8316709 100644
--- a/flag_int64_slice.go
+++ b/flag_int64_slice.go
@@ -87,21 +87,6 @@ func (f *Int64SliceFlag) String() string {
 	return withEnvHint(f.GetEnvVars(), stringifyInt64SliceFlag(f))
 }
 
-// TakesValue returns true of the flag takes a value, otherwise false
-func (f *Int64SliceFlag) TakesValue() bool {
-	return true
-}
-
-// GetUsage returns the usage string for the flag
-func (f *Int64SliceFlag) GetUsage() string {
-	return f.Usage
-}
-
-// GetCategory returns the category for the flag
-func (f *Int64SliceFlag) GetCategory() string {
-	return f.Category
-}
-
 // GetValue returns the flags value as string representation and an empty
 // string if the flag takes no value at all.
 func (f *Int64SliceFlag) GetValue() string {
@@ -111,19 +96,6 @@ func (f *Int64SliceFlag) GetValue() string {
 	return ""
 }
 
-// GetDefaultText returns the default text for this flag
-func (f *Int64SliceFlag) GetDefaultText() string {
-	if f.DefaultText != "" {
-		return f.DefaultText
-	}
-	return f.GetValue()
-}
-
-// GetEnvVars returns the env vars for this flag
-func (f *Int64SliceFlag) GetEnvVars() []string {
-	return f.EnvVars
-}
-
 // Apply populates the flag given the flag set and environment
 func (f *Int64SliceFlag) Apply(set *flag.FlagSet) error {
 	// apply any default
diff --git a/flag_int_slice.go b/flag_int_slice.go
index 7c38393..7865dab 100644
--- a/flag_int_slice.go
+++ b/flag_int_slice.go
@@ -98,21 +98,6 @@ func (f *IntSliceFlag) String() string {
 	return withEnvHint(f.GetEnvVars(), stringifyIntSliceFlag(f))
 }
 
-// TakesValue returns true of the flag takes a value, otherwise false
-func (f *IntSliceFlag) TakesValue() bool {
-	return true
-}
-
-// GetUsage returns the usage string for the flag
-func (f *IntSliceFlag) GetUsage() string {
-	return f.Usage
-}
-
-// GetCategory returns the category for the flag
-func (f *IntSliceFlag) GetCategory() string {
-	return f.Category
-}
-
 // GetValue returns the flags value as string representation and an empty
 // string if the flag takes no value at all.
 func (f *IntSliceFlag) GetValue() string {
@@ -122,19 +107,6 @@ func (f *IntSliceFlag) GetValue() string {
 	return ""
 }
 
-// GetDefaultText returns the default text for this flag
-func (f *IntSliceFlag) GetDefaultText() string {
-	if f.DefaultText != "" {
-		return f.DefaultText
-	}
-	return f.GetValue()
-}
-
-// GetEnvVars returns the env vars for this flag
-func (f *IntSliceFlag) GetEnvVars() []string {
-	return f.EnvVars
-}
-
 // Apply populates the flag given the flag set and environment
 func (f *IntSliceFlag) Apply(set *flag.FlagSet) error {
 	// apply any default
diff --git a/flag_path.go b/flag_path.go
index 7c87a89..e622c40 100644
--- a/flag_path.go
+++ b/flag_path.go
@@ -7,21 +7,6 @@ import (
 
 type Path = string
 
-// TakesValue returns true of the flag takes a value, otherwise false
-func (f *PathFlag) TakesValue() bool {
-	return true
-}
-
-// GetUsage returns the usage string for the flag
-func (f *PathFlag) GetUsage() string {
-	return f.Usage
-}
-
-// GetCategory returns the category for the flag
-func (f *PathFlag) GetCategory() string {
-	return f.Category
-}
-
 // GetValue returns the flags value as string representation and an empty
 // string if the flag takes no value at all.
 func (f *PathFlag) GetValue() string {
@@ -39,11 +24,6 @@ func (f *PathFlag) GetDefaultText() string {
 	return fmt.Sprintf("%q", f.Value)
 }
 
-// GetEnvVars returns the env vars for this flag
-func (f *PathFlag) GetEnvVars() []string {
-	return f.EnvVars
-}
-
 // Apply populates the flag given the flag set and environment
 func (f *PathFlag) Apply(set *flag.FlagSet) error {
 	if val, _, found := flagFromEnvOrFile(f.EnvVars, f.FilePath); found {
diff --git a/flag_string.go b/flag_string.go
index c8da38f..31cd89d 100644
--- a/flag_string.go
+++ b/flag_string.go
@@ -5,21 +5,6 @@ import (
 	"fmt"
 )
 
-// TakesValue returns true of the flag takes a value, otherwise false
-func (f *StringFlag) TakesValue() bool {
-	return true
-}
-
-// GetUsage returns the usage string for the flag
-func (f *StringFlag) GetUsage() string {
-	return f.Usage
-}
-
-// GetCategory returns the category for the flag
-func (f *StringFlag) GetCategory() string {
-	return f.Category
-}
-
 // GetValue returns the flags value as string representation and an empty
 // string if the flag takes no value at all.
 func (f *StringFlag) GetValue() string {
@@ -37,11 +22,6 @@ func (f *StringFlag) GetDefaultText() string {
 	return fmt.Sprintf("%q", f.Value)
 }
 
-// GetEnvVars returns the env vars for this flag
-func (f *StringFlag) GetEnvVars() []string {
-	return f.EnvVars
-}
-
 // Apply populates the flag given the flag set and environment
 func (f *StringFlag) Apply(set *flag.FlagSet) error {
 	if val, _, found := flagFromEnvOrFile(f.EnvVars, f.FilePath); found {
diff --git a/flag_string_slice.go b/flag_string_slice.go
index bcdfd4c..f50323b 100644
--- a/flag_string_slice.go
+++ b/flag_string_slice.go
@@ -76,21 +76,6 @@ func (f *StringSliceFlag) String() string {
 	return withEnvHint(f.GetEnvVars(), stringifyStringSliceFlag(f))
 }
 
-// TakesValue returns true of the flag takes a value, otherwise false
-func (f *StringSliceFlag) TakesValue() bool {
-	return true
-}
-
-// GetUsage returns the usage string for the flag
-func (f *StringSliceFlag) GetUsage() string {
-	return f.Usage
-}
-
-// GetCategory returns the category for the flag
-func (f *StringSliceFlag) GetCategory() string {
-	return f.Category
-}
-
 // GetValue returns the flags value as string representation and an empty
 // string if the flag takes no value at all.
 func (f *StringSliceFlag) GetValue() string {
@@ -100,19 +85,6 @@ func (f *StringSliceFlag) GetValue() string {
 	return ""
 }
 
-// GetDefaultText returns the default text for this flag
-func (f *StringSliceFlag) GetDefaultText() string {
-	if f.DefaultText != "" {
-		return f.DefaultText
-	}
-	return f.GetValue()
-}
-
-// GetEnvVars returns the env vars for this flag
-func (f *StringSliceFlag) GetEnvVars() []string {
-	return f.EnvVars
-}
-
 // Apply populates the flag given the flag set and environment
 func (f *StringSliceFlag) Apply(set *flag.FlagSet) error {
 	// apply any default
diff --git a/flag_timestamp.go b/flag_timestamp.go
index 80e1f47..8759b85 100644
--- a/flag_timestamp.go
+++ b/flag_timestamp.go
@@ -72,21 +72,6 @@ func (t *Timestamp) Get() interface{} {
 	return *t
 }
 
-// TakesValue returns true of the flag takes a value, otherwise false
-func (f *TimestampFlag) TakesValue() bool {
-	return true
-}
-
-// GetUsage returns the usage string for the flag
-func (f *TimestampFlag) GetUsage() string {
-	return f.Usage
-}
-
-// GetCategory returns the category for the flag
-func (f *TimestampFlag) GetCategory() string {
-	return f.Category
-}
-
 // GetValue returns the flags value as string representation and an empty
 // string if the flag takes no value at all.
 func (f *TimestampFlag) GetValue() string {
@@ -96,19 +81,6 @@ func (f *TimestampFlag) GetValue() string {
 	return ""
 }
 
-// GetDefaultText returns the default text for this flag
-func (f *TimestampFlag) GetDefaultText() string {
-	if f.DefaultText != "" {
-		return f.DefaultText
-	}
-	return f.GetValue()
-}
-
-// GetEnvVars returns the env vars for this flag
-func (f *TimestampFlag) GetEnvVars() []string {
-	return f.EnvVars
-}
-
 // Apply populates the flag given the flag set and environment
 func (f *TimestampFlag) Apply(set *flag.FlagSet) error {
 	if f.Layout == "" {
diff --git a/flag_uint.go b/flag_uint.go
index 6092b1a..d03fa7c 100644
--- a/flag_uint.go
+++ b/flag_uint.go
@@ -6,21 +6,6 @@ import (
 	"strconv"
 )
 
-// TakesValue returns true of the flag takes a value, otherwise false
-func (f *UintFlag) TakesValue() bool {
-	return true
-}
-
-// GetUsage returns the usage string for the flag
-func (f *UintFlag) GetUsage() string {
-	return f.Usage
-}
-
-// GetCategory returns the category for the flag
-func (f *UintFlag) GetCategory() string {
-	return f.Category
-}
-
 // Apply populates the flag given the flag set and environment
 func (f *UintFlag) Apply(set *flag.FlagSet) error {
 	if val, source, found := flagFromEnvOrFile(f.EnvVars, f.FilePath); found {
@@ -52,19 +37,6 @@ func (f *UintFlag) GetValue() string {
 	return fmt.Sprintf("%d", f.Value)
 }
 
-// GetDefaultText returns the default text for this flag
-func (f *UintFlag) GetDefaultText() string {
-	if f.DefaultText != "" {
-		return f.DefaultText
-	}
-	return f.GetValue()
-}
-
-// GetEnvVars returns the env vars for this flag
-func (f *UintFlag) GetEnvVars() []string {
-	return f.EnvVars
-}
-
 // Get returns the flag’s value in the given Context.
 func (f *UintFlag) Get(ctx *Context) uint {
 	return ctx.Uint(f.Name)
diff --git a/flag_uint64.go b/flag_uint64.go
index a37f30d..5c06ab4 100644
--- a/flag_uint64.go
+++ b/flag_uint64.go
@@ -6,21 +6,6 @@ import (
 	"strconv"
 )
 
-// TakesValue returns true of the flag takes a value, otherwise false
-func (f *Uint64Flag) TakesValue() bool {
-	return true
-}
-
-// GetUsage returns the usage string for the flag
-func (f *Uint64Flag) GetUsage() string {
-	return f.Usage
-}
-
-// GetCategory returns the category for the flag
-func (f *Uint64Flag) GetCategory() string {
-	return f.Category
-}
-
 // Apply populates the flag given the flag set and environment
 func (f *Uint64Flag) Apply(set *flag.FlagSet) error {
 	if val, source, found := flagFromEnvOrFile(f.EnvVars, f.FilePath); found {
@@ -52,19 +37,6 @@ func (f *Uint64Flag) GetValue() string {
 	return fmt.Sprintf("%d", f.Value)
 }
 
-// GetDefaultText returns the default text for this flag
-func (f *Uint64Flag) GetDefaultText() string {
-	if f.DefaultText != "" {
-		return f.DefaultText
-	}
-	return f.GetValue()
-}
-
-// GetEnvVars returns the env vars for this flag
-func (f *Uint64Flag) GetEnvVars() []string {
-	return f.EnvVars
-}
-
 // Get returns the flag’s value in the given Context.
 func (f *Uint64Flag) Get(ctx *Context) uint64 {
 	return ctx.Uint64(f.Name)
diff --git a/godoc-current.txt b/godoc-current.txt
index 1ba48cc..c35428e 100644
--- a/godoc-current.txt
+++ b/godoc-current.txt
@@ -64,8 +64,8 @@ GLOBAL OPTIONS:
 COPYRIGHT:
    {{wrap .Copyright 3}}{{end}}
 `
-    AppHelpTemplate is the text template for the Default help topic. cli.go uses
-    text/template to render templates. You can render custom help text by
+    AppHelpTemplate is the text template for the Default help topic. cli.go
+    uses text/template to render templates. You can render custom help text by
     setting this variable.
 
 var CommandHelpTemplate = `NAME:
@@ -201,9 +201,9 @@ func DefaultAppComplete(cCtx *Context)
 func DefaultCompleteWithFlags(cmd *Command) func(cCtx *Context)
 func FlagNames(name string, aliases []string) []string
 func HandleAction(action interface{}, cCtx *Context) (err error)
-    HandleAction attempts to figure out which Action signature was used. If it's
-    an ActionFunc or a func with the legacy signature for Action, the func is
-    run!
+    HandleAction attempts to figure out which Action signature was used.
+    If it's an ActionFunc or a func with the legacy signature for Action,
+    the func is run!
 
 func HandleExitCoder(err error)
     HandleExitCoder handles errors implementing ExitCoder by printing their
@@ -360,14 +360,14 @@ func (a *App) RunAsSubcommand(ctx *Context) (err error)
     to generate command-specific flags
 
 func (a *App) RunContext(ctx context.Context, arguments []string) (err error)
-    RunContext is like Run except it takes a Context that will be passed to its
-    commands and sub-commands. Through this, you can propagate timeouts and
+    RunContext is like Run except it takes a Context that will be passed to
+    its commands and sub-commands. Through this, you can propagate timeouts and
     cancellation requests
 
 func (a *App) Setup()
-    Setup runs initialization code to ensure all data structures are ready for
-    `Run` or inspection prior to `Run`. It is internally called by `Run`, but
-    will return early if setup has already happened.
+    Setup runs initialization code to ensure all data structures are ready
+    for `Run` or inspection prior to `Run`. It is internally called by `Run`,
+    but will return early if setup has already happened.
 
 func (a *App) ToFishCompletion() (string, error)
     ToFishCompletion creates a fish completion string for the `*App` The
@@ -460,7 +460,7 @@ func (f *BoolFlag) Get(ctx *Context) bool
     Get returns the flag’s value in the given Context.
 
 func (f *BoolFlag) GetCategory() string
-    GetCategory returns the category for the flag
+    GetCategory returns the category of the flag
 
 func (f *BoolFlag) GetDefaultText() string
     GetDefaultText returns the default text for this flag
@@ -491,15 +491,7 @@ func (f *BoolFlag) String() string
     String returns a readable representation of this value (for usage defaults)
 
 func (f *BoolFlag) TakesValue() bool
-    TakesValue returns true of the flag takes a value, otherwise false
-
-type CategorizableFlag interface {
-	VisibleFlag
-
-	GetCategory() string
-}
-    CategorizableFlag is an interface that allows us to potentially use a flag
-    in a categorized representation.
+    TakesValue returns true if the flag takes a value, otherwise false
 
 type Command struct {
 	// The name of the command
@@ -701,28 +693,6 @@ func (cCtx *Context) Uint64(name string) uint64
 func (cCtx *Context) Value(name string) interface{}
     Value returns the value of the flag corresponding to `name`
 
-type DocGenerationFlag interface {
-	Flag
-
-	// TakesValue returns true if the flag takes a value, otherwise false
-	TakesValue() bool
-
-	// GetUsage returns the usage string for the flag
-	GetUsage() string
-
-	// GetValue returns the flags value as string representation and an empty
-	// string if the flag takes no value at all.
-	GetValue() string
-
-	// GetDefaultText returns the default text for this flag
-	GetDefaultText() string
-
-	// GetEnvVars returns the env vars for this flag
-	GetEnvVars() []string
-}
-    DocGenerationFlag is an interface that allows documentation generation for
-    the flag
-
 type DurationFlag struct {
 	Name string
 
@@ -750,7 +720,7 @@ func (f *DurationFlag) Get(ctx *Context) time.Duration
     Get returns the flag’s value in the given Context.
 
 func (f *DurationFlag) GetCategory() string
-    GetCategory returns the category for the flag
+    GetCategory returns the category of the flag
 
 func (f *DurationFlag) GetDefaultText() string
     GetDefaultText returns the default text for this flag
@@ -781,7 +751,7 @@ func (f *DurationFlag) String() string
     String returns a readable representation of this value (for usage defaults)
 
 func (f *DurationFlag) TakesValue() bool
-    TakesValue returns true of the flag takes a value, otherwise false
+    TakesValue returns true if the flag takes a value, otherwise false
 
 type ErrorFormatter interface {
 	Format(s fmt.State, verb rune)
@@ -799,9 +769,9 @@ func Exit(message interface{}, exitCode int) ExitCoder
     Exit wraps a message and exit code into an error, which by default is
     handled with a call to os.Exit during default error handling.
 
-    This is the simplest way to trigger a non-zero exit code for an App without
-    having to call os.Exit manually. During testing, this behavior can be
-    avoided by overiding the ExitErrHandler function on an App or the
+    This is the simplest way to trigger a non-zero exit code for an App
+    without having to call os.Exit manually. During testing, this behavior
+    can be avoided by overiding the ExitErrHandler function on an App or the
     package-global OsExiter function.
 
 func NewExitError(message interface{}, exitCode int) ExitCoder
@@ -816,10 +786,40 @@ type ExitErrHandlerFunc func(cCtx *Context, err error)
 
 type Flag interface {
 	fmt.Stringer
+
 	// Apply Flag settings to the given flag set
 	Apply(*flag.FlagSet) error
+
+	// All possible names for this flag
 	Names() []string
+
+	// Whether the flag has been set or not
 	IsSet() bool
+
+	// whether the flag is a required flag or not
+	IsRequired() bool
+
+	// IsVisible returns true if the flag is not hidden, otherwise false
+	IsVisible() bool
+
+	// Returns the category of the flag
+	GetCategory() string
+
+	// GetUsage returns the usage string for the flag
+	GetUsage() string
+
+	// GetEnvVars returns the env vars for this flag
+	GetEnvVars() []string
+
+	// TakesValue returns true if the flag takes a value, otherwise false
+	TakesValue() bool
+
+	// GetDefaultText returns the default text for this flag
+	GetDefaultText() string
+
+	// GetValue returns the flags value as string representation and an empty
+	// string if the flag takes no value at all.
+	GetValue() string
 }
     Flag is a common interface related to parsing flags in cli. For more
     advanced flag parsing techniques, it is recommended that this interface be
@@ -923,7 +923,7 @@ func (f *Float64Flag) Get(ctx *Context) float64
     Get returns the flag’s value in the given Context.
 
 func (f *Float64Flag) GetCategory() string
-    GetCategory returns the category for the flag
+    GetCategory returns the category of the flag
 
 func (f *Float64Flag) GetDefaultText() string
     GetDefaultText returns the default text for this flag
@@ -954,7 +954,7 @@ func (f *Float64Flag) String() string
     String returns a readable representation of this value (for usage defaults)
 
 func (f *Float64Flag) TakesValue() bool
-    TakesValue returns true of the flag takes a value, otherwise false
+    TakesValue returns true if the flag takes a value, otherwise false
 
 type Float64Slice struct {
 	// Has unexported fields.
@@ -1006,7 +1006,7 @@ func (f *Float64SliceFlag) Get(ctx *Context) []float64
     Get returns the flag’s value in the given Context.
 
 func (f *Float64SliceFlag) GetCategory() string
-    GetCategory returns the category for the flag
+    GetCategory returns the category of the flag
 
 func (f *Float64SliceFlag) GetDefaultText() string
     GetDefaultText returns the default text for this flag
@@ -1081,7 +1081,7 @@ func (f *GenericFlag) Get(ctx *Context) interface{}
     Get returns the flag’s value in the given Context.
 
 func (f *GenericFlag) GetCategory() string
-    GetCategory returns the category for the flag
+    GetCategory returns the category of the flag
 
 func (f *GenericFlag) GetDefaultText() string
     GetDefaultText returns the default text for this flag
@@ -1112,7 +1112,7 @@ func (f *GenericFlag) String() string
     String returns a readable representation of this value (for usage defaults)
 
 func (f *GenericFlag) TakesValue() bool
-    TakesValue returns true of the flag takes a value, otherwise false
+    TakesValue returns true if the flag takes a value, otherwise false
 
 type Int64Flag struct {
 	Name string
@@ -1141,7 +1141,7 @@ func (f *Int64Flag) Get(ctx *Context) int64
     Get returns the flag’s value in the given Context.
 
 func (f *Int64Flag) GetCategory() string
-    GetCategory returns the category for the flag
+    GetCategory returns the category of the flag
 
 func (f *Int64Flag) GetDefaultText() string
     GetDefaultText returns the default text for this flag
@@ -1172,7 +1172,7 @@ func (f *Int64Flag) String() string
     String returns a readable representation of this value (for usage defaults)
 
 func (f *Int64Flag) TakesValue() bool
-    TakesValue returns true of the flag takes a value, otherwise false
+    TakesValue returns true if the flag takes a value, otherwise false
 
 type Int64Slice struct {
 	// Has unexported fields.
@@ -1224,7 +1224,7 @@ func (f *Int64SliceFlag) Get(ctx *Context) []int64
     Get returns the flag’s value in the given Context.
 
 func (f *Int64SliceFlag) GetCategory() string
-    GetCategory returns the category for the flag
+    GetCategory returns the category of the flag
 
 func (f *Int64SliceFlag) GetDefaultText() string
     GetDefaultText returns the default text for this flag
@@ -1261,7 +1261,7 @@ func (f *Int64SliceFlag) String() string
     String returns a readable representation of this value (for usage defaults)
 
 func (f *Int64SliceFlag) TakesValue() bool
-    TakesValue returns true of the flag takes a value, otherwise false
+    TakesValue returns true if the flag takes a value, otherwise false
 
 type IntFlag struct {
 	Name string
@@ -1290,7 +1290,7 @@ func (f *IntFlag) Get(ctx *Context) int
     Get returns the flag’s value in the given Context.
 
 func (f *IntFlag) GetCategory() string
-    GetCategory returns the category for the flag
+    GetCategory returns the category of the flag
 
 func (f *IntFlag) GetDefaultText() string
     GetDefaultText returns the default text for this flag
@@ -1321,7 +1321,7 @@ func (f *IntFlag) String() string
     String returns a readable representation of this value (for usage defaults)
 
 func (f *IntFlag) TakesValue() bool
-    TakesValue returns true of the flag takes a value, otherwise false
+    TakesValue returns true if the flag takes a value, otherwise false
 
 type IntSlice struct {
 	// Has unexported fields.
@@ -1377,7 +1377,7 @@ func (f *IntSliceFlag) Get(ctx *Context) []int
     Get returns the flag’s value in the given Context.
 
 func (f *IntSliceFlag) GetCategory() string
-    GetCategory returns the category for the flag
+    GetCategory returns the category of the flag
 
 func (f *IntSliceFlag) GetDefaultText() string
     GetDefaultText returns the default text for this flag
@@ -1414,7 +1414,7 @@ func (f *IntSliceFlag) String() string
     String returns a readable representation of this value (for usage defaults)
 
 func (f *IntSliceFlag) TakesValue() bool
-    TakesValue returns true of the flag takes a value, otherwise false
+    TakesValue returns true if the flag takes a value, otherwise false
 
 type MultiError interface {
 	error
@@ -1431,8 +1431,8 @@ type MultiInt64Flag = SliceFlag[*Int64SliceFlag, []int64, int64]
     directly, as Value and/or Destination. See also SliceFlag.
 
 type MultiIntFlag = SliceFlag[*IntSliceFlag, []int, int]
-    MultiIntFlag extends IntSliceFlag with support for using slices directly, as
-    Value and/or Destination. See also SliceFlag.
+    MultiIntFlag extends IntSliceFlag with support for using slices directly,
+    as Value and/or Destination. See also SliceFlag.
 
 type MultiStringFlag = SliceFlag[*StringSliceFlag, []string, string]
     MultiStringFlag extends StringSliceFlag with support for using slices
@@ -1475,7 +1475,7 @@ func (f *PathFlag) Get(ctx *Context) string
     Get returns the flag’s value in the given Context.
 
 func (f *PathFlag) GetCategory() string
-    GetCategory returns the category for the flag
+    GetCategory returns the category of the flag
 
 func (f *PathFlag) GetDefaultText() string
     GetDefaultText returns the default text for this flag
@@ -1506,16 +1506,7 @@ func (f *PathFlag) String() string
     String returns a readable representation of this value (for usage defaults)
 
 func (f *PathFlag) TakesValue() bool
-    TakesValue returns true of the flag takes a value, otherwise false
-
-type RequiredFlag interface {
-	Flag
-
-	IsRequired() bool
-}
-    RequiredFlag is an interface that allows us to mark flags as required it
-    allows flags required flags to be backwards compatible with the Flag
-    interface
+    TakesValue returns true if the flag takes a value, otherwise false
 
 type Serializer interface {
 	Serialize() string
@@ -1527,9 +1518,9 @@ type SliceFlag[T SliceFlagTarget[E], S ~[]E, E any] struct {
 	Value       S
 	Destination *S
 }
-    SliceFlag extends implementations like StringSliceFlag and IntSliceFlag with
-    support for using slices directly, as Value and/or Destination. See also
-    SliceFlagTarget, MultiStringFlag, MultiFloat64Flag, MultiInt64Flag,
+    SliceFlag extends implementations like StringSliceFlag and IntSliceFlag
+    with support for using slices directly, as Value and/or Destination.
+    See also SliceFlagTarget, MultiStringFlag, MultiFloat64Flag, MultiInt64Flag,
     MultiIntFlag.
 
 func (x *SliceFlag[T, S, E]) Apply(set *flag.FlagSet) error
@@ -1564,10 +1555,6 @@ func (x *SliceFlag[T, S, E]) TakesValue() bool
 
 type SliceFlagTarget[E any] interface {
 	Flag
-	RequiredFlag
-	DocGenerationFlag
-	VisibleFlag
-	CategorizableFlag
 
 	// SetValue should propagate the given slice to the target, ideally as a new value.
 	// Note that a nil slice should nil/clear any existing value (modelled as ~[]E).
@@ -1612,7 +1599,7 @@ func (f *StringFlag) Get(ctx *Context) string
     Get returns the flag’s value in the given Context.
 
 func (f *StringFlag) GetCategory() string
-    GetCategory returns the category for the flag
+    GetCategory returns the category of the flag
 
 func (f *StringFlag) GetDefaultText() string
     GetDefaultText returns the default text for this flag
@@ -1643,7 +1630,7 @@ func (f *StringFlag) String() string
     String returns a readable representation of this value (for usage defaults)
 
 func (f *StringFlag) TakesValue() bool
-    TakesValue returns true of the flag takes a value, otherwise false
+    TakesValue returns true if the flag takes a value, otherwise false
 
 type StringSlice struct {
 	// Has unexported fields.
@@ -1697,7 +1684,7 @@ func (f *StringSliceFlag) Get(ctx *Context) []string
     Get returns the flag’s value in the given Context.
 
 func (f *StringSliceFlag) GetCategory() string
-    GetCategory returns the category for the flag
+    GetCategory returns the category of the flag
 
 func (f *StringSliceFlag) GetDefaultText() string
     GetDefaultText returns the default text for this flag
@@ -1734,7 +1721,7 @@ func (f *StringSliceFlag) String() string
     String returns a readable representation of this value (for usage defaults)
 
 func (f *StringSliceFlag) TakesValue() bool
-    TakesValue returns true of the flag takes a value, otherwise false
+    TakesValue returns true if the flag takes a value, otherwise false
 
 type SuggestCommandFunc func(commands []*Command, provided string) string
 
@@ -1800,7 +1787,7 @@ func (f *TimestampFlag) Get(ctx *Context) *time.Time
     Get returns the flag’s value in the given Context.
 
 func (f *TimestampFlag) GetCategory() string
-    GetCategory returns the category for the flag
+    GetCategory returns the category of the flag
 
 func (f *TimestampFlag) GetDefaultText() string
     GetDefaultText returns the default text for this flag
@@ -1831,7 +1818,7 @@ func (f *TimestampFlag) String() string
     String returns a readable representation of this value (for usage defaults)
 
 func (f *TimestampFlag) TakesValue() bool
-    TakesValue returns true of the flag takes a value, otherwise false
+    TakesValue returns true if the flag takes a value, otherwise false
 
 type Uint64Flag struct {
 	Name string
@@ -1860,7 +1847,7 @@ func (f *Uint64Flag) Get(ctx *Context) uint64
     Get returns the flag’s value in the given Context.
 
 func (f *Uint64Flag) GetCategory() string
-    GetCategory returns the category for the flag
+    GetCategory returns the category of the flag
 
 func (f *Uint64Flag) GetDefaultText() string
     GetDefaultText returns the default text for this flag
@@ -1891,7 +1878,7 @@ func (f *Uint64Flag) String() string
     String returns a readable representation of this value (for usage defaults)
 
 func (f *Uint64Flag) TakesValue() bool
-    TakesValue returns true of the flag takes a value, otherwise false
+    TakesValue returns true if the flag takes a value, otherwise false
 
 type UintFlag struct {
 	Name string
@@ -1920,7 +1907,7 @@ func (f *UintFlag) Get(ctx *Context) uint
     Get returns the flag’s value in the given Context.
 
 func (f *UintFlag) GetCategory() string
-    GetCategory returns the category for the flag
+    GetCategory returns the category of the flag
 
 func (f *UintFlag) GetDefaultText() string
     GetDefaultText returns the default text for this flag
@@ -1951,21 +1938,13 @@ func (f *UintFlag) String() string
     String returns a readable representation of this value (for usage defaults)
 
 func (f *UintFlag) TakesValue() bool
-    TakesValue returns true of the flag takes a value, otherwise false
-
-type VisibleFlag interface {
-	Flag
-
-	// IsVisible returns true if the flag is not hidden, otherwise false
-	IsVisible() bool
-}
-    VisibleFlag is an interface that allows to check if a flag is visible
+    TakesValue returns true if the flag takes a value, otherwise false
 
 type VisibleFlagCategory interface {
 	// Name returns the category name string
 	Name() string
 	// Flags returns a slice of VisibleFlag sorted by name
-	Flags() []VisibleFlag
+	Flags() []Flag
 }
     VisibleFlagCategory is a category containing flags.
 
@@ -1986,9 +1965,9 @@ func InitInputSource(flags []cli.Flag, createInputSource func() (InputSourceCont
     that are supported by the input source
 
 func InitInputSourceWithContext(flags []cli.Flag, createInputSource func(cCtx *cli.Context) (InputSourceContext, error)) cli.BeforeFunc
-    InitInputSourceWithContext is used to to setup an InputSourceContext on a
-    cli.Command Before method. It will create a new input source based on the
-    func provided with potentially using existing cli.Context values to
+    InitInputSourceWithContext is used to to setup an InputSourceContext on
+    a cli.Command Before method. It will create a new input source based on
+    the func provided with potentially using existing cli.Context values to
     initialize itself. If there is no error it will then apply the new input
     source to any flags that are supported by the input source
 
diff --git a/internal/genflags/generated.gotmpl b/internal/genflags/generated.gotmpl
index 8b82ccf..964658e 100644
--- a/internal/genflags/generated.gotmpl
+++ b/internal/genflags/generated.gotmpl
@@ -45,21 +45,48 @@ func (f *{{.TypeName}}) Names() []string {
   return {{$.UrfaveCLINamespace}}FlagNames(f.Name, f.Aliases)
 }
 
-{{end}}{{/* /if .GenerateFlagInterface */}}
-
-{{if .GenerateRequiredFlagInterface}}
 // IsRequired returns whether or not the flag is required
 func (f *{{.TypeName}}) IsRequired() bool {
   return f.Required
 }
-{{end}}{{/* /if .GenerateRequiredFlagInterface */}}
 
-{{if .GenerateVisibleFlagInterface}}
 // IsVisible returns true if the flag is not hidden, otherwise false
 func (f *{{.TypeName}}) IsVisible() bool {
 	return !f.Hidden
 }
-{{end}}{{/* /if .GenerateVisibleFlagInterface */}}
+
+// GetCategory returns the category of the flag
+func (f *{{.TypeName}}) GetCategory() string {
+	return f.Category
+}
+
+// GetUsage returns the usage string for the flag
+func (f *{{.TypeName}}) GetUsage() string {
+	return f.Usage
+}
+
+// GetEnvVars returns the env vars for this flag
+func (f *{{.TypeName}}) GetEnvVars() []string {
+	return f.EnvVars
+}
+
+// TakesValue returns true if the flag takes a value, otherwise false
+func (f *{{.TypeName}}) TakesValue() bool {
+  return "{{.TypeName }}" != "BoolFlag"
+}
+
+{{if .GenerateDefaultText}}
+// GetDefaultText returns the default text for this flag
+func (f *{{.TypeName}}) GetDefaultText() string {
+	if f.DefaultText != "" {
+		return f.DefaultText
+	}
+	return f.GetValue()
+}
+{{end}}
+
+{{end}}{{/* /if .GenerateFlagInterface */}}
+
 {{end}}{{/* /range .SortedFlagTypes */}}
 
 // vim{{/* 👻 */}}:ro
diff --git a/internal/genflags/spec.go b/internal/genflags/spec.go
index a7afb22..5b1d4d3 100644
--- a/internal/genflags/spec.go
+++ b/internal/genflags/spec.go
@@ -43,6 +43,7 @@ type FlagTypeConfig struct {
 	StructFields   []*FlagStructField `yaml:"struct_fields"`
 	TypeName       string             `yaml:"type_name"`
 	ValuePointer   bool               `yaml:"value_pointer"`
+	NoDefaultText  bool               `yaml:"no_default_text"`
 }
 
 type FlagStructField struct {
@@ -83,12 +84,8 @@ func (ft *FlagType) GenerateFlagInterface() bool {
 	return ft.skipInterfaceNamed("Flag")
 }
 
-func (ft *FlagType) GenerateRequiredFlagInterface() bool {
-	return ft.skipInterfaceNamed("RequiredFlag")
-}
-
-func (ft *FlagType) GenerateVisibleFlagInterface() bool {
-	return ft.skipInterfaceNamed("VisibleFlag")
+func (ft *FlagType) GenerateDefaultText() bool {
+	return !ft.Config.NoDefaultText
 }
 
 func (ft *FlagType) skipInterfaceNamed(name string) bool {
diff --git a/sliceflag.go b/sliceflag.go
index b2ca590..89f3e0c 100644
--- a/sliceflag.go
+++ b/sliceflag.go
@@ -21,10 +21,6 @@ type (
 	// update).
 	SliceFlagTarget[E any] interface {
 		Flag
-		RequiredFlag
-		DocGenerationFlag
-		VisibleFlag
-		CategorizableFlag
 
 		// SetValue should propagate the given slice to the target, ideally as a new value.
 		// Note that a nil slice should nil/clear any existing value (modelled as ~[]E).
diff --git a/zz_generated.flags.go b/zz_generated.flags.go
index b89566f..685d97d 100644
--- a/zz_generated.flags.go
+++ b/zz_generated.flags.go
@@ -44,6 +44,34 @@ func (f *Float64SliceFlag) IsVisible() bool {
 	return !f.Hidden
 }
 
+// GetCategory returns the category of the flag
+func (f *Float64SliceFlag) GetCategory() string {
+	return f.Category
+}
+
+// GetUsage returns the usage string for the flag
+func (f *Float64SliceFlag) GetUsage() string {
+	return f.Usage
+}
+
+// GetEnvVars returns the env vars for this flag
+func (f *Float64SliceFlag) GetEnvVars() []string {
+	return f.EnvVars
+}
+
+// TakesValue returns true if the flag takes a value, otherwise false
+func (f *Float64SliceFlag) TakesValue() bool {
+	return "Float64SliceFlag" != "BoolFlag"
+}
+
+// GetDefaultText returns the default text for this flag
+func (f *Float64SliceFlag) GetDefaultText() string {
+	if f.DefaultText != "" {
+		return f.DefaultText
+	}
+	return f.GetValue()
+}
+
 // GenericFlag is a flag with type Generic
 type GenericFlag struct {
 	Name string
@@ -91,6 +119,34 @@ func (f *GenericFlag) IsVisible() bool {
 	return !f.Hidden
 }
 
+// GetCategory returns the category of the flag
+func (f *GenericFlag) GetCategory() string {
+	return f.Category
+}
+
+// GetUsage returns the usage string for the flag
+func (f *GenericFlag) GetUsage() string {
+	return f.Usage
+}
+
+// GetEnvVars returns the env vars for this flag
+func (f *GenericFlag) GetEnvVars() []string {
+	return f.EnvVars
+}
+
+// TakesValue returns true if the flag takes a value, otherwise false
+func (f *GenericFlag) TakesValue() bool {
+	return "GenericFlag" != "BoolFlag"
+}
+
+// GetDefaultText returns the default text for this flag
+func (f *GenericFlag) GetDefaultText() string {
+	if f.DefaultText != "" {
+		return f.DefaultText
+	}
+	return f.GetValue()
+}
+
 // Int64SliceFlag is a flag with type *Int64Slice
 type Int64SliceFlag struct {
 	Name string
@@ -131,6 +187,34 @@ func (f *Int64SliceFlag) IsVisible() bool {
 	return !f.Hidden
 }
 
+// GetCategory returns the category of the flag
+func (f *Int64SliceFlag) GetCategory() string {
+	return f.Category
+}
+
+// GetUsage returns the usage string for the flag
+func (f *Int64SliceFlag) GetUsage() string {
+	return f.Usage
+}
+
+// GetEnvVars returns the env vars for this flag
+func (f *Int64SliceFlag) GetEnvVars() []string {
+	return f.EnvVars
+}
+
+// TakesValue returns true if the flag takes a value, otherwise false
+func (f *Int64SliceFlag) TakesValue() bool {
+	return "Int64SliceFlag" != "BoolFlag"
+}
+
+// GetDefaultText returns the default text for this flag
+func (f *Int64SliceFlag) GetDefaultText() string {
+	if f.DefaultText != "" {
+		return f.DefaultText
+	}
+	return f.GetValue()
+}
+
 // IntSliceFlag is a flag with type *IntSlice
 type IntSliceFlag struct {
 	Name string
@@ -171,6 +255,34 @@ func (f *IntSliceFlag) IsVisible() bool {
 	return !f.Hidden
 }
 
+// GetCategory returns the category of the flag
+func (f *IntSliceFlag) GetCategory() string {
+	return f.Category
+}
+
+// GetUsage returns the usage string for the flag
+func (f *IntSliceFlag) GetUsage() string {
+	return f.Usage
+}
+
+// GetEnvVars returns the env vars for this flag
+func (f *IntSliceFlag) GetEnvVars() []string {
+	return f.EnvVars
+}
+
+// TakesValue returns true if the flag takes a value, otherwise false
+func (f *IntSliceFlag) TakesValue() bool {
+	return "IntSliceFlag" != "BoolFlag"
+}
+
+// GetDefaultText returns the default text for this flag
+func (f *IntSliceFlag) GetDefaultText() string {
+	if f.DefaultText != "" {
+		return f.DefaultText
+	}
+	return f.GetValue()
+}
+
 // PathFlag is a flag with type Path
 type PathFlag struct {
 	Name string
@@ -218,6 +330,26 @@ func (f *PathFlag) IsVisible() bool {
 	return !f.Hidden
 }
 
+// GetCategory returns the category of the flag
+func (f *PathFlag) GetCategory() string {
+	return f.Category
+}
+
+// GetUsage returns the usage string for the flag
+func (f *PathFlag) GetUsage() string {
+	return f.Usage
+}
+
+// GetEnvVars returns the env vars for this flag
+func (f *PathFlag) GetEnvVars() []string {
+	return f.EnvVars
+}
+
+// TakesValue returns true if the flag takes a value, otherwise false
+func (f *PathFlag) TakesValue() bool {
+	return "PathFlag" != "BoolFlag"
+}
+
 // StringSliceFlag is a flag with type *StringSlice
 type StringSliceFlag struct {
 	Name string
@@ -260,6 +392,34 @@ func (f *StringSliceFlag) IsVisible() bool {
 	return !f.Hidden
 }
 
+// GetCategory returns the category of the flag
+func (f *StringSliceFlag) GetCategory() string {
+	return f.Category
+}
+
+// GetUsage returns the usage string for the flag
+func (f *StringSliceFlag) GetUsage() string {
+	return f.Usage
+}
+
+// GetEnvVars returns the env vars for this flag
+func (f *StringSliceFlag) GetEnvVars() []string {
+	return f.EnvVars
+}
+
+// TakesValue returns true if the flag takes a value, otherwise false
+func (f *StringSliceFlag) TakesValue() bool {
+	return "StringSliceFlag" != "BoolFlag"
+}
+
+// GetDefaultText returns the default text for this flag
+func (f *StringSliceFlag) GetDefaultText() string {
+	if f.DefaultText != "" {
+		return f.DefaultText
+	}
+	return f.GetValue()
+}
+
 // TimestampFlag is a flag with type *Timestamp
 type TimestampFlag struct {
 	Name string
@@ -309,6 +469,34 @@ func (f *TimestampFlag) IsVisible() bool {
 	return !f.Hidden
 }
 
+// GetCategory returns the category of the flag
+func (f *TimestampFlag) GetCategory() string {
+	return f.Category
+}
+
+// GetUsage returns the usage string for the flag
+func (f *TimestampFlag) GetUsage() string {
+	return f.Usage
+}
+
+// GetEnvVars returns the env vars for this flag
+func (f *TimestampFlag) GetEnvVars() []string {
+	return f.EnvVars
+}
+
+// TakesValue returns true if the flag takes a value, otherwise false
+func (f *TimestampFlag) TakesValue() bool {
+	return "TimestampFlag" != "BoolFlag"
+}
+
+// GetDefaultText returns the default text for this flag
+func (f *TimestampFlag) GetDefaultText() string {
+	if f.DefaultText != "" {
+		return f.DefaultText
+	}
+	return f.GetValue()
+}
+
 // BoolFlag is a flag with type bool
 type BoolFlag struct {
 	Name string
@@ -354,6 +542,26 @@ func (f *BoolFlag) IsVisible() bool {
 	return !f.Hidden
 }
 
+// GetCategory returns the category of the flag
+func (f *BoolFlag) GetCategory() string {
+	return f.Category
+}
+
+// GetUsage returns the usage string for the flag
+func (f *BoolFlag) GetUsage() string {
+	return f.Usage
+}
+
+// GetEnvVars returns the env vars for this flag
+func (f *BoolFlag) GetEnvVars() []string {
+	return f.EnvVars
+}
+
+// TakesValue returns true if the flag takes a value, otherwise false
+func (f *BoolFlag) TakesValue() bool {
+	return "BoolFlag" != "BoolFlag"
+}
+
 // Float64Flag is a flag with type float64
 type Float64Flag struct {
 	Name string
@@ -399,6 +607,34 @@ func (f *Float64Flag) IsVisible() bool {
 	return !f.Hidden
 }
 
+// GetCategory returns the category of the flag
+func (f *Float64Flag) GetCategory() string {
+	return f.Category
+}
+
+// GetUsage returns the usage string for the flag
+func (f *Float64Flag) GetUsage() string {
+	return f.Usage
+}
+
+// GetEnvVars returns the env vars for this flag
+func (f *Float64Flag) GetEnvVars() []string {
+	return f.EnvVars
+}
+
+// TakesValue returns true if the flag takes a value, otherwise false
+func (f *Float64Flag) TakesValue() bool {
+	return "Float64Flag" != "BoolFlag"
+}
+
+// GetDefaultText returns the default text for this flag
+func (f *Float64Flag) GetDefaultText() string {
+	if f.DefaultText != "" {
+		return f.DefaultText
+	}
+	return f.GetValue()
+}
+
 // IntFlag is a flag with type int
 type IntFlag struct {
 	Name string
@@ -444,6 +680,34 @@ func (f *IntFlag) IsVisible() bool {
 	return !f.Hidden
 }
 
+// GetCategory returns the category of the flag
+func (f *IntFlag) GetCategory() string {
+	return f.Category
+}
+
+// GetUsage returns the usage string for the flag
+func (f *IntFlag) GetUsage() string {
+	return f.Usage
+}
+
+// GetEnvVars returns the env vars for this flag
+func (f *IntFlag) GetEnvVars() []string {
+	return f.EnvVars
+}
+
+// TakesValue returns true if the flag takes a value, otherwise false
+func (f *IntFlag) TakesValue() bool {
+	return "IntFlag" != "BoolFlag"
+}
+
+// GetDefaultText returns the default text for this flag
+func (f *IntFlag) GetDefaultText() string {
+	if f.DefaultText != "" {
+		return f.DefaultText
+	}
+	return f.GetValue()
+}
+
 // Int64Flag is a flag with type int64
 type Int64Flag struct {
 	Name string
@@ -489,6 +753,34 @@ func (f *Int64Flag) IsVisible() bool {
 	return !f.Hidden
 }
 
+// GetCategory returns the category of the flag
+func (f *Int64Flag) GetCategory() string {
+	return f.Category
+}
+
+// GetUsage returns the usage string for the flag
+func (f *Int64Flag) GetUsage() string {
+	return f.Usage
+}
+
+// GetEnvVars returns the env vars for this flag
+func (f *Int64Flag) GetEnvVars() []string {
+	return f.EnvVars
+}
+
+// TakesValue returns true if the flag takes a value, otherwise false
+func (f *Int64Flag) TakesValue() bool {
+	return "Int64Flag" != "BoolFlag"
+}
+
+// GetDefaultText returns the default text for this flag
+func (f *Int64Flag) GetDefaultText() string {
+	if f.DefaultText != "" {
+		return f.DefaultText
+	}
+	return f.GetValue()
+}
+
 // StringFlag is a flag with type string
 type StringFlag struct {
 	Name string
@@ -536,6 +828,26 @@ func (f *StringFlag) IsVisible() bool {
 	return !f.Hidden
 }
 
+// GetCategory returns the category of the flag
+func (f *StringFlag) GetCategory() string {
+	return f.Category
+}
+
+// GetUsage returns the usage string for the flag
+func (f *StringFlag) GetUsage() string {
+	return f.Usage
+}
+
+// GetEnvVars returns the env vars for this flag
+func (f *StringFlag) GetEnvVars() []string {
+	return f.EnvVars
+}
+
+// TakesValue returns true if the flag takes a value, otherwise false
+func (f *StringFlag) TakesValue() bool {
+	return "StringFlag" != "BoolFlag"
+}
+
 // DurationFlag is a flag with type time.Duration
 type DurationFlag struct {
 	Name string
@@ -581,6 +893,34 @@ func (f *DurationFlag) IsVisible() bool {
 	return !f.Hidden
 }
 
+// GetCategory returns the category of the flag
+func (f *DurationFlag) GetCategory() string {
+	return f.Category
+}
+
+// GetUsage returns the usage string for the flag
+func (f *DurationFlag) GetUsage() string {
+	return f.Usage
+}
+
+// GetEnvVars returns the env vars for this flag
+func (f *DurationFlag) GetEnvVars() []string {
+	return f.EnvVars
+}
+
+// TakesValue returns true if the flag takes a value, otherwise false
+func (f *DurationFlag) TakesValue() bool {
+	return "DurationFlag" != "BoolFlag"
+}
+
+// GetDefaultText returns the default text for this flag
+func (f *DurationFlag) GetDefaultText() string {
+	if f.DefaultText != "" {
+		return f.DefaultText
+	}
+	return f.GetValue()
+}
+
 // UintFlag is a flag with type uint
 type UintFlag struct {
 	Name string
@@ -626,6 +966,34 @@ func (f *UintFlag) IsVisible() bool {
 	return !f.Hidden
 }
 
+// GetCategory returns the category of the flag
+func (f *UintFlag) GetCategory() string {
+	return f.Category
+}
+
+// GetUsage returns the usage string for the flag
+func (f *UintFlag) GetUsage() string {
+	return f.Usage
+}
+
+// GetEnvVars returns the env vars for this flag
+func (f *UintFlag) GetEnvVars() []string {
+	return f.EnvVars
+}
+
+// TakesValue returns true if the flag takes a value, otherwise false
+func (f *UintFlag) TakesValue() bool {
+	return "UintFlag" != "BoolFlag"
+}
+
+// GetDefaultText returns the default text for this flag
+func (f *UintFlag) GetDefaultText() string {
+	if f.DefaultText != "" {
+		return f.DefaultText
+	}
+	return f.GetValue()
+}
+
 // Uint64Flag is a flag with type uint64
 type Uint64Flag struct {
 	Name string
@@ -671,4 +1039,32 @@ func (f *Uint64Flag) IsVisible() bool {
 	return !f.Hidden
 }
 
+// GetCategory returns the category of the flag
+func (f *Uint64Flag) GetCategory() string {
+	return f.Category
+}
+
+// GetUsage returns the usage string for the flag
+func (f *Uint64Flag) GetUsage() string {
+	return f.Usage
+}
+
+// GetEnvVars returns the env vars for this flag
+func (f *Uint64Flag) GetEnvVars() []string {
+	return f.EnvVars
+}
+
+// TakesValue returns true if the flag takes a value, otherwise false
+func (f *Uint64Flag) TakesValue() bool {
+	return "Uint64Flag" != "BoolFlag"
+}
+
+// GetDefaultText returns the default text for this flag
+func (f *Uint64Flag) GetDefaultText() string {
+	if f.DefaultText != "" {
+		return f.DefaultText
+	}
+	return f.GetValue()
+}
+
 // vim:ro


Test patch:
diff --git a/app_test.go b/app_test.go
index 437af25..da3981c 100644
--- a/app_test.go
+++ b/app_test.go
@@ -2252,6 +2252,26 @@ func (c *customBoolFlag) IsSet() bool {
 	return false
 }
 
+func (c *customBoolFlag) IsRequired() bool {
+	return false
+}
+
+func (c *customBoolFlag) IsVisible() bool {
+	return false
+}
+
+func (c *customBoolFlag) GetCategory() string {
+	return ""
+}
+
+func (c *customBoolFlag) GetEnvVars() []string {
+	return nil
+}
+
+func (c *customBoolFlag) GetDefaultText() string {
+	return ""
+}
+
 func TestCustomFlagsUnused(t *testing.T) {
 	app := &App{
 		Flags:  []Flag{&customBoolFlag{"custom"}},
diff --git a/flag_test.go b/flag_test.go
index e46b1ef..deac525 100644
--- a/flag_test.go
+++ b/flag_test.go
@@ -144,10 +144,7 @@ func TestFlagsFromEnv(t *testing.T) {
 		defer resetEnv(os.Environ())
 		os.Clearenv()
 
-		f, ok := test.flag.(DocGenerationFlag)
-		if !ok {
-			t.Errorf("flag %v needs to implement DocGenerationFlag to retrieve env vars", test.flag)
-		}
+		f := test.flag
 		envVarSlice := f.GetEnvVars()
 		_ = os.Setenv(envVarSlice[0], test.input)
 
@@ -179,12 +176,6 @@ func TestFlagsFromEnv(t *testing.T) {
 	}
 }
 
-type nodocFlag struct {
-	Flag
-
-	Name string
-}
-
 func TestFlagStringifying(t *testing.T) {
 	for _, tc := range []struct {
 		name     string
@@ -341,11 +332,6 @@ func TestFlagStringifying(t *testing.T) {
 			fl:       &UintFlag{Name: "tubes", DefaultText: "13"},
 			expected: "--tubes value\t(default: 13)",
 		},
-		{
-			name:     "nodoc-flag",
-			fl:       &nodocFlag{Name: "scarecrow"},
-			expected: "",
-		},
 	} {
 		t.Run(tc.name, func(ct *testing.T) {
 			s := stringifyFlag(tc.fl)
diff --git a/internal/genflags/generated_test.gotmpl b/internal/genflags/generated_test.gotmpl
index 52de4e4..c91f562 100644
--- a/internal/genflags/generated_test.gotmpl
+++ b/internal/genflags/generated_test.gotmpl
@@ -10,31 +10,30 @@ func Test{{.TypeName}}_SatisfiesFlagInterface(t *testing.T) {
   _ = f.IsSet()
   _ = f.Names()
 }
-{{end}}
-
-{{if .GenerateFmtStringerInterface}}
-func Test{{.TypeName}}_SatisfiesFmtStringerInterface(t *testing.T) {
-  var f fmt.Stringer = &{{$.UrfaveCLITestNamespace}}{{.TypeName}}{}
-
-  _ = f.String()
-}
-{{end}}
 
-{{if .GenerateRequiredFlagInterface}}
 func Test{{.TypeName}}_SatisfiesRequiredFlagInterface(t *testing.T) {
-  var f {{$.UrfaveCLITestNamespace}}RequiredFlag = &{{$.UrfaveCLITestNamespace}}{{.TypeName}}{}
+  var f {{$.UrfaveCLITestNamespace}}Flag = &{{$.UrfaveCLITestNamespace}}{{.TypeName}}{}
 
   _ = f.IsRequired()
 }
-{{end}}
 
-{{if .GenerateVisibleFlagInterface}}
 func Test{{.TypeName}}_SatisfiesVisibleFlagInterface(t *testing.T) {
-  var f {{$.UrfaveCLITestNamespace}}VisibleFlag = &{{$.UrfaveCLITestNamespace}}{{.TypeName}}{}
+  var f {{$.UrfaveCLITestNamespace}}Flag = &{{$.UrfaveCLITestNamespace}}{{.TypeName}}{}
 
   _ = f.IsVisible()
 }
+
 {{end}}
+
+{{if .GenerateFmtStringerInterface}}
+func Test{{.TypeName}}_SatisfiesFmtStringerInterface(t *testing.T) {
+  var f fmt.Stringer = &{{$.UrfaveCLITestNamespace}}{{.TypeName}}{}
+
+  _ = f.String()
+}
+{{end}}
+
+
 {{end}}
 
 // vim{{/* 👻 */}}:ro
diff --git a/zz_generated.flags_test.go b/zz_generated.flags_test.go
index 1d9afda..16519e6 100644
--- a/zz_generated.flags_test.go
+++ b/zz_generated.flags_test.go
@@ -17,13 +17,13 @@ func TestFloat64SliceFlag_SatisfiesFlagInterface(t *testing.T) {
 }
 
 func TestFloat64SliceFlag_SatisfiesRequiredFlagInterface(t *testing.T) {
-	var f cli.RequiredFlag = &cli.Float64SliceFlag{}
+	var f cli.Flag = &cli.Float64SliceFlag{}
 
 	_ = f.IsRequired()
 }
 
 func TestFloat64SliceFlag_SatisfiesVisibleFlagInterface(t *testing.T) {
-	var f cli.VisibleFlag = &cli.Float64SliceFlag{}
+	var f cli.Flag = &cli.Float64SliceFlag{}
 
 	_ = f.IsVisible()
 }
@@ -35,24 +35,24 @@ func TestGenericFlag_SatisfiesFlagInterface(t *testing.T) {
 	_ = f.Names()
 }
 
-func TestGenericFlag_SatisfiesFmtStringerInterface(t *testing.T) {
-	var f fmt.Stringer = &cli.GenericFlag{}
-
-	_ = f.String()
-}
-
 func TestGenericFlag_SatisfiesRequiredFlagInterface(t *testing.T) {
-	var f cli.RequiredFlag = &cli.GenericFlag{}
+	var f cli.Flag = &cli.GenericFlag{}
 
 	_ = f.IsRequired()
 }
 
 func TestGenericFlag_SatisfiesVisibleFlagInterface(t *testing.T) {
-	var f cli.VisibleFlag = &cli.GenericFlag{}
+	var f cli.Flag = &cli.GenericFlag{}
 
 	_ = f.IsVisible()
 }
 
+func TestGenericFlag_SatisfiesFmtStringerInterface(t *testing.T) {
+	var f fmt.Stringer = &cli.GenericFlag{}
+
+	_ = f.String()
+}
+
 func TestInt64SliceFlag_SatisfiesFlagInterface(t *testing.T) {
 	var f cli.Flag = &cli.Int64SliceFlag{}
 
@@ -61,13 +61,13 @@ func TestInt64SliceFlag_SatisfiesFlagInterface(t *testing.T) {
 }
 
 func TestInt64SliceFlag_SatisfiesRequiredFlagInterface(t *testing.T) {
-	var f cli.RequiredFlag = &cli.Int64SliceFlag{}
+	var f cli.Flag = &cli.Int64SliceFlag{}
 
 	_ = f.IsRequired()
 }
 
 func TestInt64SliceFlag_SatisfiesVisibleFlagInterface(t *testing.T) {
-	var f cli.VisibleFlag = &cli.Int64SliceFlag{}
+	var f cli.Flag = &cli.Int64SliceFlag{}
 
 	_ = f.IsVisible()
 }
@@ -80,13 +80,13 @@ func TestIntSliceFlag_SatisfiesFlagInterface(t *testing.T) {
 }
 
 func TestIntSliceFlag_SatisfiesRequiredFlagInterface(t *testing.T) {
-	var f cli.RequiredFlag = &cli.IntSliceFlag{}
+	var f cli.Flag = &cli.IntSliceFlag{}
 
 	_ = f.IsRequired()
 }
 
 func TestIntSliceFlag_SatisfiesVisibleFlagInterface(t *testing.T) {
-	var f cli.VisibleFlag = &cli.IntSliceFlag{}
+	var f cli.Flag = &cli.IntSliceFlag{}
 
 	_ = f.IsVisible()
 }
@@ -98,24 +98,24 @@ func TestPathFlag_SatisfiesFlagInterface(t *testing.T) {
 	_ = f.Names()
 }
 
-func TestPathFlag_SatisfiesFmtStringerInterface(t *testing.T) {
-	var f fmt.Stringer = &cli.PathFlag{}
-
-	_ = f.String()
-}
-
 func TestPathFlag_SatisfiesRequiredFlagInterface(t *testing.T) {
-	var f cli.RequiredFlag = &cli.PathFlag{}
+	var f cli.Flag = &cli.PathFlag{}
 
 	_ = f.IsRequired()
 }
 
 func TestPathFlag_SatisfiesVisibleFlagInterface(t *testing.T) {
-	var f cli.VisibleFlag = &cli.PathFlag{}
+	var f cli.Flag = &cli.PathFlag{}
 
 	_ = f.IsVisible()
 }
 
+func TestPathFlag_SatisfiesFmtStringerInterface(t *testing.T) {
+	var f fmt.Stringer = &cli.PathFlag{}
+
+	_ = f.String()
+}
+
 func TestStringSliceFlag_SatisfiesFlagInterface(t *testing.T) {
 	var f cli.Flag = &cli.StringSliceFlag{}
 
@@ -124,13 +124,13 @@ func TestStringSliceFlag_SatisfiesFlagInterface(t *testing.T) {
 }
 
 func TestStringSliceFlag_SatisfiesRequiredFlagInterface(t *testing.T) {
-	var f cli.RequiredFlag = &cli.StringSliceFlag{}
+	var f cli.Flag = &cli.StringSliceFlag{}
 
 	_ = f.IsRequired()
 }
 
 func TestStringSliceFlag_SatisfiesVisibleFlagInterface(t *testing.T) {
-	var f cli.VisibleFlag = &cli.StringSliceFlag{}
+	var f cli.Flag = &cli.StringSliceFlag{}
 
 	_ = f.IsVisible()
 }
@@ -142,24 +142,24 @@ func TestTimestampFlag_SatisfiesFlagInterface(t *testing.T) {
 	_ = f.Names()
 }
 
-func TestTimestampFlag_SatisfiesFmtStringerInterface(t *testing.T) {
-	var f fmt.Stringer = &cli.TimestampFlag{}
-
-	_ = f.String()
-}
-
 func TestTimestampFlag_SatisfiesRequiredFlagInterface(t *testing.T) {
-	var f cli.RequiredFlag = &cli.TimestampFlag{}
+	var f cli.Flag = &cli.TimestampFlag{}
 
 	_ = f.IsRequired()
 }
 
 func TestTimestampFlag_SatisfiesVisibleFlagInterface(t *testing.T) {
-	var f cli.VisibleFlag = &cli.TimestampFlag{}
+	var f cli.Flag = &cli.TimestampFlag{}
 
 	_ = f.IsVisible()
 }
 
+func TestTimestampFlag_SatisfiesFmtStringerInterface(t *testing.T) {
+	var f fmt.Stringer = &cli.TimestampFlag{}
+
+	_ = f.String()
+}
+
 func TestBoolFlag_SatisfiesFlagInterface(t *testing.T) {
 	var f cli.Flag = &cli.BoolFlag{}
 
@@ -167,24 +167,24 @@ func TestBoolFlag_SatisfiesFlagInterface(t *testing.T) {
 	_ = f.Names()
 }
 
-func TestBoolFlag_SatisfiesFmtStringerInterface(t *testing.T) {
-	var f fmt.Stringer = &cli.BoolFlag{}
-
-	_ = f.String()
-}
-
 func TestBoolFlag_SatisfiesRequiredFlagInterface(t *testing.T) {
-	var f cli.RequiredFlag = &cli.BoolFlag{}
+	var f cli.Flag = &cli.BoolFlag{}
 
 	_ = f.IsRequired()
 }
 
 func TestBoolFlag_SatisfiesVisibleFlagInterface(t *testing.T) {
-	var f cli.VisibleFlag = &cli.BoolFlag{}
+	var f cli.Flag = &cli.BoolFlag{}
 
 	_ = f.IsVisible()
 }
 
+func TestBoolFlag_SatisfiesFmtStringerInterface(t *testing.T) {
+	var f fmt.Stringer = &cli.BoolFlag{}
+
+	_ = f.String()
+}
+
 func TestFloat64Flag_SatisfiesFlagInterface(t *testing.T) {
 	var f cli.Flag = &cli.Float64Flag{}
 
@@ -192,24 +192,24 @@ func TestFloat64Flag_SatisfiesFlagInterface(t *testing.T) {
 	_ = f.Names()
 }
 
-func TestFloat64Flag_SatisfiesFmtStringerInterface(t *testing.T) {
-	var f fmt.Stringer = &cli.Float64Flag{}
-
-	_ = f.String()
-}
-
 func TestFloat64Flag_SatisfiesRequiredFlagInterface(t *testing.T) {
-	var f cli.RequiredFlag = &cli.Float64Flag{}
+	var f cli.Flag = &cli.Float64Flag{}
 
 	_ = f.IsRequired()
 }
 
 func TestFloat64Flag_SatisfiesVisibleFlagInterface(t *testing.T) {
-	var f cli.VisibleFlag = &cli.Float64Flag{}
+	var f cli.Flag = &cli.Float64Flag{}
 
 	_ = f.IsVisible()
 }
 
+func TestFloat64Flag_SatisfiesFmtStringerInterface(t *testing.T) {
+	var f fmt.Stringer = &cli.Float64Flag{}
+
+	_ = f.String()
+}
+
 func TestIntFlag_SatisfiesFlagInterface(t *testing.T) {
 	var f cli.Flag = &cli.IntFlag{}
 
@@ -217,24 +217,24 @@ func TestIntFlag_SatisfiesFlagInterface(t *testing.T) {
 	_ = f.Names()
 }
 
-func TestIntFlag_SatisfiesFmtStringerInterface(t *testing.T) {
-	var f fmt.Stringer = &cli.IntFlag{}
-
-	_ = f.String()
-}
-
 func TestIntFlag_SatisfiesRequiredFlagInterface(t *testing.T) {
-	var f cli.RequiredFlag = &cli.IntFlag{}
+	var f cli.Flag = &cli.IntFlag{}
 
 	_ = f.IsRequired()
 }
 
 func TestIntFlag_SatisfiesVisibleFlagInterface(t *testing.T) {
-	var f cli.VisibleFlag = &cli.IntFlag{}
+	var f cli.Flag = &cli.IntFlag{}
 
 	_ = f.IsVisible()
 }
 
+func TestIntFlag_SatisfiesFmtStringerInterface(t *testing.T) {
+	var f fmt.Stringer = &cli.IntFlag{}
+
+	_ = f.String()
+}
+
 func TestInt64Flag_SatisfiesFlagInterface(t *testing.T) {
 	var f cli.Flag = &cli.Int64Flag{}
 
@@ -242,24 +242,24 @@ func TestInt64Flag_SatisfiesFlagInterface(t *testing.T) {
 	_ = f.Names()
 }
 
-func TestInt64Flag_SatisfiesFmtStringerInterface(t *testing.T) {
-	var f fmt.Stringer = &cli.Int64Flag{}
-
-	_ = f.String()
-}
-
 func TestInt64Flag_SatisfiesRequiredFlagInterface(t *testing.T) {
-	var f cli.RequiredFlag = &cli.Int64Flag{}
+	var f cli.Flag = &cli.Int64Flag{}
 
 	_ = f.IsRequired()
 }
 
 func TestInt64Flag_SatisfiesVisibleFlagInterface(t *testing.T) {
-	var f cli.VisibleFlag = &cli.Int64Flag{}
+	var f cli.Flag = &cli.Int64Flag{}
 
 	_ = f.IsVisible()
 }
 
+func TestInt64Flag_SatisfiesFmtStringerInterface(t *testing.T) {
+	var f fmt.Stringer = &cli.Int64Flag{}
+
+	_ = f.String()
+}
+
 func TestStringFlag_SatisfiesFlagInterface(t *testing.T) {
 	var f cli.Flag = &cli.StringFlag{}
 
@@ -267,24 +267,24 @@ func TestStringFlag_SatisfiesFlagInterface(t *testing.T) {
 	_ = f.Names()
 }
 
-func TestStringFlag_SatisfiesFmtStringerInterface(t *testing.T) {
-	var f fmt.Stringer = &cli.StringFlag{}
-
-	_ = f.String()
-}
-
 func TestStringFlag_SatisfiesRequiredFlagInterface(t *testing.T) {
-	var f cli.RequiredFlag = &cli.StringFlag{}
+	var f cli.Flag = &cli.StringFlag{}
 
 	_ = f.IsRequired()
 }
 
 func TestStringFlag_SatisfiesVisibleFlagInterface(t *testing.T) {
-	var f cli.VisibleFlag = &cli.StringFlag{}
+	var f cli.Flag = &cli.StringFlag{}
 
 	_ = f.IsVisible()
 }
 
+func TestStringFlag_SatisfiesFmtStringerInterface(t *testing.T) {
+	var f fmt.Stringer = &cli.StringFlag{}
+
+	_ = f.String()
+}
+
 func TestDurationFlag_SatisfiesFlagInterface(t *testing.T) {
 	var f cli.Flag = &cli.DurationFlag{}
 
@@ -292,24 +292,24 @@ func TestDurationFlag_SatisfiesFlagInterface(t *testing.T) {
 	_ = f.Names()
 }
 
-func TestDurationFlag_SatisfiesFmtStringerInterface(t *testing.T) {
-	var f fmt.Stringer = &cli.DurationFlag{}
-
-	_ = f.String()
-}
-
 func TestDurationFlag_SatisfiesRequiredFlagInterface(t *testing.T) {
-	var f cli.RequiredFlag = &cli.DurationFlag{}
+	var f cli.Flag = &cli.DurationFlag{}
 
 	_ = f.IsRequired()
 }
 
 func TestDurationFlag_SatisfiesVisibleFlagInterface(t *testing.T) {
-	var f cli.VisibleFlag = &cli.DurationFlag{}
+	var f cli.Flag = &cli.DurationFlag{}
 
 	_ = f.IsVisible()
 }
 
+func TestDurationFlag_SatisfiesFmtStringerInterface(t *testing.T) {
+	var f fmt.Stringer = &cli.DurationFlag{}
+
+	_ = f.String()
+}
+
 func TestUintFlag_SatisfiesFlagInterface(t *testing.T) {
 	var f cli.Flag = &cli.UintFlag{}
 
@@ -317,24 +317,24 @@ func TestUintFlag_SatisfiesFlagInterface(t *testing.T) {
 	_ = f.Names()
 }
 
-func TestUintFlag_SatisfiesFmtStringerInterface(t *testing.T) {
-	var f fmt.Stringer = &cli.UintFlag{}
-
-	_ = f.String()
-}
-
 func TestUintFlag_SatisfiesRequiredFlagInterface(t *testing.T) {
-	var f cli.RequiredFlag = &cli.UintFlag{}
+	var f cli.Flag = &cli.UintFlag{}
 
 	_ = f.IsRequired()
 }
 
 func TestUintFlag_SatisfiesVisibleFlagInterface(t *testing.T) {
-	var f cli.VisibleFlag = &cli.UintFlag{}
+	var f cli.Flag = &cli.UintFlag{}
 
 	_ = f.IsVisible()
 }
 
+func TestUintFlag_SatisfiesFmtStringerInterface(t *testing.T) {
+	var f fmt.Stringer = &cli.UintFlag{}
+
+	_ = f.String()
+}
+
 func TestUint64Flag_SatisfiesFlagInterface(t *testing.T) {
 	var f cli.Flag = &cli.Uint64Flag{}
 
@@ -342,22 +342,22 @@ func TestUint64Flag_SatisfiesFlagInterface(t *testing.T) {
 	_ = f.Names()
 }
 
-func TestUint64Flag_SatisfiesFmtStringerInterface(t *testing.T) {
-	var f fmt.Stringer = &cli.Uint64Flag{}
-
-	_ = f.String()
-}
-
 func TestUint64Flag_SatisfiesRequiredFlagInterface(t *testing.T) {
-	var f cli.RequiredFlag = &cli.Uint64Flag{}
+	var f cli.Flag = &cli.Uint64Flag{}
 
 	_ = f.IsRequired()
 }
 
 func TestUint64Flag_SatisfiesVisibleFlagInterface(t *testing.T) {
-	var f cli.VisibleFlag = &cli.Uint64Flag{}
+	var f cli.Flag = &cli.Uint64Flag{}
 
 	_ = f.IsVisible()
 }
 
+func TestUint64Flag_SatisfiesFmtStringerInterface(t *testing.T) {
+	var f fmt.Stringer = &cli.Uint64Flag{}
+
+	_ = f.String()
+}
+
 // vim:ro