Skip to content

Commit

Permalink
Merge pull request #1508 from fjl/slice-flag-stringer
Browse files Browse the repository at this point in the history
Call FlagStringer in String() method of slice flags
  • Loading branch information
dearchap committed Oct 6, 2022
2 parents 8335f54 + 5ff1c8d commit 3c5c3a4
Show file tree
Hide file tree
Showing 8 changed files with 97 additions and 119 deletions.
29 changes: 13 additions & 16 deletions flag.go
Expand Up @@ -129,6 +129,14 @@ type DocGenerationFlag interface {
GetEnvVars() []string
}

// DocGenerationSliceFlag extends DocGenerationFlag for slice-based flags.
type DocGenerationSliceFlag interface {
DocGenerationFlag

// IsSliceFlag returns true for flags that can be given multiple times.
IsSliceFlag() bool
}

// VisibleFlag is an interface that allows to check if a flag is visible
type VisibleFlag interface {
Flag
Expand Down Expand Up @@ -325,24 +333,13 @@ func stringifyFlag(f Flag) string {

usageWithDefault := strings.TrimSpace(usage + defaultValueString)

return withEnvHint(df.GetEnvVars(),
fmt.Sprintf("%s\t%s", prefixedNames(df.Names(), placeholder), usageWithDefault))
}

func stringifySliceFlag(usage string, names, defaultVals []string) string {
placeholder, usage := unquoteUsage(usage)
if placeholder == "" {
placeholder = defaultPlaceholder
}

defaultVal := ""
if len(defaultVals) > 0 {
defaultVal = fmt.Sprintf(formatDefault("%s"), strings.Join(defaultVals, ", "))
pn := prefixedNames(df.Names(), placeholder)
sliceFlag, ok := f.(DocGenerationSliceFlag)
if ok && sliceFlag.IsSliceFlag() {
pn = pn + " [ " + pn + " ]"
}

usageWithDefault := strings.TrimSpace(fmt.Sprintf("%s%s", usage, defaultVal))
pn := prefixedNames(names, placeholder)
return fmt.Sprintf("%s [ %s ]\t%s", pn, pn, usageWithDefault)
return withEnvHint(df.GetEnvVars(), fmt.Sprintf("%s\t%s", pn, usageWithDefault))
}

func hasFlag(flags []Flag, fl Flag) bool {
Expand Down
28 changes: 12 additions & 16 deletions flag_float64_slice.go
Expand Up @@ -83,7 +83,7 @@ func (f *Float64Slice) Get() interface{} {
// String returns a readable representation of this value
// (for usage defaults)
func (f *Float64SliceFlag) String() string {
return withEnvHint(f.GetEnvVars(), f.stringify())
return FlagStringer(f)
}

// TakesValue returns true if the flag takes a value, otherwise false
Expand All @@ -104,10 +104,13 @@ func (f *Float64SliceFlag) GetCategory() string {
// 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 {
if f.Value != nil {
return f.Value.String()
var defaultVals []string
if f.Value != nil && len(f.Value.Value()) > 0 {
for _, i := range f.Value.Value() {
defaultVals = append(defaultVals, strings.TrimRight(strings.TrimRight(fmt.Sprintf("%f", i), "0"), "."))
}
}
return ""
return strings.Join(defaultVals, ", ")
}

// GetDefaultText returns the default text for this flag
Expand All @@ -123,6 +126,11 @@ func (f *Float64SliceFlag) GetEnvVars() []string {
return f.EnvVars
}

// IsSliceFlag implements DocGenerationSliceFlag.
func (f *Float64SliceFlag) IsSliceFlag() bool {
return true
}

// Apply populates the flag given the flag set and environment
func (f *Float64SliceFlag) Apply(set *flag.FlagSet) error {
// apply any default
Expand Down Expand Up @@ -169,18 +177,6 @@ func (f *Float64SliceFlag) Get(ctx *Context) []float64 {
return ctx.Float64Slice(f.Name)
}

func (f *Float64SliceFlag) stringify() string {
var defaultVals []string

if f.Value != nil && len(f.Value.Value()) > 0 {
for _, i := range f.Value.Value() {
defaultVals = append(defaultVals, strings.TrimRight(strings.TrimRight(fmt.Sprintf("%f", i), "0"), "."))
}
}

return stringifySliceFlag(f.Usage, f.Names(), defaultVals)
}

// RunAction executes flag action if set
func (f *Float64SliceFlag) RunAction(c *Context) error {
if f.Action != nil {
Expand Down
27 changes: 12 additions & 15 deletions flag_int64_slice.go
Expand Up @@ -84,7 +84,7 @@ func (i *Int64Slice) Get() interface{} {
// String returns a readable representation of this value
// (for usage defaults)
func (f *Int64SliceFlag) String() string {
return withEnvHint(f.GetEnvVars(), f.stringify())
return FlagStringer(f)
}

// TakesValue returns true of the flag takes a value, otherwise false
Expand All @@ -105,10 +105,13 @@ func (f *Int64SliceFlag) GetCategory() string {
// 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 {
if f.Value != nil {
return f.Value.String()
var defaultVals []string
if f.Value != nil && len(f.Value.Value()) > 0 {
for _, i := range f.Value.Value() {
defaultVals = append(defaultVals, strconv.FormatInt(i, 10))
}
}
return ""
return strings.Join(defaultVals, ", ")
}

// GetDefaultText returns the default text for this flag
Expand All @@ -124,6 +127,11 @@ func (f *Int64SliceFlag) GetEnvVars() []string {
return f.EnvVars
}

// IsSliceFlag implements DocGenerationSliceFlag.
func (f *Int64SliceFlag) IsSliceFlag() bool {
return true
}

// Apply populates the flag given the flag set and environment
func (f *Int64SliceFlag) Apply(set *flag.FlagSet) error {
// apply any default
Expand Down Expand Up @@ -168,17 +176,6 @@ func (f *Int64SliceFlag) Get(ctx *Context) []int64 {
return ctx.Int64Slice(f.Name)
}

func (f *Int64SliceFlag) stringify() string {
var defaultVals []string
if f.Value != nil && len(f.Value.Value()) > 0 {
for _, i := range f.Value.Value() {
defaultVals = append(defaultVals, strconv.FormatInt(i, 10))
}
}

return stringifySliceFlag(f.Usage, f.Names(), defaultVals)
}

// RunAction executes flag action if set
func (f *Int64SliceFlag) RunAction(c *Context) error {
if f.Action != nil {
Expand Down
27 changes: 12 additions & 15 deletions flag_int_slice.go
Expand Up @@ -95,7 +95,7 @@ func (i *IntSlice) Get() interface{} {
// String returns a readable representation of this value
// (for usage defaults)
func (f *IntSliceFlag) String() string {
return withEnvHint(f.GetEnvVars(), f.stringify())
return FlagStringer(f)
}

// TakesValue returns true of the flag takes a value, otherwise false
Expand All @@ -116,10 +116,13 @@ func (f *IntSliceFlag) GetCategory() string {
// 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 {
if f.Value != nil {
return f.Value.String()
var defaultVals []string
if f.Value != nil && len(f.Value.Value()) > 0 {
for _, i := range f.Value.Value() {
defaultVals = append(defaultVals, strconv.Itoa(i))
}
}
return ""
return strings.Join(defaultVals, ", ")
}

// GetDefaultText returns the default text for this flag
Expand All @@ -135,6 +138,11 @@ func (f *IntSliceFlag) GetEnvVars() []string {
return f.EnvVars
}

// IsSliceFlag implements DocGenerationSliceFlag.
func (f *IntSliceFlag) IsSliceFlag() bool {
return true
}

// Apply populates the flag given the flag set and environment
func (f *IntSliceFlag) Apply(set *flag.FlagSet) error {
// apply any default
Expand Down Expand Up @@ -188,17 +196,6 @@ func (f *IntSliceFlag) RunAction(c *Context) error {
return nil
}

func (f *IntSliceFlag) stringify() string {
var defaultVals []string
if f.Value != nil && len(f.Value.Value()) > 0 {
for _, i := range f.Value.Value() {
defaultVals = append(defaultVals, strconv.Itoa(i))
}
}

return stringifySliceFlag(f.Usage, f.Names(), defaultVals)
}

// IntSlice looks up the value of a local IntSliceFlag, returns
// nil if not found
func (cCtx *Context) IntSlice(name string) []int {
Expand Down
31 changes: 14 additions & 17 deletions flag_string_slice.go
Expand Up @@ -74,7 +74,7 @@ func (s *StringSlice) Get() interface{} {
// String returns a readable representation of this value
// (for usage defaults)
func (f *StringSliceFlag) String() string {
return withEnvHint(f.GetEnvVars(), f.stringify())
return FlagStringer(f)
}

// TakesValue returns true of the flag takes a value, otherwise false
Expand All @@ -95,10 +95,15 @@ func (f *StringSliceFlag) GetCategory() string {
// 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 {
if f.Value != nil {
return f.Value.String()
var defaultVals []string
if f.Value != nil && len(f.Value.Value()) > 0 {
for _, s := range f.Value.Value() {
if len(s) > 0 {
defaultVals = append(defaultVals, strconv.Quote(s))
}
}
}
return ""
return strings.Join(defaultVals, ", ")
}

// GetDefaultText returns the default text for this flag
Expand All @@ -114,6 +119,11 @@ func (f *StringSliceFlag) GetEnvVars() []string {
return f.EnvVars
}

// IsSliceFlag implements DocGenerationSliceFlag.
func (f *StringSliceFlag) IsSliceFlag() bool {
return true
}

// Apply populates the flag given the flag set and environment
func (f *StringSliceFlag) Apply(set *flag.FlagSet) error {
// apply any default
Expand Down Expand Up @@ -158,19 +168,6 @@ func (f *StringSliceFlag) Get(ctx *Context) []string {
return ctx.StringSlice(f.Name)
}

func (f *StringSliceFlag) stringify() string {
var defaultVals []string
if f.Value != nil && len(f.Value.Value()) > 0 {
for _, s := range f.Value.Value() {
if len(s) > 0 {
defaultVals = append(defaultVals, strconv.Quote(s))
}
}
}

return stringifySliceFlag(f.Usage, f.Names(), defaultVals)
}

// RunAction executes flag action if set
func (f *StringSliceFlag) RunAction(c *Context) error {
if f.Action != nil {
Expand Down
20 changes: 10 additions & 10 deletions flag_test.go
Expand Up @@ -307,12 +307,12 @@ func TestFlagStringifying(t *testing.T) {
{
name: "float64-slice-flag",
fl: &Float64SliceFlag{Name: "pizzas"},
expected: "--pizzas value\t",
expected: "--pizzas value [ --pizzas value ]\t",
},
{
name: "float64-slice-flag-with-default-text",
fl: &Float64SliceFlag{Name: "pepperonis", DefaultText: "shaved"},
expected: "--pepperonis value\t(default: shaved)",
expected: "--pepperonis value [ --pepperonis value ]\t(default: shaved)",
},
{
name: "generic-flag",
Expand All @@ -337,7 +337,7 @@ func TestFlagStringifying(t *testing.T) {
{
name: "int-slice-flag",
fl: &IntSliceFlag{Name: "pencils"},
expected: "--pencils value\t",
expected: "--pencils value [ --pencils value ]\t",
},
{
name: "int-slice-flag-with-default-text",
Expand All @@ -347,7 +347,7 @@ func TestFlagStringifying(t *testing.T) {
{
name: "uint-slice-flag",
fl: &UintSliceFlag{Name: "pencils"},
expected: "--pencils value\t",
expected: "--pencils value [ --pencils value ]\t",
},
{
name: "uint-slice-flag-with-default-text",
Expand All @@ -367,22 +367,22 @@ func TestFlagStringifying(t *testing.T) {
{
name: "int64-slice-flag",
fl: &Int64SliceFlag{Name: "drawers"},
expected: "--drawers value\t",
expected: "--drawers value [ --drawers value ]\t",
},
{
name: "int64-slice-flag-with-default-text",
fl: &Int64SliceFlag{Name: "handles", DefaultText: "-2"},
expected: "--handles value\t(default: -2)",
expected: "--handles value [ --handles value ]\t(default: -2)",
},
{
name: "uint64-slice-flag",
fl: &Uint64SliceFlag{Name: "drawers"},
expected: "--drawers value\t",
expected: "--drawers value [ --drawers value ]\t",
},
{
name: "uint64-slice-flag-with-default-text",
fl: &Uint64SliceFlag{Name: "handles", DefaultText: "-2"},
expected: "--handles value\t(default: -2)",
expected: "--handles value [ --handles value ]\t(default: -2)",
},
{
name: "path-flag",
Expand All @@ -407,12 +407,12 @@ func TestFlagStringifying(t *testing.T) {
{
name: "string-slice-flag",
fl: &StringSliceFlag{Name: "meow-sounds"},
expected: "--meow-sounds value\t",
expected: "--meow-sounds value [ --meow-sounds value ]\t",
},
{
name: "string-slice-flag-with-default-text",
fl: &StringSliceFlag{Name: "moo-sounds", DefaultText: "awoo"},
expected: "--moo-sounds value\t(default: awoo)",
expected: "--moo-sounds value [ --moo-sounds value ]\t(default: awoo)",
},
{
name: "timestamp-flag",
Expand Down

0 comments on commit 3c5c3a4

Please sign in to comment.