Remove all flag interfaces

This commit is contained in:
Naveen Gogineni 2022-09-04 22:51:05 -04:00
parent ab68d8a69d
commit 268cb973f8
28 changed files with 192 additions and 262 deletions

4
app.go
View File

@ -227,9 +227,7 @@ func (a *App) Setup() {
a.flagCategories = newFlagCategories() a.flagCategories = newFlagCategories()
for _, fl := range a.Flags { for _, fl := range a.Flags {
if cf, ok := fl.(CategorizableFlag); ok { a.flagCategories.AddFlag(fl.GetCategory(), fl)
a.flagCategories.AddFlag(cf.GetCategory(), cf)
}
} }
if a.Metadata == nil { if a.Metadata == nil {

View File

@ -2268,6 +2268,10 @@ func (c *customBoolFlag) GetEnvVars() []string {
return nil return nil
} }
func (c *customBoolFlag) GetDefaultText() string {
return ""
}
func TestCustomFlagsUnused(t *testing.T) { func TestCustomFlagsUnused(t *testing.T) {
app := &App{ app := &App{
Flags: []Flag{&customBoolFlag{"custom"}}, Flags: []Flag{&customBoolFlag{"custom"}},

View File

@ -101,9 +101,7 @@ func newFlagCategories() FlagCategories {
func newFlagCategoriesFromFlags(fs []Flag) FlagCategories { func newFlagCategoriesFromFlags(fs []Flag) FlagCategories {
fc := newFlagCategories() fc := newFlagCategories()
for _, fl := range fs { for _, fl := range fs {
if cf, ok := fl.(CategorizableFlag); ok { fc.AddFlag(fl.GetCategory(), fl)
fc.AddFlag(cf.GetCategory(), cf)
}
} }
return fc return fc
@ -138,7 +136,7 @@ type VisibleFlagCategory interface {
// Name returns the category name string // Name returns the category name string
Name() string Name() string
// Flags returns a slice of VisibleFlag sorted by name // Flags returns a slice of VisibleFlag sorted by name
Flags() []VisibleFlag Flags() []Flag
} }
type defaultVisibleFlagCategory struct { type defaultVisibleFlagCategory struct {
@ -150,21 +148,19 @@ func (fc *defaultVisibleFlagCategory) Name() string {
return fc.name return fc.name
} }
func (fc *defaultVisibleFlagCategory) Flags() []VisibleFlag { func (fc *defaultVisibleFlagCategory) Flags() []Flag {
vfNames := []string{} vfNames := []string{}
for flName, fl := range fc.m { for flName, fl := range fc.m {
if vf, ok := fl.(VisibleFlag); ok { if fl.IsVisible() {
if vf.IsVisible() { vfNames = append(vfNames, flName)
vfNames = append(vfNames, flName)
}
} }
} }
sort.Strings(vfNames) sort.Strings(vfNames)
ret := make([]VisibleFlag, len(vfNames)) ret := make([]Flag, len(vfNames))
for i, flName := range vfNames { for i, flName := range vfNames {
ret[i] = fc.m[flName].(VisibleFlag) ret[i] = fc.m[flName]
} }
return ret return ret

View File

@ -165,7 +165,7 @@ func (cCtx *Context) lookupFlagSet(name string) *flag.FlagSet {
func (cCtx *Context) checkRequiredFlags(flags []Flag) requiredFlagsErr { func (cCtx *Context) checkRequiredFlags(flags []Flag) requiredFlagsErr {
var missingFlags []string var missingFlags []string
for _, f := range flags { for _, f := range flags {
if rf, ok := f.(RequiredFlag); ok && rf.IsRequired() { if f.IsRequired() {
var flagPresent bool var flagPresent bool
var flagName string var flagName string

View File

@ -116,11 +116,7 @@ func prepareFlags(
addDetails bool, addDetails bool,
) []string { ) []string {
args := []string{} args := []string{}
for _, f := range flags { for _, flag := range flags {
flag, ok := f.(DocGenerationFlag)
if !ok {
continue
}
modifiedArg := opener modifiedArg := opener
for _, s := range flag.Names() { for _, s := range flag.Names() {
@ -151,7 +147,7 @@ func prepareFlags(
} }
// flagDetails returns a string containing the flags metadata // flagDetails returns a string containing the flags metadata
func flagDetails(flag DocGenerationFlag) string { func flagDetails(flag Flag) string {
description := flag.GetUsage() description := flag.GetUsage()
value := flag.GetValue() value := flag.GetValue()
if value != "" { if value != "" {

View File

@ -114,12 +114,7 @@ func (a *App) prepareFishCommands(commands []*Command, allCommands *[]string, pr
func (a *App) prepareFishFlags(flags []Flag, previousCommands []string) []string { func (a *App) prepareFishFlags(flags []Flag, previousCommands []string) []string {
completions := []string{} completions := []string{}
for _, f := range flags { for _, flag := range flags {
flag, ok := f.(DocGenerationFlag)
if !ok {
continue
}
completion := &strings.Builder{} completion := &strings.Builder{}
completion.WriteString(fmt.Sprintf( completion.WriteString(fmt.Sprintf(
"complete -c %s -n '%s'", "complete -c %s -n '%s'",
@ -127,7 +122,7 @@ func (a *App) prepareFishFlags(flags []Flag, previousCommands []string) []string
a.fishSubcommandHelper(previousCommands), a.fishSubcommandHelper(previousCommands),
)) ))
fishAddFileFlag(f, completion) fishAddFileFlag(flag, completion)
for idx, opt := range flag.Names() { for idx, opt := range flag.Names() {
if idx == 0 { if idx == 0 {

View File

@ -3,7 +3,8 @@
# `genflags.Spec` type that maps to this file structure. # `genflags.Spec` type that maps to this file structure.
flag_types: flag_types:
bool: {} bool:
no_default_text: true
float64: {} float64: {}
int64: {} int64: {}
int: {} int: {}
@ -12,12 +13,14 @@ flag_types:
uint: {} uint: {}
string: string:
no_default_text: true
struct_fields: struct_fields:
- { name: TakesFile, type: bool } - { name: TakesFile, type: bool }
Generic: Generic:
struct_fields: struct_fields:
- { name: TakesFile, type: bool } - { name: TakesFile, type: bool }
Path: Path:
no_default_text: true
struct_fields: struct_fields:
- { name: TakesFile, type: bool } - { name: TakesFile, type: bool }

47
flag.go
View File

@ -101,38 +101,13 @@ type Flag interface {
GetUsage() string GetUsage() string
// GetEnvVars returns the env vars for this flag // GetEnvVars returns the env vars for this flag
GetEnvVars() []string GetEnvVars() []string
}
// 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
}
// DocGenerationFlag is an interface that allows documentation generation for the flag
type DocGenerationFlag interface {
Flag
// TakesValue returns true if the flag takes a value, otherwise false // TakesValue returns true if the flag takes a value, otherwise false
TakesValue() bool TakesValue() bool
// GetDefaultText returns the default text for this flag
GetDefaultText() string
// GetValue returns the flags value as string representation and an empty // GetValue returns the flags value as string representation and an empty
// string if the flag takes no value at all. // string if the flag takes no value at all.
GetValue() string GetValue() string
// GetDefaultText returns the default text for this flag
GetDefaultText() string
}
// VisibleFlag is an interface that allows to check if a flag is visible
type VisibleFlag interface {
Flag
}
// CategorizableFlag is an interface that allows us to potentially
// use a flag in a categorized representation.
type CategorizableFlag interface {
VisibleFlag
} }
func flagSet(name string, flags []Flag) (*flag.FlagSet, error) { func flagSet(name string, flags []Flag) (*flag.FlagSet, error) {
@ -192,7 +167,7 @@ func normalizeFlags(flags []Flag, set *flag.FlagSet) error {
func visibleFlags(fl []Flag) []Flag { func visibleFlags(fl []Flag) []Flag {
var visible []Flag var visible []Flag
for _, f := range fl { for _, f := range fl {
if vf, ok := f.(VisibleFlag); ok && vf.IsVisible() { if f.IsVisible() {
visible = append(visible, f) visible = append(visible, f)
} }
} }
@ -288,14 +263,8 @@ func formatDefault(format string) string {
} }
func stringifyFlag(f Flag) string { func stringifyFlag(f Flag) string {
// enforce DocGeneration interface on flags to avoid reflection placeholder, usage := unquoteUsage(f.GetUsage())
df, ok := f.(DocGenerationFlag) needsPlaceholder := f.TakesValue()
if !ok {
return ""
}
placeholder, usage := unquoteUsage(df.GetUsage())
needsPlaceholder := df.TakesValue()
if needsPlaceholder && placeholder == "" { if needsPlaceholder && placeholder == "" {
placeholder = defaultPlaceholder placeholder = defaultPlaceholder
@ -303,14 +272,14 @@ func stringifyFlag(f Flag) string {
defaultValueString := "" defaultValueString := ""
if s := df.GetDefaultText(); s != "" { if s := f.GetDefaultText(); s != "" {
defaultValueString = fmt.Sprintf(formatDefault("%s"), s) defaultValueString = fmt.Sprintf(formatDefault("%s"), s)
} }
usageWithDefault := strings.TrimSpace(usage + defaultValueString) usageWithDefault := strings.TrimSpace(usage + defaultValueString)
return withEnvHint(df.GetEnvVars(), return withEnvHint(f.GetEnvVars(),
fmt.Sprintf("%s\t%s", prefixedNames(df.Names(), placeholder), usageWithDefault)) fmt.Sprintf("%s\t%s", prefixedNames(f.Names(), placeholder), usageWithDefault))
} }
func stringifyIntSliceFlag(f *IntSliceFlag) string { func stringifyIntSliceFlag(f *IntSliceFlag) string {

View File

@ -12,14 +12,6 @@ func (f *DurationFlag) GetValue() string {
return f.Value.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()
}
// Apply populates the flag given the flag set and environment // Apply populates the flag given the flag set and environment
func (f *DurationFlag) Apply(set *flag.FlagSet) error { func (f *DurationFlag) Apply(set *flag.FlagSet) error {
if val, source, found := flagFromEnvOrFile(f.EnvVars, f.FilePath); found { if val, source, found := flagFromEnvOrFile(f.EnvVars, f.FilePath); found {

View File

@ -12,14 +12,6 @@ func (f *Float64Flag) GetValue() string {
return fmt.Sprintf("%v", f.Value) 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()
}
// Apply populates the flag given the flag set and environment // Apply populates the flag given the flag set and environment
func (f *Float64Flag) Apply(set *flag.FlagSet) error { func (f *Float64Flag) Apply(set *flag.FlagSet) error {
if val, source, found := flagFromEnvOrFile(f.EnvVars, f.FilePath); found { if val, source, found := flagFromEnvOrFile(f.EnvVars, f.FilePath); found {

View File

@ -95,14 +95,6 @@ func (f *Float64SliceFlag) GetValue() string {
return "" return ""
} }
// GetDefaultText returns the default text for this flag
func (f *Float64SliceFlag) GetDefaultText() string {
if f.DefaultText != "" {
return f.DefaultText
}
return f.GetValue()
}
// Apply populates the flag given the flag set and environment // Apply populates the flag given the flag set and environment
func (f *Float64SliceFlag) Apply(set *flag.FlagSet) error { func (f *Float64SliceFlag) Apply(set *flag.FlagSet) error {
// apply any default // apply any default

View File

@ -20,14 +20,6 @@ func (f *GenericFlag) GetValue() string {
return "" return ""
} }
// GetDefaultText returns the default text for this flag
func (f *GenericFlag) GetDefaultText() string {
if f.DefaultText != "" {
return f.DefaultText
}
return f.GetValue()
}
// Apply takes the flagset and calls Set on the generic flag with the value // Apply takes the flagset and calls Set on the generic flag with the value
// provided by the user for parsing by the flag // provided by the user for parsing by the flag
func (f GenericFlag) Apply(set *flag.FlagSet) error { func (f GenericFlag) Apply(set *flag.FlagSet) error {

View File

@ -12,14 +12,6 @@ func (f *IntFlag) GetValue() string {
return fmt.Sprintf("%d", f.Value) 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()
}
// Apply populates the flag given the flag set and environment // Apply populates the flag given the flag set and environment
func (f *IntFlag) Apply(set *flag.FlagSet) error { func (f *IntFlag) Apply(set *flag.FlagSet) error {
if val, source, found := flagFromEnvOrFile(f.EnvVars, f.FilePath); found { if val, source, found := flagFromEnvOrFile(f.EnvVars, f.FilePath); found {

View File

@ -12,14 +12,6 @@ func (f *Int64Flag) GetValue() string {
return fmt.Sprintf("%d", f.Value) 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()
}
// Apply populates the flag given the flag set and environment // Apply populates the flag given the flag set and environment
func (f *Int64Flag) Apply(set *flag.FlagSet) error { func (f *Int64Flag) Apply(set *flag.FlagSet) error {
if val, source, found := flagFromEnvOrFile(f.EnvVars, f.FilePath); found { if val, source, found := flagFromEnvOrFile(f.EnvVars, f.FilePath); found {

View File

@ -96,14 +96,6 @@ func (f *Int64SliceFlag) GetValue() string {
return "" return ""
} }
// GetDefaultText returns the default text for this flag
func (f *Int64SliceFlag) GetDefaultText() string {
if f.DefaultText != "" {
return f.DefaultText
}
return f.GetValue()
}
// Apply populates the flag given the flag set and environment // Apply populates the flag given the flag set and environment
func (f *Int64SliceFlag) Apply(set *flag.FlagSet) error { func (f *Int64SliceFlag) Apply(set *flag.FlagSet) error {
// apply any default // apply any default

View File

@ -107,14 +107,6 @@ func (f *IntSliceFlag) GetValue() string {
return "" return ""
} }
// GetDefaultText returns the default text for this flag
func (f *IntSliceFlag) GetDefaultText() string {
if f.DefaultText != "" {
return f.DefaultText
}
return f.GetValue()
}
// Apply populates the flag given the flag set and environment // Apply populates the flag given the flag set and environment
func (f *IntSliceFlag) Apply(set *flag.FlagSet) error { func (f *IntSliceFlag) Apply(set *flag.FlagSet) error {
// apply any default // apply any default

View File

@ -85,14 +85,6 @@ func (f *StringSliceFlag) GetValue() string {
return "" return ""
} }
// GetDefaultText returns the default text for this flag
func (f *StringSliceFlag) GetDefaultText() string {
if f.DefaultText != "" {
return f.DefaultText
}
return f.GetValue()
}
// Apply populates the flag given the flag set and environment // Apply populates the flag given the flag set and environment
func (f *StringSliceFlag) Apply(set *flag.FlagSet) error { func (f *StringSliceFlag) Apply(set *flag.FlagSet) error {
// apply any default // apply any default

View File

@ -144,10 +144,7 @@ func TestFlagsFromEnv(t *testing.T) {
defer resetEnv(os.Environ()) defer resetEnv(os.Environ())
os.Clearenv() os.Clearenv()
f, ok := test.flag.(DocGenerationFlag) f := test.flag
if !ok {
t.Errorf("flag %v needs to implement DocGenerationFlag to retrieve env vars", test.flag)
}
envVarSlice := f.GetEnvVars() envVarSlice := f.GetEnvVars()
_ = os.Setenv(envVarSlice[0], test.input) _ = 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) { func TestFlagStringifying(t *testing.T) {
for _, tc := range []struct { for _, tc := range []struct {
name string name string
@ -341,11 +332,6 @@ func TestFlagStringifying(t *testing.T) {
fl: &UintFlag{Name: "tubes", DefaultText: "13"}, fl: &UintFlag{Name: "tubes", DefaultText: "13"},
expected: "--tubes value\t(default: 13)", expected: "--tubes value\t(default: 13)",
}, },
{
name: "nodoc-flag",
fl: &nodocFlag{Name: "scarecrow"},
expected: "",
},
} { } {
t.Run(tc.name, func(ct *testing.T) { t.Run(tc.name, func(ct *testing.T) {
s := stringifyFlag(tc.fl) s := stringifyFlag(tc.fl)
@ -2398,43 +2384,43 @@ func TestFlagDefaultValue(t *testing.T) {
name: "stringSclice", name: "stringSclice",
flag: &StringSliceFlag{Name: "flag", Value: NewStringSlice("default1", "default2")}, flag: &StringSliceFlag{Name: "flag", Value: NewStringSlice("default1", "default2")},
toParse: []string{"--flag", "parsed"}, toParse: []string{"--flag", "parsed"},
expect: `--flag value (default: "default1", "default2") (accepts multiple inputs)`, expect: `--flag value (default: "default1", "default2") (accepts multiple inputs)`,
}, },
{ {
name: "float64Sclice", name: "float64Sclice",
flag: &Float64SliceFlag{Name: "flag", Value: NewFloat64Slice(1.1, 2.2)}, flag: &Float64SliceFlag{Name: "flag", Value: NewFloat64Slice(1.1, 2.2)},
toParse: []string{"--flag", "13.3"}, toParse: []string{"--flag", "13.3"},
expect: `--flag value (default: 1.1, 2.2) (accepts multiple inputs)`, expect: `--flag value (default: 1.1, 2.2) (accepts multiple inputs)`,
}, },
{ {
name: "int64Sclice", name: "int64Sclice",
flag: &Int64SliceFlag{Name: "flag", Value: NewInt64Slice(1, 2)}, flag: &Int64SliceFlag{Name: "flag", Value: NewInt64Slice(1, 2)},
toParse: []string{"--flag", "13"}, toParse: []string{"--flag", "13"},
expect: `--flag value (default: 1, 2) (accepts multiple inputs)`, expect: `--flag value (default: 1, 2) (accepts multiple inputs)`,
}, },
{ {
name: "intSclice", name: "intSclice",
flag: &IntSliceFlag{Name: "flag", Value: NewIntSlice(1, 2)}, flag: &IntSliceFlag{Name: "flag", Value: NewIntSlice(1, 2)},
toParse: []string{"--flag", "13"}, toParse: []string{"--flag", "13"},
expect: `--flag value (default: 1, 2) (accepts multiple inputs)`, expect: `--flag value (default: 1, 2) (accepts multiple inputs)`,
}, },
{ {
name: "string", name: "string",
flag: &StringFlag{Name: "flag", Value: "default"}, flag: &StringFlag{Name: "flag", Value: "default"},
toParse: []string{"--flag", "parsed"}, toParse: []string{"--flag", "parsed"},
expect: `--flag value (default: "default")`, expect: `--flag value (default: "default")`,
}, },
{ {
name: "bool", name: "bool",
flag: &BoolFlag{Name: "flag", Value: true}, flag: &BoolFlag{Name: "flag", Value: true},
toParse: []string{"--flag", "false"}, toParse: []string{"--flag", "false"},
expect: `--flag (default: true)`, expect: `--flag (default: true)`,
}, },
{ {
name: "uint64", name: "uint64",
flag: &Uint64Flag{Name: "flag", Value: 1}, flag: &Uint64Flag{Name: "flag", Value: 1},
toParse: []string{"--flag", "13"}, toParse: []string{"--flag", "13"},
expect: `--flag value (default: 1)`, expect: `--flag value (default: 1)`,
}, },
} }
for i, v := range cases { for i, v := range cases {

View File

@ -81,14 +81,6 @@ func (f *TimestampFlag) GetValue() string {
return "" return ""
} }
// GetDefaultText returns the default text for this flag
func (f *TimestampFlag) GetDefaultText() string {
if f.DefaultText != "" {
return f.DefaultText
}
return f.GetValue()
}
// Apply populates the flag given the flag set and environment // Apply populates the flag given the flag set and environment
func (f *TimestampFlag) Apply(set *flag.FlagSet) error { func (f *TimestampFlag) Apply(set *flag.FlagSet) error {
if f.Layout == "" { if f.Layout == "" {

View File

@ -37,14 +37,6 @@ func (f *UintFlag) GetValue() string {
return fmt.Sprintf("%d", f.Value) 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()
}
// Get returns the flags value in the given Context. // Get returns the flags value in the given Context.
func (f *UintFlag) Get(ctx *Context) uint { func (f *UintFlag) Get(ctx *Context) uint {
return ctx.Uint(f.Name) return ctx.Uint(f.Name)

View File

@ -37,14 +37,6 @@ func (f *Uint64Flag) GetValue() string {
return fmt.Sprintf("%d", f.Value) 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()
}
// Get returns the flags value in the given Context. // Get returns the flags value in the given Context.
func (f *Uint64Flag) Get(ctx *Context) uint64 { func (f *Uint64Flag) Get(ctx *Context) uint64 {
return ctx.Uint64(f.Name) return ctx.Uint64(f.Name)

View File

@ -493,12 +493,6 @@ func (f *BoolFlag) String() string
func (f *BoolFlag) TakesValue() bool func (f *BoolFlag) TakesValue() bool
TakesValue returns true if the flag takes a value, otherwise false TakesValue returns true if the flag takes a value, otherwise false
type CategorizableFlag interface {
VisibleFlag
}
CategorizableFlag is an interface that allows us to potentially use a flag
in a categorized representation.
type Command struct { type Command struct {
// The name of the command // The name of the command
Name string Name string
@ -699,22 +693,6 @@ func (cCtx *Context) Uint64(name string) uint64
func (cCtx *Context) Value(name string) interface{} func (cCtx *Context) Value(name string) interface{}
Value returns the value of the flag corresponding to `name` 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
// 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
}
DocGenerationFlag is an interface that allows documentation generation for
the flag
type DurationFlag struct { type DurationFlag struct {
Name string Name string
@ -820,6 +798,13 @@ type Flag interface {
GetUsage() string GetUsage() string
// GetEnvVars returns the env vars for this flag // GetEnvVars returns the env vars for this flag
GetEnvVars() []string 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 Flag is a common interface related to parsing flags in cli. For more
advanced flag parsing techniques, it is recommended that this interface be advanced flag parsing techniques, it is recommended that this interface be
@ -1508,13 +1493,6 @@ func (f *PathFlag) String() string
func (f *PathFlag) TakesValue() bool func (f *PathFlag) TakesValue() bool
TakesValue returns true if the flag takes a value, otherwise false TakesValue returns true if the flag takes a value, otherwise false
type RequiredFlag interface {
Flag
}
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 Serializer interface { type Serializer interface {
Serialize() string Serialize() string
} }
@ -1562,8 +1540,6 @@ func (x *SliceFlag[T, S, E]) TakesValue() bool
type SliceFlagTarget[E any] interface { type SliceFlagTarget[E any] interface {
Flag Flag
DocGenerationFlag
CategorizableFlag
// SetValue should propagate the given slice to the target, ideally as a new value. // 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). // Note that a nil slice should nil/clear any existing value (modelled as ~[]E).
@ -1949,16 +1925,11 @@ func (f *UintFlag) String() string
func (f *UintFlag) TakesValue() bool func (f *UintFlag) TakesValue() bool
TakesValue returns true if the flag takes a value, otherwise false TakesValue returns true if the flag takes a value, otherwise false
type VisibleFlag interface {
Flag
}
VisibleFlag is an interface that allows to check if a flag is visible
type VisibleFlagCategory interface { type VisibleFlagCategory interface {
// Name returns the category name string // Name returns the category name string
Name() string Name() string
// Flags returns a slice of VisibleFlag sorted by name // Flags returns a slice of VisibleFlag sorted by name
Flags() []VisibleFlag Flags() []Flag
} }
VisibleFlagCategory is a category containing flags. VisibleFlagCategory is a category containing flags.

View File

@ -75,6 +75,16 @@ func (f *{{.TypeName}}) TakesValue() bool {
return "{{.TypeName }}" != "BoolFlag" 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}}{{/* /if .GenerateFlagInterface */}}
{{end}}{{/* /range .SortedFlagTypes */}} {{end}}{{/* /range .SortedFlagTypes */}}

View File

@ -12,13 +12,13 @@ func Test{{.TypeName}}_SatisfiesFlagInterface(t *testing.T) {
} }
func Test{{.TypeName}}_SatisfiesRequiredFlagInterface(t *testing.T) { func Test{{.TypeName}}_SatisfiesRequiredFlagInterface(t *testing.T) {
var f {{$.UrfaveCLITestNamespace}}RequiredFlag = &{{$.UrfaveCLITestNamespace}}{{.TypeName}}{} var f {{$.UrfaveCLITestNamespace}}Flag = &{{$.UrfaveCLITestNamespace}}{{.TypeName}}{}
_ = f.IsRequired() _ = f.IsRequired()
} }
func Test{{.TypeName}}_SatisfiesVisibleFlagInterface(t *testing.T) { func Test{{.TypeName}}_SatisfiesVisibleFlagInterface(t *testing.T) {
var f {{$.UrfaveCLITestNamespace}}VisibleFlag = &{{$.UrfaveCLITestNamespace}}{{.TypeName}}{} var f {{$.UrfaveCLITestNamespace}}Flag = &{{$.UrfaveCLITestNamespace}}{{.TypeName}}{}
_ = f.IsVisible() _ = f.IsVisible()
} }

View File

@ -39,11 +39,11 @@ func (gfs *Spec) SortedFlagTypes() []*FlagType {
} }
type FlagTypeConfig struct { type FlagTypeConfig struct {
SkipInterfaces []string `yaml:"skip_interfaces"` SkipInterfaces []string `yaml:"skip_interfaces"`
StructFields []*FlagStructField `yaml:"struct_fields"` StructFields []*FlagStructField `yaml:"struct_fields"`
TypeName string `yaml:"type_name"` TypeName string `yaml:"type_name"`
ValuePointer bool `yaml:"value_pointer"` ValuePointer bool `yaml:"value_pointer"`
DoesntNeedValue bool `yaml:"doesnt_need_value"` NoDefaultText bool `yaml:"no_default_text"`
} }
type FlagStructField struct { type FlagStructField struct {
@ -84,6 +84,10 @@ func (ft *FlagType) GenerateFlagInterface() bool {
return ft.skipInterfaceNamed("Flag") return ft.skipInterfaceNamed("Flag")
} }
func (ft *FlagType) GenerateDefaultText() bool {
return !ft.Config.NoDefaultText
}
func (ft *FlagType) skipInterfaceNamed(name string) bool { func (ft *FlagType) skipInterfaceNamed(name string) bool {
if ft.Config == nil { if ft.Config == nil {
return true return true

View File

@ -21,8 +21,6 @@ type (
// update). // update).
SliceFlagTarget[E any] interface { SliceFlagTarget[E any] interface {
Flag Flag
DocGenerationFlag
CategorizableFlag
// SetValue should propagate the given slice to the target, ideally as a new value. // 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). // Note that a nil slice should nil/clear any existing value (modelled as ~[]E).

View File

@ -64,6 +64,14 @@ func (f *Float64SliceFlag) TakesValue() bool {
return "Float64SliceFlag" != "BoolFlag" 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 // GenericFlag is a flag with type Generic
type GenericFlag struct { type GenericFlag struct {
Name string Name string
@ -131,6 +139,14 @@ func (f *GenericFlag) TakesValue() bool {
return "GenericFlag" != "BoolFlag" 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 // Int64SliceFlag is a flag with type *Int64Slice
type Int64SliceFlag struct { type Int64SliceFlag struct {
Name string Name string
@ -191,6 +207,14 @@ func (f *Int64SliceFlag) TakesValue() bool {
return "Int64SliceFlag" != "BoolFlag" 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 // IntSliceFlag is a flag with type *IntSlice
type IntSliceFlag struct { type IntSliceFlag struct {
Name string Name string
@ -251,6 +275,14 @@ func (f *IntSliceFlag) TakesValue() bool {
return "IntSliceFlag" != "BoolFlag" 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 // PathFlag is a flag with type Path
type PathFlag struct { type PathFlag struct {
Name string Name string
@ -380,6 +412,14 @@ func (f *StringSliceFlag) TakesValue() bool {
return "StringSliceFlag" != "BoolFlag" 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 // TimestampFlag is a flag with type *Timestamp
type TimestampFlag struct { type TimestampFlag struct {
Name string Name string
@ -449,6 +489,14 @@ func (f *TimestampFlag) TakesValue() bool {
return "TimestampFlag" != "BoolFlag" 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 // BoolFlag is a flag with type bool
type BoolFlag struct { type BoolFlag struct {
Name string Name string
@ -579,6 +627,14 @@ func (f *Float64Flag) TakesValue() bool {
return "Float64Flag" != "BoolFlag" 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 // IntFlag is a flag with type int
type IntFlag struct { type IntFlag struct {
Name string Name string
@ -644,6 +700,14 @@ func (f *IntFlag) TakesValue() bool {
return "IntFlag" != "BoolFlag" 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 // Int64Flag is a flag with type int64
type Int64Flag struct { type Int64Flag struct {
Name string Name string
@ -709,6 +773,14 @@ func (f *Int64Flag) TakesValue() bool {
return "Int64Flag" != "BoolFlag" 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 // StringFlag is a flag with type string
type StringFlag struct { type StringFlag struct {
Name string Name string
@ -841,6 +913,14 @@ func (f *DurationFlag) TakesValue() bool {
return "DurationFlag" != "BoolFlag" 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 // UintFlag is a flag with type uint
type UintFlag struct { type UintFlag struct {
Name string Name string
@ -906,6 +986,14 @@ func (f *UintFlag) TakesValue() bool {
return "UintFlag" != "BoolFlag" 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 // Uint64Flag is a flag with type uint64
type Uint64Flag struct { type Uint64Flag struct {
Name string Name string
@ -971,4 +1059,12 @@ func (f *Uint64Flag) TakesValue() bool {
return "Uint64Flag" != "BoolFlag" 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 // vim:ro

View File

@ -17,13 +17,13 @@ func TestFloat64SliceFlag_SatisfiesFlagInterface(t *testing.T) {
} }
func TestFloat64SliceFlag_SatisfiesRequiredFlagInterface(t *testing.T) { func TestFloat64SliceFlag_SatisfiesRequiredFlagInterface(t *testing.T) {
var f cli.RequiredFlag = &cli.Float64SliceFlag{} var f cli.Flag = &cli.Float64SliceFlag{}
_ = f.IsRequired() _ = f.IsRequired()
} }
func TestFloat64SliceFlag_SatisfiesVisibleFlagInterface(t *testing.T) { func TestFloat64SliceFlag_SatisfiesVisibleFlagInterface(t *testing.T) {
var f cli.VisibleFlag = &cli.Float64SliceFlag{} var f cli.Flag = &cli.Float64SliceFlag{}
_ = f.IsVisible() _ = f.IsVisible()
} }
@ -36,13 +36,13 @@ func TestGenericFlag_SatisfiesFlagInterface(t *testing.T) {
} }
func TestGenericFlag_SatisfiesRequiredFlagInterface(t *testing.T) { func TestGenericFlag_SatisfiesRequiredFlagInterface(t *testing.T) {
var f cli.RequiredFlag = &cli.GenericFlag{} var f cli.Flag = &cli.GenericFlag{}
_ = f.IsRequired() _ = f.IsRequired()
} }
func TestGenericFlag_SatisfiesVisibleFlagInterface(t *testing.T) { func TestGenericFlag_SatisfiesVisibleFlagInterface(t *testing.T) {
var f cli.VisibleFlag = &cli.GenericFlag{} var f cli.Flag = &cli.GenericFlag{}
_ = f.IsVisible() _ = f.IsVisible()
} }
@ -61,13 +61,13 @@ func TestInt64SliceFlag_SatisfiesFlagInterface(t *testing.T) {
} }
func TestInt64SliceFlag_SatisfiesRequiredFlagInterface(t *testing.T) { func TestInt64SliceFlag_SatisfiesRequiredFlagInterface(t *testing.T) {
var f cli.RequiredFlag = &cli.Int64SliceFlag{} var f cli.Flag = &cli.Int64SliceFlag{}
_ = f.IsRequired() _ = f.IsRequired()
} }
func TestInt64SliceFlag_SatisfiesVisibleFlagInterface(t *testing.T) { func TestInt64SliceFlag_SatisfiesVisibleFlagInterface(t *testing.T) {
var f cli.VisibleFlag = &cli.Int64SliceFlag{} var f cli.Flag = &cli.Int64SliceFlag{}
_ = f.IsVisible() _ = f.IsVisible()
} }
@ -80,13 +80,13 @@ func TestIntSliceFlag_SatisfiesFlagInterface(t *testing.T) {
} }
func TestIntSliceFlag_SatisfiesRequiredFlagInterface(t *testing.T) { func TestIntSliceFlag_SatisfiesRequiredFlagInterface(t *testing.T) {
var f cli.RequiredFlag = &cli.IntSliceFlag{} var f cli.Flag = &cli.IntSliceFlag{}
_ = f.IsRequired() _ = f.IsRequired()
} }
func TestIntSliceFlag_SatisfiesVisibleFlagInterface(t *testing.T) { func TestIntSliceFlag_SatisfiesVisibleFlagInterface(t *testing.T) {
var f cli.VisibleFlag = &cli.IntSliceFlag{} var f cli.Flag = &cli.IntSliceFlag{}
_ = f.IsVisible() _ = f.IsVisible()
} }
@ -99,13 +99,13 @@ func TestPathFlag_SatisfiesFlagInterface(t *testing.T) {
} }
func TestPathFlag_SatisfiesRequiredFlagInterface(t *testing.T) { func TestPathFlag_SatisfiesRequiredFlagInterface(t *testing.T) {
var f cli.RequiredFlag = &cli.PathFlag{} var f cli.Flag = &cli.PathFlag{}
_ = f.IsRequired() _ = f.IsRequired()
} }
func TestPathFlag_SatisfiesVisibleFlagInterface(t *testing.T) { func TestPathFlag_SatisfiesVisibleFlagInterface(t *testing.T) {
var f cli.VisibleFlag = &cli.PathFlag{} var f cli.Flag = &cli.PathFlag{}
_ = f.IsVisible() _ = f.IsVisible()
} }
@ -124,13 +124,13 @@ func TestStringSliceFlag_SatisfiesFlagInterface(t *testing.T) {
} }
func TestStringSliceFlag_SatisfiesRequiredFlagInterface(t *testing.T) { func TestStringSliceFlag_SatisfiesRequiredFlagInterface(t *testing.T) {
var f cli.RequiredFlag = &cli.StringSliceFlag{} var f cli.Flag = &cli.StringSliceFlag{}
_ = f.IsRequired() _ = f.IsRequired()
} }
func TestStringSliceFlag_SatisfiesVisibleFlagInterface(t *testing.T) { func TestStringSliceFlag_SatisfiesVisibleFlagInterface(t *testing.T) {
var f cli.VisibleFlag = &cli.StringSliceFlag{} var f cli.Flag = &cli.StringSliceFlag{}
_ = f.IsVisible() _ = f.IsVisible()
} }
@ -143,13 +143,13 @@ func TestTimestampFlag_SatisfiesFlagInterface(t *testing.T) {
} }
func TestTimestampFlag_SatisfiesRequiredFlagInterface(t *testing.T) { func TestTimestampFlag_SatisfiesRequiredFlagInterface(t *testing.T) {
var f cli.RequiredFlag = &cli.TimestampFlag{} var f cli.Flag = &cli.TimestampFlag{}
_ = f.IsRequired() _ = f.IsRequired()
} }
func TestTimestampFlag_SatisfiesVisibleFlagInterface(t *testing.T) { func TestTimestampFlag_SatisfiesVisibleFlagInterface(t *testing.T) {
var f cli.VisibleFlag = &cli.TimestampFlag{} var f cli.Flag = &cli.TimestampFlag{}
_ = f.IsVisible() _ = f.IsVisible()
} }
@ -168,13 +168,13 @@ func TestBoolFlag_SatisfiesFlagInterface(t *testing.T) {
} }
func TestBoolFlag_SatisfiesRequiredFlagInterface(t *testing.T) { func TestBoolFlag_SatisfiesRequiredFlagInterface(t *testing.T) {
var f cli.RequiredFlag = &cli.BoolFlag{} var f cli.Flag = &cli.BoolFlag{}
_ = f.IsRequired() _ = f.IsRequired()
} }
func TestBoolFlag_SatisfiesVisibleFlagInterface(t *testing.T) { func TestBoolFlag_SatisfiesVisibleFlagInterface(t *testing.T) {
var f cli.VisibleFlag = &cli.BoolFlag{} var f cli.Flag = &cli.BoolFlag{}
_ = f.IsVisible() _ = f.IsVisible()
} }
@ -193,13 +193,13 @@ func TestFloat64Flag_SatisfiesFlagInterface(t *testing.T) {
} }
func TestFloat64Flag_SatisfiesRequiredFlagInterface(t *testing.T) { func TestFloat64Flag_SatisfiesRequiredFlagInterface(t *testing.T) {
var f cli.RequiredFlag = &cli.Float64Flag{} var f cli.Flag = &cli.Float64Flag{}
_ = f.IsRequired() _ = f.IsRequired()
} }
func TestFloat64Flag_SatisfiesVisibleFlagInterface(t *testing.T) { func TestFloat64Flag_SatisfiesVisibleFlagInterface(t *testing.T) {
var f cli.VisibleFlag = &cli.Float64Flag{} var f cli.Flag = &cli.Float64Flag{}
_ = f.IsVisible() _ = f.IsVisible()
} }
@ -218,13 +218,13 @@ func TestIntFlag_SatisfiesFlagInterface(t *testing.T) {
} }
func TestIntFlag_SatisfiesRequiredFlagInterface(t *testing.T) { func TestIntFlag_SatisfiesRequiredFlagInterface(t *testing.T) {
var f cli.RequiredFlag = &cli.IntFlag{} var f cli.Flag = &cli.IntFlag{}
_ = f.IsRequired() _ = f.IsRequired()
} }
func TestIntFlag_SatisfiesVisibleFlagInterface(t *testing.T) { func TestIntFlag_SatisfiesVisibleFlagInterface(t *testing.T) {
var f cli.VisibleFlag = &cli.IntFlag{} var f cli.Flag = &cli.IntFlag{}
_ = f.IsVisible() _ = f.IsVisible()
} }
@ -243,13 +243,13 @@ func TestInt64Flag_SatisfiesFlagInterface(t *testing.T) {
} }
func TestInt64Flag_SatisfiesRequiredFlagInterface(t *testing.T) { func TestInt64Flag_SatisfiesRequiredFlagInterface(t *testing.T) {
var f cli.RequiredFlag = &cli.Int64Flag{} var f cli.Flag = &cli.Int64Flag{}
_ = f.IsRequired() _ = f.IsRequired()
} }
func TestInt64Flag_SatisfiesVisibleFlagInterface(t *testing.T) { func TestInt64Flag_SatisfiesVisibleFlagInterface(t *testing.T) {
var f cli.VisibleFlag = &cli.Int64Flag{} var f cli.Flag = &cli.Int64Flag{}
_ = f.IsVisible() _ = f.IsVisible()
} }
@ -268,13 +268,13 @@ func TestStringFlag_SatisfiesFlagInterface(t *testing.T) {
} }
func TestStringFlag_SatisfiesRequiredFlagInterface(t *testing.T) { func TestStringFlag_SatisfiesRequiredFlagInterface(t *testing.T) {
var f cli.RequiredFlag = &cli.StringFlag{} var f cli.Flag = &cli.StringFlag{}
_ = f.IsRequired() _ = f.IsRequired()
} }
func TestStringFlag_SatisfiesVisibleFlagInterface(t *testing.T) { func TestStringFlag_SatisfiesVisibleFlagInterface(t *testing.T) {
var f cli.VisibleFlag = &cli.StringFlag{} var f cli.Flag = &cli.StringFlag{}
_ = f.IsVisible() _ = f.IsVisible()
} }
@ -293,13 +293,13 @@ func TestDurationFlag_SatisfiesFlagInterface(t *testing.T) {
} }
func TestDurationFlag_SatisfiesRequiredFlagInterface(t *testing.T) { func TestDurationFlag_SatisfiesRequiredFlagInterface(t *testing.T) {
var f cli.RequiredFlag = &cli.DurationFlag{} var f cli.Flag = &cli.DurationFlag{}
_ = f.IsRequired() _ = f.IsRequired()
} }
func TestDurationFlag_SatisfiesVisibleFlagInterface(t *testing.T) { func TestDurationFlag_SatisfiesVisibleFlagInterface(t *testing.T) {
var f cli.VisibleFlag = &cli.DurationFlag{} var f cli.Flag = &cli.DurationFlag{}
_ = f.IsVisible() _ = f.IsVisible()
} }
@ -318,13 +318,13 @@ func TestUintFlag_SatisfiesFlagInterface(t *testing.T) {
} }
func TestUintFlag_SatisfiesRequiredFlagInterface(t *testing.T) { func TestUintFlag_SatisfiesRequiredFlagInterface(t *testing.T) {
var f cli.RequiredFlag = &cli.UintFlag{} var f cli.Flag = &cli.UintFlag{}
_ = f.IsRequired() _ = f.IsRequired()
} }
func TestUintFlag_SatisfiesVisibleFlagInterface(t *testing.T) { func TestUintFlag_SatisfiesVisibleFlagInterface(t *testing.T) {
var f cli.VisibleFlag = &cli.UintFlag{} var f cli.Flag = &cli.UintFlag{}
_ = f.IsVisible() _ = f.IsVisible()
} }
@ -343,13 +343,13 @@ func TestUint64Flag_SatisfiesFlagInterface(t *testing.T) {
} }
func TestUint64Flag_SatisfiesRequiredFlagInterface(t *testing.T) { func TestUint64Flag_SatisfiesRequiredFlagInterface(t *testing.T) {
var f cli.RequiredFlag = &cli.Uint64Flag{} var f cli.Flag = &cli.Uint64Flag{}
_ = f.IsRequired() _ = f.IsRequired()
} }
func TestUint64Flag_SatisfiesVisibleFlagInterface(t *testing.T) { func TestUint64Flag_SatisfiesVisibleFlagInterface(t *testing.T) {
var f cli.VisibleFlag = &cli.Uint64Flag{} var f cli.Flag = &cli.Uint64Flag{}
_ = f.IsVisible() _ = f.IsVisible()
} }