pax_global_header00006660000000000000000000000064131041361700014506gustar00rootroot0000000000000052 comment=e57e3eeb33f795204c1ca35f56c44f83227c6e66 pflag-1.0.0/000077500000000000000000000000001310413617000125755ustar00rootroot00000000000000pflag-1.0.0/.gitignore000066400000000000000000000000111310413617000145550ustar00rootroot00000000000000.idea/* pflag-1.0.0/.travis.yml000066400000000000000000000003761310413617000147140ustar00rootroot00000000000000sudo: false language: go go: - 1.7.3 - 1.8.1 - tip matrix: allow_failures: - go: tip install: - go get github.com/golang/lint/golint - export PATH=$GOPATH/bin:$PATH - go install ./... script: - verify/all.sh -v - go test ./... pflag-1.0.0/LICENSE000066400000000000000000000027731310413617000136130ustar00rootroot00000000000000Copyright (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. pflag-1.0.0/README.md000066400000000000000000000230341310413617000140560ustar00rootroot00000000000000[![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 helpers function to get values later if you have the FlagSet but it was difficult to keep up with all of the flag 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() } ``` ## 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 pflag-1.0.0/bool.go000066400000000000000000000060001310413617000140530ustar00rootroot00000000000000package 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 } pflag-1.0.0/bool_slice.go000066400000000000000000000107531310413617000152440ustar00rootroot00000000000000package 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 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) } pflag-1.0.0/bool_slice_test.go000066400000000000000000000114311310413617000162750ustar00rootroot00000000000000package 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 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) } } } } pflag-1.0.0/bool_test.go000066400000000000000000000105551310413617000151240ustar00rootroot00000000000000// 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) } } pflag-1.0.0/count.go000066400000000000000000000056141310413617000142620ustar00rootroot00000000000000package 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 { v, err := strconv.ParseInt(s, 0, 64) // -1 means that no specific value was passed, so increment if v == -1 { *i = countValue(*i + 1) } else { *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 evey 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 evey 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 evey 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) } pflag-1.0.0/count_test.go000066400000000000000000000021101310413617000153050ustar00rootroot00000000000000package 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{"-vvv"}, true, 3}, {[]string{"-v", "-v", "-v"}, true, 3}, {[]string{"-v", "--verbose", "-v"}, true, 3}, {[]string{"-v=3", "-v"}, true, 4}, {[]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 %q, got %q", tc.expected, c) } } } } pflag-1.0.0/duration.go000066400000000000000000000063651310413617000147630ustar00rootroot00000000000000package 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) } pflag-1.0.0/example_test.go000066400000000000000000000013171310413617000156200ustar00rootroot00000000000000// 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) } pflag-1.0.0/export_test.go000066400000000000000000000013371310413617000155100ustar00rootroot00000000000000// 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 } pflag-1.0.0/flag.go000066400000000000000000001014271310413617000140420ustar00rootroot00000000000000// 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("boolname", "b", true, "help message") } flag.VarP(&flagVar, "varname", "v", 1234, "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" "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 ) // 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 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 out() accessor interspersed bool // allow interspersed option/non-option args normalizeNameFunc func(f *FlagSet, name string) NormalizedName } // 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 } // 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 k, v := range f.orderedFormal { delete(f.formal, NormalizedName(v.Name)) nname := f.normalizeFlagName(v.Name) v.Name = string(nname) f.formal[nname] = v f.orderedFormal[k] = v } } // 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) } func (f *FlagSet) out() io.Writer { if f.output == nil { return os.Stderr } return f.output } // 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 definied. func (f *FlagSet) HasFlags() bool { return len(f.formal) > 0 } // HasAvailableFlags returns a bool to indicate if the FlagSet has any flags // definied that are not hidden or deprecated. func (f *FlagSet) HasAvailableFlags() bool { for _, flag := range f.formal { if !flag.Hidden && len(flag.Deprecated) == 0 { 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.out(), 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 := fmt.Errorf("flag accessed but not defined: %s", name) 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 fmt.Errorf("flag %q does not exist", name) } if usageMessage == "" { return fmt.Errorf("deprecated message for flag %q must be set", name) } flag.Deprecated = usageMessage 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 fmt.Errorf("flag %q does not exist", name) } 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 fmt.Errorf("flag %q does not exist", name) } 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 fmt.Errorf("no such flag -%v", name) } err := flag.Value.Set(value) if err != nil { 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.Errorf("invalid argument %q for %q flag: %v", value, flagName, err) } 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.out(), "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 fmt.Errorf("no such flag -%v", name) } 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.out(), 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" 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.Value.String() { 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": name = "" case "float64": name = "float" case "int64": name = "int" case "uint64": name = "uint" } 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") if w <= 0 { return s, "" } 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 s } // 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 s } // 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 + l // Now wrap the rest for s != "" { var t string t, s = wrapN(wrap, slop, s) r = r + "\n" + strings.Repeat(" ", i) + t } 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.Deprecated != "" || 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": if flag.NoOptDefVal != "true" { 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) } } 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.out(), "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.out(), 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.out(), 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.out(), 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) } // failf prints to standard error a formatted error and usage message and // returns the error. func (f *FlagSet) failf(format string, a ...interface{}) error { err := fmt.Errorf(format, a...) fmt.Fprintln(f.out(), err) 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() } } 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.failf("bad flag syntax: %s", s) return } split := strings.SplitN(name, "=", 2) name = split[0] flag, exists := f.formal[f.normalizeFlagName(name)] if !exists { if name == "help" { // special case for nice help message. f.usage() return a, ErrHelp } err = f.failf("unknown flag: --%s", name) 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.failf("flag needs an argument: %s", s) return } err = fn(flag, value) return } func (f *FlagSet) parseSingleShortArg(shorthands string, args []string, fn parseFunc) (outShorts string, outArgs []string, err error) { if strings.HasPrefix(shorthands, "test.") { return } outArgs = args outShorts = shorthands[1:] c := shorthands[0] flag, exists := f.shorthands[c] if !exists { if c == 'h' { // special case for nice help message. f.usage() err = ErrHelp return } err = f.failf("unknown shorthand flag: %q in -%s", c, shorthands) 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.failf("flag needs an argument: %q in -%s", c, shorthands) return } if flag.ShorthandDeprecated != "" { fmt.Fprintf(f.out(), "Flag shorthand -%s has been deprecated, %s\n", flag.Shorthand, flag.ShorthandDeprecated) } err = fn(flag, value) 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 { f.parsed = true if len(arguments) < 0 { return nil } f.args = make([]string, 0, len(arguments)) 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: 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: 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 } pflag-1.0.0/flag_test.go000066400000000000000000000755331310413617000151110ustar00rootroot00000000000000// 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 TestUsage(t *testing.T) { called := false ResetForTesting(func() { called = true }) if GetCommandLine().Parse([]string{"--x"}) == nil { t.Error("parse did not fail for unknown flag") } if !called { t.Error("did not call Usage for unknown flag") } } 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) if err := f.SetAnnotation("missing-flag", "key", nil); err == nil { t.Errorf("Expected error setting annotation on non-existent flag") } 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 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") 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", "--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 v, err := f.GetInt8("int8"); err != nil || v != *int8Flag { t.Error("GetInt8 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]) } } 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 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) } } 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 TestFlagSetParse(t *testing.T) { testParse(NewFlagSet("test", ContinueOnError), t) } 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 break } 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) } } // 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) } } // 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) { var 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 TestDeprecatedFlagInDocs(t *testing.T) { f := NewFlagSet("bob", ContinueOnError) f.Bool("badflag", true, "always true") f.MarkDeprecated("badflag", "use --good-flag instead") out := new(bytes.Buffer) f.SetOutput(out) f.PrintDefaults() if strings.Contains(out.String(), "badflag") { t.Errorf("found deprecated flag in usage!") } } 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 intSlice 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 stringSlice string slice with zero default --Z int an int that defaults to zero --custom custom custom Value implementation --customP custom a VarP with default (default 10) --maxT timeout set timeout for dial ` // 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") var cv customValue fs.Var(&cv, "custom", "custom Value implementation") cv2 := customValue(10) fs.VarP(&cv2, "customP", "", "a VarP with default") fs.PrintDefaults() got := buf.String() if got != defaultOutput { fmt.Println("\n" + got) fmt.Println("\n" + defaultOutput) t.Errorf("got %q want %q\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++ }) } pflag-1.0.0/float32.go000066400000000000000000000061401310413617000143770ustar00rootroot00000000000000package 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) } pflag-1.0.0/float64.go000066400000000000000000000060411310413617000144040ustar00rootroot00000000000000package 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) } pflag-1.0.0/golangflag.go000066400000000000000000000051631310413617000152320ustar00rootroot00000000000000// 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" ) // 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) }) } pflag-1.0.0/golangflag_test.go000066400000000000000000000016601310413617000162670ustar00rootroot00000000000000// 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" ) func TestGoflags(t *testing.T) { goflag.String("stringFlag", "stringFlag", "stringFlag") goflag.Bool("boolFlag", false, "boolFlag") f := NewFlagSet("test", ContinueOnError) f.AddGoFlagSet(goflag.CommandLine) err := f.Parse([]string{"--stringFlag=bob", "--boolFlag"}) 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) } } pflag-1.0.0/int.go000066400000000000000000000053341310413617000137230ustar00rootroot00000000000000package 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) } pflag-1.0.0/int32.go000066400000000000000000000057051310413617000140720ustar00rootroot00000000000000package 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) } pflag-1.0.0/int64.go000066400000000000000000000056101310413617000140720ustar00rootroot00000000000000package 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) } pflag-1.0.0/int8.go000066400000000000000000000055671310413617000140230ustar00rootroot00000000000000package 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) } pflag-1.0.0/int_slice.go000066400000000000000000000073111310413617000150770ustar00rootroot00000000000000package 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 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) } pflag-1.0.0/int_slice_test.go000066400000000000000000000071601310413617000161400ustar00rootroot00000000000000// 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) } } } pflag-1.0.0/ip.go000066400000000000000000000057431310413617000135450ustar00rootroot00000000000000package 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 { 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) } pflag-1.0.0/ip_slice.go000066400000000000000000000111031310413617000147070ustar00rootroot00000000000000package 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 ipSliceConv(val string) (interface{}, error) { val = strings.Trim(val, "[]") // Emtpy 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) } pflag-1.0.0/ip_slice_test.go000066400000000000000000000133241310413617000157550ustar00rootroot00000000000000package 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 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) } } } } pflag-1.0.0/ip_test.go000066400000000000000000000025451310413617000146010ustar00rootroot00000000000000package 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"}, {"", false, ""}, {"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()) } } } } pflag-1.0.0/ipmask.go000066400000000000000000000077241310413617000144220ustar00rootroot00000000000000package 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) } pflag-1.0.0/ipnet.go000066400000000000000000000064021310413617000142450ustar00rootroot00000000000000package 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) } pflag-1.0.0/ipnet_test.go000066400000000000000000000031621310413617000153040ustar00rootroot00000000000000package 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()) } } } } pflag-1.0.0/string.go000066400000000000000000000055551310413617000144440ustar00rootroot00000000000000package 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) } pflag-1.0.0/string_array.go000066400000000000000000000073611310413617000156370ustar00rootroot00000000000000package 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) 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 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 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 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 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) } pflag-1.0.0/string_array_test.go000066400000000000000000000131701310413617000166710ustar00rootroot00000000000000// 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 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) } } } pflag-1.0.0/string_slice.go000066400000000000000000000077271310413617000156260ustar00rootroot00000000000000package 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 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. 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. 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. 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. 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) } pflag-1.0.0/string_slice_test.go000066400000000000000000000141211310413617000166470ustar00rootroot00000000000000// 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) } } } pflag-1.0.0/uint.go000066400000000000000000000055671310413617000141200ustar00rootroot00000000000000package 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) } pflag-1.0.0/uint16.go000066400000000000000000000060001310413617000142460ustar00rootroot00000000000000package 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) } pflag-1.0.0/uint32.go000066400000000000000000000060201310413617000142460ustar00rootroot00000000000000package 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) } pflag-1.0.0/uint64.go000066400000000000000000000060151310413617000142570ustar00rootroot00000000000000package 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) } pflag-1.0.0/uint8.go000066400000000000000000000056771310413617000142120ustar00rootroot00000000000000package 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) } pflag-1.0.0/uint_slice.go000066400000000000000000000074651310413617000152760ustar00rootroot00000000000000package 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 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) } pflag-1.0.0/uint_slice_test.go000066400000000000000000000072361310413617000163310ustar00rootroot00000000000000package 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 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) } } } pflag-1.0.0/verify/000077500000000000000000000000001310413617000141015ustar00rootroot00000000000000pflag-1.0.0/verify/all.sh000077500000000000000000000023151310413617000152110ustar00rootroot00000000000000#!/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 pflag-1.0.0/verify/gofmt.sh000077500000000000000000000005561310413617000155620ustar00rootroot00000000000000#!/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 pflag-1.0.0/verify/golint.sh000077500000000000000000000004721310413617000157370ustar00rootroot00000000000000#!/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