diff --git a/.github/workflows/01-golang-lint.yaml b/.github/workflows/01-golang-lint.yaml new file mode 100644 index 00000000..cff8143e --- /dev/null +++ b/.github/workflows/01-golang-lint.yaml @@ -0,0 +1,24 @@ +name: golangci-lint +on: + push: + tags: + - v* + branches: + - master + - main + pull_request: +permissions: + contents: read +jobs: + golangci: + name: lint + runs-on: ubuntu-latest + steps: + - uses: actions/setup-go@v4 + with: + go-version: stable + - uses: actions/checkout@v3 + - name: golangci-lint + uses: golangci/golangci-lint-action@v3 + with: + version: latest diff --git a/.golangci.yml b/.golangci.yml new file mode 100644 index 00000000..99192466 --- /dev/null +++ b/.golangci.yml @@ -0,0 +1,39 @@ +linters-settings: + govet: + check-shadowing: true + maligned: + suggest-new: true + dupl: + threshold: 200 + goconst: + min-len: 3 + min-occurrences: 2 + #forbidigo: + # forbid: + # - ^print.*$ + # - 'fmt\.Print.*' + gocognit: + min-complexity: 61 # This is a rather high value. We should gradually lower it to 30-40. + +linters: + enable: + - gofmt + - goimports + - bodyclose + - dupl + - gocognit + - gocritic + - goimports + - gosec + - nakedret + #- nolintlint + - revive + - stylecheck + - unconvert + - unparam + disable: + - forbidigo + - maligned + - lll + - gochecknoinits + - gochecknoglobals diff --git a/bool_slice_test.go b/bool_slice_test.go index 3c5a274f..a30fb6cf 100644 --- a/bool_slice_test.go +++ b/bool_slice_test.go @@ -42,10 +42,11 @@ func TestBS(t *testing.T) { vals := []string{"1", "F", "TRUE", "0"} arg := fmt.Sprintf("--bs=%s", strings.Join(vals, ",")) - err := f.Parse([]string{arg}) - if err != nil { - t.Fatal("expected no error; got", err) + erp := f.Parse([]string{arg}) + if erp != nil { + t.Fatal("expected no error; got", erp) } + for i, v := range bs { b, err := strconv.ParseBool(vals[i]) if err != nil { @@ -55,10 +56,12 @@ func TestBS(t *testing.T) { t.Fatalf("expected is[%d] to be %s but got: %t", i, vals[i], v) } } - getBS, err := f.GetBoolSlice("bs") - if err != nil { - t.Fatalf("got error: %v", err) + + getBS, erb := f.GetBoolSlice("bs") + if erb != nil { + t.Fatalf("got error: %v", erb) } + for i, v := range getBS { b, err := strconv.ParseBool(vals[i]) if err != nil { @@ -76,10 +79,11 @@ func TestBSDefault(t *testing.T) { vals := []string{"false", "T"} - err := f.Parse([]string{}) - if err != nil { - t.Fatal("expected no error; got", err) + erp := f.Parse([]string{}) + if erp != nil { + t.Fatal("expected no error; got", erp) } + for i, v := range bs { b, err := strconv.ParseBool(vals[i]) if err != nil { @@ -90,10 +94,11 @@ func TestBSDefault(t *testing.T) { } } - getBS, err := f.GetBoolSlice("bs") - if err != nil { - t.Fatal("got an error from GetBoolSlice():", err) + getBS, erb := f.GetBoolSlice("bs") + if erb != nil { + t.Fatal("got an error from GetBoolSlice():", erb) } + for i, v := range getBS { b, err := strconv.ParseBool(vals[i]) if err != nil { @@ -111,10 +116,11 @@ func TestBSWithDefault(t *testing.T) { vals := []string{"FALSE", "1"} arg := fmt.Sprintf("--bs=%s", strings.Join(vals, ",")) - err := f.Parse([]string{arg}) - if err != nil { - t.Fatal("expected no error; got", err) + erp := f.Parse([]string{arg}) + if erp != nil { + t.Fatal("expected no error; got", erp) } + for i, v := range bs { b, err := strconv.ParseBool(vals[i]) if err != nil { @@ -125,10 +131,11 @@ func TestBSWithDefault(t *testing.T) { } } - getBS, err := f.GetBoolSlice("bs") - if err != nil { - t.Fatal("got an error from GetBoolSlice():", err) + getBS, erb := f.GetBoolSlice("bs") + if erb != nil { + t.Fatal("got an error from GetBoolSlice():", erb) } + for i, v := range getBS { b, err := strconv.ParseBool(vals[i]) if err != nil { diff --git a/bool_test.go b/bool_test.go index a4319e79..e3704fcd 100644 --- a/bool_test.go +++ b/bool_test.go @@ -26,7 +26,7 @@ func (v *triStateValue) IsBoolFlag() bool { } func (v *triStateValue) Get() interface{} { - return triStateValue(*v) + return *v } func (v *triStateValue) Set(s string) error { diff --git a/bytes_test.go b/bytes_test.go index 5251f347..314ace28 100644 --- a/bytes_test.go +++ b/bytes_test.go @@ -52,14 +52,15 @@ func TestBytesHex(t *testing.T) { for _, arg := range args { err := f.Parse([]string{arg}) - if err != nil && tc.success == true { + switch { + case err != nil && tc.success: t.Errorf("expected success, got %q", err) continue - } else if err == nil && tc.success == false { + case err == nil && !tc.success: // bytesHex, err := f.GetBytesHex("bytes") t.Errorf("expected failure while processing %q", tc.input) continue - } else if tc.success { + case tc.success: bytesHex, err := f.GetBytesHex("bytes") if err != nil { t.Errorf("Got error trying to fetch the 'bytes' flag: %v", err) @@ -113,14 +114,15 @@ func TestBytesBase64(t *testing.T) { for _, arg := range args { err := f.Parse([]string{arg}) - if err != nil && tc.success == true { + switch { + case err != nil && tc.success: t.Errorf("expected success, got %q", err) continue - } else if err == nil && tc.success == false { + case err == nil && !tc.success: // bytesBase64, err := f.GetBytesBase64("bytes") t.Errorf("expected failure while processing %q", tc.input) continue - } else if tc.success { + case tc.success: bytesBase64, err := f.GetBytesBase64("bytes") if err != nil { t.Errorf("Got error trying to fetch the 'bytes' flag: %v", err) diff --git a/count.go b/count.go index a0b2679f..5d659e52 100644 --- a/count.go +++ b/count.go @@ -13,7 +13,7 @@ func newCountValue(val int, p *int) *countValue { func (i *countValue) Set(s string) error { // "+1" means that no specific value was passed, so increment if s == "+1" { - *i = countValue(*i + 1) + *i++ return nil } v, err := strconv.ParseInt(s, 0, 0) diff --git a/count_test.go b/count_test.go index 3785d375..68468044 100644 --- a/count_test.go +++ b/count_test.go @@ -37,13 +37,14 @@ func TestCount(t *testing.T) { tc := &testCases[i] err := f.Parse(tc.input) - if err != nil && tc.success == true { - t.Errorf("expected success, got %q", err) + switch { + case err != nil && tc.success: + t.Errorf("expected success with %q, got %q", tc.input, err) continue - } else if err == nil && tc.success == false { - t.Errorf("expected failure, got success") + case err == nil && !tc.success: + t.Errorf("expected failure with %q, got success", tc.input) continue - } else if tc.success { + case tc.success: c, err := f.GetCount("verbose") if err != nil { t.Errorf("Got error trying to fetch the counter flag") diff --git a/duration_slice.go b/duration_slice.go index badadda5..ee987274 100644 --- a/duration_slice.go +++ b/duration_slice.go @@ -1,7 +1,6 @@ package pflag import ( - "fmt" "strings" "time" ) @@ -46,7 +45,7 @@ func (s *durationSliceValue) Type() string { func (s *durationSliceValue) String() string { out := make([]string, len(*s.value)) for i, d := range *s.value { - out[i] = fmt.Sprintf("%s", d) + out[i] = d.String() } return "[" + strings.Join(out, ",") + "]" } @@ -56,7 +55,7 @@ func (s *durationSliceValue) fromString(val string) (time.Duration, error) { } func (s *durationSliceValue) toString(val time.Duration) string { - return fmt.Sprintf("%s", val) + return val.String() } func (s *durationSliceValue) Append(val string) error { diff --git a/duration_slice_test.go b/duration_slice_test.go index 651fbd8b..cb5e3444 100644 --- a/duration_slice_test.go +++ b/duration_slice_test.go @@ -46,10 +46,11 @@ func TestDS(t *testing.T) { vals := []string{"1ns", "2ms", "3m", "4h"} arg := fmt.Sprintf("--ds=%s", strings.Join(vals, ",")) - err := f.Parse([]string{arg}) - if err != nil { - t.Fatal("expected no error; got", err) + erp := f.Parse([]string{arg}) + if erp != nil { + t.Fatal("expected no error; got", erp) } + for i, v := range ds { d, err := time.ParseDuration(vals[i]) if err != nil { @@ -59,10 +60,12 @@ func TestDS(t *testing.T) { t.Fatalf("expected ds[%d] to be %s but got: %d", i, vals[i], v) } } - getDS, err := f.GetDurationSlice("ds") - if err != nil { - t.Fatalf("got error: %v", err) + + getDS, erd := f.GetDurationSlice("ds") + if erd != nil { + t.Fatalf("got error: %v", erd) } + for i, v := range getDS { d, err := time.ParseDuration(vals[i]) if err != nil { @@ -80,10 +83,11 @@ func TestDSDefault(t *testing.T) { vals := []string{"0s", "1ns"} - err := f.Parse([]string{}) - if err != nil { - t.Fatal("expected no error; got", err) + erp := f.Parse([]string{}) + if erp != nil { + t.Fatal("expected no error; got", erp) } + for i, v := range ds { d, err := time.ParseDuration(vals[i]) if err != nil { @@ -94,10 +98,11 @@ func TestDSDefault(t *testing.T) { } } - getDS, err := f.GetDurationSlice("ds") - if err != nil { - t.Fatal("got an error from GetDurationSlice():", err) + getDS, erd := f.GetDurationSlice("ds") + if erd != nil { + t.Fatal("got an error from GetDurationSlice():", erd) } + for i, v := range getDS { d, err := time.ParseDuration(vals[i]) if err != nil { @@ -115,10 +120,11 @@ func TestDSWithDefault(t *testing.T) { vals := []string{"1ns", "2ns"} arg := fmt.Sprintf("--ds=%s", strings.Join(vals, ",")) - err := f.Parse([]string{arg}) - if err != nil { - t.Fatal("expected no error; got", err) + erp := f.Parse([]string{arg}) + if erp != nil { + t.Fatal("expected no error; got", erp) } + for i, v := range ds { d, err := time.ParseDuration(vals[i]) if err != nil { @@ -129,10 +135,11 @@ func TestDSWithDefault(t *testing.T) { } } - getDS, err := f.GetDurationSlice("ds") - if err != nil { - t.Fatal("got an error from GetDurationSlice():", err) + getDS, erd := f.GetDurationSlice("ds") + if erd != nil { + t.Fatal("got an error from GetDurationSlice():", erd) } + for i, v := range getDS { d, err := time.ParseDuration(vals[i]) if err != nil { @@ -180,6 +187,7 @@ func TestDSCalledTwice(t *testing.T) { if err != nil { t.Fatal("expected no error; got", err) } + for i, v := range ds { if expected[i] != v { t.Fatalf("expected ds[%d] to be %d but got: %d", i, expected[i], v) diff --git a/flag.go b/flag.go index 7c058de3..4121521e 100644 --- a/flag.go +++ b/flag.go @@ -27,23 +27,32 @@ unaffected. Define flags using flag.String(), Bool(), Int(), etc. This declares an integer flag, -flagname, stored in the pointer ip, with type *int. + var ip = flag.Int("flagname", 1234, "help message for flagname") + If you like, you can bind the flag to a variable using the Var() functions. + var flagvar int func init() { flag.IntVar(&flagvar, "flagname", 1234, "help message for flagname") } + Or you can create custom flags that satisfy the Value interface (with pointer receivers) and couple them to flag parsing by + flag.Var(&flagVal, "name", "help message for flagname") + For such flags, the default value is just the initial value of the variable. After all flags are defined, call + flag.Parse() + to parse the command line into the defined flags. Flags may then be used directly. If you're using the flags themselves, they are all pointers; if you bind to variables, they're values. + fmt.Println("ip has value ", *ip) fmt.Println("flagvar has value ", flagvar) @@ -54,22 +63,26 @@ The arguments are indexed from 0 through flag.NArg()-1. The pflag package also defines some new functions that are not in flag, that give one-letter shorthands for flags. You can use these by appending 'P' to the name of any function that defines a flag. + var ip = flag.IntP("flagname", "f", 1234, "help message") var flagvar bool func init() { flag.BoolVarP(&flagvar, "boolname", "b", true, "help message") } flag.VarP(&flagval, "varname", "v", "help message") + Shorthand letters can be used with single dashes on the command line. Boolean shorthand flags can be combined with other shorthand flags. Command line flag syntax: + --flag // boolean flags only --flag=x Unlike the flag package, a single dash before an option means something different than a double dash. Single dashes signify a series of shorthand letters for flags. All but the last shorthand letter must be boolean flags. + // boolean flags -f -abc @@ -365,7 +378,7 @@ func (f *FlagSet) ShorthandLookup(name string) *Flag { } if len(name) > 1 { msg := fmt.Sprintf("can not look up shorthand which is more than one ASCII character: %q", name) - fmt.Fprintf(f.Output(), msg) + fmt.Fprintln(f.Output(), msg) panic(msg) } c := name[0] @@ -606,7 +619,7 @@ func UnquoteUsage(flag *Flag) (name string, usage string) { name = "bools" } - return + return name, usage } // Splits the string `s` on whitespace into an initial substring up to @@ -634,7 +647,7 @@ func wrapN(i, slop int, s string) (string, string) { // caller). Pass `w` == 0 to do no wrapping func wrap(i, w int, s string) string { if w == 0 { - return strings.Replace(s, "\n", "\n"+strings.Repeat(" ", i), -1) + return strings.ReplaceAll(s, "\n", "\n"+strings.Repeat(" ", i)) } // space between indent i and end of line width w into which @@ -652,26 +665,26 @@ func wrap(i, w int, s string) string { } // If still not enough space then don't even try to wrap. if wrap < 24 { - return strings.Replace(s, "\n", r, -1) + return strings.ReplaceAll(s, "\n", r) } // Try to avoid short orphan words on the final line, by // allowing wrapN to go a bit over if that would fit in the // remainder of the line. slop := 5 - wrap = wrap - slop + wrap -= slop // Handle first line, which is indented by the caller (or the // special case above) l, s = wrapN(wrap, slop, s) - r = r + strings.Replace(l, "\n", "\n"+strings.Repeat(" ", i), -1) + r += strings.ReplaceAll(l, "\n", "\n"+strings.Repeat(" ", i)) // Now wrap the rest for s != "" { var t string t, s = wrapN(wrap, slop, s) - r = r + "\n" + strings.Repeat(" ", i) + strings.Replace(t, "\n", "\n"+strings.Repeat(" ", i), -1) + r = r + "\n" + strings.Repeat(" ", i) + strings.ReplaceAll(t, "\n", "\n"+strings.Repeat(" ", i)) } return r @@ -867,7 +880,7 @@ func (f *FlagSet) AddFlag(flag *Flag) { } if len(flag.Shorthand) > 1 { msg := fmt.Sprintf("%q shorthand is more than one ASCII character", flag.Shorthand) - fmt.Fprintf(f.Output(), msg) + fmt.Fprintln(f.Output(), msg) panic(msg) } if f.shorthands == nil { @@ -877,7 +890,7 @@ func (f *FlagSet) AddFlag(flag *Flag) { used, alreadyThere := f.shorthands[c] if alreadyThere { msg := fmt.Sprintf("unable to redefine %q shorthand in %q flagset: it's already used for %q flag", c, f.name, used.Name) - fmt.Fprintf(f.Output(), msg) + fmt.Fprintln(f.Output(), msg) panic(msg) } f.shorthands[c] = flag @@ -925,18 +938,19 @@ func (f *FlagSet) failf(format string, a ...interface{}) error { // usage calls the Usage method for the flag set, or the usage function if // the flag set is CommandLine. func (f *FlagSet) usage() { - if f == CommandLine { + switch { + case f == CommandLine: Usage() - } else if f.Usage == nil { + case f.Usage == nil: defaultUsage(f) - } else { + default: f.Usage() } } -//--unknown (args will be empty) -//--unknown --next-flag ... (args will be --next-flag ...) -//--unknown arg ... (args will be arg ...) +// --unknown (args will be empty) +// --unknown --next-flag ... (args will be --next-flag ...) +// --unknown arg ... (args will be arg ...) func stripUnknownFlagValue(args []string) []string { if len(args) == 0 { //--unknown @@ -961,7 +975,8 @@ func (f *FlagSet) parseLongArg(s string, args []string, fn parseFunc) (a []strin name := s[2:] if len(name) == 0 || name[0] == '-' || name[0] == '=' { err = f.failf("bad flag syntax: %s", s) - return + + return a, err } split := strings.SplitN(name, "=", 2) @@ -983,39 +998,43 @@ func (f *FlagSet) parseLongArg(s string, args []string, fn parseFunc) (a []strin return stripUnknownFlagValue(a), nil default: err = f.failf("unknown flag: --%s", name) - return + + return a, err } } var value string - if len(split) == 2 { + switch { + case len(split) == 2: // '--flag=arg' value = split[1] - } else if flag.NoOptDefVal != "" { + case flag.NoOptDefVal != "": // '--flag' (arg was optional) value = flag.NoOptDefVal - } else if len(a) > 0 { + case len(a) > 0: // '--flag arg' value = a[0] a = a[1:] - } else { + default: // '--flag' (arg was required) err = f.failf("flag needs an argument: %s", s) - return + + return a, err } err = fn(flag, value) if err != nil { - f.failf(err.Error()) + _ = f.failf(err.Error()) } - return + + return a, err } func (f *FlagSet) parseSingleShortArg(shorthands string, args []string, fn parseFunc) (outShorts string, outArgs []string, err error) { outArgs = args if strings.HasPrefix(shorthands, "test.") { - return + return "", outArgs, nil } outShorts = shorthands[1:] @@ -1026,44 +1045,44 @@ func (f *FlagSet) parseSingleShortArg(shorthands string, args []string, fn parse switch { case c == 'h': f.usage() - err = ErrHelp - return + + return "", outArgs, ErrHelp case f.ParseErrorsWhitelist.UnknownFlags: // '-f=arg arg ...' // we do not want to lose arg in this case if len(shorthands) > 2 && shorthands[1] == '=' { - outShorts = "" - return + + return "", outArgs, nil } outArgs = stripUnknownFlagValue(outArgs) - return + + return outShorts, outArgs, err default: - err = f.failf("unknown shorthand flag: %q in -%s", c, shorthands) - return + return outShorts, outArgs, f.failf("unknown shorthand flag: %q in -%s", c, shorthands) } } var value string - if len(shorthands) > 2 && shorthands[1] == '=' { + switch { + case len(shorthands) > 2 && shorthands[1] == '=': // '-f=arg' value = shorthands[2:] outShorts = "" - } else if flag.NoOptDefVal != "" { + case flag.NoOptDefVal != "": // '-f' (arg was optional) value = flag.NoOptDefVal - } else if len(shorthands) > 1 { + case len(shorthands) > 1: // '-farg' value = shorthands[1:] outShorts = "" - } else if len(args) > 0 { + case len(args) > 0: // '-f arg' value = args[0] outArgs = args[1:] - } else { + default: // '-f' (arg was required) - err = f.failf("flag needs an argument: %q in -%s", c, shorthands) - return + return outShorts, outArgs, f.failf("flag needs an argument: %q in -%s", c, shorthands) } if flag.ShorthandDeprecated != "" { @@ -1072,9 +1091,10 @@ func (f *FlagSet) parseSingleShortArg(shorthands string, args []string, fn parse err = fn(flag, value) if err != nil { - f.failf(err.Error()) + _ = f.failf(err.Error()) } - return + + return outShorts, outArgs, err } func (f *FlagSet) parseShortArg(s string, args []string, fn parseFunc) (a []string, err error) { @@ -1085,24 +1105,27 @@ func (f *FlagSet) parseShortArg(s string, args []string, fn parseFunc) (a []stri for len(shorthands) > 0 { shorthands, a, err = f.parseSingleShortArg(shorthands, args, fn) if err != nil { - return + return a, err } } - return + return a, nil } func (f *FlagSet) parseArgs(args []string, fn parseFunc) (err error) { for len(args) > 0 { s := args[0] args = args[1:] + if len(s) == 0 || s[0] != '-' || len(s) == 1 { if !f.interspersed { f.args = append(f.args, s) f.args = append(f.args, args...) + return nil } f.args = append(f.args, s) + continue } @@ -1110,6 +1133,7 @@ func (f *FlagSet) parseArgs(args []string, fn parseFunc) (err error) { if len(s) == 2 { // "--" terminates the flags f.argsLenAtDash = len(f.args) f.args = append(f.args, args...) + break } args, err = f.parseLongArg(s, args, fn) @@ -1117,10 +1141,11 @@ func (f *FlagSet) parseArgs(args []string, fn parseFunc) (err error) { args, err = f.parseShortArg(s, args, fn) } if err != nil { - return + return err } } - return + + return nil } // Parse parses flag definitions from the argument list, which should not @@ -1130,15 +1155,11 @@ func (f *FlagSet) parseArgs(args []string, fn parseFunc) (err error) { func (f *FlagSet) Parse(arguments []string) error { if f.addedGoFlagSets != nil { for _, goFlagSet := range f.addedGoFlagSets { - goFlagSet.Parse(nil) + _ = goFlagSet.Parse(nil) } } f.parsed = true - if len(arguments) < 0 { - return nil - } - f.args = make([]string, 0, len(arguments)) set := func(flag *Flag, value string) error { @@ -1157,6 +1178,7 @@ func (f *FlagSet) Parse(arguments []string) error { panic(err) } } + return nil } @@ -1194,7 +1216,7 @@ func (f *FlagSet) Parsed() bool { // after all flags are defined and before flags are accessed by the program. func Parse() { // Ignore errors; CommandLine is set for ExitOnError. - CommandLine.Parse(os.Args[1:]) + _ = CommandLine.Parse(os.Args[1:]) } // ParseAll parses the command-line flags from os.Args[1:] and called fn for each. @@ -1202,7 +1224,7 @@ func Parse() { // defined and before flags are accessed by the program. func ParseAll(fn func(flag *Flag, value string) error) { // Ignore errors; CommandLine is set for ExitOnError. - CommandLine.ParseAll(os.Args[1:], fn) + _ = CommandLine.ParseAll(os.Args[1:], fn) } // SetInterspersed sets whether to support interspersed option/non-option arguments. diff --git a/flag_test.go b/flag_test.go index 58a5d25a..e49bce30 100644 --- a/flag_test.go +++ b/flag_test.go @@ -20,18 +20,31 @@ import ( ) var ( - testBool = Bool("test_bool", false, "bool value") - testInt = Int("test_int", 0, "int value") - testInt64 = Int64("test_int64", 0, "int64 value") - testUint = Uint("test_uint", 0, "uint value") - testUint64 = Uint64("test_uint64", 0, "uint64 value") - testString = String("test_string", "0", "string value") - testFloat = Float64("test_float64", 0, "float64 value") - testDuration = Duration("test_duration", 0, "time.Duration value") - testOptionalInt = Int("test_optional_int", 0, "optional int value") + testBool *bool + testInt *int + testInt64 *int64 + testUint *uint + testUint64 *uint64 + testString *string + testFloat *float64 + testDuration *time.Duration + testOptionalInt *int + normalizeFlagNameInvocations = 0 ) +func init() { + testBool = Bool("test_bool", false, "bool value") + testInt = Int("test_int", 0, "int value") + testInt64 = Int64("test_int64", 0, "int64 value") + testUint = Uint("test_uint", 0, "uint value") + testUint64 = Uint64("test_uint64", 0, "uint64 value") + testString = String("test_string", "0", "string value") + testFloat = Float64("test_float64", 0, "float64 value") + testDuration = Duration("test_duration", 0, "time.Duration value") + testOptionalInt = Int("test_optional_int", 0, "optional int value") +} + func boolString(s string) string { if s == "0" { return "false" @@ -75,15 +88,15 @@ func TestEverything(t *testing.T) { } } // Now set all flags - Set("test_bool", "true") - Set("test_int", "1") - Set("test_int64", "1") - Set("test_uint", "1") - Set("test_uint64", "1") - Set("test_string", "1") - Set("test_float64", "1") - Set("test_duration", "1s") - Set("test_optional_int", "1") + _ = Set("test_bool", "true") + _ = Set("test_int", "1") + _ = Set("test_int64", "1") + _ = Set("test_uint", "1") + _ = Set("test_uint64", "1") + _ = Set("test_string", "1") + _ = Set("test_float64", "1") + _ = Set("test_duration", "1s") + _ = Set("test_optional_int", "1") desired = "1" Visit(visitor) if len(m) != 9 { @@ -317,16 +330,16 @@ func testParse(f *FlagSet, t *testing.T) { if v, err := f.GetFloat64("float64"); err != nil || v != *float64Flag { t.Errorf("GetFloat64 returned %v but float64Flag was %v", v, *float64Flag) } - if !(*ipFlag).Equal(net.ParseIP("10.11.12.13")) { + if !ipFlag.Equal(net.ParseIP("10.11.12.13")) { t.Error("ip flag should be 10.11.12.13, is ", *ipFlag) } if v, err := f.GetIP("ip"); err != nil || !v.Equal(*ipFlag) { t.Errorf("GetIP returned %v but ipFlag was %v", v, *ipFlag) } - if (*maskFlag).String() != ParseIPv4Mask("255.255.255.0").String() { - t.Error("mask flag should be 255.255.255.0, is ", (*maskFlag).String()) + if maskFlag.String() != ParseIPv4Mask("255.255.255.0").String() { + t.Error("mask flag should be 255.255.255.0, is ", maskFlag.String()) } - if v, err := f.GetIPv4Mask("mask"); err != nil || v.String() != (*maskFlag).String() { + if v, err := f.GetIPv4Mask("mask"); err != nil || v.String() != maskFlag.String() { t.Errorf("GetIP returned %v maskFlag was %v error was %v", v, *maskFlag, err) } if *durationFlag != 2*time.Minute { @@ -433,7 +446,7 @@ func testParseWithUnknownFlags(f *FlagSet, t *testing.T) { "-u=unknown3Value", "-p", "unknown4Value", - "-q", //another unknown with bool value + "-q", // another unknown with bool value "-y", "ee", "--unknown7=unknown7value", @@ -528,13 +541,16 @@ func TestShorthand(t *testing.T) { if *stringzFlag != "something" { t.Error("stringz flag should be `something`, is ", *stringzFlag) } - if len(f.Args()) != 2 { + + switch { + case len(f.Args()) != 2: t.Error("expected one argument, got", len(f.Args())) - } else if f.Args()[0] != extra { + case f.Args()[0] != extra: t.Errorf("expected argument %q got %q", extra, f.Args()[0]) - } else if f.Args()[1] != notaflag { + case f.Args()[1] != notaflag: t.Errorf("expected argument %q got %q", notaflag, f.Args()[1]) } + if f.ArgsLenAtDash() != 1 { t.Errorf("expected argsLenAtDash %d got %d", f.ArgsLenAtDash(), 1) } @@ -560,6 +576,7 @@ func TestShorthandLookup(t *testing.T) { flag := f.ShorthandLookup("a") if flag == nil { t.Errorf("f.ShorthandLookup(\"a\") returned nil") + return // required } if flag.Name != "boola" { t.Errorf("f.ShorthandLookup(\"a\") found %q instead of \"boola\"", flag.Name) @@ -569,9 +586,9 @@ func TestShorthandLookup(t *testing.T) { t.Errorf("f.ShorthandLookup(\"\") did not return nil") } defer func() { - recover() + _ = recover() }() - flag = f.ShorthandLookup("ab") + _ = f.ShorthandLookup("ab") // should NEVER get here. lookup should panic. defer'd func should recover it. t.Errorf("f.ShorthandLookup(\"ab\") did not panic") } @@ -626,16 +643,16 @@ func TestChangedHelper(t *testing.T) { } } -func replaceSeparators(name string, from []string, to string) string { +func replaceSeparators(name string, from []string, to string) string { //nolint: unparam result := name for _, sep := range from { - result = strings.Replace(result, sep, to, -1) + result = strings.ReplaceAll(result, sep, to) } // Type convert to indicate normalization has been done. return result } -func wordSepNormalizeFunc(f *FlagSet, name string) NormalizedName { +func wordSepNormalizeFunc(_ *FlagSet, name string) NormalizedName { seps := []string{"-", "_"} name = replaceSeparators(name, seps, ".") normalizeFlagNameInvocations++ @@ -693,15 +710,14 @@ func TestWordSepNormalizedNames(t *testing.T) { testWordSepNormalizedNames(args, t) } -func aliasAndWordSepFlagNames(f *FlagSet, name string) NormalizedName { +func aliasAndWordSepFlagNames(_ *FlagSet, name string) NormalizedName { seps := []string{"-", "_"} oldName := replaceSeparators("old-valid_flag", seps, ".") newName := replaceSeparators("valid-flag", seps, ".") name = replaceSeparators(name, seps, ".") - switch name { - case oldName: + if name == oldName { name = newName } @@ -800,7 +816,7 @@ func TestNormalizationSetFlags(t *testing.T) { } f.Bool(testName, false, "bool value") - f.Set(testName, "true") + _ = f.Set(testName, "true") f.SetNormalizeFunc(nfunc) if len(f.formal) != 1 { @@ -858,7 +874,7 @@ func TestSetOutput(t *testing.T) { var buf bytes.Buffer flags.SetOutput(&buf) flags.Init("test", ContinueOnError) - flags.Parse([]string{"--unknown"}) + _ = flags.Parse([]string{"--unknown"}) if out := buf.String(); !strings.Contains(out, "--unknown") { t.Logf("expected output mentioning unknown; got %q", out) } @@ -995,7 +1011,7 @@ func TestTermination(t *testing.T) { func getDeprecatedFlagSet() *FlagSet { f := NewFlagSet("bob", ContinueOnError) f.Bool("badflag", true, "always true") - f.MarkDeprecated("badflag", "use --good-flag instead") + _ = f.MarkDeprecated("badflag", "use --good-flag instead") return f } func TestDeprecatedFlagInDocs(t *testing.T) { @@ -1035,7 +1051,7 @@ func TestDeprecatedFlagShorthandInDocs(t *testing.T) { f := NewFlagSet("bob", ContinueOnError) name := "noshorthandflag" f.BoolP(name, "n", true, "always true") - f.MarkShorthandDeprecated("noshorthandflag", fmt.Sprintf("use --%s instead", name)) + _ = f.MarkShorthandDeprecated("noshorthandflag", fmt.Sprintf("use --%s instead", name)) out := new(bytes.Buffer) f.SetOutput(out) @@ -1046,7 +1062,7 @@ func TestDeprecatedFlagShorthandInDocs(t *testing.T) { } } -func parseReturnStderr(t *testing.T, f *FlagSet, args []string) (string, error) { +func parseReturnStderr(_ *testing.T, f *FlagSet, args []string) (string, error) { oldStderr := os.Stderr r, w, _ := os.Pipe() os.Stderr = w @@ -1057,7 +1073,7 @@ func parseReturnStderr(t *testing.T, f *FlagSet, args []string) (string, error) // copy the output in a separate goroutine so printing can't block indefinitely go func() { var buf bytes.Buffer - io.Copy(&buf, r) + _, _ = io.Copy(&buf, r) outC <- buf.String() }() @@ -1072,7 +1088,7 @@ func TestDeprecatedFlagUsage(t *testing.T) { f := NewFlagSet("bob", ContinueOnError) f.Bool("badflag", true, "always true") usageMsg := "use --good-flag instead" - f.MarkDeprecated("badflag", usageMsg) + _ = f.MarkDeprecated("badflag", usageMsg) args := []string{"--badflag"} out, err := parseReturnStderr(t, f, args) @@ -1090,7 +1106,7 @@ func TestDeprecatedFlagShorthandUsage(t *testing.T) { name := "noshorthandflag" f.BoolP(name, "n", true, "always true") usageMsg := fmt.Sprintf("use --%s instead", name) - f.MarkShorthandDeprecated(name, usageMsg) + _ = f.MarkShorthandDeprecated(name, usageMsg) args := []string{"-n"} out, err := parseReturnStderr(t, f, args) @@ -1108,7 +1124,7 @@ func TestDeprecatedFlagUsageNormalized(t *testing.T) { f.Bool("bad-double_flag", true, "always true") f.SetNormalizeFunc(wordSepNormalizeFunc) usageMsg := "use --good-flag instead" - f.MarkDeprecated("bad_double-flag", usageMsg) + _ = f.MarkDeprecated("bad_double-flag", usageMsg) args := []string{"--bad_double_flag"} out, err := parseReturnStderr(t, f, args) @@ -1134,11 +1150,10 @@ func TestMultipleNormalizeFlagNameInvocations(t *testing.T) { } } -// func TestHiddenFlagInUsage(t *testing.T) { f := NewFlagSet("bob", ContinueOnError) f.Bool("secretFlag", true, "shhh") - f.MarkHidden("secretFlag") + _ = f.MarkHidden("secretFlag") out := new(bytes.Buffer) f.SetOutput(out) @@ -1149,11 +1164,10 @@ func TestHiddenFlagInUsage(t *testing.T) { } } -// func TestHiddenFlagUsage(t *testing.T) { f := NewFlagSet("bob", ContinueOnError) f.Bool("secretFlag", true, "shhh") - f.MarkHidden("secretFlag") + _ = f.MarkHidden("secretFlag") args := []string{"--secretFlag"} out, err := parseReturnStderr(t, f, args) @@ -1239,7 +1253,7 @@ func TestPrintDefaults(t *testing.T) { got := buf.String() if got != defaultOutput { fmt.Println("\n" + got) - fmt.Println("\n" + defaultOutput) + fmt.Printf("\n" + defaultOutput) t.Errorf("got %q want %q\n", got, defaultOutput) } } @@ -1272,7 +1286,7 @@ func TestVisitFlagOrder(t *testing.T) { names := []string{"C", "B", "A", "D"} for _, name := range names { fs.Bool(name, false, "") - fs.Set(name, "true") + _ = fs.Set(name, "true") } i := 0 diff --git a/float32_slice_test.go b/float32_slice_test.go index 997ce5c6..07f2bb99 100644 --- a/float32_slice_test.go +++ b/float32_slice_test.go @@ -46,10 +46,11 @@ func TestF32S(t *testing.T) { vals := []string{"1.0", "2.0", "4.0", "3.0"} arg := fmt.Sprintf("--f32s=%s", strings.Join(vals, ",")) - err := f.Parse([]string{arg}) - if err != nil { - t.Fatal("expected no error; got", err) + erp := f.Parse([]string{arg}) + if erp != nil { + t.Fatal("expected no error; got", erp) } + for i, v := range f32s { d64, err := strconv.ParseFloat(vals[i], 32) if err != nil { @@ -61,10 +62,12 @@ func TestF32S(t *testing.T) { t.Fatalf("expected f32s[%d] to be %s but got: %f", i, vals[i], v) } } - getF32S, err := f.GetFloat32Slice("f32s") - if err != nil { - t.Fatalf("got error: %v", err) + + getF32S, erf := f.GetFloat32Slice("f32s") + if erf != nil { + t.Fatalf("got error: %v", erf) } + for i, v := range getF32S { d64, err := strconv.ParseFloat(vals[i], 32) if err != nil { @@ -84,10 +87,11 @@ func TestF32SDefault(t *testing.T) { vals := []string{"0.0", "1.0"} - err := f.Parse([]string{}) - if err != nil { - t.Fatal("expected no error; got", err) + erp := f.Parse([]string{}) + if erp != nil { + t.Fatal("expected no error; got", erp) } + for i, v := range f32s { d64, err := strconv.ParseFloat(vals[i], 32) if err != nil { @@ -100,10 +104,11 @@ func TestF32SDefault(t *testing.T) { } } - getF32S, err := f.GetFloat32Slice("f32s") - if err != nil { - t.Fatal("got an error from GetFloat32Slice():", err) + getF32S, erf := f.GetFloat32Slice("f32s") + if erf != nil { + t.Fatal("got an error from GetFloat32Slice():", erf) } + for i, v := range getF32S { d64, err := strconv.ParseFloat(vals[i], 32) if err != nil { @@ -123,10 +128,11 @@ func TestF32SWithDefault(t *testing.T) { vals := []string{"1.0", "2.0"} arg := fmt.Sprintf("--f32s=%s", strings.Join(vals, ",")) - err := f.Parse([]string{arg}) - if err != nil { - t.Fatal("expected no error; got", err) + erp := f.Parse([]string{arg}) + if erp != nil { + t.Fatal("expected no error; got", erp) } + for i, v := range f32s { d64, err := strconv.ParseFloat(vals[i], 32) if err != nil { @@ -139,10 +145,11 @@ func TestF32SWithDefault(t *testing.T) { } } - getF32S, err := f.GetFloat32Slice("f32s") - if err != nil { - t.Fatal("got an error from GetFloat32Slice():", err) + getF32S, erf := f.GetFloat32Slice("f32s") + if erf != nil { + t.Fatal("got an error from GetFloat32Slice():", erf) } + for i, v := range getF32S { d64, err := strconv.ParseFloat(vals[i], 32) if err != nil { @@ -192,6 +199,7 @@ func TestF32SCalledTwice(t *testing.T) { if err != nil { t.Fatal("expected no error; got", err) } + for i, v := range f32s { if expected[i] != v { t.Fatalf("expected f32s[%d] to be %f but got: %f", i, expected[i], v) diff --git a/float64_slice_test.go b/float64_slice_test.go index 43778ef1..ffcc86d4 100644 --- a/float64_slice_test.go +++ b/float64_slice_test.go @@ -46,10 +46,11 @@ func TestF64S(t *testing.T) { vals := []string{"1.0", "2.0", "4.0", "3.0"} arg := fmt.Sprintf("--f64s=%s", strings.Join(vals, ",")) - err := f.Parse([]string{arg}) - if err != nil { - t.Fatal("expected no error; got", err) + erp := f.Parse([]string{arg}) + if erp != nil { + t.Fatal("expected no error; got", erp) } + for i, v := range f64s { d, err := strconv.ParseFloat(vals[i], 64) if err != nil { @@ -59,10 +60,12 @@ func TestF64S(t *testing.T) { t.Fatalf("expected f64s[%d] to be %s but got: %f", i, vals[i], v) } } - getF64S, err := f.GetFloat64Slice("f64s") - if err != nil { - t.Fatalf("got error: %v", err) + + getF64S, erf := f.GetFloat64Slice("f64s") + if erf != nil { + t.Fatalf("got error: %v", erf) } + for i, v := range getF64S { d, err := strconv.ParseFloat(vals[i], 64) if err != nil { @@ -80,10 +83,11 @@ func TestF64SDefault(t *testing.T) { vals := []string{"0.0", "1.0"} - err := f.Parse([]string{}) - if err != nil { - t.Fatal("expected no error; got", err) + erp := f.Parse([]string{}) + if erp != nil { + t.Fatal("expected no error; got", erp) } + for i, v := range f64s { d, err := strconv.ParseFloat(vals[i], 64) if err != nil { @@ -94,10 +98,11 @@ func TestF64SDefault(t *testing.T) { } } - getF64S, err := f.GetFloat64Slice("f64s") - if err != nil { - t.Fatal("got an error from GetFloat64Slice():", err) + getF64S, erf := f.GetFloat64Slice("f64s") + if erf != nil { + t.Fatal("got an error from GetFloat64Slice():", erf) } + for i, v := range getF64S { d, err := strconv.ParseFloat(vals[i], 64) if err != nil { @@ -115,10 +120,11 @@ func TestF64SWithDefault(t *testing.T) { vals := []string{"1.0", "2.0"} arg := fmt.Sprintf("--f64s=%s", strings.Join(vals, ",")) - err := f.Parse([]string{arg}) - if err != nil { - t.Fatal("expected no error; got", err) + erp := f.Parse([]string{arg}) + if erp != nil { + t.Fatal("expected no error; got", erp) } + for i, v := range f64s { d, err := strconv.ParseFloat(vals[i], 64) if err != nil { @@ -129,10 +135,11 @@ func TestF64SWithDefault(t *testing.T) { } } - getF64S, err := f.GetFloat64Slice("f64s") - if err != nil { - t.Fatal("got an error from GetFloat64Slice():", err) + getF64S, erf := f.GetFloat64Slice("f64s") + if erf != nil { + t.Fatal("got an error from GetFloat64Slice():", erf) } + for i, v := range getF64S { d, err := strconv.ParseFloat(vals[i], 64) if err != nil { @@ -180,6 +187,7 @@ func TestF64SCalledTwice(t *testing.T) { if err != nil { t.Fatal("expected no error; got", err) } + for i, v := range f64s { if expected[i] != v { t.Fatalf("expected f64s[%d] to be %f but got: %f", i, expected[i], v) diff --git a/golangflag.go b/golangflag.go index d3dd72b7..e058a787 100644 --- a/golangflag.go +++ b/golangflag.go @@ -61,7 +61,7 @@ func (v *flagValueWrapper) Type() string { // If the *flag.Flag.Name was a single character (ex: `v`) it will be accessiblei // with both `-v` and `--v` in flags. If the golang flag was more than a single // character (ex: `verbose`) it will only be accessible via `--verbose` -func PFlagFromGoFlag(goflag *goflag.Flag) *Flag { +func PFlagFromGoFlag(goflag *goflag.Flag) *Flag { // nolint: revive // Remember the default value as a string; it won't change. flag := &Flag{ Name: goflag.Name, diff --git a/int16.go b/int16.go index f1a01d05..eef29a8c 100644 --- a/int16.go +++ b/int16.go @@ -1,3 +1,4 @@ +// nolint: dupl package pflag import "strconv" diff --git a/int32.go b/int32.go index 9b95944f..35002a5d 100644 --- a/int32.go +++ b/int32.go @@ -1,3 +1,4 @@ +// nolint: dupl package pflag import "strconv" diff --git a/int32_slice_test.go b/int32_slice_test.go index 809c5633..ec40e9d3 100644 --- a/int32_slice_test.go +++ b/int32_slice_test.go @@ -46,10 +46,11 @@ func TestI32S(t *testing.T) { vals := []string{"1", "2", "4", "3"} arg := fmt.Sprintf("--is=%s", strings.Join(vals, ",")) - err := f.Parse([]string{arg}) - if err != nil { - t.Fatal("expected no error; got", err) + erp := f.Parse([]string{arg}) + if erp != nil { + t.Fatal("expected no error; got", erp) } + for i, v := range is { d64, err := strconv.ParseInt(vals[i], 0, 32) if err != nil { @@ -60,10 +61,12 @@ func TestI32S(t *testing.T) { t.Fatalf("expected is[%d] to be %s but got: %d", i, vals[i], v) } } - getI32S, err := f.GetInt32Slice("is") - if err != nil { - t.Fatalf("got error: %v", err) + + getI32S, eri := f.GetInt32Slice("is") + if eri != nil { + t.Fatalf("got error: %v", eri) } + for i, v := range getI32S { d64, err := strconv.ParseInt(vals[i], 0, 32) if err != nil { @@ -82,10 +85,11 @@ func TestI32SDefault(t *testing.T) { vals := []string{"0", "1"} - err := f.Parse([]string{}) - if err != nil { - t.Fatal("expected no error; got", err) + erp := f.Parse([]string{}) + if erp != nil { + t.Fatal("expected no error; got", erp) } + for i, v := range is { d64, err := strconv.ParseInt(vals[i], 0, 32) if err != nil { @@ -97,10 +101,11 @@ func TestI32SDefault(t *testing.T) { } } - getI32S, err := f.GetInt32Slice("is") - if err != nil { - t.Fatal("got an error from GetInt32Slice():", err) + getI32S, eri := f.GetInt32Slice("is") + if eri != nil { + t.Fatal("got an error from GetInt32Slice():", eri) } + for i, v := range getI32S { d64, err := strconv.ParseInt(vals[i], 0, 32) if err != nil { @@ -119,10 +124,11 @@ func TestI32SWithDefault(t *testing.T) { vals := []string{"1", "2"} arg := fmt.Sprintf("--is=%s", strings.Join(vals, ",")) - err := f.Parse([]string{arg}) - if err != nil { - t.Fatal("expected no error; got", err) + erp := f.Parse([]string{arg}) + if erp != nil { + t.Fatal("expected no error; got", erp) } + for i, v := range is { d64, err := strconv.ParseInt(vals[i], 0, 32) if err != nil { @@ -134,10 +140,11 @@ func TestI32SWithDefault(t *testing.T) { } } - getI32S, err := f.GetInt32Slice("is") - if err != nil { - t.Fatal("got an error from GetInt32Slice():", err) + getI32S, eri := f.GetInt32Slice("is") + if eri != nil { + t.Fatal("got an error from GetInt32Slice():", eri) } + for i, v := range getI32S { d64, err := strconv.ParseInt(vals[i], 0, 32) if err != nil { @@ -186,6 +193,7 @@ func TestI32SCalledTwice(t *testing.T) { if err != nil { t.Fatal("expected no error; got", err) } + for i, v := range is { if expected[i] != v { t.Fatalf("expected is[%d] to be %d but got: %d", i, expected[i], v) diff --git a/int64_slice_test.go b/int64_slice_test.go index 09805c76..9b356b49 100644 --- a/int64_slice_test.go +++ b/int64_slice_test.go @@ -46,10 +46,11 @@ func TestI64S(t *testing.T) { vals := []string{"1", "2", "4", "3"} arg := fmt.Sprintf("--is=%s", strings.Join(vals, ",")) - err := f.Parse([]string{arg}) - if err != nil { - t.Fatal("expected no error; got", err) + erp := f.Parse([]string{arg}) + if erp != nil { + t.Fatal("expected no error; got", erp) } + for i, v := range is { d, err := strconv.ParseInt(vals[i], 0, 64) if err != nil { @@ -59,10 +60,12 @@ func TestI64S(t *testing.T) { t.Fatalf("expected is[%d] to be %s but got: %d", i, vals[i], v) } } - getI64S, err := f.GetInt64Slice("is") - if err != nil { - t.Fatalf("got error: %v", err) + + getI64S, eri := f.GetInt64Slice("is") + if eri != nil { + t.Fatalf("got error: %v", eri) } + for i, v := range getI64S { d, err := strconv.ParseInt(vals[i], 0, 64) if err != nil { @@ -80,10 +83,11 @@ func TestI64SDefault(t *testing.T) { vals := []string{"0", "1"} - err := f.Parse([]string{}) - if err != nil { - t.Fatal("expected no error; got", err) + erp := f.Parse([]string{}) + if erp != nil { + t.Fatal("expected no error; got", erp) } + for i, v := range is { d, err := strconv.ParseInt(vals[i], 0, 64) if err != nil { @@ -94,10 +98,11 @@ func TestI64SDefault(t *testing.T) { } } - getI64S, err := f.GetInt64Slice("is") - if err != nil { - t.Fatal("got an error from GetInt64Slice():", err) + getI64S, eri := f.GetInt64Slice("is") + if eri != nil { + t.Fatal("got an error from GetInt64Slice():", eri) } + for i, v := range getI64S { d, err := strconv.ParseInt(vals[i], 0, 64) if err != nil { @@ -115,10 +120,11 @@ func TestI64SWithDefault(t *testing.T) { vals := []string{"1", "2"} arg := fmt.Sprintf("--is=%s", strings.Join(vals, ",")) - err := f.Parse([]string{arg}) - if err != nil { - t.Fatal("expected no error; got", err) + erp := f.Parse([]string{arg}) + if erp != nil { + t.Fatal("expected no error; got", erp) } + for i, v := range is { d, err := strconv.ParseInt(vals[i], 0, 64) if err != nil { @@ -129,10 +135,11 @@ func TestI64SWithDefault(t *testing.T) { } } - getI64S, err := f.GetInt64Slice("is") - if err != nil { - t.Fatal("got an error from GetInt64Slice():", err) + getI64S, eri := f.GetInt64Slice("is") + if eri != nil { + t.Fatal("got an error from GetInt64Slice():", eri) } + for i, v := range getI64S { d, err := strconv.ParseInt(vals[i], 0, 64) if err != nil { @@ -180,6 +187,7 @@ func TestI64SCalledTwice(t *testing.T) { if err != nil { t.Fatal("expected no error; got", err) } + for i, v := range is { if expected[i] != v { t.Fatalf("expected is[%d] to be %d but got: %d", i, expected[i], v) diff --git a/int8.go b/int8.go index 4da92228..952c9eed 100644 --- a/int8.go +++ b/int8.go @@ -1,3 +1,4 @@ +// nolint: dupl package pflag import "strconv" diff --git a/int_slice_test.go b/int_slice_test.go index 745aecb9..2b475474 100644 --- a/int_slice_test.go +++ b/int_slice_test.go @@ -46,10 +46,11 @@ func TestIS(t *testing.T) { vals := []string{"1", "2", "4", "3"} arg := fmt.Sprintf("--is=%s", strings.Join(vals, ",")) - err := f.Parse([]string{arg}) - if err != nil { - t.Fatal("expected no error; got", err) + erp := f.Parse([]string{arg}) + if erp != nil { + t.Fatal("expected no error; got", erp) } + for i, v := range is { d, err := strconv.Atoi(vals[i]) if err != nil { @@ -59,10 +60,12 @@ func TestIS(t *testing.T) { t.Fatalf("expected is[%d] to be %s but got: %d", i, vals[i], v) } } - getIS, err := f.GetIntSlice("is") - if err != nil { - t.Fatalf("got error: %v", err) + + getIS, eri := f.GetIntSlice("is") + if eri != nil { + t.Fatalf("got error: %v", eri) } + for i, v := range getIS { d, err := strconv.Atoi(vals[i]) if err != nil { @@ -80,10 +83,11 @@ func TestISDefault(t *testing.T) { vals := []string{"0", "1"} - err := f.Parse([]string{}) - if err != nil { - t.Fatal("expected no error; got", err) + erp := f.Parse([]string{}) + if erp != nil { + t.Fatal("expected no error; got", erp) } + for i, v := range is { d, err := strconv.Atoi(vals[i]) if err != nil { @@ -94,10 +98,11 @@ func TestISDefault(t *testing.T) { } } - getIS, err := f.GetIntSlice("is") - if err != nil { - t.Fatal("got an error from GetIntSlice():", err) + getIS, eri := f.GetIntSlice("is") + if eri != nil { + t.Fatal("got an error from GetIntSlice():", eri) } + for i, v := range getIS { d, err := strconv.Atoi(vals[i]) if err != nil { @@ -115,10 +120,11 @@ func TestISWithDefault(t *testing.T) { vals := []string{"1", "2"} arg := fmt.Sprintf("--is=%s", strings.Join(vals, ",")) - err := f.Parse([]string{arg}) - if err != nil { - t.Fatal("expected no error; got", err) + erp := f.Parse([]string{arg}) + if erp != nil { + t.Fatal("expected no error; got", erp) } + for i, v := range is { d, err := strconv.Atoi(vals[i]) if err != nil { @@ -129,10 +135,11 @@ func TestISWithDefault(t *testing.T) { } } - getIS, err := f.GetIntSlice("is") - if err != nil { - t.Fatal("got an error from GetIntSlice():", err) + getIS, eri := f.GetIntSlice("is") + if eri != nil { + t.Fatal("got an error from GetIntSlice():", eri) } + for i, v := range getIS { d, err := strconv.Atoi(vals[i]) if err != nil { @@ -157,6 +164,7 @@ func TestISCalledTwice(t *testing.T) { if err != nil { t.Fatal("expected no error; got", err) } + for i, v := range is { if expected[i] != v { t.Fatalf("expected is[%d] to be %d but got: %d", i, expected[i], v) diff --git a/ip_slice.go b/ip_slice.go index 775faae4..11223900 100644 --- a/ip_slice.go +++ b/ip_slice.go @@ -72,7 +72,7 @@ func (s *ipSliceValue) String() string { return "[" + out + "]" } -func (s *ipSliceValue) fromString(val string) (net.IP, error) { +func (s *ipSliceValue) fromString(val string) (net.IP, error) { // nolint: unparam return net.ParseIP(strings.TrimSpace(val)), nil } diff --git a/ip_slice_test.go b/ip_slice_test.go index d1892768..531bc627 100644 --- a/ip_slice_test.go +++ b/ip_slice_test.go @@ -65,10 +65,11 @@ func TestIPSDefault(t *testing.T) { f := setUpIPSFlagSetWithDefault(&ips) vals := []string{"192.168.1.1", "0:0:0:0:0:0:0:1"} - err := f.Parse([]string{}) - if err != nil { - t.Fatal("expected no error; got", err) + erp := f.Parse([]string{}) + if erp != nil { + t.Fatal("expected no error; got", erp) } + for i, v := range ips { if ip := net.ParseIP(vals[i]); ip == nil { t.Fatalf("invalid string being converted to IP address: %s", vals[i]) @@ -77,10 +78,11 @@ func TestIPSDefault(t *testing.T) { } } - getIPS, err := f.GetIPSlice("ips") - if err != nil { + getIPS, eri := f.GetIPSlice("ips") + if eri != nil { t.Fatal("got an error from GetIPSlice") } + for i, v := range getIPS { if ip := net.ParseIP(vals[i]); ip == nil { t.Fatalf("invalid string being converted to IP address: %s", vals[i]) diff --git a/ip_test.go b/ip_test.go index 1fec50e4..59828114 100644 --- a/ip_test.go +++ b/ip_test.go @@ -44,13 +44,14 @@ func TestIP(t *testing.T) { arg := fmt.Sprintf("--address=%s", tc.input) err := f.Parse([]string{arg}) - if err != nil && tc.success == true { + switch { + case err != nil && tc.success: t.Errorf("expected success, got %q", err) continue - } else if err == nil && tc.success == false { + case err == nil && !tc.success: t.Errorf("expected failure") continue - } else if tc.success { + case tc.success: ip, err := f.GetIP("address") if err != nil { t.Errorf("Got error trying to fetch the IP flag: %v", err) diff --git a/ipnet_slice_test.go b/ipnet_slice_test.go index 11644c58..38cb1342 100644 --- a/ipnet_slice_test.go +++ b/ipnet_slice_test.go @@ -8,15 +8,12 @@ import ( ) // Helper function to set static slices -func getCIDR(ip net.IP, cidr *net.IPNet, err error) net.IPNet { +func getCIDR(_ net.IP, cidr *net.IPNet, _ error) net.IPNet { return *cidr } func equalCIDR(c1 net.IPNet, c2 net.IPNet) bool { - if c1.String() == c2.String() { - return true - } - return false + return c1.String() == c2.String() } func setUpIPNetFlagSet(ipsp *[]net.IPNet) *FlagSet { diff --git a/ipnet_test.go b/ipnet_test.go index 335b6fa1..bd7b728b 100644 --- a/ipnet_test.go +++ b/ipnet_test.go @@ -51,13 +51,14 @@ func TestIPNet(t *testing.T) { arg := fmt.Sprintf("--address=%s", tc.input) err := f.Parse([]string{arg}) - if err != nil && tc.success == true { + switch { + case err != nil && tc.success: t.Errorf("expected success, got %q", err) continue - } else if err == nil && tc.success == false { + case err == nil && !tc.success: t.Errorf("expected failure") continue - } else if tc.success { + case tc.success: ip, err := f.GetIPNet("address") if err != nil { t.Errorf("Got error trying to fetch the IP flag: %v", err) diff --git a/string_array.go b/string_array.go index d1ff0a96..5b67af38 100644 --- a/string_array.go +++ b/string_array.go @@ -30,18 +30,14 @@ func (s *stringArrayValue) Append(val string) error { func (s *stringArrayValue) Replace(val []string) error { out := make([]string, len(val)) - for i, d := range val { - out[i] = d - } + copy(out, val) *s.value = out return nil } func (s *stringArrayValue) GetSlice() []string { out := make([]string, len(*s.value)) - for i, d := range *s.value { - out[i] = d - } + copy(out, *s.value) return out } @@ -55,6 +51,9 @@ func (s *stringArrayValue) String() string { } func stringArrayConv(sval string) (interface{}, error) { + if len(sval) == 0 { + return []string{}, nil + } sval = sval[1 : len(sval)-1] // An empty string would cause a array with one (empty) string if len(sval) == 0 { diff --git a/string_array_test.go b/string_array_test.go index 3c6d5958..ebad8180 100644 --- a/string_array_test.go +++ b/string_array_test.go @@ -254,3 +254,10 @@ func TestSAWithSquareBrackets(t *testing.T) { } } } + +func TestStringArrayConv(t *testing.T) { + _, err := stringArrayConv("") + if err != nil { + t.Errorf("unexpected failure on stringArrayConv") + } +} diff --git a/string_slice.go b/string_slice.go index 3cb2e69d..d421887e 100644 --- a/string_slice.go +++ b/string_slice.go @@ -98,9 +98,12 @@ func (f *FlagSet) GetStringSlice(name string) ([]string, error) { // The argument p points to a []string variable in which to store the value of the flag. // Compared to StringArray flags, StringSlice flags take comma-separated value as arguments and split them accordingly. // For example: -// --ss="v1,v2" --ss="v3" +// +// --ss="v1,v2" --ss="v3" +// // will result in -// []string{"v1", "v2", "v3"} +// +// []string{"v1", "v2", "v3"} func (f *FlagSet) StringSliceVar(p *[]string, name string, value []string, usage string) { f.VarP(newStringSliceValue(value, p), name, "", usage) } @@ -114,9 +117,12 @@ func (f *FlagSet) StringSliceVarP(p *[]string, name, shorthand string, value []s // The argument p points to a []string variable in which to store the value of the flag. // Compared to StringArray flags, StringSlice flags take comma-separated value as arguments and split them accordingly. // For example: -// --ss="v1,v2" --ss="v3" +// +// --ss="v1,v2" --ss="v3" +// // will result in -// []string{"v1", "v2", "v3"} +// +// []string{"v1", "v2", "v3"} func StringSliceVar(p *[]string, name string, value []string, usage string) { CommandLine.VarP(newStringSliceValue(value, p), name, "", usage) } @@ -130,9 +136,12 @@ func StringSliceVarP(p *[]string, name, shorthand string, value []string, usage // The return value is the address of a []string variable that stores the value of the flag. // Compared to StringArray flags, StringSlice flags take comma-separated value as arguments and split them accordingly. // For example: -// --ss="v1,v2" --ss="v3" +// +// --ss="v1,v2" --ss="v3" +// // will result in -// []string{"v1", "v2", "v3"} +// +// []string{"v1", "v2", "v3"} func (f *FlagSet) StringSlice(name string, value []string, usage string) *[]string { p := []string{} f.StringSliceVarP(&p, name, "", value, usage) @@ -150,9 +159,12 @@ func (f *FlagSet) StringSliceP(name, shorthand string, value []string, usage str // The return value is the address of a []string variable that stores the value of the flag. // Compared to StringArray flags, StringSlice flags take comma-separated value as arguments and split them accordingly. // For example: -// --ss="v1,v2" --ss="v3" +// +// --ss="v1,v2" --ss="v3" +// // will result in -// []string{"v1", "v2", "v3"} +// +// []string{"v1", "v2", "v3"} func StringSlice(name string, value []string, usage string) *[]string { return CommandLine.StringSliceP(name, "", value, usage) } diff --git a/uint.go b/uint.go index dcbc2b75..b8671fb8 100644 --- a/uint.go +++ b/uint.go @@ -1,3 +1,4 @@ +// nolint: dupl package pflag import "strconv" diff --git a/uint16.go b/uint16.go index 7e9914ed..8774c5a2 100644 --- a/uint16.go +++ b/uint16.go @@ -1,3 +1,4 @@ +// nolint: dupl package pflag import "strconv" diff --git a/uint32.go b/uint32.go index d8024539..8ed0fdd6 100644 --- a/uint32.go +++ b/uint32.go @@ -1,3 +1,4 @@ +// nolint: dupl package pflag import "strconv" diff --git a/uint64.go b/uint64.go index f62240f2..86d8c7e6 100644 --- a/uint64.go +++ b/uint64.go @@ -27,7 +27,7 @@ func uint64Conv(sval string) (interface{}, error) { if err != nil { return 0, err } - return uint64(v), nil + return v, nil } // GetUint64 return the uint64 value of a flag with the given name diff --git a/uint8.go b/uint8.go index bb0e83c1..4a48d494 100644 --- a/uint8.go +++ b/uint8.go @@ -1,3 +1,4 @@ +// nolint: dupl package pflag import "strconv" diff --git a/uint_slice_test.go b/uint_slice_test.go index d0da4d07..4b33e313 100644 --- a/uint_slice_test.go +++ b/uint_slice_test.go @@ -42,10 +42,11 @@ func TestUIS(t *testing.T) { vals := []string{"1", "2", "4", "3"} arg := fmt.Sprintf("--uis=%s", strings.Join(vals, ",")) - err := f.Parse([]string{arg}) - if err != nil { - t.Fatal("expected no error; got", err) + erp := f.Parse([]string{arg}) + if erp != nil { + t.Fatal("expected no error; got", erp) } + for i, v := range uis { u, err := strconv.ParseUint(vals[i], 10, 0) if err != nil { @@ -55,10 +56,11 @@ func TestUIS(t *testing.T) { t.Fatalf("expected uis[%d] to be %s but got %d", i, vals[i], v) } } - getUIS, err := f.GetUintSlice("uis") - if err != nil { - t.Fatalf("got error: %v", err) + getUIS, eru := f.GetUintSlice("uis") + if eru != nil { + t.Fatalf("got error: %v", eru) } + for i, v := range getUIS { u, err := strconv.ParseUint(vals[i], 10, 0) if err != nil { @@ -76,10 +78,11 @@ func TestUISDefault(t *testing.T) { vals := []string{"0", "1"} - err := f.Parse([]string{}) - if err != nil { - t.Fatal("expected no error; got", err) + erp := f.Parse([]string{}) + if erp != nil { + t.Fatal("expected no error; got", erp) } + for i, v := range uis { u, err := strconv.ParseUint(vals[i], 10, 0) if err != nil { @@ -90,10 +93,11 @@ func TestUISDefault(t *testing.T) { } } - getUIS, err := f.GetUintSlice("uis") - if err != nil { - t.Fatal("got an error from GetUintSlice():", err) + getUIS, eru := f.GetUintSlice("uis") + if eru != nil { + t.Fatal("got an error from GetUintSlice():", eru) } + for i, v := range getUIS { u, err := strconv.ParseUint(vals[i], 10, 0) if err != nil { @@ -111,10 +115,11 @@ func TestUISWithDefault(t *testing.T) { vals := []string{"1", "2"} arg := fmt.Sprintf("--uis=%s", strings.Join(vals, ",")) - err := f.Parse([]string{arg}) - if err != nil { - t.Fatal("expected no error; got", err) + erp := f.Parse([]string{arg}) + if erp != nil { + t.Fatal("expected no error; got", erp) } + for i, v := range uis { u, err := strconv.ParseUint(vals[i], 10, 0) if err != nil { @@ -125,9 +130,9 @@ func TestUISWithDefault(t *testing.T) { } } - getUIS, err := f.GetUintSlice("uis") - if err != nil { - t.Fatal("got an error from GetUintSlice():", err) + getUIS, eru := f.GetUintSlice("uis") + if eru != nil { + t.Fatal("got an error from GetUintSlice():", eru) } for i, v := range getUIS { u, err := strconv.ParseUint(vals[i], 10, 0) @@ -176,6 +181,7 @@ func TestUISCalledTwice(t *testing.T) { if err != nil { t.Fatal("expected no error; got", err) } + for i, v := range uis { if uint(expected[i]) != v { t.Fatalf("expected uis[%d] to be %d but got: %d", i, expected[i], v)