Update dependencies

This commit is contained in:
Zlatko Čalušić
2017-05-31 22:23:46 +02:00
parent 954686ce66
commit ed59c2ec28
62 changed files with 6422 additions and 2878 deletions

2
vendor/github.com/spf13/pflag/.gitignore generated vendored Normal file
View File

@@ -0,0 +1,2 @@
.idea/*

View File

@@ -3,18 +3,19 @@ sudo: false
language: go
go:
- 1.6.3
- 1.7.3
- tip
- 1.7.3
- 1.8.1
- tip
matrix:
allow_failures:
- go: tip
allow_failures:
- go: tip
install:
- go get github.com/golang/lint/golint
- export PATH=$GOPATH/bin:$PATH
- go install ./...
- go get github.com/golang/lint/golint
- export PATH=$GOPATH/bin:$PATH
- go install ./...
script:
- verify/all.sh -v
- go test ./...
- verify/all.sh -v
- go test ./...

View File

@@ -1,4 +1,6 @@
[![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
@@ -244,6 +246,25 @@ It is possible to mark a flag as hidden, meaning it will still function as norma
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`).
@@ -268,8 +289,8 @@ func main() {
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/ogier/pflag][2] after
[http://localhost:6060/pkg/github.com/spf13/pflag][2] after
installation.
[2]: http://localhost:6060/pkg/github.com/ogier/pflag
[3]: http://godoc.org/github.com/ogier/pflag
[2]: http://localhost:6060/pkg/github.com/spf13/pflag
[3]: http://godoc.org/github.com/spf13/pflag

147
vendor/github.com/spf13/pflag/bool_slice.go generated vendored Normal file
View File

@@ -0,0 +1,147 @@
package 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)
}

215
vendor/github.com/spf13/pflag/bool_slice_test.go generated vendored Normal file
View File

@@ -0,0 +1,215 @@
package 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)
}
}
}
}

View File

@@ -83,7 +83,9 @@ func (f *FlagSet) CountP(name, shorthand string, usage string) *int {
return p
}
// Count like Count only the flag is placed on the CommandLine isntead of a given flag set
// 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)
}

View File

@@ -2,76 +2,35 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// These examples demonstrate more intricate uses of the flag package.
package pflag_test
import (
"errors"
"fmt"
"strings"
"time"
flag "github.com/spf13/pflag"
"github.com/spf13/pflag"
)
// Example 1: A single string flag called "species" with default value "gopher".
var species = flag.String("species", "gopher", "the species we are studying")
func ExampleShorthandLookup() {
name := "verbose"
short := name[:1]
// Example 2: A flag with a shorthand letter.
var gopherType = flag.StringP("gopher_type", "g", "pocket", "the variety of gopher")
pflag.BoolP(name, short, false, "verbose output")
// Example 3: A user-defined flag type, a slice of durations.
type interval []time.Duration
// len(short) must be == 1
flag := pflag.ShorthandLookup(short)
// String is the method to format the flag's value, part of the flag.Value interface.
// The String method's output will be used in diagnostics.
func (i *interval) String() string {
return fmt.Sprint(*i)
fmt.Println(flag.Name)
}
func (i *interval) Type() string {
return "interval"
}
// Set is the method to set the flag value, part of the flag.Value interface.
// Set's argument is a string to be parsed to set the flag.
// It's a comma-separated list, so we split it.
func (i *interval) Set(value string) error {
// If we wanted to allow the flag to be set multiple times,
// accumulating values, we would delete this if statement.
// That would permit usages such as
// -deltaT 10s -deltaT 15s
// and other combinations.
if len(*i) > 0 {
return errors.New("interval flag already set")
}
for _, dt := range strings.Split(value, ",") {
duration, err := time.ParseDuration(dt)
if err != nil {
return err
}
*i = append(*i, duration)
}
return nil
}
// Define a flag to accumulate durations. Because it has a special type,
// we need to use the Var function and therefore create the flag during
// init.
var intervalFlag interval
func init() {
// Tie the command-line flag to the intervalFlag variable and
// set a usage message.
flag.Var(&intervalFlag, "deltaT", "comma-separated list of intervals to use between events")
}
func Example() {
// All the interesting pieces are with the variables declared above, but
// to enable the flag package to see the flags defined there, one must
// execute, typically at the start of main (not init!):
// flag.Parse()
// We don't run it here because this is not a main function and
// the testing suite has already parsed the flags.
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)
}

363
vendor/github.com/spf13/pflag/flag.go generated vendored
View File

@@ -16,9 +16,9 @@ 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/ogier/pflag"
import flag "github.com/spf13/pflag"
There is one exception to this: if you directly instantiate the Flag struct
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
@@ -134,14 +134,21 @@ type FlagSet struct {
// 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 --
exitOnError bool // does the program exit if there's an error?
errorHandling ErrorHandling
output io.Writer // nil means stderr; use out() accessor
interspersed bool // allow interspersed option/non-option args
@@ -156,7 +163,7 @@ type Flag struct {
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
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
@@ -194,11 +201,13 @@ func sortFlags(flags map[NormalizedName]*Flag) []*Flag {
// "--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
for k, v := range f.formal {
delete(f.formal, k)
nname := f.normalizeFlagName(string(k))
f.formal[nname] = v
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
}
}
@@ -229,10 +238,25 @@ func (f *FlagSet) SetOutput(output io.Writer) {
f.output = output
}
// VisitAll visits the flags in lexicographical order, calling fn for each.
// 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)) {
for _, flag := range sortFlags(f.formal) {
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)
}
}
@@ -253,22 +277,39 @@ func (f *FlagSet) HasAvailableFlags() bool {
return false
}
// VisitAll visits the command-line flags in lexicographical order, calling
// fn for each. It visits all flags, even those not set.
// 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, calling fn for each.
// 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)) {
for _, flag := range sortFlags(f.actual) {
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, calling fn
// for each. It visits only those flags that have been set.
// 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)
}
@@ -278,6 +319,22 @@ 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]
@@ -319,7 +376,7 @@ func (f *FlagSet) MarkDeprecated(name string, usageMessage string) error {
if flag == nil {
return fmt.Errorf("flag %q does not exist", name)
}
if len(usageMessage) == 0 {
if usageMessage == "" {
return fmt.Errorf("deprecated message for flag %q must be set", name)
}
flag.Deprecated = usageMessage
@@ -334,7 +391,7 @@ func (f *FlagSet) MarkShorthandDeprecated(name string, usageMessage string) erro
if flag == nil {
return fmt.Errorf("flag %q does not exist", name)
}
if len(usageMessage) == 0 {
if usageMessage == "" {
return fmt.Errorf("deprecated message for flag %q must be set", name)
}
flag.ShorthandDeprecated = usageMessage
@@ -358,6 +415,12 @@ 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)
@@ -365,17 +428,28 @@ func (f *FlagSet) Set(name, value string) error {
if !ok {
return fmt.Errorf("no such flag -%v", name)
}
err := flag.Value.Set(value)
if err != nil {
return err
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 len(flag.Deprecated) > 0 {
fmt.Fprintf(os.Stderr, "Flag --%s has been deprecated, %s\n", flag.Name, flag.Deprecated)
if flag.Deprecated != "" {
fmt.Fprintf(f.out(), "Flag --%s has been deprecated, %s\n", flag.Name, flag.Deprecated)
}
return nil
}
@@ -487,31 +561,98 @@ func UnquoteUsage(flag *Flag) (name string, usage string) {
return
}
// FlagUsages Returns a string containing the usage information for all flags in
// the FlagSet
func (f *FlagSet) FlagUsages() string {
x := new(bytes.Buffer)
// 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 len(flag.Deprecated) > 0 || flag.Hidden {
if flag.Deprecated != "" || flag.Hidden {
return
}
line := ""
if len(flag.Shorthand) > 0 && len(flag.ShorthandDeprecated) == 0 {
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 len(varname) > 0 {
if varname != "" {
line += " " + varname
}
if len(flag.NoOptDefVal) > 0 {
if flag.NoOptDefVal != "" {
switch flag.Value.Type() {
case "string":
line += fmt.Sprintf("[=\"%s\"]", flag.NoOptDefVal)
@@ -534,7 +675,7 @@ func (f *FlagSet) FlagUsages() string {
line += usage
if !flag.defaultIsZeroValue() {
if flag.Value.Type() == "string" {
line += fmt.Sprintf(" (default \"%s\")", flag.DefValue)
line += fmt.Sprintf(" (default %q)", flag.DefValue)
} else {
line += fmt.Sprintf(" (default %s)", flag.DefValue)
}
@@ -546,10 +687,17 @@ func (f *FlagSet) FlagUsages() string {
for _, line := range lines {
sidx := strings.Index(line, "\x00")
spacing := strings.Repeat(" ", maxlen-sidx)
fmt.Fprintln(x, line[:sidx], spacing, line[sidx+1:])
// 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 x.String()
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.
@@ -635,16 +783,15 @@ func (f *FlagSet) VarPF(value Value, name, shorthand, usage string) *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)
f.VarPF(value, name, shorthand, usage)
}
// AddFlag will add the flag to the FlagSet
func (f *FlagSet) AddFlag(flag *Flag) {
// Call normalizeFlagName function only once
normalizedFlagName := f.normalizeFlagName(flag.Name)
_, alreadythere := f.formal[normalizedFlagName]
if alreadythere {
_, 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
@@ -655,28 +802,31 @@ func (f *FlagSet) AddFlag(flag *Flag) {
flag.Name = string(normalizedFlagName)
f.formal[normalizedFlagName] = flag
f.orderedFormal = append(f.orderedFormal, flag)
if len(flag.Shorthand) == 0 {
if flag.Shorthand == "" {
return
}
if len(flag.Shorthand) > 1 {
fmt.Fprintf(f.out(), "%s shorthand more than ASCII character: %s\n", f.name, flag.Shorthand)
panic("shorthand is more than one character")
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]
old, alreadythere := f.shorthands[c]
if alreadythere {
fmt.Fprintf(f.out(), "%s shorthand reused: %q for %s already used for %s\n", f.name, c, flag.Name, old.Name)
panic("shorthand redefinition")
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
// the flag from newSet will be ignored.
func (f *FlagSet) AddFlagSet(newSet *FlagSet) {
if newSet == nil {
return
@@ -724,45 +874,18 @@ func (f *FlagSet) usage() {
}
}
func (f *FlagSet) setFlag(flag *Flag, value string, origArg string) error {
if err := flag.Value.Set(value); err != nil {
return f.failf("invalid argument %q for %s: %v", value, origArg, err)
}
// mark as visited for Visit()
if f.actual == nil {
f.actual = make(map[NormalizedName]*Flag)
}
f.actual[f.normalizeFlagName(flag.Name)] = flag
flag.Changed = true
if len(flag.Deprecated) > 0 {
fmt.Fprintf(os.Stderr, "Flag --%s has been deprecated, %s\n", flag.Name, flag.Deprecated)
}
if len(flag.ShorthandDeprecated) > 0 && containsShorthand(origArg, flag.Shorthand) {
fmt.Fprintf(os.Stderr, "Flag shorthand -%s has been deprecated, %s\n", flag.Shorthand, flag.ShorthandDeprecated)
}
return nil
}
func containsShorthand(arg, shorthand string) bool {
// filter out flags --<flag_name>
if strings.HasPrefix(arg, "-") {
return false
}
arg = strings.SplitN(arg, "=", 2)[0]
return strings.Contains(arg, shorthand)
}
func (f *FlagSet) parseLongArg(s string, args []string) (a []string, err error) {
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, alreadythere := f.formal[f.normalizeFlagName(name)]
if !alreadythere {
flag, exists := f.formal[f.normalizeFlagName(name)]
if !exists {
if name == "help" { // special case for nice help message.
f.usage()
return a, ErrHelp
@@ -770,11 +893,12 @@ func (f *FlagSet) parseLongArg(s string, args []string) (a []string, err error)
err = f.failf("unknown flag: --%s", name)
return
}
var value string
if len(split) == 2 {
// '--flag=arg'
value = split[1]
} else if len(flag.NoOptDefVal) > 0 {
} else if flag.NoOptDefVal != "" {
// '--flag' (arg was optional)
value = flag.NoOptDefVal
} else if len(a) > 0 {
@@ -786,55 +910,68 @@ func (f *FlagSet) parseLongArg(s string, args []string) (a []string, err error)
err = f.failf("flag needs an argument: %s", s)
return
}
err = f.setFlag(flag, value, s)
err = fn(flag, value)
return
}
func (f *FlagSet) parseSingleShortArg(shorthands string, args []string) (outShorts string, outArgs []string, err error) {
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, alreadythere := f.shorthands[c]
if !alreadythere {
flag, exists := f.shorthands[c]
if !exists {
if c == 'h' { // special case for nice help message.
f.usage()
err = ErrHelp
return
}
//TODO continue on error
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 len(flag.NoOptDefVal) > 0 {
} 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
}
err = f.setFlag(flag, value, shorthands)
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) (a []string, err error) {
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)
shorthands, a, err = f.parseSingleShortArg(shorthands, args, fn)
if err != nil {
return
}
@@ -843,7 +980,7 @@ func (f *FlagSet) parseShortArg(s string, args []string) (a []string, err error)
return
}
func (f *FlagSet) parseArgs(args []string) (err error) {
func (f *FlagSet) parseArgs(args []string, fn parseFunc) (err error) {
for len(args) > 0 {
s := args[0]
args = args[1:]
@@ -863,9 +1000,9 @@ func (f *FlagSet) parseArgs(args []string) (err error) {
f.args = append(f.args, args...)
break
}
args, err = f.parseLongArg(s, args)
args, err = f.parseLongArg(s, args, fn)
} else {
args, err = f.parseShortArg(s, args)
args, err = f.parseShortArg(s, args, fn)
}
if err != nil {
return
@@ -880,8 +1017,43 @@ func (f *FlagSet) parseArgs(args []string) (err error) {
// 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))
err := f.parseArgs(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:
@@ -907,6 +1079,14 @@ func Parse() {
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)
@@ -920,14 +1100,15 @@ func Parsed() bool {
// 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 and
// error handling property.
// 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
}

View File

@@ -333,6 +333,59 @@ func testParse(f *FlagSet, t *testing.T) {
}
}
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() {
@@ -393,21 +446,62 @@ func TestShorthand(t *testing.T) {
}
}
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")
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 {
@@ -878,6 +972,7 @@ const defaultOutput = ` --A for bootstrapping, allo
--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
@@ -929,6 +1024,8 @@ func TestPrintDefaults(t *testing.T) {
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")
@@ -946,3 +1043,43 @@ func TestPrintDefaults(t *testing.T) {
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++
})
}

View File

@@ -6,13 +6,10 @@ package pflag
import (
goflag "flag"
"fmt"
"reflect"
"strings"
)
var _ = fmt.Print
// 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

View File

@@ -6,8 +6,6 @@ import (
"strings"
)
var _ = strings.TrimSpace
// -- net.IP value
type ipValue net.IP

148
vendor/github.com/spf13/pflag/ip_slice.go generated vendored Normal file
View File

@@ -0,0 +1,148 @@
package 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)
}

222
vendor/github.com/spf13/pflag/ip_slice_test.go generated vendored Normal file
View File

@@ -0,0 +1,222 @@
package 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)
}
}
}
}

View File

@@ -27,8 +27,6 @@ func (*ipNetValue) Type() string {
return "ipNet"
}
var _ = strings.TrimSpace
func newIPNetValue(val net.IPNet, p *net.IPNet) *ipNetValue {
*p = val
return (*ipNetValue)(p)

View File

@@ -1,11 +1,5 @@
package pflag
import (
"fmt"
)
var _ = fmt.Fprint
// -- stringArray Value
type stringArrayValue struct {
value *[]string

View File

@@ -3,12 +3,9 @@ package pflag
import (
"bytes"
"encoding/csv"
"fmt"
"strings"
)
var _ = fmt.Fprint
// -- stringSlice Value
type stringSliceValue struct {
value *[]string
@@ -39,7 +36,7 @@ func writeAsCSV(vals []string) (string, error) {
return "", err
}
w.Flush()
return strings.TrimSuffix(b.String(), fmt.Sprintln()), nil
return strings.TrimSuffix(b.String(), "\n"), nil
}
func (s *stringSliceValue) Set(val string) error {

126
vendor/github.com/spf13/pflag/uint_slice.go generated vendored Normal file
View File

@@ -0,0 +1,126 @@
package 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)
}

161
vendor/github.com/spf13/pflag/uint_slice_test.go generated vendored Normal file
View File

@@ -0,0 +1,161 @@
package 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)
}
}
}