diff --git a/go.mod b/go.mod index cb0882aa..ff9ebcbe 100644 --- a/go.mod +++ b/go.mod @@ -25,7 +25,7 @@ require ( github.com/muesli/termenv v0.16.0 github.com/samber/lo v1.53.0 github.com/spf13/cobra v1.10.2 - github.com/spf13/pflag v1.0.10 + github.com/spf13/pflag v1.1.0 github.com/stretchr/testify v1.11.1 github.com/zalando/go-keyring v0.2.8 go.uber.org/mock v0.6.0 diff --git a/go.sum b/go.sum index a934701c..57145ca1 100644 --- a/go.sum +++ b/go.sum @@ -126,6 +126,8 @@ github.com/spf13/cobra v1.10.2/go.mod h1:7C1pvHqHw5A4vrJfjNwvOdzYu0Gml16OCs2GRiT github.com/spf13/pflag v1.0.9/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spf13/pflag v1.0.10 h1:4EBh2KAYBwaONj6b2Ye1GiHfwjqyROoF4RwYO+vPwFk= github.com/spf13/pflag v1.0.10/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/spf13/pflag v1.1.0 h1:6W6MbVUrnMb8PEhjkqwsVLY7ryuzRfFHF4mQd7L94ag= +github.com/spf13/pflag v1.1.0/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= diff --git a/vendor/github.com/spf13/pflag/.golangci.yaml b/vendor/github.com/spf13/pflag/.golangci.yaml index b274f248..0236240b 100644 --- a/vendor/github.com/spf13/pflag/.golangci.yaml +++ b/vendor/github.com/spf13/pflag/.golangci.yaml @@ -1,4 +1,26 @@ +version: "2" + linters: - disable-all: true enable: + - errorlint - nolintlint + - revive + - unconvert + - unparam + settings: + govet: + disable: + # Suggests reflect.Pointer over reflect.Ptr, which needs Go 1.18. + # This module still builds and tests on Go 1.12 (see go.mod). + - inline + staticcheck: + # Enable all options, with some exceptions. + # For defaults, see https://golangci-lint.run/usage/linters/#staticcheck + checks: + - all + - -QF1008 # Omit embedded fields from selector expression; https://staticcheck.dev/docs/checks/#QF1008 + - -ST1003 # Poorly chosen identifier; https://staticcheck.dev/docs/checks/#ST1003 + +formatters: + enable: + - gofmt diff --git a/vendor/github.com/spf13/pflag/README.md b/vendor/github.com/spf13/pflag/README.md index 388c4e5e..cb4cca6c 100644 --- a/vendor/github.com/spf13/pflag/README.md +++ b/vendor/github.com/spf13/pflag/README.md @@ -1,6 +1,7 @@ -[![Build Status](https://travis-ci.org/spf13/pflag.svg?branch=master)](https://travis-ci.org/spf13/pflag) +[![Build Status](https://github.com/spf13/pflag/actions/workflows/ci.yaml/badge.svg)](https://github.com/spf13/pflag/actions/workflows/ci.yaml) +![GitHub License](https://img.shields.io/github/license/spf13/pflag) [![Go Report Card](https://goreportcard.com/badge/github.com/spf13/pflag)](https://goreportcard.com/report/github.com/spf13/pflag) -[![GoDoc](https://godoc.org/github.com/spf13/pflag?status.svg)](https://godoc.org/github.com/spf13/pflag) +[![PkgGoDev](https://pkg.go.dev/badge/github.com/spf13/pflag)](https://pkg.go.dev/github.com/spf13/pflag) ## Description @@ -11,7 +12,7 @@ pflag is compatible with the [GNU extensions to the POSIX recommendations for command-line options][1]. For a more precise description, see the "Command-line flag syntax" section below. -[1]: http://www.gnu.org/software/libc/manual/html_node/Argument-Syntax.html +[1]: https://sourceware.org/glibc/manual/latest/html_node/Argument-Syntax.html pflag is available under the same style of BSD license as the Go language, which can be found in the LICENSE file. @@ -22,7 +23,7 @@ pflag is available using the standard `go get` command. Install by running: - go get github.com/spf13/pflag + go get github.com/spf13/pflag@latest Run tests by running: @@ -179,6 +180,25 @@ Flag parsing stops after the terminator "--". Unlike the flag package, flags can be interspersed with arguments anywhere on the command line before this terminator. +To stop parsing at the first non-flag argument, call +`flag.SetInterspersed(false)` before `flag.Parse()`, or use +`flags.SetInterspersed(false)` on a `FlagSet`. This is useful for wrappers +that pass a command and its remaining arguments through unchanged: + +```go +flags := flag.NewFlagSet("wrapper", flag.ContinueOnError) +verbose := flags.Bool("verbose", false, "verbose output") +flags.SetInterspersed(false) +if err := flags.Parse([]string{"--verbose", "echo", "--verbose", "hello"}); err != nil { + panic(err) +} +fmt.Println(*verbose) // true +fmt.Println(flags.Args()) // [echo --verbose hello] +``` + +The second `--verbose` belongs to `echo`, so it is left in `flags.Args()` +along with every argument after the command, even if it names a known flag. + Integer flags accept 1234, 0664, 0x1234 and may be negative. Boolean flags (in their long form) accept 1, 0, t, f, true, false, TRUE, FALSE, True, False. @@ -249,13 +269,35 @@ flags.MarkHidden("secretFlag") ## Disable sorting of flags `pflag` allows you to disable sorting of flags for help and usage message. +`SortFlags` is a field on `FlagSet`, not a package-level variable. To disable +sorting on the default `CommandLine` flag set, use `pflag.CommandLine.SortFlags`. + **Example**: ```go -flags.BoolP("verbose", "v", false, "verbose output") -flags.String("coolflag", "yeaah", "it's really cool flag") -flags.Int("usefulflag", 777, "sometimes it's very useful") -flags.SortFlags = false -flags.PrintDefaults() +package main + +import ( + "fmt" + + "github.com/spf13/pflag" +) + +func main() { + flags := pflag.NewFlagSet("example", pflag.ContinueOnError) + flags.BoolP("verbose", "v", false, "verbose output") + flags.String("coolflag", "yeaah", "it's really cool flag") + flags.Int("usefulflag", 777, "sometimes it's very useful") + flags.SortFlags = false + flags.PrintDefaults() + fmt.Println() +} +``` + +For the default `CommandLine` flag set: + +```go +pflag.CommandLine.SortFlags = false +pflag.PrintDefaults() ``` **Output**: ``` @@ -271,12 +313,15 @@ to support flags defined by third-party dependencies (e.g. `golang/glog`). **Example**: You want to add the Go flags to the `CommandLine` flagset ```go +package main + import ( goflag "flag" + flag "github.com/spf13/pflag" ) -var ip *int = flag.Int("flagname", 1234, "help message for flagname") +var ip = flag.Int("flagname", 1234, "help message for flagname") func main() { flag.CommandLine.AddGoFlagSet(goflag.CommandLine) @@ -296,17 +341,22 @@ will result in the `-v` flag being ignored. This happens because of the way pfla To work around this, you can use the `ParseSkippedFlags` function, which ensures that go test's flags are parsed separately using the standard flag package. **Example**: You want to parse go test flags that are otherwise ignore by `pflag.Parse()` + ```go +package main + import ( goflag "flag" + "os" + flag "github.com/spf13/pflag" ) -var ip *int = flag.Int("flagname", 1234, "help message for flagname") +var ip = flag.Int("flagname", 1234, "help message for flagname") func main() { flag.CommandLine.AddGoFlagSet(goflag.CommandLine) - flag.ParseSkippedFlags(os.Args[1:], goflag.CommandLine) + flag.ParseSkippedFlags(os.Args[1:], goflag.CommandLine) flag.Parse() } ``` @@ -314,10 +364,7 @@ func main() { ## More info You can see the full reference documentation of the pflag package -[at godoc.org][3], or through go's standard documentation system by -running `godoc -http=:6060` and browsing to -[http://localhost:6060/pkg/github.com/spf13/pflag][2] after -installation. +at [pkg.go.dev][2], or through go's standard documentation system by +cloning the repository and running `go doc -http` in it. -[2]: http://localhost:6060/pkg/github.com/spf13/pflag -[3]: http://godoc.org/github.com/spf13/pflag +[2]: https://pkg.go.dev/github.com/spf13/pflag diff --git a/vendor/github.com/spf13/pflag/RELEASING.md b/vendor/github.com/spf13/pflag/RELEASING.md new file mode 100644 index 00000000..d90334d0 --- /dev/null +++ b/vendor/github.com/spf13/pflag/RELEASING.md @@ -0,0 +1,31 @@ +# Releasing pflag + +This document describes how to create a new pflag release. + +## Method 1: GitHub UI (recommended by maintainers) + +1. Go to the [releases page](https://github.com/spf13/pflag/releases) +2. Click **"Draft a new release"** +3. Click **"Generate release notes"** — this shows the merged PRs since the last tag, which helps determine the next version (minor vs patch) +4. Choose the tag version (e.g., `v1.0.8`) — the tag will be created when the release is published +5. Review the generated notes, then publish + +This method has the advantage that the tag and release are published atomically, and the PR list helps pick the right version number before tagging. + +## Method 2: GitHub CLI + +```bash +git checkout master +git pull origin master + +# Tag and push +git tag v1.0.8 +git push origin v1.0.8 + +# Create release with auto-generated notes +gh release create v1.0.8 --generate-notes +``` + +## Notes + +pflag follows [Semantic Versioning](https://semver.org/). Check the [releases page](https://github.com/spf13/pflag/releases) for the latest tag. diff --git a/vendor/github.com/spf13/pflag/bool.go b/vendor/github.com/spf13/pflag/bool.go index c4c5c0bf..7286df8e 100644 --- a/vendor/github.com/spf13/pflag/bool.go +++ b/vendor/github.com/spf13/pflag/bool.go @@ -1,6 +1,9 @@ package pflag -import "strconv" +import ( + "errors" + "strconv" +) // optional interface to indicate boolean flags that can be // supplied without "=value" text @@ -9,6 +12,13 @@ type boolFlag interface { IsBoolFlag() bool } +func isNoOptBoolValue(v Value) bool { + if bf, ok := v.(boolFlag); ok { + return bf.IsBoolFlag() + } + return false +} + // -- bool Value type boolValue bool @@ -19,8 +29,11 @@ func newBoolValue(val bool, p *bool) *boolValue { func (b *boolValue) Set(s string) error { v, err := strconv.ParseBool(s) + if err != nil { + return errors.New("must be true or false") + } *b = boolValue(v) - return err + return nil } func (b *boolValue) Type() string { diff --git a/vendor/github.com/spf13/pflag/bool_slice.go b/vendor/github.com/spf13/pflag/bool_slice.go index 3731370d..58a788d2 100644 --- a/vendor/github.com/spf13/pflag/bool_slice.go +++ b/vendor/github.com/spf13/pflag/bool_slice.go @@ -22,13 +22,12 @@ func newBoolSliceValue(val []bool, p *[]bool) *boolSliceValue { // Set converts, and assigns, the comma-separated boolean argument string representation as the []bool value of this flag. // If Set is called on a flag that already has a []bool assigned, the newly converted values will be appended. func (s *boolSliceValue) Set(val string) error { - // remove all quote characters rmQuote := strings.NewReplacer(`"`, "", `'`, "", "`", "") // read flag arguments with CSV parser boolStrSlice, err := readAsCSV(rmQuote.Replace(val)) - if err != nil && err != io.EOF { + if err != nil && err != io.EOF { //nolint:errorlint // not using errors.Is for compatibility with go1.12 return err } @@ -60,7 +59,6 @@ func (s *boolSliceValue) Type() string { // String defines a "native" format for this boolean slice flag value. func (s *boolSliceValue) String() string { - boolStrSlice := make([]string, len(*s.value)) for i, b := range *s.value { boolStrSlice[i] = strconv.FormatBool(b) diff --git a/vendor/github.com/spf13/pflag/bytes.go b/vendor/github.com/spf13/pflag/bytes.go index 67d53045..1c100848 100644 --- a/vendor/github.com/spf13/pflag/bytes.go +++ b/vendor/github.com/spf13/pflag/bytes.go @@ -18,7 +18,6 @@ func (bytesHex bytesHexValue) String() string { // Set implements pflag.Value.Set. func (bytesHex *bytesHexValue) Set(value string) error { bin, err := hex.DecodeString(strings.TrimSpace(value)) - if err != nil { return err } @@ -39,20 +38,18 @@ func newBytesHexValue(val []byte, p *[]byte) *bytesHexValue { } func bytesHexConv(sval string) (interface{}, error) { - bin, err := hex.DecodeString(sval) if err == nil { return bin, nil } - return nil, fmt.Errorf("invalid string being converted to Bytes: %s %s", sval, err) + return nil, fmt.Errorf("invalid string being converted to Bytes: %s %s", sval, err.Error()) } // GetBytesHex return the []byte value of a flag with the given name func (f *FlagSet) GetBytesHex(name string) ([]byte, error) { val, err := f.getFlagType(name, "bytesHex", bytesHexConv) - if err != nil { return []byte{}, err } @@ -119,7 +116,6 @@ func (bytesBase64 bytesBase64Value) String() string { // Set implements pflag.Value.Set. func (bytesBase64 *bytesBase64Value) Set(value string) error { bin, err := base64.StdEncoding.DecodeString(strings.TrimSpace(value)) - if err != nil { return err } @@ -140,19 +136,17 @@ func newBytesBase64Value(val []byte, p *[]byte) *bytesBase64Value { } func bytesBase64ValueConv(sval string) (interface{}, error) { - bin, err := base64.StdEncoding.DecodeString(sval) if err == nil { return bin, nil } - return nil, fmt.Errorf("invalid string being converted to Bytes: %s %s", sval, err) + return nil, fmt.Errorf("invalid string being converted to Bytes: %s %s", sval, err.Error()) } // GetBytesBase64 return the []byte value of a flag with the given name func (f *FlagSet) GetBytesBase64(name string) ([]byte, error) { val, err := f.getFlagType(name, "bytesBase64", bytesBase64ValueConv) - if err != nil { return []byte{}, err } diff --git a/vendor/github.com/spf13/pflag/count.go b/vendor/github.com/spf13/pflag/count.go index d49c0143..d09afc39 100644 --- a/vendor/github.com/spf13/pflag/count.go +++ b/vendor/github.com/spf13/pflag/count.go @@ -13,12 +13,15 @@ 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 = *i + 1 return nil } v, err := strconv.ParseInt(s, 0, 0) + if err != nil { + return err + } *i = countValue(v) - return err + return nil } func (i *countValue) Type() string { diff --git a/vendor/github.com/spf13/pflag/duration.go b/vendor/github.com/spf13/pflag/duration.go index e9debef8..f5d78b74 100644 --- a/vendor/github.com/spf13/pflag/duration.go +++ b/vendor/github.com/spf13/pflag/duration.go @@ -1,6 +1,7 @@ package pflag import ( + "errors" "time" ) @@ -14,8 +15,11 @@ func newDurationValue(val time.Duration, p *time.Duration) *durationValue { func (d *durationValue) Set(s string) error { v, err := time.ParseDuration(s) + if err != nil { + return errors.New(`must be a duration like "30s" or "5m"`) + } *d = durationValue(v) - return err + return nil } func (d *durationValue) Type() string { diff --git a/vendor/github.com/spf13/pflag/duration_slice.go b/vendor/github.com/spf13/pflag/duration_slice.go index badadda5..ee987274 100644 --- a/vendor/github.com/spf13/pflag/duration_slice.go +++ b/vendor/github.com/spf13/pflag/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/vendor/github.com/spf13/pflag/errors.go b/vendor/github.com/spf13/pflag/errors.go index ff11b66b..63765ddc 100644 --- a/vendor/github.com/spf13/pflag/errors.go +++ b/vendor/github.com/spf13/pflag/errors.go @@ -10,7 +10,6 @@ type notExistErrorMessageType int const ( flagNotExistMessage notExistErrorMessageType = iota - flagNotDefinedMessage flagNoSuchFlagMessage flagUnknownFlagMessage flagUnknownShorthandFlagMessage @@ -30,9 +29,6 @@ func (e *NotExistError) Error() string { case flagNotExistMessage: return fmt.Sprintf("flag %q does not exist", e.name) - case flagNotDefinedMessage: - return fmt.Sprintf("flag accessed but not defined: %s", e.name) - case flagNoSuchFlagMessage: return fmt.Sprintf("no such flag -%v", e.name) @@ -142,7 +138,7 @@ func (e *InvalidSyntaxError) Error() string { return fmt.Sprintf("bad flag syntax: %s", e.specifiedFlag) } -// GetSpecifiedName returns the exact flag (with dashes) as it +// GetSpecifiedFlag returns the exact flag (with dashes) as it // appeared in the parsed arguments. func (e *InvalidSyntaxError) GetSpecifiedFlag() string { return e.specifiedFlag diff --git a/vendor/github.com/spf13/pflag/flag.go b/vendor/github.com/spf13/pflag/flag.go index 2fd3c575..2670bb79 100644 --- a/vendor/github.com/spf13/pflag/flag.go +++ b/vendor/github.com/spf13/pflag/flag.go @@ -137,10 +137,29 @@ const ( PanicOnError ) +// UnknownFlagsHandling decides how to handle unknown flags +type UnknownFlagsHandling int + +const ( + // ErrorOnUnknownFlag will return an error if an unknown flag is found + ErrorOnUnknownFlag UnknownFlagsHandling = iota + // IgnoreUnknownFlag will ignore unknown flags and continue parsing rest of the flags + IgnoreUnknownFlag + // PassUnknownFlagToArgs will treat unknown flags as non-flag arguments. + // Combined shorthand flags mixed with known ones and unknown ones results + // combined flags only with unknown ones. + // E.g. -fghi results -gh if only `f` and `i` are known. + PassUnknownFlagToArgs +) + // ParseErrorsAllowlist defines the parsing errors that can be ignored type ParseErrorsAllowlist struct { // UnknownFlags will ignore unknown flags errors and continue parsing rest of the flags + // Deprecated: Use UnknownFlagsHandling instead UnknownFlags bool + + // UnknownFlagsHandling decides how to handle unknown flags. Defaults to UnknownFlagsHandlingErrorOnUnknown. + UnknownFlagsHandling UnknownFlagsHandling } // ParseErrorsWhitelist defines the parsing errors that can be ignored. @@ -270,7 +289,7 @@ func (f *FlagSet) GetNormalizeFunc() func(f *FlagSet, name string) NormalizedNam if f.normalizeNameFunc != nil { return f.normalizeNameFunc } - return func(f *FlagSet, name string) NormalizedName { return NormalizedName(name) } + return func(_ *FlagSet, name string) NormalizedName { return NormalizedName(name) } } func (f *FlagSet) normalizeFlagName(name string) NormalizedName { @@ -337,6 +356,35 @@ func (f *FlagSet) HasAvailableFlags() bool { return false } +// getUnknownFlagsHandling returns the UnknownFlagsHandling value, +// considering deprecated ParseErrorsWhitelist and UnknownFlags field +// After removing ParseErrorsWhitelist, this function can be simplified +// and moved to ParseErrorsAllowlist.getUnknownFlagsHandling() +func (f *FlagSet) getUnknownFlagsHandling() UnknownFlagsHandling { + // first check ParseErrorsAllowlist: + // if UnknownFlagsHandling is set, use it + if f.ParseErrorsAllowlist.UnknownFlagsHandling != ErrorOnUnknownFlag { + return f.ParseErrorsAllowlist.UnknownFlagsHandling + } + + if f.ParseErrorsAllowlist.UnknownFlags { + return IgnoreUnknownFlag + } + + // then, check deprecated ParseErrorsWhitelist: + // if UnknownFlagsHandling is set, use it + if f.ParseErrorsWhitelist.UnknownFlagsHandling != ErrorOnUnknownFlag { + return f.ParseErrorsWhitelist.UnknownFlagsHandling + } + + if f.ParseErrorsWhitelist.UnknownFlags { + return IgnoreUnknownFlag + } + + // Otherwise, return the default value + return ErrorOnUnknownFlag +} + // VisitAll visits the command-line flags in lexicographical order or // in primordial order if f.SortFlags is false, calling fn for each. // It visits all flags, even those not set. @@ -388,7 +436,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.Fprint(f.Output(), msg) panic(msg) } c := name[0] @@ -400,11 +448,16 @@ func (f *FlagSet) lookup(name NormalizedName) *Flag { return f.formal[name] } -// func to return a given type for a given flag name +// getFlagType performs a lookup of a flag with the given name and ftype. The flag is stringified and passed through +// convFunc before being returned to enforce flag immutablility. +// +// convFunc may be nil, in which case the raw flag value is returned directly and no immutability is enforced. This is +// particularly useful when users need to access the pointer of the underlying flag value for manipulation (e.g. +// resetting flag values in tests). func (f *FlagSet) getFlagType(name string, ftype string, convFunc func(sval string) (interface{}, error)) (interface{}, error) { flag := f.Lookup(name) if flag == nil { - err := &NotExistError{name: name, messageType: flagNotDefinedMessage} + err := &NotExistError{name: name, messageType: flagNotExistMessage} return nil, err } @@ -413,6 +466,10 @@ func (f *FlagSet) getFlagType(name string, ftype string, convFunc func(sval stri return nil, err } + if convFunc == nil { + return flag.Value, nil + } + sval := flag.Value.String() result, err := convFunc(sval) if err != nil { @@ -510,7 +567,7 @@ func (f *FlagSet) Set(name, value string) error { } if flag.Deprecated != "" { - fmt.Fprintf(f.Output(), "Flag --%s has been deprecated, %s\n", flag.Name, flag.Deprecated) + _, _ = fmt.Fprintf(f.Output(), "Flag --%s has been deprecated, %s\n", name, flag.Deprecated) } return nil } @@ -551,15 +608,16 @@ func Set(name, value string) error { // otherwise, the default values of all defined flags in the set. func (f *FlagSet) PrintDefaults() { usages := f.FlagUsages() - fmt.Fprint(f.Output(), usages) + _, _ = fmt.Fprint(f.Output(), usages) } // defaultIsZeroValue returns true if the default value for this flag represents // a zero value. func (f *Flag) defaultIsZeroValue() bool { - switch f.Value.(type) { - case boolFlag: + if isNoOptBoolValue(f.Value) { return f.DefValue == "false" || f.DefValue == "" + } + switch f.Value.(type) { case *durationValue: // Beginning in Go 1.7, duration zero values are "0s" return f.DefValue == "0" || f.DefValue == "0s" @@ -608,6 +666,9 @@ func UnquoteUsage(flag *Flag) (name string, usage string) { } name = flag.Value.Type() + if isNoOptBoolValue(flag.Value) { + name = "" + } switch name { case "bool", "boolfunc": name = "" @@ -635,7 +696,9 @@ func UnquoteUsage(flag *Flag) (name string, usage string) { // Splits the string `s` on whitespace into an initial substring up to // `i` runes in length and the remainder. Will go `slop` over `i` if // that encompasses the entire string (which allows the caller to -// avoid short orphan words on the final line). +// avoid short orphan words on the final line). If the next word is +// wider than `i`, it is returned on its own and wrapping continues +// after it. func wrapN(i, slop int, s string) (string, string) { if i+slop > len(s) { return s, "" @@ -643,7 +706,13 @@ func wrapN(i, slop int, s string) (string, string) { w := strings.LastIndexAny(s[:i], " \t\n") if w <= 0 { - return s, "" + // No break in the first i bytes. Emit the over-wide word + // alone and keep wrapping whatever follows. + next := strings.IndexAny(s, " \t\n") + if next <= 0 { + return s, "" + } + return s[:next], s[next+1:] } nlPos := strings.LastIndex(s[:i], "\n") if nlPos > 0 && nlPos < w { @@ -657,7 +726,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 @@ -675,7 +744,7 @@ 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 @@ -687,18 +756,17 @@ func wrap(i, w int, s string) string { // 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 = 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 - } // FlagUsagesWrapped returns a string containing the usage information @@ -723,9 +791,12 @@ func (f *FlagSet) FlagUsagesWrapped(cols int) string { } varname, usage := UnquoteUsage(flag) - if varname != "" { + if isNoOptBoolValue(flag.Value) && flag.Value.Type() == "bool" { + line += "[=true|false]" + } else if varname != "" { line += " " + varname } + if flag.NoOptDefVal != "" { switch flag.Value.Type() { case "string": @@ -769,7 +840,7 @@ func (f *FlagSet) FlagUsagesWrapped(cols int) string { sidx := strings.Index(line, "\x00") spacing := strings.Repeat(" ", maxlen-sidx) // maxlen + 2 comes from + 1 for the \x00 and + 1 for the (deliberate) off-by-one in maxlen-sidx - fmt.Fprintln(buf, line[:sidx], spacing, wrap(maxlen+2, cols, line[sidx+1:])) + _, _ = fmt.Fprintln(buf, line[:sidx], spacing, wrap(maxlen+2, cols, line[sidx+1:])) } return buf.String() @@ -788,7 +859,7 @@ func PrintDefaults() { // defaultUsage is the default function to print a usage message. func defaultUsage(f *FlagSet) { - fmt.Fprintf(f.Output(), "Usage of %s:\n", f.name) + _, _ = fmt.Fprintf(f.Output(), "Usage of %s:\n", f.name) f.PrintDefaults() } @@ -796,12 +867,13 @@ func defaultUsage(f *FlagSet) { // because it serves (via godoc flag Usage) as the example // for how to write your own usage function. -// Usage prints to standard error a usage message documenting all defined command-line flags. -// The function is a variable that may be changed to point to a custom function. -// By default it prints a simple header and calls PrintDefaults; for details about the -// format of the output and how to control it, see the documentation for PrintDefaults. +// Usage prints, to the set destination, a usage message documenting all defined +// command-line flags. The function is a variable that may be changed to point to a +// custom function. By default it prints a simple header and calls PrintDefaults; for +// details about the format of the output and how to control it, see the documentation +// for PrintDefaults. var Usage = func() { - fmt.Fprintf(os.Stderr, "Usage of %s:\n", os.Args[0]) + _, _ = fmt.Fprintf(CommandLine.Output(), "Usage of %s:\n", os.Args[0]) PrintDefaults() } @@ -874,7 +946,7 @@ func (f *FlagSet) AddFlag(flag *Flag) { _, alreadyThere := f.formal[normalizedFlagName] if alreadyThere { msg := fmt.Sprintf("%s flag redefined: %s", f.name, flag.Name) - fmt.Fprintln(f.Output(), msg) + _, _ = fmt.Fprintln(f.Output(), msg) panic(msg) // Happens only if flags are declared with identical names } if f.formal == nil { @@ -882,6 +954,9 @@ func (f *FlagSet) AddFlag(flag *Flag) { } flag.Name = string(normalizedFlagName) + if flag.NoOptDefVal == "" && isNoOptBoolValue(flag.Value) { + flag.NoOptDefVal = "true" + } f.formal[normalizedFlagName] = flag f.orderedFormal = append(f.orderedFormal, flag) @@ -890,7 +965,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.Fprint(f.Output(), msg) panic(msg) } if f.shorthands == nil { @@ -900,7 +975,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.Fprint(f.Output(), msg) panic(msg) } f.shorthands[c] = flag @@ -960,23 +1035,34 @@ func (f *FlagSet) usage() { // --unknown arg ... (args will be arg ...) func stripUnknownFlagValue(args []string) []string { if len(args) == 0 { - //--unknown + // --unknown return args } first := args[0] if len(first) > 0 && first[0] == '-' { - //--unknown --next-flag ... + // --unknown --next-flag ... return args } - //--unknown arg ... (args will be arg ...) + // --unknown arg ... (args will be arg ...) if len(args) > 1 { return args[1:] } return nil } +// errUnknownFlag is used for internal unknown flag handling. +type unknownFlagError struct { + // UnknownFlags is flags that are unknown and unprocessed. + // It depends on the context whether this has a prefix like '-' or '--'. + UnknownFlags string +} + +func (e *unknownFlagError) Error() string { + return fmt.Sprintf("unknown flag: %v", e.UnknownFlags) +} + func (f *FlagSet) parseLongArg(s string, args []string, fn parseFunc) (a []string, err error) { a = args name := s[2:] @@ -988,15 +1074,14 @@ func (f *FlagSet) parseLongArg(s string, args []string, fn parseFunc) (a []strin split := strings.SplitN(name, "=", 2) name = split[0] flag, exists := f.formal[f.normalizeFlagName(name)] + unknownFlagsHandling := f.getUnknownFlagsHandling() if !exists { switch { case name == "help": f.usage() return a, ErrHelp - case f.ParseErrorsWhitelist.UnknownFlags: - fallthrough - case f.ParseErrorsAllowlist.UnknownFlags: + case unknownFlagsHandling == IgnoreUnknownFlag: // --unknown=unknownval arg ... // we do not want to lose arg in this case if len(split) >= 2 { @@ -1004,6 +1089,10 @@ func (f *FlagSet) parseLongArg(s string, args []string, fn parseFunc) (a []strin } return stripUnknownFlagValue(a), nil + case unknownFlagsHandling == PassUnknownFlagToArgs: + return a, &unknownFlagError{ + UnknownFlags: s, + } default: err = f.fail(&NotExistError{name: name, messageType: flagUnknownFlagMessage}) return @@ -1030,9 +1119,11 @@ func (f *FlagSet) parseLongArg(s string, args []string, fn parseFunc) (a []strin return } - err = fn(flag, value) + // Pass the name the user actually typed so a deprecation message reports + // it rather than the canonical name a NormalizeFunc may have mapped it to. + err = fn(flag, name, value) if err != nil { - f.fail(err) + err = f.fail(err) } return } @@ -1049,14 +1140,14 @@ func (f *FlagSet) parseSingleShortArg(shorthands string, args []string, fn parse flag, exists := f.shorthands[c] if !exists { + unknownFlagsHandling := f.getUnknownFlagsHandling() + switch { case c == 'h': f.usage() err = ErrHelp return - case f.ParseErrorsWhitelist.UnknownFlags: - fallthrough - case f.ParseErrorsAllowlist.UnknownFlags: + case unknownFlagsHandling == IgnoreUnknownFlag: // '-f=arg arg ...' // we do not want to lose arg in this case if len(shorthands) > 2 && shorthands[1] == '=' { @@ -1066,6 +1157,20 @@ func (f *FlagSet) parseSingleShortArg(shorthands string, args []string, fn parse outArgs = stripUnknownFlagValue(outArgs) return + case unknownFlagsHandling == PassUnknownFlagToArgs: + // '-f=arg': pass all the argument + if len(shorthands) > 2 && shorthands[1] == '=' { + outShorts = "" + err = &unknownFlagError{ + UnknownFlags: shorthands, + } + return + } + // '-fgh': pass only the first switch + err = &unknownFlagError{ + UnknownFlags: shorthands[0:1], + } + return default: err = f.fail(&NotExistError{ name: string(c), @@ -1103,12 +1208,12 @@ func (f *FlagSet) parseSingleShortArg(shorthands string, args []string, fn parse } if flag.ShorthandDeprecated != "" { - fmt.Fprintf(f.Output(), "Flag shorthand -%s has been deprecated, %s\n", flag.Shorthand, flag.ShorthandDeprecated) + _, _ = fmt.Fprintf(f.Output(), "Flag shorthand -%s has been deprecated, %s\n", flag.Shorthand, flag.ShorthandDeprecated) } - err = fn(flag, value) + err = fn(flag, flag.Name, value) if err != nil { - f.fail(err) + err = f.fail(err) } return } @@ -1116,14 +1221,31 @@ func (f *FlagSet) parseSingleShortArg(shorthands string, args []string, fn parse func (f *FlagSet) parseShortArg(s string, args []string, fn parseFunc) (a []string, err error) { a = args shorthands := s[1:] + var errUnknownFlagAll *unknownFlagError // "shorthands" can be a series of shorthand letters of flags (e.g. "-vvv"). for len(shorthands) > 0 { shorthands, a, err = f.parseSingleShortArg(shorthands, args, fn) if err != nil { - return + if errUnknownFlag, ok := err.(*unknownFlagError); ok { //nolint:errorlint + // this means f.ParseErrorsAllowlist.UnknownFlagsHandling is set to UnknownFlagsHandlingPassUnknownToArgs + if errUnknownFlagAll == nil { + errUnknownFlagAll = &unknownFlagError{ + UnknownFlags: "-", + } + } + + errUnknownFlagAll.UnknownFlags = errUnknownFlagAll.UnknownFlags + + errUnknownFlag.UnknownFlags + err = nil + } else { + return + } } } + if errUnknownFlagAll != nil { + err = errUnknownFlagAll + } return } @@ -1153,7 +1275,13 @@ func (f *FlagSet) parseArgs(args []string, fn parseFunc) (err error) { args, err = f.parseShortArg(s, args, fn) } if err != nil { - return + if errUnknownFlag, ok := err.(*unknownFlagError); ok { //nolint:errorlint + // this means f.ParseErrorsAllowlist.UnknownFlagsHandling is set to UnknownFlagsHandlingPassUnknownToArgs + f.args = append(f.args, errUnknownFlag.UnknownFlags) + err = nil + } else { + return + } } } return @@ -1166,7 +1294,7 @@ 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 @@ -1177,8 +1305,8 @@ func (f *FlagSet) Parse(arguments []string) error { return nil } - set := func(flag *Flag, value string) error { - return f.Set(flag.Name, value) + set := func(_ *Flag, name, value string) error { + return f.Set(name, value) } err := f.parseArgs(arguments, set) @@ -1187,10 +1315,10 @@ func (f *FlagSet) Parse(arguments []string) error { case ContinueOnError: return err case ExitOnError: - if err == ErrHelp { + if err == ErrHelp { //nolint:errorlint // not using errors.Is for compatibility with go1.12 os.Exit(0) } - fmt.Fprintln(f.Output(), err) + _, _ = fmt.Fprintln(f.Output(), err) os.Exit(2) case PanicOnError: panic(err) @@ -1199,7 +1327,7 @@ func (f *FlagSet) Parse(arguments []string) error { return nil } -type parseFunc func(flag *Flag, value string) error +type parseFunc func(flag *Flag, name, value string) error // ParseAll parses flag definitions from the argument list, which should not // include the command name. The arguments for fn are flag and value. Must be @@ -1210,16 +1338,20 @@ func (f *FlagSet) ParseAll(arguments []string, fn func(flag *Flag, value string) f.parsed = true f.args = make([]string, 0, len(arguments)) - err := f.parseArgs(arguments, fn) + set := func(flag *Flag, _, value string) error { + return fn(flag, value) + } + + err := f.parseArgs(arguments, set) if err != nil { switch f.errorHandling { case ContinueOnError: return err case ExitOnError: - if err == ErrHelp { + if err == ErrHelp { //nolint:errorlint // not using errors.Is for compatibility with go1.12 os.Exit(0) } - fmt.Fprintln(f.Output(), err) + _, _ = fmt.Fprintln(f.Output(), err) os.Exit(2) case PanicOnError: panic(err) @@ -1237,7 +1369,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. @@ -1245,7 +1377,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/vendor/github.com/spf13/pflag/float32.go b/vendor/github.com/spf13/pflag/float32.go index a243f81f..95ba4da2 100644 --- a/vendor/github.com/spf13/pflag/float32.go +++ b/vendor/github.com/spf13/pflag/float32.go @@ -1,6 +1,9 @@ package pflag -import "strconv" +import ( + "errors" + "strconv" +) // -- float32 Value type float32Value float32 @@ -12,8 +15,11 @@ func newFloat32Value(val float32, p *float32) *float32Value { func (f *float32Value) Set(s string) error { v, err := strconv.ParseFloat(s, 32) + if err != nil { + return errors.New("must be a number") + } *f = float32Value(v) - return err + return nil } func (f *float32Value) Type() string { diff --git a/vendor/github.com/spf13/pflag/float64.go b/vendor/github.com/spf13/pflag/float64.go index 04b5492a..67f0a1e0 100644 --- a/vendor/github.com/spf13/pflag/float64.go +++ b/vendor/github.com/spf13/pflag/float64.go @@ -1,6 +1,9 @@ package pflag -import "strconv" +import ( + "errors" + "strconv" +) // -- float64 Value type float64Value float64 @@ -12,8 +15,11 @@ func newFloat64Value(val float64, p *float64) *float64Value { func (f *float64Value) Set(s string) error { v, err := strconv.ParseFloat(s, 64) + if err != nil { + return errors.New("must be a number") + } *f = float64Value(v) - return err + return nil } func (f *float64Value) Type() string { diff --git a/vendor/github.com/spf13/pflag/golangflag.go b/vendor/github.com/spf13/pflag/golangflag.go index e62eab53..6e653c26 100644 --- a/vendor/github.com/spf13/pflag/golangflag.go +++ b/vendor/github.com/spf13/pflag/golangflag.go @@ -71,14 +71,14 @@ 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 // ignore "func name will be used as pflag.PFlagFromGoFlag by other packages, and that stutters" // Remember the default value as a string; it won't change. flag := &Flag{ Name: goflag.Name, Usage: goflag.Usage, Value: wrapFlagValue(goflag.Value), // Looks like golang flags don't set DefValue correctly :-( - //DefValue: goflag.DefValue, + // DefValue: goflag.DefValue, DefValue: goflag.Value.String(), } // Ex: if the golang flag was -v, allow both -v and --v to work @@ -127,7 +127,7 @@ func (f *FlagSet) CopyToGoFlagSet(newSet *goflag.FlagSet) { switch value := flag.Value.(type) { case *stringValue: - newSet.StringVar((*string)(value), flag.Name, flag.DefValue, usage) + newSet.StringVar((*string)(value), flag.Name, *(*string)(value), usage) case *intValue: newSet.IntVar((*int)(value), flag.Name, *(*int)(value), usage) case *int64Value: @@ -158,4 +158,3 @@ func ParseSkippedFlags(osArgs []string, goFlagSet *goflag.FlagSet) error { } return goFlagSet.Parse(skippedFlags) } - diff --git a/vendor/github.com/spf13/pflag/int.go b/vendor/github.com/spf13/pflag/int.go index 1474b89d..45e83bf6 100644 --- a/vendor/github.com/spf13/pflag/int.go +++ b/vendor/github.com/spf13/pflag/int.go @@ -1,6 +1,9 @@ package pflag -import "strconv" +import ( + "errors" + "strconv" +) // -- int Value type intValue int @@ -11,9 +14,12 @@ func newIntValue(val int, p *int) *intValue { } func (i *intValue) Set(s string) error { - v, err := strconv.ParseInt(s, 0, 64) + v, err := strconv.ParseInt(s, 0, 0) + if err != nil { + return errors.New("must be an integer") + } *i = intValue(v) - return err + return nil } func (i *intValue) Type() string { diff --git a/vendor/github.com/spf13/pflag/int16.go b/vendor/github.com/spf13/pflag/int16.go index f1a01d05..880bc2a7 100644 --- a/vendor/github.com/spf13/pflag/int16.go +++ b/vendor/github.com/spf13/pflag/int16.go @@ -1,6 +1,9 @@ package pflag -import "strconv" +import ( + "errors" + "strconv" +) // -- int16 Value type int16Value int16 @@ -12,8 +15,11 @@ func newInt16Value(val int16, p *int16) *int16Value { func (i *int16Value) Set(s string) error { v, err := strconv.ParseInt(s, 0, 16) + if err != nil { + return errors.New("must be an integer") + } *i = int16Value(v) - return err + return nil } func (i *int16Value) Type() string { diff --git a/vendor/github.com/spf13/pflag/int32.go b/vendor/github.com/spf13/pflag/int32.go index 9b95944f..2e0944d6 100644 --- a/vendor/github.com/spf13/pflag/int32.go +++ b/vendor/github.com/spf13/pflag/int32.go @@ -1,6 +1,9 @@ package pflag -import "strconv" +import ( + "errors" + "strconv" +) // -- int32 Value type int32Value int32 @@ -12,8 +15,11 @@ func newInt32Value(val int32, p *int32) *int32Value { func (i *int32Value) Set(s string) error { v, err := strconv.ParseInt(s, 0, 32) + if err != nil { + return errors.New("must be an integer") + } *i = int32Value(v) - return err + return nil } func (i *int32Value) Type() string { diff --git a/vendor/github.com/spf13/pflag/int64.go b/vendor/github.com/spf13/pflag/int64.go index 0026d781..2f7ae522 100644 --- a/vendor/github.com/spf13/pflag/int64.go +++ b/vendor/github.com/spf13/pflag/int64.go @@ -1,6 +1,9 @@ package pflag -import "strconv" +import ( + "errors" + "strconv" +) // -- int64 Value type int64Value int64 @@ -12,8 +15,11 @@ func newInt64Value(val int64, p *int64) *int64Value { func (i *int64Value) Set(s string) error { v, err := strconv.ParseInt(s, 0, 64) + if err != nil { + return errors.New("must be an integer") + } *i = int64Value(v) - return err + return nil } func (i *int64Value) Type() string { diff --git a/vendor/github.com/spf13/pflag/int8.go b/vendor/github.com/spf13/pflag/int8.go index 4da92228..91fea1a6 100644 --- a/vendor/github.com/spf13/pflag/int8.go +++ b/vendor/github.com/spf13/pflag/int8.go @@ -1,6 +1,9 @@ package pflag -import "strconv" +import ( + "errors" + "strconv" +) // -- int8 Value type int8Value int8 @@ -12,8 +15,11 @@ func newInt8Value(val int8, p *int8) *int8Value { func (i *int8Value) Set(s string) error { v, err := strconv.ParseInt(s, 0, 8) + if err != nil { + return errors.New("must be an integer") + } *i = int8Value(v) - return err + return nil } func (i *int8Value) Type() string { diff --git a/vendor/github.com/spf13/pflag/ip.go b/vendor/github.com/spf13/pflag/ip.go index 06b8bcb5..046f48b3 100644 --- a/vendor/github.com/spf13/pflag/ip.go +++ b/vendor/github.com/spf13/pflag/ip.go @@ -32,6 +32,9 @@ func (i *ipValue) Type() string { } func ipConv(sval string) (interface{}, error) { + if sval == "" || sval == "" { + return net.IP(nil), nil + } ip := net.ParseIP(sval) if ip != nil { return ip, nil diff --git a/vendor/github.com/spf13/pflag/ip_slice.go b/vendor/github.com/spf13/pflag/ip_slice.go index 775faae4..699f399f 100644 --- a/vendor/github.com/spf13/pflag/ip_slice.go +++ b/vendor/github.com/spf13/pflag/ip_slice.go @@ -23,13 +23,12 @@ func newIPSliceValue(val []net.IP, p *[]net.IP) *ipSliceValue { // Set converts, and assigns, the comma-separated IP argument string representation as the []net.IP value of this flag. // If Set is called on a flag that already has a []net.IP assigned, the newly converted values will be appended. func (s *ipSliceValue) Set(val string) error { - // remove all quote characters rmQuote := strings.NewReplacer(`"`, "", `'`, "", "`", "") // read flag arguments with CSV parser ipStrSlice, err := readAsCSV(rmQuote.Replace(val)) - if err != nil && err != io.EOF { + if err != nil && err != io.EOF { //nolint:errorlint // not using errors.Is for compatibility with go1.12 return err } @@ -61,7 +60,6 @@ func (s *ipSliceValue) Type() string { // String defines a "native" format for this net.IP slice flag value. func (s *ipSliceValue) String() string { - ipStrSlice := make([]string, len(*s.value)) for i, ip := range *s.value { ipStrSlice[i] = ip.String() @@ -73,7 +71,11 @@ func (s *ipSliceValue) String() string { } func (s *ipSliceValue) fromString(val string) (net.IP, error) { - return net.ParseIP(strings.TrimSpace(val)), nil + ip := net.ParseIP(strings.TrimSpace(val)) + if ip == nil { + return nil, fmt.Errorf("invalid string being converted to IP address: %s", val) + } + return ip, nil } func (s *ipSliceValue) toString(val net.IP) string { @@ -81,22 +83,22 @@ func (s *ipSliceValue) toString(val net.IP) string { } func (s *ipSliceValue) Append(val string) error { - i, err := s.fromString(val) + ip, err := s.fromString(val) if err != nil { return err } - *s.value = append(*s.value, i) + *s.value = append(*s.value, ip) return nil } func (s *ipSliceValue) Replace(val []string) error { out := make([]net.IP, len(val)) for i, d := range val { - var err error - out[i], err = s.fromString(d) + ip, err := s.fromString(d) if err != nil { return err } + out[i] = ip } *s.value = out return nil diff --git a/vendor/github.com/spf13/pflag/ipmask.go b/vendor/github.com/spf13/pflag/ipmask.go index 5bd44bd2..228d4e92 100644 --- a/vendor/github.com/spf13/pflag/ipmask.go +++ b/vendor/github.com/spf13/pflag/ipmask.go @@ -53,7 +53,11 @@ func ParseIPv4Mask(s string) net.IPMask { return nil } } - return net.IPv4Mask(mask[12], mask[13], mask[14], mask[15]) + mask = mask.To4() + if mask == nil { + return nil + } + return net.IPv4Mask(mask[0], mask[1], mask[2], mask[3]) } func parseIPv4Mask(sval string) (interface{}, error) { diff --git a/vendor/github.com/spf13/pflag/ipnet_slice.go b/vendor/github.com/spf13/pflag/ipnet_slice.go index c6e89da1..c051fbd2 100644 --- a/vendor/github.com/spf13/pflag/ipnet_slice.go +++ b/vendor/github.com/spf13/pflag/ipnet_slice.go @@ -23,13 +23,12 @@ func newIPNetSliceValue(val []net.IPNet, p *[]net.IPNet) *ipNetSliceValue { // Set converts, and assigns, the comma-separated IPNet argument string representation as the []net.IPNet value of this flag. // If Set is called on a flag that already has a []net.IPNet assigned, the newly converted values will be appended. func (s *ipNetSliceValue) Set(val string) error { - // remove all quote characters rmQuote := strings.NewReplacer(`"`, "", `'`, "", "`", "") // read flag arguments with CSV parser ipNetStrSlice, err := readAsCSV(rmQuote.Replace(val)) - if err != nil && err != io.EOF { + if err != nil && err != io.EOF { //nolint:errorlint // not using errors.Is for compatibility with go1.12 return err } @@ -61,7 +60,6 @@ func (s *ipNetSliceValue) Type() string { // String defines a "native" format for this net.IPNet slice flag value. func (s *ipNetSliceValue) String() string { - ipNetStrSlice := make([]string, len(*s.value)) for i, n := range *s.value { ipNetStrSlice[i] = n.String() diff --git a/vendor/github.com/spf13/pflag/string.go b/vendor/github.com/spf13/pflag/string.go index 04e0a26f..c96b8020 100644 --- a/vendor/github.com/spf13/pflag/string.go +++ b/vendor/github.com/spf13/pflag/string.go @@ -12,6 +12,7 @@ func (s *stringValue) Set(val string) error { *s = stringValue(val) return nil } + func (s *stringValue) Type() string { return "string" } diff --git a/vendor/github.com/spf13/pflag/string_array.go b/vendor/github.com/spf13/pflag/string_array.go index d1ff0a96..2404407f 100644 --- a/vendor/github.com/spf13/pflag/string_array.go +++ b/vendor/github.com/spf13/pflag/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 } diff --git a/vendor/github.com/spf13/pflag/string_slice.go b/vendor/github.com/spf13/pflag/string_slice.go index 3cb2e69d..d421887e 100644 --- a/vendor/github.com/spf13/pflag/string_slice.go +++ b/vendor/github.com/spf13/pflag/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/vendor/github.com/spf13/pflag/string_to_string.go b/vendor/github.com/spf13/pflag/string_to_string.go index 1d1e3bf9..87bfe678 100644 --- a/vendor/github.com/spf13/pflag/string_to_string.go +++ b/vendor/github.com/spf13/pflag/string_to_string.go @@ -4,6 +4,7 @@ import ( "bytes" "encoding/csv" "fmt" + "io" "sort" "strings" ) @@ -21,7 +22,7 @@ func newStringToStringValue(val map[string]string, p *map[string]string) *string return ssv } -// Format: a=1,b=2 +// Set updates the flag value from the given string, adding additional mappings or updating existing ones. func (s *stringToStringValue) Set(val string) error { var ss []string n := strings.Count(val, "=") @@ -37,6 +38,9 @@ func (s *stringToStringValue) Set(val string) error { if err != nil { return err } + if _, err := r.Read(); err != io.EOF { + return fmt.Errorf("must be a single CSV record; quote fields containing newlines") + } } out := make(map[string]string, len(ss)) @@ -47,13 +51,20 @@ func (s *stringToStringValue) Set(val string) error { } out[kv[0]] = kv[1] } + + // clear out any default flag values if !s.changed { - *s.value = out - } else { - for k, v := range out { - (*s.value)[k] = v + for k := range *s.value { + delete(*s.value, k) } } + + if *s.value == nil { + *s.value = make(map[string]string, len(out)) + } + for k, v := range out { + (*s.value)[k] = v + } s.changed = true return nil } @@ -81,88 +92,113 @@ func (s *stringToStringValue) String() string { panic(err) } w.Flush() - return "[" + strings.TrimSpace(buf.String()) + "]" + return "[" + strings.TrimSuffix(buf.String(), "\n") + "]" } -func stringToStringConv(val string) (interface{}, error) { - val = strings.Trim(val, "[]") - // An empty string would cause an empty map - if len(val) == 0 { - return map[string]string{}, nil - } - r := csv.NewReader(strings.NewReader(val)) - ss, err := r.Read() - if err != nil { - return nil, err - } - out := make(map[string]string, len(ss)) - for _, pair := range ss { - kv := strings.SplitN(pair, "=", 2) - if len(kv) != 2 { - return nil, fmt.Errorf("%s must be formatted as key=value", pair) - } - out[kv[0]] = kv[1] - } - return out, nil -} - -// GetStringToString return the map[string]string value of a flag with the given name +// GetStringToString return the map value of a flag with the given name from f. The returned map shares memory with the +// internal flag value [Flag.Value]. func (f *FlagSet) GetStringToString(name string) (map[string]string, error) { - val, err := f.getFlagType(name, "stringToString", stringToStringConv) + val, err := f.getFlagType(name, "stringToString", nil) if err != nil { return map[string]string{}, err } - return val.(map[string]string), nil -} - -// StringToStringVar defines a string flag with specified name, default value, and usage string. -// The argument p points to a map[string]string variable in which to store the values of the multiple flags. -// The value of each argument will not try to be separated by comma -func (f *FlagSet) StringToStringVar(p *map[string]string, name string, value map[string]string, usage string) { - f.VarP(newStringToStringValue(value, p), name, "", usage) -} - -// StringToStringVarP is like StringToStringVar, but accepts a shorthand letter that can be used after a single dash. -func (f *FlagSet) StringToStringVarP(p *map[string]string, name, shorthand string, value map[string]string, usage string) { - f.VarP(newStringToStringValue(value, p), name, shorthand, usage) -} -// StringToStringVar defines a string flag with specified name, default value, and usage string. -// The argument p points to a map[string]string variable in which to store the value of the flag. -// The value of each argument will not try to be separated by comma -func StringToStringVar(p *map[string]string, name string, value map[string]string, usage string) { - CommandLine.VarP(newStringToStringValue(value, p), name, "", usage) -} + fv, ok := val.(*stringToStringValue) + if !ok { + panic(fmt.Errorf("illegal state: unspected internal type for stringToString flag '%s'", name)) + } + if fv.value == nil { + return nil, nil + } -// StringToStringVarP is like StringToStringVar, but accepts a shorthand letter that can be used after a single dash. -func StringToStringVarP(p *map[string]string, name, shorthand string, value map[string]string, usage string) { - CommandLine.VarP(newStringToStringValue(value, p), name, shorthand, usage) + return *fv.value, nil } -// StringToString defines a string flag with specified name, default value, and usage string. -// The return value is the address of a map[string]string variable that stores the value of the flag. -// The value of each argument will not try to be separated by comma +// StringToString defines a map flag with specified name, default value, and usage string. +// +// StringToString flags are used to pass key=value pairs to applications. The same flag can be provided more than once +// with all key=value pairs being merged into a final map. Multiple key=value pairs may be provided in a single arg, +// separated by commas. A few simple examples include: +// +// --arg a=1 -> map[string]string{ "a": "1" } +// --arg a=1 --arg b=2 -> map[string]string{ "a": "1", "b": "2" } +// --arg a=1,b=2 -> map[string]string{ "a": "1", "b": "2" } +// --arg=a=1 -> map[string]string{ "a": "1" } +// +// As a special case, a single key=value pair whose value contains a comma will be interpreted as shown below: +// +// --arg a=1,2 -> map[string]string{ "a": "1,2" } +// +// Arguments containing multiple '=' characters are parsed as one CSV record. +// Quote the entire key=value field to preserve commas, quotes, or newlines in +// its value. When invoking a command from a shell, preserve the CSV quotes, +// for example by enclosing the argument in single quotes: +// +// --arg '"a=first,second=value"' -> map[string]string{ "a": "first,second=value" } +// +// Multiple unquoted CSV records in one argument are rejected rather than +// silently discarding mappings after the first record. +// +// Returns a pointer to the map which will be updated upon invocation of [FlagSet.Parse], [Flag.Value.Set], and others. func (f *FlagSet) StringToString(name string, value map[string]string, usage string) *map[string]string { p := map[string]string{} f.StringToStringVarP(&p, name, "", value, usage) return &p } -// StringToStringP is like StringToString, but accepts a shorthand letter that can be used after a single dash. +// StringToStringP is like [FlagSet.StringToString], but also accepts a shorthand letter that can be used after a single +// dash. +// +// See [FlagSet.StringToString]. func (f *FlagSet) StringToStringP(name, shorthand string, value map[string]string, usage string) *map[string]string { p := map[string]string{} f.StringToStringVarP(&p, name, shorthand, value, usage) return &p } +// StringToStringVar is like [FlagSet.StringToString], but also accepts a map pointer argument p which is updated with +// the parsed key-value pairs. +// +// See [FlagSet.StringToString]. +func (f *FlagSet) StringToStringVar(p *map[string]string, name string, value map[string]string, usage string) { + f.VarP(newStringToStringValue(value, p), name, "", usage) +} + +// StringToStringVarP is like [FlagSet.StringToString], but also accepts a map pointer argument p which is updated with +// the parsed key-value pairs, and a shorthand letter that can be used after a single dash. +// +// See [FlagSet.StringToString]. +func (f *FlagSet) StringToStringVarP(p *map[string]string, name, shorthand string, value map[string]string, usage string) { + f.VarP(newStringToStringValue(value, p), name, shorthand, usage) +} + // StringToString defines a string flag with specified name, default value, and usage string. -// The return value is the address of a map[string]string variable that stores the value of the flag. -// The value of each argument will not try to be separated by comma +// +// See [FlagSet.StringToString]. func StringToString(name string, value map[string]string, usage string) *map[string]string { return CommandLine.StringToStringP(name, "", value, usage) } -// StringToStringP is like StringToString, but accepts a shorthand letter that can be used after a single dash. +// StringToStringP is like [FlagSet.StringToString], but also accepts a shorthand letter that can be used after a single +// dash. +// +// See [FlagSet.StringToString]. func StringToStringP(name, shorthand string, value map[string]string, usage string) *map[string]string { return CommandLine.StringToStringP(name, shorthand, value, usage) } + +// StringToStringVar is like [FlagSet.StringToString], but also accepts a map pointer argument p which is updated with +// the parsed key-value pairs. +// +// See [FlagSet.StringToString]. +func StringToStringVar(p *map[string]string, name string, value map[string]string, usage string) { + CommandLine.VarP(newStringToStringValue(value, p), name, "", usage) +} + +// StringToStringVarP is like [FlagSet.StringToString], but also accepts a map pointer argument p which is updated with +// the parsed key-value pairs, and a shorthand letter that can be used after a single dash. +// +// See [FlagSet.StringToString]. +func StringToStringVarP(p *map[string]string, name, shorthand string, value map[string]string, usage string) { + CommandLine.VarP(newStringToStringValue(value, p), name, shorthand, usage) +} diff --git a/vendor/github.com/spf13/pflag/text.go b/vendor/github.com/spf13/pflag/text.go index 886d5a3d..834bbaf6 100644 --- a/vendor/github.com/spf13/pflag/text.go +++ b/vendor/github.com/spf13/pflag/text.go @@ -42,10 +42,9 @@ func (v textValue) String() string { return "" } -//end of copy - +// end of copy func (v textValue) Type() string { - return reflect.ValueOf(v.p).Type().Name() + return reflect.TypeOf(v.p).String() } // GetText set out, which implements encoding.UnmarshalText, to the value of a flag with given name @@ -54,8 +53,8 @@ func (f *FlagSet) GetText(name string, out encoding.TextUnmarshaler) error { if flag == nil { return fmt.Errorf("flag accessed but not defined: %s", name) } - if flag.Value.Type() != reflect.TypeOf(out).Name() { - return fmt.Errorf("trying to get %s value of flag of type %s", reflect.TypeOf(out).Name(), flag.Value.Type()) + if flag.Value.Type() != reflect.TypeOf(out).String() { + return fmt.Errorf("trying to get %s value of flag of type %s", reflect.TypeOf(out).String(), flag.Value.Type()) } return out.UnmarshalText([]byte(flag.Value.String())) } diff --git a/vendor/github.com/spf13/pflag/time.go b/vendor/github.com/spf13/pflag/time.go index 3dee4247..fe457dea 100644 --- a/vendor/github.com/spf13/pflag/time.go +++ b/vendor/github.com/spf13/pflag/time.go @@ -51,9 +51,8 @@ func (d *timeValue) Type() string { func (d *timeValue) String() string { if d.Time.IsZero() { return "" - } else { - return d.Time.Format(time.RFC3339Nano) } + return d.Time.Format(time.RFC3339Nano) } // GetTime return the time value of a flag with the given name diff --git a/vendor/github.com/spf13/pflag/uint.go b/vendor/github.com/spf13/pflag/uint.go index dcbc2b75..802df0b6 100644 --- a/vendor/github.com/spf13/pflag/uint.go +++ b/vendor/github.com/spf13/pflag/uint.go @@ -1,6 +1,9 @@ package pflag -import "strconv" +import ( + "errors" + "strconv" +) // -- uint Value type uintValue uint @@ -11,9 +14,12 @@ func newUintValue(val uint, p *uint) *uintValue { } func (i *uintValue) Set(s string) error { - v, err := strconv.ParseUint(s, 0, 64) + v, err := strconv.ParseUint(s, 0, 0) + if err != nil { + return errors.New("must be a non-negative integer") + } *i = uintValue(v) - return err + return nil } func (i *uintValue) Type() string { diff --git a/vendor/github.com/spf13/pflag/uint16.go b/vendor/github.com/spf13/pflag/uint16.go index 7e9914ed..b086a368 100644 --- a/vendor/github.com/spf13/pflag/uint16.go +++ b/vendor/github.com/spf13/pflag/uint16.go @@ -1,6 +1,9 @@ package pflag -import "strconv" +import ( + "errors" + "strconv" +) // -- uint16 value type uint16Value uint16 @@ -12,8 +15,11 @@ func newUint16Value(val uint16, p *uint16) *uint16Value { func (i *uint16Value) Set(s string) error { v, err := strconv.ParseUint(s, 0, 16) + if err != nil { + return errors.New("must be a non-negative integer") + } *i = uint16Value(v) - return err + return nil } func (i *uint16Value) Type() string { diff --git a/vendor/github.com/spf13/pflag/uint32.go b/vendor/github.com/spf13/pflag/uint32.go index d8024539..ae56168d 100644 --- a/vendor/github.com/spf13/pflag/uint32.go +++ b/vendor/github.com/spf13/pflag/uint32.go @@ -1,6 +1,9 @@ package pflag -import "strconv" +import ( + "errors" + "strconv" +) // -- uint32 value type uint32Value uint32 @@ -12,8 +15,11 @@ func newUint32Value(val uint32, p *uint32) *uint32Value { func (i *uint32Value) Set(s string) error { v, err := strconv.ParseUint(s, 0, 32) + if err != nil { + return errors.New("must be a non-negative integer") + } *i = uint32Value(v) - return err + return nil } func (i *uint32Value) Type() string { diff --git a/vendor/github.com/spf13/pflag/uint64.go b/vendor/github.com/spf13/pflag/uint64.go index f62240f2..ffbdc072 100644 --- a/vendor/github.com/spf13/pflag/uint64.go +++ b/vendor/github.com/spf13/pflag/uint64.go @@ -1,6 +1,9 @@ package pflag -import "strconv" +import ( + "errors" + "strconv" +) // -- uint64 Value type uint64Value uint64 @@ -12,8 +15,11 @@ func newUint64Value(val uint64, p *uint64) *uint64Value { func (i *uint64Value) Set(s string) error { v, err := strconv.ParseUint(s, 0, 64) + if err != nil { + return errors.New("must be a non-negative integer") + } *i = uint64Value(v) - return err + return nil } func (i *uint64Value) Type() string { @@ -27,7 +33,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/vendor/github.com/spf13/pflag/uint8.go b/vendor/github.com/spf13/pflag/uint8.go index bb0e83c1..bca63f67 100644 --- a/vendor/github.com/spf13/pflag/uint8.go +++ b/vendor/github.com/spf13/pflag/uint8.go @@ -1,6 +1,9 @@ package pflag -import "strconv" +import ( + "errors" + "strconv" +) // -- uint8 Value type uint8Value uint8 @@ -12,8 +15,11 @@ func newUint8Value(val uint8, p *uint8) *uint8Value { func (i *uint8Value) Set(s string) error { v, err := strconv.ParseUint(s, 0, 8) + if err != nil { + return errors.New("must be a non-negative integer") + } *i = uint8Value(v) - return err + return nil } func (i *uint8Value) Type() string { diff --git a/vendor/github.com/spf13/pflag/uint_slice.go b/vendor/github.com/spf13/pflag/uint_slice.go index 5fa92483..d38e124e 100644 --- a/vendor/github.com/spf13/pflag/uint_slice.go +++ b/vendor/github.com/spf13/pflag/uint_slice.go @@ -23,7 +23,7 @@ func (s *uintSliceValue) Set(val string) error { ss := strings.Split(val, ",") out := make([]uint, len(ss)) for i, d := range ss { - u, err := strconv.ParseUint(d, 10, 0) + u, err := strconv.ParseUint(d, 0, 0) if err != nil { return err } @@ -51,7 +51,7 @@ func (s *uintSliceValue) String() string { } func (s *uintSliceValue) fromString(val string) (uint, error) { - t, err := strconv.ParseUint(val, 10, 0) + t, err := strconv.ParseUint(val, 0, 0) if err != nil { return 0, err } @@ -101,7 +101,7 @@ func uintSliceConv(val string) (interface{}, error) { ss := strings.Split(val, ",") out := make([]uint, len(ss)) for i, d := range ss { - u, err := strconv.ParseUint(d, 10, 0) + u, err := strconv.ParseUint(d, 0, 0) if err != nil { return nil, err } diff --git a/vendor/modules.txt b/vendor/modules.txt index c81c8d7b..455841d0 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -206,7 +206,7 @@ github.com/samber/lo/mutable ## explicit; go 1.15 github.com/spf13/cobra github.com/spf13/cobra/doc -# github.com/spf13/pflag v1.0.10 +# github.com/spf13/pflag v1.1.0 ## explicit; go 1.12 github.com/spf13/pflag # github.com/stretchr/testify v1.11.1