Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Call FlagStringer in String() method of slice flags #1508

Merged
merged 2 commits into from Oct 6, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
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