pax_global_header00006660000000000000000000000064150555047350014523gustar00rootroot0000000000000052 comment=0491e5702ad2bb108bc519a5221bcc0f52aa9564 spf13-pflag-0491e57/000077500000000000000000000000001505550473500140265ustar00rootroot00000000000000spf13-pflag-0491e57/.editorconfig000066400000000000000000000002561505550473500165060ustar00rootroot00000000000000root = true [*] charset = utf-8 end_of_line = lf indent_size = 4 indent_style = space insert_final_newline = true trim_trailing_whitespace = true [*.go] indent_style = tab spf13-pflag-0491e57/.github/000077500000000000000000000000001505550473500153665ustar00rootroot00000000000000spf13-pflag-0491e57/.github/.editorconfig000066400000000000000000000000411505550473500200360ustar00rootroot00000000000000[{*.yml,*.yaml}] indent_size = 2 spf13-pflag-0491e57/.github/dependabot.yaml000066400000000000000000000003031505550473500203530ustar00rootroot00000000000000version: 2 updates: - package-ecosystem: gomod directory: / schedule: interval: daily - package-ecosystem: github-actions directory: / schedule: interval: daily spf13-pflag-0491e57/.github/workflows/000077500000000000000000000000001505550473500174235ustar00rootroot00000000000000spf13-pflag-0491e57/.github/workflows/ci.yaml000066400000000000000000000022331505550473500207020ustar00rootroot00000000000000name: CI on: push: branches: [master] pull_request: jobs: test: name: Test runs-on: ubuntu-latest strategy: fail-fast: false matrix: go: ["1.12", "1.21", "1.22", "1.23"] steps: - name: Checkout repository uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - name: Set up Go uses: actions/setup-go@3041bf56c941b39c61721a86cd11f3bb1338122a # v5.2.0 with: go-version: ${{ matrix.go }} - name: Test # Cannot enable shuffle for now because some tests rely on global state and order # run: go test -race -v -shuffle=on ./... run: go test -race -v ./... lint: name: Lint runs-on: ubuntu-latest steps: - name: Checkout repository uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - name: Set up Go uses: actions/setup-go@3041bf56c941b39c61721a86cd11f3bb1338122a # v5.2.0 with: go-version: "1.23" - name: Lint uses: golangci/golangci-lint-action@971e284b6050e8a5849b72094c50ab08da042db8 # v6.1.1 with: version: v1.63.4 spf13-pflag-0491e57/.gitignore000066400000000000000000000000111505550473500160060ustar00rootroot00000000000000.idea/* spf13-pflag-0491e57/.golangci.yaml000066400000000000000000000001001505550473500165420ustar00rootroot00000000000000linters: disable-all: true enable: - nolintlint spf13-pflag-0491e57/.travis.yml000066400000000000000000000004051505550473500161360ustar00rootroot00000000000000sudo: false language: go go: - 1.9.x - 1.10.x - 1.11.x - tip matrix: allow_failures: - go: tip install: - go get golang.org/x/lint/golint - export PATH=$GOPATH/bin:$PATH - go install ./... script: - verify/all.sh -v - go test ./... spf13-pflag-0491e57/LICENSE000066400000000000000000000027731505550473500150440ustar00rootroot00000000000000Copyright (c) 2012 Alex Ogier. All rights reserved. Copyright (c) 2012 The Go Authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of Google Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. spf13-pflag-0491e57/README.md000066400000000000000000000253201505550473500153070ustar00rootroot00000000000000[![Build Status](https://travis-ci.org/spf13/pflag.svg?branch=master)](https://travis-ci.org/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) ## Description pflag is a drop-in replacement for Go's flag package, implementing POSIX/GNU-style --flags. 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 pflag is available under the same style of BSD license as the Go language, which can be found in the LICENSE file. ## Installation pflag is available using the standard `go get` command. Install by running: go get github.com/spf13/pflag Run tests by running: go test github.com/spf13/pflag ## Usage pflag is a drop-in replacement of Go's native flag package. If you import pflag under the name "flag" then all code should continue to function with no changes. ``` go import flag "github.com/spf13/pflag" ``` There is one exception to this: if you directly instantiate the Flag struct there is one more field "Shorthand" that you will need to set. Most code never instantiates this struct directly, and instead uses functions such as String(), BoolVar(), and Var(), and is therefore unaffected. Define flags using flag.String(), Bool(), Int(), etc. This declares an integer flag, -flagname, stored in the pointer ip, with type *int. ``` go var ip *int = flag.Int("flagname", 1234, "help message for flagname") ``` If you like, you can bind the flag to a variable using the Var() functions. ``` go 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 ``` go 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 ``` go 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. ``` go fmt.Println("ip has value ", *ip) fmt.Println("flagvar has value ", flagvar) ``` There are helper functions available to get the value stored in a Flag if you have a FlagSet but find it difficult to keep up with all of the pointers in your code. If you have a pflag.FlagSet with a flag called 'flagname' of type int you can use GetInt() to get the int value. But notice that 'flagname' must exist and it must be an int. GetString("flagname") will fail. ``` go i, err := flagset.GetInt("flagname") ``` After parsing, the arguments after the flag are available as the slice flag.Args() or individually as flag.Arg(i). 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. ``` go 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. The default set of command-line flags is controlled by top-level functions. The FlagSet type allows one to define independent sets of flags, such as to implement subcommands in a command-line interface. The methods of FlagSet are analogous to the top-level functions for the command-line flag set. ## Setting no option default values for flags After you create a flag it is possible to set the pflag.NoOptDefVal for the given flag. Doing this changes the meaning of the flag slightly. If a flag has a NoOptDefVal and the flag is set on the command line without an option the flag will be set to the NoOptDefVal. For example given: ``` go var ip = flag.IntP("flagname", "f", 1234, "help message") flag.Lookup("flagname").NoOptDefVal = "4321" ``` Would result in something like | Parsed Arguments | Resulting Value | | ------------- | ------------- | | --flagname=1357 | ip=1357 | | --flagname | ip=4321 | | [nothing] | ip=1234 | ## Command line flag syntax ``` --flag // boolean flags, or flags with no option default values --flag x // only on flags without a default value --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 or a flag with a default value ``` // boolean or flags where the 'no option default value' is set -f -f=true -abc but -b true is INVALID // non-boolean and flags without a 'no option default value' -n 1234 -n=1234 -n1234 // mixed -abcs "hello" -absd="hello" -abcs1234 ``` Flag parsing stops after the terminator "--". Unlike the flag package, flags can be interspersed with arguments anywhere on the command line before this terminator. 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. Duration flags accept any input valid for time.ParseDuration. ## Mutating or "Normalizing" Flag names It is possible to set a custom flag name 'normalization function.' It allows flag names to be mutated both when created in the code and when used on the command line to some 'normalized' form. The 'normalized' form is used for comparison. Two examples of using the custom normalization func follow. **Example #1**: You want -, _, and . in flags to compare the same. aka --my-flag == --my_flag == --my.flag ``` go func wordSepNormalizeFunc(f *pflag.FlagSet, name string) pflag.NormalizedName { from := []string{"-", "_"} to := "." for _, sep := range from { name = strings.Replace(name, sep, to, -1) } return pflag.NormalizedName(name) } myFlagSet.SetNormalizeFunc(wordSepNormalizeFunc) ``` **Example #2**: You want to alias two flags. aka --old-flag-name == --new-flag-name ``` go func aliasNormalizeFunc(f *pflag.FlagSet, name string) pflag.NormalizedName { switch name { case "old-flag-name": name = "new-flag-name" break } return pflag.NormalizedName(name) } myFlagSet.SetNormalizeFunc(aliasNormalizeFunc) ``` ## Deprecating a flag or its shorthand It is possible to deprecate a flag, or just its shorthand. Deprecating a flag/shorthand hides it from help text and prints a usage message when the deprecated flag/shorthand is used. **Example #1**: You want to deprecate a flag named "badflag" as well as inform the users what flag they should use instead. ```go // deprecate a flag by specifying its name and a usage message flags.MarkDeprecated("badflag", "please use --good-flag instead") ``` This hides "badflag" from help text, and prints `Flag --badflag has been deprecated, please use --good-flag instead` when "badflag" is used. **Example #2**: You want to keep a flag name "noshorthandflag" but deprecate its shortname "n". ```go // deprecate a flag shorthand by specifying its flag name and a usage message flags.MarkShorthandDeprecated("noshorthandflag", "please use --noshorthandflag only") ``` This hides the shortname "n" from help text, and prints `Flag shorthand -n has been deprecated, please use --noshorthandflag only` when the shorthand "n" is used. Note that usage message is essential here, and it should not be empty. ## Hidden flags It is possible to mark a flag as hidden, meaning it will still function as normal, however will not show up in usage/help text. **Example**: You have a flag named "secretFlag" that you need for internal use only and don't want it showing up in help text, or for its usage text to be available. ```go // hide a flag by specifying its name flags.MarkHidden("secretFlag") ``` ## Disable sorting of flags `pflag` allows you to disable sorting of flags for help and usage message. **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() ``` **Output**: ``` -v, --verbose verbose output --coolflag string it's really cool flag (default "yeaah") --usefulflag int sometimes it's very useful (default 777) ``` ## Supporting Go flags when using pflag In order to support flags defined using Go's `flag` package, they must be added to the `pflag` flagset. This is usually necessary 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 import ( goflag "flag" flag "github.com/spf13/pflag" ) var ip *int = flag.Int("flagname", 1234, "help message for flagname") func main() { flag.CommandLine.AddGoFlagSet(goflag.CommandLine) flag.Parse() } ``` ### Using pflag with go test `pflag` does not parse the shorthand versions of go test's built-in flags (i.e., those starting with `-test.`). For more context, see issues [#63](https://github.com/spf13/pflag/issues/63) and [#238](https://github.com/spf13/pflag/issues/238) for more details. For example, if you use pflag in your `TestMain` function and call `pflag.Parse()` after defining your custom flags, running a test like this: ```bash go test /your/tests -run ^YourTest -v --your-test-pflags ``` will result in the `-v` flag being ignored. This happens because of the way pflag handles flag parsing, skipping over go test's built-in shorthand flags. 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 import ( goflag "flag" flag "github.com/spf13/pflag" ) var ip *int = flag.Int("flagname", 1234, "help message for flagname") func main() { flag.CommandLine.AddGoFlagSet(goflag.CommandLine) flag.ParseSkippedFlags(os.Args[1:], goflag.CommandLine) flag.Parse() } ``` ## 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. [2]: http://localhost:6060/pkg/github.com/spf13/pflag [3]: http://godoc.org/github.com/spf13/pflag spf13-pflag-0491e57/bool.go000066400000000000000000000060001505550473500153040ustar00rootroot00000000000000package pflag import "strconv" // optional interface to indicate boolean flags that can be // supplied without "=value" text type boolFlag interface { Value IsBoolFlag() bool } // -- bool Value type boolValue bool func newBoolValue(val bool, p *bool) *boolValue { *p = val return (*boolValue)(p) } func (b *boolValue) Set(s string) error { v, err := strconv.ParseBool(s) *b = boolValue(v) return err } func (b *boolValue) Type() string { return "bool" } func (b *boolValue) String() string { return strconv.FormatBool(bool(*b)) } func (b *boolValue) IsBoolFlag() bool { return true } func boolConv(sval string) (interface{}, error) { return strconv.ParseBool(sval) } // GetBool return the bool value of a flag with the given name func (f *FlagSet) GetBool(name string) (bool, error) { val, err := f.getFlagType(name, "bool", boolConv) if err != nil { return false, err } return val.(bool), nil } // BoolVar defines a bool flag with specified name, default value, and usage string. // The argument p points to a bool variable in which to store the value of the flag. func (f *FlagSet) BoolVar(p *bool, name string, value bool, usage string) { f.BoolVarP(p, name, "", value, usage) } // BoolVarP is like BoolVar, but accepts a shorthand letter that can be used after a single dash. func (f *FlagSet) BoolVarP(p *bool, name, shorthand string, value bool, usage string) { flag := f.VarPF(newBoolValue(value, p), name, shorthand, usage) flag.NoOptDefVal = "true" } // BoolVar defines a bool flag with specified name, default value, and usage string. // The argument p points to a bool variable in which to store the value of the flag. func BoolVar(p *bool, name string, value bool, usage string) { BoolVarP(p, name, "", value, usage) } // BoolVarP is like BoolVar, but accepts a shorthand letter that can be used after a single dash. func BoolVarP(p *bool, name, shorthand string, value bool, usage string) { flag := CommandLine.VarPF(newBoolValue(value, p), name, shorthand, usage) flag.NoOptDefVal = "true" } // Bool defines a bool flag with specified name, default value, and usage string. // The return value is the address of a bool variable that stores the value of the flag. func (f *FlagSet) Bool(name string, value bool, usage string) *bool { return f.BoolP(name, "", value, usage) } // BoolP is like Bool, but accepts a shorthand letter that can be used after a single dash. func (f *FlagSet) BoolP(name, shorthand string, value bool, usage string) *bool { p := new(bool) f.BoolVarP(p, name, shorthand, value, usage) return p } // Bool defines a bool flag with specified name, default value, and usage string. // The return value is the address of a bool variable that stores the value of the flag. func Bool(name string, value bool, usage string) *bool { return BoolP(name, "", value, usage) } // BoolP is like Bool, but accepts a shorthand letter that can be used after a single dash. func BoolP(name, shorthand string, value bool, usage string) *bool { b := CommandLine.BoolP(name, shorthand, value, usage) return b } spf13-pflag-0491e57/bool_func.go000066400000000000000000000030231505550473500163210ustar00rootroot00000000000000package pflag // -- func Value type boolfuncValue func(string) error func (f boolfuncValue) Set(s string) error { return f(s) } func (f boolfuncValue) Type() string { return "boolfunc" } func (f boolfuncValue) String() string { return "" } // same behavior as stdlib 'flag' package func (f boolfuncValue) IsBoolFlag() bool { return true } // BoolFunc defines a func flag with specified name, callback function and usage string. // // The callback function will be called every time "--{name}" (or any form that matches the flag) is parsed // on the command line. func (f *FlagSet) BoolFunc(name string, usage string, fn func(string) error) { f.BoolFuncP(name, "", usage, fn) } // BoolFuncP is like BoolFunc, but accepts a shorthand letter that can be used after a single dash. func (f *FlagSet) BoolFuncP(name, shorthand string, usage string, fn func(string) error) { var val Value = boolfuncValue(fn) flag := f.VarPF(val, name, shorthand, usage) flag.NoOptDefVal = "true" } // BoolFunc defines a func flag with specified name, callback function and usage string. // // The callback function will be called every time "--{name}" (or any form that matches the flag) is parsed // on the command line. func BoolFunc(name string, usage string, fn func(string) error) { CommandLine.BoolFuncP(name, "", usage, fn) } // BoolFuncP is like BoolFunc, but accepts a shorthand letter that can be used after a single dash. func BoolFuncP(name, shorthand string, usage string, fn func(string) error) { CommandLine.BoolFuncP(name, shorthand, usage, fn) } spf13-pflag-0491e57/bool_func_go1.21_test.go000066400000000000000000000073321505550473500203560ustar00rootroot00000000000000//go:build go1.21 // +build go1.21 package pflag import ( "errors" "flag" "io" "strings" "testing" ) func TestBoolFuncCompat(t *testing.T) { // compare behavior with the stdlib 'flag' package type BoolFuncFlagSet interface { BoolFunc(name string, usage string, fn func(string) error) Parse([]string) error } unitTestErr := errors.New("unit test error") runCase := func(f BoolFuncFlagSet, name string, args []string) (values []string, err error) { fn := func(s string) error { values = append(values, s) if s == "err" { return unitTestErr } return nil } f.BoolFunc(name, "Callback function", fn) err = f.Parse(args) return values, err } t.Run("regular parsing", func(t *testing.T) { flagName := "bflag" args := []string{"--bflag", "--bflag=false", "--bflag=1", "--bflag=bar", "--bflag="} // It turns out that, even though the function is called "BoolFunc", // the standard flag package does not try to parse the value assigned to // that cli flag as a boolean. The string provided on the command line is // passed as is to the callback. // e.g: with "--bflag=not_a_bool" on the command line, the FlagSet does not // generate an error stating "invalid boolean value", and `fn` will be called // with "not_a_bool" as an argument. stdFSet := flag.NewFlagSet("std test", flag.ContinueOnError) stdValues, err := runCase(stdFSet, flagName, args) if err != nil { t.Fatalf("std flag: expected no error, got %v", err) } expected := []string{"true", "false", "1", "bar", ""} if !cmpLists(expected, stdValues) { t.Fatalf("std flag: expected %v, got %v", expected, stdValues) } fset := NewFlagSet("pflag test", ContinueOnError) pflagValues, err := runCase(fset, flagName, args) if err != nil { t.Fatalf("pflag: expected no error, got %v", err) } if !cmpLists(stdValues, pflagValues) { t.Fatalf("pflag: expected %v, got %v", stdValues, pflagValues) } }) t.Run("error triggered by callback", func(t *testing.T) { flagName := "bflag" args := []string{"--bflag", "--bflag=err", "--bflag=after"} // test behavior of standard flag.Fset with an error triggered by the callback: // (note: as can be seen in 'runCase()', if the callback sees "err" as a value // for the bool flag, it will return an error) stdFSet := flag.NewFlagSet("std test", flag.ContinueOnError) stdFSet.SetOutput(io.Discard) // suppress output // run test case with standard flag.Fset stdValues, err := runCase(stdFSet, flagName, args) // double check the standard behavior: // - .Parse() should return an error, which contains the error message if err == nil { t.Fatalf("std flag: expected an error triggered by callback, got no error instead") } if !strings.HasSuffix(err.Error(), unitTestErr.Error()) { t.Fatalf("std flag: expected unittest error, got unexpected error value: %T %v", err, err) } // - the function should have been called twice, with the first two values, // the final "=after" should not be recorded expected := []string{"true", "err"} if !cmpLists(expected, stdValues) { t.Fatalf("std flag: expected %v, got %v", expected, stdValues) } // now run the test case on a pflag FlagSet: fset := NewFlagSet("pflag test", ContinueOnError) pflagValues, err := runCase(fset, flagName, args) // check that there is a similar error (note: pflag will _wrap_ the error, while the stdlib // currently keeps the original message but creates a flat errors.Error) if !errors.Is(err, unitTestErr) { t.Fatalf("pflag: got unexpected error value: %T %v", err, err) } // the callback should be called the same number of times, with the same values: if !cmpLists(stdValues, pflagValues) { t.Fatalf("pflag: expected %v, got %v", stdValues, pflagValues) } }) } spf13-pflag-0491e57/bool_func_test.go000066400000000000000000000041461505550473500173670ustar00rootroot00000000000000package pflag import ( "strings" "testing" ) func TestBoolFunc(t *testing.T) { var count int fn := func(_ string) error { count++ return nil } fset := NewFlagSet("test", ContinueOnError) fset.BoolFunc("func", "Callback function", fn) err := fset.Parse([]string{"--func", "--func=1", "--func=false"}) if err != nil { t.Fatal("expected no error; got", err) } if count != 3 { t.Fatalf("expected 3 calls to the callback, got %d calls", count) } } func TestBoolFuncP(t *testing.T) { var count int fn := func(_ string) error { count++ return nil } fset := NewFlagSet("test", ContinueOnError) fset.BoolFuncP("bfunc", "b", "Callback function", fn) err := fset.Parse([]string{"--bfunc", "--bfunc=0", "--bfunc=false", "-b", "-b=0"}) if err != nil { t.Fatal("expected no error; got", err) } if count != 5 { t.Fatalf("expected 5 calls to the callback, got %d calls", count) } } func TestBoolFuncUsage(t *testing.T) { t.Run("regular func flag", func(t *testing.T) { // regular boolfunc flag: // expect to see '--flag1' followed by the usageMessage, and no mention of a default value fset := NewFlagSet("unittest", ContinueOnError) fset.BoolFunc("flag1", "usage message", func(s string) error { return nil }) usage := fset.FlagUsagesWrapped(80) usage = strings.TrimSpace(usage) expected := "--flag1 usage message" if usage != expected { t.Fatalf("unexpected generated usage message\n expected: %s\n got: %s", expected, usage) } }) t.Run("func flag with placeholder name", func(t *testing.T) { // func flag, with a placeholder name: // if usageMesage contains a placeholder, expect '--flag2 {placeholder}'; still expect no mention of a default value fset := NewFlagSet("unittest", ContinueOnError) fset.BoolFunc("flag2", "usage message with `name` placeholder", func(s string) error { return nil }) usage := fset.FlagUsagesWrapped(80) usage = strings.TrimSpace(usage) expected := "--flag2 name usage message with name placeholder" if usage != expected { t.Fatalf("unexpected generated usage message\n expected: %s\n got: %s", expected, usage) } }) } spf13-pflag-0491e57/bool_slice.go000066400000000000000000000123111505550473500164650ustar00rootroot00000000000000package pflag import ( "io" "strconv" "strings" ) // -- boolSlice Value type boolSliceValue struct { value *[]bool changed bool } func newBoolSliceValue(val []bool, p *[]bool) *boolSliceValue { bsv := new(boolSliceValue) bsv.value = p *bsv.value = val return bsv } // 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 { return err } // parse boolean values into slice out := make([]bool, 0, len(boolStrSlice)) for _, boolStr := range boolStrSlice { b, err := strconv.ParseBool(strings.TrimSpace(boolStr)) if err != nil { return err } out = append(out, b) } if !s.changed { *s.value = out } else { *s.value = append(*s.value, out...) } s.changed = true return nil } // Type returns a string that uniquely represents this flag's type. func (s *boolSliceValue) Type() string { return "boolSlice" } // 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) } out, _ := writeAsCSV(boolStrSlice) return "[" + out + "]" } func (s *boolSliceValue) fromString(val string) (bool, error) { return strconv.ParseBool(val) } func (s *boolSliceValue) toString(val bool) string { return strconv.FormatBool(val) } func (s *boolSliceValue) Append(val string) error { i, err := s.fromString(val) if err != nil { return err } *s.value = append(*s.value, i) return nil } func (s *boolSliceValue) Replace(val []string) error { out := make([]bool, len(val)) for i, d := range val { var err error out[i], err = s.fromString(d) if err != nil { return err } } *s.value = out return nil } func (s *boolSliceValue) GetSlice() []string { out := make([]string, len(*s.value)) for i, d := range *s.value { out[i] = s.toString(d) } return out } func boolSliceConv(val string) (interface{}, error) { val = strings.Trim(val, "[]") // Empty string would cause a slice with one (empty) entry if len(val) == 0 { return []bool{}, nil } ss := strings.Split(val, ",") out := make([]bool, len(ss)) for i, t := range ss { var err error out[i], err = strconv.ParseBool(t) if err != nil { return nil, err } } return out, nil } // GetBoolSlice returns the []bool value of a flag with the given name. func (f *FlagSet) GetBoolSlice(name string) ([]bool, error) { val, err := f.getFlagType(name, "boolSlice", boolSliceConv) if err != nil { return []bool{}, err } return val.([]bool), nil } // BoolSliceVar defines a boolSlice flag with specified name, default value, and usage string. // The argument p points to a []bool variable in which to store the value of the flag. func (f *FlagSet) BoolSliceVar(p *[]bool, name string, value []bool, usage string) { f.VarP(newBoolSliceValue(value, p), name, "", usage) } // BoolSliceVarP is like BoolSliceVar, but accepts a shorthand letter that can be used after a single dash. func (f *FlagSet) BoolSliceVarP(p *[]bool, name, shorthand string, value []bool, usage string) { f.VarP(newBoolSliceValue(value, p), name, shorthand, usage) } // BoolSliceVar defines a []bool flag with specified name, default value, and usage string. // The argument p points to a []bool variable in which to store the value of the flag. func BoolSliceVar(p *[]bool, name string, value []bool, usage string) { CommandLine.VarP(newBoolSliceValue(value, p), name, "", usage) } // BoolSliceVarP is like BoolSliceVar, but accepts a shorthand letter that can be used after a single dash. func BoolSliceVarP(p *[]bool, name, shorthand string, value []bool, usage string) { CommandLine.VarP(newBoolSliceValue(value, p), name, shorthand, usage) } // BoolSlice defines a []bool flag with specified name, default value, and usage string. // The return value is the address of a []bool variable that stores the value of the flag. func (f *FlagSet) BoolSlice(name string, value []bool, usage string) *[]bool { p := []bool{} f.BoolSliceVarP(&p, name, "", value, usage) return &p } // BoolSliceP is like BoolSlice, but accepts a shorthand letter that can be used after a single dash. func (f *FlagSet) BoolSliceP(name, shorthand string, value []bool, usage string) *[]bool { p := []bool{} f.BoolSliceVarP(&p, name, shorthand, value, usage) return &p } // BoolSlice defines a []bool flag with specified name, default value, and usage string. // The return value is the address of a []bool variable that stores the value of the flag. func BoolSlice(name string, value []bool, usage string) *[]bool { return CommandLine.BoolSliceP(name, "", value, usage) } // BoolSliceP is like BoolSlice, but accepts a shorthand letter that can be used after a single dash. func BoolSliceP(name, shorthand string, value []bool, usage string) *[]bool { return CommandLine.BoolSliceP(name, shorthand, value, usage) } spf13-pflag-0491e57/bool_slice_test.go000066400000000000000000000124671505550473500175400ustar00rootroot00000000000000package pflag import ( "fmt" "strconv" "strings" "testing" ) func setUpBSFlagSet(bsp *[]bool) *FlagSet { f := NewFlagSet("test", ContinueOnError) f.BoolSliceVar(bsp, "bs", []bool{}, "Command separated list!") return f } func setUpBSFlagSetWithDefault(bsp *[]bool) *FlagSet { f := NewFlagSet("test", ContinueOnError) f.BoolSliceVar(bsp, "bs", []bool{false, true}, "Command separated list!") return f } func TestEmptyBS(t *testing.T) { var bs []bool f := setUpBSFlagSet(&bs) err := f.Parse([]string{}) if err != nil { t.Fatal("expected no error; got", err) } getBS, err := f.GetBoolSlice("bs") if err != nil { t.Fatal("got an error from GetBoolSlice():", err) } if len(getBS) != 0 { t.Fatalf("got bs %v with len=%d but expected length=0", getBS, len(getBS)) } } func TestBS(t *testing.T) { var bs []bool f := setUpBSFlagSet(&bs) 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) } for i, v := range bs { b, err := strconv.ParseBool(vals[i]) if err != nil { t.Fatalf("got error: %v", err) } if b != v { 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) } for i, v := range getBS { b, err := strconv.ParseBool(vals[i]) if err != nil { t.Fatalf("got error: %v", err) } if b != v { t.Fatalf("expected bs[%d] to be %s but got: %t from GetBoolSlice", i, vals[i], v) } } } func TestBSDefault(t *testing.T) { var bs []bool f := setUpBSFlagSetWithDefault(&bs) vals := []string{"false", "T"} err := f.Parse([]string{}) if err != nil { t.Fatal("expected no error; got", err) } for i, v := range bs { b, err := strconv.ParseBool(vals[i]) if err != nil { t.Fatalf("got error: %v", err) } if b != v { t.Fatalf("expected bs[%d] to be %t from GetBoolSlice but got: %t", i, b, v) } } getBS, err := f.GetBoolSlice("bs") if err != nil { t.Fatal("got an error from GetBoolSlice():", err) } for i, v := range getBS { b, err := strconv.ParseBool(vals[i]) if err != nil { t.Fatal("got an error from GetBoolSlice():", err) } if b != v { t.Fatalf("expected bs[%d] to be %t from GetBoolSlice but got: %t", i, b, v) } } } func TestBSWithDefault(t *testing.T) { var bs []bool f := setUpBSFlagSetWithDefault(&bs) 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) } for i, v := range bs { b, err := strconv.ParseBool(vals[i]) if err != nil { t.Fatalf("got error: %v", err) } if b != v { t.Fatalf("expected bs[%d] to be %t but got: %t", i, b, v) } } getBS, err := f.GetBoolSlice("bs") if err != nil { t.Fatal("got an error from GetBoolSlice():", err) } for i, v := range getBS { b, err := strconv.ParseBool(vals[i]) if err != nil { t.Fatalf("got error: %v", err) } if b != v { t.Fatalf("expected bs[%d] to be %t from GetBoolSlice but got: %t", i, b, v) } } } func TestBSCalledTwice(t *testing.T) { var bs []bool f := setUpBSFlagSet(&bs) in := []string{"T,F", "T"} expected := []bool{true, false, true} argfmt := "--bs=%s" arg1 := fmt.Sprintf(argfmt, in[0]) arg2 := fmt.Sprintf(argfmt, in[1]) err := f.Parse([]string{arg1, arg2}) if err != nil { t.Fatal("expected no error; got", err) } for i, v := range bs { if expected[i] != v { t.Fatalf("expected bs[%d] to be %t but got %t", i, expected[i], v) } } } func TestBSAsSliceValue(t *testing.T) { var bs []bool f := setUpBSFlagSet(&bs) in := []string{"true", "false"} argfmt := "--bs=%s" arg1 := fmt.Sprintf(argfmt, in[0]) arg2 := fmt.Sprintf(argfmt, in[1]) err := f.Parse([]string{arg1, arg2}) if err != nil { t.Fatal("expected no error; got", err) } f.VisitAll(func(f *Flag) { if val, ok := f.Value.(SliceValue); ok { _ = val.Replace([]string{"false"}) } }) if len(bs) != 1 || bs[0] != false { t.Fatalf("Expected ss to be overwritten with 'false', but got: %v", bs) } } func TestBSBadQuoting(t *testing.T) { tests := []struct { Want []bool FlagArg []string }{ { Want: []bool{true, false, true}, FlagArg: []string{"1", "0", "true"}, }, { Want: []bool{true, false}, FlagArg: []string{"True", "F"}, }, { Want: []bool{true, false}, FlagArg: []string{"T", "0"}, }, { Want: []bool{true, false}, FlagArg: []string{"1", "0"}, }, { Want: []bool{true, false, false}, FlagArg: []string{"true,false", "false"}, }, { Want: []bool{true, false, false, true, false, true, false}, FlagArg: []string{`"true,false,false,1,0, T"`, " false "}, }, { Want: []bool{false, false, true, false, true, false, true}, FlagArg: []string{`"0, False, T,false , true,F"`, "true"}, }, } for i, test := range tests { var bs []bool f := setUpBSFlagSet(&bs) if err := f.Parse([]string{fmt.Sprintf("--bs=%s", strings.Join(test.FlagArg, ","))}); err != nil { t.Fatalf("flag parsing failed with error: %s\nparsing:\t%#v\nwant:\t\t%#v", err, test.FlagArg, test.Want[i]) } for j, b := range bs { if b != test.Want[j] { t.Fatalf("bad value parsed for test %d on bool %d:\nwant:\t%t\ngot:\t%t", i, j, test.Want[j], b) } } } } spf13-pflag-0491e57/bool_test.go000066400000000000000000000105551505550473500163550ustar00rootroot00000000000000// Copyright 2009 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. package pflag import ( "bytes" "strconv" "testing" ) // This value can be a boolean ("true", "false") or "maybe" type triStateValue int const ( triStateFalse triStateValue = 0 triStateTrue triStateValue = 1 triStateMaybe triStateValue = 2 ) const strTriStateMaybe = "maybe" func (v *triStateValue) IsBoolFlag() bool { return true } func (v *triStateValue) Get() interface{} { return triStateValue(*v) } func (v *triStateValue) Set(s string) error { if s == strTriStateMaybe { *v = triStateMaybe return nil } boolVal, err := strconv.ParseBool(s) if boolVal { *v = triStateTrue } else { *v = triStateFalse } return err } func (v *triStateValue) String() string { if *v == triStateMaybe { return strTriStateMaybe } return strconv.FormatBool(*v == triStateTrue) } // The type of the flag as required by the pflag.Value interface func (v *triStateValue) Type() string { return "version" } func setUpFlagSet(tristate *triStateValue) *FlagSet { f := NewFlagSet("test", ContinueOnError) *tristate = triStateFalse flag := f.VarPF(tristate, "tristate", "t", "tristate value (true, maybe or false)") flag.NoOptDefVal = "true" return f } func TestExplicitTrue(t *testing.T) { var tristate triStateValue f := setUpFlagSet(&tristate) err := f.Parse([]string{"--tristate=true"}) if err != nil { t.Fatal("expected no error; got", err) } if tristate != triStateTrue { t.Fatal("expected", triStateTrue, "(triStateTrue) but got", tristate, "instead") } } func TestImplicitTrue(t *testing.T) { var tristate triStateValue f := setUpFlagSet(&tristate) err := f.Parse([]string{"--tristate"}) if err != nil { t.Fatal("expected no error; got", err) } if tristate != triStateTrue { t.Fatal("expected", triStateTrue, "(triStateTrue) but got", tristate, "instead") } } func TestShortFlag(t *testing.T) { var tristate triStateValue f := setUpFlagSet(&tristate) err := f.Parse([]string{"-t"}) if err != nil { t.Fatal("expected no error; got", err) } if tristate != triStateTrue { t.Fatal("expected", triStateTrue, "(triStateTrue) but got", tristate, "instead") } } func TestShortFlagExtraArgument(t *testing.T) { var tristate triStateValue f := setUpFlagSet(&tristate) // The"maybe"turns into an arg, since short boolean options will only do true/false err := f.Parse([]string{"-t", "maybe"}) if err != nil { t.Fatal("expected no error; got", err) } if tristate != triStateTrue { t.Fatal("expected", triStateTrue, "(triStateTrue) but got", tristate, "instead") } args := f.Args() if len(args) != 1 || args[0] != "maybe" { t.Fatal("expected an extra 'maybe' argument to stick around") } } func TestExplicitMaybe(t *testing.T) { var tristate triStateValue f := setUpFlagSet(&tristate) err := f.Parse([]string{"--tristate=maybe"}) if err != nil { t.Fatal("expected no error; got", err) } if tristate != triStateMaybe { t.Fatal("expected", triStateMaybe, "(triStateMaybe) but got", tristate, "instead") } } func TestExplicitFalse(t *testing.T) { var tristate triStateValue f := setUpFlagSet(&tristate) err := f.Parse([]string{"--tristate=false"}) if err != nil { t.Fatal("expected no error; got", err) } if tristate != triStateFalse { t.Fatal("expected", triStateFalse, "(triStateFalse) but got", tristate, "instead") } } func TestImplicitFalse(t *testing.T) { var tristate triStateValue f := setUpFlagSet(&tristate) err := f.Parse([]string{}) if err != nil { t.Fatal("expected no error; got", err) } if tristate != triStateFalse { t.Fatal("expected", triStateFalse, "(triStateFalse) but got", tristate, "instead") } } func TestInvalidValue(t *testing.T) { var tristate triStateValue f := setUpFlagSet(&tristate) var buf bytes.Buffer f.SetOutput(&buf) err := f.Parse([]string{"--tristate=invalid"}) if err == nil { t.Fatal("expected an error but did not get any, tristate has value", tristate) } } func TestBoolP(t *testing.T) { b := BoolP("bool", "b", false, "bool value in CommandLine") c := BoolP("c", "c", false, "other bool value") args := []string{"--bool"} if err := CommandLine.Parse(args); err != nil { t.Error("expected no error, got ", err) } if *b != true { t.Errorf("expected b=true got b=%v", *b) } if *c != false { t.Errorf("expect c=false got c=%v", *c) } } spf13-pflag-0491e57/bytes.go000066400000000000000000000160011505550473500155010ustar00rootroot00000000000000package pflag import ( "encoding/base64" "encoding/hex" "fmt" "strings" ) // BytesHex adapts []byte for use as a flag. Value of flag is HEX encoded type bytesHexValue []byte // String implements pflag.Value.String. func (bytesHex bytesHexValue) String() string { return fmt.Sprintf("%X", []byte(bytesHex)) } // Set implements pflag.Value.Set. func (bytesHex *bytesHexValue) Set(value string) error { bin, err := hex.DecodeString(strings.TrimSpace(value)) if err != nil { return err } *bytesHex = bin return nil } // Type implements pflag.Value.Type. func (*bytesHexValue) Type() string { return "bytesHex" } func newBytesHexValue(val []byte, p *[]byte) *bytesHexValue { *p = val return (*bytesHexValue)(p) } 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) } // 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 } return val.([]byte), nil } // BytesHexVar defines an []byte flag with specified name, default value, and usage string. // The argument p points to an []byte variable in which to store the value of the flag. func (f *FlagSet) BytesHexVar(p *[]byte, name string, value []byte, usage string) { f.VarP(newBytesHexValue(value, p), name, "", usage) } // BytesHexVarP is like BytesHexVar, but accepts a shorthand letter that can be used after a single dash. func (f *FlagSet) BytesHexVarP(p *[]byte, name, shorthand string, value []byte, usage string) { f.VarP(newBytesHexValue(value, p), name, shorthand, usage) } // BytesHexVar defines an []byte flag with specified name, default value, and usage string. // The argument p points to an []byte variable in which to store the value of the flag. func BytesHexVar(p *[]byte, name string, value []byte, usage string) { CommandLine.VarP(newBytesHexValue(value, p), name, "", usage) } // BytesHexVarP is like BytesHexVar, but accepts a shorthand letter that can be used after a single dash. func BytesHexVarP(p *[]byte, name, shorthand string, value []byte, usage string) { CommandLine.VarP(newBytesHexValue(value, p), name, shorthand, usage) } // BytesHex defines an []byte flag with specified name, default value, and usage string. // The return value is the address of an []byte variable that stores the value of the flag. func (f *FlagSet) BytesHex(name string, value []byte, usage string) *[]byte { p := new([]byte) f.BytesHexVarP(p, name, "", value, usage) return p } // BytesHexP is like BytesHex, but accepts a shorthand letter that can be used after a single dash. func (f *FlagSet) BytesHexP(name, shorthand string, value []byte, usage string) *[]byte { p := new([]byte) f.BytesHexVarP(p, name, shorthand, value, usage) return p } // BytesHex defines an []byte flag with specified name, default value, and usage string. // The return value is the address of an []byte variable that stores the value of the flag. func BytesHex(name string, value []byte, usage string) *[]byte { return CommandLine.BytesHexP(name, "", value, usage) } // BytesHexP is like BytesHex, but accepts a shorthand letter that can be used after a single dash. func BytesHexP(name, shorthand string, value []byte, usage string) *[]byte { return CommandLine.BytesHexP(name, shorthand, value, usage) } // BytesBase64 adapts []byte for use as a flag. Value of flag is Base64 encoded type bytesBase64Value []byte // String implements pflag.Value.String. func (bytesBase64 bytesBase64Value) String() string { return base64.StdEncoding.EncodeToString([]byte(bytesBase64)) } // 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 } *bytesBase64 = bin return nil } // Type implements pflag.Value.Type. func (*bytesBase64Value) Type() string { return "bytesBase64" } func newBytesBase64Value(val []byte, p *[]byte) *bytesBase64Value { *p = val return (*bytesBase64Value)(p) } 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) } // 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 } return val.([]byte), nil } // BytesBase64Var defines an []byte flag with specified name, default value, and usage string. // The argument p points to an []byte variable in which to store the value of the flag. func (f *FlagSet) BytesBase64Var(p *[]byte, name string, value []byte, usage string) { f.VarP(newBytesBase64Value(value, p), name, "", usage) } // BytesBase64VarP is like BytesBase64Var, but accepts a shorthand letter that can be used after a single dash. func (f *FlagSet) BytesBase64VarP(p *[]byte, name, shorthand string, value []byte, usage string) { f.VarP(newBytesBase64Value(value, p), name, shorthand, usage) } // BytesBase64Var defines an []byte flag with specified name, default value, and usage string. // The argument p points to an []byte variable in which to store the value of the flag. func BytesBase64Var(p *[]byte, name string, value []byte, usage string) { CommandLine.VarP(newBytesBase64Value(value, p), name, "", usage) } // BytesBase64VarP is like BytesBase64Var, but accepts a shorthand letter that can be used after a single dash. func BytesBase64VarP(p *[]byte, name, shorthand string, value []byte, usage string) { CommandLine.VarP(newBytesBase64Value(value, p), name, shorthand, usage) } // BytesBase64 defines an []byte flag with specified name, default value, and usage string. // The return value is the address of an []byte variable that stores the value of the flag. func (f *FlagSet) BytesBase64(name string, value []byte, usage string) *[]byte { p := new([]byte) f.BytesBase64VarP(p, name, "", value, usage) return p } // BytesBase64P is like BytesBase64, but accepts a shorthand letter that can be used after a single dash. func (f *FlagSet) BytesBase64P(name, shorthand string, value []byte, usage string) *[]byte { p := new([]byte) f.BytesBase64VarP(p, name, shorthand, value, usage) return p } // BytesBase64 defines an []byte flag with specified name, default value, and usage string. // The return value is the address of an []byte variable that stores the value of the flag. func BytesBase64(name string, value []byte, usage string) *[]byte { return CommandLine.BytesBase64P(name, "", value, usage) } // BytesBase64P is like BytesBase64, but accepts a shorthand letter that can be used after a single dash. func BytesBase64P(name, shorthand string, value []byte, usage string) *[]byte { return CommandLine.BytesBase64P(name, shorthand, value, usage) } spf13-pflag-0491e57/bytes_test.go000066400000000000000000000065461505550473500165550ustar00rootroot00000000000000package pflag import ( "encoding/base64" "fmt" "os" "testing" ) func setUpBytesHex(bytesHex *[]byte) *FlagSet { f := NewFlagSet("test", ContinueOnError) f.BytesHexVar(bytesHex, "bytes", []byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 0}, "Some bytes in HEX") f.BytesHexVarP(bytesHex, "bytes2", "B", []byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 0}, "Some bytes in HEX") return f } func TestBytesHex(t *testing.T) { testCases := []struct { input string success bool expected string }{ /// Positive cases {"", true, ""}, // Is empty string OK ? {"01", true, "01"}, {"0101", true, "0101"}, {"1234567890abcdef", true, "1234567890ABCDEF"}, {"1234567890ABCDEF", true, "1234567890ABCDEF"}, // Negative cases {"0", false, ""}, // Short string {"000", false, ""}, /// Odd-length string {"qq", false, ""}, /// non-hex character } devnull, _ := os.Open(os.DevNull) os.Stderr = devnull for i := range testCases { var bytesHex []byte f := setUpBytesHex(&bytesHex) tc := &testCases[i] // --bytes args := []string{ fmt.Sprintf("--bytes=%s", tc.input), fmt.Sprintf("-B %s", tc.input), fmt.Sprintf("--bytes2=%s", tc.input), } for _, arg := range args { err := f.Parse([]string{arg}) if err != nil && tc.success == true { t.Errorf("expected success, got %q", err) continue } else if err == nil && tc.success == false { // bytesHex, err := f.GetBytesHex("bytes") t.Errorf("expected failure while processing %q", tc.input) continue } else if tc.success { bytesHex, err := f.GetBytesHex("bytes") if err != nil { t.Errorf("Got error trying to fetch the 'bytes' flag: %v", err) } if fmt.Sprintf("%X", bytesHex) != tc.expected { t.Errorf("expected %q, got '%X'", tc.expected, bytesHex) } } } } } func setUpBytesBase64(bytesBase64 *[]byte) *FlagSet { f := NewFlagSet("test", ContinueOnError) f.BytesBase64Var(bytesBase64, "bytes", []byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 0}, "Some bytes in Base64") f.BytesBase64VarP(bytesBase64, "bytes2", "B", []byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 0}, "Some bytes in Base64") return f } func TestBytesBase64(t *testing.T) { testCases := []struct { input string success bool expected string }{ /// Positive cases {"", true, ""}, // Is empty string OK ? {"AQ==", true, "AQ=="}, // Negative cases {"AQ", false, ""}, // Padding removed {"ï", false, ""}, // non-base64 characters } devnull, _ := os.Open(os.DevNull) os.Stderr = devnull for i := range testCases { var bytesBase64 []byte f := setUpBytesBase64(&bytesBase64) tc := &testCases[i] // --bytes args := []string{ fmt.Sprintf("--bytes=%s", tc.input), fmt.Sprintf("-B %s", tc.input), fmt.Sprintf("--bytes2=%s", tc.input), } for _, arg := range args { err := f.Parse([]string{arg}) if err != nil && tc.success == true { t.Errorf("expected success, got %q", err) continue } else if err == nil && tc.success == false { // bytesBase64, err := f.GetBytesBase64("bytes") t.Errorf("expected failure while processing %q", tc.input) continue } else if tc.success { bytesBase64, err := f.GetBytesBase64("bytes") if err != nil { t.Errorf("Got error trying to fetch the 'bytes' flag: %v", err) } if base64.StdEncoding.EncodeToString(bytesBase64) != tc.expected { t.Errorf("expected %q, got '%X'", tc.expected, bytesBase64) } } } } } spf13-pflag-0491e57/count.go000066400000000000000000000056241505550473500155140ustar00rootroot00000000000000package pflag import "strconv" // -- count Value type countValue int func newCountValue(val int, p *int) *countValue { *p = val return (*countValue)(p) } func (i *countValue) Set(s string) error { // "+1" means that no specific value was passed, so increment if s == "+1" { *i = countValue(*i + 1) return nil } v, err := strconv.ParseInt(s, 0, 0) *i = countValue(v) return err } func (i *countValue) Type() string { return "count" } func (i *countValue) String() string { return strconv.Itoa(int(*i)) } func countConv(sval string) (interface{}, error) { i, err := strconv.Atoi(sval) if err != nil { return nil, err } return i, nil } // GetCount return the int value of a flag with the given name func (f *FlagSet) GetCount(name string) (int, error) { val, err := f.getFlagType(name, "count", countConv) if err != nil { return 0, err } return val.(int), nil } // CountVar defines a count flag with specified name, default value, and usage string. // The argument p points to an int variable in which to store the value of the flag. // A count flag will add 1 to its value every time it is found on the command line func (f *FlagSet) CountVar(p *int, name string, usage string) { f.CountVarP(p, name, "", usage) } // CountVarP is like CountVar only take a shorthand for the flag name. func (f *FlagSet) CountVarP(p *int, name, shorthand string, usage string) { flag := f.VarPF(newCountValue(0, p), name, shorthand, usage) flag.NoOptDefVal = "+1" } // CountVar like CountVar only the flag is placed on the CommandLine instead of a given flag set func CountVar(p *int, name string, usage string) { CommandLine.CountVar(p, name, usage) } // CountVarP is like CountVar only take a shorthand for the flag name. func CountVarP(p *int, name, shorthand string, usage string) { CommandLine.CountVarP(p, name, shorthand, usage) } // Count defines a count flag with specified name, default value, and usage string. // The return value is the address of an int variable that stores the value of the flag. // A count flag will add 1 to its value every time it is found on the command line func (f *FlagSet) Count(name string, usage string) *int { p := new(int) f.CountVarP(p, name, "", usage) return p } // CountP is like Count only takes a shorthand for the flag name. func (f *FlagSet) CountP(name, shorthand string, usage string) *int { p := new(int) f.CountVarP(p, name, shorthand, usage) return p } // Count defines a count flag with specified name, default value, and usage string. // The return value is the address of an int variable that stores the value of the flag. // A count flag will add 1 to its value every time it is found on the command line func Count(name string, usage string) *int { return CommandLine.CountP(name, "", usage) } // CountP is like Count only takes a shorthand for the flag name. func CountP(name, shorthand string, usage string) *int { return CommandLine.CountP(name, shorthand, usage) } spf13-pflag-0491e57/count_test.go000066400000000000000000000023031505550473500165420ustar00rootroot00000000000000package pflag import ( "os" "testing" ) func setUpCount(c *int) *FlagSet { f := NewFlagSet("test", ContinueOnError) f.CountVarP(c, "verbose", "v", "a counter") return f } func TestCount(t *testing.T) { testCases := []struct { input []string success bool expected int }{ {[]string{}, true, 0}, {[]string{"-v"}, true, 1}, {[]string{"-vvv"}, true, 3}, {[]string{"-v", "-v", "-v"}, true, 3}, {[]string{"-v", "--verbose", "-v"}, true, 3}, {[]string{"-v=3", "-v"}, true, 4}, {[]string{"--verbose=0"}, true, 0}, {[]string{"-v=0"}, true, 0}, {[]string{"-v=a"}, false, 0}, } devnull, _ := os.Open(os.DevNull) os.Stderr = devnull for i := range testCases { var count int f := setUpCount(&count) tc := &testCases[i] err := f.Parse(tc.input) if err != nil && tc.success == true { t.Errorf("expected success, got %q", err) continue } else if err == nil && tc.success == false { t.Errorf("expected failure, got success") continue } else if tc.success { c, err := f.GetCount("verbose") if err != nil { t.Errorf("Got error trying to fetch the counter flag") } if c != tc.expected { t.Errorf("expected %d, got %d", tc.expected, c) } } } } spf13-pflag-0491e57/duration.go000066400000000000000000000063651505550473500162140ustar00rootroot00000000000000package pflag import ( "time" ) // -- time.Duration Value type durationValue time.Duration func newDurationValue(val time.Duration, p *time.Duration) *durationValue { *p = val return (*durationValue)(p) } func (d *durationValue) Set(s string) error { v, err := time.ParseDuration(s) *d = durationValue(v) return err } func (d *durationValue) Type() string { return "duration" } func (d *durationValue) String() string { return (*time.Duration)(d).String() } func durationConv(sval string) (interface{}, error) { return time.ParseDuration(sval) } // GetDuration return the duration value of a flag with the given name func (f *FlagSet) GetDuration(name string) (time.Duration, error) { val, err := f.getFlagType(name, "duration", durationConv) if err != nil { return 0, err } return val.(time.Duration), nil } // DurationVar defines a time.Duration flag with specified name, default value, and usage string. // The argument p points to a time.Duration variable in which to store the value of the flag. func (f *FlagSet) DurationVar(p *time.Duration, name string, value time.Duration, usage string) { f.VarP(newDurationValue(value, p), name, "", usage) } // DurationVarP is like DurationVar, but accepts a shorthand letter that can be used after a single dash. func (f *FlagSet) DurationVarP(p *time.Duration, name, shorthand string, value time.Duration, usage string) { f.VarP(newDurationValue(value, p), name, shorthand, usage) } // DurationVar defines a time.Duration flag with specified name, default value, and usage string. // The argument p points to a time.Duration variable in which to store the value of the flag. func DurationVar(p *time.Duration, name string, value time.Duration, usage string) { CommandLine.VarP(newDurationValue(value, p), name, "", usage) } // DurationVarP is like DurationVar, but accepts a shorthand letter that can be used after a single dash. func DurationVarP(p *time.Duration, name, shorthand string, value time.Duration, usage string) { CommandLine.VarP(newDurationValue(value, p), name, shorthand, usage) } // Duration defines a time.Duration flag with specified name, default value, and usage string. // The return value is the address of a time.Duration variable that stores the value of the flag. func (f *FlagSet) Duration(name string, value time.Duration, usage string) *time.Duration { p := new(time.Duration) f.DurationVarP(p, name, "", value, usage) return p } // DurationP is like Duration, but accepts a shorthand letter that can be used after a single dash. func (f *FlagSet) DurationP(name, shorthand string, value time.Duration, usage string) *time.Duration { p := new(time.Duration) f.DurationVarP(p, name, shorthand, value, usage) return p } // Duration defines a time.Duration flag with specified name, default value, and usage string. // The return value is the address of a time.Duration variable that stores the value of the flag. func Duration(name string, value time.Duration, usage string) *time.Duration { return CommandLine.DurationP(name, "", value, usage) } // DurationP is like Duration, but accepts a shorthand letter that can be used after a single dash. func DurationP(name, shorthand string, value time.Duration, usage string) *time.Duration { return CommandLine.DurationP(name, shorthand, value, usage) } spf13-pflag-0491e57/duration_slice.go000066400000000000000000000120131505550473500173560ustar00rootroot00000000000000package pflag import ( "fmt" "strings" "time" ) // -- durationSlice Value type durationSliceValue struct { value *[]time.Duration changed bool } func newDurationSliceValue(val []time.Duration, p *[]time.Duration) *durationSliceValue { dsv := new(durationSliceValue) dsv.value = p *dsv.value = val return dsv } func (s *durationSliceValue) Set(val string) error { ss := strings.Split(val, ",") out := make([]time.Duration, len(ss)) for i, d := range ss { var err error out[i], err = time.ParseDuration(d) if err != nil { return err } } if !s.changed { *s.value = out } else { *s.value = append(*s.value, out...) } s.changed = true return nil } func (s *durationSliceValue) Type() string { return "durationSlice" } func (s *durationSliceValue) String() string { out := make([]string, len(*s.value)) for i, d := range *s.value { out[i] = fmt.Sprintf("%s", d) } return "[" + strings.Join(out, ",") + "]" } func (s *durationSliceValue) fromString(val string) (time.Duration, error) { return time.ParseDuration(val) } func (s *durationSliceValue) toString(val time.Duration) string { return fmt.Sprintf("%s", val) } func (s *durationSliceValue) Append(val string) error { i, err := s.fromString(val) if err != nil { return err } *s.value = append(*s.value, i) return nil } func (s *durationSliceValue) Replace(val []string) error { out := make([]time.Duration, len(val)) for i, d := range val { var err error out[i], err = s.fromString(d) if err != nil { return err } } *s.value = out return nil } func (s *durationSliceValue) GetSlice() []string { out := make([]string, len(*s.value)) for i, d := range *s.value { out[i] = s.toString(d) } return out } func durationSliceConv(val string) (interface{}, error) { val = strings.Trim(val, "[]") // Empty string would cause a slice with one (empty) entry if len(val) == 0 { return []time.Duration{}, nil } ss := strings.Split(val, ",") out := make([]time.Duration, len(ss)) for i, d := range ss { var err error out[i], err = time.ParseDuration(d) if err != nil { return nil, err } } return out, nil } // GetDurationSlice returns the []time.Duration value of a flag with the given name func (f *FlagSet) GetDurationSlice(name string) ([]time.Duration, error) { val, err := f.getFlagType(name, "durationSlice", durationSliceConv) if err != nil { return []time.Duration{}, err } return val.([]time.Duration), nil } // DurationSliceVar defines a durationSlice flag with specified name, default value, and usage string. // The argument p points to a []time.Duration variable in which to store the value of the flag. func (f *FlagSet) DurationSliceVar(p *[]time.Duration, name string, value []time.Duration, usage string) { f.VarP(newDurationSliceValue(value, p), name, "", usage) } // DurationSliceVarP is like DurationSliceVar, but accepts a shorthand letter that can be used after a single dash. func (f *FlagSet) DurationSliceVarP(p *[]time.Duration, name, shorthand string, value []time.Duration, usage string) { f.VarP(newDurationSliceValue(value, p), name, shorthand, usage) } // DurationSliceVar defines a duration[] flag with specified name, default value, and usage string. // The argument p points to a duration[] variable in which to store the value of the flag. func DurationSliceVar(p *[]time.Duration, name string, value []time.Duration, usage string) { CommandLine.VarP(newDurationSliceValue(value, p), name, "", usage) } // DurationSliceVarP is like DurationSliceVar, but accepts a shorthand letter that can be used after a single dash. func DurationSliceVarP(p *[]time.Duration, name, shorthand string, value []time.Duration, usage string) { CommandLine.VarP(newDurationSliceValue(value, p), name, shorthand, usage) } // DurationSlice defines a []time.Duration flag with specified name, default value, and usage string. // The return value is the address of a []time.Duration variable that stores the value of the flag. func (f *FlagSet) DurationSlice(name string, value []time.Duration, usage string) *[]time.Duration { p := []time.Duration{} f.DurationSliceVarP(&p, name, "", value, usage) return &p } // DurationSliceP is like DurationSlice, but accepts a shorthand letter that can be used after a single dash. func (f *FlagSet) DurationSliceP(name, shorthand string, value []time.Duration, usage string) *[]time.Duration { p := []time.Duration{} f.DurationSliceVarP(&p, name, shorthand, value, usage) return &p } // DurationSlice defines a []time.Duration flag with specified name, default value, and usage string. // The return value is the address of a []time.Duration variable that stores the value of the flag. func DurationSlice(name string, value []time.Duration, usage string) *[]time.Duration { return CommandLine.DurationSliceP(name, "", value, usage) } // DurationSliceP is like DurationSlice, but accepts a shorthand letter that can be used after a single dash. func DurationSliceP(name, shorthand string, value []time.Duration, usage string) *[]time.Duration { return CommandLine.DurationSliceP(name, shorthand, value, usage) } spf13-pflag-0491e57/duration_slice_test.go000066400000000000000000000105641505550473500204260ustar00rootroot00000000000000// Copyright 2009 The Go Authors. All rights reserved. // Use of this source code ds governed by a BSD-style // license that can be found in the LICENSE file. package pflag import ( "fmt" "strings" "testing" "time" ) func setUpDSFlagSet(dsp *[]time.Duration) *FlagSet { f := NewFlagSet("test", ContinueOnError) f.DurationSliceVar(dsp, "ds", []time.Duration{}, "Command separated list!") return f } func setUpDSFlagSetWithDefault(dsp *[]time.Duration) *FlagSet { f := NewFlagSet("test", ContinueOnError) f.DurationSliceVar(dsp, "ds", []time.Duration{0, 1}, "Command separated list!") return f } func TestEmptyDS(t *testing.T) { var ds []time.Duration f := setUpDSFlagSet(&ds) err := f.Parse([]string{}) if err != nil { t.Fatal("expected no error; got", err) } getDS, err := f.GetDurationSlice("ds") if err != nil { t.Fatal("got an error from GetDurationSlice():", err) } if len(getDS) != 0 { t.Fatalf("got ds %v with len=%d but expected length=0", getDS, len(getDS)) } } func TestDS(t *testing.T) { var ds []time.Duration f := setUpDSFlagSet(&ds) 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) } for i, v := range ds { d, err := time.ParseDuration(vals[i]) if err != nil { t.Fatalf("got error: %v", err) } if d != v { 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) } for i, v := range getDS { d, err := time.ParseDuration(vals[i]) if err != nil { t.Fatalf("got error: %v", err) } if d != v { t.Fatalf("expected ds[%d] to be %s but got: %d from GetDurationSlice", i, vals[i], v) } } } func TestDSDefault(t *testing.T) { var ds []time.Duration f := setUpDSFlagSetWithDefault(&ds) vals := []string{"0s", "1ns"} err := f.Parse([]string{}) if err != nil { t.Fatal("expected no error; got", err) } for i, v := range ds { d, err := time.ParseDuration(vals[i]) if err != nil { t.Fatalf("got error: %v", err) } if d != v { t.Fatalf("expected ds[%d] to be %d but got: %d", i, d, v) } } getDS, err := f.GetDurationSlice("ds") if err != nil { t.Fatal("got an error from GetDurationSlice():", err) } for i, v := range getDS { d, err := time.ParseDuration(vals[i]) if err != nil { t.Fatal("got an error from GetDurationSlice():", err) } if d != v { t.Fatalf("expected ds[%d] to be %d from GetDurationSlice but got: %d", i, d, v) } } } func TestDSWithDefault(t *testing.T) { var ds []time.Duration f := setUpDSFlagSetWithDefault(&ds) 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) } for i, v := range ds { d, err := time.ParseDuration(vals[i]) if err != nil { t.Fatalf("got error: %v", err) } if d != v { t.Fatalf("expected ds[%d] to be %d but got: %d", i, d, v) } } getDS, err := f.GetDurationSlice("ds") if err != nil { t.Fatal("got an error from GetDurationSlice():", err) } for i, v := range getDS { d, err := time.ParseDuration(vals[i]) if err != nil { t.Fatalf("got error: %v", err) } if d != v { t.Fatalf("expected ds[%d] to be %d from GetDurationSlice but got: %d", i, d, v) } } } func TestDSAsSliceValue(t *testing.T) { var ds []time.Duration f := setUpDSFlagSet(&ds) in := []string{"1ns", "2ns"} argfmt := "--ds=%s" arg1 := fmt.Sprintf(argfmt, in[0]) arg2 := fmt.Sprintf(argfmt, in[1]) err := f.Parse([]string{arg1, arg2}) if err != nil { t.Fatal("expected no error; got", err) } f.VisitAll(func(f *Flag) { if val, ok := f.Value.(SliceValue); ok { _ = val.Replace([]string{"3ns"}) } }) if len(ds) != 1 || ds[0] != time.Duration(3) { t.Fatalf("Expected ss to be overwritten with '3ns', but got: %v", ds) } } func TestDSCalledTwice(t *testing.T) { var ds []time.Duration f := setUpDSFlagSet(&ds) in := []string{"1ns,2ns", "3ns"} expected := []time.Duration{1, 2, 3} argfmt := "--ds=%s" arg1 := fmt.Sprintf(argfmt, in[0]) arg2 := fmt.Sprintf(argfmt, in[1]) err := f.Parse([]string{arg1, arg2}) 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) } } } spf13-pflag-0491e57/errors.go000066400000000000000000000104101505550473500156650ustar00rootroot00000000000000package pflag import "fmt" // notExistErrorMessageType specifies which flavor of "flag does not exist" // is printed by NotExistError. This allows the related errors to be grouped // under a single NotExistError struct without making a breaking change to // the error message text. type notExistErrorMessageType int const ( flagNotExistMessage notExistErrorMessageType = iota flagNotDefinedMessage flagNoSuchFlagMessage flagUnknownFlagMessage flagUnknownShorthandFlagMessage ) // NotExistError is the error returned when trying to access a flag that // does not exist in the FlagSet. type NotExistError struct { name string specifiedShorthands string messageType notExistErrorMessageType } // Error implements error. func (e *NotExistError) Error() string { switch e.messageType { 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) case flagUnknownFlagMessage: return fmt.Sprintf("unknown flag: --%s", e.name) case flagUnknownShorthandFlagMessage: c := rune(e.name[0]) return fmt.Sprintf("unknown shorthand flag: %q in -%s", c, e.specifiedShorthands) } panic(fmt.Errorf("unknown flagNotExistErrorMessageType: %v", e.messageType)) } // GetSpecifiedName returns the name of the flag (without dashes) as it // appeared in the parsed arguments. func (e *NotExistError) GetSpecifiedName() string { return e.name } // GetSpecifiedShortnames returns the group of shorthand arguments // (without dashes) that the flag appeared within. If the flag was not in a // shorthand group, this will return an empty string. func (e *NotExistError) GetSpecifiedShortnames() string { return e.specifiedShorthands } // ValueRequiredError is the error returned when a flag needs an argument but // no argument was provided. type ValueRequiredError struct { flag *Flag specifiedName string specifiedShorthands string } // Error implements error. func (e *ValueRequiredError) Error() string { if len(e.specifiedShorthands) > 0 { c := rune(e.specifiedName[0]) return fmt.Sprintf("flag needs an argument: %q in -%s", c, e.specifiedShorthands) } return fmt.Sprintf("flag needs an argument: --%s", e.specifiedName) } // GetFlag returns the flag for which the error occurred. func (e *ValueRequiredError) GetFlag() *Flag { return e.flag } // GetSpecifiedName returns the name of the flag (without dashes) as it // appeared in the parsed arguments. func (e *ValueRequiredError) GetSpecifiedName() string { return e.specifiedName } // GetSpecifiedShortnames returns the group of shorthand arguments // (without dashes) that the flag appeared within. If the flag was not in a // shorthand group, this will return an empty string. func (e *ValueRequiredError) GetSpecifiedShortnames() string { return e.specifiedShorthands } // InvalidValueError is the error returned when an invalid value is used // for a flag. type InvalidValueError struct { flag *Flag value string cause error } // Error implements error. func (e *InvalidValueError) Error() string { flag := e.flag var flagName string if flag.Shorthand != "" && flag.ShorthandDeprecated == "" { flagName = fmt.Sprintf("-%s, --%s", flag.Shorthand, flag.Name) } else { flagName = fmt.Sprintf("--%s", flag.Name) } return fmt.Sprintf("invalid argument %q for %q flag: %v", e.value, flagName, e.cause) } // Unwrap implements errors.Unwrap. func (e *InvalidValueError) Unwrap() error { return e.cause } // GetFlag returns the flag for which the error occurred. func (e *InvalidValueError) GetFlag() *Flag { return e.flag } // GetValue returns the invalid value that was provided. func (e *InvalidValueError) GetValue() string { return e.value } // InvalidSyntaxError is the error returned when a bad flag name is passed on // the command line. type InvalidSyntaxError struct { specifiedFlag string } // Error implements error. func (e *InvalidSyntaxError) Error() string { return fmt.Sprintf("bad flag syntax: %s", e.specifiedFlag) } // GetSpecifiedName returns the exact flag (with dashes) as it // appeared in the parsed arguments. func (e *InvalidSyntaxError) GetSpecifiedFlag() string { return e.specifiedFlag } spf13-pflag-0491e57/errors_test.go000066400000000000000000000033531505550473500167340ustar00rootroot00000000000000package pflag import ( "errors" "testing" ) func TestNotExistError(t *testing.T) { err := &NotExistError{ name: "foo", specifiedShorthands: "bar", } if err.GetSpecifiedName() != "foo" { t.Errorf("Expected GetSpecifiedName to return %q, got %q", "foo", err.GetSpecifiedName()) } if err.GetSpecifiedShortnames() != "bar" { t.Errorf("Expected GetSpecifiedShortnames to return %q, got %q", "bar", err.GetSpecifiedShortnames()) } } func TestValueRequiredError(t *testing.T) { err := &ValueRequiredError{ flag: &Flag{}, specifiedName: "foo", specifiedShorthands: "bar", } if err.GetFlag() == nil { t.Error("Expected GetSpecifiedName to return its flag field, but got nil") } if err.GetSpecifiedName() != "foo" { t.Errorf("Expected GetSpecifiedName to return %q, got %q", "foo", err.GetSpecifiedName()) } if err.GetSpecifiedShortnames() != "bar" { t.Errorf("Expected GetSpecifiedShortnames to return %q, got %q", "bar", err.GetSpecifiedShortnames()) } } func TestInvalidValueError(t *testing.T) { expectedCause := errors.New("error") err := &InvalidValueError{ flag: &Flag{}, value: "foo", cause: expectedCause, } if err.GetFlag() == nil { t.Error("Expected GetSpecifiedName to return its flag field, but got nil") } if err.GetValue() != "foo" { t.Errorf("Expected GetValue to return %q, got %q", "foo", err.GetValue()) } if err.Unwrap() != expectedCause { t.Errorf("Expected Unwrwap to return %q, got %q", expectedCause, err.Unwrap()) } } func TestInvalidSyntaxError(t *testing.T) { err := &InvalidSyntaxError{ specifiedFlag: "--=", } if err.GetSpecifiedFlag() != "--=" { t.Errorf("Expected GetSpecifiedFlag to return %q, got %q", "--=", err.GetSpecifiedFlag()) } } spf13-pflag-0491e57/example_test.go000066400000000000000000000013171505550473500170510ustar00rootroot00000000000000// Copyright 2012 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. package pflag_test import ( "fmt" "github.com/spf13/pflag" ) func ExampleShorthandLookup() { name := "verbose" short := name[:1] pflag.BoolP(name, short, false, "verbose output") // len(short) must be == 1 flag := pflag.ShorthandLookup(short) fmt.Println(flag.Name) } func ExampleFlagSet_ShorthandLookup() { name := "verbose" short := name[:1] fs := pflag.NewFlagSet("Example", pflag.ContinueOnError) fs.BoolP(name, short, false, "verbose output") // len(short) must be == 1 flag := fs.ShorthandLookup(short) fmt.Println(flag.Name) } spf13-pflag-0491e57/export_test.go000066400000000000000000000013371505550473500167410ustar00rootroot00000000000000// Copyright 2010 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. package pflag import ( "io/ioutil" "os" ) // Additional routines compiled into the package only during testing. // ResetForTesting clears all flag state and sets the usage function as directed. // After calling ResetForTesting, parse errors in flag handling will not // exit the program. func ResetForTesting(usage func()) { CommandLine = &FlagSet{ name: os.Args[0], errorHandling: ContinueOnError, output: ioutil.Discard, } Usage = usage } // GetCommandLine returns the default FlagSet. func GetCommandLine() *FlagSet { return CommandLine } spf13-pflag-0491e57/flag.go000066400000000000000000001110721505550473500152700ustar00rootroot00000000000000// Copyright 2009 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. /* Package pflag is a drop-in replacement for Go's flag package, implementing POSIX/GNU-style --flags. pflag is compatible with the GNU extensions to the POSIX recommendations for command-line options. See http://www.gnu.org/software/libc/manual/html_node/Argument-Syntax.html Usage: pflag is a drop-in replacement of Go's native flag package. If you import pflag under the name "flag" then all code should continue to function with no changes. import flag "github.com/spf13/pflag" There is one exception to this: if you directly instantiate the Flag struct there is one more field "Shorthand" that you will need to set. Most code never instantiates this struct directly, and instead uses functions such as String(), BoolVar(), and Var(), and is therefore 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) After parsing, the arguments after the flag are available as the slice flag.Args() or individually as flag.Arg(i). 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 // non-boolean flags -n 1234 -Ifile // mixed -abcs "hello" -abcn1234 Flag parsing stops after the terminator "--". Unlike the flag package, flags can be interspersed with arguments anywhere on the command line before this terminator. 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. Duration flags accept any input valid for time.ParseDuration. The default set of command-line flags is controlled by top-level functions. The FlagSet type allows one to define independent sets of flags, such as to implement subcommands in a command-line interface. The methods of FlagSet are analogous to the top-level functions for the command-line flag set. */ package pflag import ( "bytes" "errors" goflag "flag" "fmt" "io" "os" "sort" "strings" ) // ErrHelp is the error returned if the flag -help is invoked but no such flag is defined. var ErrHelp = errors.New("pflag: help requested") // ErrorHandling defines how to handle flag parsing errors. type ErrorHandling int const ( // ContinueOnError will return an err from Parse() if an error is found ContinueOnError ErrorHandling = iota // ExitOnError will call os.Exit(2) if an error is found when parsing ExitOnError // PanicOnError will panic() if an error is found when parsing flags PanicOnError ) // 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 UnknownFlags bool } // ParseErrorsWhitelist defines the parsing errors that can be ignored. // // Deprecated: use [ParseErrorsAllowlist] instead. This type will be removed in a future release. type ParseErrorsWhitelist = ParseErrorsAllowlist // NormalizedName is a flag name that has been normalized according to rules // for the FlagSet (e.g. making '-' and '_' equivalent). type NormalizedName string // A FlagSet represents a set of defined flags. type FlagSet struct { // Usage is the function called when an error occurs while parsing flags. // The field is a function (not a method) that may be changed to point to // a custom error handler. Usage func() // SortFlags is used to indicate, if user wants to have sorted flags in // help/usage messages. SortFlags bool // ParseErrorsAllowlist is used to configure an allowlist of errors ParseErrorsAllowlist ParseErrorsAllowlist // ParseErrorsAllowlist is used to configure an allowlist of errors. // // Deprecated: use [FlagSet.ParseErrorsAllowlist] instead. This field will be removed in a future release. ParseErrorsWhitelist ParseErrorsAllowlist name string parsed bool actual map[NormalizedName]*Flag orderedActual []*Flag sortedActual []*Flag formal map[NormalizedName]*Flag orderedFormal []*Flag sortedFormal []*Flag shorthands map[byte]*Flag args []string // arguments after flags argsLenAtDash int // len(args) when a '--' was located when parsing, or -1 if no -- errorHandling ErrorHandling output io.Writer // nil means stderr; use Output() accessor interspersed bool // allow interspersed option/non-option args normalizeNameFunc func(f *FlagSet, name string) NormalizedName addedGoFlagSets []*goflag.FlagSet } // A Flag represents the state of a flag. type Flag struct { Name string // name as it appears on command line Shorthand string // one-letter abbreviated flag Usage string // help message Value Value // value as set DefValue string // default value (as text); for usage message Changed bool // If the user set the value (or if left to default) NoOptDefVal string // default value (as text); if the flag is on the command line without any options Deprecated string // If this flag is deprecated, this string is the new or now thing to use Hidden bool // used by cobra.Command to allow flags to be hidden from help/usage text ShorthandDeprecated string // If the shorthand of this flag is deprecated, this string is the new or now thing to use Annotations map[string][]string // used by cobra.Command bash autocomple code } // Value is the interface to the dynamic value stored in a flag. // (The default value is represented as a string.) type Value interface { String() string Set(string) error Type() string } // SliceValue is a secondary interface to all flags which hold a list // of values. This allows full control over the value of list flags, // and avoids complicated marshalling and unmarshalling to csv. type SliceValue interface { // Append adds the specified value to the end of the flag value list. Append(string) error // Replace will fully overwrite any data currently in the flag value list. Replace([]string) error // GetSlice returns the flag value list as an array of strings. GetSlice() []string } // sortFlags returns the flags as a slice in lexicographical sorted order. func sortFlags(flags map[NormalizedName]*Flag) []*Flag { list := make(sort.StringSlice, len(flags)) i := 0 for k := range flags { list[i] = string(k) i++ } list.Sort() result := make([]*Flag, len(list)) for i, name := range list { result[i] = flags[NormalizedName(name)] } return result } // SetNormalizeFunc allows you to add a function which can translate flag names. // Flags added to the FlagSet will be translated and then when anything tries to // look up the flag that will also be translated. So it would be possible to create // a flag named "getURL" and have it translated to "geturl". A user could then pass // "--getUrl" which may also be translated to "geturl" and everything will work. func (f *FlagSet) SetNormalizeFunc(n func(f *FlagSet, name string) NormalizedName) { f.normalizeNameFunc = n f.sortedFormal = f.sortedFormal[:0] for fname, flag := range f.formal { nname := f.normalizeFlagName(flag.Name) if fname == nname { continue } flag.Name = string(nname) delete(f.formal, fname) f.formal[nname] = flag if _, set := f.actual[fname]; set { delete(f.actual, fname) f.actual[nname] = flag } } } // GetNormalizeFunc returns the previously set NormalizeFunc of a function which // does no translation, if not set previously. func (f *FlagSet) GetNormalizeFunc() func(f *FlagSet, name string) NormalizedName { if f.normalizeNameFunc != nil { return f.normalizeNameFunc } return func(f *FlagSet, name string) NormalizedName { return NormalizedName(name) } } func (f *FlagSet) normalizeFlagName(name string) NormalizedName { n := f.GetNormalizeFunc() return n(f, name) } // Output returns the destination for usage and error messages. os.Stderr is returned if // output was not set or was set to nil. func (f *FlagSet) Output() io.Writer { if f.output == nil { return os.Stderr } return f.output } // Name returns the name of the flag set. func (f *FlagSet) Name() string { return f.name } // SetOutput sets the destination for usage and error messages. // If output is nil, os.Stderr is used. func (f *FlagSet) SetOutput(output io.Writer) { f.output = output } // VisitAll visits the 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. func (f *FlagSet) VisitAll(fn func(*Flag)) { if len(f.formal) == 0 { return } var flags []*Flag if f.SortFlags { if len(f.formal) != len(f.sortedFormal) { f.sortedFormal = sortFlags(f.formal) } flags = f.sortedFormal } else { flags = f.orderedFormal } for _, flag := range flags { fn(flag) } } // HasFlags returns a bool to indicate if the FlagSet has any flags defined. func (f *FlagSet) HasFlags() bool { return len(f.formal) > 0 } // HasAvailableFlags returns a bool to indicate if the FlagSet has any flags // that are not hidden. func (f *FlagSet) HasAvailableFlags() bool { for _, flag := range f.formal { if !flag.Hidden { return true } } return false } // 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. func VisitAll(fn func(*Flag)) { CommandLine.VisitAll(fn) } // Visit visits the flags in lexicographical order or // in primordial order if f.SortFlags is false, calling fn for each. // It visits only those flags that have been set. func (f *FlagSet) Visit(fn func(*Flag)) { if len(f.actual) == 0 { return } var flags []*Flag if f.SortFlags { if len(f.actual) != len(f.sortedActual) { f.sortedActual = sortFlags(f.actual) } flags = f.sortedActual } else { flags = f.orderedActual } for _, flag := range flags { fn(flag) } } // Visit visits the command-line flags in lexicographical order or // in primordial order if f.SortFlags is false, calling fn for each. // It visits only those flags that have been set. func Visit(fn func(*Flag)) { CommandLine.Visit(fn) } // Lookup returns the Flag structure of the named flag, returning nil if none exists. func (f *FlagSet) Lookup(name string) *Flag { return f.lookup(f.normalizeFlagName(name)) } // ShorthandLookup returns the Flag structure of the short handed flag, // returning nil if none exists. // It panics, if len(name) > 1. func (f *FlagSet) ShorthandLookup(name string) *Flag { if name == "" { return nil } 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) panic(msg) } c := name[0] return f.shorthands[c] } // lookup returns the Flag structure of the named flag, returning nil if none exists. func (f *FlagSet) lookup(name NormalizedName) *Flag { return f.formal[name] } // func to return a given type for a given flag name 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} return nil, err } if flag.Value.Type() != ftype { err := fmt.Errorf("trying to get %s value of flag of type %s", ftype, flag.Value.Type()) return nil, err } sval := flag.Value.String() result, err := convFunc(sval) if err != nil { return nil, err } return result, nil } // ArgsLenAtDash will return the length of f.Args at the moment when a -- was // found during arg parsing. This allows your program to know which args were // before the -- and which came after. func (f *FlagSet) ArgsLenAtDash() int { return f.argsLenAtDash } // MarkDeprecated indicated that a flag is deprecated in your program. It will // continue to function but will not show up in help or usage messages. Using // this flag will also print the given usageMessage. func (f *FlagSet) MarkDeprecated(name string, usageMessage string) error { flag := f.Lookup(name) if flag == nil { return &NotExistError{name: name, messageType: flagNotExistMessage} } if usageMessage == "" { return fmt.Errorf("deprecated message for flag %q must be set", name) } flag.Deprecated = usageMessage flag.Hidden = true return nil } // MarkShorthandDeprecated will mark the shorthand of a flag deprecated in your // program. It will continue to function but will not show up in help or usage // messages. Using this flag will also print the given usageMessage. func (f *FlagSet) MarkShorthandDeprecated(name string, usageMessage string) error { flag := f.Lookup(name) if flag == nil { return &NotExistError{name: name, messageType: flagNotExistMessage} } if usageMessage == "" { return fmt.Errorf("deprecated message for flag %q must be set", name) } flag.ShorthandDeprecated = usageMessage return nil } // MarkHidden sets a flag to 'hidden' in your program. It will continue to // function but will not show up in help or usage messages. func (f *FlagSet) MarkHidden(name string) error { flag := f.Lookup(name) if flag == nil { return &NotExistError{name: name, messageType: flagNotExistMessage} } flag.Hidden = true return nil } // Lookup returns the Flag structure of the named command-line flag, // returning nil if none exists. func Lookup(name string) *Flag { return CommandLine.Lookup(name) } // ShorthandLookup returns the Flag structure of the short handed flag, // returning nil if none exists. func ShorthandLookup(name string) *Flag { return CommandLine.ShorthandLookup(name) } // Set sets the value of the named flag. func (f *FlagSet) Set(name, value string) error { normalName := f.normalizeFlagName(name) flag, ok := f.formal[normalName] if !ok { return &NotExistError{name: name, messageType: flagNoSuchFlagMessage} } err := flag.Value.Set(value) if err != nil { return &InvalidValueError{ flag: flag, value: value, cause: err, } } if !flag.Changed { if f.actual == nil { f.actual = make(map[NormalizedName]*Flag) } f.actual[normalName] = flag f.orderedActual = append(f.orderedActual, flag) flag.Changed = true } if flag.Deprecated != "" { fmt.Fprintf(f.Output(), "Flag --%s has been deprecated, %s\n", flag.Name, flag.Deprecated) } return nil } // SetAnnotation allows one to set arbitrary annotations on a flag in the FlagSet. // This is sometimes used by spf13/cobra programs which want to generate additional // bash completion information. func (f *FlagSet) SetAnnotation(name, key string, values []string) error { normalName := f.normalizeFlagName(name) flag, ok := f.formal[normalName] if !ok { return &NotExistError{name: name, messageType: flagNoSuchFlagMessage} } if flag.Annotations == nil { flag.Annotations = map[string][]string{} } flag.Annotations[key] = values return nil } // Changed returns true if the flag was explicitly set during Parse() and false // otherwise func (f *FlagSet) Changed(name string) bool { flag := f.Lookup(name) // If a flag doesn't exist, it wasn't changed.... if flag == nil { return false } return flag.Changed } // Set sets the value of the named command-line flag. func Set(name, value string) error { return CommandLine.Set(name, value) } // PrintDefaults prints, to standard error unless configured // otherwise, the default values of all defined flags in the set. func (f *FlagSet) PrintDefaults() { usages := f.FlagUsages() 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: return f.DefValue == "false" || f.DefValue == "" case *durationValue: // Beginning in Go 1.7, duration zero values are "0s" return f.DefValue == "0" || f.DefValue == "0s" case *intValue, *int8Value, *int32Value, *int64Value, *uintValue, *uint8Value, *uint16Value, *uint32Value, *uint64Value, *countValue, *float32Value, *float64Value: return f.DefValue == "0" case *stringValue: return f.DefValue == "" case *ipValue, *ipMaskValue, *ipNetValue: return f.DefValue == "" case *intSliceValue, *stringSliceValue, *stringArrayValue: return f.DefValue == "[]" default: switch f.DefValue { case "false": return true case "": return true case "": return true case "0": return true } return false } } // UnquoteUsage extracts a back-quoted name from the usage // string for a flag and returns it and the un-quoted usage. // Given "a `name` to show" it returns ("name", "a name to show"). // If there are no back quotes, the name is an educated guess of the // type of the flag's value, or the empty string if the flag is boolean. func UnquoteUsage(flag *Flag) (name string, usage string) { // Look for a back-quoted name, but avoid the strings package. usage = flag.Usage for i := 0; i < len(usage); i++ { if usage[i] == '`' { for j := i + 1; j < len(usage); j++ { if usage[j] == '`' { name = usage[i+1 : j] usage = usage[:i] + name + usage[j+1:] return name, usage } } break // Only one back quote; use type name. } } name = flag.Value.Type() switch name { case "bool", "boolfunc": name = "" case "func": name = "value" case "float64": name = "float" case "int64": name = "int" case "uint64": name = "uint" case "stringSlice": name = "strings" case "intSlice": name = "ints" case "uintSlice": name = "uints" case "boolSlice": name = "bools" } return } // 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). func wrapN(i, slop int, s string) (string, string) { if i+slop > len(s) { return s, "" } w := strings.LastIndexAny(s[:i], " \t\n") if w <= 0 { return s, "" } nlPos := strings.LastIndex(s[:i], "\n") if nlPos > 0 && nlPos < w { return s[:nlPos], s[nlPos+1:] } return s[:w], s[w+1:] } // Wraps the string `s` to a maximum width `w` with leading indent // `i`. The first line is not indented (this is assumed to be done by // 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) } // space between indent i and end of line width w into which // we should wrap the text. wrap := w - i var r, l string // Not enough space for sensible wrapping. Wrap as a block on // the next line instead. if wrap < 24 { i = 16 wrap = w - i r += "\n" + strings.Repeat(" ", i) } // If still not enough space then don't even try to wrap. if wrap < 24 { return strings.Replace(s, "\n", r, -1) } // 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 // 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) // 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) } return r } // FlagUsagesWrapped returns a string containing the usage information // for all flags in the FlagSet. Wrapped to `cols` columns (0 for no // wrapping) func (f *FlagSet) FlagUsagesWrapped(cols int) string { buf := new(bytes.Buffer) lines := make([]string, 0, len(f.formal)) maxlen := 0 f.VisitAll(func(flag *Flag) { if flag.Hidden { return } line := "" if flag.Shorthand != "" && flag.ShorthandDeprecated == "" { line = fmt.Sprintf(" -%s, --%s", flag.Shorthand, flag.Name) } else { line = fmt.Sprintf(" --%s", flag.Name) } varname, usage := UnquoteUsage(flag) if varname != "" { line += " " + varname } if flag.NoOptDefVal != "" { switch flag.Value.Type() { case "string": line += fmt.Sprintf("[=\"%s\"]", flag.NoOptDefVal) case "bool", "boolfunc": if flag.NoOptDefVal != "true" { line += fmt.Sprintf("[=%s]", flag.NoOptDefVal) } case "count": if flag.NoOptDefVal != "+1" { line += fmt.Sprintf("[=%s]", flag.NoOptDefVal) } default: line += fmt.Sprintf("[=%s]", flag.NoOptDefVal) } } // This special character will be replaced with spacing once the // correct alignment is calculated line += "\x00" if len(line) > maxlen { maxlen = len(line) } line += usage if !flag.defaultIsZeroValue() { if flag.Value.Type() == "string" { line += fmt.Sprintf(" (default %q)", flag.DefValue) } else { line += fmt.Sprintf(" (default %s)", flag.DefValue) } } if len(flag.Deprecated) != 0 { line += fmt.Sprintf(" (DEPRECATED: %s)", flag.Deprecated) } lines = append(lines, line) }) for _, line := range lines { 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:])) } return buf.String() } // FlagUsages returns a string containing the usage information for all flags in // the FlagSet func (f *FlagSet) FlagUsages() string { return f.FlagUsagesWrapped(0) } // PrintDefaults prints to standard error the default values of all defined command-line flags. func PrintDefaults() { CommandLine.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) f.PrintDefaults() } // NOTE: Usage is not just defaultUsage(CommandLine) // 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. var Usage = func() { fmt.Fprintf(os.Stderr, "Usage of %s:\n", os.Args[0]) PrintDefaults() } // NFlag returns the number of flags that have been set. func (f *FlagSet) NFlag() int { return len(f.actual) } // NFlag returns the number of command-line flags that have been set. func NFlag() int { return len(CommandLine.actual) } // Arg returns the i'th argument. Arg(0) is the first remaining argument // after flags have been processed. func (f *FlagSet) Arg(i int) string { if i < 0 || i >= len(f.args) { return "" } return f.args[i] } // Arg returns the i'th command-line argument. Arg(0) is the first remaining argument // after flags have been processed. func Arg(i int) string { return CommandLine.Arg(i) } // NArg is the number of arguments remaining after flags have been processed. func (f *FlagSet) NArg() int { return len(f.args) } // NArg is the number of arguments remaining after flags have been processed. func NArg() int { return len(CommandLine.args) } // Args returns the non-flag arguments. func (f *FlagSet) Args() []string { return f.args } // Args returns the non-flag command-line arguments. func Args() []string { return CommandLine.args } // Var defines a flag with the specified name and usage string. The type and // value of the flag are represented by the first argument, of type Value, which // typically holds a user-defined implementation of Value. For instance, the // caller could create a flag that turns a comma-separated string into a slice // of strings by giving the slice the methods of Value; in particular, Set would // decompose the comma-separated string into the slice. func (f *FlagSet) Var(value Value, name string, usage string) { f.VarP(value, name, "", usage) } // VarPF is like VarP, but returns the flag created func (f *FlagSet) VarPF(value Value, name, shorthand, usage string) *Flag { // Remember the default value as a string; it won't change. flag := &Flag{ Name: name, Shorthand: shorthand, Usage: usage, Value: value, DefValue: value.String(), } f.AddFlag(flag) return flag } // VarP is like Var, but accepts a shorthand letter that can be used after a single dash. func (f *FlagSet) VarP(value Value, name, shorthand, usage string) { f.VarPF(value, name, shorthand, usage) } // AddFlag will add the flag to the FlagSet func (f *FlagSet) AddFlag(flag *Flag) { normalizedFlagName := f.normalizeFlagName(flag.Name) _, alreadyThere := f.formal[normalizedFlagName] if alreadyThere { msg := fmt.Sprintf("%s flag redefined: %s", f.name, flag.Name) fmt.Fprintln(f.Output(), msg) panic(msg) // Happens only if flags are declared with identical names } if f.formal == nil { f.formal = make(map[NormalizedName]*Flag) } flag.Name = string(normalizedFlagName) f.formal[normalizedFlagName] = flag f.orderedFormal = append(f.orderedFormal, flag) if flag.Shorthand == "" { return } if len(flag.Shorthand) > 1 { msg := fmt.Sprintf("%q shorthand is more than one ASCII character", flag.Shorthand) fmt.Fprintf(f.Output(), msg) panic(msg) } if f.shorthands == nil { f.shorthands = make(map[byte]*Flag) } c := flag.Shorthand[0] 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) panic(msg) } f.shorthands[c] = flag } // AddFlagSet adds one FlagSet to another. If a flag is already present in f // the flag from newSet will be ignored. func (f *FlagSet) AddFlagSet(newSet *FlagSet) { if newSet == nil { return } newSet.VisitAll(func(flag *Flag) { if f.Lookup(flag.Name) == nil { f.AddFlag(flag) } }) } // Var defines a flag with the specified name and usage string. The type and // value of the flag are represented by the first argument, of type Value, which // typically holds a user-defined implementation of Value. For instance, the // caller could create a flag that turns a comma-separated string into a slice // of strings by giving the slice the methods of Value; in particular, Set would // decompose the comma-separated string into the slice. func Var(value Value, name string, usage string) { CommandLine.VarP(value, name, "", usage) } // VarP is like Var, but accepts a shorthand letter that can be used after a single dash. func VarP(value Value, name, shorthand, usage string) { CommandLine.VarP(value, name, shorthand, usage) } // fail prints an error message and usage message to standard error and // returns the error. func (f *FlagSet) fail(err error) error { if f.errorHandling != ContinueOnError { f.usage() } return err } // 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 { Usage() } else if f.Usage == nil { defaultUsage(f) } else { f.Usage() } } // --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 return args } first := args[0] if len(first) > 0 && first[0] == '-' { //--unknown --next-flag ... return args } //--unknown arg ... (args will be arg ...) if len(args) > 1 { return args[1:] } return nil } func (f *FlagSet) parseLongArg(s string, args []string, fn parseFunc) (a []string, err error) { a = args name := s[2:] if len(name) == 0 || name[0] == '-' || name[0] == '=' { err = f.fail(&InvalidSyntaxError{specifiedFlag: s}) return } split := strings.SplitN(name, "=", 2) name = split[0] flag, exists := f.formal[f.normalizeFlagName(name)] if !exists { switch { case name == "help": f.usage() return a, ErrHelp case f.ParseErrorsWhitelist.UnknownFlags: fallthrough case f.ParseErrorsAllowlist.UnknownFlags: // --unknown=unknownval arg ... // we do not want to lose arg in this case if len(split) >= 2 { return a, nil } return stripUnknownFlagValue(a), nil default: err = f.fail(&NotExistError{name: name, messageType: flagUnknownFlagMessage}) return } } var value string if len(split) == 2 { // '--flag=arg' value = split[1] } else if flag.NoOptDefVal != "" { // '--flag' (arg was optional) value = flag.NoOptDefVal } else if len(a) > 0 { // '--flag arg' value = a[0] a = a[1:] } else { // '--flag' (arg was required) err = f.fail(&ValueRequiredError{ flag: flag, specifiedName: name, }) return } err = fn(flag, value) if err != nil { f.fail(err) } return } func (f *FlagSet) parseSingleShortArg(shorthands string, args []string, fn parseFunc) (outShorts string, outArgs []string, err error) { outArgs = args if isGotestShorthandFlag(shorthands) { return } outShorts = shorthands[1:] c := shorthands[0] flag, exists := f.shorthands[c] if !exists { switch { case c == 'h': f.usage() err = ErrHelp return case f.ParseErrorsWhitelist.UnknownFlags: fallthrough case f.ParseErrorsAllowlist.UnknownFlags: // '-f=arg arg ...' // we do not want to lose arg in this case if len(shorthands) > 2 && shorthands[1] == '=' { outShorts = "" return } outArgs = stripUnknownFlagValue(outArgs) return default: err = f.fail(&NotExistError{ name: string(c), specifiedShorthands: shorthands, messageType: flagUnknownShorthandFlagMessage, }) return } } var value string if len(shorthands) > 2 && shorthands[1] == '=' { // '-f=arg' value = shorthands[2:] outShorts = "" } else if flag.NoOptDefVal != "" { // '-f' (arg was optional) value = flag.NoOptDefVal } else if len(shorthands) > 1 { // '-farg' value = shorthands[1:] outShorts = "" } else if len(args) > 0 { // '-f arg' value = args[0] outArgs = args[1:] } else { // '-f' (arg was required) err = f.fail(&ValueRequiredError{ flag: flag, specifiedName: string(c), specifiedShorthands: shorthands, }) return } if flag.ShorthandDeprecated != "" { fmt.Fprintf(f.Output(), "Flag shorthand -%s has been deprecated, %s\n", flag.Shorthand, flag.ShorthandDeprecated) } err = fn(flag, value) if err != nil { f.fail(err) } return } func (f *FlagSet) parseShortArg(s string, args []string, fn parseFunc) (a []string, err error) { a = args shorthands := s[1:] // "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 } } return } 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 } if s[1] == '-' { 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) } else { args, err = f.parseShortArg(s, args, fn) } if err != nil { return } } return } // Parse parses flag definitions from the argument list, which should not // include the command name. Must be called after all flags in the FlagSet // are defined and before flags are accessed by the program. // The return value will be ErrHelp if -help was set but not defined. func (f *FlagSet) Parse(arguments []string) error { if f.addedGoFlagSets != nil { for _, goFlagSet := range f.addedGoFlagSets { goFlagSet.Parse(nil) } } f.parsed = true f.args = make([]string, 0, len(arguments)) if len(arguments) == 0 { return nil } set := func(flag *Flag, value string) error { return f.Set(flag.Name, value) } err := f.parseArgs(arguments, set) if err != nil { switch f.errorHandling { case ContinueOnError: return err case ExitOnError: if err == ErrHelp { os.Exit(0) } fmt.Fprintln(f.Output(), err) os.Exit(2) case PanicOnError: panic(err) } } return nil } type parseFunc func(flag *Flag, 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 // called after all flags in the FlagSet are defined and before flags are // accessed by the program. The return value will be ErrHelp if -help was set // but not defined. func (f *FlagSet) ParseAll(arguments []string, fn func(flag *Flag, value string) error) error { f.parsed = true f.args = make([]string, 0, len(arguments)) err := f.parseArgs(arguments, fn) if err != nil { switch f.errorHandling { case ContinueOnError: return err case ExitOnError: if err == ErrHelp { os.Exit(0) } fmt.Fprintln(f.Output(), err) os.Exit(2) case PanicOnError: panic(err) } } return nil } // Parsed reports whether f.Parse has been called. func (f *FlagSet) Parsed() bool { return f.parsed } // Parse parses the command-line flags from os.Args[1:]. Must be called // 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:]) } // ParseAll parses the command-line flags from os.Args[1:] and called fn for each. // The arguments for fn are flag and value. Must be called after all flags are // 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) } // SetInterspersed sets whether to support interspersed option/non-option arguments. func SetInterspersed(interspersed bool) { CommandLine.SetInterspersed(interspersed) } // Parsed returns true if the command-line flags have been parsed. func Parsed() bool { return CommandLine.Parsed() } // CommandLine is the default set of command-line flags, parsed from os.Args. var CommandLine = NewFlagSet(os.Args[0], ExitOnError) // NewFlagSet returns a new, empty flag set with the specified name, // error handling property and SortFlags set to true. func NewFlagSet(name string, errorHandling ErrorHandling) *FlagSet { f := &FlagSet{ name: name, errorHandling: errorHandling, argsLenAtDash: -1, interspersed: true, SortFlags: true, } return f } // SetInterspersed sets whether to support interspersed option/non-option arguments. func (f *FlagSet) SetInterspersed(interspersed bool) { f.interspersed = interspersed } // Init sets the name and error handling property for a flag set. // By default, the zero FlagSet uses an empty name and the // ContinueOnError error handling policy. func (f *FlagSet) Init(name string, errorHandling ErrorHandling) { f.name = name f.errorHandling = errorHandling f.argsLenAtDash = -1 } spf13-pflag-0491e57/flag_test.go000066400000000000000000001175421505550473500163370ustar00rootroot00000000000000// Copyright 2009 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. package pflag import ( "bytes" "fmt" "io" "io/ioutil" "net" "os" "reflect" "sort" "strconv" "strings" "testing" "time" ) 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") normalizeFlagNameInvocations = 0 ) func boolString(s string) string { if s == "0" { return "false" } return "true" } func TestEverything(t *testing.T) { m := make(map[string]*Flag) desired := "0" visitor := func(f *Flag) { if len(f.Name) > 5 && f.Name[0:5] == "test_" { m[f.Name] = f ok := false switch { case f.Value.String() == desired: ok = true case f.Name == "test_bool" && f.Value.String() == boolString(desired): ok = true case f.Name == "test_duration" && f.Value.String() == desired+"s": ok = true } if !ok { t.Error("Visit: bad value", f.Value.String(), "for", f.Name) } } } VisitAll(visitor) if len(m) != 9 { t.Error("VisitAll misses some flags") for k, v := range m { t.Log(k, *v) } } m = make(map[string]*Flag) Visit(visitor) if len(m) != 0 { t.Errorf("Visit sees unset flags") for k, v := range m { t.Log(k, *v) } } // 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") desired = "1" Visit(visitor) if len(m) != 9 { t.Error("Visit fails after set") for k, v := range m { t.Log(k, *v) } } // Now test they're visited in sort order. var flagNames []string Visit(func(f *Flag) { flagNames = append(flagNames, f.Name) }) if !sort.StringsAreSorted(flagNames) { t.Errorf("flag names not sorted: %v", flagNames) } } func TestNoArgument(t *testing.T) { if GetCommandLine().Parse([]string{}) != nil { t.Error("parse failed for empty argument list") } } func TestUsage(t *testing.T) { called := false ResetForTesting(func() { called = true }) err := GetCommandLine().Parse([]string{"--x"}) expectedErr := "unknown flag: --x" if err == nil { t.Error("parse did not fail for unknown flag") } if err.Error() != expectedErr { t.Errorf("expected error %q, got %q", expectedErr, err.Error()) } if called { t.Error("did call Usage while using ContinueOnError") } } func TestAddFlagSet(t *testing.T) { oldSet := NewFlagSet("old", ContinueOnError) newSet := NewFlagSet("new", ContinueOnError) oldSet.String("flag1", "flag1", "flag1") oldSet.String("flag2", "flag2", "flag2") newSet.String("flag2", "flag2", "flag2") newSet.String("flag3", "flag3", "flag3") oldSet.AddFlagSet(newSet) if len(oldSet.formal) != 3 { t.Errorf("Unexpected result adding a FlagSet to a FlagSet %v", oldSet) } } func TestAnnotation(t *testing.T) { f := NewFlagSet("shorthand", ContinueOnError) err := f.SetAnnotation("missing-flag", "key", nil) expectedErr := "no such flag -missing-flag" if err == nil { t.Errorf("Expected error setting annotation on non-existent flag") } if err.Error() != expectedErr { t.Errorf("expected error %q, got %q", expectedErr, err.Error()) } f.StringP("stringa", "a", "", "string value") if err := f.SetAnnotation("stringa", "key", nil); err != nil { t.Errorf("Unexpected error setting new nil annotation: %v", err) } if annotation := f.Lookup("stringa").Annotations["key"]; annotation != nil { t.Errorf("Unexpected annotation: %v", annotation) } f.StringP("stringb", "b", "", "string2 value") if err := f.SetAnnotation("stringb", "key", []string{"value1"}); err != nil { t.Errorf("Unexpected error setting new annotation: %v", err) } if annotation := f.Lookup("stringb").Annotations["key"]; !reflect.DeepEqual(annotation, []string{"value1"}) { t.Errorf("Unexpected annotation: %v", annotation) } if err := f.SetAnnotation("stringb", "key", []string{"value2"}); err != nil { t.Errorf("Unexpected error updating annotation: %v", err) } if annotation := f.Lookup("stringb").Annotations["key"]; !reflect.DeepEqual(annotation, []string{"value2"}) { t.Errorf("Unexpected annotation: %v", annotation) } } func TestName(t *testing.T) { flagSetName := "bob" f := NewFlagSet(flagSetName, ContinueOnError) givenName := f.Name() if givenName != flagSetName { t.Errorf("Unexpected result when retrieving a FlagSet's name: expected %s, but found %s", flagSetName, givenName) } } func testParse(f *FlagSet, t *testing.T) { if f.Parsed() { t.Error("f.Parse() = true before Parse") } boolFlag := f.Bool("bool", false, "bool value") bool2Flag := f.Bool("bool2", false, "bool2 value") bool3Flag := f.Bool("bool3", false, "bool3 value") intFlag := f.Int("int", 0, "int value") int8Flag := f.Int8("int8", 0, "int value") int16Flag := f.Int16("int16", 0, "int value") int32Flag := f.Int32("int32", 0, "int value") int64Flag := f.Int64("int64", 0, "int64 value") uintFlag := f.Uint("uint", 0, "uint value") uint8Flag := f.Uint8("uint8", 0, "uint value") uint16Flag := f.Uint16("uint16", 0, "uint value") uint32Flag := f.Uint32("uint32", 0, "uint value") uint64Flag := f.Uint64("uint64", 0, "uint64 value") stringFlag := f.String("string", "0", "string value") float32Flag := f.Float32("float32", 0, "float32 value") float64Flag := f.Float64("float64", 0, "float64 value") ipFlag := f.IP("ip", net.ParseIP("127.0.0.1"), "ip value") maskFlag := f.IPMask("mask", ParseIPv4Mask("0.0.0.0"), "mask value") durationFlag := f.Duration("duration", 5*time.Second, "time.Duration value") optionalIntNoValueFlag := f.Int("optional-int-no-value", 0, "int value") f.Lookup("optional-int-no-value").NoOptDefVal = "9" optionalIntWithValueFlag := f.Int("optional-int-with-value", 0, "int value") f.Lookup("optional-int-no-value").NoOptDefVal = "9" extra := "one-extra-argument" args := []string{ "--bool", "--bool2=true", "--bool3=false", "--int=22", "--int8=-8", "--int16=-16", "--int32=-32", "--int64=0x23", "--uint", "24", "--uint8=8", "--uint16=16", "--uint32=32", "--uint64=25", "--string=hello", "--float32=-172e12", "--float64=2718e28", "--ip=10.11.12.13", "--mask=255.255.255.0", "--duration=2m", "--optional-int-no-value", "--optional-int-with-value=42", extra, } if err := f.Parse(args); err != nil { t.Fatal(err) } if !f.Parsed() { t.Error("f.Parse() = false after Parse") } if *boolFlag != true { t.Error("bool flag should be true, is ", *boolFlag) } if v, err := f.GetBool("bool"); err != nil || v != *boolFlag { t.Error("GetBool does not work.") } if *bool2Flag != true { t.Error("bool2 flag should be true, is ", *bool2Flag) } if *bool3Flag != false { t.Error("bool3 flag should be false, is ", *bool2Flag) } if *intFlag != 22 { t.Error("int flag should be 22, is ", *intFlag) } if v, err := f.GetInt("int"); err != nil || v != *intFlag { t.Error("GetInt does not work.") } if *int8Flag != -8 { t.Error("int8 flag should be 0x23, is ", *int8Flag) } if *int16Flag != -16 { t.Error("int16 flag should be -16, is ", *int16Flag) } if v, err := f.GetInt8("int8"); err != nil || v != *int8Flag { t.Error("GetInt8 does not work.") } if v, err := f.GetInt16("int16"); err != nil || v != *int16Flag { t.Error("GetInt16 does not work.") } if *int32Flag != -32 { t.Error("int32 flag should be 0x23, is ", *int32Flag) } if v, err := f.GetInt32("int32"); err != nil || v != *int32Flag { t.Error("GetInt32 does not work.") } if *int64Flag != 0x23 { t.Error("int64 flag should be 0x23, is ", *int64Flag) } if v, err := f.GetInt64("int64"); err != nil || v != *int64Flag { t.Error("GetInt64 does not work.") } if *uintFlag != 24 { t.Error("uint flag should be 24, is ", *uintFlag) } if v, err := f.GetUint("uint"); err != nil || v != *uintFlag { t.Error("GetUint does not work.") } if *uint8Flag != 8 { t.Error("uint8 flag should be 8, is ", *uint8Flag) } if v, err := f.GetUint8("uint8"); err != nil || v != *uint8Flag { t.Error("GetUint8 does not work.") } if *uint16Flag != 16 { t.Error("uint16 flag should be 16, is ", *uint16Flag) } if v, err := f.GetUint16("uint16"); err != nil || v != *uint16Flag { t.Error("GetUint16 does not work.") } if *uint32Flag != 32 { t.Error("uint32 flag should be 32, is ", *uint32Flag) } if v, err := f.GetUint32("uint32"); err != nil || v != *uint32Flag { t.Error("GetUint32 does not work.") } if *uint64Flag != 25 { t.Error("uint64 flag should be 25, is ", *uint64Flag) } if v, err := f.GetUint64("uint64"); err != nil || v != *uint64Flag { t.Error("GetUint64 does not work.") } if *stringFlag != "hello" { t.Error("string flag should be `hello`, is ", *stringFlag) } if v, err := f.GetString("string"); err != nil || v != *stringFlag { t.Error("GetString does not work.") } if *float32Flag != -172e12 { t.Error("float32 flag should be -172e12, is ", *float32Flag) } if v, err := f.GetFloat32("float32"); err != nil || v != *float32Flag { t.Errorf("GetFloat32 returned %v but float32Flag was %v", v, *float32Flag) } if *float64Flag != 2718e28 { t.Error("float64 flag should be 2718e28, is ", *float64Flag) } 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")) { 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 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 { t.Error("duration flag should be 2m, is ", *durationFlag) } if v, err := f.GetDuration("duration"); err != nil || v != *durationFlag { t.Error("GetDuration does not work.") } if _, err := f.GetInt("duration"); err == nil { t.Error("GetInt parsed a time.Duration?!?!") } if *optionalIntNoValueFlag != 9 { t.Error("optional int flag should be the default value, is ", *optionalIntNoValueFlag) } if *optionalIntWithValueFlag != 42 { t.Error("optional int flag should be 42, is ", *optionalIntWithValueFlag) } if len(f.Args()) != 1 { t.Error("expected one argument, got", len(f.Args())) } else if f.Args()[0] != extra { t.Errorf("expected argument %q got %q", extra, f.Args()[0]) } // Test unknown err := f.Parse([]string{"--unknown"}) expectedErr := "unknown flag: --unknown" if err == nil { t.Error("parse did not fail for unknown flag") } if err.Error() != expectedErr { t.Errorf("expected error %q, got %q", expectedErr, err.Error()) } // Test invalid err = f.Parse([]string{"--bool=abcdefg"}) expectedErr = `invalid argument "abcdefg" for "--bool" flag: strconv.ParseBool: parsing "abcdefg": invalid syntax` if err == nil { t.Error("parse did not fail for invalid argument") } if err.Error() != expectedErr { t.Errorf("expected error %q, got %q", expectedErr, err.Error()) } // Test required err = f.Parse([]string{"--int"}) expectedErr = `flag needs an argument: --int` if err == nil { t.Error("parse did not fail for missing argument") } if err.Error() != expectedErr { t.Errorf("expected error %q, got %q", expectedErr, err.Error()) } } func testParseAll(f *FlagSet, t *testing.T) { if f.Parsed() { t.Error("f.Parse() = true before Parse") } f.BoolP("boola", "a", false, "bool value") f.BoolP("boolb", "b", false, "bool2 value") f.BoolP("boolc", "c", false, "bool3 value") f.BoolP("boold", "d", false, "bool4 value") f.StringP("stringa", "s", "0", "string value") f.StringP("stringz", "z", "0", "string value") f.StringP("stringx", "x", "0", "string value") f.StringP("stringy", "y", "0", "string value") f.Lookup("stringx").NoOptDefVal = "1" args := []string{ "-ab", "-cs=xx", "--stringz=something", "-d=true", "-x", "-y", "ee", } want := []string{ "boola", "true", "boolb", "true", "boolc", "true", "stringa", "xx", "stringz", "something", "boold", "true", "stringx", "1", "stringy", "ee", } got := []string{} store := func(flag *Flag, value string) error { got = append(got, flag.Name) if len(value) > 0 { got = append(got, value) } return nil } if err := f.ParseAll(args, store); err != nil { t.Errorf("expected no error, got %s", err) } if !f.Parsed() { t.Errorf("f.Parse() = false after Parse") } if !reflect.DeepEqual(got, want) { t.Errorf("f.ParseAll() fail to restore the args") t.Errorf("Got: %v", got) t.Errorf("Want: %v", want) } } func testParseWithUnknownFlags(f *FlagSet, t *testing.T, setUnknownFlags func(f *FlagSet)) { if f.Parsed() { t.Error("f.Parse() = true before Parse") } setUnknownFlags(f) f.BoolP("boola", "a", false, "bool value") f.BoolP("boolb", "b", false, "bool2 value") f.BoolP("boolc", "c", false, "bool3 value") f.BoolP("boold", "d", false, "bool4 value") f.BoolP("boole", "e", false, "bool4 value") f.StringP("stringa", "s", "0", "string value") f.StringP("stringz", "z", "0", "string value") f.StringP("stringx", "x", "0", "string value") f.StringP("stringy", "y", "0", "string value") f.StringP("stringo", "o", "0", "string value") f.Lookup("stringx").NoOptDefVal = "1" args := []string{ "-ab", "-cs=xx", "--stringz=something", "--unknown1", "unknown1Value", "-d=true", "-x", "--unknown2=unknown2Value", "-u=unknown3Value", "-p", "unknown4Value", "-q", // another unknown with bool value "-y", "ee", "--unknown7=unknown7value", "--stringo=ovalue", "--unknown8=unknown8value", "--boole", "--unknown6", "", "-uuuuu", "", "--unknown10", "--unknown11", } want := []string{ "boola", "true", "boolb", "true", "boolc", "true", "stringa", "xx", "stringz", "something", "boold", "true", "stringx", "1", "stringy", "ee", "stringo", "ovalue", "boole", "true", } got := []string{} store := func(flag *Flag, value string) error { got = append(got, flag.Name) if len(value) > 0 { got = append(got, value) } return nil } if err := f.ParseAll(args, store); err != nil { t.Errorf("expected no error, got %s", err) } if !f.Parsed() { t.Errorf("f.Parse() = false after Parse") } if !reflect.DeepEqual(got, want) { t.Errorf("f.ParseAll() fail to restore the args") t.Errorf("Got: %v", got) t.Errorf("Want: %v", want) } } func TestShorthand(t *testing.T) { f := NewFlagSet("shorthand", ContinueOnError) if f.Parsed() { t.Error("f.Parse() = true before Parse") } boolaFlag := f.BoolP("boola", "a", false, "bool value") boolbFlag := f.BoolP("boolb", "b", false, "bool2 value") boolcFlag := f.BoolP("boolc", "c", false, "bool3 value") booldFlag := f.BoolP("boold", "d", false, "bool4 value") stringaFlag := f.StringP("stringa", "s", "0", "string value") stringzFlag := f.StringP("stringz", "z", "0", "string value") extra := "interspersed-argument" notaflag := "--i-look-like-a-flag" args := []string{ "-ab", extra, "-cs", "hello", "-z=something", "-d=true", "--", notaflag, } f.SetOutput(ioutil.Discard) if err := f.Parse(args); err != nil { t.Error("expected no error, got ", err) } if !f.Parsed() { t.Error("f.Parse() = false after Parse") } if *boolaFlag != true { t.Error("boola flag should be true, is ", *boolaFlag) } if *boolbFlag != true { t.Error("boolb flag should be true, is ", *boolbFlag) } if *boolcFlag != true { t.Error("boolc flag should be true, is ", *boolcFlag) } if *booldFlag != true { t.Error("boold flag should be true, is ", *booldFlag) } if *stringaFlag != "hello" { t.Error("stringa flag should be `hello`, is ", *stringaFlag) } if *stringzFlag != "something" { t.Error("stringz flag should be `something`, is ", *stringzFlag) } if len(f.Args()) != 2 { t.Error("expected one argument, got", len(f.Args())) } else if f.Args()[0] != extra { t.Errorf("expected argument %q got %q", extra, f.Args()[0]) } else if 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) } // Test unknown err := f.Parse([]string{"-ukn"}) expectedErr := "unknown shorthand flag: 'u' in -ukn" if err == nil { t.Error("parse did not fail for unknown shorthand flag") } if err.Error() != expectedErr { t.Errorf("expected error %q, got %q", expectedErr, err.Error()) } // Test required err = f.Parse([]string{"-as"}) expectedErr = `flag needs an argument: 's' in -s` if err == nil { t.Error("parse did not fail for missing argument") } if err.Error() != expectedErr { t.Errorf("expected error %q, got %q", expectedErr, err.Error()) } } func TestShorthandLookup(t *testing.T) { f := NewFlagSet("shorthand", ContinueOnError) if f.Parsed() { t.Error("f.Parse() = true before Parse") } f.BoolP("boola", "a", false, "bool value") f.BoolP("boolb", "b", false, "bool2 value") args := []string{ "-ab", } f.SetOutput(ioutil.Discard) if err := f.Parse(args); err != nil { t.Error("expected no error, got ", err) } if !f.Parsed() { t.Error("f.Parse() = false after Parse") } flag := f.ShorthandLookup("a") if flag == nil { t.Errorf("f.ShorthandLookup(\"a\") returned nil") } if flag.Name != "boola" { t.Errorf("f.ShorthandLookup(\"a\") found %q instead of \"boola\"", flag.Name) } flag = f.ShorthandLookup("") if flag != nil { t.Errorf("f.ShorthandLookup(\"\") did not return nil") } defer func() { recover() }() flag = f.ShorthandLookup("ab") // should NEVER get here. lookup should panic. defer'd func should recover it. t.Errorf("f.ShorthandLookup(\"ab\") did not panic") } func TestParse(t *testing.T) { ResetForTesting(func() { t.Error("bad parse") }) testParse(GetCommandLine(), t) } func TestParseAll(t *testing.T) { ResetForTesting(func() { t.Error("bad parse") }) testParseAll(GetCommandLine(), t) } func TestIgnoreUnknownFlags(t *testing.T) { ResetForTesting(func() { t.Error("bad parse") }) testParseWithUnknownFlags(GetCommandLine(), t, func(f *FlagSet) { f.ParseErrorsAllowlist.UnknownFlags = true }) } func TestIgnoreUnknownFlagsBackwardsCompat(t *testing.T) { ResetForTesting(func() { t.Error("bad parse") }) testParseWithUnknownFlags(GetCommandLine(), t, func(f *FlagSet) { f.ParseErrorsWhitelist.UnknownFlags = true }) } func TestFlagSetParse(t *testing.T) { testParse(NewFlagSet("test", ContinueOnError), t) } func TestParseRepeated(t *testing.T) { fs := NewFlagSet("test repeated", ContinueOnError) t.Run("first parse", func(t *testing.T) { err := fs.Parse([]string{"foo", "bar"}) if err != nil { t.Fatal("expected no error, got ", err) } argsAfterFirst := fs.Args() if !reflect.DeepEqual(argsAfterFirst, []string{"foo", "bar"}) { t.Fatalf("expected args [foo bar], got %v", argsAfterFirst) } }) t.Run("re-parse with fewer args", func(t *testing.T) { err := fs.Parse([]string{"baz"}) if err != nil { t.Fatal("expected no error, got ", err) } argsAfterSecond := fs.Args() if !reflect.DeepEqual(argsAfterSecond, []string{"baz"}) { t.Fatalf("expected args [baz], got %v", argsAfterSecond) } }) t.Run("re-parse with no args", func(t *testing.T) { err := fs.Parse([]string{}) if err != nil { t.Fatal("expected no error, got ", err) } argsAfterThird := fs.Args() if !reflect.DeepEqual(argsAfterThird, []string{}) { t.Fatalf("expected args [], got %v", argsAfterThird) } }) } func TestChangedHelper(t *testing.T) { f := NewFlagSet("changedtest", ContinueOnError) f.Bool("changed", false, "changed bool") f.Bool("settrue", true, "true to true") f.Bool("setfalse", false, "false to false") f.Bool("unchanged", false, "unchanged bool") args := []string{"--changed", "--settrue", "--setfalse=false"} if err := f.Parse(args); err != nil { t.Error("f.Parse() = false after Parse") } if !f.Changed("changed") { t.Errorf("--changed wasn't changed!") } if !f.Changed("settrue") { t.Errorf("--settrue wasn't changed!") } if !f.Changed("setfalse") { t.Errorf("--setfalse wasn't changed!") } if f.Changed("unchanged") { t.Errorf("--unchanged was changed!") } if f.Changed("invalid") { t.Errorf("--invalid was changed!") } if f.ArgsLenAtDash() != -1 { t.Errorf("Expected argsLenAtDash: %d but got %d", -1, f.ArgsLenAtDash()) } } func replaceSeparators(name string, from []string, to string) string { result := name for _, sep := range from { result = strings.Replace(result, sep, to, -1) } // Type convert to indicate normalization has been done. return result } func wordSepNormalizeFunc(f *FlagSet, name string) NormalizedName { seps := []string{"-", "_"} name = replaceSeparators(name, seps, ".") normalizeFlagNameInvocations++ return NormalizedName(name) } func testWordSepNormalizedNames(args []string, t *testing.T) { f := NewFlagSet("normalized", ContinueOnError) if f.Parsed() { t.Error("f.Parse() = true before Parse") } withDashFlag := f.Bool("with-dash-flag", false, "bool value") // Set this after some flags have been added and before others. f.SetNormalizeFunc(wordSepNormalizeFunc) withUnderFlag := f.Bool("with_under_flag", false, "bool value") withBothFlag := f.Bool("with-both_flag", false, "bool value") if err := f.Parse(args); err != nil { t.Fatal(err) } if !f.Parsed() { t.Error("f.Parse() = false after Parse") } if *withDashFlag != true { t.Error("withDashFlag flag should be true, is ", *withDashFlag) } if *withUnderFlag != true { t.Error("withUnderFlag flag should be true, is ", *withUnderFlag) } if *withBothFlag != true { t.Error("withBothFlag flag should be true, is ", *withBothFlag) } } func TestWordSepNormalizedNames(t *testing.T) { args := []string{ "--with-dash-flag", "--with-under-flag", "--with-both-flag", } testWordSepNormalizedNames(args, t) args = []string{ "--with_dash_flag", "--with_under_flag", "--with_both_flag", } testWordSepNormalizedNames(args, t) args = []string{ "--with-dash_flag", "--with-under_flag", "--with-both_flag", } testWordSepNormalizedNames(args, t) } func aliasAndWordSepFlagNames(f *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: name = newName } return NormalizedName(name) } func TestCustomNormalizedNames(t *testing.T) { f := NewFlagSet("normalized", ContinueOnError) if f.Parsed() { t.Error("f.Parse() = true before Parse") } validFlag := f.Bool("valid-flag", false, "bool value") f.SetNormalizeFunc(aliasAndWordSepFlagNames) someOtherFlag := f.Bool("some-other-flag", false, "bool value") args := []string{"--old_valid_flag", "--some-other_flag"} if err := f.Parse(args); err != nil { t.Fatal(err) } if *validFlag != true { t.Errorf("validFlag is %v even though we set the alias --old_valid_falg", *validFlag) } if *someOtherFlag != true { t.Error("someOtherFlag should be true, is ", *someOtherFlag) } } // Every flag we add, the name (displayed also in usage) should normalized func TestNormalizationFuncShouldChangeFlagName(t *testing.T) { // Test normalization after addition f := NewFlagSet("normalized", ContinueOnError) f.Bool("valid_flag", false, "bool value") if f.Lookup("valid_flag").Name != "valid_flag" { t.Error("The new flag should have the name 'valid_flag' instead of ", f.Lookup("valid_flag").Name) } f.SetNormalizeFunc(wordSepNormalizeFunc) if f.Lookup("valid_flag").Name != "valid.flag" { t.Error("The new flag should have the name 'valid.flag' instead of ", f.Lookup("valid_flag").Name) } // Test normalization before addition f = NewFlagSet("normalized", ContinueOnError) f.SetNormalizeFunc(wordSepNormalizeFunc) f.Bool("valid_flag", false, "bool value") if f.Lookup("valid_flag").Name != "valid.flag" { t.Error("The new flag should have the name 'valid.flag' instead of ", f.Lookup("valid_flag").Name) } } // Related to https://github.com/spf13/cobra/issues/521. func TestNormalizationSharedFlags(t *testing.T) { f := NewFlagSet("set f", ContinueOnError) g := NewFlagSet("set g", ContinueOnError) nfunc := wordSepNormalizeFunc testName := "valid_flag" normName := nfunc(nil, testName) if testName == string(normName) { t.Error("TestNormalizationSharedFlags meaningless: the original and normalized flag names are identical:", testName) } f.Bool(testName, false, "bool value") g.AddFlagSet(f) f.SetNormalizeFunc(nfunc) g.SetNormalizeFunc(nfunc) if len(f.formal) != 1 { t.Error("Normalizing flags should not result in duplications in the flag set:", f.formal) } if f.orderedFormal[0].Name != string(normName) { t.Error("Flag name not normalized") } for k := range f.formal { if k != "valid.flag" { t.Errorf("The key in the flag map should have been normalized: wanted \"%s\", got \"%s\" instead", normName, k) } } if !reflect.DeepEqual(f.formal, g.formal) || !reflect.DeepEqual(f.orderedFormal, g.orderedFormal) { t.Error("Two flag sets sharing the same flags should stay consistent after being normalized. Original set:", f.formal, "Duplicate set:", g.formal) } } func TestNormalizationSetFlags(t *testing.T) { f := NewFlagSet("normalized", ContinueOnError) nfunc := wordSepNormalizeFunc testName := "valid_flag" normName := nfunc(nil, testName) if testName == string(normName) { t.Error("TestNormalizationSetFlags meaningless: the original and normalized flag names are identical:", testName) } f.Bool(testName, false, "bool value") f.Set(testName, "true") f.SetNormalizeFunc(nfunc) if len(f.formal) != 1 { t.Error("Normalizing flags should not result in duplications in the flag set:", f.formal) } if f.orderedFormal[0].Name != string(normName) { t.Error("Flag name not normalized") } for k := range f.formal { if k != "valid.flag" { t.Errorf("The key in the flag map should have been normalized: wanted \"%s\", got \"%s\" instead", normName, k) } } if !reflect.DeepEqual(f.formal, f.actual) { t.Error("The map of set flags should get normalized. Formal:", f.formal, "Actual:", f.actual) } } // Declare a user-defined flag type. type flagVar []string func (f *flagVar) String() string { return fmt.Sprint([]string(*f)) } func (f *flagVar) Set(value string) error { *f = append(*f, value) return nil } func (f *flagVar) Type() string { return "flagVar" } func TestUserDefined(t *testing.T) { var flags FlagSet flags.Init("test", ContinueOnError) var v flagVar flags.VarP(&v, "v", "v", "usage") if err := flags.Parse([]string{"--v=1", "-v2", "-v", "3"}); err != nil { t.Error(err) } if len(v) != 3 { t.Fatal("expected 3 args; got ", len(v)) } expect := "[1 2 3]" if v.String() != expect { t.Errorf("expected value %q got %q", expect, v.String()) } } func TestSetOutput(t *testing.T) { var flags FlagSet var buf bytes.Buffer flags.SetOutput(&buf) flags.Init("test", ContinueOnError) flags.Parse([]string{"--unknown"}) if out := buf.String(); !strings.Contains(out, "--unknown") { t.Logf("expected output mentioning unknown; got %q", out) } } func TestOutput(t *testing.T) { var flags FlagSet var buf bytes.Buffer expect := "an example string" flags.SetOutput(&buf) fmt.Fprint(flags.Output(), expect) if out := buf.String(); !strings.Contains(out, expect) { t.Errorf("expected output %q; got %q", expect, out) } } // This tests that one can reset the flags. This still works but not well, and is // superseded by FlagSet. func TestChangingArgs(t *testing.T) { ResetForTesting(func() { t.Fatal("bad parse") }) oldArgs := os.Args defer func() { os.Args = oldArgs }() os.Args = []string{"cmd", "--before", "subcmd"} before := Bool("before", false, "") if err := GetCommandLine().Parse(os.Args[1:]); err != nil { t.Fatal(err) } cmd := Arg(0) os.Args = []string{"subcmd", "--after", "args"} after := Bool("after", false, "") Parse() args := Args() if !*before || cmd != "subcmd" || !*after || len(args) != 1 || args[0] != "args" { t.Fatalf("expected true subcmd true [args] got %v %v %v %v", *before, cmd, *after, args) } } // Test that -help invokes the usage message and returns ErrHelp. func TestHelp(t *testing.T) { helpCalled := false fs := NewFlagSet("help test", ContinueOnError) fs.Usage = func() { helpCalled = true } var flag bool fs.BoolVar(&flag, "flag", false, "regular flag") // Regular flag invocation should work err := fs.Parse([]string{"--flag=true"}) if err != nil { t.Fatal("expected no error; got ", err) } if !flag { t.Error("flag was not set by --flag") } if helpCalled { t.Error("help called for regular flag") helpCalled = false // reset for next test } // Help flag should work as expected. err = fs.Parse([]string{"--help"}) if err == nil { t.Fatal("error expected") } if err != ErrHelp { t.Fatal("expected ErrHelp; got ", err) } if !helpCalled { t.Fatal("help was not called") } // If we define a help flag, that should override. var help bool fs.BoolVar(&help, "help", false, "help flag") helpCalled = false err = fs.Parse([]string{"--help"}) if err != nil { t.Fatal("expected no error for defined --help; got ", err) } if helpCalled { t.Fatal("help was called; should not have been for defined help flag") } } func TestNoInterspersed(t *testing.T) { f := NewFlagSet("test", ContinueOnError) f.SetInterspersed(false) f.Bool("true", true, "always true") f.Bool("false", false, "always false") err := f.Parse([]string{"--true", "break", "--false"}) if err != nil { t.Fatal("expected no error; got ", err) } args := f.Args() if len(args) != 2 || args[0] != "break" || args[1] != "--false" { t.Fatal("expected interspersed options/non-options to fail") } } func TestTermination(t *testing.T) { f := NewFlagSet("termination", ContinueOnError) boolFlag := f.BoolP("bool", "l", false, "bool value") if f.Parsed() { t.Error("f.Parse() = true before Parse") } arg1 := "ls" arg2 := "-l" args := []string{ "--", arg1, arg2, } f.SetOutput(ioutil.Discard) if err := f.Parse(args); err != nil { t.Fatal("expected no error; got ", err) } if !f.Parsed() { t.Error("f.Parse() = false after Parse") } if *boolFlag { t.Error("expected boolFlag=false, got true") } if len(f.Args()) != 2 { t.Errorf("expected 2 arguments, got %d: %v", len(f.Args()), f.Args()) } if f.Args()[0] != arg1 { t.Errorf("expected argument %q got %q", arg1, f.Args()[0]) } if f.Args()[1] != arg2 { t.Errorf("expected argument %q got %q", arg2, f.Args()[1]) } if f.ArgsLenAtDash() != 0 { t.Errorf("expected argsLenAtDash %d got %d", 0, f.ArgsLenAtDash()) } } func getDeprecatedFlagSet() *FlagSet { f := NewFlagSet("bob", ContinueOnError) f.Bool("badflag", true, "always true") f.MarkDeprecated("badflag", "use --good-flag instead") return f } func TestDeprecatedFlagInDocs(t *testing.T) { f := getDeprecatedFlagSet() out := new(bytes.Buffer) f.SetOutput(out) f.PrintDefaults() if strings.Contains(out.String(), "badflag") { t.Errorf("found deprecated flag in usage!") } } func TestUnHiddenDeprecatedFlagInDocs(t *testing.T) { f := getDeprecatedFlagSet() flg := f.Lookup("badflag") if flg == nil { t.Fatalf("Unable to lookup 'bob' in TestUnHiddenDeprecatedFlagInDocs") } flg.Hidden = false out := new(bytes.Buffer) f.SetOutput(out) f.PrintDefaults() defaults := out.String() if !strings.Contains(defaults, "badflag") { t.Errorf("Did not find deprecated flag in usage!") } if !strings.Contains(defaults, "use --good-flag instead") { t.Errorf("Did not find 'use --good-flag instead' in defaults") } } 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)) out := new(bytes.Buffer) f.SetOutput(out) f.PrintDefaults() if strings.Contains(out.String(), "-n,") { t.Errorf("found deprecated flag shorthand in usage!") } } func parseReturnStderr(t *testing.T, f *FlagSet, args []string) (string, error) { oldStderr := os.Stderr r, w, _ := os.Pipe() os.Stderr = w err := f.Parse(args) outC := make(chan string) // copy the output in a separate goroutine so printing can't block indefinitely go func() { var buf bytes.Buffer io.Copy(&buf, r) outC <- buf.String() }() w.Close() os.Stderr = oldStderr out := <-outC return out, err } func TestDeprecatedFlagUsage(t *testing.T) { f := NewFlagSet("bob", ContinueOnError) f.Bool("badflag", true, "always true") usageMsg := "use --good-flag instead" f.MarkDeprecated("badflag", usageMsg) args := []string{"--badflag"} out, err := parseReturnStderr(t, f, args) if err != nil { t.Fatal("expected no error; got ", err) } if !strings.Contains(out, usageMsg) { t.Errorf("usageMsg not printed when using a deprecated flag!") } } func TestDeprecatedFlagShorthandUsage(t *testing.T) { f := NewFlagSet("bob", ContinueOnError) name := "noshorthandflag" f.BoolP(name, "n", true, "always true") usageMsg := fmt.Sprintf("use --%s instead", name) f.MarkShorthandDeprecated(name, usageMsg) args := []string{"-n"} out, err := parseReturnStderr(t, f, args) if err != nil { t.Fatal("expected no error; got ", err) } if !strings.Contains(out, usageMsg) { t.Errorf("usageMsg not printed when using a deprecated flag!") } } func TestDeprecatedFlagUsageNormalized(t *testing.T) { f := NewFlagSet("bob", ContinueOnError) f.Bool("bad-double_flag", true, "always true") f.SetNormalizeFunc(wordSepNormalizeFunc) usageMsg := "use --good-flag instead" f.MarkDeprecated("bad_double-flag", usageMsg) args := []string{"--bad_double_flag"} out, err := parseReturnStderr(t, f, args) if err != nil { t.Fatal("expected no error; got ", err) } if !strings.Contains(out, usageMsg) { t.Errorf("usageMsg not printed when using a deprecated flag!") } } // Name normalization function should be called only once on flag addition func TestMultipleNormalizeFlagNameInvocations(t *testing.T) { normalizeFlagNameInvocations = 0 f := NewFlagSet("normalized", ContinueOnError) f.SetNormalizeFunc(wordSepNormalizeFunc) f.Bool("with_under_flag", false, "bool value") if normalizeFlagNameInvocations != 1 { t.Fatal("Expected normalizeFlagNameInvocations to be 1; got ", normalizeFlagNameInvocations) } } func TestHiddenFlagInUsage(t *testing.T) { f := NewFlagSet("bob", ContinueOnError) f.Bool("secretFlag", true, "shhh") f.MarkHidden("secretFlag") out := new(bytes.Buffer) f.SetOutput(out) f.PrintDefaults() if strings.Contains(out.String(), "secretFlag") { t.Errorf("found hidden flag in usage!") } } func TestHiddenFlagUsage(t *testing.T) { f := NewFlagSet("bob", ContinueOnError) f.Bool("secretFlag", true, "shhh") f.MarkHidden("secretFlag") args := []string{"--secretFlag"} out, err := parseReturnStderr(t, f, args) if err != nil { t.Fatal("expected no error; got ", err) } if strings.Contains(out, "shhh") { t.Errorf("usage message printed when using a hidden flag!") } } const defaultOutput = ` --A for bootstrapping, allow 'any' type --Alongflagname disable bounds checking -C, --CCC a boolean defaulting to true (default true) --D path set relative path for local imports -E, --EEE num[=1234] a num with NoOptDefVal (default 4321) --F number a non-zero number (default 2.7) --G float a float that defaults to zero --IP ip IP address with no default --IPMask ipMask Netmask address with no default --IPNet ipNet IP network with no default --Ints ints int slice with zero default --N int a non-zero int (default 27) --ND1 string[="bar"] a string with NoOptDefVal (default "foo") --ND2 num[=4321] a num with NoOptDefVal (default 1234) --StringArray stringArray string array with zero default --StringSlice strings string slice with zero default --Z int an int that defaults to zero --custom custom custom Value implementation --custom-with-val custom custom value which has been set from command line while help is shown --customP custom a VarP with default (default 10) --maxT timeout set timeout for dial -v, --verbose count verbosity ` // Custom value that satisfies the Value interface. type customValue int func (cv *customValue) String() string { return fmt.Sprintf("%v", *cv) } func (cv *customValue) Set(s string) error { v, err := strconv.ParseInt(s, 0, 64) *cv = customValue(v) return err } func (cv *customValue) Type() string { return "custom" } func TestPrintDefaults(t *testing.T) { fs := NewFlagSet("print defaults test", ContinueOnError) var buf bytes.Buffer fs.SetOutput(&buf) fs.Bool("A", false, "for bootstrapping, allow 'any' type") fs.Bool("Alongflagname", false, "disable bounds checking") fs.BoolP("CCC", "C", true, "a boolean defaulting to true") fs.String("D", "", "set relative `path` for local imports") fs.Float64("F", 2.7, "a non-zero `number`") fs.Float64("G", 0, "a float that defaults to zero") fs.Int("N", 27, "a non-zero int") fs.IntSlice("Ints", []int{}, "int slice with zero default") fs.IP("IP", nil, "IP address with no default") fs.IPMask("IPMask", nil, "Netmask address with no default") fs.IPNet("IPNet", net.IPNet{}, "IP network with no default") fs.Int("Z", 0, "an int that defaults to zero") fs.Duration("maxT", 0, "set `timeout` for dial") fs.String("ND1", "foo", "a string with NoOptDefVal") fs.Lookup("ND1").NoOptDefVal = "bar" fs.Int("ND2", 1234, "a `num` with NoOptDefVal") fs.Lookup("ND2").NoOptDefVal = "4321" fs.IntP("EEE", "E", 4321, "a `num` with NoOptDefVal") fs.ShorthandLookup("E").NoOptDefVal = "1234" fs.StringSlice("StringSlice", []string{}, "string slice with zero default") fs.StringArray("StringArray", []string{}, "string array with zero default") fs.CountP("verbose", "v", "verbosity") var cv customValue fs.Var(&cv, "custom", "custom Value implementation") cv2 := customValue(10) fs.VarP(&cv2, "customP", "", "a VarP with default") // Simulate case where a value has been provided and the help screen is shown var cv3 customValue fs.Var(&cv3, "custom-with-val", "custom value which has been set from command line while help is shown") err := fs.Parse([]string{"--custom-with-val", "3"}) if err != nil { t.Error("Parsing flags failed:", err) } fs.PrintDefaults() got := buf.String() if got != defaultOutput { t.Errorf("\n--- Got:\n%s--- Wanted:\n%s\n", got, defaultOutput) } } func TestVisitAllFlagOrder(t *testing.T) { fs := NewFlagSet("TestVisitAllFlagOrder", ContinueOnError) fs.SortFlags = false // https://github.com/spf13/pflag/issues/120 fs.SetNormalizeFunc(func(f *FlagSet, name string) NormalizedName { return NormalizedName(name) }) names := []string{"C", "B", "A", "D"} for _, name := range names { fs.Bool(name, false, "") } i := 0 fs.VisitAll(func(f *Flag) { if names[i] != f.Name { t.Errorf("Incorrect order. Expected %v, got %v", names[i], f.Name) } i++ }) } func TestVisitFlagOrder(t *testing.T) { fs := NewFlagSet("TestVisitFlagOrder", ContinueOnError) fs.SortFlags = false names := []string{"C", "B", "A", "D"} for _, name := range names { fs.Bool(name, false, "") fs.Set(name, "true") } i := 0 fs.Visit(func(f *Flag) { if names[i] != f.Name { t.Errorf("Incorrect order. Expected %v, got %v", names[i], f.Name) } i++ }) } spf13-pflag-0491e57/float32.go000066400000000000000000000061401505550473500156300ustar00rootroot00000000000000package pflag import "strconv" // -- float32 Value type float32Value float32 func newFloat32Value(val float32, p *float32) *float32Value { *p = val return (*float32Value)(p) } func (f *float32Value) Set(s string) error { v, err := strconv.ParseFloat(s, 32) *f = float32Value(v) return err } func (f *float32Value) Type() string { return "float32" } func (f *float32Value) String() string { return strconv.FormatFloat(float64(*f), 'g', -1, 32) } func float32Conv(sval string) (interface{}, error) { v, err := strconv.ParseFloat(sval, 32) if err != nil { return 0, err } return float32(v), nil } // GetFloat32 return the float32 value of a flag with the given name func (f *FlagSet) GetFloat32(name string) (float32, error) { val, err := f.getFlagType(name, "float32", float32Conv) if err != nil { return 0, err } return val.(float32), nil } // Float32Var defines a float32 flag with specified name, default value, and usage string. // The argument p points to a float32 variable in which to store the value of the flag. func (f *FlagSet) Float32Var(p *float32, name string, value float32, usage string) { f.VarP(newFloat32Value(value, p), name, "", usage) } // Float32VarP is like Float32Var, but accepts a shorthand letter that can be used after a single dash. func (f *FlagSet) Float32VarP(p *float32, name, shorthand string, value float32, usage string) { f.VarP(newFloat32Value(value, p), name, shorthand, usage) } // Float32Var defines a float32 flag with specified name, default value, and usage string. // The argument p points to a float32 variable in which to store the value of the flag. func Float32Var(p *float32, name string, value float32, usage string) { CommandLine.VarP(newFloat32Value(value, p), name, "", usage) } // Float32VarP is like Float32Var, but accepts a shorthand letter that can be used after a single dash. func Float32VarP(p *float32, name, shorthand string, value float32, usage string) { CommandLine.VarP(newFloat32Value(value, p), name, shorthand, usage) } // Float32 defines a float32 flag with specified name, default value, and usage string. // The return value is the address of a float32 variable that stores the value of the flag. func (f *FlagSet) Float32(name string, value float32, usage string) *float32 { p := new(float32) f.Float32VarP(p, name, "", value, usage) return p } // Float32P is like Float32, but accepts a shorthand letter that can be used after a single dash. func (f *FlagSet) Float32P(name, shorthand string, value float32, usage string) *float32 { p := new(float32) f.Float32VarP(p, name, shorthand, value, usage) return p } // Float32 defines a float32 flag with specified name, default value, and usage string. // The return value is the address of a float32 variable that stores the value of the flag. func Float32(name string, value float32, usage string) *float32 { return CommandLine.Float32P(name, "", value, usage) } // Float32P is like Float32, but accepts a shorthand letter that can be used after a single dash. func Float32P(name, shorthand string, value float32, usage string) *float32 { return CommandLine.Float32P(name, shorthand, value, usage) } spf13-pflag-0491e57/float32_slice.go000066400000000000000000000116621505550473500170140ustar00rootroot00000000000000package pflag import ( "fmt" "strconv" "strings" ) // -- float32Slice Value type float32SliceValue struct { value *[]float32 changed bool } func newFloat32SliceValue(val []float32, p *[]float32) *float32SliceValue { isv := new(float32SliceValue) isv.value = p *isv.value = val return isv } func (s *float32SliceValue) Set(val string) error { ss := strings.Split(val, ",") out := make([]float32, len(ss)) for i, d := range ss { var err error var temp64 float64 temp64, err = strconv.ParseFloat(d, 32) if err != nil { return err } out[i] = float32(temp64) } if !s.changed { *s.value = out } else { *s.value = append(*s.value, out...) } s.changed = true return nil } func (s *float32SliceValue) Type() string { return "float32Slice" } func (s *float32SliceValue) String() string { out := make([]string, len(*s.value)) for i, d := range *s.value { out[i] = fmt.Sprintf("%f", d) } return "[" + strings.Join(out, ",") + "]" } func (s *float32SliceValue) fromString(val string) (float32, error) { t64, err := strconv.ParseFloat(val, 32) if err != nil { return 0, err } return float32(t64), nil } func (s *float32SliceValue) toString(val float32) string { return fmt.Sprintf("%f", val) } func (s *float32SliceValue) Append(val string) error { i, err := s.fromString(val) if err != nil { return err } *s.value = append(*s.value, i) return nil } func (s *float32SliceValue) Replace(val []string) error { out := make([]float32, len(val)) for i, d := range val { var err error out[i], err = s.fromString(d) if err != nil { return err } } *s.value = out return nil } func (s *float32SliceValue) GetSlice() []string { out := make([]string, len(*s.value)) for i, d := range *s.value { out[i] = s.toString(d) } return out } func float32SliceConv(val string) (interface{}, error) { val = strings.Trim(val, "[]") // Empty string would cause a slice with one (empty) entry if len(val) == 0 { return []float32{}, nil } ss := strings.Split(val, ",") out := make([]float32, len(ss)) for i, d := range ss { var err error var temp64 float64 temp64, err = strconv.ParseFloat(d, 32) if err != nil { return nil, err } out[i] = float32(temp64) } return out, nil } // GetFloat32Slice return the []float32 value of a flag with the given name func (f *FlagSet) GetFloat32Slice(name string) ([]float32, error) { val, err := f.getFlagType(name, "float32Slice", float32SliceConv) if err != nil { return []float32{}, err } return val.([]float32), nil } // Float32SliceVar defines a float32Slice flag with specified name, default value, and usage string. // The argument p points to a []float32 variable in which to store the value of the flag. func (f *FlagSet) Float32SliceVar(p *[]float32, name string, value []float32, usage string) { f.VarP(newFloat32SliceValue(value, p), name, "", usage) } // Float32SliceVarP is like Float32SliceVar, but accepts a shorthand letter that can be used after a single dash. func (f *FlagSet) Float32SliceVarP(p *[]float32, name, shorthand string, value []float32, usage string) { f.VarP(newFloat32SliceValue(value, p), name, shorthand, usage) } // Float32SliceVar defines a float32[] flag with specified name, default value, and usage string. // The argument p points to a float32[] variable in which to store the value of the flag. func Float32SliceVar(p *[]float32, name string, value []float32, usage string) { CommandLine.VarP(newFloat32SliceValue(value, p), name, "", usage) } // Float32SliceVarP is like Float32SliceVar, but accepts a shorthand letter that can be used after a single dash. func Float32SliceVarP(p *[]float32, name, shorthand string, value []float32, usage string) { CommandLine.VarP(newFloat32SliceValue(value, p), name, shorthand, usage) } // Float32Slice defines a []float32 flag with specified name, default value, and usage string. // The return value is the address of a []float32 variable that stores the value of the flag. func (f *FlagSet) Float32Slice(name string, value []float32, usage string) *[]float32 { p := []float32{} f.Float32SliceVarP(&p, name, "", value, usage) return &p } // Float32SliceP is like Float32Slice, but accepts a shorthand letter that can be used after a single dash. func (f *FlagSet) Float32SliceP(name, shorthand string, value []float32, usage string) *[]float32 { p := []float32{} f.Float32SliceVarP(&p, name, shorthand, value, usage) return &p } // Float32Slice defines a []float32 flag with specified name, default value, and usage string. // The return value is the address of a []float32 variable that stores the value of the flag. func Float32Slice(name string, value []float32, usage string) *[]float32 { return CommandLine.Float32SliceP(name, "", value, usage) } // Float32SliceP is like Float32Slice, but accepts a shorthand letter that can be used after a single dash. func Float32SliceP(name, shorthand string, value []float32, usage string) *[]float32 { return CommandLine.Float32SliceP(name, shorthand, value, usage) } spf13-pflag-0491e57/float32_slice_test.go000066400000000000000000000111141505550473500200430ustar00rootroot00000000000000// Copyright 2009 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. package pflag import ( "fmt" "strconv" "strings" "testing" ) func setUpF32SFlagSet(f32sp *[]float32) *FlagSet { f := NewFlagSet("test", ContinueOnError) f.Float32SliceVar(f32sp, "f32s", []float32{}, "Command separated list!") return f } func setUpF32SFlagSetWithDefault(f32sp *[]float32) *FlagSet { f := NewFlagSet("test", ContinueOnError) f.Float32SliceVar(f32sp, "f32s", []float32{0.0, 1.0}, "Command separated list!") return f } func TestEmptyF32S(t *testing.T) { var f32s []float32 f := setUpF32SFlagSet(&f32s) err := f.Parse([]string{}) if err != nil { t.Fatal("expected no error; got", err) } getF32S, err := f.GetFloat32Slice("f32s") if err != nil { t.Fatal("got an error from GetFloat32Slice():", err) } if len(getF32S) != 0 { t.Fatalf("got f32s %v with len=%d but expected length=0", getF32S, len(getF32S)) } } func TestF32S(t *testing.T) { var f32s []float32 f := setUpF32SFlagSet(&f32s) 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) } for i, v := range f32s { d64, err := strconv.ParseFloat(vals[i], 32) if err != nil { t.Fatalf("got error: %v", err) } d := float32(d64) if d != v { 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) } for i, v := range getF32S { d64, err := strconv.ParseFloat(vals[i], 32) if err != nil { t.Fatalf("got error: %v", err) } d := float32(d64) if d != v { t.Fatalf("expected f32s[%d] to be %s but got: %f from GetFloat32Slice", i, vals[i], v) } } } func TestF32SDefault(t *testing.T) { var f32s []float32 f := setUpF32SFlagSetWithDefault(&f32s) vals := []string{"0.0", "1.0"} err := f.Parse([]string{}) if err != nil { t.Fatal("expected no error; got", err) } for i, v := range f32s { d64, err := strconv.ParseFloat(vals[i], 32) if err != nil { t.Fatalf("got error: %v", err) } d := float32(d64) if d != v { t.Fatalf("expected f32s[%d] to be %f but got: %f", i, d, v) } } getF32S, err := f.GetFloat32Slice("f32s") if err != nil { t.Fatal("got an error from GetFloat32Slice():", err) } for i, v := range getF32S { d64, err := strconv.ParseFloat(vals[i], 32) if err != nil { t.Fatal("got an error from GetFloat32Slice():", err) } d := float32(d64) if d != v { t.Fatalf("expected f32s[%d] to be %f from GetFloat32Slice but got: %f", i, d, v) } } } func TestF32SWithDefault(t *testing.T) { var f32s []float32 f := setUpF32SFlagSetWithDefault(&f32s) 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) } for i, v := range f32s { d64, err := strconv.ParseFloat(vals[i], 32) if err != nil { t.Fatalf("got error: %v", err) } d := float32(d64) if d != v { t.Fatalf("expected f32s[%d] to be %f but got: %f", i, d, v) } } getF32S, err := f.GetFloat32Slice("f32s") if err != nil { t.Fatal("got an error from GetFloat32Slice():", err) } for i, v := range getF32S { d64, err := strconv.ParseFloat(vals[i], 32) if err != nil { t.Fatalf("got error: %v", err) } d := float32(d64) if d != v { t.Fatalf("expected f32s[%d] to be %f from GetFloat32Slice but got: %f", i, d, v) } } } func TestF32SAsSliceValue(t *testing.T) { var f32s []float32 f := setUpF32SFlagSet(&f32s) in := []string{"1.0", "2.0"} argfmt := "--f32s=%s" arg1 := fmt.Sprintf(argfmt, in[0]) arg2 := fmt.Sprintf(argfmt, in[1]) err := f.Parse([]string{arg1, arg2}) if err != nil { t.Fatal("expected no error; got", err) } f.VisitAll(func(f *Flag) { if val, ok := f.Value.(SliceValue); ok { _ = val.Replace([]string{"3.1"}) } }) if len(f32s) != 1 || f32s[0] != 3.1 { t.Fatalf("Expected ss to be overwritten with '3.1', but got: %v", f32s) } } func TestF32SCalledTwice(t *testing.T) { var f32s []float32 f := setUpF32SFlagSet(&f32s) in := []string{"1.0,2.0", "3.0"} expected := []float32{1.0, 2.0, 3.0} argfmt := "--f32s=%s" arg1 := fmt.Sprintf(argfmt, in[0]) arg2 := fmt.Sprintf(argfmt, in[1]) err := f.Parse([]string{arg1, arg2}) 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) } } } spf13-pflag-0491e57/float64.go000066400000000000000000000060411505550473500156350ustar00rootroot00000000000000package pflag import "strconv" // -- float64 Value type float64Value float64 func newFloat64Value(val float64, p *float64) *float64Value { *p = val return (*float64Value)(p) } func (f *float64Value) Set(s string) error { v, err := strconv.ParseFloat(s, 64) *f = float64Value(v) return err } func (f *float64Value) Type() string { return "float64" } func (f *float64Value) String() string { return strconv.FormatFloat(float64(*f), 'g', -1, 64) } func float64Conv(sval string) (interface{}, error) { return strconv.ParseFloat(sval, 64) } // GetFloat64 return the float64 value of a flag with the given name func (f *FlagSet) GetFloat64(name string) (float64, error) { val, err := f.getFlagType(name, "float64", float64Conv) if err != nil { return 0, err } return val.(float64), nil } // Float64Var defines a float64 flag with specified name, default value, and usage string. // The argument p points to a float64 variable in which to store the value of the flag. func (f *FlagSet) Float64Var(p *float64, name string, value float64, usage string) { f.VarP(newFloat64Value(value, p), name, "", usage) } // Float64VarP is like Float64Var, but accepts a shorthand letter that can be used after a single dash. func (f *FlagSet) Float64VarP(p *float64, name, shorthand string, value float64, usage string) { f.VarP(newFloat64Value(value, p), name, shorthand, usage) } // Float64Var defines a float64 flag with specified name, default value, and usage string. // The argument p points to a float64 variable in which to store the value of the flag. func Float64Var(p *float64, name string, value float64, usage string) { CommandLine.VarP(newFloat64Value(value, p), name, "", usage) } // Float64VarP is like Float64Var, but accepts a shorthand letter that can be used after a single dash. func Float64VarP(p *float64, name, shorthand string, value float64, usage string) { CommandLine.VarP(newFloat64Value(value, p), name, shorthand, usage) } // Float64 defines a float64 flag with specified name, default value, and usage string. // The return value is the address of a float64 variable that stores the value of the flag. func (f *FlagSet) Float64(name string, value float64, usage string) *float64 { p := new(float64) f.Float64VarP(p, name, "", value, usage) return p } // Float64P is like Float64, but accepts a shorthand letter that can be used after a single dash. func (f *FlagSet) Float64P(name, shorthand string, value float64, usage string) *float64 { p := new(float64) f.Float64VarP(p, name, shorthand, value, usage) return p } // Float64 defines a float64 flag with specified name, default value, and usage string. // The return value is the address of a float64 variable that stores the value of the flag. func Float64(name string, value float64, usage string) *float64 { return CommandLine.Float64P(name, "", value, usage) } // Float64P is like Float64, but accepts a shorthand letter that can be used after a single dash. func Float64P(name, shorthand string, value float64, usage string) *float64 { return CommandLine.Float64P(name, shorthand, value, usage) } spf13-pflag-0491e57/float64_slice.go000066400000000000000000000114171505550473500170170ustar00rootroot00000000000000package pflag import ( "fmt" "strconv" "strings" ) // -- float64Slice Value type float64SliceValue struct { value *[]float64 changed bool } func newFloat64SliceValue(val []float64, p *[]float64) *float64SliceValue { isv := new(float64SliceValue) isv.value = p *isv.value = val return isv } func (s *float64SliceValue) Set(val string) error { ss := strings.Split(val, ",") out := make([]float64, len(ss)) for i, d := range ss { var err error out[i], err = strconv.ParseFloat(d, 64) if err != nil { return err } } if !s.changed { *s.value = out } else { *s.value = append(*s.value, out...) } s.changed = true return nil } func (s *float64SliceValue) Type() string { return "float64Slice" } func (s *float64SliceValue) String() string { out := make([]string, len(*s.value)) for i, d := range *s.value { out[i] = fmt.Sprintf("%f", d) } return "[" + strings.Join(out, ",") + "]" } func (s *float64SliceValue) fromString(val string) (float64, error) { return strconv.ParseFloat(val, 64) } func (s *float64SliceValue) toString(val float64) string { return fmt.Sprintf("%f", val) } func (s *float64SliceValue) Append(val string) error { i, err := s.fromString(val) if err != nil { return err } *s.value = append(*s.value, i) return nil } func (s *float64SliceValue) Replace(val []string) error { out := make([]float64, len(val)) for i, d := range val { var err error out[i], err = s.fromString(d) if err != nil { return err } } *s.value = out return nil } func (s *float64SliceValue) GetSlice() []string { out := make([]string, len(*s.value)) for i, d := range *s.value { out[i] = s.toString(d) } return out } func float64SliceConv(val string) (interface{}, error) { val = strings.Trim(val, "[]") // Empty string would cause a slice with one (empty) entry if len(val) == 0 { return []float64{}, nil } ss := strings.Split(val, ",") out := make([]float64, len(ss)) for i, d := range ss { var err error out[i], err = strconv.ParseFloat(d, 64) if err != nil { return nil, err } } return out, nil } // GetFloat64Slice return the []float64 value of a flag with the given name func (f *FlagSet) GetFloat64Slice(name string) ([]float64, error) { val, err := f.getFlagType(name, "float64Slice", float64SliceConv) if err != nil { return []float64{}, err } return val.([]float64), nil } // Float64SliceVar defines a float64Slice flag with specified name, default value, and usage string. // The argument p points to a []float64 variable in which to store the value of the flag. func (f *FlagSet) Float64SliceVar(p *[]float64, name string, value []float64, usage string) { f.VarP(newFloat64SliceValue(value, p), name, "", usage) } // Float64SliceVarP is like Float64SliceVar, but accepts a shorthand letter that can be used after a single dash. func (f *FlagSet) Float64SliceVarP(p *[]float64, name, shorthand string, value []float64, usage string) { f.VarP(newFloat64SliceValue(value, p), name, shorthand, usage) } // Float64SliceVar defines a float64[] flag with specified name, default value, and usage string. // The argument p points to a float64[] variable in which to store the value of the flag. func Float64SliceVar(p *[]float64, name string, value []float64, usage string) { CommandLine.VarP(newFloat64SliceValue(value, p), name, "", usage) } // Float64SliceVarP is like Float64SliceVar, but accepts a shorthand letter that can be used after a single dash. func Float64SliceVarP(p *[]float64, name, shorthand string, value []float64, usage string) { CommandLine.VarP(newFloat64SliceValue(value, p), name, shorthand, usage) } // Float64Slice defines a []float64 flag with specified name, default value, and usage string. // The return value is the address of a []float64 variable that stores the value of the flag. func (f *FlagSet) Float64Slice(name string, value []float64, usage string) *[]float64 { p := []float64{} f.Float64SliceVarP(&p, name, "", value, usage) return &p } // Float64SliceP is like Float64Slice, but accepts a shorthand letter that can be used after a single dash. func (f *FlagSet) Float64SliceP(name, shorthand string, value []float64, usage string) *[]float64 { p := []float64{} f.Float64SliceVarP(&p, name, shorthand, value, usage) return &p } // Float64Slice defines a []float64 flag with specified name, default value, and usage string. // The return value is the address of a []float64 variable that stores the value of the flag. func Float64Slice(name string, value []float64, usage string) *[]float64 { return CommandLine.Float64SliceP(name, "", value, usage) } // Float64SliceP is like Float64Slice, but accepts a shorthand letter that can be used after a single dash. func Float64SliceP(name, shorthand string, value []float64, usage string) *[]float64 { return CommandLine.Float64SliceP(name, shorthand, value, usage) } spf13-pflag-0491e57/float64_slice_test.go000066400000000000000000000107021505550473500200520ustar00rootroot00000000000000// Copyright 2009 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. package pflag import ( "fmt" "strconv" "strings" "testing" ) func setUpF64SFlagSet(f64sp *[]float64) *FlagSet { f := NewFlagSet("test", ContinueOnError) f.Float64SliceVar(f64sp, "f64s", []float64{}, "Command separated list!") return f } func setUpF64SFlagSetWithDefault(f64sp *[]float64) *FlagSet { f := NewFlagSet("test", ContinueOnError) f.Float64SliceVar(f64sp, "f64s", []float64{0.0, 1.0}, "Command separated list!") return f } func TestEmptyF64S(t *testing.T) { var f64s []float64 f := setUpF64SFlagSet(&f64s) err := f.Parse([]string{}) if err != nil { t.Fatal("expected no error; got", err) } getF64S, err := f.GetFloat64Slice("f64s") if err != nil { t.Fatal("got an error from GetFloat64Slice():", err) } if len(getF64S) != 0 { t.Fatalf("got f64s %v with len=%d but expected length=0", getF64S, len(getF64S)) } } func TestF64S(t *testing.T) { var f64s []float64 f := setUpF64SFlagSet(&f64s) 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) } for i, v := range f64s { d, err := strconv.ParseFloat(vals[i], 64) if err != nil { t.Fatalf("got error: %v", err) } if d != v { 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) } for i, v := range getF64S { d, err := strconv.ParseFloat(vals[i], 64) if err != nil { t.Fatalf("got error: %v", err) } if d != v { t.Fatalf("expected f64s[%d] to be %s but got: %f from GetFloat64Slice", i, vals[i], v) } } } func TestF64SDefault(t *testing.T) { var f64s []float64 f := setUpF64SFlagSetWithDefault(&f64s) vals := []string{"0.0", "1.0"} err := f.Parse([]string{}) if err != nil { t.Fatal("expected no error; got", err) } for i, v := range f64s { d, err := strconv.ParseFloat(vals[i], 64) if err != nil { t.Fatalf("got error: %v", err) } if d != v { t.Fatalf("expected f64s[%d] to be %f but got: %f", i, d, v) } } getF64S, err := f.GetFloat64Slice("f64s") if err != nil { t.Fatal("got an error from GetFloat64Slice():", err) } for i, v := range getF64S { d, err := strconv.ParseFloat(vals[i], 64) if err != nil { t.Fatal("got an error from GetFloat64Slice():", err) } if d != v { t.Fatalf("expected f64s[%d] to be %f from GetFloat64Slice but got: %f", i, d, v) } } } func TestF64SWithDefault(t *testing.T) { var f64s []float64 f := setUpF64SFlagSetWithDefault(&f64s) 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) } for i, v := range f64s { d, err := strconv.ParseFloat(vals[i], 64) if err != nil { t.Fatalf("got error: %v", err) } if d != v { t.Fatalf("expected f64s[%d] to be %f but got: %f", i, d, v) } } getF64S, err := f.GetFloat64Slice("f64s") if err != nil { t.Fatal("got an error from GetFloat64Slice():", err) } for i, v := range getF64S { d, err := strconv.ParseFloat(vals[i], 64) if err != nil { t.Fatalf("got error: %v", err) } if d != v { t.Fatalf("expected f64s[%d] to be %f from GetFloat64Slice but got: %f", i, d, v) } } } func TestF64SAsSliceValue(t *testing.T) { var f64s []float64 f := setUpF64SFlagSet(&f64s) in := []string{"1.0", "2.0"} argfmt := "--f64s=%s" arg1 := fmt.Sprintf(argfmt, in[0]) arg2 := fmt.Sprintf(argfmt, in[1]) err := f.Parse([]string{arg1, arg2}) if err != nil { t.Fatal("expected no error; got", err) } f.VisitAll(func(f *Flag) { if val, ok := f.Value.(SliceValue); ok { _ = val.Replace([]string{"3.1"}) } }) if len(f64s) != 1 || f64s[0] != 3.1 { t.Fatalf("Expected ss to be overwritten with '3.1', but got: %v", f64s) } } func TestF64SCalledTwice(t *testing.T) { var f64s []float64 f := setUpF64SFlagSet(&f64s) in := []string{"1.0,2.0", "3.0"} expected := []float64{1.0, 2.0, 3.0} argfmt := "--f64s=%s" arg1 := fmt.Sprintf(argfmt, in[0]) arg2 := fmt.Sprintf(argfmt, in[1]) err := f.Parse([]string{arg1, arg2}) 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) } } } spf13-pflag-0491e57/func.go000066400000000000000000000026261505550473500153160ustar00rootroot00000000000000package pflag // -- func Value type funcValue func(string) error func (f funcValue) Set(s string) error { return f(s) } func (f funcValue) Type() string { return "func" } func (f funcValue) String() string { return "" } // same behavior as stdlib 'flag' package // Func defines a func flag with specified name, callback function and usage string. // // The callback function will be called every time "--{name}={value}" (or equivalent) is // parsed on the command line, with "{value}" as an argument. func (f *FlagSet) Func(name string, usage string, fn func(string) error) { f.FuncP(name, "", usage, fn) } // FuncP is like Func, but accepts a shorthand letter that can be used after a single dash. func (f *FlagSet) FuncP(name string, shorthand string, usage string, fn func(string) error) { var val Value = funcValue(fn) f.VarP(val, name, shorthand, usage) } // Func defines a func flag with specified name, callback function and usage string. // // The callback function will be called every time "--{name}={value}" (or equivalent) is // parsed on the command line, with "{value}" as an argument. func Func(name string, usage string, fn func(string) error) { CommandLine.FuncP(name, "", usage, fn) } // FuncP is like Func, but accepts a shorthand letter that can be used after a single dash. func FuncP(name, shorthand string, usage string, fn func(string) error) { CommandLine.FuncP(name, shorthand, usage, fn) } spf13-pflag-0491e57/func_go1.21_test.go000066400000000000000000000063541505550473500173460ustar00rootroot00000000000000//go:build go1.21 // +build go1.21 package pflag import ( "errors" "flag" "io" "strings" "testing" ) func TestFuncCompat(t *testing.T) { // compare behavior with the stdlib 'flag' package type FuncFlagSet interface { Func(name string, usage string, fn func(string) error) Parse([]string) error } unitTestErr := errors.New("unit test error") runCase := func(f FuncFlagSet, name string, args []string) (values []string, err error) { fn := func(s string) error { values = append(values, s) if s == "err" { return unitTestErr } return nil } f.Func(name, "Callback function", fn) err = f.Parse(args) return values, err } t.Run("regular parsing", func(t *testing.T) { flagName := "fnflag" args := []string{"--fnflag=xx", "--fnflag", "yy", "--fnflag=zz"} stdFSet := flag.NewFlagSet("std test", flag.ContinueOnError) stdValues, err := runCase(stdFSet, flagName, args) if err != nil { t.Fatalf("std flag: expected no error, got %v", err) } expected := []string{"xx", "yy", "zz"} if !cmpLists(expected, stdValues) { t.Fatalf("std flag: expected %v, got %v", expected, stdValues) } fset := NewFlagSet("pflag test", ContinueOnError) pflagValues, err := runCase(fset, flagName, args) if err != nil { t.Fatalf("pflag: expected no error, got %v", err) } if !cmpLists(stdValues, pflagValues) { t.Fatalf("pflag: expected %v, got %v", stdValues, pflagValues) } }) t.Run("error triggered by callback", func(t *testing.T) { flagName := "fnflag" args := []string{"--fnflag", "before", "--fnflag", "err", "--fnflag", "after"} // test behavior of standard flag.Fset with an error triggered by the callback: // (note: as can be seen in 'runCase()', if the callback sees "err" as a value // for the flag, it will return an error) stdFSet := flag.NewFlagSet("std test", flag.ContinueOnError) stdFSet.SetOutput(io.Discard) // suppress output // run test case with standard flag.Fset stdValues, err := runCase(stdFSet, flagName, args) // double check the standard behavior: // - .Parse() should return an error, which contains the error message if err == nil { t.Fatalf("std flag: expected an error triggered by callback, got no error instead") } if !strings.HasSuffix(err.Error(), unitTestErr.Error()) { t.Fatalf("std flag: expected unittest error, got unexpected error value: %T %v", err, err) } // - the function should have been called twice, with the first two values, // the final "=after" should not be recorded expected := []string{"before", "err"} if !cmpLists(expected, stdValues) { t.Fatalf("std flag: expected %v, got %v", expected, stdValues) } // now run the test case on a pflag FlagSet: fset := NewFlagSet("pflag test", ContinueOnError) pflagValues, err := runCase(fset, flagName, args) // check that there is a similar error (note: pflag will _wrap_ the error, while the stdlib // currently keeps the original message but creates a flat errors.Error) if !errors.Is(err, unitTestErr) { t.Fatalf("pflag: got unexpected error value: %T %v", err, err) } // the callback should be called the same number of times, with the same values: if !cmpLists(stdValues, pflagValues) { t.Fatalf("pflag: expected %v, got %v", stdValues, pflagValues) } }) } spf13-pflag-0491e57/func_test.go000066400000000000000000000045451505550473500163570ustar00rootroot00000000000000package pflag import ( "strings" "testing" ) func cmpLists(a, b []string) bool { if len(a) != len(b) { return false } for i := range a { if a[i] != b[i] { return false } } return true } func TestFunc(t *testing.T) { var values []string fn := func(s string) error { values = append(values, s) return nil } fset := NewFlagSet("test", ContinueOnError) fset.Func("fnflag", "Callback function", fn) err := fset.Parse([]string{"--fnflag=aa", "--fnflag", "bb"}) if err != nil { t.Fatal("expected no error; got", err) } expected := []string{"aa", "bb"} if !cmpLists(expected, values) { t.Fatalf("expected %v, got %v", expected, values) } } func TestFuncP(t *testing.T) { var values []string fn := func(s string) error { values = append(values, s) return nil } fset := NewFlagSet("test", ContinueOnError) fset.FuncP("fnflag", "f", "Callback function", fn) err := fset.Parse([]string{"--fnflag=a", "--fnflag", "b", "-fc", "-f=d", "-f", "e"}) if err != nil { t.Fatal("expected no error; got", err) } expected := []string{"a", "b", "c", "d", "e"} if !cmpLists(expected, values) { t.Fatalf("expected %v, got %v", expected, values) } } func TestFuncUsage(t *testing.T) { t.Run("regular func flag", func(t *testing.T) { // regular func flag: // expect to see '--flag1 value' followed by the usageMessage, and no mention of a default value fset := NewFlagSet("unittest", ContinueOnError) fset.Func("flag1", "usage message", func(s string) error { return nil }) usage := fset.FlagUsagesWrapped(80) usage = strings.TrimSpace(usage) expected := "--flag1 value usage message" if usage != expected { t.Fatalf("unexpected generated usage message\n expected: %s\n got: %s", expected, usage) } }) t.Run("func flag with placeholder name", func(t *testing.T) { // func flag, with a placeholder name: // if usageMesage contains a placeholder, expect that name; still expect no mention of a default value fset := NewFlagSet("unittest", ContinueOnError) fset.Func("flag2", "usage message with `name` placeholder", func(s string) error { return nil }) usage := fset.FlagUsagesWrapped(80) usage = strings.TrimSpace(usage) expected := "--flag2 name usage message with name placeholder" if usage != expected { t.Fatalf("unexpected generated usage message\n expected: %s\n got: %s", expected, usage) } }) } spf13-pflag-0491e57/go.mod000066400000000000000000000000471505550473500151350ustar00rootroot00000000000000module github.com/spf13/pflag go 1.12 spf13-pflag-0491e57/go.sum000066400000000000000000000000001505550473500151470ustar00rootroot00000000000000spf13-pflag-0491e57/golangflag.go000066400000000000000000000111561505550473500164620ustar00rootroot00000000000000// Copyright 2009 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. package pflag import ( goflag "flag" "reflect" "strings" "time" ) // go test flags prefixes func isGotestFlag(flag string) bool { return strings.HasPrefix(flag, "-test.") } func isGotestShorthandFlag(flag string) bool { return strings.HasPrefix(flag, "test.") } // flagValueWrapper implements pflag.Value around a flag.Value. The main // difference here is the addition of the Type method that returns a string // name of the type. As this is generally unknown, we approximate that with // reflection. type flagValueWrapper struct { inner goflag.Value flagType string } // We are just copying the boolFlag interface out of goflag as that is what // they use to decide if a flag should get "true" when no arg is given. type goBoolFlag interface { goflag.Value IsBoolFlag() bool } func wrapFlagValue(v goflag.Value) Value { // If the flag.Value happens to also be a pflag.Value, just use it directly. if pv, ok := v.(Value); ok { return pv } pv := &flagValueWrapper{ inner: v, } t := reflect.TypeOf(v) if t.Kind() == reflect.Interface || t.Kind() == reflect.Ptr { t = t.Elem() } pv.flagType = strings.TrimSuffix(t.Name(), "Value") return pv } func (v *flagValueWrapper) String() string { return v.inner.String() } func (v *flagValueWrapper) Set(s string) error { return v.inner.Set(s) } func (v *flagValueWrapper) Type() string { return v.flagType } // PFlagFromGoFlag will return a *pflag.Flag given a *flag.Flag // 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 { // 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.Value.String(), } // Ex: if the golang flag was -v, allow both -v and --v to work if len(flag.Name) == 1 { flag.Shorthand = flag.Name } if fv, ok := goflag.Value.(goBoolFlag); ok && fv.IsBoolFlag() { flag.NoOptDefVal = "true" } return flag } // AddGoFlag will add the given *flag.Flag to the pflag.FlagSet func (f *FlagSet) AddGoFlag(goflag *goflag.Flag) { if f.Lookup(goflag.Name) != nil { return } newflag := PFlagFromGoFlag(goflag) f.AddFlag(newflag) } // AddGoFlagSet will add the given *flag.FlagSet to the pflag.FlagSet func (f *FlagSet) AddGoFlagSet(newSet *goflag.FlagSet) { if newSet == nil { return } newSet.VisitAll(func(goflag *goflag.Flag) { f.AddGoFlag(goflag) }) if f.addedGoFlagSets == nil { f.addedGoFlagSets = make([]*goflag.FlagSet, 0) } f.addedGoFlagSets = append(f.addedGoFlagSets, newSet) } // CopyToGoFlagSet will add all current flags to the given Go flag set. // Deprecation remarks get copied into the usage description. // Whenever possible, a flag gets added for which Go flags shows // a proper type in the help message. func (f *FlagSet) CopyToGoFlagSet(newSet *goflag.FlagSet) { f.VisitAll(func(flag *Flag) { usage := flag.Usage if flag.Deprecated != "" { usage += " (DEPRECATED: " + flag.Deprecated + ")" } switch value := flag.Value.(type) { case *stringValue: newSet.StringVar((*string)(value), flag.Name, flag.DefValue, usage) case *intValue: newSet.IntVar((*int)(value), flag.Name, *(*int)(value), usage) case *int64Value: newSet.Int64Var((*int64)(value), flag.Name, *(*int64)(value), usage) case *uintValue: newSet.UintVar((*uint)(value), flag.Name, *(*uint)(value), usage) case *uint64Value: newSet.Uint64Var((*uint64)(value), flag.Name, *(*uint64)(value), usage) case *durationValue: newSet.DurationVar((*time.Duration)(value), flag.Name, *(*time.Duration)(value), usage) case *float64Value: newSet.Float64Var((*float64)(value), flag.Name, *(*float64)(value), usage) default: newSet.Var(flag.Value, flag.Name, usage) } }) } // ParseSkippedFlags explicitly Parses go test flags (i.e. the one starting with '-test.') with goflag.Parse(), // since by default those are skipped by pflag.Parse(). // Typical usage example: `ParseGoTestFlags(os.Args[1:], goflag.CommandLine)` func ParseSkippedFlags(osArgs []string, goFlagSet *goflag.FlagSet) error { var skippedFlags []string for _, f := range osArgs { if isGotestFlag(f) { skippedFlags = append(skippedFlags, f) } } return goFlagSet.Parse(skippedFlags) } spf13-pflag-0491e57/golangflag_test.go000066400000000000000000000074331505550473500175240ustar00rootroot00000000000000// Copyright 2009 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. package pflag import ( goflag "flag" "testing" "time" ) func TestGoflags(t *testing.T) { goflag.String("stringFlag", "stringFlag", "stringFlag") goflag.Bool("boolFlag", false, "boolFlag") var testxxxValue string goflag.StringVar(&testxxxValue, "test.xxx", "test.xxx", "it is a test flag") f := NewFlagSet("test", ContinueOnError) f.AddGoFlagSet(goflag.CommandLine) args := []string{"--stringFlag=bob", "--boolFlag", "-test.xxx=testvalue"} err := f.Parse(args) if err != nil { t.Fatal("expected no error; get", err) } getString, err := f.GetString("stringFlag") if err != nil { t.Fatal("expected no error; get", err) } if getString != "bob" { t.Fatalf("expected getString=bob but got getString=%s", getString) } getBool, err := f.GetBool("boolFlag") if err != nil { t.Fatal("expected no error; get", err) } if getBool != true { t.Fatalf("expected getBool=true but got getBool=%v", getBool) } if !f.Parsed() { t.Fatal("f.Parsed() return false after f.Parse() called") } if testxxxValue != "test.xxx" { t.Fatalf("expected testxxxValue to be test.xxx but got %v", testxxxValue) } err = ParseSkippedFlags(args, goflag.CommandLine) if err != nil { t.Fatal("expected no error; ParseSkippedFlags", err) } if testxxxValue != "testvalue" { t.Fatalf("expected testxxxValue to be testvalue but got %v", testxxxValue) } // in fact it is useless. because `go test` called flag.Parse() if !goflag.CommandLine.Parsed() { t.Fatal("goflag.CommandLine.Parsed() return false after f.Parse() called") } } func TestToGoflags(t *testing.T) { pfs := FlagSet{} gfs := goflag.FlagSet{} pfs.String("StringFlag", "String value", "String flag usage") pfs.Int("IntFlag", 1, "Int flag usage") pfs.Uint("UintFlag", 2, "Uint flag usage") pfs.Int64("Int64Flag", 3, "Int64 flag usage") pfs.Uint64("Uint64Flag", 4, "Uint64 flag usage") pfs.Int8("Int8Flag", 5, "Int8 flag usage") pfs.Float64("Float64Flag", 6.0, "Float64 flag usage") pfs.Duration("DurationFlag", time.Second, "Duration flag usage") pfs.Bool("BoolFlag", true, "Bool flag usage") pfs.String("deprecated", "Deprecated value", "Deprecated flag usage") pfs.MarkDeprecated("deprecated", "obsolete") pfs.CopyToGoFlagSet(&gfs) // Modify via pfs. Should be visible via gfs because both share the // same values. for name, value := range map[string]string{ "StringFlag": "Modified String value", "IntFlag": "11", "UintFlag": "12", "Int64Flag": "13", "Uint64Flag": "14", "Int8Flag": "15", "Float64Flag": "16.0", "BoolFlag": "false", } { pf := pfs.Lookup(name) if pf == nil { t.Errorf("%s: not found in pflag flag set", name) continue } if err := pf.Value.Set(value); err != nil { t.Errorf("error setting %s = %s: %v", name, value, err) } } // Check that all flags were added and share the same value. pfs.VisitAll(func(pf *Flag) { gf := gfs.Lookup(pf.Name) if gf == nil { t.Errorf("%s: not found in Go flag set", pf.Name) return } if gf.Value.String() != pf.Value.String() { t.Errorf("%s: expected value %v from Go flag set, got %v", pf.Name, pf.Value, gf.Value) return } }) // Check for unexpected additional flags. gfs.VisitAll(func(gf *goflag.Flag) { pf := gfs.Lookup(gf.Name) if pf == nil { t.Errorf("%s: not found in pflag flag set", gf.Name) return } }) deprecated := gfs.Lookup("deprecated") if deprecated == nil { t.Error("deprecated: not found in Go flag set") } else { expectedUsage := "Deprecated flag usage (DEPRECATED: obsolete)" if deprecated.Usage != expectedUsage { t.Errorf("deprecation remark not added, expected usage %q, got %q", expectedUsage, deprecated.Usage) } } } spf13-pflag-0491e57/int.go000066400000000000000000000053341505550473500151540ustar00rootroot00000000000000package pflag import "strconv" // -- int Value type intValue int func newIntValue(val int, p *int) *intValue { *p = val return (*intValue)(p) } func (i *intValue) Set(s string) error { v, err := strconv.ParseInt(s, 0, 64) *i = intValue(v) return err } func (i *intValue) Type() string { return "int" } func (i *intValue) String() string { return strconv.Itoa(int(*i)) } func intConv(sval string) (interface{}, error) { return strconv.Atoi(sval) } // GetInt return the int value of a flag with the given name func (f *FlagSet) GetInt(name string) (int, error) { val, err := f.getFlagType(name, "int", intConv) if err != nil { return 0, err } return val.(int), nil } // IntVar defines an int flag with specified name, default value, and usage string. // The argument p points to an int variable in which to store the value of the flag. func (f *FlagSet) IntVar(p *int, name string, value int, usage string) { f.VarP(newIntValue(value, p), name, "", usage) } // IntVarP is like IntVar, but accepts a shorthand letter that can be used after a single dash. func (f *FlagSet) IntVarP(p *int, name, shorthand string, value int, usage string) { f.VarP(newIntValue(value, p), name, shorthand, usage) } // IntVar defines an int flag with specified name, default value, and usage string. // The argument p points to an int variable in which to store the value of the flag. func IntVar(p *int, name string, value int, usage string) { CommandLine.VarP(newIntValue(value, p), name, "", usage) } // IntVarP is like IntVar, but accepts a shorthand letter that can be used after a single dash. func IntVarP(p *int, name, shorthand string, value int, usage string) { CommandLine.VarP(newIntValue(value, p), name, shorthand, usage) } // Int defines an int flag with specified name, default value, and usage string. // The return value is the address of an int variable that stores the value of the flag. func (f *FlagSet) Int(name string, value int, usage string) *int { p := new(int) f.IntVarP(p, name, "", value, usage) return p } // IntP is like Int, but accepts a shorthand letter that can be used after a single dash. func (f *FlagSet) IntP(name, shorthand string, value int, usage string) *int { p := new(int) f.IntVarP(p, name, shorthand, value, usage) return p } // Int defines an int flag with specified name, default value, and usage string. // The return value is the address of an int variable that stores the value of the flag. func Int(name string, value int, usage string) *int { return CommandLine.IntP(name, "", value, usage) } // IntP is like Int, but accepts a shorthand letter that can be used after a single dash. func IntP(name, shorthand string, value int, usage string) *int { return CommandLine.IntP(name, shorthand, value, usage) } spf13-pflag-0491e57/int16.go000066400000000000000000000057061505550473500153260ustar00rootroot00000000000000package pflag import "strconv" // -- int16 Value type int16Value int16 func newInt16Value(val int16, p *int16) *int16Value { *p = val return (*int16Value)(p) } func (i *int16Value) Set(s string) error { v, err := strconv.ParseInt(s, 0, 16) *i = int16Value(v) return err } func (i *int16Value) Type() string { return "int16" } func (i *int16Value) String() string { return strconv.FormatInt(int64(*i), 10) } func int16Conv(sval string) (interface{}, error) { v, err := strconv.ParseInt(sval, 0, 16) if err != nil { return 0, err } return int16(v), nil } // GetInt16 returns the int16 value of a flag with the given name func (f *FlagSet) GetInt16(name string) (int16, error) { val, err := f.getFlagType(name, "int16", int16Conv) if err != nil { return 0, err } return val.(int16), nil } // Int16Var defines an int16 flag with specified name, default value, and usage string. // The argument p points to an int16 variable in which to store the value of the flag. func (f *FlagSet) Int16Var(p *int16, name string, value int16, usage string) { f.VarP(newInt16Value(value, p), name, "", usage) } // Int16VarP is like Int16Var, but accepts a shorthand letter that can be used after a single dash. func (f *FlagSet) Int16VarP(p *int16, name, shorthand string, value int16, usage string) { f.VarP(newInt16Value(value, p), name, shorthand, usage) } // Int16Var defines an int16 flag with specified name, default value, and usage string. // The argument p points to an int16 variable in which to store the value of the flag. func Int16Var(p *int16, name string, value int16, usage string) { CommandLine.VarP(newInt16Value(value, p), name, "", usage) } // Int16VarP is like Int16Var, but accepts a shorthand letter that can be used after a single dash. func Int16VarP(p *int16, name, shorthand string, value int16, usage string) { CommandLine.VarP(newInt16Value(value, p), name, shorthand, usage) } // Int16 defines an int16 flag with specified name, default value, and usage string. // The return value is the address of an int16 variable that stores the value of the flag. func (f *FlagSet) Int16(name string, value int16, usage string) *int16 { p := new(int16) f.Int16VarP(p, name, "", value, usage) return p } // Int16P is like Int16, but accepts a shorthand letter that can be used after a single dash. func (f *FlagSet) Int16P(name, shorthand string, value int16, usage string) *int16 { p := new(int16) f.Int16VarP(p, name, shorthand, value, usage) return p } // Int16 defines an int16 flag with specified name, default value, and usage string. // The return value is the address of an int16 variable that stores the value of the flag. func Int16(name string, value int16, usage string) *int16 { return CommandLine.Int16P(name, "", value, usage) } // Int16P is like Int16, but accepts a shorthand letter that can be used after a single dash. func Int16P(name, shorthand string, value int16, usage string) *int16 { return CommandLine.Int16P(name, shorthand, value, usage) } spf13-pflag-0491e57/int32.go000066400000000000000000000057051505550473500153230ustar00rootroot00000000000000package pflag import "strconv" // -- int32 Value type int32Value int32 func newInt32Value(val int32, p *int32) *int32Value { *p = val return (*int32Value)(p) } func (i *int32Value) Set(s string) error { v, err := strconv.ParseInt(s, 0, 32) *i = int32Value(v) return err } func (i *int32Value) Type() string { return "int32" } func (i *int32Value) String() string { return strconv.FormatInt(int64(*i), 10) } func int32Conv(sval string) (interface{}, error) { v, err := strconv.ParseInt(sval, 0, 32) if err != nil { return 0, err } return int32(v), nil } // GetInt32 return the int32 value of a flag with the given name func (f *FlagSet) GetInt32(name string) (int32, error) { val, err := f.getFlagType(name, "int32", int32Conv) if err != nil { return 0, err } return val.(int32), nil } // Int32Var defines an int32 flag with specified name, default value, and usage string. // The argument p points to an int32 variable in which to store the value of the flag. func (f *FlagSet) Int32Var(p *int32, name string, value int32, usage string) { f.VarP(newInt32Value(value, p), name, "", usage) } // Int32VarP is like Int32Var, but accepts a shorthand letter that can be used after a single dash. func (f *FlagSet) Int32VarP(p *int32, name, shorthand string, value int32, usage string) { f.VarP(newInt32Value(value, p), name, shorthand, usage) } // Int32Var defines an int32 flag with specified name, default value, and usage string. // The argument p points to an int32 variable in which to store the value of the flag. func Int32Var(p *int32, name string, value int32, usage string) { CommandLine.VarP(newInt32Value(value, p), name, "", usage) } // Int32VarP is like Int32Var, but accepts a shorthand letter that can be used after a single dash. func Int32VarP(p *int32, name, shorthand string, value int32, usage string) { CommandLine.VarP(newInt32Value(value, p), name, shorthand, usage) } // Int32 defines an int32 flag with specified name, default value, and usage string. // The return value is the address of an int32 variable that stores the value of the flag. func (f *FlagSet) Int32(name string, value int32, usage string) *int32 { p := new(int32) f.Int32VarP(p, name, "", value, usage) return p } // Int32P is like Int32, but accepts a shorthand letter that can be used after a single dash. func (f *FlagSet) Int32P(name, shorthand string, value int32, usage string) *int32 { p := new(int32) f.Int32VarP(p, name, shorthand, value, usage) return p } // Int32 defines an int32 flag with specified name, default value, and usage string. // The return value is the address of an int32 variable that stores the value of the flag. func Int32(name string, value int32, usage string) *int32 { return CommandLine.Int32P(name, "", value, usage) } // Int32P is like Int32, but accepts a shorthand letter that can be used after a single dash. func Int32P(name, shorthand string, value int32, usage string) *int32 { return CommandLine.Int32P(name, shorthand, value, usage) } spf13-pflag-0491e57/int32_slice.go000066400000000000000000000113771505550473500165040ustar00rootroot00000000000000package pflag import ( "fmt" "strconv" "strings" ) // -- int32Slice Value type int32SliceValue struct { value *[]int32 changed bool } func newInt32SliceValue(val []int32, p *[]int32) *int32SliceValue { isv := new(int32SliceValue) isv.value = p *isv.value = val return isv } func (s *int32SliceValue) Set(val string) error { ss := strings.Split(val, ",") out := make([]int32, len(ss)) for i, d := range ss { var err error var temp64 int64 temp64, err = strconv.ParseInt(d, 0, 32) if err != nil { return err } out[i] = int32(temp64) } if !s.changed { *s.value = out } else { *s.value = append(*s.value, out...) } s.changed = true return nil } func (s *int32SliceValue) Type() string { return "int32Slice" } func (s *int32SliceValue) String() string { out := make([]string, len(*s.value)) for i, d := range *s.value { out[i] = fmt.Sprintf("%d", d) } return "[" + strings.Join(out, ",") + "]" } func (s *int32SliceValue) fromString(val string) (int32, error) { t64, err := strconv.ParseInt(val, 0, 32) if err != nil { return 0, err } return int32(t64), nil } func (s *int32SliceValue) toString(val int32) string { return fmt.Sprintf("%d", val) } func (s *int32SliceValue) Append(val string) error { i, err := s.fromString(val) if err != nil { return err } *s.value = append(*s.value, i) return nil } func (s *int32SliceValue) Replace(val []string) error { out := make([]int32, len(val)) for i, d := range val { var err error out[i], err = s.fromString(d) if err != nil { return err } } *s.value = out return nil } func (s *int32SliceValue) GetSlice() []string { out := make([]string, len(*s.value)) for i, d := range *s.value { out[i] = s.toString(d) } return out } func int32SliceConv(val string) (interface{}, error) { val = strings.Trim(val, "[]") // Empty string would cause a slice with one (empty) entry if len(val) == 0 { return []int32{}, nil } ss := strings.Split(val, ",") out := make([]int32, len(ss)) for i, d := range ss { var err error var temp64 int64 temp64, err = strconv.ParseInt(d, 0, 32) if err != nil { return nil, err } out[i] = int32(temp64) } return out, nil } // GetInt32Slice return the []int32 value of a flag with the given name func (f *FlagSet) GetInt32Slice(name string) ([]int32, error) { val, err := f.getFlagType(name, "int32Slice", int32SliceConv) if err != nil { return []int32{}, err } return val.([]int32), nil } // Int32SliceVar defines a int32Slice flag with specified name, default value, and usage string. // The argument p points to a []int32 variable in which to store the value of the flag. func (f *FlagSet) Int32SliceVar(p *[]int32, name string, value []int32, usage string) { f.VarP(newInt32SliceValue(value, p), name, "", usage) } // Int32SliceVarP is like Int32SliceVar, but accepts a shorthand letter that can be used after a single dash. func (f *FlagSet) Int32SliceVarP(p *[]int32, name, shorthand string, value []int32, usage string) { f.VarP(newInt32SliceValue(value, p), name, shorthand, usage) } // Int32SliceVar defines a int32[] flag with specified name, default value, and usage string. // The argument p points to a int32[] variable in which to store the value of the flag. func Int32SliceVar(p *[]int32, name string, value []int32, usage string) { CommandLine.VarP(newInt32SliceValue(value, p), name, "", usage) } // Int32SliceVarP is like Int32SliceVar, but accepts a shorthand letter that can be used after a single dash. func Int32SliceVarP(p *[]int32, name, shorthand string, value []int32, usage string) { CommandLine.VarP(newInt32SliceValue(value, p), name, shorthand, usage) } // Int32Slice defines a []int32 flag with specified name, default value, and usage string. // The return value is the address of a []int32 variable that stores the value of the flag. func (f *FlagSet) Int32Slice(name string, value []int32, usage string) *[]int32 { p := []int32{} f.Int32SliceVarP(&p, name, "", value, usage) return &p } // Int32SliceP is like Int32Slice, but accepts a shorthand letter that can be used after a single dash. func (f *FlagSet) Int32SliceP(name, shorthand string, value []int32, usage string) *[]int32 { p := []int32{} f.Int32SliceVarP(&p, name, shorthand, value, usage) return &p } // Int32Slice defines a []int32 flag with specified name, default value, and usage string. // The return value is the address of a []int32 variable that stores the value of the flag. func Int32Slice(name string, value []int32, usage string) *[]int32 { return CommandLine.Int32SliceP(name, "", value, usage) } // Int32SliceP is like Int32Slice, but accepts a shorthand letter that can be used after a single dash. func Int32SliceP(name, shorthand string, value []int32, usage string) *[]int32 { return CommandLine.Int32SliceP(name, shorthand, value, usage) } spf13-pflag-0491e57/int32_slice_test.go000066400000000000000000000106401505550473500175330ustar00rootroot00000000000000// Copyright 2009 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. package pflag import ( "fmt" "strconv" "strings" "testing" ) func setUpI32SFlagSet(isp *[]int32) *FlagSet { f := NewFlagSet("test", ContinueOnError) f.Int32SliceVar(isp, "is", []int32{}, "Command separated list!") return f } func setUpI32SFlagSetWithDefault(isp *[]int32) *FlagSet { f := NewFlagSet("test", ContinueOnError) f.Int32SliceVar(isp, "is", []int32{0, 1}, "Command separated list!") return f } func TestEmptyI32S(t *testing.T) { var is []int32 f := setUpI32SFlagSet(&is) err := f.Parse([]string{}) if err != nil { t.Fatal("expected no error; got", err) } getI32S, err := f.GetInt32Slice("is") if err != nil { t.Fatal("got an error from GetInt32Slice():", err) } if len(getI32S) != 0 { t.Fatalf("got is %v with len=%d but expected length=0", getI32S, len(getI32S)) } } func TestI32S(t *testing.T) { var is []int32 f := setUpI32SFlagSet(&is) 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) } for i, v := range is { d64, err := strconv.ParseInt(vals[i], 0, 32) if err != nil { t.Fatalf("got error: %v", err) } d := int32(d64) if d != v { 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) } for i, v := range getI32S { d64, err := strconv.ParseInt(vals[i], 0, 32) if err != nil { t.Fatalf("got error: %v", err) } d := int32(d64) if d != v { t.Fatalf("expected is[%d] to be %s but got: %d from GetInt32Slice", i, vals[i], v) } } } func TestI32SDefault(t *testing.T) { var is []int32 f := setUpI32SFlagSetWithDefault(&is) vals := []string{"0", "1"} err := f.Parse([]string{}) if err != nil { t.Fatal("expected no error; got", err) } for i, v := range is { d64, err := strconv.ParseInt(vals[i], 0, 32) if err != nil { t.Fatalf("got error: %v", err) } d := int32(d64) if d != v { t.Fatalf("expected is[%d] to be %d but got: %d", i, d, v) } } getI32S, err := f.GetInt32Slice("is") if err != nil { t.Fatal("got an error from GetInt32Slice():", err) } for i, v := range getI32S { d64, err := strconv.ParseInt(vals[i], 0, 32) if err != nil { t.Fatal("got an error from GetInt32Slice():", err) } d := int32(d64) if d != v { t.Fatalf("expected is[%d] to be %d from GetInt32Slice but got: %d", i, d, v) } } } func TestI32SWithDefault(t *testing.T) { var is []int32 f := setUpI32SFlagSetWithDefault(&is) 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) } for i, v := range is { d64, err := strconv.ParseInt(vals[i], 0, 32) if err != nil { t.Fatalf("got error: %v", err) } d := int32(d64) if d != v { t.Fatalf("expected is[%d] to be %d but got: %d", i, d, v) } } getI32S, err := f.GetInt32Slice("is") if err != nil { t.Fatal("got an error from GetInt32Slice():", err) } for i, v := range getI32S { d64, err := strconv.ParseInt(vals[i], 0, 32) if err != nil { t.Fatalf("got error: %v", err) } d := int32(d64) if d != v { t.Fatalf("expected is[%d] to be %d from GetInt32Slice but got: %d", i, d, v) } } } func TestI32SAsSliceValue(t *testing.T) { var i32s []int32 f := setUpI32SFlagSet(&i32s) in := []string{"1", "2"} argfmt := "--is=%s" arg1 := fmt.Sprintf(argfmt, in[0]) arg2 := fmt.Sprintf(argfmt, in[1]) err := f.Parse([]string{arg1, arg2}) if err != nil { t.Fatal("expected no error; got", err) } f.VisitAll(func(f *Flag) { if val, ok := f.Value.(SliceValue); ok { _ = val.Replace([]string{"3"}) } }) if len(i32s) != 1 || i32s[0] != 3 { t.Fatalf("Expected ss to be overwritten with '3.1', but got: %v", i32s) } } func TestI32SCalledTwice(t *testing.T) { var is []int32 f := setUpI32SFlagSet(&is) in := []string{"1,2", "3"} expected := []int32{1, 2, 3} argfmt := "--is=%s" arg1 := fmt.Sprintf(argfmt, in[0]) arg2 := fmt.Sprintf(argfmt, in[1]) err := f.Parse([]string{arg1, arg2}) 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) } } } spf13-pflag-0491e57/int64.go000066400000000000000000000056101505550473500153230ustar00rootroot00000000000000package pflag import "strconv" // -- int64 Value type int64Value int64 func newInt64Value(val int64, p *int64) *int64Value { *p = val return (*int64Value)(p) } func (i *int64Value) Set(s string) error { v, err := strconv.ParseInt(s, 0, 64) *i = int64Value(v) return err } func (i *int64Value) Type() string { return "int64" } func (i *int64Value) String() string { return strconv.FormatInt(int64(*i), 10) } func int64Conv(sval string) (interface{}, error) { return strconv.ParseInt(sval, 0, 64) } // GetInt64 return the int64 value of a flag with the given name func (f *FlagSet) GetInt64(name string) (int64, error) { val, err := f.getFlagType(name, "int64", int64Conv) if err != nil { return 0, err } return val.(int64), nil } // Int64Var defines an int64 flag with specified name, default value, and usage string. // The argument p points to an int64 variable in which to store the value of the flag. func (f *FlagSet) Int64Var(p *int64, name string, value int64, usage string) { f.VarP(newInt64Value(value, p), name, "", usage) } // Int64VarP is like Int64Var, but accepts a shorthand letter that can be used after a single dash. func (f *FlagSet) Int64VarP(p *int64, name, shorthand string, value int64, usage string) { f.VarP(newInt64Value(value, p), name, shorthand, usage) } // Int64Var defines an int64 flag with specified name, default value, and usage string. // The argument p points to an int64 variable in which to store the value of the flag. func Int64Var(p *int64, name string, value int64, usage string) { CommandLine.VarP(newInt64Value(value, p), name, "", usage) } // Int64VarP is like Int64Var, but accepts a shorthand letter that can be used after a single dash. func Int64VarP(p *int64, name, shorthand string, value int64, usage string) { CommandLine.VarP(newInt64Value(value, p), name, shorthand, usage) } // Int64 defines an int64 flag with specified name, default value, and usage string. // The return value is the address of an int64 variable that stores the value of the flag. func (f *FlagSet) Int64(name string, value int64, usage string) *int64 { p := new(int64) f.Int64VarP(p, name, "", value, usage) return p } // Int64P is like Int64, but accepts a shorthand letter that can be used after a single dash. func (f *FlagSet) Int64P(name, shorthand string, value int64, usage string) *int64 { p := new(int64) f.Int64VarP(p, name, shorthand, value, usage) return p } // Int64 defines an int64 flag with specified name, default value, and usage string. // The return value is the address of an int64 variable that stores the value of the flag. func Int64(name string, value int64, usage string) *int64 { return CommandLine.Int64P(name, "", value, usage) } // Int64P is like Int64, but accepts a shorthand letter that can be used after a single dash. func Int64P(name, shorthand string, value int64, usage string) *int64 { return CommandLine.Int64P(name, shorthand, value, usage) } spf13-pflag-0491e57/int64_slice.go000066400000000000000000000111461505550473500165030ustar00rootroot00000000000000package pflag import ( "fmt" "strconv" "strings" ) // -- int64Slice Value type int64SliceValue struct { value *[]int64 changed bool } func newInt64SliceValue(val []int64, p *[]int64) *int64SliceValue { isv := new(int64SliceValue) isv.value = p *isv.value = val return isv } func (s *int64SliceValue) Set(val string) error { ss := strings.Split(val, ",") out := make([]int64, len(ss)) for i, d := range ss { var err error out[i], err = strconv.ParseInt(d, 0, 64) if err != nil { return err } } if !s.changed { *s.value = out } else { *s.value = append(*s.value, out...) } s.changed = true return nil } func (s *int64SliceValue) Type() string { return "int64Slice" } func (s *int64SliceValue) String() string { out := make([]string, len(*s.value)) for i, d := range *s.value { out[i] = fmt.Sprintf("%d", d) } return "[" + strings.Join(out, ",") + "]" } func (s *int64SliceValue) fromString(val string) (int64, error) { return strconv.ParseInt(val, 0, 64) } func (s *int64SliceValue) toString(val int64) string { return fmt.Sprintf("%d", val) } func (s *int64SliceValue) Append(val string) error { i, err := s.fromString(val) if err != nil { return err } *s.value = append(*s.value, i) return nil } func (s *int64SliceValue) Replace(val []string) error { out := make([]int64, len(val)) for i, d := range val { var err error out[i], err = s.fromString(d) if err != nil { return err } } *s.value = out return nil } func (s *int64SliceValue) GetSlice() []string { out := make([]string, len(*s.value)) for i, d := range *s.value { out[i] = s.toString(d) } return out } func int64SliceConv(val string) (interface{}, error) { val = strings.Trim(val, "[]") // Empty string would cause a slice with one (empty) entry if len(val) == 0 { return []int64{}, nil } ss := strings.Split(val, ",") out := make([]int64, len(ss)) for i, d := range ss { var err error out[i], err = strconv.ParseInt(d, 0, 64) if err != nil { return nil, err } } return out, nil } // GetInt64Slice return the []int64 value of a flag with the given name func (f *FlagSet) GetInt64Slice(name string) ([]int64, error) { val, err := f.getFlagType(name, "int64Slice", int64SliceConv) if err != nil { return []int64{}, err } return val.([]int64), nil } // Int64SliceVar defines a int64Slice flag with specified name, default value, and usage string. // The argument p points to a []int64 variable in which to store the value of the flag. func (f *FlagSet) Int64SliceVar(p *[]int64, name string, value []int64, usage string) { f.VarP(newInt64SliceValue(value, p), name, "", usage) } // Int64SliceVarP is like Int64SliceVar, but accepts a shorthand letter that can be used after a single dash. func (f *FlagSet) Int64SliceVarP(p *[]int64, name, shorthand string, value []int64, usage string) { f.VarP(newInt64SliceValue(value, p), name, shorthand, usage) } // Int64SliceVar defines a int64[] flag with specified name, default value, and usage string. // The argument p points to a int64[] variable in which to store the value of the flag. func Int64SliceVar(p *[]int64, name string, value []int64, usage string) { CommandLine.VarP(newInt64SliceValue(value, p), name, "", usage) } // Int64SliceVarP is like Int64SliceVar, but accepts a shorthand letter that can be used after a single dash. func Int64SliceVarP(p *[]int64, name, shorthand string, value []int64, usage string) { CommandLine.VarP(newInt64SliceValue(value, p), name, shorthand, usage) } // Int64Slice defines a []int64 flag with specified name, default value, and usage string. // The return value is the address of a []int64 variable that stores the value of the flag. func (f *FlagSet) Int64Slice(name string, value []int64, usage string) *[]int64 { p := []int64{} f.Int64SliceVarP(&p, name, "", value, usage) return &p } // Int64SliceP is like Int64Slice, but accepts a shorthand letter that can be used after a single dash. func (f *FlagSet) Int64SliceP(name, shorthand string, value []int64, usage string) *[]int64 { p := []int64{} f.Int64SliceVarP(&p, name, shorthand, value, usage) return &p } // Int64Slice defines a []int64 flag with specified name, default value, and usage string. // The return value is the address of a []int64 variable that stores the value of the flag. func Int64Slice(name string, value []int64, usage string) *[]int64 { return CommandLine.Int64SliceP(name, "", value, usage) } // Int64SliceP is like Int64Slice, but accepts a shorthand letter that can be used after a single dash. func Int64SliceP(name, shorthand string, value []int64, usage string) *[]int64 { return CommandLine.Int64SliceP(name, shorthand, value, usage) } spf13-pflag-0491e57/int64_slice_test.go000066400000000000000000000104501505550473500175370ustar00rootroot00000000000000// Copyright 2009 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. package pflag import ( "fmt" "strconv" "strings" "testing" ) func setUpI64SFlagSet(isp *[]int64) *FlagSet { f := NewFlagSet("test", ContinueOnError) f.Int64SliceVar(isp, "is", []int64{}, "Command separated list!") return f } func setUpI64SFlagSetWithDefault(isp *[]int64) *FlagSet { f := NewFlagSet("test", ContinueOnError) f.Int64SliceVar(isp, "is", []int64{0, 1}, "Command separated list!") return f } func TestEmptyI64S(t *testing.T) { var is []int64 f := setUpI64SFlagSet(&is) err := f.Parse([]string{}) if err != nil { t.Fatal("expected no error; got", err) } getI64S, err := f.GetInt64Slice("is") if err != nil { t.Fatal("got an error from GetInt64Slice():", err) } if len(getI64S) != 0 { t.Fatalf("got is %v with len=%d but expected length=0", getI64S, len(getI64S)) } } func TestI64S(t *testing.T) { var is []int64 f := setUpI64SFlagSet(&is) 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) } for i, v := range is { d, err := strconv.ParseInt(vals[i], 0, 64) if err != nil { t.Fatalf("got error: %v", err) } if d != v { 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) } for i, v := range getI64S { d, err := strconv.ParseInt(vals[i], 0, 64) if err != nil { t.Fatalf("got error: %v", err) } if d != v { t.Fatalf("expected is[%d] to be %s but got: %d from GetInt64Slice", i, vals[i], v) } } } func TestI64SDefault(t *testing.T) { var is []int64 f := setUpI64SFlagSetWithDefault(&is) vals := []string{"0", "1"} err := f.Parse([]string{}) if err != nil { t.Fatal("expected no error; got", err) } for i, v := range is { d, err := strconv.ParseInt(vals[i], 0, 64) if err != nil { t.Fatalf("got error: %v", err) } if d != v { t.Fatalf("expected is[%d] to be %d but got: %d", i, d, v) } } getI64S, err := f.GetInt64Slice("is") if err != nil { t.Fatal("got an error from GetInt64Slice():", err) } for i, v := range getI64S { d, err := strconv.ParseInt(vals[i], 0, 64) if err != nil { t.Fatal("got an error from GetInt64Slice():", err) } if d != v { t.Fatalf("expected is[%d] to be %d from GetInt64Slice but got: %d", i, d, v) } } } func TestI64SWithDefault(t *testing.T) { var is []int64 f := setUpI64SFlagSetWithDefault(&is) 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) } for i, v := range is { d, err := strconv.ParseInt(vals[i], 0, 64) if err != nil { t.Fatalf("got error: %v", err) } if d != v { t.Fatalf("expected is[%d] to be %d but got: %d", i, d, v) } } getI64S, err := f.GetInt64Slice("is") if err != nil { t.Fatal("got an error from GetInt64Slice():", err) } for i, v := range getI64S { d, err := strconv.ParseInt(vals[i], 0, 64) if err != nil { t.Fatalf("got error: %v", err) } if d != v { t.Fatalf("expected is[%d] to be %d from GetInt64Slice but got: %d", i, d, v) } } } func TestI64SAsSliceValue(t *testing.T) { var i64s []int64 f := setUpI64SFlagSet(&i64s) in := []string{"1", "2"} argfmt := "--is=%s" arg1 := fmt.Sprintf(argfmt, in[0]) arg2 := fmt.Sprintf(argfmt, in[1]) err := f.Parse([]string{arg1, arg2}) if err != nil { t.Fatal("expected no error; got", err) } f.VisitAll(func(f *Flag) { if val, ok := f.Value.(SliceValue); ok { _ = val.Replace([]string{"3"}) } }) if len(i64s) != 1 || i64s[0] != 3 { t.Fatalf("Expected ss to be overwritten with '3.1', but got: %v", i64s) } } func TestI64SCalledTwice(t *testing.T) { var is []int64 f := setUpI64SFlagSet(&is) in := []string{"1,2", "3"} expected := []int64{1, 2, 3} argfmt := "--is=%s" arg1 := fmt.Sprintf(argfmt, in[0]) arg2 := fmt.Sprintf(argfmt, in[1]) err := f.Parse([]string{arg1, arg2}) 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) } } } spf13-pflag-0491e57/int8.go000066400000000000000000000055671505550473500152540ustar00rootroot00000000000000package pflag import "strconv" // -- int8 Value type int8Value int8 func newInt8Value(val int8, p *int8) *int8Value { *p = val return (*int8Value)(p) } func (i *int8Value) Set(s string) error { v, err := strconv.ParseInt(s, 0, 8) *i = int8Value(v) return err } func (i *int8Value) Type() string { return "int8" } func (i *int8Value) String() string { return strconv.FormatInt(int64(*i), 10) } func int8Conv(sval string) (interface{}, error) { v, err := strconv.ParseInt(sval, 0, 8) if err != nil { return 0, err } return int8(v), nil } // GetInt8 return the int8 value of a flag with the given name func (f *FlagSet) GetInt8(name string) (int8, error) { val, err := f.getFlagType(name, "int8", int8Conv) if err != nil { return 0, err } return val.(int8), nil } // Int8Var defines an int8 flag with specified name, default value, and usage string. // The argument p points to an int8 variable in which to store the value of the flag. func (f *FlagSet) Int8Var(p *int8, name string, value int8, usage string) { f.VarP(newInt8Value(value, p), name, "", usage) } // Int8VarP is like Int8Var, but accepts a shorthand letter that can be used after a single dash. func (f *FlagSet) Int8VarP(p *int8, name, shorthand string, value int8, usage string) { f.VarP(newInt8Value(value, p), name, shorthand, usage) } // Int8Var defines an int8 flag with specified name, default value, and usage string. // The argument p points to an int8 variable in which to store the value of the flag. func Int8Var(p *int8, name string, value int8, usage string) { CommandLine.VarP(newInt8Value(value, p), name, "", usage) } // Int8VarP is like Int8Var, but accepts a shorthand letter that can be used after a single dash. func Int8VarP(p *int8, name, shorthand string, value int8, usage string) { CommandLine.VarP(newInt8Value(value, p), name, shorthand, usage) } // Int8 defines an int8 flag with specified name, default value, and usage string. // The return value is the address of an int8 variable that stores the value of the flag. func (f *FlagSet) Int8(name string, value int8, usage string) *int8 { p := new(int8) f.Int8VarP(p, name, "", value, usage) return p } // Int8P is like Int8, but accepts a shorthand letter that can be used after a single dash. func (f *FlagSet) Int8P(name, shorthand string, value int8, usage string) *int8 { p := new(int8) f.Int8VarP(p, name, shorthand, value, usage) return p } // Int8 defines an int8 flag with specified name, default value, and usage string. // The return value is the address of an int8 variable that stores the value of the flag. func Int8(name string, value int8, usage string) *int8 { return CommandLine.Int8P(name, "", value, usage) } // Int8P is like Int8, but accepts a shorthand letter that can be used after a single dash. func Int8P(name, shorthand string, value int8, usage string) *int8 { return CommandLine.Int8P(name, shorthand, value, usage) } spf13-pflag-0491e57/int_slice.go000066400000000000000000000103531505550473500163300ustar00rootroot00000000000000package pflag import ( "fmt" "strconv" "strings" ) // -- intSlice Value type intSliceValue struct { value *[]int changed bool } func newIntSliceValue(val []int, p *[]int) *intSliceValue { isv := new(intSliceValue) isv.value = p *isv.value = val return isv } func (s *intSliceValue) Set(val string) error { ss := strings.Split(val, ",") out := make([]int, len(ss)) for i, d := range ss { var err error out[i], err = strconv.Atoi(d) if err != nil { return err } } if !s.changed { *s.value = out } else { *s.value = append(*s.value, out...) } s.changed = true return nil } func (s *intSliceValue) Type() string { return "intSlice" } func (s *intSliceValue) String() string { out := make([]string, len(*s.value)) for i, d := range *s.value { out[i] = fmt.Sprintf("%d", d) } return "[" + strings.Join(out, ",") + "]" } func (s *intSliceValue) Append(val string) error { i, err := strconv.Atoi(val) if err != nil { return err } *s.value = append(*s.value, i) return nil } func (s *intSliceValue) Replace(val []string) error { out := make([]int, len(val)) for i, d := range val { var err error out[i], err = strconv.Atoi(d) if err != nil { return err } } *s.value = out return nil } func (s *intSliceValue) GetSlice() []string { out := make([]string, len(*s.value)) for i, d := range *s.value { out[i] = strconv.Itoa(d) } return out } func intSliceConv(val string) (interface{}, error) { val = strings.Trim(val, "[]") // Empty string would cause a slice with one (empty) entry if len(val) == 0 { return []int{}, nil } ss := strings.Split(val, ",") out := make([]int, len(ss)) for i, d := range ss { var err error out[i], err = strconv.Atoi(d) if err != nil { return nil, err } } return out, nil } // GetIntSlice return the []int value of a flag with the given name func (f *FlagSet) GetIntSlice(name string) ([]int, error) { val, err := f.getFlagType(name, "intSlice", intSliceConv) if err != nil { return []int{}, err } return val.([]int), nil } // IntSliceVar defines a intSlice flag with specified name, default value, and usage string. // The argument p points to a []int variable in which to store the value of the flag. func (f *FlagSet) IntSliceVar(p *[]int, name string, value []int, usage string) { f.VarP(newIntSliceValue(value, p), name, "", usage) } // IntSliceVarP is like IntSliceVar, but accepts a shorthand letter that can be used after a single dash. func (f *FlagSet) IntSliceVarP(p *[]int, name, shorthand string, value []int, usage string) { f.VarP(newIntSliceValue(value, p), name, shorthand, usage) } // IntSliceVar defines a int[] flag with specified name, default value, and usage string. // The argument p points to a int[] variable in which to store the value of the flag. func IntSliceVar(p *[]int, name string, value []int, usage string) { CommandLine.VarP(newIntSliceValue(value, p), name, "", usage) } // IntSliceVarP is like IntSliceVar, but accepts a shorthand letter that can be used after a single dash. func IntSliceVarP(p *[]int, name, shorthand string, value []int, usage string) { CommandLine.VarP(newIntSliceValue(value, p), name, shorthand, usage) } // IntSlice defines a []int flag with specified name, default value, and usage string. // The return value is the address of a []int variable that stores the value of the flag. func (f *FlagSet) IntSlice(name string, value []int, usage string) *[]int { p := []int{} f.IntSliceVarP(&p, name, "", value, usage) return &p } // IntSliceP is like IntSlice, but accepts a shorthand letter that can be used after a single dash. func (f *FlagSet) IntSliceP(name, shorthand string, value []int, usage string) *[]int { p := []int{} f.IntSliceVarP(&p, name, shorthand, value, usage) return &p } // IntSlice defines a []int flag with specified name, default value, and usage string. // The return value is the address of a []int variable that stores the value of the flag. func IntSlice(name string, value []int, usage string) *[]int { return CommandLine.IntSliceP(name, "", value, usage) } // IntSliceP is like IntSlice, but accepts a shorthand letter that can be used after a single dash. func IntSliceP(name, shorthand string, value []int, usage string) *[]int { return CommandLine.IntSliceP(name, shorthand, value, usage) } spf13-pflag-0491e57/int_slice_test.go000066400000000000000000000071601505550473500173710ustar00rootroot00000000000000// Copyright 2009 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. package pflag import ( "fmt" "strconv" "strings" "testing" ) func setUpISFlagSet(isp *[]int) *FlagSet { f := NewFlagSet("test", ContinueOnError) f.IntSliceVar(isp, "is", []int{}, "Command separated list!") return f } func setUpISFlagSetWithDefault(isp *[]int) *FlagSet { f := NewFlagSet("test", ContinueOnError) f.IntSliceVar(isp, "is", []int{0, 1}, "Command separated list!") return f } func TestEmptyIS(t *testing.T) { var is []int f := setUpISFlagSet(&is) err := f.Parse([]string{}) if err != nil { t.Fatal("expected no error; got", err) } getIS, err := f.GetIntSlice("is") if err != nil { t.Fatal("got an error from GetIntSlice():", err) } if len(getIS) != 0 { t.Fatalf("got is %v with len=%d but expected length=0", getIS, len(getIS)) } } func TestIS(t *testing.T) { var is []int f := setUpISFlagSet(&is) 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) } for i, v := range is { d, err := strconv.Atoi(vals[i]) if err != nil { t.Fatalf("got error: %v", err) } if d != v { 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) } for i, v := range getIS { d, err := strconv.Atoi(vals[i]) if err != nil { t.Fatalf("got error: %v", err) } if d != v { t.Fatalf("expected is[%d] to be %s but got: %d from GetIntSlice", i, vals[i], v) } } } func TestISDefault(t *testing.T) { var is []int f := setUpISFlagSetWithDefault(&is) vals := []string{"0", "1"} err := f.Parse([]string{}) if err != nil { t.Fatal("expected no error; got", err) } for i, v := range is { d, err := strconv.Atoi(vals[i]) if err != nil { t.Fatalf("got error: %v", err) } if d != v { t.Fatalf("expected is[%d] to be %d but got: %d", i, d, v) } } getIS, err := f.GetIntSlice("is") if err != nil { t.Fatal("got an error from GetIntSlice():", err) } for i, v := range getIS { d, err := strconv.Atoi(vals[i]) if err != nil { t.Fatal("got an error from GetIntSlice():", err) } if d != v { t.Fatalf("expected is[%d] to be %d from GetIntSlice but got: %d", i, d, v) } } } func TestISWithDefault(t *testing.T) { var is []int f := setUpISFlagSetWithDefault(&is) 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) } for i, v := range is { d, err := strconv.Atoi(vals[i]) if err != nil { t.Fatalf("got error: %v", err) } if d != v { t.Fatalf("expected is[%d] to be %d but got: %d", i, d, v) } } getIS, err := f.GetIntSlice("is") if err != nil { t.Fatal("got an error from GetIntSlice():", err) } for i, v := range getIS { d, err := strconv.Atoi(vals[i]) if err != nil { t.Fatalf("got error: %v", err) } if d != v { t.Fatalf("expected is[%d] to be %d from GetIntSlice but got: %d", i, d, v) } } } func TestISCalledTwice(t *testing.T) { var is []int f := setUpISFlagSet(&is) in := []string{"1,2", "3"} expected := []int{1, 2, 3} argfmt := "--is=%s" arg1 := fmt.Sprintf(argfmt, in[0]) arg2 := fmt.Sprintf(argfmt, in[1]) err := f.Parse([]string{arg1, arg2}) 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) } } } spf13-pflag-0491e57/ip.go000066400000000000000000000060011505550473500147620ustar00rootroot00000000000000package pflag import ( "fmt" "net" "strings" ) // -- net.IP value type ipValue net.IP func newIPValue(val net.IP, p *net.IP) *ipValue { *p = val return (*ipValue)(p) } func (i *ipValue) String() string { return net.IP(*i).String() } func (i *ipValue) Set(s string) error { if s == "" { return nil } ip := net.ParseIP(strings.TrimSpace(s)) if ip == nil { return fmt.Errorf("failed to parse IP: %q", s) } *i = ipValue(ip) return nil } func (i *ipValue) Type() string { return "ip" } func ipConv(sval string) (interface{}, error) { ip := net.ParseIP(sval) if ip != nil { return ip, nil } return nil, fmt.Errorf("invalid string being converted to IP address: %s", sval) } // GetIP return the net.IP value of a flag with the given name func (f *FlagSet) GetIP(name string) (net.IP, error) { val, err := f.getFlagType(name, "ip", ipConv) if err != nil { return nil, err } return val.(net.IP), nil } // IPVar defines an net.IP flag with specified name, default value, and usage string. // The argument p points to an net.IP variable in which to store the value of the flag. func (f *FlagSet) IPVar(p *net.IP, name string, value net.IP, usage string) { f.VarP(newIPValue(value, p), name, "", usage) } // IPVarP is like IPVar, but accepts a shorthand letter that can be used after a single dash. func (f *FlagSet) IPVarP(p *net.IP, name, shorthand string, value net.IP, usage string) { f.VarP(newIPValue(value, p), name, shorthand, usage) } // IPVar defines an net.IP flag with specified name, default value, and usage string. // The argument p points to an net.IP variable in which to store the value of the flag. func IPVar(p *net.IP, name string, value net.IP, usage string) { CommandLine.VarP(newIPValue(value, p), name, "", usage) } // IPVarP is like IPVar, but accepts a shorthand letter that can be used after a single dash. func IPVarP(p *net.IP, name, shorthand string, value net.IP, usage string) { CommandLine.VarP(newIPValue(value, p), name, shorthand, usage) } // IP defines an net.IP flag with specified name, default value, and usage string. // The return value is the address of an net.IP variable that stores the value of the flag. func (f *FlagSet) IP(name string, value net.IP, usage string) *net.IP { p := new(net.IP) f.IPVarP(p, name, "", value, usage) return p } // IPP is like IP, but accepts a shorthand letter that can be used after a single dash. func (f *FlagSet) IPP(name, shorthand string, value net.IP, usage string) *net.IP { p := new(net.IP) f.IPVarP(p, name, shorthand, value, usage) return p } // IP defines an net.IP flag with specified name, default value, and usage string. // The return value is the address of an net.IP variable that stores the value of the flag. func IP(name string, value net.IP, usage string) *net.IP { return CommandLine.IPP(name, "", value, usage) } // IPP is like IP, but accepts a shorthand letter that can be used after a single dash. func IPP(name, shorthand string, value net.IP, usage string) *net.IP { return CommandLine.IPP(name, shorthand, value, usage) } spf13-pflag-0491e57/ip_slice.go000066400000000000000000000124441505550473500161510ustar00rootroot00000000000000package pflag import ( "fmt" "io" "net" "strings" ) // -- ipSlice Value type ipSliceValue struct { value *[]net.IP changed bool } func newIPSliceValue(val []net.IP, p *[]net.IP) *ipSliceValue { ipsv := new(ipSliceValue) ipsv.value = p *ipsv.value = val return ipsv } // 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 { return err } // parse ip values into slice out := make([]net.IP, 0, len(ipStrSlice)) for _, ipStr := range ipStrSlice { ip := net.ParseIP(strings.TrimSpace(ipStr)) if ip == nil { return fmt.Errorf("invalid string being converted to IP address: %s", ipStr) } out = append(out, ip) } if !s.changed { *s.value = out } else { *s.value = append(*s.value, out...) } s.changed = true return nil } // Type returns a string that uniquely represents this flag's type. func (s *ipSliceValue) Type() string { return "ipSlice" } // 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() } out, _ := writeAsCSV(ipStrSlice) return "[" + out + "]" } func (s *ipSliceValue) fromString(val string) (net.IP, error) { return net.ParseIP(strings.TrimSpace(val)), nil } func (s *ipSliceValue) toString(val net.IP) string { return val.String() } func (s *ipSliceValue) Append(val string) error { i, err := s.fromString(val) if err != nil { return err } *s.value = append(*s.value, i) 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) if err != nil { return err } } *s.value = out return nil } func (s *ipSliceValue) GetSlice() []string { out := make([]string, len(*s.value)) for i, d := range *s.value { out[i] = s.toString(d) } return out } func ipSliceConv(val string) (interface{}, error) { val = strings.Trim(val, "[]") // Empty string would cause a slice with one (empty) entry if len(val) == 0 { return []net.IP{}, nil } ss := strings.Split(val, ",") out := make([]net.IP, len(ss)) for i, sval := range ss { ip := net.ParseIP(strings.TrimSpace(sval)) if ip == nil { return nil, fmt.Errorf("invalid string being converted to IP address: %s", sval) } out[i] = ip } return out, nil } // GetIPSlice returns the []net.IP value of a flag with the given name func (f *FlagSet) GetIPSlice(name string) ([]net.IP, error) { val, err := f.getFlagType(name, "ipSlice", ipSliceConv) if err != nil { return []net.IP{}, err } return val.([]net.IP), nil } // IPSliceVar defines a ipSlice flag with specified name, default value, and usage string. // The argument p points to a []net.IP variable in which to store the value of the flag. func (f *FlagSet) IPSliceVar(p *[]net.IP, name string, value []net.IP, usage string) { f.VarP(newIPSliceValue(value, p), name, "", usage) } // IPSliceVarP is like IPSliceVar, but accepts a shorthand letter that can be used after a single dash. func (f *FlagSet) IPSliceVarP(p *[]net.IP, name, shorthand string, value []net.IP, usage string) { f.VarP(newIPSliceValue(value, p), name, shorthand, usage) } // IPSliceVar defines a []net.IP flag with specified name, default value, and usage string. // The argument p points to a []net.IP variable in which to store the value of the flag. func IPSliceVar(p *[]net.IP, name string, value []net.IP, usage string) { CommandLine.VarP(newIPSliceValue(value, p), name, "", usage) } // IPSliceVarP is like IPSliceVar, but accepts a shorthand letter that can be used after a single dash. func IPSliceVarP(p *[]net.IP, name, shorthand string, value []net.IP, usage string) { CommandLine.VarP(newIPSliceValue(value, p), name, shorthand, usage) } // IPSlice defines a []net.IP flag with specified name, default value, and usage string. // The return value is the address of a []net.IP variable that stores the value of that flag. func (f *FlagSet) IPSlice(name string, value []net.IP, usage string) *[]net.IP { p := []net.IP{} f.IPSliceVarP(&p, name, "", value, usage) return &p } // IPSliceP is like IPSlice, but accepts a shorthand letter that can be used after a single dash. func (f *FlagSet) IPSliceP(name, shorthand string, value []net.IP, usage string) *[]net.IP { p := []net.IP{} f.IPSliceVarP(&p, name, shorthand, value, usage) return &p } // IPSlice defines a []net.IP flag with specified name, default value, and usage string. // The return value is the address of a []net.IP variable that stores the value of the flag. func IPSlice(name string, value []net.IP, usage string) *[]net.IP { return CommandLine.IPSliceP(name, "", value, usage) } // IPSliceP is like IPSlice, but accepts a shorthand letter that can be used after a single dash. func IPSliceP(name, shorthand string, value []net.IP, usage string) *[]net.IP { return CommandLine.IPSliceP(name, shorthand, value, usage) } spf13-pflag-0491e57/ip_slice_test.go000066400000000000000000000144631505550473500172130ustar00rootroot00000000000000package pflag import ( "fmt" "net" "strings" "testing" ) func setUpIPSFlagSet(ipsp *[]net.IP) *FlagSet { f := NewFlagSet("test", ContinueOnError) f.IPSliceVar(ipsp, "ips", []net.IP{}, "Command separated list!") return f } func setUpIPSFlagSetWithDefault(ipsp *[]net.IP) *FlagSet { f := NewFlagSet("test", ContinueOnError) f.IPSliceVar(ipsp, "ips", []net.IP{ net.ParseIP("192.168.1.1"), net.ParseIP("0:0:0:0:0:0:0:1"), }, "Command separated list!") return f } func TestEmptyIP(t *testing.T) { var ips []net.IP f := setUpIPSFlagSet(&ips) err := f.Parse([]string{}) if err != nil { t.Fatal("expected no error; got", err) } getIPS, err := f.GetIPSlice("ips") if err != nil { t.Fatal("got an error from GetIPSlice():", err) } if len(getIPS) != 0 { t.Fatalf("got ips %v with len=%d but expected length=0", getIPS, len(getIPS)) } } func TestIPS(t *testing.T) { var ips []net.IP f := setUpIPSFlagSet(&ips) vals := []string{"192.168.1.1", "10.0.0.1", "0:0:0:0:0:0:0:2"} arg := fmt.Sprintf("--ips=%s", strings.Join(vals, ",")) err := f.Parse([]string{arg}) if err != nil { t.Fatal("expected no error; got", err) } 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]) } else if !ip.Equal(v) { t.Fatalf("expected ips[%d] to be %s but got: %s from GetIPSlice", i, vals[i], v) } } } func TestIPSDefault(t *testing.T) { var ips []net.IP 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) } 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]) } else if !ip.Equal(v) { t.Fatalf("expected ips[%d] to be %s but got: %s", i, vals[i], v) } } getIPS, err := f.GetIPSlice("ips") if err != 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]) } else if !ip.Equal(v) { t.Fatalf("expected ips[%d] to be %s but got: %s", i, vals[i], v) } } } func TestIPSWithDefault(t *testing.T) { var ips []net.IP f := setUpIPSFlagSetWithDefault(&ips) vals := []string{"192.168.1.1", "0:0:0:0:0:0:0:1"} arg := fmt.Sprintf("--ips=%s", strings.Join(vals, ",")) err := f.Parse([]string{arg}) if err != nil { t.Fatal("expected no error; got", err) } 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]) } else if !ip.Equal(v) { t.Fatalf("expected ips[%d] to be %s but got: %s", i, vals[i], v) } } getIPS, err := f.GetIPSlice("ips") if err != 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]) } else if !ip.Equal(v) { t.Fatalf("expected ips[%d] to be %s but got: %s", i, vals[i], v) } } } func TestIPSCalledTwice(t *testing.T) { var ips []net.IP f := setUpIPSFlagSet(&ips) in := []string{"192.168.1.2,0:0:0:0:0:0:0:1", "10.0.0.1"} expected := []net.IP{net.ParseIP("192.168.1.2"), net.ParseIP("0:0:0:0:0:0:0:1"), net.ParseIP("10.0.0.1")} argfmt := "ips=%s" arg1 := fmt.Sprintf(argfmt, in[0]) arg2 := fmt.Sprintf(argfmt, in[1]) err := f.Parse([]string{arg1, arg2}) if err != nil { t.Fatal("expected no error; got", err) } for i, v := range ips { if !expected[i].Equal(v) { t.Fatalf("expected ips[%d] to be %s but got: %s", i, expected[i], v) } } } func TestIPSAsSliceValue(t *testing.T) { var ips []net.IP f := setUpIPSFlagSet(&ips) in := []string{"192.168.1.1", "0:0:0:0:0:0:0:1"} argfmt := "--ips=%s" arg1 := fmt.Sprintf(argfmt, in[0]) arg2 := fmt.Sprintf(argfmt, in[1]) err := f.Parse([]string{arg1, arg2}) if err != nil { t.Fatal("expected no error; got", err) } f.VisitAll(func(f *Flag) { if val, ok := f.Value.(SliceValue); ok { _ = val.Replace([]string{"192.168.1.2"}) } }) if len(ips) != 1 || !ips[0].Equal(net.ParseIP("192.168.1.2")) { t.Fatalf("Expected ss to be overwritten with '192.168.1.2', but got: %v", ips) } } func TestIPSBadQuoting(t *testing.T) { tests := []struct { Want []net.IP FlagArg []string }{ { Want: []net.IP{ net.ParseIP("a4ab:61d:f03e:5d7d:fad7:d4c2:a1a5:568"), net.ParseIP("203.107.49.208"), net.ParseIP("14.57.204.90"), }, FlagArg: []string{ "a4ab:61d:f03e:5d7d:fad7:d4c2:a1a5:568", "203.107.49.208", "14.57.204.90", }, }, { Want: []net.IP{ net.ParseIP("204.228.73.195"), net.ParseIP("86.141.15.94"), }, FlagArg: []string{ "204.228.73.195", "86.141.15.94", }, }, { Want: []net.IP{ net.ParseIP("c70c:db36:3001:890f:c6ea:3f9b:7a39:cc3f"), net.ParseIP("4d17:1d6e:e699:bd7a:88c5:5e7e:ac6a:4472"), }, FlagArg: []string{ "c70c:db36:3001:890f:c6ea:3f9b:7a39:cc3f", "4d17:1d6e:e699:bd7a:88c5:5e7e:ac6a:4472", }, }, { Want: []net.IP{ net.ParseIP("5170:f971:cfac:7be3:512a:af37:952c:bc33"), net.ParseIP("93.21.145.140"), net.ParseIP("2cac:61d3:c5ff:6caf:73e0:1b1a:c336:c1ca"), }, FlagArg: []string{ " 5170:f971:cfac:7be3:512a:af37:952c:bc33 , 93.21.145.140 ", "2cac:61d3:c5ff:6caf:73e0:1b1a:c336:c1ca", }, }, { Want: []net.IP{ net.ParseIP("2e5e:66b2:6441:848:5b74:76ea:574c:3a7b"), net.ParseIP("2e5e:66b2:6441:848:5b74:76ea:574c:3a7b"), net.ParseIP("2e5e:66b2:6441:848:5b74:76ea:574c:3a7b"), net.ParseIP("2e5e:66b2:6441:848:5b74:76ea:574c:3a7b"), }, FlagArg: []string{ `"2e5e:66b2:6441:848:5b74:76ea:574c:3a7b, 2e5e:66b2:6441:848:5b74:76ea:574c:3a7b,2e5e:66b2:6441:848:5b74:76ea:574c:3a7b "`, " 2e5e:66b2:6441:848:5b74:76ea:574c:3a7b"}, }, } for i, test := range tests { var ips []net.IP f := setUpIPSFlagSet(&ips) if err := f.Parse([]string{fmt.Sprintf("--ips=%s", strings.Join(test.FlagArg, ","))}); err != nil { t.Fatalf("flag parsing failed with error: %s\nparsing:\t%#v\nwant:\t\t%s", err, test.FlagArg, test.Want[i]) } for j, b := range ips { if !b.Equal(test.Want[j]) { t.Fatalf("bad value parsed for test %d on net.IP %d:\nwant:\t%s\ngot:\t%s", i, j, test.Want[j], b) } } } } spf13-pflag-0491e57/ip_test.go000066400000000000000000000025531505550473500160310ustar00rootroot00000000000000package pflag import ( "fmt" "net" "os" "testing" ) func setUpIP(ip *net.IP) *FlagSet { f := NewFlagSet("test", ContinueOnError) f.IPVar(ip, "address", net.ParseIP("0.0.0.0"), "IP Address") return f } func TestIP(t *testing.T) { testCases := []struct { input string success bool expected string }{ {"0.0.0.0", true, "0.0.0.0"}, {" 0.0.0.0 ", true, "0.0.0.0"}, {"1.2.3.4", true, "1.2.3.4"}, {"127.0.0.1", true, "127.0.0.1"}, {"255.255.255.255", true, "255.255.255.255"}, {"", true, "0.0.0.0"}, {"0", false, ""}, {"localhost", false, ""}, {"0.0.0", false, ""}, {"0.0.0.", false, ""}, {"0.0.0.0.", false, ""}, {"0.0.0.256", false, ""}, {"0 . 0 . 0 . 0", false, ""}, } devnull, _ := os.Open(os.DevNull) os.Stderr = devnull for i := range testCases { var addr net.IP f := setUpIP(&addr) tc := &testCases[i] arg := fmt.Sprintf("--address=%s", tc.input) err := f.Parse([]string{arg}) if err != nil && tc.success == true { t.Errorf("expected success, got %q", err) continue } else if err == nil && tc.success == false { t.Errorf("expected failure") continue } else if tc.success { ip, err := f.GetIP("address") if err != nil { t.Errorf("Got error trying to fetch the IP flag: %v", err) } if ip.String() != tc.expected { t.Errorf("expected %q, got %q", tc.expected, ip.String()) } } } } spf13-pflag-0491e57/ipmask.go000066400000000000000000000077241505550473500156530ustar00rootroot00000000000000package pflag import ( "fmt" "net" "strconv" ) // -- net.IPMask value type ipMaskValue net.IPMask func newIPMaskValue(val net.IPMask, p *net.IPMask) *ipMaskValue { *p = val return (*ipMaskValue)(p) } func (i *ipMaskValue) String() string { return net.IPMask(*i).String() } func (i *ipMaskValue) Set(s string) error { ip := ParseIPv4Mask(s) if ip == nil { return fmt.Errorf("failed to parse IP mask: %q", s) } *i = ipMaskValue(ip) return nil } func (i *ipMaskValue) Type() string { return "ipMask" } // ParseIPv4Mask written in IP form (e.g. 255.255.255.0). // This function should really belong to the net package. func ParseIPv4Mask(s string) net.IPMask { mask := net.ParseIP(s) if mask == nil { if len(s) != 8 { return nil } // net.IPMask.String() actually outputs things like ffffff00 // so write a horrible parser for that as well :-( m := []int{} for i := 0; i < 4; i++ { b := "0x" + s[2*i:2*i+2] d, err := strconv.ParseInt(b, 0, 0) if err != nil { return nil } m = append(m, int(d)) } s := fmt.Sprintf("%d.%d.%d.%d", m[0], m[1], m[2], m[3]) mask = net.ParseIP(s) if mask == nil { return nil } } return net.IPv4Mask(mask[12], mask[13], mask[14], mask[15]) } func parseIPv4Mask(sval string) (interface{}, error) { mask := ParseIPv4Mask(sval) if mask == nil { return nil, fmt.Errorf("unable to parse %s as net.IPMask", sval) } return mask, nil } // GetIPv4Mask return the net.IPv4Mask value of a flag with the given name func (f *FlagSet) GetIPv4Mask(name string) (net.IPMask, error) { val, err := f.getFlagType(name, "ipMask", parseIPv4Mask) if err != nil { return nil, err } return val.(net.IPMask), nil } // IPMaskVar defines an net.IPMask flag with specified name, default value, and usage string. // The argument p points to an net.IPMask variable in which to store the value of the flag. func (f *FlagSet) IPMaskVar(p *net.IPMask, name string, value net.IPMask, usage string) { f.VarP(newIPMaskValue(value, p), name, "", usage) } // IPMaskVarP is like IPMaskVar, but accepts a shorthand letter that can be used after a single dash. func (f *FlagSet) IPMaskVarP(p *net.IPMask, name, shorthand string, value net.IPMask, usage string) { f.VarP(newIPMaskValue(value, p), name, shorthand, usage) } // IPMaskVar defines an net.IPMask flag with specified name, default value, and usage string. // The argument p points to an net.IPMask variable in which to store the value of the flag. func IPMaskVar(p *net.IPMask, name string, value net.IPMask, usage string) { CommandLine.VarP(newIPMaskValue(value, p), name, "", usage) } // IPMaskVarP is like IPMaskVar, but accepts a shorthand letter that can be used after a single dash. func IPMaskVarP(p *net.IPMask, name, shorthand string, value net.IPMask, usage string) { CommandLine.VarP(newIPMaskValue(value, p), name, shorthand, usage) } // IPMask defines an net.IPMask flag with specified name, default value, and usage string. // The return value is the address of an net.IPMask variable that stores the value of the flag. func (f *FlagSet) IPMask(name string, value net.IPMask, usage string) *net.IPMask { p := new(net.IPMask) f.IPMaskVarP(p, name, "", value, usage) return p } // IPMaskP is like IPMask, but accepts a shorthand letter that can be used after a single dash. func (f *FlagSet) IPMaskP(name, shorthand string, value net.IPMask, usage string) *net.IPMask { p := new(net.IPMask) f.IPMaskVarP(p, name, shorthand, value, usage) return p } // IPMask defines an net.IPMask flag with specified name, default value, and usage string. // The return value is the address of an net.IPMask variable that stores the value of the flag. func IPMask(name string, value net.IPMask, usage string) *net.IPMask { return CommandLine.IPMaskP(name, "", value, usage) } // IPMaskP is like IP, but accepts a shorthand letter that can be used after a single dash. func IPMaskP(name, shorthand string, value net.IPMask, usage string) *net.IPMask { return CommandLine.IPMaskP(name, shorthand, value, usage) } spf13-pflag-0491e57/ipnet.go000066400000000000000000000064021505550473500154760ustar00rootroot00000000000000package pflag import ( "fmt" "net" "strings" ) // IPNet adapts net.IPNet for use as a flag. type ipNetValue net.IPNet func (ipnet ipNetValue) String() string { n := net.IPNet(ipnet) return n.String() } func (ipnet *ipNetValue) Set(value string) error { _, n, err := net.ParseCIDR(strings.TrimSpace(value)) if err != nil { return err } *ipnet = ipNetValue(*n) return nil } func (*ipNetValue) Type() string { return "ipNet" } func newIPNetValue(val net.IPNet, p *net.IPNet) *ipNetValue { *p = val return (*ipNetValue)(p) } func ipNetConv(sval string) (interface{}, error) { _, n, err := net.ParseCIDR(strings.TrimSpace(sval)) if err == nil { return *n, nil } return nil, fmt.Errorf("invalid string being converted to IPNet: %s", sval) } // GetIPNet return the net.IPNet value of a flag with the given name func (f *FlagSet) GetIPNet(name string) (net.IPNet, error) { val, err := f.getFlagType(name, "ipNet", ipNetConv) if err != nil { return net.IPNet{}, err } return val.(net.IPNet), nil } // IPNetVar defines an net.IPNet flag with specified name, default value, and usage string. // The argument p points to an net.IPNet variable in which to store the value of the flag. func (f *FlagSet) IPNetVar(p *net.IPNet, name string, value net.IPNet, usage string) { f.VarP(newIPNetValue(value, p), name, "", usage) } // IPNetVarP is like IPNetVar, but accepts a shorthand letter that can be used after a single dash. func (f *FlagSet) IPNetVarP(p *net.IPNet, name, shorthand string, value net.IPNet, usage string) { f.VarP(newIPNetValue(value, p), name, shorthand, usage) } // IPNetVar defines an net.IPNet flag with specified name, default value, and usage string. // The argument p points to an net.IPNet variable in which to store the value of the flag. func IPNetVar(p *net.IPNet, name string, value net.IPNet, usage string) { CommandLine.VarP(newIPNetValue(value, p), name, "", usage) } // IPNetVarP is like IPNetVar, but accepts a shorthand letter that can be used after a single dash. func IPNetVarP(p *net.IPNet, name, shorthand string, value net.IPNet, usage string) { CommandLine.VarP(newIPNetValue(value, p), name, shorthand, usage) } // IPNet defines an net.IPNet flag with specified name, default value, and usage string. // The return value is the address of an net.IPNet variable that stores the value of the flag. func (f *FlagSet) IPNet(name string, value net.IPNet, usage string) *net.IPNet { p := new(net.IPNet) f.IPNetVarP(p, name, "", value, usage) return p } // IPNetP is like IPNet, but accepts a shorthand letter that can be used after a single dash. func (f *FlagSet) IPNetP(name, shorthand string, value net.IPNet, usage string) *net.IPNet { p := new(net.IPNet) f.IPNetVarP(p, name, shorthand, value, usage) return p } // IPNet defines an net.IPNet flag with specified name, default value, and usage string. // The return value is the address of an net.IPNet variable that stores the value of the flag. func IPNet(name string, value net.IPNet, usage string) *net.IPNet { return CommandLine.IPNetP(name, "", value, usage) } // IPNetP is like IPNet, but accepts a shorthand letter that can be used after a single dash. func IPNetP(name, shorthand string, value net.IPNet, usage string) *net.IPNet { return CommandLine.IPNetP(name, shorthand, value, usage) } spf13-pflag-0491e57/ipnet_slice.go000066400000000000000000000115321505550473500166550ustar00rootroot00000000000000package pflag import ( "fmt" "io" "net" "strings" ) // -- ipNetSlice Value type ipNetSliceValue struct { value *[]net.IPNet changed bool } func newIPNetSliceValue(val []net.IPNet, p *[]net.IPNet) *ipNetSliceValue { ipnsv := new(ipNetSliceValue) ipnsv.value = p *ipnsv.value = val return ipnsv } // 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 { return err } // parse ip values into slice out := make([]net.IPNet, 0, len(ipNetStrSlice)) for _, ipNetStr := range ipNetStrSlice { _, n, err := net.ParseCIDR(strings.TrimSpace(ipNetStr)) if err != nil { return fmt.Errorf("invalid string being converted to CIDR: %s", ipNetStr) } out = append(out, *n) } if !s.changed { *s.value = out } else { *s.value = append(*s.value, out...) } s.changed = true return nil } // Type returns a string that uniquely represents this flag's type. func (s *ipNetSliceValue) Type() string { return "ipNetSlice" } // 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() } out, _ := writeAsCSV(ipNetStrSlice) return "[" + out + "]" } func ipNetSliceConv(val string) (interface{}, error) { val = strings.Trim(val, "[]") // Empty string would cause a slice with one (empty) entry if len(val) == 0 { return []net.IPNet{}, nil } ss := strings.Split(val, ",") out := make([]net.IPNet, len(ss)) for i, sval := range ss { _, n, err := net.ParseCIDR(strings.TrimSpace(sval)) if err != nil { return nil, fmt.Errorf("invalid string being converted to CIDR: %s", sval) } out[i] = *n } return out, nil } // GetIPNetSlice returns the []net.IPNet value of a flag with the given name func (f *FlagSet) GetIPNetSlice(name string) ([]net.IPNet, error) { val, err := f.getFlagType(name, "ipNetSlice", ipNetSliceConv) if err != nil { return []net.IPNet{}, err } return val.([]net.IPNet), nil } // IPNetSliceVar defines a ipNetSlice flag with specified name, default value, and usage string. // The argument p points to a []net.IPNet variable in which to store the value of the flag. func (f *FlagSet) IPNetSliceVar(p *[]net.IPNet, name string, value []net.IPNet, usage string) { f.VarP(newIPNetSliceValue(value, p), name, "", usage) } // IPNetSliceVarP is like IPNetSliceVar, but accepts a shorthand letter that can be used after a single dash. func (f *FlagSet) IPNetSliceVarP(p *[]net.IPNet, name, shorthand string, value []net.IPNet, usage string) { f.VarP(newIPNetSliceValue(value, p), name, shorthand, usage) } // IPNetSliceVar defines a []net.IPNet flag with specified name, default value, and usage string. // The argument p points to a []net.IPNet variable in which to store the value of the flag. func IPNetSliceVar(p *[]net.IPNet, name string, value []net.IPNet, usage string) { CommandLine.VarP(newIPNetSliceValue(value, p), name, "", usage) } // IPNetSliceVarP is like IPNetSliceVar, but accepts a shorthand letter that can be used after a single dash. func IPNetSliceVarP(p *[]net.IPNet, name, shorthand string, value []net.IPNet, usage string) { CommandLine.VarP(newIPNetSliceValue(value, p), name, shorthand, usage) } // IPNetSlice defines a []net.IPNet flag with specified name, default value, and usage string. // The return value is the address of a []net.IPNet variable that stores the value of that flag. func (f *FlagSet) IPNetSlice(name string, value []net.IPNet, usage string) *[]net.IPNet { p := []net.IPNet{} f.IPNetSliceVarP(&p, name, "", value, usage) return &p } // IPNetSliceP is like IPNetSlice, but accepts a shorthand letter that can be used after a single dash. func (f *FlagSet) IPNetSliceP(name, shorthand string, value []net.IPNet, usage string) *[]net.IPNet { p := []net.IPNet{} f.IPNetSliceVarP(&p, name, shorthand, value, usage) return &p } // IPNetSlice defines a []net.IPNet flag with specified name, default value, and usage string. // The return value is the address of a []net.IP variable that stores the value of the flag. func IPNetSlice(name string, value []net.IPNet, usage string) *[]net.IPNet { return CommandLine.IPNetSliceP(name, "", value, usage) } // IPNetSliceP is like IPNetSlice, but accepts a shorthand letter that can be used after a single dash. func IPNetSliceP(name, shorthand string, value []net.IPNet, usage string) *[]net.IPNet { return CommandLine.IPNetSliceP(name, shorthand, value, usage) } spf13-pflag-0491e57/ipnet_slice_test.go000066400000000000000000000150121505550473500177110ustar00rootroot00000000000000package pflag import ( "fmt" "net" "strings" "testing" ) // Helper function to set static slices func getCIDR(ip net.IP, cidr *net.IPNet, err error) net.IPNet { return *cidr } func equalCIDR(c1 net.IPNet, c2 net.IPNet) bool { if c1.String() == c2.String() { return true } return false } func setUpIPNetFlagSet(ipsp *[]net.IPNet) *FlagSet { f := NewFlagSet("test", ContinueOnError) f.IPNetSliceVar(ipsp, "cidrs", []net.IPNet{}, "Command separated list!") return f } func setUpIPNetFlagSetWithDefault(ipsp *[]net.IPNet) *FlagSet { f := NewFlagSet("test", ContinueOnError) f.IPNetSliceVar(ipsp, "cidrs", []net.IPNet{ getCIDR(net.ParseCIDR("192.168.1.1/16")), getCIDR(net.ParseCIDR("fd00::/64")), }, "Command separated list!") return f } func TestEmptyIPNet(t *testing.T) { var cidrs []net.IPNet f := setUpIPNetFlagSet(&cidrs) err := f.Parse([]string{}) if err != nil { t.Fatal("expected no error; got", err) } getIPNet, err := f.GetIPNetSlice("cidrs") if err != nil { t.Fatal("got an error from GetIPNetSlice():", err) } if len(getIPNet) != 0 { t.Fatalf("got ips %v with len=%d but expected length=0", getIPNet, len(getIPNet)) } } func TestIPNets(t *testing.T) { var ips []net.IPNet f := setUpIPNetFlagSet(&ips) vals := []string{"192.168.1.1/24", "10.0.0.1/16", "fd00:0:0:0:0:0:0:2/64"} arg := fmt.Sprintf("--cidrs=%s", strings.Join(vals, ",")) err := f.Parse([]string{arg}) if err != nil { t.Fatal("expected no error; got", err) } for i, v := range ips { if _, cidr, _ := net.ParseCIDR(vals[i]); cidr == nil { t.Fatalf("invalid string being converted to CIDR: %s", vals[i]) } else if !equalCIDR(*cidr, v) { t.Fatalf("expected ips[%d] to be %s but got: %s from GetIPSlice", i, vals[i], v) } } } func TestIPNetDefault(t *testing.T) { var cidrs []net.IPNet f := setUpIPNetFlagSetWithDefault(&cidrs) vals := []string{"192.168.1.1/16", "fd00::/64"} err := f.Parse([]string{}) if err != nil { t.Fatal("expected no error; got", err) } for i, v := range cidrs { if _, cidr, _ := net.ParseCIDR(vals[i]); cidr == nil { t.Fatalf("invalid string being converted to CIDR: %s", vals[i]) } else if !equalCIDR(*cidr, v) { t.Fatalf("expected cidrs[%d] to be %s but got: %s", i, vals[i], v) } } getIPNet, err := f.GetIPNetSlice("cidrs") if err != nil { t.Fatal("got an error from GetIPNetSlice") } for i, v := range getIPNet { if _, cidr, _ := net.ParseCIDR(vals[i]); cidr == nil { t.Fatalf("invalid string being converted to CIDR: %s", vals[i]) } else if !equalCIDR(*cidr, v) { t.Fatalf("expected cidrs[%d] to be %s but got: %s", i, vals[i], v) } } } func TestIPNetWithDefault(t *testing.T) { var cidrs []net.IPNet f := setUpIPNetFlagSetWithDefault(&cidrs) vals := []string{"192.168.1.1/16", "fd00::/64"} arg := fmt.Sprintf("--cidrs=%s", strings.Join(vals, ",")) err := f.Parse([]string{arg}) if err != nil { t.Fatal("expected no error; got", err) } for i, v := range cidrs { if _, cidr, _ := net.ParseCIDR(vals[i]); cidr == nil { t.Fatalf("invalid string being converted to CIDR: %s", vals[i]) } else if !equalCIDR(*cidr, v) { t.Fatalf("expected cidrs[%d] to be %s but got: %s", i, vals[i], v) } } getIPNet, err := f.GetIPNetSlice("cidrs") if err != nil { t.Fatal("got an error from GetIPNetSlice") } for i, v := range getIPNet { if _, cidr, _ := net.ParseCIDR(vals[i]); cidr == nil { t.Fatalf("invalid string being converted to CIDR: %s", vals[i]) } else if !equalCIDR(*cidr, v) { t.Fatalf("expected cidrs[%d] to be %s but got: %s", i, vals[i], v) } } } func TestIPNetCalledTwice(t *testing.T) { var cidrs []net.IPNet f := setUpIPNetFlagSet(&cidrs) in := []string{"192.168.1.2/16,fd00::/64", "10.0.0.1/24"} expected := []net.IPNet{ getCIDR(net.ParseCIDR("192.168.1.2/16")), getCIDR(net.ParseCIDR("fd00::/64")), getCIDR(net.ParseCIDR("10.0.0.1/24")), } argfmt := "--cidrs=%s" arg1 := fmt.Sprintf(argfmt, in[0]) arg2 := fmt.Sprintf(argfmt, in[1]) err := f.Parse([]string{arg1, arg2}) if err != nil { t.Fatal("expected no error; got", err) } for i, v := range cidrs { if !equalCIDR(expected[i], v) { t.Fatalf("expected cidrs[%d] to be %s but got: %s", i, expected[i], v) } } } func TestIPNetBadQuoting(t *testing.T) { tests := []struct { Want []net.IPNet FlagArg []string }{ { Want: []net.IPNet{ getCIDR(net.ParseCIDR("a4ab:61d:f03e:5d7d:fad7:d4c2:a1a5:568/128")), getCIDR(net.ParseCIDR("203.107.49.208/32")), getCIDR(net.ParseCIDR("14.57.204.90/32")), }, FlagArg: []string{ "a4ab:61d:f03e:5d7d:fad7:d4c2:a1a5:568/128", "203.107.49.208/32", "14.57.204.90/32", }, }, { Want: []net.IPNet{ getCIDR(net.ParseCIDR("204.228.73.195/32")), getCIDR(net.ParseCIDR("86.141.15.94/32")), }, FlagArg: []string{ "204.228.73.195/32", "86.141.15.94/32", }, }, { Want: []net.IPNet{ getCIDR(net.ParseCIDR("c70c:db36:3001:890f:c6ea:3f9b:7a39:cc3f/128")), getCIDR(net.ParseCIDR("4d17:1d6e:e699:bd7a:88c5:5e7e:ac6a:4472/128")), }, FlagArg: []string{ "c70c:db36:3001:890f:c6ea:3f9b:7a39:cc3f/128", "4d17:1d6e:e699:bd7a:88c5:5e7e:ac6a:4472/128", }, }, { Want: []net.IPNet{ getCIDR(net.ParseCIDR("5170:f971:cfac:7be3:512a:af37:952c:bc33/128")), getCIDR(net.ParseCIDR("93.21.145.140/32")), getCIDR(net.ParseCIDR("2cac:61d3:c5ff:6caf:73e0:1b1a:c336:c1ca/128")), }, FlagArg: []string{ " 5170:f971:cfac:7be3:512a:af37:952c:bc33/128 , 93.21.145.140/32 ", "2cac:61d3:c5ff:6caf:73e0:1b1a:c336:c1ca/128", }, }, { Want: []net.IPNet{ getCIDR(net.ParseCIDR("2e5e:66b2:6441:848:5b74:76ea:574c:3a7b/128")), getCIDR(net.ParseCIDR("2e5e:66b2:6441:848:5b74:76ea:574c:3a7b/128")), getCIDR(net.ParseCIDR("2e5e:66b2:6441:848:5b74:76ea:574c:3a7b/128")), getCIDR(net.ParseCIDR("2e5e:66b2:6441:848:5b74:76ea:574c:3a7b/128")), }, FlagArg: []string{ `"2e5e:66b2:6441:848:5b74:76ea:574c:3a7b/128, 2e5e:66b2:6441:848:5b74:76ea:574c:3a7b/128,2e5e:66b2:6441:848:5b74:76ea:574c:3a7b/128 "`, " 2e5e:66b2:6441:848:5b74:76ea:574c:3a7b/128"}, }, } for i, test := range tests { var cidrs []net.IPNet f := setUpIPNetFlagSet(&cidrs) if err := f.Parse([]string{fmt.Sprintf("--cidrs=%s", strings.Join(test.FlagArg, ","))}); err != nil { t.Fatalf("flag parsing failed with error: %s\nparsing:\t%#v\nwant:\t\t%s", err, test.FlagArg, test.Want[i]) } for j, b := range cidrs { if !equalCIDR(b, test.Want[j]) { t.Fatalf("bad value parsed for test %d on net.IP %d:\nwant:\t%s\ngot:\t%s", i, j, test.Want[j], b) } } } } spf13-pflag-0491e57/ipnet_test.go000066400000000000000000000031621505550473500165350ustar00rootroot00000000000000package pflag import ( "fmt" "net" "os" "testing" ) func setUpIPNet(ip *net.IPNet) *FlagSet { f := NewFlagSet("test", ContinueOnError) _, def, _ := net.ParseCIDR("0.0.0.0/0") f.IPNetVar(ip, "address", *def, "IP Address") return f } func TestIPNet(t *testing.T) { testCases := []struct { input string success bool expected string }{ {"0.0.0.0/0", true, "0.0.0.0/0"}, {" 0.0.0.0/0 ", true, "0.0.0.0/0"}, {"1.2.3.4/8", true, "1.0.0.0/8"}, {"127.0.0.1/16", true, "127.0.0.0/16"}, {"255.255.255.255/19", true, "255.255.224.0/19"}, {"255.255.255.255/32", true, "255.255.255.255/32"}, {"", false, ""}, {"/0", false, ""}, {"0", false, ""}, {"0/0", false, ""}, {"localhost/0", false, ""}, {"0.0.0/4", false, ""}, {"0.0.0./8", false, ""}, {"0.0.0.0./12", false, ""}, {"0.0.0.256/16", false, ""}, {"0.0.0.0 /20", false, ""}, {"0.0.0.0/ 24", false, ""}, {"0 . 0 . 0 . 0 / 28", false, ""}, {"0.0.0.0/33", false, ""}, } devnull, _ := os.Open(os.DevNull) os.Stderr = devnull for i := range testCases { var addr net.IPNet f := setUpIPNet(&addr) tc := &testCases[i] arg := fmt.Sprintf("--address=%s", tc.input) err := f.Parse([]string{arg}) if err != nil && tc.success == true { t.Errorf("expected success, got %q", err) continue } else if err == nil && tc.success == false { t.Errorf("expected failure") continue } else if tc.success { ip, err := f.GetIPNet("address") if err != nil { t.Errorf("Got error trying to fetch the IP flag: %v", err) } if ip.String() != tc.expected { t.Errorf("expected %q, got %q", tc.expected, ip.String()) } } } } spf13-pflag-0491e57/printusage_test.go000066400000000000000000000052301505550473500175750ustar00rootroot00000000000000package pflag import ( "bytes" "io" "testing" ) const expectedOutput = ` --long-form Some description --long-form2 Some description with multiline -s, --long-name Some description -t, --long-name2 Some description with multiline ` func setUpPFlagSet(buf io.Writer) *FlagSet { f := NewFlagSet("test", ExitOnError) f.Bool("long-form", false, "Some description") f.Bool("long-form2", false, "Some description\n with multiline") f.BoolP("long-name", "s", false, "Some description") f.BoolP("long-name2", "t", false, "Some description with\n multiline") f.SetOutput(buf) return f } func TestPrintUsage(t *testing.T) { buf := bytes.Buffer{} f := setUpPFlagSet(&buf) f.PrintDefaults() res := buf.String() if res != expectedOutput { t.Errorf("Expected \n%s \nActual \n%s", expectedOutput, res) } } func setUpPFlagSet2(buf io.Writer) *FlagSet { f := NewFlagSet("test", ExitOnError) f.Bool("long-form", false, "Some description") f.Bool("long-form2", false, "Some description\n with multiline") f.BoolP("long-name", "s", false, "Some description") f.BoolP("long-name2", "t", false, "Some description with\n multiline") f.StringP("some-very-long-arg", "l", "test", "Some very long description having break the limit") f.StringP("other-very-long-arg", "o", "long-default-value", "Some very long description having break the limit") f.String("some-very-long-arg2", "very long default value", "Some very long description\nwith line break\nmultiple") f.SetOutput(buf) return f } const expectedOutput2 = ` --long-form Some description --long-form2 Some description with multiline -s, --long-name Some description -t, --long-name2 Some description with multiline -o, --other-very-long-arg string Some very long description having break the limit (default "long-default-value") -l, --some-very-long-arg string Some very long description having break the limit (default "test") --some-very-long-arg2 string Some very long description with line break multiple (default "very long default value") ` func TestPrintUsage_2(t *testing.T) { buf := bytes.Buffer{} f := setUpPFlagSet2(&buf) res := f.FlagUsagesWrapped(80) if res != expectedOutput2 { t.Errorf("Expected \n%q \nActual \n%q", expectedOutput2, res) } } spf13-pflag-0491e57/string.go000066400000000000000000000055551505550473500156750ustar00rootroot00000000000000package pflag // -- string Value type stringValue string func newStringValue(val string, p *string) *stringValue { *p = val return (*stringValue)(p) } func (s *stringValue) Set(val string) error { *s = stringValue(val) return nil } func (s *stringValue) Type() string { return "string" } func (s *stringValue) String() string { return string(*s) } func stringConv(sval string) (interface{}, error) { return sval, nil } // GetString return the string value of a flag with the given name func (f *FlagSet) GetString(name string) (string, error) { val, err := f.getFlagType(name, "string", stringConv) if err != nil { return "", err } return val.(string), nil } // StringVar defines a string flag with specified name, default value, and usage string. // The argument p points to a string variable in which to store the value of the flag. func (f *FlagSet) StringVar(p *string, name string, value string, usage string) { f.VarP(newStringValue(value, p), name, "", usage) } // StringVarP is like StringVar, but accepts a shorthand letter that can be used after a single dash. func (f *FlagSet) StringVarP(p *string, name, shorthand string, value string, usage string) { f.VarP(newStringValue(value, p), name, shorthand, usage) } // StringVar defines a string flag with specified name, default value, and usage string. // The argument p points to a string variable in which to store the value of the flag. func StringVar(p *string, name string, value string, usage string) { CommandLine.VarP(newStringValue(value, p), name, "", usage) } // StringVarP is like StringVar, but accepts a shorthand letter that can be used after a single dash. func StringVarP(p *string, name, shorthand string, value string, usage string) { CommandLine.VarP(newStringValue(value, p), name, shorthand, usage) } // String defines a string flag with specified name, default value, and usage string. // The return value is the address of a string variable that stores the value of the flag. func (f *FlagSet) String(name string, value string, usage string) *string { p := new(string) f.StringVarP(p, name, "", value, usage) return p } // StringP is like String, but accepts a shorthand letter that can be used after a single dash. func (f *FlagSet) StringP(name, shorthand string, value string, usage string) *string { p := new(string) f.StringVarP(p, name, shorthand, value, usage) return p } // String defines a string flag with specified name, default value, and usage string. // The return value is the address of a string variable that stores the value of the flag. func String(name string, value string, usage string) *string { return CommandLine.StringP(name, "", value, usage) } // StringP is like String, but accepts a shorthand letter that can be used after a single dash. func StringP(name, shorthand string, value string, usage string) *string { return CommandLine.StringP(name, shorthand, value, usage) } spf13-pflag-0491e57/string_array.go000066400000000000000000000104021505550473500170560ustar00rootroot00000000000000package pflag // -- stringArray Value type stringArrayValue struct { value *[]string changed bool } func newStringArrayValue(val []string, p *[]string) *stringArrayValue { ssv := new(stringArrayValue) ssv.value = p *ssv.value = val return ssv } func (s *stringArrayValue) Set(val string) error { if !s.changed { *s.value = []string{val} s.changed = true } else { *s.value = append(*s.value, val) } return nil } func (s *stringArrayValue) Append(val string) error { *s.value = append(*s.value, val) return nil } func (s *stringArrayValue) Replace(val []string) error { out := make([]string, len(val)) for i, d := range val { out[i] = d } *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 } return out } func (s *stringArrayValue) Type() string { return "stringArray" } func (s *stringArrayValue) String() string { str, _ := writeAsCSV(*s.value) return "[" + str + "]" } func stringArrayConv(sval string) (interface{}, error) { sval = sval[1 : len(sval)-1] // An empty string would cause a array with one (empty) string if len(sval) == 0 { return []string{}, nil } return readAsCSV(sval) } // GetStringArray return the []string value of a flag with the given name func (f *FlagSet) GetStringArray(name string) ([]string, error) { val, err := f.getFlagType(name, "stringArray", stringArrayConv) if err != nil { return []string{}, err } return val.([]string), nil } // StringArrayVar defines a string flag with specified name, default value, and usage string. // The argument p points to a []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. Use a StringSlice for that. func (f *FlagSet) StringArrayVar(p *[]string, name string, value []string, usage string) { f.VarP(newStringArrayValue(value, p), name, "", usage) } // StringArrayVarP is like StringArrayVar, but accepts a shorthand letter that can be used after a single dash. func (f *FlagSet) StringArrayVarP(p *[]string, name, shorthand string, value []string, usage string) { f.VarP(newStringArrayValue(value, p), name, shorthand, usage) } // StringArrayVar defines a string flag with specified name, default value, and usage string. // The argument p points to a []string variable in which to store the value of the flag. // The value of each argument will not try to be separated by comma. Use a StringSlice for that. func StringArrayVar(p *[]string, name string, value []string, usage string) { CommandLine.VarP(newStringArrayValue(value, p), name, "", usage) } // StringArrayVarP is like StringArrayVar, but accepts a shorthand letter that can be used after a single dash. func StringArrayVarP(p *[]string, name, shorthand string, value []string, usage string) { CommandLine.VarP(newStringArrayValue(value, p), name, shorthand, usage) } // StringArray defines a string flag with specified name, default value, and usage string. // The return value is the address of a []string variable that stores the value of the flag. // The value of each argument will not try to be separated by comma. Use a StringSlice for that. func (f *FlagSet) StringArray(name string, value []string, usage string) *[]string { p := []string{} f.StringArrayVarP(&p, name, "", value, usage) return &p } // StringArrayP is like StringArray, but accepts a shorthand letter that can be used after a single dash. func (f *FlagSet) StringArrayP(name, shorthand string, value []string, usage string) *[]string { p := []string{} f.StringArrayVarP(&p, name, shorthand, value, usage) return &p } // StringArray defines a string flag with specified name, default value, and usage string. // The return value is the address of a []string variable that stores the value of the flag. // The value of each argument will not try to be separated by comma. Use a StringSlice for that. func StringArray(name string, value []string, usage string) *[]string { return CommandLine.StringArrayP(name, "", value, usage) } // StringArrayP is like StringArray, but accepts a shorthand letter that can be used after a single dash. func StringArrayP(name, shorthand string, value []string, usage string) *[]string { return CommandLine.StringArrayP(name, shorthand, value, usage) } spf13-pflag-0491e57/string_array_test.go000066400000000000000000000142211505550473500201200ustar00rootroot00000000000000// Copyright 2009 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. package pflag import ( "fmt" "testing" ) func setUpSAFlagSet(sap *[]string) *FlagSet { f := NewFlagSet("test", ContinueOnError) f.StringArrayVar(sap, "sa", []string{}, "Command separated list!") return f } func setUpSAFlagSetWithDefault(sap *[]string) *FlagSet { f := NewFlagSet("test", ContinueOnError) f.StringArrayVar(sap, "sa", []string{"default", "values"}, "Command separated list!") return f } func TestEmptySA(t *testing.T) { var sa []string f := setUpSAFlagSet(&sa) err := f.Parse([]string{}) if err != nil { t.Fatal("expected no error; got", err) } getSA, err := f.GetStringArray("sa") if err != nil { t.Fatal("got an error from GetStringArray():", err) } if len(getSA) != 0 { t.Fatalf("got sa %v with len=%d but expected length=0", getSA, len(getSA)) } } func TestEmptySAValue(t *testing.T) { var sa []string f := setUpSAFlagSet(&sa) err := f.Parse([]string{"--sa="}) if err != nil { t.Fatal("expected no error; got", err) } getSA, err := f.GetStringArray("sa") if err != nil { t.Fatal("got an error from GetStringArray():", err) } if len(getSA) != 0 { t.Fatalf("got sa %v with len=%d but expected length=0", getSA, len(getSA)) } } func TestSADefault(t *testing.T) { var sa []string f := setUpSAFlagSetWithDefault(&sa) vals := []string{"default", "values"} err := f.Parse([]string{}) if err != nil { t.Fatal("expected no error; got", err) } for i, v := range sa { if vals[i] != v { t.Fatalf("expected sa[%d] to be %s but got: %s", i, vals[i], v) } } getSA, err := f.GetStringArray("sa") if err != nil { t.Fatal("got an error from GetStringArray():", err) } for i, v := range getSA { if vals[i] != v { t.Fatalf("expected sa[%d] to be %s from GetStringArray but got: %s", i, vals[i], v) } } } func TestSAWithDefault(t *testing.T) { var sa []string f := setUpSAFlagSetWithDefault(&sa) val := "one" arg := fmt.Sprintf("--sa=%s", val) err := f.Parse([]string{arg}) if err != nil { t.Fatal("expected no error; got", err) } if len(sa) != 1 { t.Fatalf("expected number of values to be %d but %d", 1, len(sa)) } if sa[0] != val { t.Fatalf("expected value to be %s but got: %s", sa[0], val) } getSA, err := f.GetStringArray("sa") if err != nil { t.Fatal("got an error from GetStringArray():", err) } if len(getSA) != 1 { t.Fatalf("expected number of values to be %d but %d", 1, len(getSA)) } if getSA[0] != val { t.Fatalf("expected value to be %s but got: %s", getSA[0], val) } } func TestSACalledTwice(t *testing.T) { var sa []string f := setUpSAFlagSet(&sa) in := []string{"one", "two"} expected := []string{"one", "two"} argfmt := "--sa=%s" arg1 := fmt.Sprintf(argfmt, in[0]) arg2 := fmt.Sprintf(argfmt, in[1]) err := f.Parse([]string{arg1, arg2}) if err != nil { t.Fatal("expected no error; got", err) } if len(expected) != len(sa) { t.Fatalf("expected number of sa to be %d but got: %d", len(expected), len(sa)) } for i, v := range sa { if expected[i] != v { t.Fatalf("expected sa[%d] to be %s but got: %s", i, expected[i], v) } } values, err := f.GetStringArray("sa") if err != nil { t.Fatal("expected no error; got", err) } if len(expected) != len(values) { t.Fatalf("expected number of values to be %d but got: %d", len(expected), len(sa)) } for i, v := range values { if expected[i] != v { t.Fatalf("expected got sa[%d] to be %s but got: %s", i, expected[i], v) } } } func TestSAWithSpecialChar(t *testing.T) { var sa []string f := setUpSAFlagSet(&sa) in := []string{"one,two", `"three"`, `"four,five",six`, "seven eight"} expected := []string{"one,two", `"three"`, `"four,five",six`, "seven eight"} argfmt := "--sa=%s" arg1 := fmt.Sprintf(argfmt, in[0]) arg2 := fmt.Sprintf(argfmt, in[1]) arg3 := fmt.Sprintf(argfmt, in[2]) arg4 := fmt.Sprintf(argfmt, in[3]) err := f.Parse([]string{arg1, arg2, arg3, arg4}) if err != nil { t.Fatal("expected no error; got", err) } if len(expected) != len(sa) { t.Fatalf("expected number of sa to be %d but got: %d", len(expected), len(sa)) } for i, v := range sa { if expected[i] != v { t.Fatalf("expected sa[%d] to be %s but got: %s", i, expected[i], v) } } values, err := f.GetStringArray("sa") if err != nil { t.Fatal("expected no error; got", err) } if len(expected) != len(values) { t.Fatalf("expected number of values to be %d but got: %d", len(expected), len(values)) } for i, v := range values { if expected[i] != v { t.Fatalf("expected got sa[%d] to be %s but got: %s", i, expected[i], v) } } } func TestSAAsSliceValue(t *testing.T) { var sa []string f := setUpSAFlagSet(&sa) in := []string{"1ns", "2ns"} argfmt := "--sa=%s" arg1 := fmt.Sprintf(argfmt, in[0]) arg2 := fmt.Sprintf(argfmt, in[1]) err := f.Parse([]string{arg1, arg2}) if err != nil { t.Fatal("expected no error; got", err) } f.VisitAll(func(f *Flag) { if val, ok := f.Value.(SliceValue); ok { _ = val.Replace([]string{"3ns"}) } }) if len(sa) != 1 || sa[0] != "3ns" { t.Fatalf("Expected ss to be overwritten with '3ns', but got: %v", sa) } } func TestSAWithSquareBrackets(t *testing.T) { var sa []string f := setUpSAFlagSet(&sa) in := []string{"][]-[", "[a-z]", "[a-z]+"} expected := []string{"][]-[", "[a-z]", "[a-z]+"} argfmt := "--sa=%s" arg1 := fmt.Sprintf(argfmt, in[0]) arg2 := fmt.Sprintf(argfmt, in[1]) arg3 := fmt.Sprintf(argfmt, in[2]) err := f.Parse([]string{arg1, arg2, arg3}) if err != nil { t.Fatal("expected no error; got", err) } if len(expected) != len(sa) { t.Fatalf("expected number of sa to be %d but got: %d", len(expected), len(sa)) } for i, v := range sa { if expected[i] != v { t.Fatalf("expected sa[%d] to be %s but got: %s", i, expected[i], v) } } values, err := f.GetStringArray("sa") if err != nil { t.Fatal("expected no error; got", err) } if len(expected) != len(values) { t.Fatalf("expected number of values to be %d but got: %d", len(expected), len(values)) } for i, v := range values { if expected[i] != v { t.Fatalf("expected got sa[%d] to be %s but got: %s", i, expected[i], v) } } } spf13-pflag-0491e57/string_slice.go000066400000000000000000000120631505550473500170440ustar00rootroot00000000000000package pflag import ( "bytes" "encoding/csv" "strings" ) // -- stringSlice Value type stringSliceValue struct { value *[]string changed bool } func newStringSliceValue(val []string, p *[]string) *stringSliceValue { ssv := new(stringSliceValue) ssv.value = p *ssv.value = val return ssv } func readAsCSV(val string) ([]string, error) { if val == "" { return []string{}, nil } stringReader := strings.NewReader(val) csvReader := csv.NewReader(stringReader) return csvReader.Read() } func writeAsCSV(vals []string) (string, error) { b := &bytes.Buffer{} w := csv.NewWriter(b) err := w.Write(vals) if err != nil { return "", err } w.Flush() return strings.TrimSuffix(b.String(), "\n"), nil } func (s *stringSliceValue) Set(val string) error { v, err := readAsCSV(val) if err != nil { return err } if !s.changed { *s.value = v } else { *s.value = append(*s.value, v...) } s.changed = true return nil } func (s *stringSliceValue) Type() string { return "stringSlice" } func (s *stringSliceValue) String() string { str, _ := writeAsCSV(*s.value) return "[" + str + "]" } func (s *stringSliceValue) Append(val string) error { *s.value = append(*s.value, val) return nil } func (s *stringSliceValue) Replace(val []string) error { *s.value = val return nil } func (s *stringSliceValue) GetSlice() []string { return *s.value } func stringSliceConv(sval string) (interface{}, error) { sval = sval[1 : len(sval)-1] // An empty string would cause a slice with one (empty) string if len(sval) == 0 { return []string{}, nil } return readAsCSV(sval) } // GetStringSlice return the []string value of a flag with the given name func (f *FlagSet) GetStringSlice(name string) ([]string, error) { val, err := f.getFlagType(name, "stringSlice", stringSliceConv) if err != nil { return []string{}, err } return val.([]string), nil } // StringSliceVar defines a string flag with specified name, default value, and usage string. // 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" // will result in // []string{"v1", "v2", "v3"} func (f *FlagSet) StringSliceVar(p *[]string, name string, value []string, usage string) { f.VarP(newStringSliceValue(value, p), name, "", usage) } // StringSliceVarP is like StringSliceVar, but accepts a shorthand letter that can be used after a single dash. func (f *FlagSet) StringSliceVarP(p *[]string, name, shorthand string, value []string, usage string) { f.VarP(newStringSliceValue(value, p), name, shorthand, usage) } // StringSliceVar defines a string flag with specified name, default value, and usage string. // 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" // will result in // []string{"v1", "v2", "v3"} func StringSliceVar(p *[]string, name string, value []string, usage string) { CommandLine.VarP(newStringSliceValue(value, p), name, "", usage) } // StringSliceVarP is like StringSliceVar, but accepts a shorthand letter that can be used after a single dash. func StringSliceVarP(p *[]string, name, shorthand string, value []string, usage string) { CommandLine.VarP(newStringSliceValue(value, p), name, shorthand, usage) } // StringSlice defines a string flag with specified name, default value, and usage string. // 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" // will result in // []string{"v1", "v2", "v3"} func (f *FlagSet) StringSlice(name string, value []string, usage string) *[]string { p := []string{} f.StringSliceVarP(&p, name, "", value, usage) return &p } // StringSliceP is like StringSlice, but accepts a shorthand letter that can be used after a single dash. func (f *FlagSet) StringSliceP(name, shorthand string, value []string, usage string) *[]string { p := []string{} f.StringSliceVarP(&p, name, shorthand, value, usage) return &p } // StringSlice defines a string flag with specified name, default value, and usage string. // 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" // will result in // []string{"v1", "v2", "v3"} func StringSlice(name string, value []string, usage string) *[]string { return CommandLine.StringSliceP(name, "", value, usage) } // StringSliceP is like StringSlice, but accepts a shorthand letter that can be used after a single dash. func StringSliceP(name, shorthand string, value []string, usage string) *[]string { return CommandLine.StringSliceP(name, shorthand, value, usage) } spf13-pflag-0491e57/string_slice_test.go000066400000000000000000000151601505550473500201040ustar00rootroot00000000000000// Copyright 2009 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. package pflag import ( "fmt" "strings" "testing" ) func setUpSSFlagSet(ssp *[]string) *FlagSet { f := NewFlagSet("test", ContinueOnError) f.StringSliceVar(ssp, "ss", []string{}, "Command separated list!") return f } func setUpSSFlagSetWithDefault(ssp *[]string) *FlagSet { f := NewFlagSet("test", ContinueOnError) f.StringSliceVar(ssp, "ss", []string{"default", "values"}, "Command separated list!") return f } func TestEmptySS(t *testing.T) { var ss []string f := setUpSSFlagSet(&ss) err := f.Parse([]string{}) if err != nil { t.Fatal("expected no error; got", err) } getSS, err := f.GetStringSlice("ss") if err != nil { t.Fatal("got an error from GetStringSlice():", err) } if len(getSS) != 0 { t.Fatalf("got ss %v with len=%d but expected length=0", getSS, len(getSS)) } } func TestEmptySSValue(t *testing.T) { var ss []string f := setUpSSFlagSet(&ss) err := f.Parse([]string{"--ss="}) if err != nil { t.Fatal("expected no error; got", err) } getSS, err := f.GetStringSlice("ss") if err != nil { t.Fatal("got an error from GetStringSlice():", err) } if len(getSS) != 0 { t.Fatalf("got ss %v with len=%d but expected length=0", getSS, len(getSS)) } } func TestSS(t *testing.T) { var ss []string f := setUpSSFlagSet(&ss) vals := []string{"one", "two", "4", "3"} arg := fmt.Sprintf("--ss=%s", strings.Join(vals, ",")) err := f.Parse([]string{arg}) if err != nil { t.Fatal("expected no error; got", err) } for i, v := range ss { if vals[i] != v { t.Fatalf("expected ss[%d] to be %s but got: %s", i, vals[i], v) } } getSS, err := f.GetStringSlice("ss") if err != nil { t.Fatal("got an error from GetStringSlice():", err) } for i, v := range getSS { if vals[i] != v { t.Fatalf("expected ss[%d] to be %s from GetStringSlice but got: %s", i, vals[i], v) } } } func TestSSDefault(t *testing.T) { var ss []string f := setUpSSFlagSetWithDefault(&ss) vals := []string{"default", "values"} err := f.Parse([]string{}) if err != nil { t.Fatal("expected no error; got", err) } for i, v := range ss { if vals[i] != v { t.Fatalf("expected ss[%d] to be %s but got: %s", i, vals[i], v) } } getSS, err := f.GetStringSlice("ss") if err != nil { t.Fatal("got an error from GetStringSlice():", err) } for i, v := range getSS { if vals[i] != v { t.Fatalf("expected ss[%d] to be %s from GetStringSlice but got: %s", i, vals[i], v) } } } func TestSSWithDefault(t *testing.T) { var ss []string f := setUpSSFlagSetWithDefault(&ss) vals := []string{"one", "two", "4", "3"} arg := fmt.Sprintf("--ss=%s", strings.Join(vals, ",")) err := f.Parse([]string{arg}) if err != nil { t.Fatal("expected no error; got", err) } for i, v := range ss { if vals[i] != v { t.Fatalf("expected ss[%d] to be %s but got: %s", i, vals[i], v) } } getSS, err := f.GetStringSlice("ss") if err != nil { t.Fatal("got an error from GetStringSlice():", err) } for i, v := range getSS { if vals[i] != v { t.Fatalf("expected ss[%d] to be %s from GetStringSlice but got: %s", i, vals[i], v) } } } func TestSSCalledTwice(t *testing.T) { var ss []string f := setUpSSFlagSet(&ss) in := []string{"one,two", "three"} expected := []string{"one", "two", "three"} argfmt := "--ss=%s" arg1 := fmt.Sprintf(argfmt, in[0]) arg2 := fmt.Sprintf(argfmt, in[1]) err := f.Parse([]string{arg1, arg2}) if err != nil { t.Fatal("expected no error; got", err) } if len(expected) != len(ss) { t.Fatalf("expected number of ss to be %d but got: %d", len(expected), len(ss)) } for i, v := range ss { if expected[i] != v { t.Fatalf("expected ss[%d] to be %s but got: %s", i, expected[i], v) } } values, err := f.GetStringSlice("ss") if err != nil { t.Fatal("expected no error; got", err) } if len(expected) != len(values) { t.Fatalf("expected number of values to be %d but got: %d", len(expected), len(ss)) } for i, v := range values { if expected[i] != v { t.Fatalf("expected got ss[%d] to be %s but got: %s", i, expected[i], v) } } } func TestSSWithComma(t *testing.T) { var ss []string f := setUpSSFlagSet(&ss) in := []string{`"one,two"`, `"three"`, `"four,five",six`} expected := []string{"one,two", "three", "four,five", "six"} argfmt := "--ss=%s" arg1 := fmt.Sprintf(argfmt, in[0]) arg2 := fmt.Sprintf(argfmt, in[1]) arg3 := fmt.Sprintf(argfmt, in[2]) err := f.Parse([]string{arg1, arg2, arg3}) if err != nil { t.Fatal("expected no error; got", err) } if len(expected) != len(ss) { t.Fatalf("expected number of ss to be %d but got: %d", len(expected), len(ss)) } for i, v := range ss { if expected[i] != v { t.Fatalf("expected ss[%d] to be %s but got: %s", i, expected[i], v) } } values, err := f.GetStringSlice("ss") if err != nil { t.Fatal("expected no error; got", err) } if len(expected) != len(values) { t.Fatalf("expected number of values to be %d but got: %d", len(expected), len(values)) } for i, v := range values { if expected[i] != v { t.Fatalf("expected got ss[%d] to be %s but got: %s", i, expected[i], v) } } } func TestSSWithSquareBrackets(t *testing.T) { var ss []string f := setUpSSFlagSet(&ss) in := []string{`"[a-z]"`, `"[a-z]+"`} expected := []string{"[a-z]", "[a-z]+"} argfmt := "--ss=%s" arg1 := fmt.Sprintf(argfmt, in[0]) arg2 := fmt.Sprintf(argfmt, in[1]) err := f.Parse([]string{arg1, arg2}) if err != nil { t.Fatal("expected no error; got", err) } if len(expected) != len(ss) { t.Fatalf("expected number of ss to be %d but got: %d", len(expected), len(ss)) } for i, v := range ss { if expected[i] != v { t.Fatalf("expected ss[%d] to be %s but got: %s", i, expected[i], v) } } values, err := f.GetStringSlice("ss") if err != nil { t.Fatal("expected no error; got", err) } if len(expected) != len(values) { t.Fatalf("expected number of values to be %d but got: %d", len(expected), len(values)) } for i, v := range values { if expected[i] != v { t.Fatalf("expected got ss[%d] to be %s but got: %s", i, expected[i], v) } } } func TestSSAsSliceValue(t *testing.T) { var ss []string f := setUpSSFlagSet(&ss) in := []string{"one", "two"} argfmt := "--ss=%s" arg1 := fmt.Sprintf(argfmt, in[0]) arg2 := fmt.Sprintf(argfmt, in[1]) err := f.Parse([]string{arg1, arg2}) if err != nil { t.Fatal("expected no error; got", err) } f.VisitAll(func(f *Flag) { if val, ok := f.Value.(SliceValue); ok { _ = val.Replace([]string{"three"}) } }) if len(ss) != 1 || ss[0] != "three" { t.Fatalf("Expected ss to be overwritten with 'three', but got: %s", ss) } } spf13-pflag-0491e57/string_to_int.go000066400000000000000000000113701505550473500172410ustar00rootroot00000000000000package pflag import ( "bytes" "fmt" "strconv" "strings" ) // -- stringToInt Value type stringToIntValue struct { value *map[string]int changed bool } func newStringToIntValue(val map[string]int, p *map[string]int) *stringToIntValue { ssv := new(stringToIntValue) ssv.value = p *ssv.value = val return ssv } // Format: a=1,b=2 func (s *stringToIntValue) Set(val string) error { ss := strings.Split(val, ",") out := make(map[string]int, len(ss)) for _, pair := range ss { kv := strings.SplitN(pair, "=", 2) if len(kv) != 2 { return fmt.Errorf("%s must be formatted as key=value", pair) } var err error out[kv[0]], err = strconv.Atoi(kv[1]) if err != nil { return err } } if !s.changed { *s.value = out } else { for k, v := range out { (*s.value)[k] = v } } s.changed = true return nil } func (s *stringToIntValue) Type() string { return "stringToInt" } func (s *stringToIntValue) String() string { var buf bytes.Buffer i := 0 for k, v := range *s.value { if i > 0 { buf.WriteRune(',') } buf.WriteString(k) buf.WriteRune('=') buf.WriteString(strconv.Itoa(v)) i++ } return "[" + buf.String() + "]" } func stringToIntConv(val string) (interface{}, error) { val = strings.Trim(val, "[]") // An empty string would cause an empty map if len(val) == 0 { return map[string]int{}, nil } ss := strings.Split(val, ",") out := make(map[string]int, 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) } var err error out[kv[0]], err = strconv.Atoi(kv[1]) if err != nil { return nil, err } } return out, nil } // GetStringToInt return the map[string]int value of a flag with the given name func (f *FlagSet) GetStringToInt(name string) (map[string]int, error) { val, err := f.getFlagType(name, "stringToInt", stringToIntConv) if err != nil { return map[string]int{}, err } return val.(map[string]int), nil } // StringToIntVar defines a string flag with specified name, default value, and usage string. // The argument p points to a map[string]int 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) StringToIntVar(p *map[string]int, name string, value map[string]int, usage string) { f.VarP(newStringToIntValue(value, p), name, "", usage) } // StringToIntVarP is like StringToIntVar, but accepts a shorthand letter that can be used after a single dash. func (f *FlagSet) StringToIntVarP(p *map[string]int, name, shorthand string, value map[string]int, usage string) { f.VarP(newStringToIntValue(value, p), name, shorthand, usage) } // StringToIntVar defines a string flag with specified name, default value, and usage string. // The argument p points to a map[string]int variable in which to store the value of the flag. // The value of each argument will not try to be separated by comma func StringToIntVar(p *map[string]int, name string, value map[string]int, usage string) { CommandLine.VarP(newStringToIntValue(value, p), name, "", usage) } // StringToIntVarP is like StringToIntVar, but accepts a shorthand letter that can be used after a single dash. func StringToIntVarP(p *map[string]int, name, shorthand string, value map[string]int, usage string) { CommandLine.VarP(newStringToIntValue(value, p), name, shorthand, usage) } // StringToInt defines a string flag with specified name, default value, and usage string. // The return value is the address of a map[string]int variable that stores the value of the flag. // The value of each argument will not try to be separated by comma func (f *FlagSet) StringToInt(name string, value map[string]int, usage string) *map[string]int { p := map[string]int{} f.StringToIntVarP(&p, name, "", value, usage) return &p } // StringToIntP is like StringToInt, but accepts a shorthand letter that can be used after a single dash. func (f *FlagSet) StringToIntP(name, shorthand string, value map[string]int, usage string) *map[string]int { p := map[string]int{} f.StringToIntVarP(&p, name, shorthand, value, usage) return &p } // StringToInt defines a string flag with specified name, default value, and usage string. // The return value is the address of a map[string]int variable that stores the value of the flag. // The value of each argument will not try to be separated by comma func StringToInt(name string, value map[string]int, usage string) *map[string]int { return CommandLine.StringToIntP(name, "", value, usage) } // StringToIntP is like StringToInt, but accepts a shorthand letter that can be used after a single dash. func StringToIntP(name, shorthand string, value map[string]int, usage string) *map[string]int { return CommandLine.StringToIntP(name, shorthand, value, usage) } spf13-pflag-0491e57/string_to_int64.go000066400000000000000000000116611505550473500174160ustar00rootroot00000000000000package pflag import ( "bytes" "fmt" "strconv" "strings" ) // -- stringToInt64 Value type stringToInt64Value struct { value *map[string]int64 changed bool } func newStringToInt64Value(val map[string]int64, p *map[string]int64) *stringToInt64Value { ssv := new(stringToInt64Value) ssv.value = p *ssv.value = val return ssv } // Format: a=1,b=2 func (s *stringToInt64Value) Set(val string) error { ss := strings.Split(val, ",") out := make(map[string]int64, len(ss)) for _, pair := range ss { kv := strings.SplitN(pair, "=", 2) if len(kv) != 2 { return fmt.Errorf("%s must be formatted as key=value", pair) } var err error out[kv[0]], err = strconv.ParseInt(kv[1], 10, 64) if err != nil { return err } } if !s.changed { *s.value = out } else { for k, v := range out { (*s.value)[k] = v } } s.changed = true return nil } func (s *stringToInt64Value) Type() string { return "stringToInt64" } func (s *stringToInt64Value) String() string { var buf bytes.Buffer i := 0 for k, v := range *s.value { if i > 0 { buf.WriteRune(',') } buf.WriteString(k) buf.WriteRune('=') buf.WriteString(strconv.FormatInt(v, 10)) i++ } return "[" + buf.String() + "]" } func stringToInt64Conv(val string) (interface{}, error) { val = strings.Trim(val, "[]") // An empty string would cause an empty map if len(val) == 0 { return map[string]int64{}, nil } ss := strings.Split(val, ",") out := make(map[string]int64, 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) } var err error out[kv[0]], err = strconv.ParseInt(kv[1], 10, 64) if err != nil { return nil, err } } return out, nil } // GetStringToInt64 return the map[string]int64 value of a flag with the given name func (f *FlagSet) GetStringToInt64(name string) (map[string]int64, error) { val, err := f.getFlagType(name, "stringToInt64", stringToInt64Conv) if err != nil { return map[string]int64{}, err } return val.(map[string]int64), nil } // StringToInt64Var defines a string flag with specified name, default value, and usage string. // The argument p point64s to a map[string]int64 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) StringToInt64Var(p *map[string]int64, name string, value map[string]int64, usage string) { f.VarP(newStringToInt64Value(value, p), name, "", usage) } // StringToInt64VarP is like StringToInt64Var, but accepts a shorthand letter that can be used after a single dash. func (f *FlagSet) StringToInt64VarP(p *map[string]int64, name, shorthand string, value map[string]int64, usage string) { f.VarP(newStringToInt64Value(value, p), name, shorthand, usage) } // StringToInt64Var defines a string flag with specified name, default value, and usage string. // The argument p point64s to a map[string]int64 variable in which to store the value of the flag. // The value of each argument will not try to be separated by comma func StringToInt64Var(p *map[string]int64, name string, value map[string]int64, usage string) { CommandLine.VarP(newStringToInt64Value(value, p), name, "", usage) } // StringToInt64VarP is like StringToInt64Var, but accepts a shorthand letter that can be used after a single dash. func StringToInt64VarP(p *map[string]int64, name, shorthand string, value map[string]int64, usage string) { CommandLine.VarP(newStringToInt64Value(value, p), name, shorthand, usage) } // StringToInt64 defines a string flag with specified name, default value, and usage string. // The return value is the address of a map[string]int64 variable that stores the value of the flag. // The value of each argument will not try to be separated by comma func (f *FlagSet) StringToInt64(name string, value map[string]int64, usage string) *map[string]int64 { p := map[string]int64{} f.StringToInt64VarP(&p, name, "", value, usage) return &p } // StringToInt64P is like StringToInt64, but accepts a shorthand letter that can be used after a single dash. func (f *FlagSet) StringToInt64P(name, shorthand string, value map[string]int64, usage string) *map[string]int64 { p := map[string]int64{} f.StringToInt64VarP(&p, name, shorthand, value, usage) return &p } // StringToInt64 defines a string flag with specified name, default value, and usage string. // The return value is the address of a map[string]int64 variable that stores the value of the flag. // The value of each argument will not try to be separated by comma func StringToInt64(name string, value map[string]int64, usage string) *map[string]int64 { return CommandLine.StringToInt64P(name, "", value, usage) } // StringToInt64P is like StringToInt64, but accepts a shorthand letter that can be used after a single dash. func StringToInt64P(name, shorthand string, value map[string]int64, usage string) *map[string]int64 { return CommandLine.StringToInt64P(name, shorthand, value, usage) } spf13-pflag-0491e57/string_to_int64_test.go000066400000000000000000000073111505550473500204520ustar00rootroot00000000000000// Copyright 2009 The Go Authors. All rights reserved. // Use of ths2i source code s2i governed by a BSD-style // license that can be found in the LICENSE file. package pflag import ( "bytes" "fmt" "strconv" "testing" ) func setUpS2I64FlagSet(s2ip *map[string]int64) *FlagSet { f := NewFlagSet("test", ContinueOnError) f.StringToInt64Var(s2ip, "s2i", map[string]int64{}, "Command separated ls2it!") return f } func setUpS2I64FlagSetWithDefault(s2ip *map[string]int64) *FlagSet { f := NewFlagSet("test", ContinueOnError) f.StringToInt64Var(s2ip, "s2i", map[string]int64{"a": 1, "b": 2}, "Command separated ls2it!") return f } func createS2I64Flag(vals map[string]int64) string { var buf bytes.Buffer i := 0 for k, v := range vals { if i > 0 { buf.WriteRune(',') } buf.WriteString(k) buf.WriteRune('=') buf.WriteString(strconv.FormatInt(v, 10)) i++ } return buf.String() } func TestEmptyS2I64(t *testing.T) { var s2i map[string]int64 f := setUpS2I64FlagSet(&s2i) err := f.Parse([]string{}) if err != nil { t.Fatal("expected no error; got", err) } getS2I, err := f.GetStringToInt64("s2i") if err != nil { t.Fatal("got an error from GetStringToInt64():", err) } if len(getS2I) != 0 { t.Fatalf("got s2i %v with len=%d but expected length=0", getS2I, len(getS2I)) } } func TestS2I64(t *testing.T) { var s2i map[string]int64 f := setUpS2I64FlagSet(&s2i) vals := map[string]int64{"a": 1, "b": 2, "d": 4, "c": 3} arg := fmt.Sprintf("--s2i=%s", createS2I64Flag(vals)) err := f.Parse([]string{arg}) if err != nil { t.Fatal("expected no error; got", err) } for k, v := range s2i { if vals[k] != v { t.Fatalf("expected s2i[%s] to be %d but got: %d", k, vals[k], v) } } getS2I, err := f.GetStringToInt64("s2i") if err != nil { t.Fatalf("got error: %v", err) } for k, v := range getS2I { if vals[k] != v { t.Fatalf("expected s2i[%s] to be %d but got: %d from GetStringToInt64", k, vals[k], v) } } } func TestS2I64Default(t *testing.T) { var s2i map[string]int64 f := setUpS2I64FlagSetWithDefault(&s2i) vals := map[string]int64{"a": 1, "b": 2} err := f.Parse([]string{}) if err != nil { t.Fatal("expected no error; got", err) } for k, v := range s2i { if vals[k] != v { t.Fatalf("expected s2i[%s] to be %d but got: %d", k, vals[k], v) } } getS2I, err := f.GetStringToInt64("s2i") if err != nil { t.Fatal("got an error from GetStringToInt64():", err) } for k, v := range getS2I { if vals[k] != v { t.Fatalf("expected s2i[%s] to be %d from GetStringToInt64 but got: %d", k, vals[k], v) } } } func TestS2I64WithDefault(t *testing.T) { var s2i map[string]int64 f := setUpS2I64FlagSetWithDefault(&s2i) vals := map[string]int64{"a": 1, "b": 2} arg := fmt.Sprintf("--s2i=%s", createS2I64Flag(vals)) err := f.Parse([]string{arg}) if err != nil { t.Fatal("expected no error; got", err) } for k, v := range s2i { if vals[k] != v { t.Fatalf("expected s2i[%s] to be %d but got: %d", k, vals[k], v) } } getS2I, err := f.GetStringToInt64("s2i") if err != nil { t.Fatal("got an error from GetStringToInt64():", err) } for k, v := range getS2I { if vals[k] != v { t.Fatalf("expected s2i[%s] to be %d from GetStringToInt64 but got: %d", k, vals[k], v) } } } func TestS2I64CalledTwice(t *testing.T) { var s2i map[string]int64 f := setUpS2I64FlagSet(&s2i) in := []string{"a=1,b=2", "b=3"} expected := map[string]int64{"a": 1, "b": 3} argfmt := "--s2i=%s" arg1 := fmt.Sprintf(argfmt, in[0]) arg2 := fmt.Sprintf(argfmt, in[1]) err := f.Parse([]string{arg1, arg2}) if err != nil { t.Fatal("expected no error; got", err) } for i, v := range s2i { if expected[i] != v { t.Fatalf("expected s2i[%s] to be %d but got: %d", i, expected[i], v) } } } spf13-pflag-0491e57/string_to_int_test.go000066400000000000000000000071561505550473500203070ustar00rootroot00000000000000// Copyright 2009 The Go Authors. All rights reserved. // Use of ths2i source code s2i governed by a BSD-style // license that can be found in the LICENSE file. package pflag import ( "bytes" "fmt" "strconv" "testing" ) func setUpS2IFlagSet(s2ip *map[string]int) *FlagSet { f := NewFlagSet("test", ContinueOnError) f.StringToIntVar(s2ip, "s2i", map[string]int{}, "Command separated ls2it!") return f } func setUpS2IFlagSetWithDefault(s2ip *map[string]int) *FlagSet { f := NewFlagSet("test", ContinueOnError) f.StringToIntVar(s2ip, "s2i", map[string]int{"a": 1, "b": 2}, "Command separated ls2it!") return f } func createS2IFlag(vals map[string]int) string { var buf bytes.Buffer i := 0 for k, v := range vals { if i > 0 { buf.WriteRune(',') } buf.WriteString(k) buf.WriteRune('=') buf.WriteString(strconv.Itoa(v)) i++ } return buf.String() } func TestEmptyS2I(t *testing.T) { var s2i map[string]int f := setUpS2IFlagSet(&s2i) err := f.Parse([]string{}) if err != nil { t.Fatal("expected no error; got", err) } getS2I, err := f.GetStringToInt("s2i") if err != nil { t.Fatal("got an error from GetStringToInt():", err) } if len(getS2I) != 0 { t.Fatalf("got s2i %v with len=%d but expected length=0", getS2I, len(getS2I)) } } func TestS2I(t *testing.T) { var s2i map[string]int f := setUpS2IFlagSet(&s2i) vals := map[string]int{"a": 1, "b": 2, "d": 4, "c": 3} arg := fmt.Sprintf("--s2i=%s", createS2IFlag(vals)) err := f.Parse([]string{arg}) if err != nil { t.Fatal("expected no error; got", err) } for k, v := range s2i { if vals[k] != v { t.Fatalf("expected s2i[%s] to be %d but got: %d", k, vals[k], v) } } getS2I, err := f.GetStringToInt("s2i") if err != nil { t.Fatalf("got error: %v", err) } for k, v := range getS2I { if vals[k] != v { t.Fatalf("expected s2i[%s] to be %d but got: %d from GetStringToInt", k, vals[k], v) } } } func TestS2IDefault(t *testing.T) { var s2i map[string]int f := setUpS2IFlagSetWithDefault(&s2i) vals := map[string]int{"a": 1, "b": 2} err := f.Parse([]string{}) if err != nil { t.Fatal("expected no error; got", err) } for k, v := range s2i { if vals[k] != v { t.Fatalf("expected s2i[%s] to be %d but got: %d", k, vals[k], v) } } getS2I, err := f.GetStringToInt("s2i") if err != nil { t.Fatal("got an error from GetStringToInt():", err) } for k, v := range getS2I { if vals[k] != v { t.Fatalf("expected s2i[%s] to be %d from GetStringToInt but got: %d", k, vals[k], v) } } } func TestS2IWithDefault(t *testing.T) { var s2i map[string]int f := setUpS2IFlagSetWithDefault(&s2i) vals := map[string]int{"a": 1, "b": 2} arg := fmt.Sprintf("--s2i=%s", createS2IFlag(vals)) err := f.Parse([]string{arg}) if err != nil { t.Fatal("expected no error; got", err) } for k, v := range s2i { if vals[k] != v { t.Fatalf("expected s2i[%s] to be %d but got: %d", k, vals[k], v) } } getS2I, err := f.GetStringToInt("s2i") if err != nil { t.Fatal("got an error from GetStringToInt():", err) } for k, v := range getS2I { if vals[k] != v { t.Fatalf("expected s2i[%s] to be %d from GetStringToInt but got: %d", k, vals[k], v) } } } func TestS2ICalledTwice(t *testing.T) { var s2i map[string]int f := setUpS2IFlagSet(&s2i) in := []string{"a=1,b=2", "b=3"} expected := map[string]int{"a": 1, "b": 3} argfmt := "--s2i=%s" arg1 := fmt.Sprintf(argfmt, in[0]) arg2 := fmt.Sprintf(argfmt, in[1]) err := f.Parse([]string{arg1, arg2}) if err != nil { t.Fatal("expected no error; got", err) } for i, v := range s2i { if expected[i] != v { t.Fatalf("expected s2i[%s] to be %d but got: %d", i, expected[i], v) } } } spf13-pflag-0491e57/string_to_string.go000066400000000000000000000125771505550473500177670ustar00rootroot00000000000000package pflag import ( "bytes" "encoding/csv" "fmt" "sort" "strings" ) // -- stringToString Value type stringToStringValue struct { value *map[string]string changed bool } func newStringToStringValue(val map[string]string, p *map[string]string) *stringToStringValue { ssv := new(stringToStringValue) ssv.value = p *ssv.value = val return ssv } // Format: a=1,b=2 func (s *stringToStringValue) Set(val string) error { var ss []string n := strings.Count(val, "=") switch n { case 0: return fmt.Errorf("%s must be formatted as key=value", val) case 1: ss = append(ss, strings.Trim(val, `"`)) default: r := csv.NewReader(strings.NewReader(val)) var err error ss, err = r.Read() if err != nil { return err } } out := make(map[string]string, len(ss)) for _, pair := range ss { kv := strings.SplitN(pair, "=", 2) if len(kv) != 2 { return fmt.Errorf("%s must be formatted as key=value", pair) } out[kv[0]] = kv[1] } if !s.changed { *s.value = out } else { for k, v := range out { (*s.value)[k] = v } } s.changed = true return nil } func (s *stringToStringValue) Type() string { return "stringToString" } func (s *stringToStringValue) String() string { keys := make([]string, 0, len(*s.value)) for k := range *s.value { keys = append(keys, k) } sort.Strings(keys) records := make([]string, 0, len(*s.value)>>1) for _, k := range keys { v := (*s.value)[k] records = append(records, k+"="+v) } var buf bytes.Buffer w := csv.NewWriter(&buf) if err := w.Write(records); err != nil { panic(err) } w.Flush() return "[" + strings.TrimSpace(buf.String()) + "]" } 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 func (f *FlagSet) GetStringToString(name string) (map[string]string, error) { val, err := f.getFlagType(name, "stringToString", stringToStringConv) 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) } // 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) } // 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 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. 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 } // 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 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. func StringToStringP(name, shorthand string, value map[string]string, usage string) *map[string]string { return CommandLine.StringToStringP(name, shorthand, value, usage) } spf13-pflag-0491e57/string_to_string_test.go000066400000000000000000000101061505550473500210100ustar00rootroot00000000000000// Copyright 2009 The Go Authors. All rights reserved. // Use of ths2s source code s2s governed by a BSD-style // license that can be found in the LICENSE file. package pflag import ( "bytes" "encoding/csv" "fmt" "strings" "testing" ) func setUpS2SFlagSet(s2sp *map[string]string) *FlagSet { f := NewFlagSet("test", ContinueOnError) f.StringToStringVar(s2sp, "s2s", map[string]string{}, "Command separated ls2st!") return f } func setUpS2SFlagSetWithDefault(s2sp *map[string]string) *FlagSet { f := NewFlagSet("test", ContinueOnError) f.StringToStringVar(s2sp, "s2s", map[string]string{"da": "1", "db": "2", "de": "5,6"}, "Command separated ls2st!") return f } func createS2SFlag(vals map[string]string) string { records := make([]string, 0, len(vals)>>1) for k, v := range vals { records = append(records, k+"="+v) } var buf bytes.Buffer w := csv.NewWriter(&buf) if err := w.Write(records); err != nil { panic(err) } w.Flush() return strings.TrimSpace(buf.String()) } func TestEmptyS2S(t *testing.T) { var s2s map[string]string f := setUpS2SFlagSet(&s2s) err := f.Parse([]string{}) if err != nil { t.Fatal("expected no error; got", err) } getS2S, err := f.GetStringToString("s2s") if err != nil { t.Fatal("got an error from GetStringToString():", err) } if len(getS2S) != 0 { t.Fatalf("got s2s %v with len=%d but expected length=0", getS2S, len(getS2S)) } } func TestS2S(t *testing.T) { var s2s map[string]string f := setUpS2SFlagSet(&s2s) vals := map[string]string{"a": "1", "b": "2", "d": "4", "c": "3", "e": "5,6"} arg := fmt.Sprintf("--s2s=%s", createS2SFlag(vals)) err := f.Parse([]string{arg}) if err != nil { t.Fatal("expected no error; got", err) } for k, v := range s2s { if vals[k] != v { t.Fatalf("expected s2s[%s] to be %s but got: %s", k, vals[k], v) } } getS2S, err := f.GetStringToString("s2s") if err != nil { t.Fatalf("got error: %v", err) } for k, v := range getS2S { if vals[k] != v { t.Fatalf("expected s2s[%s] to be %s but got: %s from GetStringToString", k, vals[k], v) } } } func TestS2SDefault(t *testing.T) { var s2s map[string]string f := setUpS2SFlagSetWithDefault(&s2s) vals := map[string]string{"da": "1", "db": "2", "de": "5,6"} err := f.Parse([]string{}) if err != nil { t.Fatal("expected no error; got", err) } for k, v := range s2s { if vals[k] != v { t.Fatalf("expected s2s[%s] to be %s but got: %s", k, vals[k], v) } } getS2S, err := f.GetStringToString("s2s") if err != nil { t.Fatal("got an error from GetStringToString():", err) } for k, v := range getS2S { if vals[k] != v { t.Fatalf("expected s2s[%s] to be %s from GetStringToString but got: %s", k, vals[k], v) } } } func TestS2SWithDefault(t *testing.T) { var s2s map[string]string f := setUpS2SFlagSetWithDefault(&s2s) vals := map[string]string{"a": "1", "b": "2", "e": "5,6"} arg := fmt.Sprintf("--s2s=%s", createS2SFlag(vals)) err := f.Parse([]string{arg}) if err != nil { t.Fatal("expected no error; got", err) } for k, v := range s2s { if vals[k] != v { t.Fatalf("expected s2s[%s] to be %s but got: %s", k, vals[k], v) } } getS2S, err := f.GetStringToString("s2s") if err != nil { t.Fatal("got an error from GetStringToString():", err) } for k, v := range getS2S { if vals[k] != v { t.Fatalf("expected s2s[%s] to be %s from GetStringToString but got: %s", k, vals[k], v) } } } func TestS2SCalledTwice(t *testing.T) { var s2s map[string]string f := setUpS2SFlagSet(&s2s) in := []string{"a=1,b=2", "b=3", `"e=5,6"`, `f=7,8`} expected := map[string]string{"a": "1", "b": "3", "e": "5,6", "f": "7,8"} argfmt := "--s2s=%s" arg0 := fmt.Sprintf(argfmt, in[0]) arg1 := fmt.Sprintf(argfmt, in[1]) arg2 := fmt.Sprintf(argfmt, in[2]) arg3 := fmt.Sprintf(argfmt, in[3]) err := f.Parse([]string{arg0, arg1, arg2, arg3}) if err != nil { t.Fatal("expected no error; got", err) } if len(s2s) != len(expected) { t.Fatalf("expected %d flags; got %d flags", len(expected), len(s2s)) } for i, v := range s2s { if expected[i] != v { t.Fatalf("expected s2s[%s] to be %s but got: %s", i, expected[i], v) } } } spf13-pflag-0491e57/text.go000066400000000000000000000061601505550473500153440ustar00rootroot00000000000000package pflag import ( "encoding" "fmt" "reflect" ) // following is copied from go 1.23.4 flag.go type textValue struct{ p encoding.TextUnmarshaler } func newTextValue(val encoding.TextMarshaler, p encoding.TextUnmarshaler) textValue { ptrVal := reflect.ValueOf(p) if ptrVal.Kind() != reflect.Ptr { panic("variable value type must be a pointer") } defVal := reflect.ValueOf(val) if defVal.Kind() == reflect.Ptr { defVal = defVal.Elem() } if defVal.Type() != ptrVal.Type().Elem() { panic(fmt.Sprintf("default type does not match variable type: %v != %v", defVal.Type(), ptrVal.Type().Elem())) } ptrVal.Elem().Set(defVal) return textValue{p} } func (v textValue) Set(s string) error { return v.p.UnmarshalText([]byte(s)) } func (v textValue) Get() interface{} { return v.p } func (v textValue) String() string { if m, ok := v.p.(encoding.TextMarshaler); ok { if b, err := m.MarshalText(); err == nil { return string(b) } } return "" } //end of copy func (v textValue) Type() string { return reflect.ValueOf(v.p).Type().Name() } // GetText set out, which implements encoding.UnmarshalText, to the value of a flag with given name func (f *FlagSet) GetText(name string, out encoding.TextUnmarshaler) error { flag := f.Lookup(name) 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()) } return out.UnmarshalText([]byte(flag.Value.String())) } // TextVar defines a flag with a specified name, default value, and usage string. The argument p must be a pointer to a variable that will hold the value of the flag, and p must implement encoding.TextUnmarshaler. If the flag is used, the flag value will be passed to p's UnmarshalText method. The type of the default value must be the same as the type of p. func (f *FlagSet) TextVar(p encoding.TextUnmarshaler, name string, value encoding.TextMarshaler, usage string) { f.VarP(newTextValue(value, p), name, "", usage) } // TextVarP is like TextVar, but accepts a shorthand letter that can be used after a single dash. func (f *FlagSet) TextVarP(p encoding.TextUnmarshaler, name, shorthand string, value encoding.TextMarshaler, usage string) { f.VarP(newTextValue(value, p), name, shorthand, usage) } // TextVar defines a flag with a specified name, default value, and usage string. The argument p must be a pointer to a variable that will hold the value of the flag, and p must implement encoding.TextUnmarshaler. If the flag is used, the flag value will be passed to p's UnmarshalText method. The type of the default value must be the same as the type of p. func TextVar(p encoding.TextUnmarshaler, name string, value encoding.TextMarshaler, usage string) { CommandLine.VarP(newTextValue(value, p), name, "", usage) } // TextVarP is like TextVar, but accepts a shorthand letter that can be used after a single dash. func TextVarP(p encoding.TextUnmarshaler, name, shorthand string, value encoding.TextMarshaler, usage string) { CommandLine.VarP(newTextValue(value, p), name, shorthand, usage) } spf13-pflag-0491e57/text_test.go000066400000000000000000000025231505550473500164020ustar00rootroot00000000000000package pflag import ( "fmt" "os" "testing" "time" ) func setUpTime(t *time.Time) *FlagSet { f := NewFlagSet("test", ContinueOnError) f.TextVar(t, "time", time.Now(), "time stamp") return f } func TestText(t *testing.T) { testCases := []struct { input string success bool expected time.Time }{ {"2003-01-02T15:04:05Z", true, time.Date(2003, 1, 2, 15, 04, 05, 0, time.UTC)}, {"2003-01-02 15:05:01", false, time.Time{}}, //negative case, invalid layout {"2024-11-22T03:01:02Z", true, time.Date(2024, 11, 22, 3, 1, 02, 0, time.UTC)}, {"2006-01-02T15:04:05+07:00", true, time.Date(2006, 1, 2, 15, 4, 5, 0, time.FixedZone("UTC+7", 7*60*60))}, } devnull, _ := os.Open(os.DevNull) os.Stderr = devnull for i := range testCases { var ts time.Time f := setUpTime(&ts) tc := &testCases[i] arg := fmt.Sprintf("--time=%s", tc.input) err := f.Parse([]string{arg}) if err != nil { if tc.success { t.Errorf("expected parsing to succeed, but got %q", err) } continue } if !tc.success { t.Errorf("expected parsing failure, but parsing succeeded") continue } parsedT := new(time.Time) err = f.GetText("time", parsedT) if err != nil { t.Errorf("Got error trying to fetch the time flag: %v", err) } if !parsedT.Equal(tc.expected) { t.Errorf("expected %q, got %q", tc.expected, parsedT) } } } spf13-pflag-0491e57/time.go000066400000000000000000000076421505550473500153240ustar00rootroot00000000000000package pflag import ( "fmt" "strings" "time" ) // TimeValue adapts time.Time for use as a flag. type timeValue struct { *time.Time formats []string } func newTimeValue(val time.Time, p *time.Time, formats []string) *timeValue { *p = val return &timeValue{ Time: p, formats: formats, } } // Set time.Time value from string based on accepted formats. func (d *timeValue) Set(s string) error { s = strings.TrimSpace(s) for _, f := range d.formats { v, err := time.Parse(f, s) if err != nil { continue } *d.Time = v return nil } formatsString := "" for i, f := range d.formats { if i > 0 { formatsString += ", " } formatsString += fmt.Sprintf("`%s`", f) } return fmt.Errorf("invalid time format `%s` must be one of: %s", s, formatsString) } // Type name for time.Time flags. func (d *timeValue) Type() string { return "time" } func (d *timeValue) String() string { if d.Time.IsZero() { return "" } else { return d.Time.Format(time.RFC3339Nano) } } // GetTime return the time value of a flag with the given name func (f *FlagSet) GetTime(name string) (time.Time, error) { flag := f.Lookup(name) if flag == nil { err := fmt.Errorf("flag accessed but not defined: %s", name) return time.Time{}, err } if flag.Value.Type() != "time" { err := fmt.Errorf("trying to get %s value of flag of type %s", "time", flag.Value.Type()) return time.Time{}, err } val, ok := flag.Value.(*timeValue) if !ok { return time.Time{}, fmt.Errorf("value %s is not a time", flag.Value) } return *val.Time, nil } // TimeVar defines a time.Time flag with specified name, default value, and usage string. // The argument p points to a time.Time variable in which to store the value of the flag. func (f *FlagSet) TimeVar(p *time.Time, name string, value time.Time, formats []string, usage string) { f.TimeVarP(p, name, "", value, formats, usage) } // TimeVarP is like TimeVar, but accepts a shorthand letter that can be used after a single dash. func (f *FlagSet) TimeVarP(p *time.Time, name, shorthand string, value time.Time, formats []string, usage string) { f.VarP(newTimeValue(value, p, formats), name, shorthand, usage) } // TimeVar defines a time.Time flag with specified name, default value, and usage string. // The argument p points to a time.Time variable in which to store the value of the flag. func TimeVar(p *time.Time, name string, value time.Time, formats []string, usage string) { CommandLine.TimeVarP(p, name, "", value, formats, usage) } // TimeVarP is like TimeVar, but accepts a shorthand letter that can be used after a single dash. func TimeVarP(p *time.Time, name, shorthand string, value time.Time, formats []string, usage string) { CommandLine.VarP(newTimeValue(value, p, formats), name, shorthand, usage) } // Time defines a time.Time flag with specified name, default value, and usage string. // The return value is the address of a time.Time variable that stores the value of the flag. func (f *FlagSet) Time(name string, value time.Time, formats []string, usage string) *time.Time { return f.TimeP(name, "", value, formats, usage) } // TimeP is like Time, but accepts a shorthand letter that can be used after a single dash. func (f *FlagSet) TimeP(name, shorthand string, value time.Time, formats []string, usage string) *time.Time { p := new(time.Time) f.TimeVarP(p, name, shorthand, value, formats, usage) return p } // Time defines a time.Time flag with specified name, default value, and usage string. // The return value is the address of a time.Time variable that stores the value of the flag. func Time(name string, value time.Time, formats []string, usage string) *time.Time { return CommandLine.TimeP(name, "", value, formats, usage) } // TimeP is like Time, but accepts a shorthand letter that can be used after a single dash. func TimeP(name, shorthand string, value time.Time, formats []string, usage string) *time.Time { return CommandLine.TimeP(name, shorthand, value, formats, usage) } spf13-pflag-0491e57/time_test.go000066400000000000000000000055321505550473500163570ustar00rootroot00000000000000package pflag import ( "fmt" "strings" "testing" "time" ) func setUpTimeVar(t *time.Time, formats []string) *FlagSet { f := NewFlagSet("test", ContinueOnError) f.TimeVar(t, "time", *t, formats, "Time") return f } func TestTime(t *testing.T) { testCases := []struct { input string success bool expected time.Time }{ {"2022-01-01T01:01:01+00:00", true, time.Date(2022, 1, 1, 1, 1, 1, 0, time.UTC)}, {" 2022-01-01T01:01:01+00:00", true, time.Date(2022, 1, 1, 1, 1, 1, 0, time.UTC)}, {"2022-01-01T01:01:01+00:00 ", true, time.Date(2022, 1, 1, 1, 1, 1, 0, time.UTC)}, {"2022-01-01T01:01:01+02:00", true, time.Date(2022, 1, 1, 1, 1, 1, 0, time.FixedZone("UTC+2", 2*60*60))}, {"2022-01-01T01:01:01.01+02:00", true, time.Date(2022, 1, 1, 1, 1, 1, 10000000, time.FixedZone("UTC+2", 2*60*60))}, {"Sat, 01 Jan 2022 01:01:01 +0000", true, time.Date(2022, 1, 1, 1, 1, 1, 0, time.UTC)}, {"Sat, 01 Jan 2022 01:01:01 +0200", true, time.Date(2022, 1, 1, 1, 1, 1, 0, time.FixedZone("UTC+2", 2*60*60))}, {"Sat, 01 Jan 2022 01:01:01 +0000", true, time.Date(2022, 1, 1, 1, 1, 1, 0, time.UTC)}, {"", false, time.Time{}}, {"not a date", false, time.Time{}}, {"2022-01-01 01:01:01", false, time.Time{}}, {"2022-01-01T01:01:01", false, time.Time{}}, {"01 Jan 2022 01:01:01 +0000", false, time.Time{}}, {"Sat, 01 Jan 2022 01:01:01", false, time.Time{}}, } for i := range testCases { var timeVar time.Time formats := []string{time.RFC3339Nano, time.RFC1123Z} f := setUpTimeVar(&timeVar, formats) tc := &testCases[i] arg := fmt.Sprintf("--time=%s", tc.input) err := f.Parse([]string{arg}) if err != nil && tc.success == true { t.Errorf("expected success, got %q", err) continue } else if err == nil && tc.success == false { t.Errorf("expected failure") continue } else if tc.success { timeResult, err := f.GetTime("time") if err != nil { t.Errorf("Got error trying to fetch the Time flag: %v", err) } if !timeResult.Equal(tc.expected) { t.Errorf("expected %q, got %q", tc.expected.Format(time.RFC3339Nano), timeVar.Format(time.RFC3339Nano)) } } } } func usageForTimeFlagSet(t *testing.T, timeVar time.Time) string { t.Helper() formats := []string{time.RFC3339Nano, time.RFC1123Z} f := setUpTimeVar(&timeVar, formats) if err := f.Parse([]string{}); err != nil { t.Fatalf("expected success, got %q", err) } return f.FlagUsages() } func TestTimeDefaultZero(t *testing.T) { usage := usageForTimeFlagSet(t, time.Time{}) if strings.Contains(usage, "default") { t.Errorf("expected no default value in usage, got %q", usage) } } func TestTimeDefaultNonZero(t *testing.T) { timeVar := time.Date(2025, 1, 1, 1, 1, 1, 0, time.UTC) usage := usageForTimeFlagSet(t, timeVar) if !strings.Contains(usage, "default") || !strings.Contains(usage, "2025") { t.Errorf("expected default value in usage, got %q", usage) } } spf13-pflag-0491e57/uint.go000066400000000000000000000055671505550473500153510ustar00rootroot00000000000000package pflag import "strconv" // -- uint Value type uintValue uint func newUintValue(val uint, p *uint) *uintValue { *p = val return (*uintValue)(p) } func (i *uintValue) Set(s string) error { v, err := strconv.ParseUint(s, 0, 64) *i = uintValue(v) return err } func (i *uintValue) Type() string { return "uint" } func (i *uintValue) String() string { return strconv.FormatUint(uint64(*i), 10) } func uintConv(sval string) (interface{}, error) { v, err := strconv.ParseUint(sval, 0, 0) if err != nil { return 0, err } return uint(v), nil } // GetUint return the uint value of a flag with the given name func (f *FlagSet) GetUint(name string) (uint, error) { val, err := f.getFlagType(name, "uint", uintConv) if err != nil { return 0, err } return val.(uint), nil } // UintVar defines a uint flag with specified name, default value, and usage string. // The argument p points to a uint variable in which to store the value of the flag. func (f *FlagSet) UintVar(p *uint, name string, value uint, usage string) { f.VarP(newUintValue(value, p), name, "", usage) } // UintVarP is like UintVar, but accepts a shorthand letter that can be used after a single dash. func (f *FlagSet) UintVarP(p *uint, name, shorthand string, value uint, usage string) { f.VarP(newUintValue(value, p), name, shorthand, usage) } // UintVar defines a uint flag with specified name, default value, and usage string. // The argument p points to a uint variable in which to store the value of the flag. func UintVar(p *uint, name string, value uint, usage string) { CommandLine.VarP(newUintValue(value, p), name, "", usage) } // UintVarP is like UintVar, but accepts a shorthand letter that can be used after a single dash. func UintVarP(p *uint, name, shorthand string, value uint, usage string) { CommandLine.VarP(newUintValue(value, p), name, shorthand, usage) } // Uint defines a uint flag with specified name, default value, and usage string. // The return value is the address of a uint variable that stores the value of the flag. func (f *FlagSet) Uint(name string, value uint, usage string) *uint { p := new(uint) f.UintVarP(p, name, "", value, usage) return p } // UintP is like Uint, but accepts a shorthand letter that can be used after a single dash. func (f *FlagSet) UintP(name, shorthand string, value uint, usage string) *uint { p := new(uint) f.UintVarP(p, name, shorthand, value, usage) return p } // Uint defines a uint flag with specified name, default value, and usage string. // The return value is the address of a uint variable that stores the value of the flag. func Uint(name string, value uint, usage string) *uint { return CommandLine.UintP(name, "", value, usage) } // UintP is like Uint, but accepts a shorthand letter that can be used after a single dash. func UintP(name, shorthand string, value uint, usage string) *uint { return CommandLine.UintP(name, shorthand, value, usage) } spf13-pflag-0491e57/uint16.go000066400000000000000000000060001505550473500154770ustar00rootroot00000000000000package pflag import "strconv" // -- uint16 value type uint16Value uint16 func newUint16Value(val uint16, p *uint16) *uint16Value { *p = val return (*uint16Value)(p) } func (i *uint16Value) Set(s string) error { v, err := strconv.ParseUint(s, 0, 16) *i = uint16Value(v) return err } func (i *uint16Value) Type() string { return "uint16" } func (i *uint16Value) String() string { return strconv.FormatUint(uint64(*i), 10) } func uint16Conv(sval string) (interface{}, error) { v, err := strconv.ParseUint(sval, 0, 16) if err != nil { return 0, err } return uint16(v), nil } // GetUint16 return the uint16 value of a flag with the given name func (f *FlagSet) GetUint16(name string) (uint16, error) { val, err := f.getFlagType(name, "uint16", uint16Conv) if err != nil { return 0, err } return val.(uint16), nil } // Uint16Var defines a uint flag with specified name, default value, and usage string. // The argument p points to a uint variable in which to store the value of the flag. func (f *FlagSet) Uint16Var(p *uint16, name string, value uint16, usage string) { f.VarP(newUint16Value(value, p), name, "", usage) } // Uint16VarP is like Uint16Var, but accepts a shorthand letter that can be used after a single dash. func (f *FlagSet) Uint16VarP(p *uint16, name, shorthand string, value uint16, usage string) { f.VarP(newUint16Value(value, p), name, shorthand, usage) } // Uint16Var defines a uint flag with specified name, default value, and usage string. // The argument p points to a uint variable in which to store the value of the flag. func Uint16Var(p *uint16, name string, value uint16, usage string) { CommandLine.VarP(newUint16Value(value, p), name, "", usage) } // Uint16VarP is like Uint16Var, but accepts a shorthand letter that can be used after a single dash. func Uint16VarP(p *uint16, name, shorthand string, value uint16, usage string) { CommandLine.VarP(newUint16Value(value, p), name, shorthand, usage) } // Uint16 defines a uint flag with specified name, default value, and usage string. // The return value is the address of a uint variable that stores the value of the flag. func (f *FlagSet) Uint16(name string, value uint16, usage string) *uint16 { p := new(uint16) f.Uint16VarP(p, name, "", value, usage) return p } // Uint16P is like Uint16, but accepts a shorthand letter that can be used after a single dash. func (f *FlagSet) Uint16P(name, shorthand string, value uint16, usage string) *uint16 { p := new(uint16) f.Uint16VarP(p, name, shorthand, value, usage) return p } // Uint16 defines a uint flag with specified name, default value, and usage string. // The return value is the address of a uint variable that stores the value of the flag. func Uint16(name string, value uint16, usage string) *uint16 { return CommandLine.Uint16P(name, "", value, usage) } // Uint16P is like Uint16, but accepts a shorthand letter that can be used after a single dash. func Uint16P(name, shorthand string, value uint16, usage string) *uint16 { return CommandLine.Uint16P(name, shorthand, value, usage) } spf13-pflag-0491e57/uint32.go000066400000000000000000000060201505550473500154770ustar00rootroot00000000000000package pflag import "strconv" // -- uint32 value type uint32Value uint32 func newUint32Value(val uint32, p *uint32) *uint32Value { *p = val return (*uint32Value)(p) } func (i *uint32Value) Set(s string) error { v, err := strconv.ParseUint(s, 0, 32) *i = uint32Value(v) return err } func (i *uint32Value) Type() string { return "uint32" } func (i *uint32Value) String() string { return strconv.FormatUint(uint64(*i), 10) } func uint32Conv(sval string) (interface{}, error) { v, err := strconv.ParseUint(sval, 0, 32) if err != nil { return 0, err } return uint32(v), nil } // GetUint32 return the uint32 value of a flag with the given name func (f *FlagSet) GetUint32(name string) (uint32, error) { val, err := f.getFlagType(name, "uint32", uint32Conv) if err != nil { return 0, err } return val.(uint32), nil } // Uint32Var defines a uint32 flag with specified name, default value, and usage string. // The argument p points to a uint32 variable in which to store the value of the flag. func (f *FlagSet) Uint32Var(p *uint32, name string, value uint32, usage string) { f.VarP(newUint32Value(value, p), name, "", usage) } // Uint32VarP is like Uint32Var, but accepts a shorthand letter that can be used after a single dash. func (f *FlagSet) Uint32VarP(p *uint32, name, shorthand string, value uint32, usage string) { f.VarP(newUint32Value(value, p), name, shorthand, usage) } // Uint32Var defines a uint32 flag with specified name, default value, and usage string. // The argument p points to a uint32 variable in which to store the value of the flag. func Uint32Var(p *uint32, name string, value uint32, usage string) { CommandLine.VarP(newUint32Value(value, p), name, "", usage) } // Uint32VarP is like Uint32Var, but accepts a shorthand letter that can be used after a single dash. func Uint32VarP(p *uint32, name, shorthand string, value uint32, usage string) { CommandLine.VarP(newUint32Value(value, p), name, shorthand, usage) } // Uint32 defines a uint32 flag with specified name, default value, and usage string. // The return value is the address of a uint32 variable that stores the value of the flag. func (f *FlagSet) Uint32(name string, value uint32, usage string) *uint32 { p := new(uint32) f.Uint32VarP(p, name, "", value, usage) return p } // Uint32P is like Uint32, but accepts a shorthand letter that can be used after a single dash. func (f *FlagSet) Uint32P(name, shorthand string, value uint32, usage string) *uint32 { p := new(uint32) f.Uint32VarP(p, name, shorthand, value, usage) return p } // Uint32 defines a uint32 flag with specified name, default value, and usage string. // The return value is the address of a uint32 variable that stores the value of the flag. func Uint32(name string, value uint32, usage string) *uint32 { return CommandLine.Uint32P(name, "", value, usage) } // Uint32P is like Uint32, but accepts a shorthand letter that can be used after a single dash. func Uint32P(name, shorthand string, value uint32, usage string) *uint32 { return CommandLine.Uint32P(name, shorthand, value, usage) } spf13-pflag-0491e57/uint64.go000066400000000000000000000060151505550473500155100ustar00rootroot00000000000000package pflag import "strconv" // -- uint64 Value type uint64Value uint64 func newUint64Value(val uint64, p *uint64) *uint64Value { *p = val return (*uint64Value)(p) } func (i *uint64Value) Set(s string) error { v, err := strconv.ParseUint(s, 0, 64) *i = uint64Value(v) return err } func (i *uint64Value) Type() string { return "uint64" } func (i *uint64Value) String() string { return strconv.FormatUint(uint64(*i), 10) } func uint64Conv(sval string) (interface{}, error) { v, err := strconv.ParseUint(sval, 0, 64) if err != nil { return 0, err } return uint64(v), nil } // GetUint64 return the uint64 value of a flag with the given name func (f *FlagSet) GetUint64(name string) (uint64, error) { val, err := f.getFlagType(name, "uint64", uint64Conv) if err != nil { return 0, err } return val.(uint64), nil } // Uint64Var defines a uint64 flag with specified name, default value, and usage string. // The argument p points to a uint64 variable in which to store the value of the flag. func (f *FlagSet) Uint64Var(p *uint64, name string, value uint64, usage string) { f.VarP(newUint64Value(value, p), name, "", usage) } // Uint64VarP is like Uint64Var, but accepts a shorthand letter that can be used after a single dash. func (f *FlagSet) Uint64VarP(p *uint64, name, shorthand string, value uint64, usage string) { f.VarP(newUint64Value(value, p), name, shorthand, usage) } // Uint64Var defines a uint64 flag with specified name, default value, and usage string. // The argument p points to a uint64 variable in which to store the value of the flag. func Uint64Var(p *uint64, name string, value uint64, usage string) { CommandLine.VarP(newUint64Value(value, p), name, "", usage) } // Uint64VarP is like Uint64Var, but accepts a shorthand letter that can be used after a single dash. func Uint64VarP(p *uint64, name, shorthand string, value uint64, usage string) { CommandLine.VarP(newUint64Value(value, p), name, shorthand, usage) } // Uint64 defines a uint64 flag with specified name, default value, and usage string. // The return value is the address of a uint64 variable that stores the value of the flag. func (f *FlagSet) Uint64(name string, value uint64, usage string) *uint64 { p := new(uint64) f.Uint64VarP(p, name, "", value, usage) return p } // Uint64P is like Uint64, but accepts a shorthand letter that can be used after a single dash. func (f *FlagSet) Uint64P(name, shorthand string, value uint64, usage string) *uint64 { p := new(uint64) f.Uint64VarP(p, name, shorthand, value, usage) return p } // Uint64 defines a uint64 flag with specified name, default value, and usage string. // The return value is the address of a uint64 variable that stores the value of the flag. func Uint64(name string, value uint64, usage string) *uint64 { return CommandLine.Uint64P(name, "", value, usage) } // Uint64P is like Uint64, but accepts a shorthand letter that can be used after a single dash. func Uint64P(name, shorthand string, value uint64, usage string) *uint64 { return CommandLine.Uint64P(name, shorthand, value, usage) } spf13-pflag-0491e57/uint8.go000066400000000000000000000056771505550473500154430ustar00rootroot00000000000000package pflag import "strconv" // -- uint8 Value type uint8Value uint8 func newUint8Value(val uint8, p *uint8) *uint8Value { *p = val return (*uint8Value)(p) } func (i *uint8Value) Set(s string) error { v, err := strconv.ParseUint(s, 0, 8) *i = uint8Value(v) return err } func (i *uint8Value) Type() string { return "uint8" } func (i *uint8Value) String() string { return strconv.FormatUint(uint64(*i), 10) } func uint8Conv(sval string) (interface{}, error) { v, err := strconv.ParseUint(sval, 0, 8) if err != nil { return 0, err } return uint8(v), nil } // GetUint8 return the uint8 value of a flag with the given name func (f *FlagSet) GetUint8(name string) (uint8, error) { val, err := f.getFlagType(name, "uint8", uint8Conv) if err != nil { return 0, err } return val.(uint8), nil } // Uint8Var defines a uint8 flag with specified name, default value, and usage string. // The argument p points to a uint8 variable in which to store the value of the flag. func (f *FlagSet) Uint8Var(p *uint8, name string, value uint8, usage string) { f.VarP(newUint8Value(value, p), name, "", usage) } // Uint8VarP is like Uint8Var, but accepts a shorthand letter that can be used after a single dash. func (f *FlagSet) Uint8VarP(p *uint8, name, shorthand string, value uint8, usage string) { f.VarP(newUint8Value(value, p), name, shorthand, usage) } // Uint8Var defines a uint8 flag with specified name, default value, and usage string. // The argument p points to a uint8 variable in which to store the value of the flag. func Uint8Var(p *uint8, name string, value uint8, usage string) { CommandLine.VarP(newUint8Value(value, p), name, "", usage) } // Uint8VarP is like Uint8Var, but accepts a shorthand letter that can be used after a single dash. func Uint8VarP(p *uint8, name, shorthand string, value uint8, usage string) { CommandLine.VarP(newUint8Value(value, p), name, shorthand, usage) } // Uint8 defines a uint8 flag with specified name, default value, and usage string. // The return value is the address of a uint8 variable that stores the value of the flag. func (f *FlagSet) Uint8(name string, value uint8, usage string) *uint8 { p := new(uint8) f.Uint8VarP(p, name, "", value, usage) return p } // Uint8P is like Uint8, but accepts a shorthand letter that can be used after a single dash. func (f *FlagSet) Uint8P(name, shorthand string, value uint8, usage string) *uint8 { p := new(uint8) f.Uint8VarP(p, name, shorthand, value, usage) return p } // Uint8 defines a uint8 flag with specified name, default value, and usage string. // The return value is the address of a uint8 variable that stores the value of the flag. func Uint8(name string, value uint8, usage string) *uint8 { return CommandLine.Uint8P(name, "", value, usage) } // Uint8P is like Uint8, but accepts a shorthand letter that can be used after a single dash. func Uint8P(name, shorthand string, value uint8, usage string) *uint8 { return CommandLine.Uint8P(name, shorthand, value, usage) } spf13-pflag-0491e57/uint_slice.go000066400000000000000000000111251505550473500165130ustar00rootroot00000000000000package pflag import ( "fmt" "strconv" "strings" ) // -- uintSlice Value type uintSliceValue struct { value *[]uint changed bool } func newUintSliceValue(val []uint, p *[]uint) *uintSliceValue { uisv := new(uintSliceValue) uisv.value = p *uisv.value = val return uisv } 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) if err != nil { return err } out[i] = uint(u) } if !s.changed { *s.value = out } else { *s.value = append(*s.value, out...) } s.changed = true return nil } func (s *uintSliceValue) Type() string { return "uintSlice" } func (s *uintSliceValue) String() string { out := make([]string, len(*s.value)) for i, d := range *s.value { out[i] = fmt.Sprintf("%d", d) } return "[" + strings.Join(out, ",") + "]" } func (s *uintSliceValue) fromString(val string) (uint, error) { t, err := strconv.ParseUint(val, 10, 0) if err != nil { return 0, err } return uint(t), nil } func (s *uintSliceValue) toString(val uint) string { return fmt.Sprintf("%d", val) } func (s *uintSliceValue) Append(val string) error { i, err := s.fromString(val) if err != nil { return err } *s.value = append(*s.value, i) return nil } func (s *uintSliceValue) Replace(val []string) error { out := make([]uint, len(val)) for i, d := range val { var err error out[i], err = s.fromString(d) if err != nil { return err } } *s.value = out return nil } func (s *uintSliceValue) GetSlice() []string { out := make([]string, len(*s.value)) for i, d := range *s.value { out[i] = s.toString(d) } return out } func uintSliceConv(val string) (interface{}, error) { val = strings.Trim(val, "[]") // Empty string would cause a slice with one (empty) entry if len(val) == 0 { return []uint{}, nil } ss := strings.Split(val, ",") out := make([]uint, len(ss)) for i, d := range ss { u, err := strconv.ParseUint(d, 10, 0) if err != nil { return nil, err } out[i] = uint(u) } return out, nil } // GetUintSlice returns the []uint value of a flag with the given name. func (f *FlagSet) GetUintSlice(name string) ([]uint, error) { val, err := f.getFlagType(name, "uintSlice", uintSliceConv) if err != nil { return []uint{}, err } return val.([]uint), nil } // UintSliceVar defines a uintSlice flag with specified name, default value, and usage string. // The argument p points to a []uint variable in which to store the value of the flag. func (f *FlagSet) UintSliceVar(p *[]uint, name string, value []uint, usage string) { f.VarP(newUintSliceValue(value, p), name, "", usage) } // UintSliceVarP is like UintSliceVar, but accepts a shorthand letter that can be used after a single dash. func (f *FlagSet) UintSliceVarP(p *[]uint, name, shorthand string, value []uint, usage string) { f.VarP(newUintSliceValue(value, p), name, shorthand, usage) } // UintSliceVar defines a uint[] flag with specified name, default value, and usage string. // The argument p points to a uint[] variable in which to store the value of the flag. func UintSliceVar(p *[]uint, name string, value []uint, usage string) { CommandLine.VarP(newUintSliceValue(value, p), name, "", usage) } // UintSliceVarP is like the UintSliceVar, but accepts a shorthand letter that can be used after a single dash. func UintSliceVarP(p *[]uint, name, shorthand string, value []uint, usage string) { CommandLine.VarP(newUintSliceValue(value, p), name, shorthand, usage) } // UintSlice defines a []uint flag with specified name, default value, and usage string. // The return value is the address of a []uint variable that stores the value of the flag. func (f *FlagSet) UintSlice(name string, value []uint, usage string) *[]uint { p := []uint{} f.UintSliceVarP(&p, name, "", value, usage) return &p } // UintSliceP is like UintSlice, but accepts a shorthand letter that can be used after a single dash. func (f *FlagSet) UintSliceP(name, shorthand string, value []uint, usage string) *[]uint { p := []uint{} f.UintSliceVarP(&p, name, shorthand, value, usage) return &p } // UintSlice defines a []uint flag with specified name, default value, and usage string. // The return value is the address of a []uint variable that stores the value of the flag. func UintSlice(name string, value []uint, usage string) *[]uint { return CommandLine.UintSliceP(name, "", value, usage) } // UintSliceP is like UintSlice, but accepts a shorthand letter that can be used after a single dash. func UintSliceP(name, shorthand string, value []uint, usage string) *[]uint { return CommandLine.UintSliceP(name, shorthand, value, usage) } spf13-pflag-0491e57/uint_slice_test.go000066400000000000000000000102631505550473500175540ustar00rootroot00000000000000package pflag import ( "fmt" "strconv" "strings" "testing" ) func setUpUISFlagSet(uisp *[]uint) *FlagSet { f := NewFlagSet("test", ContinueOnError) f.UintSliceVar(uisp, "uis", []uint{}, "Command separated list!") return f } func setUpUISFlagSetWithDefault(uisp *[]uint) *FlagSet { f := NewFlagSet("test", ContinueOnError) f.UintSliceVar(uisp, "uis", []uint{0, 1}, "Command separated list!") return f } func TestEmptyUIS(t *testing.T) { var uis []uint f := setUpUISFlagSet(&uis) err := f.Parse([]string{}) if err != nil { t.Fatal("expected no error; got", err) } getUIS, err := f.GetUintSlice("uis") if err != nil { t.Fatal("got an error from GetUintSlice():", err) } if len(getUIS) != 0 { t.Fatalf("got is %v with len=%d but expected length=0", getUIS, len(getUIS)) } } func TestUIS(t *testing.T) { var uis []uint f := setUpUISFlagSet(&uis) 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) } for i, v := range uis { u, err := strconv.ParseUint(vals[i], 10, 0) if err != nil { t.Fatalf("got error: %v", err) } if uint(u) != v { 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) } for i, v := range getUIS { u, err := strconv.ParseUint(vals[i], 10, 0) if err != nil { t.Fatalf("got error: %v", err) } if uint(u) != v { t.Fatalf("expected uis[%d] to be %s but got: %d from GetUintSlice", i, vals[i], v) } } } func TestUISDefault(t *testing.T) { var uis []uint f := setUpUISFlagSetWithDefault(&uis) vals := []string{"0", "1"} err := f.Parse([]string{}) if err != nil { t.Fatal("expected no error; got", err) } for i, v := range uis { u, err := strconv.ParseUint(vals[i], 10, 0) if err != nil { t.Fatalf("got error: %v", err) } if uint(u) != v { t.Fatalf("expect uis[%d] to be %d but got: %d", i, u, v) } } getUIS, err := f.GetUintSlice("uis") if err != nil { t.Fatal("got an error from GetUintSlice():", err) } for i, v := range getUIS { u, err := strconv.ParseUint(vals[i], 10, 0) if err != nil { t.Fatal("got an error from GetIntSlice():", err) } if uint(u) != v { t.Fatalf("expected uis[%d] to be %d from GetUintSlice but got: %d", i, u, v) } } } func TestUISWithDefault(t *testing.T) { var uis []uint f := setUpUISFlagSetWithDefault(&uis) 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) } for i, v := range uis { u, err := strconv.ParseUint(vals[i], 10, 0) if err != nil { t.Fatalf("got error: %v", err) } if uint(u) != v { t.Fatalf("expected uis[%d] to be %d from GetUintSlice but got: %d", i, u, v) } } getUIS, err := f.GetUintSlice("uis") if err != nil { t.Fatal("got an error from GetUintSlice():", err) } for i, v := range getUIS { u, err := strconv.ParseUint(vals[i], 10, 0) if err != nil { t.Fatalf("got error: %v", err) } if uint(u) != v { t.Fatalf("expected uis[%d] to be %d from GetUintSlice but got: %d", i, u, v) } } } func TestUISAsSliceValue(t *testing.T) { var uis []uint f := setUpUISFlagSet(&uis) in := []string{"1", "2"} argfmt := "--uis=%s" arg1 := fmt.Sprintf(argfmt, in[0]) arg2 := fmt.Sprintf(argfmt, in[1]) err := f.Parse([]string{arg1, arg2}) if err != nil { t.Fatal("expected no error; got", err) } f.VisitAll(func(f *Flag) { if val, ok := f.Value.(SliceValue); ok { _ = val.Replace([]string{"3"}) } }) if len(uis) != 1 || uis[0] != 3 { t.Fatalf("Expected ss to be overwritten with '3.1', but got: %v", uis) } } func TestUISCalledTwice(t *testing.T) { var uis []uint f := setUpUISFlagSet(&uis) in := []string{"1,2", "3"} expected := []int{1, 2, 3} argfmt := "--uis=%s" arg1 := fmt.Sprintf(argfmt, in[0]) arg2 := fmt.Sprintf(argfmt, in[1]) err := f.Parse([]string{arg1, arg2}) 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) } } } spf13-pflag-0491e57/verify/000077500000000000000000000000001505550473500153325ustar00rootroot00000000000000spf13-pflag-0491e57/verify/all.sh000077500000000000000000000023151505550473500164420ustar00rootroot00000000000000#!/bin/bash set -o errexit set -o nounset set -o pipefail ROOT=$(dirname "${BASH_SOURCE}")/.. # Some useful colors. if [[ -z "${color_start-}" ]]; then declare -r color_start="\033[" declare -r color_red="${color_start}0;31m" declare -r color_yellow="${color_start}0;33m" declare -r color_green="${color_start}0;32m" declare -r color_norm="${color_start}0m" fi SILENT=true function is-excluded { for e in $EXCLUDE; do if [[ $1 -ef ${BASH_SOURCE} ]]; then return fi if [[ $1 -ef "$ROOT/hack/$e" ]]; then return fi done return 1 } while getopts ":v" opt; do case $opt in v) SILENT=false ;; \?) echo "Invalid flag: -$OPTARG" >&2 exit 1 ;; esac done if $SILENT ; then echo "Running in the silent mode, run with -v if you want to see script logs." fi EXCLUDE="all.sh" ret=0 for t in `ls $ROOT/verify/*.sh` do if is-excluded $t ; then echo "Skipping $t" continue fi if $SILENT ; then echo -e "Verifying $t" if bash "$t" &> /dev/null; then echo -e "${color_green}SUCCESS${color_norm}" else echo -e "${color_red}FAILED${color_norm}" ret=1 fi else bash "$t" || ret=1 fi done exit $ret spf13-pflag-0491e57/verify/gofmt.sh000077500000000000000000000005561505550473500170130ustar00rootroot00000000000000#!/bin/bash set -o errexit set -o nounset set -o pipefail ROOT=$(dirname "${BASH_SOURCE}")/.. pushd "${ROOT}" > /dev/null GOFMT=${GOFMT:-"gofmt"} bad_files=$(find . -name '*.go' | xargs $GOFMT -s -l) if [[ -n "${bad_files}" ]]; then echo "!!! '$GOFMT' needs to be run on the following files: " echo "${bad_files}" exit 1 fi # ex: ts=2 sw=2 et filetype=sh spf13-pflag-0491e57/verify/golint.sh000077500000000000000000000004721505550473500171700ustar00rootroot00000000000000#!/bin/bash ROOT=$(dirname "${BASH_SOURCE}")/.. GOLINT=${GOLINT:-"golint"} pushd "${ROOT}" > /dev/null bad_files=$($GOLINT -min_confidence=0.9 ./...) if [[ -n "${bad_files}" ]]; then echo "!!! '$GOLINT' problems: " echo "${bad_files}" exit 1 fi popd > /dev/null # ex: ts=2 sw=2 et filetype=sh