From 868807a9088afa253acd2f604b51fb13217554d1 Mon Sep 17 00:00:00 2001 From: Ramana Reddy Date: Tue, 27 Jun 2023 12:22:46 +0530 Subject: [PATCH 1/2] support days unit with DuarationVar --- duration_var.go | 51 ++++++++++++++++++++++++++++++++++++++++++++ duration_var_test.go | 43 +++++++++++++++++++++++++++++++++++++ go.mod | 10 ++++----- go.sum | 20 ++++++++--------- goflags.go | 28 ------------------------ 5 files changed, 109 insertions(+), 43 deletions(-) create mode 100644 duration_var.go create mode 100644 duration_var_test.go diff --git a/duration_var.go b/duration_var.go new file mode 100644 index 0000000..6f6ec9c --- /dev/null +++ b/duration_var.go @@ -0,0 +1,51 @@ +package goflags + +import ( + "errors" + "time" + timeutil "github.com/projectdiscovery/utils/time" +) + +type durationValue time.Duration + +func newDurationValue(val time.Duration, p *time.Duration) *durationValue { + *p = val + return (*durationValue)(p) +} + +func (d *durationValue) Set(s string) error { + v, err := timeutil.ParseDuration(s) + if err != nil { + err = errors.New("parse error") + } + *d = durationValue(v) + return err +} + +func (d *durationValue) Get() any { return time.Duration(*d) } + +func (d *durationValue) String() string { return (*time.Duration)(d).String() } + +// DurationVar adds a duration flag with a longname +func (flagSet *FlagSet) DurationVar(field *time.Duration, long string, defaultValue time.Duration, usage string) *FlagData { + return flagSet.DurationVarP(field, long, "", defaultValue, usage) +} + +// DurationVarP adds a duration flag with a short name and long name. +// It is equivalent to DurationVar but also allows specifying durations in days (e.g., "2d" for 2 days, which is equivalent to 2*24h). +// The default unit for durations is seconds (ex: "10" => 10s). +func (flagSet *FlagSet) DurationVarP(field *time.Duration, long, short string, defaultValue time.Duration, usage string) *FlagData { + flagData := &FlagData{ + usage: usage, + long: long, + defaultValue: defaultValue, + } + if short != "" { + flagData.short = short + flagSet.CommandLine.Var(newDurationValue(defaultValue, field), short, usage) + flagSet.flagKeys.Set(short, flagData) + } + flagSet.CommandLine.Var(newDurationValue(defaultValue, field), long, usage) + flagSet.flagKeys.Set(long, flagData) + return flagData +} diff --git a/duration_var_test.go b/duration_var_test.go new file mode 100644 index 0000000..945e4d8 --- /dev/null +++ b/duration_var_test.go @@ -0,0 +1,43 @@ +package goflags + +import ( + "os" + "testing" + "time" + + "github.com/stretchr/testify/assert" +) + +func TestDurationVar(t *testing.T) { + t.Run("day-unit", func(t *testing.T) { + var tt time.Duration + flagSet := NewFlagSet() + flagSet.CreateGroup("Config", "Config", + flagSet.DurationVarP(&tt, "time-out", "tm", 0, "timeout for the process"), + ) + os.Args = []string{ + os.Args[0], + "-time-out", "2d", + } + err := flagSet.Parse() + assert.Nil(t, err) + assert.Equal(t, 2*24*time.Hour, tt) + tearDown(t.Name()) + }) + + t.Run("without-unit", func(t *testing.T) { + var tt time.Duration + flagSet := NewFlagSet() + flagSet.CreateGroup("Config", "Config", + flagSet.DurationVarP(&tt, "time-out", "tm", 0, "timeout for the process"), + ) + os.Args = []string{ + os.Args[0], + "-time-out", "2", + } + err := flagSet.Parse() + assert.Nil(t, err) + assert.Equal(t, 2*time.Second, tt) + tearDown(t.Name()) + }) +} diff --git a/go.mod b/go.mod index 6855fe4..f9e7b97 100644 --- a/go.mod +++ b/go.mod @@ -5,16 +5,16 @@ go 1.18 require ( github.com/cnf/structhash v0.0.0-20201127153200-e1b16c1ebc08 github.com/pkg/errors v0.9.1 - github.com/stretchr/testify v1.8.3 + github.com/stretchr/testify v1.8.4 golang.org/x/exp v0.0.0-20221019170559-20944726eadf gopkg.in/yaml.v3 v3.0.1 ) require ( - github.com/miekg/dns v1.1.54 // indirect + github.com/miekg/dns v1.1.55 // indirect github.com/projectdiscovery/blackrock v0.0.1 // indirect golang.org/x/mod v0.8.0 // indirect - golang.org/x/sys v0.8.0 // indirect + golang.org/x/sys v0.9.0 // indirect golang.org/x/tools v0.6.0 // indirect ) @@ -25,7 +25,7 @@ require ( github.com/gorilla/css v1.0.0 // indirect github.com/microcosm-cc/bluemonday v1.0.24 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - github.com/projectdiscovery/utils v0.0.35 + github.com/projectdiscovery/utils v0.0.40-0.20230627061640-8ec2b35f851c github.com/saintfish/chardet v0.0.0-20120816061221-3af4cd4741ca // indirect - golang.org/x/net v0.10.0 // indirect + golang.org/x/net v0.11.0 // indirect ) diff --git a/go.sum b/go.sum index ae407b4..b898859 100644 --- a/go.sum +++ b/go.sum @@ -10,29 +10,29 @@ github.com/gorilla/css v1.0.0 h1:BQqNyPTi50JCFMTw/b67hByjMVXZRwGha6wxVGkeihY= github.com/gorilla/css v1.0.0/go.mod h1:Dn721qIggHpt4+EFCcTLTU/vk5ySda2ReITrtgBl60c= github.com/microcosm-cc/bluemonday v1.0.24 h1:NGQoPtwGVcbGkKfvyYk1yRqknzBuoMiUrO6R7uFTPlw= github.com/microcosm-cc/bluemonday v1.0.24/go.mod h1:ArQySAMps0790cHSkdPEJ7bGkF2VePWH773hsJNSHf8= -github.com/miekg/dns v1.1.54 h1:5jon9mWcb0sFJGpnI99tOMhCPyJ+RPVz5b63MQG0VWI= -github.com/miekg/dns v1.1.54/go.mod h1:uInx36IzPl7FYnDcMeVWxj9byh7DutNykX4G9Sj60FY= +github.com/miekg/dns v1.1.55 h1:GoQ4hpsj0nFLYe+bWiCToyrBEJXkQfOOIvFGFy0lEgo= +github.com/miekg/dns v1.1.55/go.mod h1:uInx36IzPl7FYnDcMeVWxj9byh7DutNykX4G9Sj60FY= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/projectdiscovery/blackrock v0.0.1 h1:lHQqhaaEFjgf5WkuItbpeCZv2DUIE45k0VbGJyft6LQ= github.com/projectdiscovery/blackrock v0.0.1/go.mod h1:ANUtjDfaVrqB453bzToU+YB4cUbvBRpLvEwoWIwlTss= -github.com/projectdiscovery/utils v0.0.35 h1:+ex4fbJlcbf/5/RXFZcI9SG0Fo27vxlwV5DP+fMLY+4= -github.com/projectdiscovery/utils v0.0.35/go.mod h1:gyDuJpCGPHN6Lyo3O8PAkTxf88iiAxRZyaMFMrXV0z4= +github.com/projectdiscovery/utils v0.0.40-0.20230627061640-8ec2b35f851c h1:mNV/VSMi9wVpq3gcz4km2oUml9M+La20GaFoJPe3Ils= +github.com/projectdiscovery/utils v0.0.40-0.20230627061640-8ec2b35f851c/go.mod h1:rrd8dTBuKEScNMLgs1Xiu8rPCVeR0QTzmRcQ5iM3ymo= github.com/saintfish/chardet v0.0.0-20120816061221-3af4cd4741ca h1:NugYot0LIVPxTvN8n+Kvkn6TrbMyxQiuvKdEwFdR9vI= github.com/saintfish/chardet v0.0.0-20120816061221-3af4cd4741ca/go.mod h1:uugorj2VCxiV1x+LzaIdVa9b4S4qGAcH6cbhh4qVxOU= -github.com/stretchr/testify v1.8.3 h1:RP3t2pwF7cMEbC1dqtB6poj3niw/9gnV4Cjg5oW5gtY= -github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= +github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= golang.org/x/exp v0.0.0-20221019170559-20944726eadf h1:nFVjjKDgNY37+ZSYCJmtYf7tOlfQswHqplG2eosjOMg= golang.org/x/exp v0.0.0-20221019170559-20944726eadf/go.mod h1:cyybsKvd6eL0RnXn6p/Grxp8F5bW7iYuBgsNCOHpMYE= golang.org/x/mod v0.8.0 h1:LUYupSeNrTNCGzR/hVBk2NHZO4hXcVaW1k4Qx7rjPx8= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/net v0.10.0 h1:X2//UzNDwYmtCLn7To6G58Wr6f5ahEAQgKNzv9Y951M= -golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= +golang.org/x/net v0.11.0 h1:Gi2tvZIJyBtO9SDr1q9h5hEQCp/4L2RQ+ar0qjx2oNU= +golang.org/x/net v0.11.0/go.mod h1:2L/ixqYpgIVXmeoSA/4Lu7BzTG4KIyPIryS4IsOd1oQ= golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o= -golang.org/x/sys v0.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU= -golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.9.0 h1:KS/R3tvhPqvJvwcKfnBHJwwthS11LRhmM5D59eEXa0s= +golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/tools v0.6.0 h1:BOw41kyTf3PuCW1pVQf8+Cyg8pMlkYB1oo9iJ6D/lKM= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= diff --git a/goflags.go b/goflags.go index e1edeaa..de76313 100644 --- a/goflags.go +++ b/goflags.go @@ -448,34 +448,6 @@ func (flagSet *FlagSet) PortVarP(field *Port, long, short string, defaultValue [ return flagData } -// DurationVarP adds a duration flag with a shortname and longname -func (flagSet *FlagSet) DurationVarP(field *time.Duration, long, short string, defaultValue time.Duration, usage string) *FlagData { - flagSet.CommandLine.DurationVar(field, short, defaultValue, usage) - flagSet.CommandLine.DurationVar(field, long, defaultValue, usage) - - flagData := &FlagData{ - usage: usage, - short: short, - long: long, - defaultValue: defaultValue, - } - flagSet.flagKeys.Set(short, flagData) - flagSet.flagKeys.Set(long, flagData) - return flagData -} - -// DurationVar adds a duration flag with a longname -func (flagSet *FlagSet) DurationVar(field *time.Duration, long string, defaultValue time.Duration, usage string) *FlagData { - flagSet.CommandLine.DurationVar(field, long, defaultValue, usage) - flagData := &FlagData{ - usage: usage, - long: long, - defaultValue: defaultValue, - } - flagSet.flagKeys.Set(long, flagData) - return flagData -} - // EnumVar adds a enum flag with a longname func (flagSet *FlagSet) EnumVar(field *string, long string, defaultValue EnumVariable, usage string, allowedTypes AllowdTypes) *FlagData { return flagSet.EnumVarP(field, long, "", defaultValue, usage, allowedTypes) From c9f5bd28a88c7867dadd9087030d943a2e7c39c2 Mon Sep 17 00:00:00 2001 From: Mzack9999 Date: Tue, 27 Jun 2023 14:25:02 +0200 Subject: [PATCH 2/2] adding duration to example --- examples/basic/main.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/examples/basic/main.go b/examples/basic/main.go index c857027..f4fc21a 100644 --- a/examples/basic/main.go +++ b/examples/basic/main.go @@ -3,6 +3,7 @@ package main import ( "fmt" "log" + "time" "github.com/projectdiscovery/goflags" ) @@ -13,6 +14,7 @@ type Options struct { Phone string Address goflags.StringSlice fileSize goflags.Size + duration time.Duration } func main() { @@ -32,6 +34,7 @@ func main() { flagSet.StringSliceVarP(&testOptions.Address, "address", "add", nil, "address of the user", goflags.StringSliceOptions), flagSet.CallbackVarP(CheckUpdate, "update", "ut", "update this tool to latest version"), flagSet.SizeVarP(&testOptions.fileSize, "max-size", "ms", "", "max file size"), + flagSet.DurationVar(&testOptions.duration, "timeout", time.Hour, "timeout"), ) if err := flagSet.Parse(); err != nil {