Skip to content

Commit

Permalink
Add hashmap type show. And fix some print
Browse files Browse the repository at this point in the history
If flag is StringMapFlag ,it will print
`--property string=string [--property string=string]…`

Signed-off-by: jokemanfire <[email protected]>
  • Loading branch information
jokemanfire committed Jan 15, 2025
1 parent 3043a47 commit 0baf377
Show file tree
Hide file tree
Showing 6 changed files with 112 additions and 96 deletions.
11 changes: 4 additions & 7 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 @@ -180,11 +182,6 @@ type LocalFlag interface {
IsLocal() bool
}

// FlagType is an interface to detect if a flag is a string, bool, etc.
type FlagType interface {
GetFlagType() string
}

func newFlagSet(name string, flags []Flag) (*flag.FlagSet, error) {
set := flag.NewFlagSet(name, flag.ContinueOnError)

Expand Down Expand Up @@ -312,8 +309,8 @@ func stringifyFlag(f Flag) string {
// if needsPlaceholder is true, placeholder is empty
if needsPlaceholder && placeholder == "" {
// try to get type from flag
if v1, ok := f.(FlagType); ok && v1.GetFlagType() != "" {
placeholder = v1.GetFlagType()
if tname := df.TypeName(); tname != "" {
placeholder = tname
} else {
placeholder = defaultPlaceholder
}
Expand Down
33 changes: 28 additions & 5 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,18 +99,40 @@ func (f *FlagBase[T, C, V]) GetValue() string {
return fmt.Sprintf("%v", f.Value)
}

// GetFlagType returns the type of the flag.
func (f *FlagBase[T, C, V]) GetFlagType() string {
// 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?
if ty.Kind() == reflect.Slice {
case reflect.Slice:
elemType := ty.Elem()
return elemType.Name()
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())
}
return ty.Name()
}

// Apply populates the flag given the flag set and environment
Expand Down
Loading

0 comments on commit 0baf377

Please sign in to comment.