Add DestinationPointer for flags generator
In this commit I added a DestinationPointer variable that should be set if the `Destination` should be configured as a pointer for a specific flag type. It is expected that Generic type which is an interface will not be a pointer but a struct. Before this change the code compilation was failing with `type *Generic is pointer to interface, not interface`. See https://github.com/urfave/cli/issues/1441
This commit is contained in:
parent
b68db8d010
commit
891ffb017b
@ -17,7 +17,11 @@ type {{.TypeName}} struct {
|
||||
HasBeenSet bool
|
||||
|
||||
Value {{if .ValuePointer}}*{{end}}{{.GoType}}
|
||||
<<<<<<< HEAD:cmd/urfave-cli-genflags/generated.gotmpl
|
||||
Destination {{if .NoDestinationPointer}}{{else}}*{{end}}{{.GoType}}
|
||||
=======
|
||||
Destination {{if .DestinationPointer}}*{{end}}{{.GoType}}
|
||||
>>>>>>> Add DestinationPointer for flags generator:internal/genflags/generated.gotmpl
|
||||
|
||||
Aliases []string
|
||||
EnvVars []string
|
||||
|
@ -80,8 +80,9 @@ func genFlagType() *main.FlagType {
|
||||
Type: "bool",
|
||||
},
|
||||
},
|
||||
TypeName: "YeOldeBlerfFlag",
|
||||
ValuePointer: true,
|
||||
TypeName: "YeOldeBlerfFlag",
|
||||
ValuePointer: true,
|
||||
DestinationPointer: true,
|
||||
},
|
||||
}
|
||||
}
|
||||
@ -115,6 +116,21 @@ func TestFlagType_ValuePointer(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestFlagType_DestinationPointer(t *testing.T) {
|
||||
ft := genFlagType()
|
||||
|
||||
if !ft.DestinationPointer() {
|
||||
t.Errorf("expected DestinationPointer to be true")
|
||||
return
|
||||
}
|
||||
|
||||
ft.Config = nil
|
||||
|
||||
if ft.DestinationPointer() {
|
||||
t.Errorf("expected DestinationPointer to be false")
|
||||
}
|
||||
}
|
||||
|
||||
func TestFlagType_GenerateFmtStringerInterface(t *testing.T) {
|
||||
ft := genFlagType()
|
||||
|
||||
|
@ -2,6 +2,7 @@
|
||||
# ./cmd/urfave-cli-genflags/main.go which uses the
|
||||
# `Spec` type that maps to this file structure.
|
||||
flag_types:
|
||||
<<<<<<< HEAD
|
||||
bool:
|
||||
struct_fields:
|
||||
- name: Count
|
||||
@ -13,8 +14,30 @@ flag_types:
|
||||
struct_fields:
|
||||
- name: Action
|
||||
type: "func(*Context, float64) error"
|
||||
=======
|
||||
bool: {}
|
||||
float64: {}
|
||||
int64: {}
|
||||
int: {}
|
||||
time.Duration: {}
|
||||
uint64: {}
|
||||
uint: {}
|
||||
|
||||
string:
|
||||
destination_pointer: true
|
||||
struct_fields:
|
||||
- { name: TakesFile, type: bool }
|
||||
Generic:
|
||||
struct_fields:
|
||||
- { name: TakesFile, type: bool }
|
||||
Path:
|
||||
destination_pointer: true
|
||||
struct_fields:
|
||||
- { name: TakesFile, type: bool }
|
||||
>>>>>>> Add DestinationPointer for flags generator
|
||||
Float64Slice:
|
||||
value_pointer: true
|
||||
destination_pointer: true
|
||||
skip_interfaces:
|
||||
- fmt.Stringer
|
||||
struct_fields:
|
||||
@ -41,6 +64,7 @@ flag_types:
|
||||
type: "func(*Context, int64) error"
|
||||
Int64Slice:
|
||||
value_pointer: true
|
||||
destination_pointer: true
|
||||
skip_interfaces:
|
||||
- fmt.Stringer
|
||||
struct_fields:
|
||||
@ -54,6 +78,7 @@ flag_types:
|
||||
type: "func(*Context, uint) error"
|
||||
UintSlice:
|
||||
value_pointer: true
|
||||
destination_pointer: true
|
||||
skip_interfaces:
|
||||
- fmt.Stringer
|
||||
struct_fields:
|
||||
@ -80,6 +105,7 @@ flag_types:
|
||||
type: "func(*Context, string) error"
|
||||
StringSlice:
|
||||
value_pointer: true
|
||||
destination_pointer: true
|
||||
skip_interfaces:
|
||||
- fmt.Stringer
|
||||
struct_fields:
|
||||
@ -93,6 +119,7 @@ flag_types:
|
||||
type: "func(*Context, time.Duration) error"
|
||||
Timestamp:
|
||||
value_pointer: true
|
||||
destination_pointer: true
|
||||
struct_fields:
|
||||
- name: Layout
|
||||
type: string
|
||||
|
117
internal/genflags/spec.go
Normal file
117
internal/genflags/spec.go
Normal file
@ -0,0 +1,117 @@
|
||||
package genflags
|
||||
|
||||
import (
|
||||
"sort"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type Spec struct {
|
||||
FlagTypes map[string]*FlagTypeConfig `yaml:"flag_types"`
|
||||
PackageName string `yaml:"package_name"`
|
||||
TestPackageName string `yaml:"test_package_name"`
|
||||
UrfaveCLINamespace string `yaml:"urfave_cli_namespace"`
|
||||
UrfaveCLITestNamespace string `yaml:"urfave_cli_test_namespace"`
|
||||
}
|
||||
|
||||
func (gfs *Spec) SortedFlagTypes() []*FlagType {
|
||||
typeNames := []string{}
|
||||
|
||||
for name := range gfs.FlagTypes {
|
||||
if strings.HasPrefix(name, "[]") {
|
||||
name = strings.TrimPrefix(name, "[]") + "Slice"
|
||||
}
|
||||
|
||||
typeNames = append(typeNames, name)
|
||||
}
|
||||
|
||||
sort.Strings(typeNames)
|
||||
|
||||
ret := make([]*FlagType, len(typeNames))
|
||||
|
||||
for i, typeName := range typeNames {
|
||||
ret[i] = &FlagType{
|
||||
GoType: typeName,
|
||||
Config: gfs.FlagTypes[typeName],
|
||||
}
|
||||
}
|
||||
|
||||
return ret
|
||||
}
|
||||
|
||||
type FlagTypeConfig struct {
|
||||
SkipInterfaces []string `yaml:"skip_interfaces"`
|
||||
StructFields []*FlagStructField `yaml:"struct_fields"`
|
||||
TypeName string `yaml:"type_name"`
|
||||
ValuePointer bool `yaml:"value_pointer"`
|
||||
DestinationPointer bool `yaml:"destination_pointer"`
|
||||
}
|
||||
|
||||
type FlagStructField struct {
|
||||
Name string
|
||||
Type string
|
||||
}
|
||||
|
||||
type FlagType struct {
|
||||
GoType string
|
||||
Config *FlagTypeConfig
|
||||
}
|
||||
|
||||
func (ft *FlagType) StructFields() []*FlagStructField {
|
||||
if ft.Config == nil || ft.Config.StructFields == nil {
|
||||
return []*FlagStructField{}
|
||||
}
|
||||
|
||||
return ft.Config.StructFields
|
||||
}
|
||||
|
||||
func (ft *FlagType) ValuePointer() bool {
|
||||
if ft.Config == nil {
|
||||
return false
|
||||
}
|
||||
|
||||
return ft.Config.ValuePointer
|
||||
}
|
||||
|
||||
func (ft *FlagType) DestinationPointer() bool {
|
||||
if ft.Config == nil {
|
||||
return false
|
||||
}
|
||||
|
||||
return ft.Config.DestinationPointer
|
||||
}
|
||||
|
||||
func (ft *FlagType) TypeName() string {
|
||||
return TypeName(ft.GoType, ft.Config)
|
||||
}
|
||||
|
||||
func (ft *FlagType) GenerateFmtStringerInterface() bool {
|
||||
return ft.skipInterfaceNamed("fmt.Stringer")
|
||||
}
|
||||
|
||||
func (ft *FlagType) GenerateFlagInterface() bool {
|
||||
return ft.skipInterfaceNamed("Flag")
|
||||
}
|
||||
|
||||
func (ft *FlagType) GenerateRequiredFlagInterface() bool {
|
||||
return ft.skipInterfaceNamed("RequiredFlag")
|
||||
}
|
||||
|
||||
func (ft *FlagType) GenerateVisibleFlagInterface() bool {
|
||||
return ft.skipInterfaceNamed("VisibleFlag")
|
||||
}
|
||||
|
||||
func (ft *FlagType) skipInterfaceNamed(name string) bool {
|
||||
if ft.Config == nil {
|
||||
return true
|
||||
}
|
||||
|
||||
lowName := strings.ToLower(name)
|
||||
|
||||
for _, interfaceName := range ft.Config.SkipInterfaces {
|
||||
if strings.ToLower(interfaceName) == lowName {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
Loading…
Reference in New Issue
Block a user