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
|
HasBeenSet bool
|
||||||
|
|
||||||
Value {{if .ValuePointer}}*{{end}}{{.GoType}}
|
Value {{if .ValuePointer}}*{{end}}{{.GoType}}
|
||||||
|
<<<<<<< HEAD:cmd/urfave-cli-genflags/generated.gotmpl
|
||||||
Destination {{if .NoDestinationPointer}}{{else}}*{{end}}{{.GoType}}
|
Destination {{if .NoDestinationPointer}}{{else}}*{{end}}{{.GoType}}
|
||||||
|
=======
|
||||||
|
Destination {{if .DestinationPointer}}*{{end}}{{.GoType}}
|
||||||
|
>>>>>>> Add DestinationPointer for flags generator:internal/genflags/generated.gotmpl
|
||||||
|
|
||||||
Aliases []string
|
Aliases []string
|
||||||
EnvVars []string
|
EnvVars []string
|
||||||
|
@ -80,8 +80,9 @@ func genFlagType() *main.FlagType {
|
|||||||
Type: "bool",
|
Type: "bool",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
TypeName: "YeOldeBlerfFlag",
|
TypeName: "YeOldeBlerfFlag",
|
||||||
ValuePointer: true,
|
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) {
|
func TestFlagType_GenerateFmtStringerInterface(t *testing.T) {
|
||||||
ft := genFlagType()
|
ft := genFlagType()
|
||||||
|
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
# ./cmd/urfave-cli-genflags/main.go which uses the
|
# ./cmd/urfave-cli-genflags/main.go which uses the
|
||||||
# `Spec` type that maps to this file structure.
|
# `Spec` type that maps to this file structure.
|
||||||
flag_types:
|
flag_types:
|
||||||
|
<<<<<<< HEAD
|
||||||
bool:
|
bool:
|
||||||
struct_fields:
|
struct_fields:
|
||||||
- name: Count
|
- name: Count
|
||||||
@ -13,8 +14,30 @@ flag_types:
|
|||||||
struct_fields:
|
struct_fields:
|
||||||
- name: Action
|
- name: Action
|
||||||
type: "func(*Context, float64) error"
|
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:
|
Float64Slice:
|
||||||
value_pointer: true
|
value_pointer: true
|
||||||
|
destination_pointer: true
|
||||||
skip_interfaces:
|
skip_interfaces:
|
||||||
- fmt.Stringer
|
- fmt.Stringer
|
||||||
struct_fields:
|
struct_fields:
|
||||||
@ -41,6 +64,7 @@ flag_types:
|
|||||||
type: "func(*Context, int64) error"
|
type: "func(*Context, int64) error"
|
||||||
Int64Slice:
|
Int64Slice:
|
||||||
value_pointer: true
|
value_pointer: true
|
||||||
|
destination_pointer: true
|
||||||
skip_interfaces:
|
skip_interfaces:
|
||||||
- fmt.Stringer
|
- fmt.Stringer
|
||||||
struct_fields:
|
struct_fields:
|
||||||
@ -54,6 +78,7 @@ flag_types:
|
|||||||
type: "func(*Context, uint) error"
|
type: "func(*Context, uint) error"
|
||||||
UintSlice:
|
UintSlice:
|
||||||
value_pointer: true
|
value_pointer: true
|
||||||
|
destination_pointer: true
|
||||||
skip_interfaces:
|
skip_interfaces:
|
||||||
- fmt.Stringer
|
- fmt.Stringer
|
||||||
struct_fields:
|
struct_fields:
|
||||||
@ -80,6 +105,7 @@ flag_types:
|
|||||||
type: "func(*Context, string) error"
|
type: "func(*Context, string) error"
|
||||||
StringSlice:
|
StringSlice:
|
||||||
value_pointer: true
|
value_pointer: true
|
||||||
|
destination_pointer: true
|
||||||
skip_interfaces:
|
skip_interfaces:
|
||||||
- fmt.Stringer
|
- fmt.Stringer
|
||||||
struct_fields:
|
struct_fields:
|
||||||
@ -93,6 +119,7 @@ flag_types:
|
|||||||
type: "func(*Context, time.Duration) error"
|
type: "func(*Context, time.Duration) error"
|
||||||
Timestamp:
|
Timestamp:
|
||||||
value_pointer: true
|
value_pointer: true
|
||||||
|
destination_pointer: true
|
||||||
struct_fields:
|
struct_fields:
|
||||||
- name: Layout
|
- name: Layout
|
||||||
type: string
|
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…
x
Reference in New Issue
Block a user