From 1a31a6e2fce716fd377c220c0a1e8f0de6324272 Mon Sep 17 00:00:00 2001 From: Naveen Gogineni Date: Sat, 8 Oct 2022 09:47:46 -0500 Subject: [PATCH] Revert "Remove all flag interfaces" This reverts commit 268cb973f8f7b1f38999f43122fb3e39b90b0522. --- app.go | 10 +- app_test.go | 4 - category.go | 18 ++-- cmd/urfave-cli-genflags/generated.gotmpl | 10 -- cmd/urfave-cli-genflags/generated_test.gotmpl | 4 +- command.go | 4 +- context.go | 2 +- docs.go | 8 +- fish.go | 9 +- flag.go | 72 ++++++++++---- flag_duration.go | 8 ++ flag_float64.go | 8 ++ flag_float64_slice.go | 8 ++ flag_generic.go | 8 ++ flag_int.go | 8 ++ flag_int64.go | 8 ++ flag_int64_slice.go | 8 ++ flag_int_slice.go | 8 ++ flag_string_slice.go | 8 ++ flag_test.go | 16 +++- flag_timestamp.go | 8 ++ flag_uint.go | 8 ++ flag_uint64.go | 8 ++ godoc-current.txt | 91 ++++++++++++------ sliceflag.go | 27 +++--- zz_generated.flags.go | 96 ------------------- zz_generated.flags_test.go | 60 ++++++------ 27 files changed, 306 insertions(+), 221 deletions(-) diff --git a/app.go b/app.go index 7be6f76..9f72f1b 100644 --- a/app.go +++ b/app.go @@ -228,7 +228,9 @@ func (a *App) Setup() { a.flagCategories = newFlagCategories() for _, fl := range a.Flags { - a.flagCategories.AddFlag(fl.GetCategory(), fl) + if cf, ok := fl.(CategorizableFlag); ok { + a.flagCategories.AddFlag(cf.GetCategory(), cf) + } } if a.Metadata == nil { @@ -662,8 +664,10 @@ func runFlagActions(c *Context, fs []Flag) error { } } if isSet { - if err := f.RunAction(c); err != nil { - return err + if af, ok := f.(ActionableFlag); ok { + if err := af.RunAction(c); err != nil { + return err + } } } } diff --git a/app_test.go b/app_test.go index 1428c39..dbe7a46 100644 --- a/app_test.go +++ b/app_test.go @@ -2386,10 +2386,6 @@ 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/category.go b/category.go index 188937d..8bf325e 100644 --- a/category.go +++ b/category.go @@ -101,7 +101,9 @@ func newFlagCategories() FlagCategories { func newFlagCategoriesFromFlags(fs []Flag) FlagCategories { fc := newFlagCategories() for _, fl := range fs { - fc.AddFlag(fl.GetCategory(), fl) + if cf, ok := fl.(CategorizableFlag); ok { + fc.AddFlag(cf.GetCategory(), cf) + } } return fc @@ -136,7 +138,7 @@ type VisibleFlagCategory interface { // Name returns the category name string Name() string // Flags returns a slice of VisibleFlag sorted by name - Flags() []Flag + Flags() []VisibleFlag } type defaultVisibleFlagCategory struct { @@ -148,19 +150,21 @@ func (fc *defaultVisibleFlagCategory) Name() string { return fc.name } -func (fc *defaultVisibleFlagCategory) Flags() []Flag { +func (fc *defaultVisibleFlagCategory) Flags() []VisibleFlag { vfNames := []string{} for flName, fl := range fc.m { - if fl.IsVisible() { - vfNames = append(vfNames, flName) + if vf, ok := fl.(VisibleFlag); ok { + if vf.IsVisible() { + vfNames = append(vfNames, flName) + } } } sort.Strings(vfNames) - ret := make([]Flag, len(vfNames)) + ret := make([]VisibleFlag, len(vfNames)) for i, flName := range vfNames { - ret[i] = fc.m[flName] + ret[i] = fc.m[flName].(VisibleFlag) } return ret diff --git a/cmd/urfave-cli-genflags/generated.gotmpl b/cmd/urfave-cli-genflags/generated.gotmpl index 85bd66f..bee11d5 100644 --- a/cmd/urfave-cli-genflags/generated.gotmpl +++ b/cmd/urfave-cli-genflags/generated.gotmpl @@ -75,16 +75,6 @@ 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 */}} diff --git a/cmd/urfave-cli-genflags/generated_test.gotmpl b/cmd/urfave-cli-genflags/generated_test.gotmpl index c91f562..83229b0 100644 --- a/cmd/urfave-cli-genflags/generated_test.gotmpl +++ b/cmd/urfave-cli-genflags/generated_test.gotmpl @@ -12,13 +12,13 @@ func Test{{.TypeName}}_SatisfiesFlagInterface(t *testing.T) { } func Test{{.TypeName}}_SatisfiesRequiredFlagInterface(t *testing.T) { - var f {{$.UrfaveCLITestNamespace}}Flag = &{{$.UrfaveCLITestNamespace}}{{.TypeName}}{} + var f {{$.UrfaveCLITestNamespace}}RequiredFlag = &{{$.UrfaveCLITestNamespace}}{{.TypeName}}{} _ = f.IsRequired() } func Test{{.TypeName}}_SatisfiesVisibleFlagInterface(t *testing.T) { - var f {{$.UrfaveCLITestNamespace}}Flag = &{{$.UrfaveCLITestNamespace}}{{.TypeName}}{} + var f {{$.UrfaveCLITestNamespace}}VisibleFlag = &{{$.UrfaveCLITestNamespace}}{{.TypeName}}{} _ = f.IsVisible() } diff --git a/command.go b/command.go index decfb73..de78faa 100644 --- a/command.go +++ b/command.go @@ -300,7 +300,9 @@ func (c *Command) VisibleFlagCategories() []VisibleFlagCategory { if c.flagCategories == nil { c.flagCategories = newFlagCategories() for _, fl := range c.Flags { - c.flagCategories.AddFlag(fl.GetCategory(), fl) + if cf, ok := fl.(CategorizableFlag); ok { + c.flagCategories.AddFlag(cf.GetCategory(), fl) + } } } return c.flagCategories.VisibleCategories() diff --git a/context.go b/context.go index 81416da..315c2fb 100644 --- a/context.go +++ b/context.go @@ -180,7 +180,7 @@ func (cCtx *Context) lookupFlagSet(name string) *flag.FlagSet { func (cCtx *Context) checkRequiredFlags(flags []Flag) requiredFlagsErr { var missingFlags []string for _, f := range flags { - if f.IsRequired() { + if rf, ok := f.(RequiredFlag); ok && rf.IsRequired() { var flagPresent bool var flagName string diff --git a/docs.go b/docs.go index 5a8be0a..8b1c9c8 100644 --- a/docs.go +++ b/docs.go @@ -116,7 +116,11 @@ func prepareFlags( addDetails bool, ) []string { args := []string{} - for _, flag := range flags { + for _, f := range flags { + flag, ok := f.(DocGenerationFlag) + if !ok { + continue + } modifiedArg := opener for _, s := range flag.Names() { @@ -147,7 +151,7 @@ func prepareFlags( } // flagDetails returns a string containing the flags metadata -func flagDetails(flag Flag) string { +func flagDetails(flag DocGenerationFlag) string { description := flag.GetUsage() value := flag.GetValue() if value != "" { diff --git a/fish.go b/fish.go index 70946e1..eec3253 100644 --- a/fish.go +++ b/fish.go @@ -114,7 +114,12 @@ func (a *App) prepareFishCommands(commands []*Command, allCommands *[]string, pr func (a *App) prepareFishFlags(flags []Flag, previousCommands []string) []string { completions := []string{} - for _, flag := range flags { + for _, f := range flags { + flag, ok := f.(DocGenerationFlag) + if !ok { + continue + } + completion := &strings.Builder{} completion.WriteString(fmt.Sprintf( "complete -c %s -n '%s'", @@ -122,7 +127,7 @@ func (a *App) prepareFishFlags(flags []Flag, previousCommands []string) []string a.fishSubcommandHelper(previousCommands), )) - fishAddFileFlag(flag, completion) + fishAddFileFlag(f, completion) for idx, opt := range flag.Names() { if idx == 0 { diff --git a/flag.go b/flag.go index aade1de..68d882c 100644 --- a/flag.go +++ b/flag.go @@ -83,6 +83,12 @@ func (f FlagsByName) Swap(i, j int) { f[i], f[j] = f[j], f[i] } +// ActionableFlag is an interface that wraps Flag interface and RunAction operation. +type ActionableFlag interface { + Flag + RunAction(*Context) error +} + // Flag is a common interface related to parsing flags in cli. // For more advanced flag parsing techniques, it is recommended that // this interface be implemented. @@ -97,33 +103,36 @@ type Flag interface { // Whether the flag has been set or not 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 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 +// 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() bool - // GetDefaultText returns the default text for this flag - GetDefaultText() 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 - RunAction(*Context) error + // GetDefaultText returns the default text for this flag + GetDefaultText() string + + // GetEnvVars returns the env vars for this flag + GetEnvVars() []string } // Countable is an interface to enable detection of flag values which support @@ -132,6 +141,23 @@ type Countable interface { Count() int } +// 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 +} + +// CategorizableFlag is an interface that allows us to potentially +// use a flag in a categorized representation. +type CategorizableFlag interface { + VisibleFlag + + // Returns the category of the flag + GetCategory() string +} + func flagSet(name string, flags []Flag) (*flag.FlagSet, error) { set := flag.NewFlagSet(name, flag.ContinueOnError) @@ -189,7 +215,7 @@ func normalizeFlags(flags []Flag, set *flag.FlagSet) error { func visibleFlags(fl []Flag) []Flag { var visible []Flag for _, f := range fl { - if f.IsVisible() { + if vf, ok := f.(VisibleFlag); ok && vf.IsVisible() { visible = append(visible, f) } } @@ -285,8 +311,14 @@ func formatDefault(format string) string { } func stringifyFlag(f Flag) string { - placeholder, usage := unquoteUsage(f.GetUsage()) - needsPlaceholder := f.TakesValue() + // enforce DocGeneration interface on flags to avoid reflection + df, ok := f.(DocGenerationFlag) + if !ok { + return "" + } + + placeholder, usage := unquoteUsage(df.GetUsage()) + needsPlaceholder := df.TakesValue() if needsPlaceholder && placeholder == "" { placeholder = defaultPlaceholder @@ -294,14 +326,14 @@ func stringifyFlag(f Flag) string { defaultValueString := "" - if s := f.GetDefaultText(); s != "" { + if s := df.GetDefaultText(); s != "" { defaultValueString = fmt.Sprintf(formatDefault("%s"), s) } usageWithDefault := strings.TrimSpace(usage + defaultValueString) - return withEnvHint(f.GetEnvVars(), - fmt.Sprintf("%s\t%s", prefixedNames(f.Names(), placeholder), usageWithDefault)) + return withEnvHint(df.GetEnvVars(), + fmt.Sprintf("%s\t%s", prefixedNames(df.Names(), placeholder), usageWithDefault)) } func stringifySliceFlag(usage string, names, defaultVals []string) string { diff --git a/flag_duration.go b/flag_duration.go index b6adce3..06391f3 100644 --- a/flag_duration.go +++ b/flag_duration.go @@ -12,6 +12,14 @@ 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() +} + // 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 3e21a01..d522ac0 100644 --- a/flag_float64.go +++ b/flag_float64.go @@ -12,6 +12,14 @@ 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() +} + // 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 5bb2693..203aa42 100644 --- a/flag_float64_slice.go +++ b/flag_float64_slice.go @@ -95,6 +95,14 @@ 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() +} + // 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 9f06338..183a588 100644 --- a/flag_generic.go +++ b/flag_generic.go @@ -20,6 +20,14 @@ 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() +} + // 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 bcaab7f..a716f39 100644 --- a/flag_int.go +++ b/flag_int.go @@ -12,6 +12,14 @@ 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() +} + // 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 d8e591d..05d8506 100644 --- a/flag_int64.go +++ b/flag_int64.go @@ -12,6 +12,14 @@ 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() +} + // 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 89fd445..e3575cd 100644 --- a/flag_int64_slice.go +++ b/flag_int64_slice.go @@ -96,6 +96,14 @@ 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() +} + // 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 f7a6b06..5c1b6b6 100644 --- a/flag_int_slice.go +++ b/flag_int_slice.go @@ -107,6 +107,14 @@ 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() +} + // 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_string_slice.go b/flag_string_slice.go index 2a24ec5..086b18d 100644 --- a/flag_string_slice.go +++ b/flag_string_slice.go @@ -86,6 +86,14 @@ 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() +} + // 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_test.go b/flag_test.go index e7fa309..ddd3e67 100644 --- a/flag_test.go +++ b/flag_test.go @@ -223,7 +223,10 @@ func TestFlagsFromEnv(t *testing.T) { defer resetEnv(os.Environ()) os.Clearenv() - f := test.flag + f, ok := test.flag.(DocGenerationFlag) + if !ok { + t.Errorf("flag %v needs to implement DocGenerationFlag to retrieve env vars", test.flag) + } envVarSlice := f.GetEnvVars() _ = os.Setenv(envVarSlice[0], test.input) @@ -259,6 +262,12 @@ func TestFlagsFromEnv(t *testing.T) { } } +type nodocFlag struct { + Flag + + Name string +} + func TestFlagStringifying(t *testing.T) { for _, tc := range []struct { name string @@ -435,6 +444,11 @@ 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/flag_timestamp.go b/flag_timestamp.go index 671be8b..4302f13 100644 --- a/flag_timestamp.go +++ b/flag_timestamp.go @@ -81,6 +81,14 @@ 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() +} + // 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 e1b0450..2214386 100644 --- a/flag_uint.go +++ b/flag_uint.go @@ -37,6 +37,14 @@ 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() +} + // 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 593b260..e314a4a 100644 --- a/flag_uint64.go +++ b/flag_uint64.go @@ -37,6 +37,14 @@ 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() +} + // 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 2c8b5e0..03b76f8 100644 --- a/godoc-current.txt +++ b/godoc-current.txt @@ -247,6 +247,13 @@ TYPES type ActionFunc func(*Context) error ActionFunc is the action to execute when no subcommands are specified +type ActionableFlag interface { + Flag + RunAction(*Context) error +} + ActionableFlag is an interface that wraps Flag interface and RunAction + operation. + type AfterFunc func(*Context) error AfterFunc is an action to execute after any subcommands are run, but after the subcommand has finished it is run even if Action() panics @@ -499,6 +506,15 @@ func (f *BoolFlag) String() string func (f *BoolFlag) TakesValue() bool TakesValue returns true if the flag takes a value, otherwise false +type CategorizableFlag interface { + VisibleFlag + + // Returns the category of the flag + GetCategory() string +} + CategorizableFlag is an interface that allows us to potentially use a flag + in a categorized representation. + type Command struct { // The name of the command Name string @@ -716,6 +732,28 @@ type Countable interface { Countable is an interface to enable detection of flag values which support repetitive flags +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 @@ -823,33 +861,6 @@ type Flag interface { // 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 - - RunAction(*Context) error } Flag is a common interface related to parsing flags in cli. For more advanced flag parsing techniques, it is recommended that this interface be @@ -1586,6 +1597,16 @@ func (f *PathFlag) String() string func (f *PathFlag) TakesValue() bool TakesValue returns true if the flag takes a value, otherwise false +type RequiredFlag interface { + Flag + + // whether the flag is a required flag or not + 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 + type Serializer interface { Serialize() string } @@ -1623,8 +1644,6 @@ func (x *SliceFlag[T, S, E]) IsVisible() bool func (x *SliceFlag[T, S, E]) Names() []string -func (x *SliceFlag[T, S, E]) RunAction(c *Context) error - func (x *SliceFlag[T, S, E]) SetDestination(slice S) func (x *SliceFlag[T, S, E]) SetValue(slice S) @@ -1635,6 +1654,10 @@ 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). @@ -2229,11 +2252,19 @@ func (f *UintSliceFlag) String() string func (f *UintSliceFlag) 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 + type VisibleFlagCategory interface { // Name returns the category name string Name() string // Flags returns a slice of VisibleFlag sorted by name - Flags() []Flag + Flags() []VisibleFlag } VisibleFlagCategory is a category containing flags. diff --git a/sliceflag.go b/sliceflag.go index c8670cb..b2ca590 100644 --- a/sliceflag.go +++ b/sliceflag.go @@ -21,6 +21,10 @@ 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). @@ -110,18 +114,17 @@ func (x *SliceFlag[T, S, E]) GetDestination() S { return nil } -func (x *SliceFlag[T, S, E]) String() string { return x.Target.String() } -func (x *SliceFlag[T, S, E]) Names() []string { return x.Target.Names() } -func (x *SliceFlag[T, S, E]) IsSet() bool { return x.Target.IsSet() } -func (x *SliceFlag[T, S, E]) IsRequired() bool { return x.Target.IsRequired() } -func (x *SliceFlag[T, S, E]) TakesValue() bool { return x.Target.TakesValue() } -func (x *SliceFlag[T, S, E]) GetUsage() string { return x.Target.GetUsage() } -func (x *SliceFlag[T, S, E]) GetValue() string { return x.Target.GetValue() } -func (x *SliceFlag[T, S, E]) GetDefaultText() string { return x.Target.GetDefaultText() } -func (x *SliceFlag[T, S, E]) GetEnvVars() []string { return x.Target.GetEnvVars() } -func (x *SliceFlag[T, S, E]) IsVisible() bool { return x.Target.IsVisible() } -func (x *SliceFlag[T, S, E]) GetCategory() string { return x.Target.GetCategory() } -func (x *SliceFlag[T, S, E]) RunAction(c *Context) error { return x.Target.RunAction(c) } +func (x *SliceFlag[T, S, E]) String() string { return x.Target.String() } +func (x *SliceFlag[T, S, E]) Names() []string { return x.Target.Names() } +func (x *SliceFlag[T, S, E]) IsSet() bool { return x.Target.IsSet() } +func (x *SliceFlag[T, S, E]) IsRequired() bool { return x.Target.IsRequired() } +func (x *SliceFlag[T, S, E]) TakesValue() bool { return x.Target.TakesValue() } +func (x *SliceFlag[T, S, E]) GetUsage() string { return x.Target.GetUsage() } +func (x *SliceFlag[T, S, E]) GetValue() string { return x.Target.GetValue() } +func (x *SliceFlag[T, S, E]) GetDefaultText() string { return x.Target.GetDefaultText() } +func (x *SliceFlag[T, S, E]) GetEnvVars() []string { return x.Target.GetEnvVars() } +func (x *SliceFlag[T, S, E]) IsVisible() bool { return x.Target.IsVisible() } +func (x *SliceFlag[T, S, E]) GetCategory() string { return x.Target.GetCategory() } func (x *flagValueHook) Set(value string) error { if err := x.value.Set(value); err != nil { diff --git a/zz_generated.flags.go b/zz_generated.flags.go index 68934c7..d2e1cde 100644 --- a/zz_generated.flags.go +++ b/zz_generated.flags.go @@ -66,14 +66,6 @@ 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 @@ -143,14 +135,6 @@ 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 @@ -213,14 +197,6 @@ 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 @@ -283,14 +259,6 @@ 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 @@ -424,14 +392,6 @@ 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 @@ -503,14 +463,6 @@ 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() -} - // Uint64SliceFlag is a flag with type *Uint64Slice type Uint64SliceFlag struct { Name string @@ -731,14 +683,6 @@ 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 @@ -808,14 +752,6 @@ 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 @@ -885,14 +821,6 @@ 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 @@ -1029,14 +957,6 @@ 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 @@ -1106,14 +1026,6 @@ 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 @@ -1183,12 +1095,4 @@ 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 diff --git a/zz_generated.flags_test.go b/zz_generated.flags_test.go index be6dadf..6862afc 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.Flag = &cli.Float64SliceFlag{} + var f cli.RequiredFlag = &cli.Float64SliceFlag{} _ = f.IsRequired() } func TestFloat64SliceFlag_SatisfiesVisibleFlagInterface(t *testing.T) { - var f cli.Flag = &cli.Float64SliceFlag{} + var f cli.VisibleFlag = &cli.Float64SliceFlag{} _ = f.IsVisible() } @@ -36,13 +36,13 @@ func TestGenericFlag_SatisfiesFlagInterface(t *testing.T) { } func TestGenericFlag_SatisfiesRequiredFlagInterface(t *testing.T) { - var f cli.Flag = &cli.GenericFlag{} + var f cli.RequiredFlag = &cli.GenericFlag{} _ = f.IsRequired() } func TestGenericFlag_SatisfiesVisibleFlagInterface(t *testing.T) { - var f cli.Flag = &cli.GenericFlag{} + var f cli.VisibleFlag = &cli.GenericFlag{} _ = f.IsVisible() } @@ -61,13 +61,13 @@ func TestInt64SliceFlag_SatisfiesFlagInterface(t *testing.T) { } func TestInt64SliceFlag_SatisfiesRequiredFlagInterface(t *testing.T) { - var f cli.Flag = &cli.Int64SliceFlag{} + var f cli.RequiredFlag = &cli.Int64SliceFlag{} _ = f.IsRequired() } func TestInt64SliceFlag_SatisfiesVisibleFlagInterface(t *testing.T) { - var f cli.Flag = &cli.Int64SliceFlag{} + var f cli.VisibleFlag = &cli.Int64SliceFlag{} _ = f.IsVisible() } @@ -80,13 +80,13 @@ func TestIntSliceFlag_SatisfiesFlagInterface(t *testing.T) { } func TestIntSliceFlag_SatisfiesRequiredFlagInterface(t *testing.T) { - var f cli.Flag = &cli.IntSliceFlag{} + var f cli.RequiredFlag = &cli.IntSliceFlag{} _ = f.IsRequired() } func TestIntSliceFlag_SatisfiesVisibleFlagInterface(t *testing.T) { - var f cli.Flag = &cli.IntSliceFlag{} + var f cli.VisibleFlag = &cli.IntSliceFlag{} _ = f.IsVisible() } @@ -99,13 +99,13 @@ func TestPathFlag_SatisfiesFlagInterface(t *testing.T) { } func TestPathFlag_SatisfiesRequiredFlagInterface(t *testing.T) { - var f cli.Flag = &cli.PathFlag{} + var f cli.RequiredFlag = &cli.PathFlag{} _ = f.IsRequired() } func TestPathFlag_SatisfiesVisibleFlagInterface(t *testing.T) { - var f cli.Flag = &cli.PathFlag{} + var f cli.VisibleFlag = &cli.PathFlag{} _ = f.IsVisible() } @@ -124,13 +124,13 @@ func TestStringSliceFlag_SatisfiesFlagInterface(t *testing.T) { } func TestStringSliceFlag_SatisfiesRequiredFlagInterface(t *testing.T) { - var f cli.Flag = &cli.StringSliceFlag{} + var f cli.RequiredFlag = &cli.StringSliceFlag{} _ = f.IsRequired() } func TestStringSliceFlag_SatisfiesVisibleFlagInterface(t *testing.T) { - var f cli.Flag = &cli.StringSliceFlag{} + var f cli.VisibleFlag = &cli.StringSliceFlag{} _ = f.IsVisible() } @@ -143,13 +143,13 @@ func TestTimestampFlag_SatisfiesFlagInterface(t *testing.T) { } func TestTimestampFlag_SatisfiesRequiredFlagInterface(t *testing.T) { - var f cli.Flag = &cli.TimestampFlag{} + var f cli.RequiredFlag = &cli.TimestampFlag{} _ = f.IsRequired() } func TestTimestampFlag_SatisfiesVisibleFlagInterface(t *testing.T) { - var f cli.Flag = &cli.TimestampFlag{} + var f cli.VisibleFlag = &cli.TimestampFlag{} _ = f.IsVisible() } @@ -182,13 +182,13 @@ func TestBoolFlag_SatisfiesFlagInterface(t *testing.T) { } func TestBoolFlag_SatisfiesRequiredFlagInterface(t *testing.T) { - var f cli.Flag = &cli.BoolFlag{} + var f cli.RequiredFlag = &cli.BoolFlag{} _ = f.IsRequired() } func TestBoolFlag_SatisfiesVisibleFlagInterface(t *testing.T) { - var f cli.Flag = &cli.BoolFlag{} + var f cli.VisibleFlag = &cli.BoolFlag{} _ = f.IsVisible() } @@ -207,13 +207,13 @@ func TestFloat64Flag_SatisfiesFlagInterface(t *testing.T) { } func TestFloat64Flag_SatisfiesRequiredFlagInterface(t *testing.T) { - var f cli.Flag = &cli.Float64Flag{} + var f cli.RequiredFlag = &cli.Float64Flag{} _ = f.IsRequired() } func TestFloat64Flag_SatisfiesVisibleFlagInterface(t *testing.T) { - var f cli.Flag = &cli.Float64Flag{} + var f cli.VisibleFlag = &cli.Float64Flag{} _ = f.IsVisible() } @@ -232,13 +232,13 @@ func TestIntFlag_SatisfiesFlagInterface(t *testing.T) { } func TestIntFlag_SatisfiesRequiredFlagInterface(t *testing.T) { - var f cli.Flag = &cli.IntFlag{} + var f cli.RequiredFlag = &cli.IntFlag{} _ = f.IsRequired() } func TestIntFlag_SatisfiesVisibleFlagInterface(t *testing.T) { - var f cli.Flag = &cli.IntFlag{} + var f cli.VisibleFlag = &cli.IntFlag{} _ = f.IsVisible() } @@ -257,13 +257,13 @@ func TestInt64Flag_SatisfiesFlagInterface(t *testing.T) { } func TestInt64Flag_SatisfiesRequiredFlagInterface(t *testing.T) { - var f cli.Flag = &cli.Int64Flag{} + var f cli.RequiredFlag = &cli.Int64Flag{} _ = f.IsRequired() } func TestInt64Flag_SatisfiesVisibleFlagInterface(t *testing.T) { - var f cli.Flag = &cli.Int64Flag{} + var f cli.VisibleFlag = &cli.Int64Flag{} _ = f.IsVisible() } @@ -282,13 +282,13 @@ func TestStringFlag_SatisfiesFlagInterface(t *testing.T) { } func TestStringFlag_SatisfiesRequiredFlagInterface(t *testing.T) { - var f cli.Flag = &cli.StringFlag{} + var f cli.RequiredFlag = &cli.StringFlag{} _ = f.IsRequired() } func TestStringFlag_SatisfiesVisibleFlagInterface(t *testing.T) { - var f cli.Flag = &cli.StringFlag{} + var f cli.VisibleFlag = &cli.StringFlag{} _ = f.IsVisible() } @@ -307,13 +307,13 @@ func TestDurationFlag_SatisfiesFlagInterface(t *testing.T) { } func TestDurationFlag_SatisfiesRequiredFlagInterface(t *testing.T) { - var f cli.Flag = &cli.DurationFlag{} + var f cli.RequiredFlag = &cli.DurationFlag{} _ = f.IsRequired() } func TestDurationFlag_SatisfiesVisibleFlagInterface(t *testing.T) { - var f cli.Flag = &cli.DurationFlag{} + var f cli.VisibleFlag = &cli.DurationFlag{} _ = f.IsVisible() } @@ -332,13 +332,13 @@ func TestUintFlag_SatisfiesFlagInterface(t *testing.T) { } func TestUintFlag_SatisfiesRequiredFlagInterface(t *testing.T) { - var f cli.Flag = &cli.UintFlag{} + var f cli.RequiredFlag = &cli.UintFlag{} _ = f.IsRequired() } func TestUintFlag_SatisfiesVisibleFlagInterface(t *testing.T) { - var f cli.Flag = &cli.UintFlag{} + var f cli.VisibleFlag = &cli.UintFlag{} _ = f.IsVisible() } @@ -357,13 +357,13 @@ func TestUint64Flag_SatisfiesFlagInterface(t *testing.T) { } func TestUint64Flag_SatisfiesRequiredFlagInterface(t *testing.T) { - var f cli.Flag = &cli.Uint64Flag{} + var f cli.RequiredFlag = &cli.Uint64Flag{} _ = f.IsRequired() } func TestUint64Flag_SatisfiesVisibleFlagInterface(t *testing.T) { - var f cli.Flag = &cli.Uint64Flag{} + var f cli.VisibleFlag = &cli.Uint64Flag{} _ = f.IsVisible() }