Skip to content

Commit

Permalink
Merge pull request #1765 from urfave/collapse-int64-into-int
Browse files Browse the repository at this point in the history
Collapse `int64` and `int` flag types
  • Loading branch information
meatballhat committed Jun 21, 2023
2 parents f531a7e + 8a19f93 commit f0aab7f
Show file tree
Hide file tree
Showing 12 changed files with 194 additions and 771 deletions.
66 changes: 13 additions & 53 deletions command_test.go
Expand Up @@ -543,7 +543,7 @@ func TestCommand_VisibleFlagCategories(t *testing.T) {
&StringFlag{
Name: "strd", // no category set
},
&Int64Flag{
&IntFlag{
Name: "intd",
Aliases: []string{"altd1", "altd2"},
Category: "cat1",
Expand Down Expand Up @@ -1233,15 +1233,15 @@ func TestCommand_Float64Flag(t *testing.T) {
}

func TestCommand_ParseSliceFlags(t *testing.T) {
var parsedIntSlice []int
var parsedIntSlice []int64
var parsedStringSlice []string

cmd := &Command{
Commands: []*Command{
{
Name: "cmd",
Flags: []Flag{
&IntSliceFlag{Name: "p", Value: []int{}, Usage: "set one or more ip addr"},
&IntSliceFlag{Name: "p", Value: []int64{}, 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 {
Expand All @@ -1255,7 +1255,7 @@ func TestCommand_ParseSliceFlags(t *testing.T) {

_ = cmd.Run(buildTestContext(t), []string{"", "cmd", "-p", "22", "-p", "80", "-ip", "8.8.8.8", "-ip", "8.8.4.4"})

IntsEquals := func(a, b []int) bool {
IntsEquals := func(a, b []int64) bool {
if len(a) != len(b) {
return false
}
Expand All @@ -1278,7 +1278,7 @@ func TestCommand_ParseSliceFlags(t *testing.T) {
}
return true
}
expectedIntSlice := []int{22, 80}
expectedIntSlice := []int64{22, 80}
expectedStringSlice := []string{"8.8.8.8", "8.8.4.4"}

if !IntsEquals(parsedIntSlice, expectedIntSlice) {
Expand All @@ -1291,7 +1291,7 @@ func TestCommand_ParseSliceFlags(t *testing.T) {
}

func TestCommand_ParseSliceFlagsWithMissingValue(t *testing.T) {
var parsedIntSlice []int
var parsedIntSlice []int64
var parsedStringSlice []string

cmd := &Command{
Expand All @@ -1313,7 +1313,7 @@ func TestCommand_ParseSliceFlagsWithMissingValue(t *testing.T) {

_ = cmd.Run(buildTestContext(t), []string{"", "cmd", "-a", "2", "-str", "A"})

expectedIntSlice := []int{2}
expectedIntSlice := []int64{2}
expectedStringSlice := []string{"A"}

if parsedIntSlice[0] != expectedIntSlice[0] {
Expand Down Expand Up @@ -2758,26 +2758,6 @@ func TestFlagAction(t *testing.T) {
args: []string{"app", "--f_int_slice=-1"},
err: "invalid int slice",
},
{
name: "flag_int64",
args: []string{"app", "--f_int64=1"},
exp: "1 ",
},
{
name: "flag_int64_error",
args: []string{"app", "--f_int64=-1"},
err: "negative int64",
},
{
name: "flag_int64_slice",
args: []string{"app", "--f_int64_slice=1,2,3"},
exp: "[1 2 3] ",
},
{
name: "flag_int64_slice",
args: []string{"app", "--f_int64_slice=-1"},
err: "invalid int64 slice",
},
{
name: "flag_timestamp",
args: []string{"app", "--f_timestamp", "2022-05-01 02:26:20"},
Expand Down Expand Up @@ -2929,7 +2909,7 @@ func TestFlagAction(t *testing.T) {
},
&IntFlag{
Name: "f_int",
Action: func(cCtx *Context, v int) error {
Action: func(cCtx *Context, v int64) error {
if v < 0 {
return fmt.Errorf("negative int")
}
Expand All @@ -2939,29 +2919,9 @@ func TestFlagAction(t *testing.T) {
},
&IntSliceFlag{
Name: "f_int_slice",
Action: func(cCtx *Context, v []int) error {
if len(v) > 0 && v[0] < 0 {
return fmt.Errorf("invalid int slice")
}
_, err := cCtx.Command.Root().Writer.Write([]byte(fmt.Sprintf("%v ", v)))
return err
},
},
&Int64Flag{
Name: "f_int64",
Action: func(cCtx *Context, v int64) error {
if v < 0 {
return fmt.Errorf("negative int64")
}
_, err := cCtx.Command.Root().Writer.Write([]byte(fmt.Sprintf("%v ", v)))
return err
},
},
&Int64SliceFlag{
Name: "f_int64_slice",
Action: func(cCtx *Context, v []int64) error {
if len(v) > 0 && v[0] < 0 {
return fmt.Errorf("invalid int64 slice")
return fmt.Errorf("invalid int slice")
}
_, err := cCtx.Command.Root().Writer.Write([]byte(fmt.Sprintf("%v ", v)))
return err
Expand Down Expand Up @@ -3030,7 +2990,7 @@ func TestFlagAction(t *testing.T) {
}

func TestPersistentFlag(t *testing.T) {
var topInt, topPersistentInt, subCommandInt, appOverrideInt int
var topInt, topPersistentInt, subCommandInt, appOverrideInt int64
var appFlag string
var appOverrideCmdInt int64
var appSliceFloat64 []float64
Expand All @@ -3048,7 +3008,7 @@ func TestPersistentFlag(t *testing.T) {
return nil
},
},
&Int64SliceFlag{
&IntSliceFlag{
Name: "persistentCommandSliceFlag",
Persistent: true,
Destination: &persistentCommandSliceInt,
Expand Down Expand Up @@ -3077,7 +3037,7 @@ func TestPersistentFlag(t *testing.T) {
Persistent: true,
Destination: &topPersistentInt,
},
&Int64Flag{
&IntFlag{
Name: "paof",
Aliases: []string{"persistentCommandOverrideFlag"},
Destination: &appOverrideCmdInt,
Expand Down Expand Up @@ -3171,7 +3131,7 @@ func TestFlagDuplicates(t *testing.T) {
Name: "sflag",
OnlyOnce: true,
},
&Int64SliceFlag{
&IntSliceFlag{
Name: "isflag",
},
&Float64SliceFlag{
Expand Down
65 changes: 32 additions & 33 deletions context_test.go
Expand Up @@ -8,53 +8,50 @@ import (
"strings"
"testing"
"time"

"github.com/stretchr/testify/require"
)

func TestNewContext(t *testing.T) {
set := flag.NewFlagSet("test", 0)
set.Int("myflag", 12, "doc")
set.Int64("myflagInt64", int64(12), "doc")
set.Int64("myflag", 12, "doc")
set.Uint("myflagUint", uint(93), "doc")
set.Uint64("myflagUint64", uint64(93), "doc")
set.Float64("myflag64", float64(17), "doc")

globalSet := flag.NewFlagSet("test", 0)
globalSet.Int("myflag", 42, "doc")
globalSet.Int64("myflagInt64", int64(42), "doc")
globalSet.Int64("myflag", 42, "doc")
globalSet.Uint("myflagUint", uint(33), "doc")
globalSet.Uint64("myflagUint64", uint64(33), "doc")
globalSet.Float64("myflag64", float64(47), "doc")

globalCtx := NewContext(nil, globalSet, nil)

command := &Command{Name: "mycommand"}
c := NewContext(nil, set, globalCtx)
c.Command = command
expect(t, c.Int("myflag"), 12)
expect(t, c.Int64("myflagInt64"), int64(12))
expect(t, c.Uint("myflagUint"), uint(93))
expect(t, c.Uint64("myflagUint64"), uint64(93))
expect(t, c.Float64("myflag64"), float64(17))
expect(t, c.Command.Name, "mycommand")
cCtx := NewContext(nil, set, globalCtx)
cCtx.Command = command

r := require.New(t)
r.Equal(int64(12), cCtx.Int("myflag"))
r.Equal(uint(93), cCtx.Uint("myflagUint"))
r.Equal(uint64(93), cCtx.Uint64("myflagUint64"))
r.Equal(float64(17), cCtx.Float64("myflag64"))
r.Equal("mycommand", cCtx.Command.Name)
}

func TestContext_Int(t *testing.T) {
set := flag.NewFlagSet("test", 0)
set.Int("myflag", 12, "doc")
parentSet := flag.NewFlagSet("test", 0)
parentSet.Int("top-flag", 13, "doc")
parentCtx := NewContext(nil, parentSet, nil)
c := NewContext(nil, set, parentCtx)
expect(t, c.Int("myflag"), 12)
expect(t, c.Int("top-flag"), 13)
}
set.Int64("myflag", 12, "doc")

func TestContext_Int64(t *testing.T) {
set := flag.NewFlagSet("test", 0)
set.Int64("myflagInt64", 12, "doc")
parentSet := flag.NewFlagSet("test", 0)
parentSet.Int64("top-flag", 13, "doc")
parentCtx := NewContext(nil, parentSet, nil)
c := NewContext(nil, set, parentCtx)
expect(t, c.Int64("myflagInt64"), int64(12))
expect(t, c.Int64("top-flag"), int64(13))
parentCctx := NewContext(nil, parentSet, nil)

cCtx := NewContext(nil, set, parentCctx)

r := require.New(t)
r.Equal(int64(12), cCtx.Int("myflag"))
r.Equal(int64(13), cCtx.Int("top-flag"))
}

func TestContext_Uint(t *testing.T) {
Expand Down Expand Up @@ -265,13 +262,15 @@ func TestContext_NumFlags(t *testing.T) {

func TestContext_Set(t *testing.T) {
set := flag.NewFlagSet("test", 0)
set.Int("int", 5, "an int")
c := NewContext(nil, set, nil)
set.Int64("int", int64(5), "an int")
cCtx := NewContext(nil, set, nil)

r := require.New(t)

expect(t, c.IsSet("int"), false)
_ = c.Set("int", "1")
expect(t, c.Int("int"), 1)
expect(t, c.IsSet("int"), true)
r.False(cCtx.IsSet("int"))
r.NoError(cCtx.Set("int", "1"))
r.Equal(int64(1), cCtx.Int("int"))
r.True(cCtx.IsSet("int"))
}

func TestContext_Set_InvalidFlagAccessHandler(t *testing.T) {
Expand Down
21 changes: 9 additions & 12 deletions examples_test.go
Expand Up @@ -419,10 +419,9 @@ func ExampleCommand_Run_sliceValues() {
cmd := &cli.Command{
Name: "multi_values",
Flags: []cli.Flag{
&cli.StringSliceFlag{Name: "stringSclice"},
&cli.Float64SliceFlag{Name: "float64Sclice"},
&cli.Int64SliceFlag{Name: "int64Sclice"},
&cli.IntSliceFlag{Name: "intSclice"},
&cli.StringSliceFlag{Name: "stringSlice"},
&cli.Float64SliceFlag{Name: "float64Slice"},
&cli.IntSliceFlag{Name: "intSlice"},
},
Action: func(cCtx *cli.Context) error {
for i, v := range cCtx.FlagNames() {
Expand All @@ -437,18 +436,16 @@ func ExampleCommand_Run_sliceValues() {
// Simulate command line arguments
os.Args = []string{
"multi_values",
"--stringSclice", "parsed1,parsed2", "--stringSclice", "parsed3,parsed4",
"--float64Sclice", "13.3,14.4", "--float64Sclice", "15.5,16.6",
"--int64Sclice", "13,14", "--int64Sclice", "15,16",
"--intSclice", "13,14", "--intSclice", "15,16",
"--stringSlice", "parsed1,parsed2", "--stringSlice", "parsed3,parsed4",
"--float64Slice", "13.3,14.4", "--float64Slice", "15.5,16.6",
"--intSlice", "13,14", "--intSlice", "15,16",
}

_ = cmd.Run(context.Background(), os.Args)
// Output:
// 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"}
// 0-float64Slice []float64{13.3, 14.4, 15.5, 16.6}
// 1-intSlice []int64{13, 14, 15, 16}
// 2-stringSlice []string{"parsed1", "parsed2", "parsed3", "parsed4"}
// error: <nil>
}

Expand Down
31 changes: 13 additions & 18 deletions flag_int.go
Expand Up @@ -5,57 +5,52 @@ import (
"strconv"
)

type IntFlag = FlagBase[int, IntegerConfig, intValue]
type IntFlag = FlagBase[int64, IntegerConfig, intValue]

// IntegerConfig is the configuration for all integer type flags
type IntegerConfig struct {
Base int
}

// -- int Value
// -- int64 Value
type intValue struct {
val *int
val *int64
base int
}

// Below functions are to satisfy the ValueCreator interface

func (i intValue) Create(val int, p *int, c IntegerConfig) Value {
func (i intValue) Create(val int64, p *int64, c IntegerConfig) Value {
*p = val
return &intValue{
val: p,
base: c.Base,
}
}

func (i intValue) ToString(b int) string {
return fmt.Sprintf("%v", b)
func (i intValue) ToString(b int64) string {
return fmt.Sprintf("%d", b)
}

// Below functions are to satisfy the flag.Value interface

func (i *intValue) Set(s string) error {
v, err := strconv.ParseInt(s, i.base, strconv.IntSize)
v, err := strconv.ParseInt(s, i.base, 64)
if err != nil {
return err
}
*i.val = int(v)
*i.val = v
return err
}

func (i *intValue) Get() any { return int(*i.val) }
func (i *intValue) Get() any { return int64(*i.val) }

func (i *intValue) String() string {
if i == nil || i.val == nil {
return ""
}
return strconv.Itoa(int(*i.val))
}
func (i *intValue) String() string { return strconv.FormatInt(int64(*i.val), 10) }

// Int looks up the value of a local IntFlag, returns
// Int64 looks up the value of a local Int64Flag, returns
// 0 if not found
func (cCtx *Context) Int(name string) int {
if v, ok := cCtx.Value(name).(int); ok {
func (cCtx *Context) Int(name string) int64 {
if v, ok := cCtx.Value(name).(int64); ok {
return v
}
return 0
Expand Down

0 comments on commit f0aab7f

Please sign in to comment.