Skip to content

Commit

Permalink
Merge pull request #1512 from dearchap/use_generics
Browse files Browse the repository at this point in the history
First cut at using generics for base flag types
  • Loading branch information
dearchap authored Nov 26, 2022
2 parents 268bea7 + e2e3aa0 commit aef9126
Show file tree
Hide file tree
Showing 34 changed files with 1,108 additions and 8,203 deletions.
70 changes: 13 additions & 57 deletions app_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -425,10 +425,10 @@ func ExampleApp_Run_sliceValues() {

_ = app.Run(os.Args)
// Output:
// 0-float64Sclice cli.Float64Slice{slice:[]float64{13.3, 14.4, 15.5, 16.6}, hasBeenSet:true}
// 1-int64Sclice cli.Int64Slice{slice:[]int64{13, 14, 15, 16}, hasBeenSet:true}
// 2-intSclice cli.IntSlice{slice:[]int{13, 14, 15, 16}, hasBeenSet:true}
// 3-stringSclice cli.StringSlice{slice:[]string{"parsed1", "parsed2", "parsed3", "parsed4"}, hasBeenSet:true}
// 0-float64Sclice []float64{13.3, 14.4, 15.5, 16.6}
// 1-int64Sclice []int64{13, 14, 15, 16}
// 2-intSclice []int{13, 14, 15, 16}
// 3-stringSclice []string{"parsed1", "parsed2", "parsed3", "parsed4"}
// error: <nil>
}

