From a8e44a8b5b1a75b1bfd95a46f809f9aba3ddb214 Mon Sep 17 00:00:00 2001 From: Zack Scholl Date: Thu, 17 Sep 2020 12:46:05 -0700 Subject: [PATCH 01/42] show only subcommand flags with bash completion --- help.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/help.go b/help.go index c1e974a..95ba188 100644 --- a/help.go +++ b/help.go @@ -164,9 +164,10 @@ func DefaultCompleteWithFlags(cmd *Command) func(c *Context) { if len(os.Args) > 2 { lastArg := os.Args[len(os.Args)-2] if strings.HasPrefix(lastArg, "-") { - printFlagSuggestions(lastArg, c.App.Flags, c.App.Writer) if cmd != nil { printFlagSuggestions(lastArg, cmd.Flags, c.App.Writer) + } else { + printFlagSuggestions(lastArg, c.App.Flags, c.App.Writer) } return } From ef9430e77eb1e7e05daecdfaa9ec75fa43b79e7e Mon Sep 17 00:00:00 2001 From: Ally Dale Date: Mon, 8 Feb 2021 20:10:28 +0800 Subject: [PATCH 02/42] fix #1238: accept multi-value input on sclice flags --- app_test.go | 34 ++++++++++++++++++++++++++++++ docs/v2/manual.md | 46 +++++++++++++++++++++++++++++++++++++++++ flag.go | 4 ++++ flag_float64_slice.go | 12 ++++++----- flag_int64_slice.go | 14 +++++++------ flag_int_slice.go | 14 +++++++------ flag_string_slice.go | 6 ++++-- flag_test.go | 48 +++++++++++++++++++++++++++++++++++++++++++ 8 files changed, 159 insertions(+), 19 deletions(-) diff --git a/app_test.go b/app_test.go index 7c38f60..0b8b4bf 100644 --- a/app_test.go +++ b/app_test.go @@ -390,6 +390,40 @@ func ExampleApp_Run_zshComplete() { // h:Shows a list of commands or help for one command } +func ExampleApp_Run_sliceValues() { + // set args for examples sake + 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", + } + app := NewApp() + app.Name = "multi_values" + app.Flags = []Flag{ + &StringSliceFlag{Name: "stringSclice"}, + &Float64SliceFlag{Name: "float64Sclice"}, + &Int64SliceFlag{Name: "int64Sclice"}, + &IntSliceFlag{Name: "intSclice"}, + } + app.Action = func(ctx *Context) error { + for i, v := range ctx.FlagNames() { + fmt.Printf("%d-%s %#v\n", i, v, ctx.Value(v)) + } + err := ctx.Err() + fmt.Println("error:", err) + return err + } + + _ = 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} + // error: +} + func TestApp_Run(t *testing.T) { s := "" diff --git a/docs/v2/manual.md b/docs/v2/manual.md index af09010..8f7cbbb 100644 --- a/docs/v2/manual.md +++ b/docs/v2/manual.md @@ -14,6 +14,7 @@ cli v2 manual + [Values from the Environment](#values-from-the-environment) + [Values from files](#values-from-files) + [Values from alternate input sources (YAML, TOML, and others)](#values-from-alternate-input-sources-yaml-toml-and-others) + + [Muti values](#multi-values) + [Required Flags](#required-flags) + [Default Values for help output](#default-values-for-help-output) + [Precedence](#precedence) @@ -660,6 +661,51 @@ func main() { } ``` +#### Multi values + +Slice flags(Float64SliceFlag, Int64SliceFlag, IntSliceFlag, StringSliceFlag) are designed to accept multi values. + +Here is a sample of setting multi values for slice flags: + + +``` +package main + +import ( + "fmt" + "os" + "github.com/urfave/cli/v2" +) + +func main() { + 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", + } + app := cli.NewApp() + app.Name = "multi_values" + app.Flags = []cli.Flag{ + &cli.StringSliceFlag{Name: "stringSclice"}, + &cli.Float64SliceFlag{Name: "float64Sclice"}, + &cli.Int64SliceFlag{Name: "int64Sclice"}, + &cli.IntSliceFlag{Name: "intSclice"}, + } + app.Action = func(ctx *cli.Context) error { + for i, v := range ctx.FlagNames() { + fmt.Printf("%d-%s %#v\n", i, v, ctx.Value(v)) + } + return ctx.Err() + } + + _ = app.Run(os.Args) +} + +``` + #### Required Flags You can make a flag required by setting the `Required` field to `true`. If a user diff --git a/flag.go b/flag.go index aff8d5b..bca41cc 100644 --- a/flag.go +++ b/flag.go @@ -390,3 +390,7 @@ func flagFromEnvOrFile(envVars []string, filePath string) (val string, ok bool) } return "", false } + +func flagSplitMultiValues(val string) []string { + return strings.Split(val, ",") +} diff --git a/flag_float64_slice.go b/flag_float64_slice.go index 706ee6c..8ee1204 100644 --- a/flag_float64_slice.go +++ b/flag_float64_slice.go @@ -33,12 +33,14 @@ func (f *Float64Slice) Set(value string) error { return nil } - tmp, err := strconv.ParseFloat(value, 64) - if err != nil { - return err - } + for _, s := range flagSplitMultiValues(value) { + tmp, err := strconv.ParseFloat(strings.TrimSpace(s), 64) + if err != nil { + return err + } - f.slice = append(f.slice, tmp) + f.slice = append(f.slice, tmp) + } return nil } diff --git a/flag_int64_slice.go b/flag_int64_slice.go index 2c9a15a..2edc3c6 100644 --- a/flag_int64_slice.go +++ b/flag_int64_slice.go @@ -33,12 +33,14 @@ func (i *Int64Slice) Set(value string) error { return nil } - tmp, err := strconv.ParseInt(value, 0, 64) - if err != nil { - return err - } + for _, s := range flagSplitMultiValues(value) { + tmp, err := strconv.ParseInt(strings.TrimSpace(s), 0, 64) + if err != nil { + return err + } - i.slice = append(i.slice, tmp) + i.slice = append(i.slice, tmp) + } return nil } @@ -123,7 +125,7 @@ func (f *Int64SliceFlag) Apply(set *flag.FlagSet) error { if val, ok := flagFromEnvOrFile(f.EnvVars, f.FilePath); ok { f.Value = &Int64Slice{} - for _, s := range strings.Split(val, ",") { + for _, s := range flagSplitMultiValues(val) { if err := f.Value.Set(strings.TrimSpace(s)); err != nil { return fmt.Errorf("could not parse %q as int64 slice value for flag %s: %s", val, f.Name, err) } diff --git a/flag_int_slice.go b/flag_int_slice.go index a73ca6b..8861649 100644 --- a/flag_int_slice.go +++ b/flag_int_slice.go @@ -44,12 +44,14 @@ func (i *IntSlice) Set(value string) error { return nil } - tmp, err := strconv.ParseInt(value, 0, 64) - if err != nil { - return err - } + for _, s := range flagSplitMultiValues(value) { + tmp, err := strconv.ParseInt(strings.TrimSpace(s), 0, 64) + if err != nil { + return err + } - i.slice = append(i.slice, int(tmp)) + i.slice = append(i.slice, int(tmp)) + } return nil } @@ -134,7 +136,7 @@ func (f *IntSliceFlag) Apply(set *flag.FlagSet) error { if val, ok := flagFromEnvOrFile(f.EnvVars, f.FilePath); ok { f.Value = &IntSlice{} - for _, s := range strings.Split(val, ",") { + for _, s := range flagSplitMultiValues(val) { if err := f.Value.Set(strings.TrimSpace(s)); err != nil { return fmt.Errorf("could not parse %q as int slice value for flag %s: %s", val, f.Name, err) } diff --git a/flag_string_slice.go b/flag_string_slice.go index 3549703..92ded57 100644 --- a/flag_string_slice.go +++ b/flag_string_slice.go @@ -32,7 +32,9 @@ func (s *StringSlice) Set(value string) error { return nil } - s.slice = append(s.slice, value) + for _, t := range flagSplitMultiValues(value) { + s.slice = append(s.slice, strings.TrimSpace(t)) + } return nil } @@ -132,7 +134,7 @@ func (f *StringSliceFlag) Apply(set *flag.FlagSet) error { destination = f.Destination } - for _, s := range strings.Split(val, ",") { + for _, s := range flagSplitMultiValues(val) { if err := destination.Set(strings.TrimSpace(s)); err != nil { return fmt.Errorf("could not parse %q as string value for flag %s: %s", val, f.Name, err) } diff --git a/flag_test.go b/flag_test.go index b3b0d7c..1afc631 100644 --- a/flag_test.go +++ b/flag_test.go @@ -1973,3 +1973,51 @@ func TestTimestampFlagApply_Fail_Parse_Wrong_Time(t *testing.T) { 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\"")) } + +type flagValueTestCase struct { + name string + flag Flag + toParse []string + expect string +} + +func TestFlagValue(t *testing.T) { + cases := []*flagValueTestCase{ + &flagValueTestCase{ + name: "stringSclice", + flag: &StringSliceFlag{Name: "flag", Value: NewStringSlice("default1", "default2")}, + toParse: []string{"--flag", "parsed,parsed2", "--flag", "parsed3,parsed4"}, + expect: `[parsed parsed2 parsed3 parsed4]`, + }, + &flagValueTestCase{ + name: "float64Sclice", + flag: &Float64SliceFlag{Name: "flag", Value: NewFloat64Slice(1.1, 2.2)}, + toParse: []string{"--flag", "13.3,14.4", "--flag", "15.5,16.6"}, + expect: `[]float64{13.3, 14.4, 15.5, 16.6}`, + }, + &flagValueTestCase{ + name: "int64Sclice", + flag: &Int64SliceFlag{Name: "flag", Value: NewInt64Slice(1, 2)}, + toParse: []string{"--flag", "13,14", "--flag", "15,16"}, + expect: `[]int64{13, 14, 15, 16}`, + }, + &flagValueTestCase{ + name: "intSclice", + flag: &IntSliceFlag{Name: "flag", Value: NewIntSlice(1, 2)}, + toParse: []string{"--flag", "13,14", "--flag", "15,16"}, + expect: `[]int{13, 14, 15, 16}`, + }, + } + for i, v := range cases { + set := flag.NewFlagSet("test", 0) + set.SetOutput(ioutil.Discard) + _ = v.flag.Apply(set) + if err := set.Parse(v.toParse); err != nil { + t.Error(err) + } + f := set.Lookup("flag") + if got := f.Value.String(); got != v.expect { + t.Errorf("TestFlagValue %d-%s\nexpect:%s\ngot:%s", i, v.name, v.expect, got) + } + } +} From 06f6815b8d881483b4ce75de2471fa7d2b724903 Mon Sep 17 00:00:00 2001 From: Ally Dale Date: Mon, 8 Feb 2021 22:41:34 +0800 Subject: [PATCH 03/42] revert docs/v2/manual.md --- docs/v2/manual.md | 46 ------------------------------------------- flag_float64_slice.go | 2 +- 2 files changed, 1 insertion(+), 47 deletions(-) diff --git a/docs/v2/manual.md b/docs/v2/manual.md index 8f7cbbb..af09010 100644 --- a/docs/v2/manual.md +++ b/docs/v2/manual.md @@ -14,7 +14,6 @@ cli v2 manual + [Values from the Environment](#values-from-the-environment) + [Values from files](#values-from-files) + [Values from alternate input sources (YAML, TOML, and others)](#values-from-alternate-input-sources-yaml-toml-and-others) - + [Muti values](#multi-values) + [Required Flags](#required-flags) + [Default Values for help output](#default-values-for-help-output) + [Precedence](#precedence) @@ -661,51 +660,6 @@ func main() { } ``` -#### Multi values - -Slice flags(Float64SliceFlag, Int64SliceFlag, IntSliceFlag, StringSliceFlag) are designed to accept multi values. - -Here is a sample of setting multi values for slice flags: - - -``` -package main - -import ( - "fmt" - "os" - "github.com/urfave/cli/v2" -) - -func main() { - 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", - } - app := cli.NewApp() - app.Name = "multi_values" - app.Flags = []cli.Flag{ - &cli.StringSliceFlag{Name: "stringSclice"}, - &cli.Float64SliceFlag{Name: "float64Sclice"}, - &cli.Int64SliceFlag{Name: "int64Sclice"}, - &cli.IntSliceFlag{Name: "intSclice"}, - } - app.Action = func(ctx *cli.Context) error { - for i, v := range ctx.FlagNames() { - fmt.Printf("%d-%s %#v\n", i, v, ctx.Value(v)) - } - return ctx.Err() - } - - _ = app.Run(os.Args) -} - -``` - #### Required Flags You can make a flag required by setting the `Required` field to `true`. If a user diff --git a/flag_float64_slice.go b/flag_float64_slice.go index 8ee1204..343c9b0 100644 --- a/flag_float64_slice.go +++ b/flag_float64_slice.go @@ -125,7 +125,7 @@ func (f *Float64SliceFlag) Apply(set *flag.FlagSet) error { if val != "" { f.Value = &Float64Slice{} - for _, s := range strings.Split(val, ",") { + for _, s := range flagSplitMultiValues(val) { if err := f.Value.Set(strings.TrimSpace(s)); err != nil { return fmt.Errorf("could not parse %q as float64 slice value for flag %s: %s", f.Value, f.Name, err) } From 50c71ed517bd28c3ead9b70ad8f13e668957f7b6 Mon Sep 17 00:00:00 2001 From: Naveen Gogineni Date: Sat, 27 Mar 2021 13:07:49 -0400 Subject: [PATCH 04/42] Remove reflect calls for doc generation --- flag.go | 60 +++++++++++++++---------------------------- flag_bool.go | 13 ++++++++++ flag_duration.go | 13 ++++++++++ flag_float64.go | 15 ++++++++++- flag_float64_slice.go | 15 ++++++++++- flag_generic.go | 13 ++++++++++ flag_int.go | 13 ++++++++++ flag_int64.go | 13 ++++++++++ flag_int64_slice.go | 15 ++++++++++- flag_int_slice.go | 15 ++++++++++- flag_path.go | 21 ++++++++++++++- flag_string.go | 21 ++++++++++++++- flag_string_slice.go | 15 ++++++++++- flag_timestamp.go | 13 ++++++++++ flag_uint.go | 13 ++++++++++ flag_uint64.go | 13 ++++++++++ 16 files changed, 234 insertions(+), 47 deletions(-) diff --git a/flag.go b/flag.go index 125c6ce..0d72662 100644 --- a/flag.go +++ b/flag.go @@ -117,6 +117,12 @@ type DocGenerationFlag interface { // GetValue returns the flags value as string representation and an empty // string if the flag takes no value at all. GetValue() string + + // GetDefaultText returns the default text for this flag + GetDefaultText() string + + // GetEnvVars returns the env vars for this flag + GetEnvVars() []string } // VisibleFlag is an interface that allows to check if a flag is visible @@ -299,55 +305,29 @@ func formatDefault(format string) string { } func stringifyFlag(f Flag) string { - fv := flagValue(f) - - switch f := f.(type) { - case *IntSliceFlag: - return withEnvHint(flagStringSliceField(f, "EnvVars"), - stringifyIntSliceFlag(f)) - case *Int64SliceFlag: - return withEnvHint(flagStringSliceField(f, "EnvVars"), - stringifyInt64SliceFlag(f)) - case *Float64SliceFlag: - return withEnvHint(flagStringSliceField(f, "EnvVars"), - stringifyFloat64SliceFlag(f)) - case *StringSliceFlag: - return withEnvHint(flagStringSliceField(f, "EnvVars"), - stringifyStringSliceFlag(f)) + // enforce DocGeneration interface on flags to avoid reflection + df, ok := f.(DocGenerationFlag) + if !ok { + return "" } - placeholder, usage := unquoteUsage(fv.FieldByName("Usage").String()) - - needsPlaceholder := false - defaultValueString := "" - val := fv.FieldByName("Value") - if val.IsValid() { - needsPlaceholder = val.Kind() != reflect.Bool - defaultValueString = fmt.Sprintf(formatDefault("%v"), val.Interface()) - - if val.Kind() == reflect.String && val.String() != "" { - defaultValueString = fmt.Sprintf(formatDefault("%q"), val.String()) - } - } - - helpText := fv.FieldByName("DefaultText") - if helpText.IsValid() && helpText.String() != "" { - needsPlaceholder = val.Kind() != reflect.Bool - defaultValueString = fmt.Sprintf(formatDefault("%s"), helpText.String()) - } - - if defaultValueString == formatDefault("") { - defaultValueString = "" - } + placeholder, usage := unquoteUsage(df.GetUsage()) + needsPlaceholder := df.TakesValue() if needsPlaceholder && placeholder == "" { placeholder = defaultPlaceholder } + defaultValueString := "" + + if s := df.GetDefaultText(); s != "" { + defaultValueString = fmt.Sprintf(formatDefault("%s"), s) + } + usageWithDefault := strings.TrimSpace(usage + defaultValueString) - return withEnvHint(flagStringSliceField(f, "EnvVars"), - fmt.Sprintf("%s\t%s", prefixedNames(f.Names(), placeholder), usageWithDefault)) + return withEnvHint(df.GetEnvVars(), + fmt.Sprintf("%s\t%s", prefixedNames(df.Names(), placeholder), usageWithDefault)) } func stringifyIntSliceFlag(f *IntSliceFlag) string { diff --git a/flag_bool.go b/flag_bool.go index 8bd5820..b8e625a 100644 --- a/flag_bool.go +++ b/flag_bool.go @@ -63,6 +63,19 @@ func (f *BoolFlag) IsVisible() bool { return !f.Hidden } +// GetDefaultText returns the default text for this flag +func (f *BoolFlag) GetDefaultText() string { + if f.DefaultText != "" { + return f.DefaultText + } + return fmt.Sprintf("%v", f.Value) +} + +// GetEnvVars returns the env vars for this flag +func (f *BoolFlag) GetEnvVars() []string { + return f.EnvVars +} + // Apply populates the flag given the flag set and environment func (f *BoolFlag) Apply(set *flag.FlagSet) error { if val, ok := flagFromEnvOrFile(f.EnvVars, f.FilePath); ok { diff --git a/flag_duration.go b/flag_duration.go index 28f3978..e8ca15e 100644 --- a/flag_duration.go +++ b/flag_duration.go @@ -63,6 +63,19 @@ func (f *DurationFlag) IsVisible() bool { return !f.Hidden } +// GetDefaultText returns the default text for this flag +func (f *DurationFlag) GetDefaultText() string { + if f.DefaultText != "" { + return f.DefaultText + } + return f.GetValue() +} + +// GetEnvVars returns the env vars for this flag +func (f *DurationFlag) GetEnvVars() []string { + return f.EnvVars +} + // Apply populates the flag given the flag set and environment func (f *DurationFlag) Apply(set *flag.FlagSet) error { if val, ok := flagFromEnvOrFile(f.EnvVars, f.FilePath); ok { diff --git a/flag_float64.go b/flag_float64.go index 10fb8df..e08e97f 100644 --- a/flag_float64.go +++ b/flag_float64.go @@ -55,7 +55,20 @@ func (f *Float64Flag) GetUsage() string { // GetValue returns the flags value as string representation and an empty // string if the flag takes no value at all. func (f *Float64Flag) GetValue() string { - return fmt.Sprintf("%f", f.Value) + return fmt.Sprintf("%v", f.Value) +} + +// GetDefaultText returns the default text for this flag +func (f *Float64Flag) GetDefaultText() string { + if f.DefaultText != "" { + return f.DefaultText + } + return f.GetValue() +} + +// GetEnvVars returns the env vars for this flag +func (f *Float64Flag) GetEnvVars() []string { + return f.EnvVars } // IsVisible returns true if the flag is not hidden, otherwise false diff --git a/flag_float64_slice.go b/flag_float64_slice.go index f752ad7..ecef6ee 100644 --- a/flag_float64_slice.go +++ b/flag_float64_slice.go @@ -95,7 +95,7 @@ func (f *Float64SliceFlag) IsSet() bool { // String returns a readable representation of this value // (for usage defaults) func (f *Float64SliceFlag) String() string { - return FlagStringer(f) + return withEnvHint(f.GetEnvVars(), stringifyFloat64SliceFlag(f)) } // Names returns the names of the flag @@ -132,6 +132,19 @@ func (f *Float64SliceFlag) IsVisible() bool { return !f.Hidden } +// GetDefaultText returns the default text for this flag +func (f *Float64SliceFlag) GetDefaultText() string { + if f.DefaultText != "" { + return f.DefaultText + } + return f.GetValue() +} + +// GetEnvVars returns the env vars for this flag +func (f *Float64SliceFlag) GetEnvVars() []string { + return f.EnvVars +} + // Apply populates the flag given the flag set and environment func (f *Float64SliceFlag) Apply(set *flag.FlagSet) error { if val, ok := flagFromEnvOrFile(f.EnvVars, f.FilePath); ok { diff --git a/flag_generic.go b/flag_generic.go index fdf586d..d159507 100644 --- a/flag_generic.go +++ b/flag_generic.go @@ -71,6 +71,19 @@ func (f *GenericFlag) IsVisible() bool { return !f.Hidden } +// GetDefaultText returns the default text for this flag +func (f *GenericFlag) GetDefaultText() string { + if f.DefaultText != "" { + return f.DefaultText + } + return f.GetValue() +} + +// GetEnvVars returns the env vars for this flag +func (f *GenericFlag) GetEnvVars() []string { + return f.EnvVars +} + // Apply takes the flagset and calls Set on the generic flag with the value // provided by the user for parsing by the flag func (f GenericFlag) Apply(set *flag.FlagSet) error { diff --git a/flag_int.go b/flag_int.go index 1ebe356..62c0848 100644 --- a/flag_int.go +++ b/flag_int.go @@ -63,6 +63,19 @@ func (f *IntFlag) IsVisible() bool { return !f.Hidden } +// GetDefaultText returns the default text for this flag +func (f *IntFlag) GetDefaultText() string { + if f.DefaultText != "" { + return f.DefaultText + } + return f.GetValue() +} + +// GetEnvVars returns the env vars for this flag +func (f *IntFlag) GetEnvVars() []string { + return f.EnvVars +} + // Apply populates the flag given the flag set and environment func (f *IntFlag) Apply(set *flag.FlagSet) error { if val, ok := flagFromEnvOrFile(f.EnvVars, f.FilePath); ok { diff --git a/flag_int64.go b/flag_int64.go index ecf0e9e..2f0be7a 100644 --- a/flag_int64.go +++ b/flag_int64.go @@ -63,6 +63,19 @@ func (f *Int64Flag) IsVisible() bool { return !f.Hidden } +// GetDefaultText returns the default text for this flag +func (f *Int64Flag) GetDefaultText() string { + if f.DefaultText != "" { + return f.DefaultText + } + return f.GetValue() +} + +// GetEnvVars returns the env vars for this flag +func (f *Int64Flag) GetEnvVars() []string { + return f.EnvVars +} + // Apply populates the flag given the flag set and environment func (f *Int64Flag) Apply(set *flag.FlagSet) error { if val, ok := flagFromEnvOrFile(f.EnvVars, f.FilePath); ok { diff --git a/flag_int64_slice.go b/flag_int64_slice.go index b4c8bc1..7995f44 100644 --- a/flag_int64_slice.go +++ b/flag_int64_slice.go @@ -96,7 +96,7 @@ func (f *Int64SliceFlag) IsSet() bool { // String returns a readable representation of this value // (for usage defaults) func (f *Int64SliceFlag) String() string { - return FlagStringer(f) + return withEnvHint(f.GetEnvVars(), stringifyInt64SliceFlag(f)) } // Names returns the names of the flag @@ -133,6 +133,19 @@ func (f *Int64SliceFlag) IsVisible() bool { return !f.Hidden } +// GetDefaultText returns the default text for this flag +func (f *Int64SliceFlag) GetDefaultText() string { + if f.DefaultText != "" { + return f.DefaultText + } + return f.GetValue() +} + +// GetEnvVars returns the env vars for this flag +func (f *Int64SliceFlag) GetEnvVars() []string { + return f.EnvVars +} + // Apply populates the flag given the flag set and environment func (f *Int64SliceFlag) Apply(set *flag.FlagSet) error { if val, ok := flagFromEnvOrFile(f.EnvVars, f.FilePath); ok { diff --git a/flag_int_slice.go b/flag_int_slice.go index d4889b3..8f5f1d5 100644 --- a/flag_int_slice.go +++ b/flag_int_slice.go @@ -107,7 +107,7 @@ func (f *IntSliceFlag) IsSet() bool { // String returns a readable representation of this value // (for usage defaults) func (f *IntSliceFlag) String() string { - return FlagStringer(f) + return withEnvHint(f.GetEnvVars(), stringifyIntSliceFlag(f)) } // Names returns the names of the flag @@ -144,6 +144,19 @@ func (f *IntSliceFlag) IsVisible() bool { return !f.Hidden } +// GetDefaultText returns the default text for this flag +func (f *IntSliceFlag) GetDefaultText() string { + if f.DefaultText != "" { + return f.DefaultText + } + return f.GetValue() +} + +// GetEnvVars returns the env vars for this flag +func (f *IntSliceFlag) GetEnvVars() []string { + return f.EnvVars +} + // Apply populates the flag given the flag set and environment func (f *IntSliceFlag) Apply(set *flag.FlagSet) error { if val, ok := flagFromEnvOrFile(f.EnvVars, f.FilePath); ok { diff --git a/flag_path.go b/flag_path.go index b3aa919..4010e84 100644 --- a/flag_path.go +++ b/flag_path.go @@ -1,6 +1,9 @@ package cli -import "flag" +import ( + "flag" + "fmt" +) type PathFlag struct { Name string @@ -59,6 +62,22 @@ func (f *PathFlag) IsVisible() bool { return !f.Hidden } +// GetDefaultText returns the default text for this flag +func (f *PathFlag) GetDefaultText() string { + if f.DefaultText != "" { + return f.DefaultText + } + if f.Value == "" { + return f.Value + } + return fmt.Sprintf("%q", f.Value) +} + +// GetEnvVars returns the env vars for this flag +func (f *PathFlag) GetEnvVars() []string { + return f.EnvVars +} + // Apply populates the flag given the flag set and environment func (f *PathFlag) Apply(set *flag.FlagSet) error { if val, ok := flagFromEnvOrFile(f.EnvVars, f.FilePath); ok { diff --git a/flag_string.go b/flag_string.go index e7bd412..7e81499 100644 --- a/flag_string.go +++ b/flag_string.go @@ -1,6 +1,9 @@ package cli -import "flag" +import ( + "flag" + "fmt" +) // StringFlag is a flag with type string type StringFlag struct { @@ -60,6 +63,22 @@ func (f *StringFlag) IsVisible() bool { return !f.Hidden } +// GetDefaultText returns the default text for this flag +func (f *StringFlag) GetDefaultText() string { + if f.DefaultText != "" { + return f.DefaultText + } + if f.Value == "" { + return f.Value + } + return fmt.Sprintf("%q", f.Value) +} + +// GetEnvVars returns the env vars for this flag +func (f *StringFlag) GetEnvVars() []string { + return f.EnvVars +} + // Apply populates the flag given the flag set and environment func (f *StringFlag) Apply(set *flag.FlagSet) error { if val, ok := flagFromEnvOrFile(f.EnvVars, f.FilePath); ok { diff --git a/flag_string_slice.go b/flag_string_slice.go index 5269643..1664247 100644 --- a/flag_string_slice.go +++ b/flag_string_slice.go @@ -92,7 +92,7 @@ func (f *StringSliceFlag) IsSet() bool { // String returns a readable representation of this value // (for usage defaults) func (f *StringSliceFlag) String() string { - return FlagStringer(f) + return withEnvHint(f.GetEnvVars(), stringifyStringSliceFlag(f)) } // Names returns the names of the flag @@ -129,6 +129,19 @@ func (f *StringSliceFlag) IsVisible() bool { return !f.Hidden } +// GetDefaultText returns the default text for this flag +func (f *StringSliceFlag) GetDefaultText() string { + if f.DefaultText != "" { + return f.DefaultText + } + return f.GetValue() +} + +// GetEnvVars returns the env vars for this flag +func (f *StringSliceFlag) GetEnvVars() []string { + return f.EnvVars +} + // Apply populates the flag given the flag set and environment func (f *StringSliceFlag) Apply(set *flag.FlagSet) error { diff --git a/flag_timestamp.go b/flag_timestamp.go index 7458a79..ed06418 100644 --- a/flag_timestamp.go +++ b/flag_timestamp.go @@ -119,6 +119,19 @@ func (f *TimestampFlag) IsVisible() bool { return !f.Hidden } +// GetDefaultText returns the default text for this flag +func (f *TimestampFlag) GetDefaultText() string { + if f.DefaultText != "" { + return f.DefaultText + } + return f.GetValue() +} + +// GetEnvVars returns the env vars for this flag +func (f *TimestampFlag) GetEnvVars() []string { + return f.EnvVars +} + // Apply populates the flag given the flag set and environment func (f *TimestampFlag) Apply(set *flag.FlagSet) error { if f.Layout == "" { diff --git a/flag_uint.go b/flag_uint.go index 23a70a7..dd10e1c 100644 --- a/flag_uint.go +++ b/flag_uint.go @@ -88,6 +88,19 @@ func (f *UintFlag) GetValue() string { return fmt.Sprintf("%d", f.Value) } +// GetDefaultText returns the default text for this flag +func (f *UintFlag) GetDefaultText() string { + if f.DefaultText != "" { + return f.DefaultText + } + return f.GetValue() +} + +// GetEnvVars returns the env vars for this flag +func (f *UintFlag) GetEnvVars() []string { + return f.EnvVars +} + // Uint looks up the value of a local UintFlag, returns // 0 if not found func (c *Context) Uint(name string) uint { diff --git a/flag_uint64.go b/flag_uint64.go index a2df024..017db53 100644 --- a/flag_uint64.go +++ b/flag_uint64.go @@ -88,6 +88,19 @@ func (f *Uint64Flag) GetValue() string { return fmt.Sprintf("%d", f.Value) } +// GetDefaultText returns the default text for this flag +func (f *Uint64Flag) GetDefaultText() string { + if f.DefaultText != "" { + return f.DefaultText + } + return f.GetValue() +} + +// GetEnvVars returns the env vars for this flag +func (f *Uint64Flag) GetEnvVars() []string { + return f.EnvVars +} + // Uint64 looks up the value of a local Uint64Flag, returns // 0 if not found func (c *Context) Uint64(name string) uint64 { From 7cd7ff7dd55db47593c1a5e45a4c8b8457851b87 Mon Sep 17 00:00:00 2001 From: Naveen Gogineni Date: Sun, 28 Mar 2021 18:34:30 -0400 Subject: [PATCH 05/42] Remove reflect from flag_test --- flag_test.go | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/flag_test.go b/flag_test.go index e46270d..d44214c 100644 --- a/flag_test.go +++ b/flag_test.go @@ -123,8 +123,13 @@ func TestFlagsFromEnv(t *testing.T) { for i, test := range flagTests { defer resetEnv(os.Environ()) os.Clearenv() - envVarSlice := reflect.Indirect(reflect.ValueOf(test.flag)).FieldByName("EnvVars").Slice(0, 1) - _ = os.Setenv(envVarSlice.Index(0).String(), test.input) + + f, ok := test.flag.(DocGenerationFlag) + if !ok { + t.Errorf("flag %v needs to implement DocGenerationFlag to retrieve env vars", test.flag) + } + envVarSlice := f.GetEnvVars() + _ = os.Setenv(envVarSlice[0], test.input) a := App{ Flags: []Flag{test.flag}, From 69366976476213a8da7b774588fe78167b75e15c Mon Sep 17 00:00:00 2001 From: Naveen Gogineni Date: Wed, 28 Apr 2021 21:00:51 -0400 Subject: [PATCH 06/42] Change min binary size --- internal/build/build.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/build/build.go b/internal/build/build.go index d0be855..a7bf0dd 100644 --- a/internal/build/build.go +++ b/internal/build/build.go @@ -193,7 +193,7 @@ func checkBinarySizeActionFunc(c *cli.Context) (err error) { cliBuiltFilePath = "./internal/example-cli/built-example" helloSourceFilePath = "./internal/example-hello-world/example-hello-world.go" helloBuiltFilePath = "./internal/example-hello-world/built-example" - desiredMinBinarySize = 1.9 + desiredMinBinarySize = 1.8 desiredMaxBinarySize = 2.1 badNewsEmoji = "🚨" goodNewsEmoji = "✨" From e7157a87d96483a94e51dc53f6db7c400a85f74d Mon Sep 17 00:00:00 2001 From: jolheiser Date: Mon, 18 Apr 2022 20:58:38 -0500 Subject: [PATCH 07/42] Exclude hidden sub-command flags from docs Signed-off-by: jolheiser --- docs.go | 4 ++-- docs_test.go | 5 +++++ fish.go | 2 +- 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/docs.go b/docs.go index 9f82fc6..e6f0265 100644 --- a/docs.go +++ b/docs.go @@ -80,14 +80,14 @@ func prepareCommands(commands []*Command, level int) []string { usageText, ) - flags := prepareArgsWithValues(command.Flags) + flags := prepareArgsWithValues(command.VisibleFlags()) if len(flags) > 0 { prepared += fmt.Sprintf("\n%s", strings.Join(flags, "\n")) } coms = append(coms, prepared) - // recursevly iterate subcommands + // recursively iterate subcommands if len(command.Subcommands) > 0 { coms = append( coms, diff --git a/docs_test.go b/docs_test.go index adccbbb..ad714e5 100644 --- a/docs_test.go +++ b/docs_test.go @@ -103,6 +103,11 @@ Should be a part of the same code block Aliases: []string{"s"}, Usage: "some usage text", }, + &StringFlag{ + Name: "sub-command-hidden-flag", + Usage: "some hidden usage text", + Hidden: true, + }, }, Name: "sub-usage", Usage: "standard usage text", diff --git a/fish.go b/fish.go index 588e070..eec3253 100644 --- a/fish.go +++ b/fish.go @@ -95,7 +95,7 @@ func (a *App) prepareFishCommands(commands []*Command, allCommands *[]string, pr completions = append(completions, completion.String()) completions = append( completions, - a.prepareFishFlags(command.Flags, command.Names())..., + a.prepareFishFlags(command.VisibleFlags(), command.Names())..., ) // recursevly iterate subcommands From 12b9c9d42002b6ad33e8572430ab446448c117fb Mon Sep 17 00:00:00 2001 From: Dan Buch Date: Tue, 19 Apr 2022 16:32:23 -0400 Subject: [PATCH 08/42] Bump matrix of supported Go versions to test on the latest release (^1.18) and drop testing/supporting ^1.15. --- .github/workflows/cli.yml | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/.github/workflows/cli.yml b/.github/workflows/cli.yml index e3b7a97..2752ec2 100644 --- a/.github/workflows/cli.yml +++ b/.github/workflows/cli.yml @@ -15,7 +15,7 @@ jobs: strategy: matrix: os: [ubuntu-latest, macos-latest, windows-latest] - go: [1.15, 1.16, 1.17] + go: [^1.16, ^1.17, ^1.18] name: ${{ matrix.os }} @ Go ${{ matrix.go }} runs-on: ${{ matrix.os }} steps: @@ -38,7 +38,7 @@ jobs: ref: ${{ github.ref }} - name: GOFMT Check - if: matrix.go == 1.17 && matrix.os == 'ubuntu-latest' + if: matrix.go == '^1.17' && matrix.os == 'ubuntu-latest' run: test -z $(gofmt -l .) - name: vet @@ -51,7 +51,7 @@ jobs: run: go run internal/build/build.go check-binary-size - name: Upload coverage to Codecov - if: success() && matrix.go == 1.17 && matrix.os == 'ubuntu-latest' + if: success() && matrix.go == '^1.17' && matrix.os == 'ubuntu-latest' uses: codecov/codecov-action@v1 with: fail_ci_if_error: true @@ -63,8 +63,7 @@ jobs: - name: Set up Go uses: actions/setup-go@v1 with: - # Currently fails on 1.16+ - go-version: 1.15 + go-version: ^1.18 - name: Use Node.js 12.x uses: actions/setup-node@v1 From e61b99e19a022a8db3ac0538518c781676f06362 Mon Sep 17 00:00:00 2001 From: Dan Buch Date: Tue, 19 Apr 2022 16:51:13 -0400 Subject: [PATCH 09/42] Add Stale bot configuration per docs with (greatly) extended values for `daysUntilStale` and `daysUntilClose` per suggestion. --- .github/stale.yml | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 .github/stale.yml diff --git a/.github/stale.yml b/.github/stale.yml new file mode 100644 index 0000000..f050e9b --- /dev/null +++ b/.github/stale.yml @@ -0,0 +1,17 @@ +# Number of days of inactivity before an issue becomes stale +daysUntilStale: 365 +# Number of days of inactivity before a stale issue is closed +daysUntilClose: 90 +# Issues with these labels will never be considered stale +exemptLabels: + - pinned + - security +# Label to use when marking an issue as stale +staleLabel: wontfix +# Comment to post when marking an issue as stale. Set to `false` to disable +markComment: > + This issue has been automatically marked as stale because it has not had + recent activity. It will be closed if no further activity occurs. Thank you + for your contributions. +# Comment to post when closing a stale issue. Set to `false` to disable +closeComment: false From d7bc33018bd2b0f391def3e9c31293d835747663 Mon Sep 17 00:00:00 2001 From: Dan Buch Date: Tue, 19 Apr 2022 16:57:25 -0400 Subject: [PATCH 10/42] Drop references/usage of GO111MODULE --- .github/workflows/cli.yml | 2 -- README.md | 4 ++-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/.github/workflows/cli.yml b/.github/workflows/cli.yml index e3b7a97..e803058 100644 --- a/.github/workflows/cli.yml +++ b/.github/workflows/cli.yml @@ -27,7 +27,6 @@ jobs: - name: Set GOPATH, PATH and ENV run: | echo "GOPATH=$(dirname $GITHUB_WORKSPACE)" >> $GITHUB_ENV - echo "GO111MODULE=on" >> $GITHUB_ENV echo "GOPROXY=https://proxy.golang.org" >> $GITHUB_ENV echo "$(dirname $GITHUB_WORKSPACE)/bin" >> $GITHUB_PATH shell: bash @@ -74,7 +73,6 @@ jobs: - name: Set GOPATH, PATH and ENV run: | echo "GOPATH=$(dirname $GITHUB_WORKSPACE)" >> $GITHUB_ENV - echo "GO111MODULE=on" >> $GITHUB_ENV echo "GOPROXY=https://proxy.golang.org" >> $GITHUB_ENV echo "$(dirname $GITHUB_WORKSPACE)/bin" >> $GITHUB_PATH shell: bash diff --git a/README.md b/README.md index 2b74f1f..eab7371 100644 --- a/README.md +++ b/README.md @@ -30,7 +30,7 @@ Go Modules are required when using this package. [See the go blog guide on using ### Using `v2` releases ``` -$ GO111MODULE=on go get github.com/urfave/cli/v2 +$ go get github.com/urfave/cli/v2 ``` ```go @@ -44,7 +44,7 @@ import ( ### Using `v1` releases ``` -$ GO111MODULE=on go get github.com/urfave/cli +$ go get github.com/urfave/cli ``` ```go From 17aa508d22ae7997bc9b650556f27caa0f24265c Mon Sep 17 00:00:00 2001 From: Dan Buch Date: Wed, 20 Apr 2022 14:38:32 -0400 Subject: [PATCH 11/42] Switch to gfmrun v1.3.0 --- .github/workflows/cli.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/cli.yml b/.github/workflows/cli.yml index 2752ec2..8edeb91 100644 --- a/.github/workflows/cli.yml +++ b/.github/workflows/cli.yml @@ -29,7 +29,7 @@ jobs: echo "GOPATH=$(dirname $GITHUB_WORKSPACE)" >> $GITHUB_ENV echo "GO111MODULE=on" >> $GITHUB_ENV echo "GOPROXY=https://proxy.golang.org" >> $GITHUB_ENV - echo "$(dirname $GITHUB_WORKSPACE)/bin" >> $GITHUB_PATH + echo "${GITHUB_WORKSPACE}/.local/bin" >> $GITHUB_PATH shell: bash - name: Checkout Code @@ -75,7 +75,7 @@ jobs: echo "GOPATH=$(dirname $GITHUB_WORKSPACE)" >> $GITHUB_ENV echo "GO111MODULE=on" >> $GITHUB_ENV echo "GOPROXY=https://proxy.golang.org" >> $GITHUB_ENV - echo "$(dirname $GITHUB_WORKSPACE)/bin" >> $GITHUB_PATH + echo "${GITHUB_WORKSPACE}/.local/bin" >> $GITHUB_PATH shell: bash - name: Checkout Code @@ -85,9 +85,9 @@ jobs: - name: Install Dependencies run: | - mkdir -p $GOPATH/bin - curl -L -o $GOPATH/bin/gfmrun "https://github.com/urfave/gfmrun/releases/download/v1.2.14/gfmrun-$(go env GOOS)-amd64-v1.2.14" - chmod +x $GOPATH/bin/gfmrun + mkdir -p "${GITHUB_WORKSPACE}/.local/bin" && \ + curl -fsSL -o "${GITHUB_WORKSPACE}/.local/bin/gfmrun" "https://github.com/urfave/gfmrun/releases/download/v1.3.0/gfmrun-$(go env GOOS)-$(go env goarch)-v1.3.0" && \ + chmod +x "${GITHUB_WORKSPACE}/.local/bin/gfmrun" && \ npm install -g markdown-toc@1.2.0 - name: Run Tests (v1) From 8c33a078d1fd99ad15144ff275f4cc767301b806 Mon Sep 17 00:00:00 2001 From: Dan Buch Date: Wed, 20 Apr 2022 14:41:26 -0400 Subject: [PATCH 12/42] Use `go env` correctly --- .github/workflows/cli.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/cli.yml b/.github/workflows/cli.yml index 8edeb91..480a4a0 100644 --- a/.github/workflows/cli.yml +++ b/.github/workflows/cli.yml @@ -86,7 +86,7 @@ jobs: - name: Install Dependencies run: | mkdir -p "${GITHUB_WORKSPACE}/.local/bin" && \ - curl -fsSL -o "${GITHUB_WORKSPACE}/.local/bin/gfmrun" "https://github.com/urfave/gfmrun/releases/download/v1.3.0/gfmrun-$(go env GOOS)-$(go env goarch)-v1.3.0" && \ + curl -fsSL -o "${GITHUB_WORKSPACE}/.local/bin/gfmrun" "https://github.com/urfave/gfmrun/releases/download/v1.3.0/gfmrun-$(go env GOOS)-$(go env GOARCH)-v1.3.0" && \ chmod +x "${GITHUB_WORKSPACE}/.local/bin/gfmrun" && \ npm install -g markdown-toc@1.2.0 From 5c6ccfb097f10c64582ed943d52d9cac21dd5106 Mon Sep 17 00:00:00 2001 From: Dan Buch Date: Wed, 20 Apr 2022 14:45:04 -0400 Subject: [PATCH 13/42] Add missing `"fmt"` import in example --- .gitignore | 1 + docs/v2/manual.md | 2 ++ 2 files changed, 3 insertions(+) diff --git a/.gitignore b/.gitignore index afdca41..e0c50ab 100644 --- a/.gitignore +++ b/.gitignore @@ -5,5 +5,6 @@ vendor .idea internal/*/built-example coverage.txt +/.local/ *.exe diff --git a/docs/v2/manual.md b/docs/v2/manual.md index 56be65b..b480dd6 100644 --- a/docs/v2/manual.md +++ b/docs/v2/manual.md @@ -674,8 +674,10 @@ Take for example this app that requires the `lang` flag: package main import ( + "fmt" "log" "os" + "github.com/urfave/cli/v2" ) From e63054a42e87bc5710b8911d8650f33f8cde2027 Mon Sep 17 00:00:00 2001 From: Dan Buch Date: Thu, 21 Apr 2022 15:07:45 -0400 Subject: [PATCH 14/42] Attempting to soften the barrier to entry and also removing issue title formatting that overlaps with label functionality --- .github/ISSUE_TEMPLATE/question.md | 8 ++-- .github/ISSUE_TEMPLATE/v1-bug-report.md | 39 +++++++++++++------- .github/ISSUE_TEMPLATE/v2-bug-report.md | 39 +++++++++++++------- .github/ISSUE_TEMPLATE/v2-feature-request.md | 16 +++++--- .github/pull_request_template.md | 13 +++++-- 5 files changed, 72 insertions(+), 43 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/question.md b/.github/ISSUE_TEMPLATE/question.md index bca4fea..b968075 100644 --- a/.github/ISSUE_TEMPLATE/question.md +++ b/.github/ISSUE_TEMPLATE/question.md @@ -1,12 +1,10 @@ --- name: ask a question -about: ask us question - assume stackoverflow's guidelines apply here -title: 'q: ( your question title goes here )' +about: ask a question - assume stackoverflow's guidelines apply here +title: your question title goes here labels: 'kind/question, status/triage, area/v2' assignees: '' --- -## my question is... - -_**( Put the question text here )**_ +my question is... diff --git a/.github/ISSUE_TEMPLATE/v1-bug-report.md b/.github/ISSUE_TEMPLATE/v1-bug-report.md index aabfe82..b37f40e 100644 --- a/.github/ISSUE_TEMPLATE/v1-bug-report.md +++ b/.github/ISSUE_TEMPLATE/v1-bug-report.md @@ -1,28 +1,32 @@ --- name: v1 bug report about: Create a report to help us fix v1 bugs -title: 'v1 bug: ( your bug title goes here )' +title: 'your bug title goes here' labels: 'kind/bug, status/triage, area/v1' assignees: '' --- -## my urfave/cli version is +## My urfave/cli version is _**( Put the version of urfave/cli that you are using here )**_ ## Checklist -* [ ] Are you running the latest v1 release? The list of releases is [here](https://github.com/urfave/cli/releases). -* [ ] Did you check the manual for your release? The v1 manual is [here](https://github.com/urfave/cli/blob/master/docs/v1/manual.md) -* [ ] Did you perform a search about this problem? Here's the [Github guide](https://help.github.com/en/github/managing-your-work-on-github/using-search-to-filter-issues-and-pull-requests) about searching. +- [ ] Are you running the latest v1 release? The list of releases is [here](https://github.com/urfave/cli/releases). +- [ ] Did you check the manual for your release? The v1 manual is [here](https://github.com/urfave/cli/blob/master/docs/v1/manual.md). +- [ ] Did you perform a search about this problem? Here's the [Github guide](https://help.github.com/en/github/managing-your-work-on-github/using-search-to-filter-issues-and-pull-requests) about searching. ## Dependency Management -- [ ] My project is using go modules. -- [ ] My project is using vendoring. -- [ ] My project is automatically downloading the latest version. -- [ ] I am unsure of what my dependency management setup is. + + +- My project is using go modules. +- My project is using vendoring. +- My project is automatically downloading the latest version. +- I am unsure of what my dependency management setup is. ## Describe the bug @@ -34,23 +38,30 @@ Describe the steps or code required to reproduce the behavior ## Observed behavior -What did you see happen immediately after the reproduction steps above? +What did you see happen immediately after the reproduction steps +above? ## Expected behavior -What would you have expected to happen immediately after the reproduction steps above? +What would you have expected to happen immediately after the +reproduction steps above? ## Additional context Add any other context about the problem here. -If the issue relates to a specific open source Github repo, please link that repo here. +If the issue relates to a specific open source Github repo, please +link that repo here. -If you can reproduce this issue with a public CI system, please link a failing build here. +If you can reproduce this issue with a public CI system, please +link a failing build here. ## Want to fix this yourself? -We'd love to have more contributors on this project! If the fix for this bug is easily explained and very small, free free to create a pull request for it. You'll want to base the PR off the `v1` branch, all `v1` bug fix releases will be made from that branch. +We'd love to have more contributors on this project! If the fix for +this bug is easily explained and very small, free free to create a +pull request for it. You'll want to base the PR off the `v1` +branch, all `v1` bug fix releases will be made from that branch. ## Run `go version` and paste its output here diff --git a/.github/ISSUE_TEMPLATE/v2-bug-report.md b/.github/ISSUE_TEMPLATE/v2-bug-report.md index 9944769..6561ebf 100644 --- a/.github/ISSUE_TEMPLATE/v2-bug-report.md +++ b/.github/ISSUE_TEMPLATE/v2-bug-report.md @@ -1,28 +1,32 @@ --- name: v2 bug report about: Create a report to help us fix v2 bugs -title: 'v2 bug: ( your bug title goes here )' +title: 'your bug title goes here' labels: 'kind/bug, area/v2, status/triage' assignees: '' --- -## my urfave/cli version is +## My urfave/cli version is _**( Put the version of urfave/cli that you are using here )**_ ## Checklist -* [ ] Are you running the latest v2 release? The list of releases is [here](https://github.com/urfave/cli/releases). -* [ ] Did you check the manual for your release? The v2 manual is [here](https://github.com/urfave/cli/blob/master/docs/v2/manual.md) -* [ ] Did you perform a search about this problem? Here's the [Github guide](https://help.github.com/en/github/managing-your-work-on-github/using-search-to-filter-issues-and-pull-requests) about searching. +- [ ] Are you running the latest v2 release? The list of releases is [here](https://github.com/urfave/cli/releases). +- [ ] Did you check the manual for your release? The v2 manual is [here](https://github.com/urfave/cli/blob/master/docs/v2/manual.md) +- [ ] Did you perform a search about this problem? Here's the [Github guide](https://help.github.com/en/github/managing-your-work-on-github/using-search-to-filter-issues-and-pull-requests) about searching. ## Dependency Management -- [ ] My project is using go modules. -- [ ] My project is using vendoring. -- [ ] My project is automatically downloading the latest version. -- [ ] I am unsure of what my dependency management setup is. + + +- My project is using go modules. +- My project is using vendoring. +- My project is automatically downloading the latest version. +- I am unsure of what my dependency management setup is. ## Describe the bug @@ -34,23 +38,30 @@ Describe the steps or code required to reproduce the behavior ## Observed behavior -What did you see happen immediately after the reproduction steps above? +What did you see happen immediately after the reproduction steps +above? ## Expected behavior -What would you have expected to happen immediately after the reproduction steps above? +What would you have expected to happen immediately after the +reproduction steps above? ## Additional context Add any other context about the problem here. -If the issue relates to a specific open source Github repo, please link that repo here. +If the issue relates to a specific open source Github repo, please +link that repo here. -If you can reproduce this issue with a public CI system, please link a failing build here. +If you can reproduce this issue with a public CI system, please +link a failing build here. ## Want to fix this yourself? -We'd love to have more contributors on this project! If the fix for this bug is easily explained and very small, free free to create a pull request for it. +We'd love to have more contributors on this project! If the fix for +this bug is easily explained and very small, free free to create a +pull request for it. + ## Run `go version` and paste its output here ``` diff --git a/.github/ISSUE_TEMPLATE/v2-feature-request.md b/.github/ISSUE_TEMPLATE/v2-feature-request.md index bc527b1..e830446 100644 --- a/.github/ISSUE_TEMPLATE/v2-feature-request.md +++ b/.github/ISSUE_TEMPLATE/v2-feature-request.md @@ -1,7 +1,7 @@ --- name: v2 feature request about: Suggest an improvement for v2 -title: 'v2 feature: ( your feature title goes here )' +title: 'your feature title goes here' labels: 'type/feature, area/v2, status/triage' assignees: '' @@ -10,16 +10,19 @@ assignees: '' ## Checklist * [ ] Are you running the latest v2 release? The list of releases is [here](https://github.com/urfave/cli/releases). -* [ ] Did you check the manual for your release? The v2 manual is [here](https://github.com/urfave/cli/blob/master/docs/v2/manual.md) +* [ ] Did you check the manual for your release? The v2 manual is [here](https://github.com/urfave/cli/blob/master/docs/v2/manual.md). * [ ] Did you perform a search about this feature? Here's the [Github guide](https://help.github.com/en/github/managing-your-work-on-github/using-search-to-filter-issues-and-pull-requests) about searching. ## What problem does this solve? A clear and concise description of what problem this feature would solve. For example: -- needing to type out the full flag name takes a long time, so I would like to suggest adding auto-complete -- I use (osx, windows, linux) and would like support for (some existing feature) to be extended to my platform -- the terminal output for a particular error case is confusing, and I think it could be improved +- needing to type out the full flag name takes a long time, so I + would like to suggest adding auto-complete +- I use (osx, windows, linux) and would like support for (some + existing feature) to be extended to my platform +- the terminal output for a particular error case is confusing, and + I think it could be improved ## Solution description @@ -27,4 +30,5 @@ A detailed description of what you want to happen. ## Describe alternatives you've considered -A clear and concise description of any alternative solutions or features you've considered. +A clear and concise description of any alternative solutions or +features you've considered. diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index 4e76725..47348f8 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -8,10 +8,14 @@ _(REQUIRED)_ -- [ ] bug -- [ ] cleanup -- [ ] documentation -- [ ] feature + + +- bug +- cleanup +- documentation +- feature ## What this PR does / why we need it: @@ -28,6 +32,7 @@ _(REQUIRED)_ ## Which issue(s) this PR fixes: _(REQUIRED)_ +