From 31c19a8ef300f6be92ef9115a50b68990b14f310 Mon Sep 17 00:00:00 2001 From: Martin Lees Date: Mon, 9 Dec 2019 11:50:47 +0100 Subject: [PATCH 1/9] timestamp flag --- flag_timestamp.go | 130 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 130 insertions(+) create mode 100644 flag_timestamp.go diff --git a/flag_timestamp.go b/flag_timestamp.go new file mode 100644 index 0000000000..0b2cb23e66 --- /dev/null +++ b/flag_timestamp.go @@ -0,0 +1,130 @@ +package cli + +import ( + "flag" + "fmt" + "time" +) + + +// timestamp wrap to satisfy golang's flag interface. +type timestampWrap struct { + timestamp *time.Time + hasBeenSet bool + layout string +} + +// Set the timestamp value directly +func (t *timestampWrap) SetTimestamp(value time.Time) { + if !t.hasBeenSet { + t.timestamp = &value + t.hasBeenSet = true + } +} +// Set the timestamp string layout for future parsing +func (t *timestampWrap) SetLayout(layout string) { + t.layout = layout +} + +// Parses the string value to timestamp +func (t *timestampWrap) Set(value string) error { + timestamp, err := time.Parse(t.layout, value) + if err != nil { + return err + } + + t.timestamp = ×tamp + return nil +} + +// String returns a readable representation of this value (for usage defaults) +func (t *timestampWrap) String() string { + return fmt.Sprintf("%#v", t.timestamp) +} + +// Value returns the timestamp value stored in the flag +func (t *timestampWrap) Value() *time.Time { + return t.timestamp +} + +// Get returns the flag structure +func (t *timestampWrap) Get() interface{} { + return *t +} + +// TimestampFlag is a flag with type protobuf.timestamp +type TimestampFlag struct { + Name string + Aliases []string + Usage string + EnvVars []string + FilePath string + Required bool + Hidden bool + Layout string + Value timestampWrap + DefaultText string + HasBeenSet bool +} + +// IsSet returns whether or not the flag has been set through env or file +func (f *TimestampFlag) IsSet() bool { + return f.HasBeenSet +} + +// String returns a readable representation of this value +// (for usage defaults) +func (f *TimestampFlag) String() string { + return FlagStringer(f) +} + +// Names returns the names of the flag +func (f *TimestampFlag) Names() []string { + return flagNames(f) +} + +// IsRequired returns whether or not the flag is required +func (f *TimestampFlag) IsRequired() bool { + return f.Required +} + +// TakesValue returns true of the flag takes a value, otherwise false +func (f *TimestampFlag) TakesValue() bool { + return true +} + +// GetUsage returns the usage string for the flag +func (f *TimestampFlag) GetUsage() string { + return f.Usage +} + +// GetValue returns the flag value +func (f *TimestampFlag) GetValue() *time.Time { + return f.Value.timestamp +} + +// Apply populates the flag given the flag set and environment +func (f *TimestampFlag) Apply(set *flag.FlagSet) error { + for _, name := range f.Names() { + f.Value.SetLayout(f.Layout) + set.Var(&f.Value, name, f.Usage) + } + return nil +} + +// Timestamp gets the timestamp from a flag name +func (c *Context) Timestamp(name string) *time.Time { + if fs := lookupFlagSet(name, c); fs != nil { + return lookupTimestamp(name, fs) + } + return nil +} + +// Fetches the timestamp value from the local timestampWrap +func lookupTimestamp(name string, set *flag.FlagSet) *time.Time { + f := set.Lookup(name) + if f != nil { + return (f.Value.(*timestampWrap)).Value() + } + return nil +} From 06eb576eaac0fbe45231cb0a99e06a4c463d04d6 Mon Sep 17 00:00:00 2001 From: Martin Lees Date: Thu, 12 Dec 2019 17:31:20 +0100 Subject: [PATCH 2/9] Review fixes --- flag_test.go | 30 ++++++++++++++++++++++++-- flag_timestamp.go | 55 ++++++++++++++++++++++++++++++++--------------- 2 files changed, 66 insertions(+), 19 deletions(-) diff --git a/flag_test.go b/flag_test.go index 769f7bf687..915108967a 100644 --- a/flag_test.go +++ b/flag_test.go @@ -121,8 +121,8 @@ func TestFlagsFromEnv(t *testing.T) { a := App{ Flags: []Flag{test.flag}, Action: func(ctx *Context) error { - if !reflect.DeepEqual(ctx.Value(test.flag.Names()[0]), test.output) { - t.Errorf("ex:%01d expected %q to be parsed as %#v, instead was %#v", i, test.input, test.output, ctx.Value(test.flag.Names()[0])) + if !reflect.DeepEqual(ctx.value(test.flag.Names()[0]), test.output) { + t.Errorf("ex:%01d expected %q to be parsed as %#v, instead was %#v", i, test.input, test.output, ctx.value(test.flag.Names()[0])) } return nil }, @@ -1678,3 +1678,29 @@ func TestInt64Slice_Serialized_Set(t *testing.T) { t.Fatalf("pre and post serialization do not match: %v != %v", sl0, sl1) } } + +func TestTimestamp_set(t *testing.T) { + ts := Timestamp{ + timestamp: nil, + hasBeenSet: false, + layout: "Jan 2, 2006 at 3:04pm (MST)", + } + + time1 := "Feb 3, 2013 at 7:54pm (PST)" + if err := ts.Set(time1); err != nil { + t.Fatalf("Failed to parse time %s with layout %s", time1, ts.layout) + } + if ts.hasBeenSet == false { + t.Fatalf("hasBeenSet is not true after setting a time") + } + + ts.hasBeenSet = false + ts.SetLayout(time.RFC3339) + time2 := "2006-01-02T15:04:05Z" + if err := ts.Set(time2); err != nil { + t.Fatalf("Failed to parse time %s with layout %s", time2, ts.layout) + } + if ts.hasBeenSet == false { + t.Fatalf("hasBeenSet is not true after setting a time") + } +} diff --git a/flag_timestamp.go b/flag_timestamp.go index 0b2cb23e66..91b4e8724b 100644 --- a/flag_timestamp.go +++ b/flag_timestamp.go @@ -6,53 +6,58 @@ import ( "time" ) - -// timestamp wrap to satisfy golang's flag interface. -type timestampWrap struct { +// Timestamp wrap to satisfy golang's flag interface. +type Timestamp struct { timestamp *time.Time hasBeenSet bool layout string } +// Timestamp constructor +func NewTimestamp(timestamp time.Time) *Timestamp { + return &Timestamp{timestamp: ×tamp} +} + // Set the timestamp value directly -func (t *timestampWrap) SetTimestamp(value time.Time) { +func (t *Timestamp) SetTimestamp(value time.Time) { if !t.hasBeenSet { t.timestamp = &value t.hasBeenSet = true } } // Set the timestamp string layout for future parsing -func (t *timestampWrap) SetLayout(layout string) { +func (t *Timestamp) SetLayout(layout string) { t.layout = layout } // Parses the string value to timestamp -func (t *timestampWrap) Set(value string) error { +func (t *Timestamp) Set(value string) error { timestamp, err := time.Parse(t.layout, value) if err != nil { return err } t.timestamp = ×tamp + t.hasBeenSet = true return nil } // String returns a readable representation of this value (for usage defaults) -func (t *timestampWrap) String() string { +func (t *Timestamp) String() string { return fmt.Sprintf("%#v", t.timestamp) } // Value returns the timestamp value stored in the flag -func (t *timestampWrap) Value() *time.Time { +func (t *Timestamp) Value() *time.Time { return t.timestamp } // Get returns the flag structure -func (t *timestampWrap) Get() interface{} { +func (t *Timestamp) Get() interface{} { return *t } -// TimestampFlag is a flag with type protobuf.timestamp +// TimestampFlag is a flag with type time type TimestampFlag struct { Name string Aliases []string @@ -62,7 +67,7 @@ type TimestampFlag struct { Required bool Hidden bool Layout string - Value timestampWrap + Value *Timestamp DefaultText string HasBeenSet bool } @@ -98,16 +103,32 @@ func (f *TimestampFlag) GetUsage() string { return f.Usage } -// GetValue returns the flag value -func (f *TimestampFlag) GetValue() *time.Time { - return f.Value.timestamp +// GetValue returns the flags value as string representation and an empty +// string if the flag takes no value at all. +func (f *TimestampFlag) GetValue() string { + if f.Value != nil { + return f.Value.timestamp.String() + } + return "" } // Apply populates the flag given the flag set and environment func (f *TimestampFlag) Apply(set *flag.FlagSet) error { + if f.Layout == "" { + return fmt.Errorf("timestamp Layout is required") + } + f.Value = &Timestamp{} + f.Value.SetLayout(f.Layout) + + if val, ok := flagFromEnvOrFile(f.EnvVars, f.FilePath); ok { + if err := f.Value.Set(val); err != nil { + return fmt.Errorf("could not parse %q as timestamp value for flag %s: %s", val, f.Name, err) + } + f.HasBeenSet = true + } + for _, name := range f.Names() { - f.Value.SetLayout(f.Layout) - set.Var(&f.Value, name, f.Usage) + set.Var(f.Value, name, f.Usage) } return nil } @@ -124,7 +145,7 @@ func (c *Context) Timestamp(name string) *time.Time { func lookupTimestamp(name string, set *flag.FlagSet) *time.Time { f := set.Lookup(name) if f != nil { - return (f.Value.(*timestampWrap)).Value() + return (f.Value.(*Timestamp)).Value() } return nil } From c62d7736ea411dab88efaf9bb7175454038a380f Mon Sep 17 00:00:00 2001 From: Martin Lees Date: Thu, 12 Dec 2019 17:31:41 +0100 Subject: [PATCH 3/9] fmt --- flag_float64.go | 4 ++-- flag_timestamp.go | 7 ++++--- help.go | 2 +- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/flag_float64.go b/flag_float64.go index 228554715a..31f06f35e5 100644 --- a/flag_float64.go +++ b/flag_float64.go @@ -18,11 +18,11 @@ type Float64Flag struct { Value float64 DefaultText string Destination *float64 - HasBeenSet bool + HasBeenSet bool } // IsSet returns whether or not the flag has been set through env or file -func (f *Float64Flag)IsSet() bool { +func (f *Float64Flag) IsSet() bool { return f.HasBeenSet } diff --git a/flag_timestamp.go b/flag_timestamp.go index 91b4e8724b..d24edcd7f2 100644 --- a/flag_timestamp.go +++ b/flag_timestamp.go @@ -8,9 +8,9 @@ import ( // Timestamp wrap to satisfy golang's flag interface. type Timestamp struct { - timestamp *time.Time + timestamp *time.Time hasBeenSet bool - layout string + layout string } // Timestamp constructor @@ -25,6 +25,7 @@ func (t *Timestamp) SetTimestamp(value time.Time) { t.hasBeenSet = true } } + // Set the timestamp string layout for future parsing func (t *Timestamp) SetLayout(layout string) { t.layout = layout @@ -66,7 +67,7 @@ type TimestampFlag struct { FilePath string Required bool Hidden bool - Layout string + Layout string Value *Timestamp DefaultText string HasBeenSet bool diff --git a/help.go b/help.go index aa5947d6e9..c1e974a481 100644 --- a/help.go +++ b/help.go @@ -138,7 +138,7 @@ func printFlagSuggestions(lastArg string, flags []Flag, writer io.Writer) { if bflag, ok := flag.(*BoolFlag); ok && bflag.Hidden { continue } - for _, name := range flag.Names(){ + for _, name := range flag.Names() { name = strings.TrimSpace(name) // this will get total count utf8 letters in flag name count := utf8.RuneCountInString(name) From 76ebb62d0216a11c92b2b4a5158aaabec8508c70 Mon Sep 17 00:00:00 2001 From: Martin Lees Date: Thu, 12 Dec 2019 17:40:18 +0100 Subject: [PATCH 4/9] fix flagTests loop --- flag_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/flag_test.go b/flag_test.go index 915108967a..0801cfb8fd 100644 --- a/flag_test.go +++ b/flag_test.go @@ -121,8 +121,8 @@ func TestFlagsFromEnv(t *testing.T) { a := App{ Flags: []Flag{test.flag}, Action: func(ctx *Context) error { - if !reflect.DeepEqual(ctx.value(test.flag.Names()[0]), test.output) { - t.Errorf("ex:%01d expected %q to be parsed as %#v, instead was %#v", i, test.input, test.output, ctx.value(test.flag.Names()[0])) + if !reflect.DeepEqual(ctx.Value(test.flag.Names()[0]), test.output) { + t.Errorf("ex:%01d expected %q to be parsed as %#v, instead was %#v", i, test.input, test.output, ctx.Value(test.flag.Names()[0])) } return nil }, From d2b7f68cf3114a2791169d79d9077d279cdd0a44 Mon Sep 17 00:00:00 2001 From: Martin Lees Date: Thu, 12 Dec 2019 18:14:08 +0100 Subject: [PATCH 5/9] Add more tests --- flag_test.go | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/flag_test.go b/flag_test.go index 0801cfb8fd..aaf3a6a86b 100644 --- a/flag_test.go +++ b/flag_test.go @@ -1704,3 +1704,32 @@ func TestTimestamp_set(t *testing.T) { t.Fatalf("hasBeenSet is not true after setting a time") } } + +func TestTimestampFlagApply(t *testing.T) { + expectedResult, _ := time.Parse(time.RFC3339, "2006-01-02T15:04:05Z") + fl := TimestampFlag{Name: "time", Aliases: []string{"t"}, Layout: time.RFC3339} + set := flag.NewFlagSet("test", 0) + _ = fl.Apply(set) + + err := set.Parse([]string{"--time", "2006-01-02T15:04:05Z"}) + expect(t, err, nil) + expect(t, *fl.Value.timestamp, expectedResult) +} + +func TestTimestampFlagApply_Fail_Parse_Wrong_Layout(t *testing.T) { + fl := TimestampFlag{Name: "time", Aliases: []string{"t"}, Layout: "randomlayout"} + set := flag.NewFlagSet("test", 0) + _ = fl.Apply(set) + + err := set.Parse([]string{"--time", "2006-01-02T15:04:05Z"}) + expect(t, err, fmt.Errorf("invalid value \"2006-01-02T15:04:05Z\" for flag -time: parsing time \"2006-01-02T15:04:05Z\" as \"randomlayout\": cannot parse \"2006-01-02T15:04:05Z\" as \"randomlayout\"")) +} + +func TestTimestampFlagApply_Fail_Parse_Wrong_Time(t *testing.T) { + fl := TimestampFlag{Name: "time", Aliases: []string{"t"}, Layout: "Jan 2, 2006 at 3:04pm (MST)"} + set := flag.NewFlagSet("test", 0) + _ = fl.Apply(set) + + err := set.Parse([]string{"--time", "2006-01-02T15:04:05Z"}) + expect(t, err, fmt.Errorf("invalid value \"2006-01-02T15:04:05Z\" for flag -time: parsing time \"2006-01-02T15:04:05Z\" as \"Jan 2, 2006 at 3:04pm (MST)\": cannot parse \"2006-01-02T15:04:05Z\" as \"Jan\"")) +} From d4715a44b9f1f3c71ead0ac405cac1caea8adce9 Mon Sep 17 00:00:00 2001 From: Martin Lees Date: Mon, 16 Dec 2019 12:06:39 +0100 Subject: [PATCH 6/9] timestampflag examples --- docs/v2/manual.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/v2/manual.md b/docs/v2/manual.md index 5e04d4ed15..0be9007d95 100644 --- a/docs/v2/manual.md +++ b/docs/v2/manual.md @@ -1364,6 +1364,8 @@ func main() { &cli.StringFlag{Name: "dance-move", Aliases: []string{"d"}}, &cli.StringSliceFlag{Name: "names", Aliases: []string{"N"}}, &cli.UintFlag{Name: "age"}, + &cli.TimestampFlag{Name: "meeting", Layout: "2006-01-02T15:04:05"}, + &cli.TimestampFlag{Name: "birthday", Layout: "2006-01-02"}, &cli.Uint64Flag{Name: "bigage"}, }, EnableBashCompletion: true, From 07a35024e7624cd89d075b3dba61f0602cf13d53 Mon Sep 17 00:00:00 2001 From: Martin Lees Date: Mon, 16 Dec 2019 15:12:42 +0100 Subject: [PATCH 7/9] put the manual in its own doc block --- docs/v2/manual.md | 37 +++++++++++++++++++++++++++++++++++++ go.mod | 1 + go.sum | 12 ++++++++++++ 3 files changed, 50 insertions(+) diff --git a/docs/v2/manual.md b/docs/v2/manual.md index 0be9007d95..8f66092b2d 100644 --- a/docs/v2/manual.md +++ b/docs/v2/manual.md @@ -1150,6 +1150,43 @@ The default version flag (`-v/--version`) is defined as `cli.VersionFlag`, which is checked by the cli internals in order to print the `App.Version` via `cli.VersionPrinter` and break execution. +### Timestamp Flag + +Using the timestamp flag is simple, You can look at time.Parse to get layout examples : https://golang.org/pkg/time/#example_Parse + + +``` go +package main + +import ( + "fmt" + "log" + "os" + + "github.com/urfave/cli/v2" +) + +func main() { + app := &cli.App{ + Flags: []cli.Flag { + &cli.TimestampFlag{Name: "meeting", Layout: "2006-01-02T15:04:05"}, + }, + Action: func(c *cli.Context) error { + fmt.Printf("%#v",c.Timestamp("meeting").String()) + return nil + }, + } + + err := app.Run(os.Args) + if err != nil { + log.Fatal(err) + } +} +``` + #### Customization The default flag may be customized to something other than `-v/--version` by diff --git a/go.mod b/go.mod index c38d41c14b..5c001dedd3 100644 --- a/go.mod +++ b/go.mod @@ -5,5 +5,6 @@ go 1.11 require ( github.com/BurntSushi/toml v0.3.1 github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d + github.com/urfave/gfmrun v1.2.14 // indirect gopkg.in/yaml.v2 v2.2.2 ) diff --git a/go.sum b/go.sum index ef121ff5db..f88b93675a 100644 --- a/go.sum +++ b/go.sum @@ -2,12 +2,24 @@ github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d h1:U+s90UTSYgptZMwQh2aRr3LuazLJIa+Pg3Kc1ylSYVY= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk= +github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= 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/russross/blackfriday/v2 v2.0.1 h1:lPqVAte+HuHNfhJ/0LC98ESWRz8afy9tM/0RK8m9o+Q= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= +github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4= +github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= +github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/urfave/cli/v2 v2.0.0/go.mod h1:SE9GqnLQmjVa0iPEY0f1w3ygNIYcIJ0OKPMoW2caLfQ= +github.com/urfave/gfmrun v1.2.14 h1:z8u4ikt3fWAAdMeeKjx/wX4AyFkNNLYcjaRQOUZ2FJk= +github.com/urfave/gfmrun v1.2.14/go.mod h1:ojqta1nGJf8QmY7bNdi2Q+9FjcvDosUokI6eiWrkDWg= +golang.org/x/sys v0.0.0-20190422165155-953cdadca894 h1:Cz4ceDQGXuKRnVBDTS23GTn/pU5OE2C0WrNTOYK1Uuc= +golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw= From 539d14a1e124f42e1cabda93095c6e89907661e8 Mon Sep 17 00:00:00 2001 From: Martin Lees Date: Mon, 16 Dec 2019 15:16:41 +0100 Subject: [PATCH 8/9] fix tests --- docs/v2/manual.md | 2 -- go.mod | 1 - go.sum | 12 ------------ 3 files changed, 15 deletions(-) diff --git a/docs/v2/manual.md b/docs/v2/manual.md index 8f66092b2d..5e54d6402a 100644 --- a/docs/v2/manual.md +++ b/docs/v2/manual.md @@ -1401,8 +1401,6 @@ func main() { &cli.StringFlag{Name: "dance-move", Aliases: []string{"d"}}, &cli.StringSliceFlag{Name: "names", Aliases: []string{"N"}}, &cli.UintFlag{Name: "age"}, - &cli.TimestampFlag{Name: "meeting", Layout: "2006-01-02T15:04:05"}, - &cli.TimestampFlag{Name: "birthday", Layout: "2006-01-02"}, &cli.Uint64Flag{Name: "bigage"}, }, EnableBashCompletion: true, diff --git a/go.mod b/go.mod index 5c001dedd3..c38d41c14b 100644 --- a/go.mod +++ b/go.mod @@ -5,6 +5,5 @@ go 1.11 require ( github.com/BurntSushi/toml v0.3.1 github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d - github.com/urfave/gfmrun v1.2.14 // indirect gopkg.in/yaml.v2 v2.2.2 ) diff --git a/go.sum b/go.sum index f88b93675a..ef121ff5db 100644 --- a/go.sum +++ b/go.sum @@ -2,24 +2,12 @@ github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d h1:U+s90UTSYgptZMwQh2aRr3LuazLJIa+Pg3Kc1ylSYVY= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= -github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk= -github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= 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/russross/blackfriday/v2 v2.0.1 h1:lPqVAte+HuHNfhJ/0LC98ESWRz8afy9tM/0RK8m9o+Q= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= -github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4= -github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= -github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= -github.com/urfave/cli/v2 v2.0.0/go.mod h1:SE9GqnLQmjVa0iPEY0f1w3ygNIYcIJ0OKPMoW2caLfQ= -github.com/urfave/gfmrun v1.2.14 h1:z8u4ikt3fWAAdMeeKjx/wX4AyFkNNLYcjaRQOUZ2FJk= -github.com/urfave/gfmrun v1.2.14/go.mod h1:ojqta1nGJf8QmY7bNdi2Q+9FjcvDosUokI6eiWrkDWg= -golang.org/x/sys v0.0.0-20190422165155-953cdadca894 h1:Cz4ceDQGXuKRnVBDTS23GTn/pU5OE2C0WrNTOYK1Uuc= -golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw= From dcbd0094dd1e0f8416d6169b0a137d0ab3b0fa9c Mon Sep 17 00:00:00 2001 From: Martin Lees Date: Wed, 18 Dec 2019 17:30:16 +0100 Subject: [PATCH 9/9] removal of timestamp flag doc --- docs/v2/manual.md | 37 ------------------------------------- 1 file changed, 37 deletions(-) diff --git a/docs/v2/manual.md b/docs/v2/manual.md index 5e54d6402a..5e04d4ed15 100644 --- a/docs/v2/manual.md +++ b/docs/v2/manual.md @@ -1150,43 +1150,6 @@ The default version flag (`-v/--version`) is defined as `cli.VersionFlag`, which is checked by the cli internals in order to print the `App.Version` via `cli.VersionPrinter` and break execution. -### Timestamp Flag - -Using the timestamp flag is simple, You can look at time.Parse to get layout examples : https://golang.org/pkg/time/#example_Parse - - -``` go -package main - -import ( - "fmt" - "log" - "os" - - "github.com/urfave/cli/v2" -) - -func main() { - app := &cli.App{ - Flags: []cli.Flag { - &cli.TimestampFlag{Name: "meeting", Layout: "2006-01-02T15:04:05"}, - }, - Action: func(c *cli.Context) error { - fmt.Printf("%#v",c.Timestamp("meeting").String()) - return nil - }, - } - - err := app.Run(os.Args) - if err != nil { - log.Fatal(err) - } -} -``` - #### Customization The default flag may be customized to something other than `-v/--version` by