Skip to content

Commit

Permalink
Merge pull request #2043 from jokemanfire/dev2
Browse files Browse the repository at this point in the history
while print flag , the placeholder if need but not set.
  • Loading branch information
dearchap authored Feb 8, 2025
2 parents 8e49873 + 2b084ed commit e815209
Show file tree
Hide file tree
Showing 7 changed files with 148 additions and 94 deletions.
2 changes: 1 addition & 1 deletion examples_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ func ExampleCommand_Run_appHelp() {
// help, h Shows a list of commands or help for one command
//
// GLOBAL OPTIONS:
// --name value a name to say (default: "bob")
// --name string a name to say (default: "bob")
// --help, -h show help
// --version, -v print the version
}
Expand Down
11 changes: 9 additions & 2 deletions flag.go
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,8 @@ type DocGenerationFlag interface {
// IsDefaultVisible returns whether the default value should be shown in
// help text
IsDefaultVisible() bool
// TypeName to detect if a flag is a string, bool, etc.
TypeName() string
}

// DocGenerationMultiValueFlag extends DocGenerationFlag for slice/map based flags.
Expand Down Expand Up @@ -304,9 +306,14 @@ func stringifyFlag(f Flag) string {
}
placeholder, usage := unquoteUsage(df.GetUsage())
needsPlaceholder := df.TakesValue()

// if needsPlaceholder is true, placeholder is empty
if needsPlaceholder && placeholder == "" {
placeholder = defaultPlaceholder
// try to get type from flag
if tname := df.TypeName(); tname != "" {
placeholder = tname
} else {
placeholder = defaultPlaceholder
}
}

defaultValueString := ""
Expand Down
37 changes: 37 additions & 0 deletions flag_impl.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"flag"
"fmt"
"reflect"
"strings"
)

// Value represents a value as used by cli.
Expand Down Expand Up @@ -98,6 +99,42 @@ func (f *FlagBase[T, C, V]) GetValue() string {
return fmt.Sprintf("%v", f.Value)
}

// TypeName returns the type of the flag.
func (f *FlagBase[T, C, V]) TypeName() string {
ty := reflect.TypeOf(f.Value)
if ty == nil {
return ""
}
// convert the typename to generic type
convertToGenericType := func(name string) string {
prefixMap := map[string]string{
"float": "float",
"int": "int",
"uint": "uint",
}
for prefix, genericType := range prefixMap {
if strings.HasPrefix(name, prefix) {
return genericType
}
}
return strings.ToLower(name)
}

switch ty.Kind() {
// if it is a Slice, then return the slice's inner type. Will nested slices be used in the future?
case reflect.Slice:
elemType := ty.Elem()
return convertToGenericType(elemType.Name())
// if it is a Map, then return the map's key and value types.
case reflect.Map:
keyType := ty.Key()
valueType := ty.Elem()
return fmt.Sprintf("%s=%s", convertToGenericType(keyType.Name()), convertToGenericType(valueType.Name()))
default:
return convertToGenericType(ty.Name())
}
}

// Apply populates the flag given the flag set and environment
func (f *FlagBase[T, C, V]) Apply(set *flag.FlagSet) error {
tracef("apply (flag=%[1]q)", f.Name)
Expand Down
Loading

0 comments on commit e815209

Please sign in to comment.