Expand Down Expand Up @@ -1018,7 +1018,7 @@ func TestApp_UseShortOptionHandlingSubCommand_missing_value(t *testing.T) {
func TestApp_UseShortOptionAfterSliceFlag(t *testing.T) {
var one, two bool
var name string
var sliceValDest StringSlice
var sliceValDest []string
var sliceVal []string
expected := "expectedName"

Expand All @@ -1040,7 +1040,7 @@ func TestApp_UseShortOptionAfterSliceFlag(t *testing.T) {

_ = app.Run([]string{"", "-e", "foo", "-on", expected})
expect(t, sliceVal, []string{"foo"})
expect(t, sliceValDest.Value(), []string{"foo"})
expect(t, sliceValDest, []string{"foo"})
expect(t, one, true)
expect(t, two, false)
expect(t, name, expected)
Expand Down Expand Up @@ -1072,8 +1072,8 @@ func TestApp_ParseSliceFlags(t *testing.T) {
{
Name: "cmd",
Flags: []Flag{
&IntSliceFlag{Name: "p", Value: NewIntSlice(), Usage: "set one or more ip addr"},
&StringSliceFlag{Name: "ip", Value: NewStringSlice(), Usage: "set one or more ports to open"},
&IntSliceFlag{Name: "p", Value: []int{}, Usage: "set one or more ip addr"},
&StringSliceFlag{Name: "ip", Value: []string{}, Usage: "set one or more ports to open"},
},
Action: func(c *Context) error {
parsedIntSlice = c.IntSlice("p")
Expand Down Expand Up @@ -2804,22 +2804,6 @@ func TestFlagAction(t *testing.T) {
return nil
},
},
&GenericFlag{
Name: "f_generic",
Value: new(stringGeneric),
Action: func(c *Context, v interface{}) error {
fmt.Printf("%T %v\n", v, v)
switch vv := v.(type) {
case *stringGeneric:
if vv.value == "" {
return fmt.Errorf("generic value not set")
}
}

c.App.Writer.Write([]byte(fmt.Sprintf("%v ", v)))
return nil
},
},
&IntFlag{
Name: "f_int",
Action: func(c *Context, v int) error {
Expand Down Expand Up @@ -2860,20 +2844,12 @@ func TestFlagAction(t *testing.T) {
return nil
},
},
&PathFlag{
Name: "f_path",
Action: func(c *Context, v string) error {
if v == "" {
return fmt.Errorf("empty path")
}
c.App.Writer.Write([]byte(fmt.Sprintf("%v ", v)))
return nil
},
},
&TimestampFlag{
Name: "f_timestamp",
Layout: "2006-01-02 15:04:05",
Action: func(c *Context, v *time.Time) error {
Name: "f_timestamp",
Config: TimestampConfig{
Layout: "2006-01-02 15:04:05",
},
Action: func(c *Context, v time.Time) error {
if v.IsZero() {
return fmt.Errorf("zero timestamp")
}
Expand Down Expand Up @@ -2971,16 +2947,6 @@ func TestFlagAction(t *testing.T) {
args: []string{"app", "--f_float64_slice=-1"},
err: fmt.Errorf("invalid float64 slice"),
},
{
name: "flag_generic",
args: []string{"app", "--f_generic=1"},
exp: "1 ",
},
{
name: "flag_generic_error",
args: []string{"app", "--f_generic="},
err: fmt.Errorf("generic value not set"),
},
{
name: "flag_int",
args: []string{"app", "--f_int=1"},
Expand Down Expand Up @@ -3021,16 +2987,6 @@ func TestFlagAction(t *testing.T) {
args: []string{"app", "--f_int64_slice=-1"},
err: fmt.Errorf("invalid int64 slice"),
},
{
name: "flag_path",
args: []string{"app", "--f_path=/root"},
exp: "/root ",
},
{
name: "flag_path_error",
args: []string{"app", "--f_path="},
err: fmt.Errorf("empty path"),
},
{
name: "flag_timestamp",
args: []string{"app", "--f_timestamp", "2022-05-01 02:26:20"},
Expand Down
11 changes: 0 additions & 11 deletions context_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -116,17 +116,6 @@ func TestContext_String(t *testing.T) {
expect(t, c.String("top-flag"), "hai veld")
}

func TestContext_Path(t *testing.T) {
set := flag.NewFlagSet("test", 0)
set.String("path", "path/to/file", "path to file")
parentSet := flag.NewFlagSet("test", 0)
parentSet.String("top-path", "path/to/top/file", "doc")
parentCtx := NewContext(nil, parentSet, nil)
c := NewContext(nil, set, parentCtx)
expect(t, c.Path("path"), "path/to/file")
expect(t, c.Path("top-path"), "path/to/top/file")
}

func TestContext_Bool(t *testing.T) {
set := flag.NewFlagSet("test", 0)
set.Bool("myflag", false, "doc")
Expand Down
8 changes: 0 additions & 8 deletions fish.go
Original file line number Diff line number Diff line change
Expand Up @@ -159,10 +159,6 @@ func (a *App) prepareFishFlags(flags []Flag, previousCommands []string) []string

func fishAddFileFlag(flag Flag, completion *strings.Builder) {
switch f := flag.(type) {
case *GenericFlag:
if f.TakesFile {
return
}
case *StringFlag:
if f.TakesFile {
return
Expand All @@ -171,10 +167,6 @@ func fishAddFileFlag(flag Flag, completion *strings.Builder) {
if f.TakesFile {
return
}
case *PathFlag:
if f.TakesFile {
return
}
}
completion.WriteString(" -f")
}
Expand Down
2 changes: 1 addition & 1 deletion fish_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import (
func TestFishCompletion(t *testing.T) {
// Given
app := testApp()
app.Flags = append(app.Flags, &PathFlag{
app.Flags = append(app.Flags, &StringFlag{
Name: "logfile",
TakesFile: true,
})
Expand Down
112 changes: 0 additions & 112 deletions flag-spec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,115 +2,3 @@
# ./cmd/urfave-cli-genflags/main.go which uses the
# `Spec` type that maps to this file structure.
flag_types:
bool:
no_default_text: true
struct_fields:
- name: Count
type: int
pointer: true
- name: Action
type: "func(*Context, bool) error"
float64:
struct_fields:
- name: Action
type: "func(*Context, float64) error"
Float64Slice:
value_pointer: true
skip_interfaces:
- fmt.Stringer
struct_fields:
- name: Action
type: "func(*Context, []float64) error"
int:
struct_fields:
- name: Base
type: int
- name: Action
type: "func(*Context, int) error"
IntSlice:
value_pointer: true
skip_interfaces:
- fmt.Stringer
struct_fields:
- name: Action
type: "func(*Context, []int) error"
int64:
struct_fields:
- name: Base
type: int
- name: Action
type: "func(*Context, int64) error"
Int64Slice:
value_pointer: true
skip_interfaces:
- fmt.Stringer
struct_fields:
- name: Action
type: "func(*Context, []int64) error"
uint:
struct_fields:
- name: Base
type: int
- name: Action
type: "func(*Context, uint) error"
UintSlice:
value_pointer: true
skip_interfaces:
- fmt.Stringer
struct_fields:
- name: Action
type: "func(*Context, []uint) error"
uint64:
struct_fields:
- name: Base
type: int
- name: Action
type: "func(*Context, uint64) error"
Uint64Slice:
value_pointer: true
skip_interfaces:
- fmt.Stringer
struct_fields:
- name: Action
type: "func(*Context, []uint64) error"
string:
struct_fields:
- name: TakesFile
type: bool
- name: Action
type: "func(*Context, string) error"
StringSlice:
value_pointer: true
skip_interfaces:
- fmt.Stringer
struct_fields:
- name: TakesFile
type: bool
- name: Action
type: "func(*Context, []string) error"
time.Duration:
struct_fields:
- name: Action
type: "func(*Context, time.Duration) error"
Timestamp:
value_pointer: true
struct_fields:
- name: Layout
type: string
- name: Timezone
type: "*time.Location"
- name: Action
type: "func(*Context, *time.Time) error"
Generic:
no_destination_pointer: true
struct_fields:
- name: TakesFile
type: bool
- name: Action
type: "func(*Context, interface{}) error"
Path:
struct_fields:
- name: TakesFile
type: bool
- name: Action
type: "func(*Context, Path) error"
Loading

0 comments on commit aef9126

Please sign in to comment.