diff --git a/Nut.toml b/Nut.toml index fb4b1421..f858c7af 100644 --- a/Nut.toml +++ b/Nut.toml @@ -13,9 +13,10 @@ authors = [ "github.com/kr/pretty" = "088c856450c08c03eb32f7a6c221e6eefaa10e6f" "github.com/kr/pty" = "5cf931ef8f76dccd0910001d74a58a7fca84a83d" "github.com/kr/text" = "6807e777504f54ad073ecef66747de158294b639" +"github.com/inconshreveable/mousetrap" = "76626ae9c91c4f2a10f34cad8ce83ea42c93bb75" "github.com/olekukonko/ts" = "ecf753e7c962639ab5a1fb46f7da627d4c0a04b8" "github.com/rubyist/tracerx" = "d7bcc0bc315bed2a841841bee5dbecc8d7d7582f" -"github.com/spf13/cobra" = "864687ae689edc28688c67edef47e3d2ad651a1b" -"github.com/spf13/pflag" = "463bdc838f2b35e9307e91d480878bda5fff7232" +"github.com/spf13/cobra" = "c55cdf33856a08e4822738728b41783292812889" +"github.com/spf13/pflag" = "4869ec2ae0628354eaac5bf88fccf9a7265ae475" "github.com/technoweenie/assert" = "b25ea301d127043ffacf3b2545726e79b6632139" "github.com/technoweenie/go-contentaddressable" = "38171def3cd15e3b76eb156219b3d48704643899" diff --git a/vendor/_nuts/github.com/inconshreveable/mousetrap/LICENSE b/vendor/_nuts/github.com/inconshreveable/mousetrap/LICENSE new file mode 100644 index 00000000..5f0d1fb6 --- /dev/null +++ b/vendor/_nuts/github.com/inconshreveable/mousetrap/LICENSE @@ -0,0 +1,13 @@ +Copyright 2014 Alan Shreve + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. diff --git a/vendor/_nuts/github.com/inconshreveable/mousetrap/README.md b/vendor/_nuts/github.com/inconshreveable/mousetrap/README.md new file mode 100644 index 00000000..7a950d17 --- /dev/null +++ b/vendor/_nuts/github.com/inconshreveable/mousetrap/README.md @@ -0,0 +1,23 @@ +# mousetrap + +mousetrap is a tiny library that answers a single question. + +On a Windows machine, was the process invoked by someone double clicking on +the executable file while browsing in explorer? + +### Motivation + +Windows developers unfamiliar with command line tools will often "double-click" +the executable for a tool. Because most CLI tools print the help and then exit +when invoked without arguments, this is often very frustrating for those users. + +mousetrap provides a way to detect these invocations so that you can provide +more helpful behavior and instructions on how to run the CLI tool. To see what +this looks like, both from an organizational and a technical perspective, see +https://inconshreveable.com/09-09-2014/sweat-the-small-stuff/ + +### The interface + +The library exposes a single interface: + + func StartedByExplorer() (bool) diff --git a/vendor/_nuts/github.com/inconshreveable/mousetrap/trap_others.go b/vendor/_nuts/github.com/inconshreveable/mousetrap/trap_others.go new file mode 100644 index 00000000..9d2d8a4b --- /dev/null +++ b/vendor/_nuts/github.com/inconshreveable/mousetrap/trap_others.go @@ -0,0 +1,15 @@ +// +build !windows + +package mousetrap + +// StartedByExplorer returns true if the program was invoked by the user +// double-clicking on the executable from explorer.exe +// +// It is conservative and returns false if any of the internal calls fail. +// It does not guarantee that the program was run from a terminal. It only can tell you +// whether it was launched from explorer.exe +// +// On non-Windows platforms, it always returns false. +func StartedByExplorer() bool { + return false +} diff --git a/vendor/_nuts/github.com/inconshreveable/mousetrap/trap_windows.go b/vendor/_nuts/github.com/inconshreveable/mousetrap/trap_windows.go new file mode 100644 index 00000000..336142a5 --- /dev/null +++ b/vendor/_nuts/github.com/inconshreveable/mousetrap/trap_windows.go @@ -0,0 +1,98 @@ +// +build windows +// +build !go1.4 + +package mousetrap + +import ( + "fmt" + "os" + "syscall" + "unsafe" +) + +const ( + // defined by the Win32 API + th32cs_snapprocess uintptr = 0x2 +) + +var ( + kernel = syscall.MustLoadDLL("kernel32.dll") + CreateToolhelp32Snapshot = kernel.MustFindProc("CreateToolhelp32Snapshot") + Process32First = kernel.MustFindProc("Process32FirstW") + Process32Next = kernel.MustFindProc("Process32NextW") +) + +// ProcessEntry32 structure defined by the Win32 API +type processEntry32 struct { + dwSize uint32 + cntUsage uint32 + th32ProcessID uint32 + th32DefaultHeapID int + th32ModuleID uint32 + cntThreads uint32 + th32ParentProcessID uint32 + pcPriClassBase int32 + dwFlags uint32 + szExeFile [syscall.MAX_PATH]uint16 +} + +func getProcessEntry(pid int) (pe *processEntry32, err error) { + snapshot, _, e1 := CreateToolhelp32Snapshot.Call(th32cs_snapprocess, uintptr(0)) + if snapshot == uintptr(syscall.InvalidHandle) { + err = fmt.Errorf("CreateToolhelp32Snapshot: %v", e1) + return + } + defer syscall.CloseHandle(syscall.Handle(snapshot)) + + var processEntry processEntry32 + processEntry.dwSize = uint32(unsafe.Sizeof(processEntry)) + ok, _, e1 := Process32First.Call(snapshot, uintptr(unsafe.Pointer(&processEntry))) + if ok == 0 { + err = fmt.Errorf("Process32First: %v", e1) + return + } + + for { + if processEntry.th32ProcessID == uint32(pid) { + pe = &processEntry + return + } + + ok, _, e1 = Process32Next.Call(snapshot, uintptr(unsafe.Pointer(&processEntry))) + if ok == 0 { + err = fmt.Errorf("Process32Next: %v", e1) + return + } + } +} + +func getppid() (pid int, err error) { + pe, err := getProcessEntry(os.Getpid()) + if err != nil { + return + } + + pid = int(pe.th32ParentProcessID) + return +} + +// StartedByExplorer returns true if the program was invoked by the user double-clicking +// on the executable from explorer.exe +// +// It is conservative and returns false if any of the internal calls fail. +// It does not guarantee that the program was run from a terminal. It only can tell you +// whether it was launched from explorer.exe +func StartedByExplorer() bool { + ppid, err := getppid() + if err != nil { + return false + } + + pe, err := getProcessEntry(ppid) + if err != nil { + return false + } + + name := syscall.UTF16ToString(pe.szExeFile[:]) + return name == "explorer.exe" +} diff --git a/vendor/_nuts/github.com/inconshreveable/mousetrap/trap_windows_1.4.go b/vendor/_nuts/github.com/inconshreveable/mousetrap/trap_windows_1.4.go new file mode 100644 index 00000000..9a28e57c --- /dev/null +++ b/vendor/_nuts/github.com/inconshreveable/mousetrap/trap_windows_1.4.go @@ -0,0 +1,46 @@ +// +build windows +// +build go1.4 + +package mousetrap + +import ( + "os" + "syscall" + "unsafe" +) + +func getProcessEntry(pid int) (*syscall.ProcessEntry32, error) { + snapshot, err := syscall.CreateToolhelp32Snapshot(syscall.TH32CS_SNAPPROCESS, 0) + if err != nil { + return nil, err + } + defer syscall.CloseHandle(snapshot) + var procEntry syscall.ProcessEntry32 + procEntry.Size = uint32(unsafe.Sizeof(procEntry)) + if err = syscall.Process32First(snapshot, &procEntry); err != nil { + return nil, err + } + for { + if procEntry.ProcessID == uint32(pid) { + return &procEntry, nil + } + err = syscall.Process32Next(snapshot, &procEntry) + if err != nil { + return nil, err + } + } +} + +// StartedByExplorer returns true if the program was invoked by the user double-clicking +// on the executable from explorer.exe +// +// It is conservative and returns false if any of the internal calls fail. +// It does not guarantee that the program was run from a terminal. It only can tell you +// whether it was launched from explorer.exe +func StartedByExplorer() bool { + pe, err := getProcessEntry(os.Getppid()) + if err != nil { + return false + } + return "explorer.exe" == syscall.UTF16ToString(pe.ExeFile[:]) +} diff --git a/vendor/_nuts/github.com/ogier/pflag/.travis.yml b/vendor/_nuts/github.com/ogier/pflag/.travis.yml deleted file mode 100644 index 4f2ee4d9..00000000 --- a/vendor/_nuts/github.com/ogier/pflag/.travis.yml +++ /dev/null @@ -1 +0,0 @@ -language: go diff --git a/vendor/_nuts/github.com/ogier/pflag/LICENSE b/vendor/_nuts/github.com/ogier/pflag/LICENSE deleted file mode 100644 index 63ed1cfe..00000000 --- a/vendor/_nuts/github.com/ogier/pflag/LICENSE +++ /dev/null @@ -1,28 +0,0 @@ -Copyright (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. diff --git a/vendor/_nuts/github.com/ogier/pflag/README.md b/vendor/_nuts/github.com/ogier/pflag/README.md deleted file mode 100644 index d9b189f8..00000000 --- a/vendor/_nuts/github.com/ogier/pflag/README.md +++ /dev/null @@ -1,157 +0,0 @@ -[![Build Status](https://travis-ci.org/ogier/pflag.png?branch=master)](https://travis-ci.org/ogier/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/ogier/pflag - -Run tests by running: - - go test github.com/ogier/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/ogier/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) -``` - -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("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. - -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. - -## 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. - -## 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/ogier/pflag][2] after -installation. - -[2]: http://localhost:6060/pkg/github.com/ogier/pflag -[3]: http://godoc.org/github.com/ogier/pflag diff --git a/vendor/_nuts/github.com/ogier/pflag/bool.go b/vendor/_nuts/github.com/ogier/pflag/bool.go deleted file mode 100644 index 617971a0..00000000 --- a/vendor/_nuts/github.com/ogier/pflag/bool.go +++ /dev/null @@ -1,79 +0,0 @@ -package pflag - -import ( - "fmt" - "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) String() string { return fmt.Sprintf("%v", *b) } - -func (b *boolValue) IsBoolFlag() bool { return 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 (f *FlagSet) BoolVar(p *bool, name string, value bool, usage string) { - f.VarP(newBoolValue(value, p), name, "", usage) -} - -// 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) { - f.VarP(newBoolValue(value, p), name, shorthand, usage) -} - -// 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) { - CommandLine.VarP(newBoolValue(value, p), name, "", usage) -} - -// 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) { - CommandLine.VarP(newBoolValue(value, p), name, shorthand, usage) -} - -// 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 { - p := new(bool) - f.BoolVarP(p, name, "", value, usage) - return p -} - -// 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 CommandLine.BoolP(name, "", value, usage) -} - -// 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 { - return CommandLine.BoolP(name, shorthand, value, usage) -} diff --git a/vendor/_nuts/github.com/ogier/pflag/duration.go b/vendor/_nuts/github.com/ogier/pflag/duration.go deleted file mode 100644 index db594639..00000000 --- a/vendor/_nuts/github.com/ogier/pflag/duration.go +++ /dev/null @@ -1,74 +0,0 @@ -package 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) String() string { return (*time.Duration)(d).String() } - -// 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 -} - -// 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) -} - -// 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) -} - -// 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 -} - -// 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) -} - -// 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) -} diff --git a/vendor/_nuts/github.com/ogier/pflag/example_test.go b/vendor/_nuts/github.com/ogier/pflag/example_test.go deleted file mode 100644 index 54f91165..00000000 --- a/vendor/_nuts/github.com/ogier/pflag/example_test.go +++ /dev/null @@ -1,73 +0,0 @@ -// 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. - -// These examples demonstrate more intricate uses of the flag package. -package pflag_test - -import ( - "errors" - "fmt" - "strings" - "time" - - flag "github.com/github/git-lfs/vendor/_nuts/github.com/ogier/pflag" -) - -// Example 1: A single string flag called "species" with default value "gopher". -var species = flag.String("species", "gopher", "the species we are studying") - -// Example 2: A flag with a shorthand letter. -var gopherType = flag.StringP("gopher_type", "g", "pocket", "the variety of gopher") - -// Example 3: A user-defined flag type, a slice of durations. -type interval []time.Duration - -// 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) -} - -// 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. -} diff --git a/vendor/_nuts/github.com/ogier/pflag/export_test.go b/vendor/_nuts/github.com/ogier/pflag/export_test.go deleted file mode 100644 index 9318fee0..00000000 --- a/vendor/_nuts/github.com/ogier/pflag/export_test.go +++ /dev/null @@ -1,29 +0,0 @@ -// 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 -} diff --git a/vendor/_nuts/github.com/ogier/pflag/flag.go b/vendor/_nuts/github.com/ogier/pflag/flag.go deleted file mode 100644 index f3830586..00000000 --- a/vendor/_nuts/github.com/ogier/pflag/flag.go +++ /dev/null @@ -1,554 +0,0 @@ -// 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. - -/* - 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/ogier/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 ( - "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 ErrorHandling = iota - ExitOnError - PanicOnError -) - -// 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() - - name string - parsed bool - actual map[string]*Flag - formal map[string]*Flag - shorthands map[byte]*Flag - args []string // arguments after flags - 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 -} - -// 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 -} - -// sortFlags returns the flags as a slice in lexicographical sorted order. -func sortFlags(flags map[string]*Flag) []*Flag { - list := make(sort.StringSlice, len(flags)) - i := 0 - for _, f := range flags { - list[i] = f.Name - i++ - } - list.Sort() - result := make([]*Flag, len(list)) - for i, name := range list { - result[i] = flags[name] - } - return result -} - -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, 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) { - fn(flag) - } -} - -// VisitAll visits the command-line flags in lexicographical order, 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. -// It visits only those flags that have been set. -func (f *FlagSet) Visit(fn func(*Flag)) { - for _, flag := range sortFlags(f.actual) { - fn(flag) - } -} - -// Visit visits the command-line flags in lexicographical order, 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.formal[name] -} - -// Lookup returns the Flag structure of the named command-line flag, -// returning nil if none exists. -func Lookup(name string) *Flag { - return CommandLine.formal[name] -} - -// Set sets the value of the named flag. -func (f *FlagSet) Set(name, value string) error { - flag, ok := f.formal[name] - if !ok { - return fmt.Errorf("no such flag -%v", name) - } - err := flag.Value.Set(value) - if err != nil { - return err - } - if f.actual == nil { - f.actual = make(map[string]*Flag) - } - f.actual[name] = flag - return nil -} - -// 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() { - f.VisitAll(func(flag *Flag) { - format := "--%s=%s: %s\n" - if _, ok := flag.Value.(*stringValue); ok { - // put quotes on the value - format = "--%s=%q: %s\n" - } - if len(flag.Shorthand) > 0 { - format = " -%s, " + format - } else { - format = " %s " + format - } - fmt.Fprintf(f.out(), format, flag.Shorthand, flag.Name, flag.DefValue, flag.Usage) - }) -} - -// 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. -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) -} - -// 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) { - // Remember the default value as a string; it won't change. - flag := &Flag{name, shorthand, usage, value, value.String()} - _, alreadythere := f.formal[name] - if alreadythere { - msg := fmt.Sprintf("%s flag redefined: %s", f.name, 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[string]*Flag) - } - f.formal[name] = flag - - if len(shorthand) == 0 { - return - } - if len(shorthand) > 1 { - fmt.Fprintf(f.out(), "%s shorthand more than ASCII character: %s\n", f.name, shorthand) - panic("shorthand is more than one character") - } - if f.shorthands == nil { - f.shorthands = make(map[byte]*Flag) - } - c := 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, name, old.Name) - panic("shorthand redefinition") - } - f.shorthands[c] = 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) -} - -// 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) 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[string]*Flag) - } - f.actual[flag.Name] = flag - - return nil -} - -func (f *FlagSet) parseArgs(args []string) 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.args = append(f.args, args...) - return nil - } - name := s[2:] - if len(name) == 0 || name[0] == '-' || name[0] == '=' { - return f.failf("bad flag syntax: %s", s) - } - split := strings.SplitN(name, "=", 2) - name = split[0] - m := f.formal - flag, alreadythere := m[name] // BUG - if !alreadythere { - if name == "help" { // special case for nice help message. - f.usage() - return ErrHelp - } - return f.failf("unknown flag: --%s", name) - } - if len(split) == 1 { - if bv, ok := flag.Value.(boolFlag); !ok || !bv.IsBoolFlag() { - return f.failf("flag needs an argument: %s", s) - } - f.setFlag(flag, "true", s) - } else { - if err := f.setFlag(flag, split[1], s); err != nil { - return err - } - } - } else { - shorthands := s[1:] - for i := 0; i < len(shorthands); i++ { - c := shorthands[i] - flag, alreadythere := f.shorthands[c] - if !alreadythere { - if c == 'h' { // special case for nice help message. - f.usage() - return ErrHelp - } - return f.failf("unknown shorthand flag: %q in -%s", c, shorthands) - } - if bv, ok := flag.Value.(boolFlag); ok && bv.IsBoolFlag() { - f.setFlag(flag, "true", s) - continue - } - if i < len(shorthands)-1 { - if err := f.setFlag(flag, shorthands[i+1:], s); err != nil { - return err - } - break - } - if len(args) == 0 { - return f.failf("flag needs an argument: %q in -%s", c, shorthands) - } - if err := f.setFlag(flag, args[0], s); err != nil { - return err - } - args = args[1:] - break // should be unnecessary - } - } - } - return nil -} - -// 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 - f.args = make([]string, 0, len(arguments)) - err := f.parseArgs(arguments) - 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:]) -} - -// 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() -} - -// 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. -func NewFlagSet(name string, errorHandling ErrorHandling) *FlagSet { - f := &FlagSet{ - name: name, - errorHandling: errorHandling, - interspersed: true, - } - return f -} - -// 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 -} diff --git a/vendor/_nuts/github.com/ogier/pflag/flag_test.go b/vendor/_nuts/github.com/ogier/pflag/flag_test.go deleted file mode 100644 index 82f7fae7..00000000 --- a/vendor/_nuts/github.com/ogier/pflag/flag_test.go +++ /dev/null @@ -1,350 +0,0 @@ -// 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" - "os" - "sort" - "strings" - "testing" - "time" -) - -var ( - test_bool = Bool("test_bool", false, "bool value") - test_int = Int("test_int", 0, "int value") - test_int64 = Int64("test_int64", 0, "int64 value") - test_uint = Uint("test_uint", 0, "uint value") - test_uint64 = Uint64("test_uint64", 0, "uint64 value") - test_string = String("test_string", "0", "string value") - test_float64 = Float64("test_float64", 0, "float64 value") - test_duration = Duration("test_duration", 0, "time.Duration value") -) - -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) != 8 { - 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") - desired = "1" - Visit(visitor) - if len(m) != 8 { - 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 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") - int64Flag := f.Int64("int64", 0, "int64 value") - uintFlag := f.Uint("uint", 0, "uint value") - uint64Flag := f.Uint64("uint64", 0, "uint64 value") - stringFlag := f.String("string", "0", "string value") - float64Flag := f.Float64("float64", 0, "float64 value") - durationFlag := f.Duration("duration", 5*time.Second, "time.Duration value") - extra := "one-extra-argument" - args := []string{ - "--bool", - "--bool2=true", - "--bool3=false", - "--int=22", - "--int64=0x23", - "--uint=24", - "--uint64=25", - "--string=hello", - "--float64=2718e28", - "--duration=2m", - 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 *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 *int64Flag != 0x23 { - t.Error("int64 flag should be 0x23, is ", *int64Flag) - } - if *uintFlag != 24 { - t.Error("uint flag should be 24, is ", *uintFlag) - } - if *uint64Flag != 25 { - t.Error("uint64 flag should be 25, is ", *uint64Flag) - } - if *stringFlag != "hello" { - t.Error("string flag should be `hello`, is ", *stringFlag) - } - if *float64Flag != 2718e28 { - t.Error("float64 flag should be 2718e28, is ", *float64Flag) - } - if *durationFlag != 2*time.Minute { - t.Error("duration flag should be 2m, is ", *durationFlag) - } - 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 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") - stringFlag := f.StringP("string", "s", "0", "string value") - extra := "interspersed-argument" - notaflag := "--i-look-like-a-flag" - args := []string{ - "-ab", - extra, - "-cs", - "hello", - "--", - notaflag, - } - if err := f.Parse(args); err != nil { - t.Fatal(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 *stringFlag != "hello" { - t.Error("string flag should be `hello`, is ", *stringFlag) - } - 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]) - } -} - -func TestParse(t *testing.T) { - ResetForTesting(func() { t.Error("bad parse") }) - testParse(GetCommandLine(), t) -} - -func TestFlagSetParse(t *testing.T) { - testParse(NewFlagSet("test", ContinueOnError), t) -} - -// 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 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") - } -} diff --git a/vendor/_nuts/github.com/ogier/pflag/float32.go b/vendor/_nuts/github.com/ogier/pflag/float32.go deleted file mode 100644 index a0041e25..00000000 --- a/vendor/_nuts/github.com/ogier/pflag/float32.go +++ /dev/null @@ -1,70 +0,0 @@ -package pflag - -import ( - "fmt" - "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) String() string { return fmt.Sprintf("%v", *f) } - -// 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) -} - -// 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) -} - -// 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 -} - -// 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) -} - -// 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) -} diff --git a/vendor/_nuts/github.com/ogier/pflag/float64.go b/vendor/_nuts/github.com/ogier/pflag/float64.go deleted file mode 100644 index 8d79be06..00000000 --- a/vendor/_nuts/github.com/ogier/pflag/float64.go +++ /dev/null @@ -1,70 +0,0 @@ -package pflag - -import ( - "fmt" - "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) String() string { return fmt.Sprintf("%v", *f) } - -// 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) -} - -// 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) -} - -// 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 -} - -// 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) -} - -// 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) -} diff --git a/vendor/_nuts/github.com/ogier/pflag/int.go b/vendor/_nuts/github.com/ogier/pflag/int.go deleted file mode 100644 index cb85e149..00000000 --- a/vendor/_nuts/github.com/ogier/pflag/int.go +++ /dev/null @@ -1,70 +0,0 @@ -package pflag - -import ( - "fmt" - "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) String() string { return fmt.Sprintf("%v", *i) } - -// 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) -} - -// 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) -} - -// 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 -} - -// 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) -} - -// 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) -} diff --git a/vendor/_nuts/github.com/ogier/pflag/int32.go b/vendor/_nuts/github.com/ogier/pflag/int32.go deleted file mode 100644 index 2e1a317f..00000000 --- a/vendor/_nuts/github.com/ogier/pflag/int32.go +++ /dev/null @@ -1,70 +0,0 @@ -package pflag - -import ( - "fmt" - "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) String() string { return fmt.Sprintf("%v", *i) } - -// 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) -} - -// 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) -} - -// 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 -} - -// 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) -} - -// 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) -} diff --git a/vendor/_nuts/github.com/ogier/pflag/int64.go b/vendor/_nuts/github.com/ogier/pflag/int64.go deleted file mode 100644 index 43aeced8..00000000 --- a/vendor/_nuts/github.com/ogier/pflag/int64.go +++ /dev/null @@ -1,70 +0,0 @@ -package pflag - -import ( - "fmt" - "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) String() string { return fmt.Sprintf("%v", *i) } - -// 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) -} - -// 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) -} - -// 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 -} - -// 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) -} - -// 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) -} diff --git a/vendor/_nuts/github.com/ogier/pflag/int8.go b/vendor/_nuts/github.com/ogier/pflag/int8.go deleted file mode 100644 index 539c4eb3..00000000 --- a/vendor/_nuts/github.com/ogier/pflag/int8.go +++ /dev/null @@ -1,70 +0,0 @@ -package pflag - -import ( - "fmt" - "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) String() string { return fmt.Sprintf("%v", *i) } - -// 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) -} - -// 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) -} - -// 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 -} - -// 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) -} - -// 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) -} diff --git a/vendor/_nuts/github.com/ogier/pflag/ip.go b/vendor/_nuts/github.com/ogier/pflag/ip.go deleted file mode 100644 index 3a411fcd..00000000 --- a/vendor/_nuts/github.com/ogier/pflag/ip.go +++ /dev/null @@ -1,75 +0,0 @@ -package pflag - -import ( - "fmt" - "net" -) - -// -- 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(s) - if ip == nil { - return fmt.Errorf("failed to parse IP: %q", s) - } - *i = ipValue(ip) - return nil -} -func (i *ipValue) Get() interface{} { - return net.IP(*i) -} - -// 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) -} - -// 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) -} - -// 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 -} - -// 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) -} - -// 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) -} diff --git a/vendor/_nuts/github.com/ogier/pflag/ipmask.go b/vendor/_nuts/github.com/ogier/pflag/ipmask.go deleted file mode 100644 index b8a164ae..00000000 --- a/vendor/_nuts/github.com/ogier/pflag/ipmask.go +++ /dev/null @@ -1,85 +0,0 @@ -package pflag - -import ( - "fmt" - "net" -) - -// -- 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) Get() interface{} { - return net.IPMask(*i) -} - -// Parse IPv4 netmask 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 { - return nil - } - return net.IPv4Mask(mask[12], mask[13], mask[14], mask[15]) -} - -// 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) -} - -// 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) -} - -// 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 -} - -// 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) -} - -// 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) -} diff --git a/vendor/_nuts/github.com/ogier/pflag/string.go b/vendor/_nuts/github.com/ogier/pflag/string.go deleted file mode 100644 index 65c0cb74..00000000 --- a/vendor/_nuts/github.com/ogier/pflag/string.go +++ /dev/null @@ -1,66 +0,0 @@ -package pflag - -import "fmt" - -// -- 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) String() string { return fmt.Sprintf("%s", *s) } - -// 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) -} - -// 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) -} - -// 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 -} - -// 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) -} - -// 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) -} diff --git a/vendor/_nuts/github.com/ogier/pflag/uint.go b/vendor/_nuts/github.com/ogier/pflag/uint.go deleted file mode 100644 index 40b9ebbe..00000000 --- a/vendor/_nuts/github.com/ogier/pflag/uint.go +++ /dev/null @@ -1,70 +0,0 @@ -package pflag - -import ( - "fmt" - "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) String() string { return fmt.Sprintf("%v", *i) } - -// 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) -} - -// 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) -} - -// 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 -} - -// 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) -} - -// 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) -} diff --git a/vendor/_nuts/github.com/ogier/pflag/uint16.go b/vendor/_nuts/github.com/ogier/pflag/uint16.go deleted file mode 100644 index 182dc409..00000000 --- a/vendor/_nuts/github.com/ogier/pflag/uint16.go +++ /dev/null @@ -1,71 +0,0 @@ -package pflag - -import ( - "fmt" - "strconv" -) - -// -- uint16 value -type uint16Value uint16 - -func newUint16Value(val uint16, p *uint16) *uint16Value { - *p = val - return (*uint16Value)(p) -} -func (i *uint16Value) String() string { return fmt.Sprintf("%d", *i) } -func (i *uint16Value) Set(s string) error { - v, err := strconv.ParseUint(s, 0, 16) - *i = uint16Value(v) - return err -} -func (i *uint16Value) Get() interface{} { - return uint16(*i) -} - -// 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) -} - -// 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) -} - -// 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 -} - -// 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) -} - -// 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) -} diff --git a/vendor/_nuts/github.com/ogier/pflag/uint32.go b/vendor/_nuts/github.com/ogier/pflag/uint32.go deleted file mode 100644 index 165c8b25..00000000 --- a/vendor/_nuts/github.com/ogier/pflag/uint32.go +++ /dev/null @@ -1,71 +0,0 @@ -package pflag - -import ( - "fmt" - "strconv" -) - -// -- uint16 value -type uint32Value uint32 - -func newUint32Value(val uint32, p *uint32) *uint32Value { - *p = val - return (*uint32Value)(p) -} -func (i *uint32Value) String() string { return fmt.Sprintf("%d", *i) } -func (i *uint32Value) Set(s string) error { - v, err := strconv.ParseUint(s, 0, 32) - *i = uint32Value(v) - return err -} -func (i *uint32Value) Get() interface{} { - return uint32(*i) -} - -// 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) -} - -// 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) -} - -// 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 -} - -// 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) -} - -// 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) -} diff --git a/vendor/_nuts/github.com/ogier/pflag/uint64.go b/vendor/_nuts/github.com/ogier/pflag/uint64.go deleted file mode 100644 index f41c5a29..00000000 --- a/vendor/_nuts/github.com/ogier/pflag/uint64.go +++ /dev/null @@ -1,70 +0,0 @@ -package pflag - -import ( - "fmt" - "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) String() string { return fmt.Sprintf("%v", *i) } - -// 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) -} - -// 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) -} - -// 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 -} - -// 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) -} - -// 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) -} diff --git a/vendor/_nuts/github.com/ogier/pflag/uint8.go b/vendor/_nuts/github.com/ogier/pflag/uint8.go deleted file mode 100644 index 174f99ca..00000000 --- a/vendor/_nuts/github.com/ogier/pflag/uint8.go +++ /dev/null @@ -1,70 +0,0 @@ -package pflag - -import ( - "fmt" - "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) String() string { return fmt.Sprintf("%v", *i) } - -// 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) -} - -// 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) -} - -// 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 -} - -// 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) -} - -// 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) -} diff --git a/vendor/_nuts/github.com/spf13/cobra/.travis.yml b/vendor/_nuts/github.com/spf13/cobra/.travis.yml index 6de9ac23..dc43afd6 100644 --- a/vendor/_nuts/github.com/spf13/cobra/.travis.yml +++ b/vendor/_nuts/github.com/spf13/cobra/.travis.yml @@ -1,6 +1,8 @@ language: go go: - - 1.1 + - 1.3 + - 1.4.2 + - tip script: - go test ./... - go build diff --git a/vendor/_nuts/github.com/spf13/cobra/README.md b/vendor/_nuts/github.com/spf13/cobra/README.md index b2b9a660..b1fb0889 100644 --- a/vendor/_nuts/github.com/spf13/cobra/README.md +++ b/vendor/_nuts/github.com/spf13/cobra/README.md @@ -2,12 +2,12 @@ A Commander for modern go CLI interactions -[![Build Status](https://travis-ci.org/spf13/cobra.png)](https://travis-ci.org/spf13/cobra) +[![Build Status](https://travis-ci.org/spf13/cobra.svg)](https://travis-ci.org/spf13/cobra) ## Overview Cobra is a commander providing a simple interface to create powerful modern CLI -interfaces similar to git & go tools. In addition to providing an iterface, Cobra +interfaces similar to git & go tools. In addition to providing an interface, Cobra simultaneously provides a controller to organize your application code. Inspired by go, go-Commander, gh and subcommand, Cobra improves on these by @@ -62,7 +62,7 @@ and flags that are only available to that command. In the example above 'port' is the flag. Flag functionality is provided by the [pflag -libary](https://github.com/ogier/pflag), a fork of the flag standard library +library](https://github.com/ogier/pflag), a fork of the flag standard library which maintains the same interface while adding posix compliance. ## Usage @@ -120,7 +120,9 @@ In this example we are attaching it to the root, but commands can be attached at ### Assign flags to a command -Since the flags are defined and used in different locations, we need to define a variable outside with the correct scope to assign the flag to work with. +Since the flags are defined and used in different locations, we need to +define a variable outside with the correct scope to assign the flag to +work with. var Verbose bool var Source string @@ -141,6 +143,15 @@ A flag can also be assigned locally which will only apply to that specific comma HugoCmd.Flags().StringVarP(&Source, "source", "s", "", "Source directory to read from") +### Remove a command from its parent + +Removing a command is not a common action in simple programs but it allows 3rd parties to customize an existing command tree. + +In this example, we remove the existing `VersionCmd` command of an existing root command, and we replace it by our own version. + + mainlib.RootCmd.RemoveCommand(mainlib.VersionCmd) + mainlib.RootCmd.AddCommand(versionCmd) + ### Once all commands and flags are defined, Execute the commands Execute should be run on the root for clarity, though it can be called on any command. @@ -151,7 +162,7 @@ Execute should be run on the root for clarity, though it can be called on any co In the example below we have defined three commands. Two are at the top level and one (cmdTimes) is a child of one of the top commands. In this case the root -is not executible meaning that a subcommand is required. This is accomplished +is not executable meaning that a subcommand is required. This is accomplished by not providing a 'Run' for the 'rootCmd'. We have only defined one flag for a single command. @@ -214,11 +225,11 @@ For a more complete example of a larger application, please checkout [Hugo](http ## The Help Command -Cobra automatically adds a help command to your application. +Cobra automatically adds a help command to your application when you have subcommands. This will be called when a user runs 'app help'. Additionally help will also support all other commands as input. Say for instance you have a command called 'create' without any additional configuration cobra will work when 'app help -create' is called. +create' is called. Every command will automatically have the '--help' flag added. ### Example @@ -337,6 +348,83 @@ Like help the function and template are over ridable through public methods. command.SetUsageTemplate(s string) +## PreRun or PostRun Hooks + +It is possible to run functions before or after the main `Run` function of your command. The `PersistentPreRun` and `PreRun` functions will be executed before `Run`. `PersistendPostRun` and `PostRun` will be executed after `Run`. The `Persistent*Run` functions will be inherrited by children if they do not declare their own. These function are run in the following order: + +- `PersistentPreRun` +- `PreRun` +- `Run` +- `PostRun` +- `PersistenPostRun` + +And example of two commands which use all of these features is below. When the subcommand in executed it will run the root command's `PersistentPreRun` but not the root command's `PersistentPostRun` + +```go +package main + +import ( + "fmt" + + "github.com/spf13/cobra" +) + +func main() { + + var rootCmd = &cobra.Command{ + Use: "root [sub]", + Short: "My root command", + PersistentPreRun: func(cmd *cobra.Command, args []string) { + fmt.Printf("Inside rootCmd PersistentPreRun with args: %v\n", args) + }, + PreRun: func(cmd *cobra.Command, args []string) { + fmt.Printf("Inside rootCmd PreRun with args: %v\n", args) + }, + Run: func(cmd *cobra.Command, args []string) { + fmt.Printf("Inside rootCmd Run with args: %v\n", args) + }, + PostRun: func(cmd *cobra.Command, args []string) { + fmt.Printf("Inside rootCmd PostRun with args: %v\n", args) + }, + PersistentPostRun: func(cmd *cobra.Command, args []string) { + fmt.Printf("Inside rootCmd PersistentPostRun with args: %v\n", args) + }, + } + + var subCmd = &cobra.Command{ + Use: "sub [no options!]", + Short: "My sub command", + PreRun: func(cmd *cobra.Command, args []string) { + fmt.Printf("Inside subCmd PreRun with args: %v\n", args) + }, + Run: func(cmd *cobra.Command, args []string) { + fmt.Printf("Inside subCmd Run with args: %v\n", args) + }, + PostRun: func(cmd *cobra.Command, args []string) { + fmt.Printf("Inside subCmd PostRun with args: %v\n", args) + }, + PersistentPostRun: func(cmd *cobra.Command, args []string) { + fmt.Printf("Inside subCmd PersistentPostRun with args: %v\n", args) + }, + } + + rootCmd.AddCommand(subCmd) + + rootCmd.SetArgs([]string{""}) + _ = rootCmd.Execute() + fmt.Print("\n") + rootCmd.SetArgs([]string{"sub", "arg1", "arg2"}) + _ = rootCmd.Execute() +} +``` + +## Generating markdown formatted documentation for your command + +Cobra can generate a markdown formatted document based on the subcommands, flags, etc. A simple example of how to do this for your command can be found in [Markdown Docs](md_docs.md) + +## Generating bash completions for your command + +Cobra can generate a bash completions file. If you add more information to your command these completions can be amazingly powerful and flexible. Read more about [Bash Completions](bash_completions.md) ## Debugging diff --git a/vendor/_nuts/github.com/spf13/cobra/bash_completions.go b/vendor/_nuts/github.com/spf13/cobra/bash_completions.go new file mode 100644 index 00000000..29ad2f91 --- /dev/null +++ b/vendor/_nuts/github.com/spf13/cobra/bash_completions.go @@ -0,0 +1,387 @@ +package cobra + +import ( + "bytes" + "fmt" + "os" + "sort" + "strings" + + "github.com/github/git-lfs/vendor/_nuts/github.com/spf13/pflag" +) + +const ( + BashCompFilenameExt = "cobra_annotation_bash_completion_filename_extentions" + BashCompOneRequiredFlag = "cobra_annotation_bash_completion_one_required_flag" + BashCompSubdirsInDir = "cobra_annotation_bash_completion_subdirs_in_dir" +) + +func preamble(out *bytes.Buffer) { + fmt.Fprintf(out, `#!/bin/bash + + +__debug() +{ + if [[ -n ${BASH_COMP_DEBUG_FILE} ]]; then + echo "$*" >> "${BASH_COMP_DEBUG_FILE}" + fi +} + +__index_of_word() +{ + local w word=$1 + shift + index=0 + for w in "$@"; do + [[ $w = "$word" ]] && return + index=$((index+1)) + done + index=-1 +} + +__contains_word() +{ + local w word=$1; shift + for w in "$@"; do + [[ $w = "$word" ]] && return + done + return 1 +} + +__handle_reply() +{ + __debug "${FUNCNAME}" + case $cur in + -*) + compopt -o nospace + local allflags + if [ ${#must_have_one_flag[@]} -ne 0 ]; then + allflags=("${must_have_one_flag[@]}") + else + allflags=("${flags[*]} ${two_word_flags[*]}") + fi + COMPREPLY=( $(compgen -W "${allflags[*]}" -- "$cur") ) + [[ $COMPREPLY == *= ]] || compopt +o nospace + return 0; + ;; + esac + + # check if we are handling a flag with special work handling + local index + __index_of_word "${prev}" "${flags_with_completion[@]}" + if [[ ${index} -ge 0 ]]; then + ${flags_completion[${index}]} + return + fi + + # we are parsing a flag and don't have a special handler, no completion + if [[ ${cur} != "${words[cword]}" ]]; then + return + fi + + local completions + if [[ ${#must_have_one_flag[@]} -ne 0 ]]; then + completions=("${must_have_one_flag[@]}") + elif [[ ${#must_have_one_noun[@]} -ne 0 ]]; then + completions=("${must_have_one_noun[@]}") + else + completions=("${commands[@]}") + fi + COMPREPLY=( $(compgen -W "${completions[*]}" -- "$cur") ) + + if [[ ${#COMPREPLY[@]} -eq 0 ]]; then + declare -F __custom_func >/dev/null && __custom_func + fi +} + +# The arguments should be in the form "ext1|ext2|extn" +__handle_filename_extension_flag() +{ + local ext="$1" + _filedir "@(${ext})" +} + +__handle_subdirs_in_dir_flag() +{ + local dir="$1" + pushd "${dir}" >/dev/null 2>&1 && _filedir -d && popd >/dev/null 2>&1 +} + +__handle_flag() +{ + __debug "${FUNCNAME}: c is $c words[c] is ${words[c]}" + + # if a command required a flag, and we found it, unset must_have_one_flag() + local flagname=${words[c]} + # if the word contained an = + if [[ ${words[c]} == *"="* ]]; then + flagname=${flagname%%=*} # strip everything after the = + flagname="${flagname}=" # but put the = back + fi + __debug "${FUNCNAME}: looking for ${flagname}" + if __contains_word "${flagname}" "${must_have_one_flag[@]}"; then + must_have_one_flag=() + fi + + # skip the argument to a two word flag + if __contains_word "${words[c]}" "${two_word_flags[@]}"; then + c=$((c+1)) + # if we are looking for a flags value, don't show commands + if [[ $c -eq $cword ]]; then + commands=() + fi + fi + + # skip the flag itself + c=$((c+1)) + +} + +__handle_noun() +{ + __debug "${FUNCNAME}: c is $c words[c] is ${words[c]}" + + if __contains_word "${words[c]}" "${must_have_one_noun[@]}"; then + must_have_one_noun=() + fi + + nouns+=("${words[c]}") + c=$((c+1)) +} + +__handle_command() +{ + __debug "${FUNCNAME}: c is $c words[c] is ${words[c]}" + + local next_command + if [[ -n ${last_command} ]]; then + next_command="_${last_command}_${words[c]}" + else + next_command="_${words[c]}" + fi + c=$((c+1)) + __debug "${FUNCNAME}: looking for ${next_command}" + declare -F $next_command >/dev/null && $next_command +} + +__handle_word() +{ + if [[ $c -ge $cword ]]; then + __handle_reply + return + fi + __debug "${FUNCNAME}: c is $c words[c] is ${words[c]}" + if [[ "${words[c]}" == -* ]]; then + __handle_flag + elif __contains_word "${words[c]}" "${commands[@]}"; then + __handle_command + else + __handle_noun + fi + __handle_word +} + +`) +} + +func postscript(out *bytes.Buffer, name string) { + fmt.Fprintf(out, "__start_%s()\n", name) + fmt.Fprintf(out, `{ + local cur prev words cword + _init_completion -s || return + + local c=0 + local flags=() + local two_word_flags=() + local flags_with_completion=() + local flags_completion=() + local commands=("%s") + local must_have_one_flag=() + local must_have_one_noun=() + local last_command + local nouns=() + + __handle_word +} + +`, name) + fmt.Fprintf(out, "complete -F __start_%s %s\n", name, name) + fmt.Fprintf(out, "# ex: ts=4 sw=4 et filetype=sh\n") +} + +func writeCommands(cmd *Command, out *bytes.Buffer) { + fmt.Fprintf(out, " commands=()\n") + for _, c := range cmd.Commands() { + if len(c.Deprecated) > 0 { + continue + } + fmt.Fprintf(out, " commands+=(%q)\n", c.Name()) + } + fmt.Fprintf(out, "\n") +} + +func writeFlagHandler(name string, annotations map[string][]string, out *bytes.Buffer) { + for key, value := range annotations { + switch key { + case BashCompFilenameExt: + fmt.Fprintf(out, " flags_with_completion+=(%q)\n", name) + + if len(value) > 0 { + ext := "__handle_filename_extension_flag " + strings.Join(value, "|") + fmt.Fprintf(out, " flags_completion+=(%q)\n", ext) + } else { + ext := "_filedir" + fmt.Fprintf(out, " flags_completion+=(%q)\n", ext) + } + case BashCompSubdirsInDir: + fmt.Fprintf(out, " flags_with_completion+=(%q)\n", name) + + if len(value) == 1 { + ext := "__handle_subdirs_in_dir_flag " + value[0] + fmt.Fprintf(out, " flags_completion+=(%q)\n", ext) + } else { + ext := "_filedir -d" + fmt.Fprintf(out, " flags_completion+=(%q)\n", ext) + } + } + } +} + +func writeShortFlag(flag *pflag.Flag, out *bytes.Buffer) { + b := (flag.Value.Type() == "bool") + name := flag.Shorthand + format := " " + if !b { + format += "two_word_" + } + format += "flags+=(\"-%s\")\n" + fmt.Fprintf(out, format, name) + writeFlagHandler("-"+name, flag.Annotations, out) +} + +func writeFlag(flag *pflag.Flag, out *bytes.Buffer) { + b := (flag.Value.Type() == "bool") + name := flag.Name + format := " flags+=(\"--%s" + if !b { + format += "=" + } + format += "\")\n" + fmt.Fprintf(out, format, name) + writeFlagHandler("--"+name, flag.Annotations, out) +} + +func writeFlags(cmd *Command, out *bytes.Buffer) { + fmt.Fprintf(out, ` flags=() + two_word_flags=() + flags_with_completion=() + flags_completion=() + +`) + cmd.NonInheritedFlags().VisitAll(func(flag *pflag.Flag) { + writeFlag(flag, out) + if len(flag.Shorthand) > 0 { + writeShortFlag(flag, out) + } + }) + + fmt.Fprintf(out, "\n") +} + +func writeRequiredFlag(cmd *Command, out *bytes.Buffer) { + fmt.Fprintf(out, " must_have_one_flag=()\n") + flags := cmd.NonInheritedFlags() + flags.VisitAll(func(flag *pflag.Flag) { + for key, _ := range flag.Annotations { + switch key { + case BashCompOneRequiredFlag: + format := " must_have_one_flag+=(\"--%s" + b := (flag.Value.Type() == "bool") + if !b { + format += "=" + } + format += "\")\n" + fmt.Fprintf(out, format, flag.Name) + + if len(flag.Shorthand) > 0 { + fmt.Fprintf(out, " must_have_one_flag+=(\"-%s\")\n", flag.Shorthand) + } + } + } + }) +} + +func writeRequiredNoun(cmd *Command, out *bytes.Buffer) { + fmt.Fprintf(out, " must_have_one_noun=()\n") + sort.Sort(sort.StringSlice(cmd.ValidArgs)) + for _, value := range cmd.ValidArgs { + fmt.Fprintf(out, " must_have_one_noun+=(%q)\n", value) + } +} + +func gen(cmd *Command, out *bytes.Buffer) { + for _, c := range cmd.Commands() { + if len(c.Deprecated) > 0 { + continue + } + gen(c, out) + } + commandName := cmd.CommandPath() + commandName = strings.Replace(commandName, " ", "_", -1) + fmt.Fprintf(out, "_%s()\n{\n", commandName) + fmt.Fprintf(out, " last_command=%q\n", commandName) + writeCommands(cmd, out) + writeFlags(cmd, out) + writeRequiredFlag(cmd, out) + writeRequiredNoun(cmd, out) + fmt.Fprintf(out, "}\n\n") +} + +func (cmd *Command) GenBashCompletion(out *bytes.Buffer) { + preamble(out) + if len(cmd.BashCompletionFunction) > 0 { + fmt.Fprintf(out, "%s\n", cmd.BashCompletionFunction) + } + gen(cmd, out) + postscript(out, cmd.Name()) +} + +func (cmd *Command) GenBashCompletionFile(filename string) error { + out := new(bytes.Buffer) + + cmd.GenBashCompletion(out) + + outFile, err := os.Create(filename) + if err != nil { + return err + } + defer outFile.Close() + + _, err = outFile.Write(out.Bytes()) + if err != nil { + return err + } + return nil +} + +// MarkFlagRequired adds the BashCompOneRequiredFlag annotation to the named flag, if it exists. +func (cmd *Command) MarkFlagRequired(name string) error { + return MarkFlagRequired(cmd.Flags(), name) +} + +// MarkFlagRequired adds the BashCompOneRequiredFlag annotation to the named flag in the flag set, if it exists. +func MarkFlagRequired(flags *pflag.FlagSet, name string) error { + return flags.SetAnnotation(name, BashCompOneRequiredFlag, []string{"true"}) +} + +// MarkFlagFilename adds the BashCompFilenameExt annotation to the named flag, if it exists. +// Generated bash autocompletion will select filenames for the flag, limiting to named extensions if provided. +func (cmd *Command) MarkFlagFilename(name string, extensions ...string) error { + return MarkFlagFilename(cmd.Flags(), name, extensions...) +} + +// MarkFlagFilename adds the BashCompFilenameExt annotation to the named flag in the flag set, if it exists. +// Generated bash autocompletion will select filenames for the flag, limiting to named extensions if provided. +func MarkFlagFilename(flags *pflag.FlagSet, name string, extensions ...string) error { + return flags.SetAnnotation(name, BashCompFilenameExt, extensions) +} diff --git a/vendor/_nuts/github.com/spf13/cobra/bash_completions.md b/vendor/_nuts/github.com/spf13/cobra/bash_completions.md new file mode 100644 index 00000000..204704ef --- /dev/null +++ b/vendor/_nuts/github.com/spf13/cobra/bash_completions.md @@ -0,0 +1,149 @@ +# Generating Bash Completions For Your Own cobra.Command + +Generating bash completions from a cobra command is incredibly easy. An actual program which does so for the kubernetes kubectl binary is as follows: + +```go +package main + +import ( + "io/ioutil" + "os" + + "github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl/cmd" +) + +func main() { + kubectl := cmd.NewFactory(nil).NewKubectlCommand(os.Stdin, ioutil.Discard, ioutil.Discard) + kubectl.GenBashCompletionFile("out.sh") +} +``` + +That will get you completions of subcommands and flags. If you make additional annotations to your code, you can get even more intelligent and flexible behavior. + +## Creating your own custom functions + +Some more actual code that works in kubernetes: + +```bash +const ( + bash_completion_func = `__kubectl_parse_get() +{ + local kubectl_output out + if kubectl_output=$(kubectl get --no-headers "$1" 2>/dev/null); then + out=($(echo "${kubectl_output}" | awk '{print $1}')) + COMPREPLY=( $( compgen -W "${out[*]}" -- "$cur" ) ) + fi +} + +__kubectl_get_resource() +{ + if [[ ${#nouns[@]} -eq 0 ]]; then + return 1 + fi + __kubectl_parse_get ${nouns[${#nouns[@]} -1]} + if [[ $? -eq 0 ]]; then + return 0 + fi +} + +__custom_func() { + case ${last_command} in + kubectl_get | kubectl_describe | kubectl_delete | kubectl_stop) + __kubectl_get_resource + return + ;; + *) + ;; + esac +} +`) +``` + +And then I set that in my command definition: + +```go +cmds := &cobra.Command{ + Use: "kubectl", + Short: "kubectl controls the Kubernetes cluster manager", + Long: `kubectl controls the Kubernetes cluster manager. + +Find more information at https://github.com/GoogleCloudPlatform/kubernetes.`, + Run: runHelp, + BashCompletionFunction: bash_completion_func, +} +``` + +The `BashCompletionFunction` option is really only valid/useful on the root command. Doing the above will cause `__custom_func()` to be called when the built in processor was unable to find a solution. In the case of kubernetes a valid command might look something like `kubectl get pod [mypod]`. If you type `kubectl get pod [tab][tab]` the `__customc_func()` will run because the cobra.Command only understood "kubectl" and "get." `__custom_func()` will see that the cobra.Command is "kubectl_get" and will thus call another helper `__kubectl_get_resource()`. `__kubectl_get_resource` will look at the 'nouns' collected. In our example the only noun will be `pod`. So it will call `__kubectl_parse_get pod`. `__kubectl_parse_get` will actually call out to kubernetes and get any pods. It will then set `COMPREPLY` to valid pods! + +## Have the completions code complete your 'nouns' + +In the above example "pod" was assumed to already be typed. But if you want `kubectl get [tab][tab]` to show a list of valid "nouns" you have to set them. Simplified code from `kubectl get` looks like: + +```go +validArgs []string = { "pods", "nodes", "services", "replicationControllers" } + +cmd := &cobra.Command{ + Use: "get [(-o|--output=)json|yaml|template|...] (RESOURCE [NAME] | RESOURCE/NAME ...)", + Short: "Display one or many resources", + Long: get_long, + Example: get_example, + Run: func(cmd *cobra.Command, args []string) { + err := RunGet(f, out, cmd, args) + util.CheckErr(err) + }, + ValidArgs: validArgs, +} +``` + +Notice we put the "ValidArgs" on the "get" subcommand. Doing so will give results like + +```bash +# kubectl get [tab][tab] +nodes pods replicationControllers services +``` + +## Mark flags as required + +Most of the time completions will only show subcommands. But if a flag is required to make a subcommand work, you probably want it to show up when the user types [tab][tab]. Marking a flag as 'Required' is incredibly easy. + +```go +cmd.MarkFlagRequired("pod") +cmd.MarkFlagRequired("container") +``` + +and you'll get something like + +```bash +# kubectl exec [tab][tab][tab] +-c --container= -p --pod= +``` + +# Specify valid filename extensions for flags that take a filename + +In this example we use --filename= and expect to get a json or yaml file as the argument. To make this easier we annotate the --filename flag with valid filename extensions. + +```go + annotations := []string{"json", "yaml", "yml"} + annotation := make(map[string][]string) + annotation[cobra.BashCompFilenameExt] = annotations + + flag := &pflag.Flag{ + Name: "filename", + Shorthand: "f", + Usage: usage, + Value: value, + DefValue: value.String(), + Annotations: annotation, + } + cmd.Flags().AddFlag(flag) +``` + +Now when you run a command with this filename flag you'll get something like + +```bash +# kubectl create -f +test/ example/ rpmbuild/ +hello.yml test.json +``` + +So while there are many other files in the CWD it only shows me subdirs and those with valid extensions. diff --git a/vendor/_nuts/github.com/spf13/cobra/bash_completions_test.go b/vendor/_nuts/github.com/spf13/cobra/bash_completions_test.go new file mode 100644 index 00000000..a1f2b13c --- /dev/null +++ b/vendor/_nuts/github.com/spf13/cobra/bash_completions_test.go @@ -0,0 +1,87 @@ +package cobra + +import ( + "bytes" + "fmt" + "os" + "strings" + "testing" +) + +var _ = fmt.Println +var _ = os.Stderr + +func checkOmit(t *testing.T, found, unexpected string) { + if strings.Contains(found, unexpected) { + t.Errorf("Unexpected response.\nGot: %q\nBut should not have!\n", unexpected) + } +} + +func check(t *testing.T, found, expected string) { + if !strings.Contains(found, expected) { + t.Errorf("Unexpected response.\nExpecting to contain: \n %q\nGot:\n %q\n", expected, found) + } +} + +// World worst custom function, just keep telling you to enter hello! +const ( + bash_completion_func = `__custom_func() { +COMPREPLY=( "hello" ) +} +` +) + +func TestBashCompletions(t *testing.T) { + c := initializeWithRootCmd() + cmdEcho.AddCommand(cmdTimes) + c.AddCommand(cmdEcho, cmdPrint, cmdDeprecated) + + // custom completion function + c.BashCompletionFunction = bash_completion_func + + // required flag + c.MarkFlagRequired("introot") + + // valid nouns + validArgs := []string{"pods", "nodes", "services", "replicationControllers"} + c.ValidArgs = validArgs + + // filename + var flagval string + c.Flags().StringVar(&flagval, "filename", "", "Enter a filename") + c.MarkFlagFilename("filename", "json", "yaml", "yml") + + // filename extensions + var flagvalExt string + c.Flags().StringVar(&flagvalExt, "filename-ext", "", "Enter a filename (extension limited)") + c.MarkFlagFilename("filename-ext") + + // subdirectories in a given directory + var flagvalTheme string + c.Flags().StringVar(&flagvalTheme, "theme", "", "theme to use (located in /themes/THEMENAME/)") + c.Flags().SetAnnotation("theme", BashCompSubdirsInDir, []string{"themes"}) + + out := new(bytes.Buffer) + c.GenBashCompletion(out) + str := out.String() + + check(t, str, "_cobra-test") + check(t, str, "_cobra-test_echo") + check(t, str, "_cobra-test_echo_times") + check(t, str, "_cobra-test_print") + + // check for required flags + check(t, str, `must_have_one_flag+=("--introot=")`) + // check for custom completion function + check(t, str, `COMPREPLY=( "hello" )`) + // check for required nouns + check(t, str, `must_have_one_noun+=("pods")`) + // check for filename extension flags + check(t, str, `flags_completion+=("_filedir")`) + // check for filename extension flags + check(t, str, `flags_completion+=("__handle_filename_extension_flag json|yaml|yml")`) + // check for subdirs_in_dir flags + check(t, str, `flags_completion+=("__handle_subdirs_in_dir_flag themes")`) + + checkOmit(t, str, cmdDeprecated.Name()) +} diff --git a/vendor/_nuts/github.com/spf13/cobra/cobra.go b/vendor/_nuts/github.com/spf13/cobra/cobra.go index 039c1853..78b92b0a 100644 --- a/vendor/_nuts/github.com/spf13/cobra/cobra.go +++ b/vendor/_nuts/github.com/spf13/cobra/cobra.go @@ -27,12 +27,28 @@ import ( var initializers []func() +// automatic prefix matching can be a dangerous thing to automatically enable in CLI tools. +// Set this to true to enable it +var EnablePrefixMatching bool = false + +// enables an information splash screen on Windows if the CLI is started from explorer.exe. +var EnableWindowsMouseTrap bool = true + +var MousetrapHelpText string = `This is a command line tool + +You need to open cmd.exe and run it from there. +` + +//OnInitialize takes a series of func() arguments and appends them to a slice of func(). func OnInitialize(y ...func()) { for _, x := range y { initializers = append(initializers, x) } } +//Gt takes two types and checks whether the first type is greater than the second. In case of types Arrays, Chans, +//Maps and Slices, Gt will compare their lengths. Ints are compared directly while strings are first parsed as +//ints and then compared. func Gt(a interface{}, b interface{}) bool { var left, right int64 av := reflect.ValueOf(a) @@ -60,6 +76,7 @@ func Gt(a interface{}, b interface{}) bool { return left > right } +//Eq takes two types and checks whether they are equal. Supported types are int and string. Unsupported types will panic. func Eq(a interface{}, b interface{}) bool { av := reflect.ValueOf(a) bv := reflect.ValueOf(b) @@ -75,6 +92,7 @@ func Eq(a interface{}, b interface{}) bool { return false } +//rpad adds padding to the right of a string func rpad(s string, padding int) string { template := fmt.Sprintf("%%-%ds", padding) return fmt.Sprintf(template, s) diff --git a/vendor/_nuts/github.com/spf13/cobra/cobra_test.go b/vendor/_nuts/github.com/spf13/cobra/cobra_test.go index 5f4af277..c636692e 100644 --- a/vendor/_nuts/github.com/spf13/cobra/cobra_test.go +++ b/vendor/_nuts/github.com/spf13/cobra/cobra_test.go @@ -3,48 +3,92 @@ package cobra import ( "bytes" "fmt" + "os" + "reflect" + "runtime" "strings" "testing" + + "github.com/github/git-lfs/vendor/_nuts/github.com/spf13/pflag" ) var _ = fmt.Println +var _ = os.Stderr -var tp, te, tt, t1 []string -var flagb1, flagb2, flagb3, flagbr bool -var flags1, flags2, flags3 string +var tp, te, tt, t1, tr []string +var rootPersPre, echoPre, echoPersPre, timesPersPre []string +var flagb1, flagb2, flagb3, flagbr, flagbp bool +var flags1, flags2a, flags2b, flags3 string var flagi1, flagi2, flagi3, flagir int var globalFlag1 bool var flagEcho, rootcalled bool +var versionUsed int + +const strtwoParentHelp = "help message for parent flag strtwo" +const strtwoChildHelp = "help message for child flag strtwo" var cmdPrint = &Command{ Use: "print [string to print]", Short: "Print anything to the screen", - Long: `an utterly useless command for testing.`, + Long: `an absolutely utterly useless command for testing.`, Run: func(cmd *Command, args []string) { tp = args }, } var cmdEcho = &Command{ - Use: "echo [string to echo]", - Short: "Echo anything to the screen", - Long: `an utterly useless command for testing.`, + Use: "echo [string to echo]", + Aliases: []string{"say"}, + Short: "Echo anything to the screen", + Long: `an utterly useless command for testing.`, + Example: "Just run cobra-test echo", + PersistentPreRun: func(cmd *Command, args []string) { + echoPersPre = args + }, + PreRun: func(cmd *Command, args []string) { + echoPre = args + }, Run: func(cmd *Command, args []string) { te = args }, } +var cmdEchoSub = &Command{ + Use: "echosub [string to print]", + Short: "second sub command for echo", + Long: `an absolutely utterly useless command for testing gendocs!.`, + Run: func(cmd *Command, args []string) { + }, +} + +var cmdDeprecated = &Command{ + Use: "deprecated [can't do anything here]", + Short: "A command which is deprecated", + Long: `an absolutely utterly useless command for testing deprecation!.`, + Deprecated: "Please use echo instead", + Run: func(cmd *Command, args []string) { + }, +} + var cmdTimes = &Command{ Use: "times [# times] [string to echo]", Short: "Echo anything to the screen more times", - Long: `an slightly useless command for testing.`, - Run: timesRunner, + Long: `a slightly useless command for testing.`, + PersistentPreRun: func(cmd *Command, args []string) { + timesPersPre = args + }, + Run: func(cmd *Command, args []string) { + tt = args + }, } var cmdRootNoRun = &Command{ Use: "cobra-test", Short: "The root can run it's own function", Long: "The root description for help", + PersistentPreRun: func(cmd *Command, args []string) { + rootPersPre = args + }, } var cmdRootSameName = &Command{ @@ -58,12 +102,33 @@ var cmdRootWithRun = &Command{ Short: "The root can run it's own function", Long: "The root description for help", Run: func(cmd *Command, args []string) { + tr = args rootcalled = true }, } -func timesRunner(cmd *Command, args []string) { - tt = args +var cmdSubNoRun = &Command{ + Use: "subnorun", + Short: "A subcommand without a Run function", + Long: "A long output about a subcommand without a Run function", +} + +var cmdVersion1 = &Command{ + Use: "version", + Short: "Print the version number", + Long: `First version of the version command`, + Run: func(cmd *Command, args []string) { + versionUsed = 1 + }, +} + +var cmdVersion2 = &Command{ + Use: "version", + Short: "Print the version number", + Long: `Second version of the version command`, + Run: func(cmd *Command, args []string) { + versionUsed = 2 + }, } func flagInit() { @@ -73,15 +138,20 @@ func flagInit() { cmdRootNoRun.ResetFlags() cmdRootSameName.ResetFlags() cmdRootWithRun.ResetFlags() + cmdSubNoRun.ResetFlags() + cmdRootNoRun.PersistentFlags().StringVarP(&flags2a, "strtwo", "t", "two", strtwoParentHelp) cmdEcho.Flags().IntVarP(&flagi1, "intone", "i", 123, "help message for flag intone") cmdTimes.Flags().IntVarP(&flagi2, "inttwo", "j", 234, "help message for flag inttwo") cmdPrint.Flags().IntVarP(&flagi3, "intthree", "i", 345, "help message for flag intthree") cmdEcho.PersistentFlags().StringVarP(&flags1, "strone", "s", "one", "help message for flag strone") - cmdTimes.PersistentFlags().StringVarP(&flags2, "strtwo", "t", "two", "help message for flag strtwo") + cmdEcho.PersistentFlags().BoolVarP(&flagbp, "persistentbool", "p", false, "help message for flag persistentbool") + cmdTimes.PersistentFlags().StringVarP(&flags2b, "strtwo", "t", "2", strtwoChildHelp) cmdPrint.PersistentFlags().StringVarP(&flags3, "strthree", "s", "three", "help message for flag strthree") cmdEcho.Flags().BoolVarP(&flagb1, "boolone", "b", true, "help message for flag boolone") cmdTimes.Flags().BoolVarP(&flagb2, "booltwo", "c", false, "help message for flag booltwo") cmdPrint.Flags().BoolVarP(&flagb3, "boolthree", "b", true, "help message for flag boolthree") + cmdVersion1.ResetFlags() + cmdVersion2.ResetFlags() } func commandInit() { @@ -91,10 +161,13 @@ func commandInit() { cmdRootNoRun.ResetCommands() cmdRootSameName.ResetCommands() cmdRootWithRun.ResetCommands() + cmdSubNoRun.ResetCommands() } func initialize() *Command { tt, tp, te = nil, nil, nil + rootPersPre, echoPre, echoPersPre, timesPersPre = nil, nil, nil, nil + var c = cmdRootNoRun flagInit() commandInit() @@ -103,6 +176,7 @@ func initialize() *Command { func initializeWithSameName() *Command { tt, tp, te = nil, nil, nil + rootPersPre, echoPre, echoPersPre, timesPersPre = nil, nil, nil, nil var c = cmdRootSameName flagInit() commandInit() @@ -111,7 +185,7 @@ func initializeWithSameName() *Command { func initializeWithRootCmd() *Command { cmdRootWithRun.ResetCommands() - tt, tp, te, rootcalled = nil, nil, nil, false + tt, tp, te, tr, rootcalled = nil, nil, nil, nil, false flagInit() cmdRootWithRun.Flags().BoolVarP(&flagbr, "boolroot", "b", false, "help message for flag boolroot") cmdRootWithRun.Flags().IntVarP(&flagir, "introot", "i", 321, "help message for flag introot") @@ -137,12 +211,16 @@ func noRRSetupTest(input string) resulter { return fullTester(c, input) } -func fullTester(c *Command, input string) resulter { +func rootOnlySetupTest(input string) resulter { + c := initializeWithRootCmd() + + return simpleTester(c, input) +} + +func simpleTester(c *Command, input string) resulter { buf := new(bytes.Buffer) // Testing flag with invalid input c.SetOutput(buf) - cmdEcho.AddCommand(cmdTimes) - c.AddCommand(cmdPrint, cmdEcho) c.SetArgs(strings.Split(input, " ")) err := c.Execute() @@ -151,9 +229,40 @@ func fullTester(c *Command, input string) resulter { return resulter{err, output, c} } +func fullTester(c *Command, input string) resulter { + buf := new(bytes.Buffer) + // Testing flag with invalid input + c.SetOutput(buf) + cmdEcho.AddCommand(cmdTimes) + c.AddCommand(cmdPrint, cmdEcho, cmdSubNoRun, cmdDeprecated) + c.SetArgs(strings.Split(input, " ")) + + err := c.Execute() + output := buf.String() + + return resulter{err, output, c} +} + +func logErr(t *testing.T, found, expected string) { + out := new(bytes.Buffer) + + _, _, line, ok := runtime.Caller(2) + if ok { + fmt.Fprintf(out, "Line: %d ", line) + } + fmt.Fprintf(out, "Unexpected response.\nExpecting to contain: \n %q\nGot:\n %q\n", expected, found) + t.Errorf(out.String()) +} + func checkResultContains(t *testing.T, x resulter, check string) { if !strings.Contains(x.Output, check) { - t.Errorf("Unexpected response.\nExpecting to contain: \n %q\nGot:\n %q\n", check, x.Output) + logErr(t, x.Output, check) + } +} + +func checkResultOmits(t *testing.T, x resulter, check string) { + if strings.Contains(x.Output, check) { + logErr(t, x.Output, check) } } @@ -163,7 +272,7 @@ func checkOutputContains(t *testing.T, c *Command, check string) { c.Execute() if !strings.Contains(buf.String(), check) { - t.Errorf("Unexpected response.\nExpecting to contain: \n %q\nGot:\n %q\n", check, buf.String()) + logErr(t, buf.String(), check) } } @@ -195,8 +304,8 @@ func TestChildCommand(t *testing.T) { } } -func TestChildCommandPrefix(t *testing.T) { - noRRSetupTest("ech tim one two") +func TestCommandAlias(t *testing.T) { + noRRSetupTest("say times one two") if te != nil || tp != nil { t.Error("Wrong command called") @@ -209,6 +318,49 @@ func TestChildCommandPrefix(t *testing.T) { } } +func TestPrefixMatching(t *testing.T) { + EnablePrefixMatching = true + noRRSetupTest("ech times one two") + + if te != nil || tp != nil { + t.Error("Wrong command called") + } + if tt == nil { + t.Error("Wrong command called") + } + if strings.Join(tt, " ") != "one two" { + t.Error("Command didn't parse correctly") + } + + EnablePrefixMatching = false +} + +func TestNoPrefixMatching(t *testing.T) { + EnablePrefixMatching = false + + noRRSetupTest("ech times one two") + + if !(tt == nil && te == nil && tp == nil) { + t.Error("Wrong command called") + } +} + +func TestAliasPrefixMatching(t *testing.T) { + EnablePrefixMatching = true + noRRSetupTest("sa times one two") + + if te != nil || tp != nil { + t.Error("Wrong command called") + } + if tt == nil { + t.Error("Wrong command called") + } + if strings.Join(tt, " ") != "one two" { + t.Error("Command didn't parse correctly") + } + EnablePrefixMatching = false +} + func TestChildSameName(t *testing.T) { c := initializeWithSameName() c.AddCommand(cmdPrint, cmdEcho) @@ -226,10 +378,11 @@ func TestChildSameName(t *testing.T) { } } -func TestChildSameNamePrefix(t *testing.T) { +func TestGrandChildSameName(t *testing.T) { c := initializeWithSameName() - c.AddCommand(cmdPrint, cmdEcho) - c.SetArgs(strings.Split("pr one two", " ")) + cmdTimes.AddCommand(cmdPrint) + c.AddCommand(cmdTimes) + c.SetArgs(strings.Split("times print one two", " ")) c.Execute() if te != nil || tt != nil { @@ -328,10 +481,21 @@ func TestChildCommandFlags(t *testing.T) { t.Errorf("invalid flag should generate error") } - if !strings.Contains(r.Output, "intone=123") { + if !strings.Contains(r.Output, "unknown shorthand flag") { t.Errorf("Wrong error message displayed, \n %s", r.Output) } + // Testing with persistent flag overwritten by child + noRRSetupTest("echo times --strtwo=child one two") + + if flags2b != "child" { + t.Errorf("flag value should be child, %s given", flags2b) + } + + if flags2a != "two" { + t.Errorf("unset flag should have default value, expecting two, given %s", flags2a) + } + // Testing flag with invalid input r = noRRSetupTest("echo -i10E") @@ -339,7 +503,7 @@ func TestChildCommandFlags(t *testing.T) { t.Errorf("invalid input should generate error") } - if !strings.Contains(r.Output, "invalid argument \"10E\" for -i10E") { + if !strings.Contains(r.Output, "invalid argument \"10E\" for i10E") { t.Errorf("Wrong error message displayed, \n %s", r.Output) } } @@ -352,20 +516,62 @@ func TestTrailingCommandFlags(t *testing.T) { } } +func TestInvalidSubcommandFlags(t *testing.T) { + cmd := initializeWithRootCmd() + cmd.AddCommand(cmdTimes) + + result := simpleTester(cmd, "times --inttwo=2 --badflag=bar") + + checkResultContains(t, result, "unknown flag: --badflag") + + if strings.Contains(result.Output, "unknown flag: --inttwo") { + t.Errorf("invalid --badflag flag shouldn't fail on 'unknown' --inttwo flag") + } + +} + +func TestSubcommandArgEvaluation(t *testing.T) { + cmd := initializeWithRootCmd() + + first := &Command{ + Use: "first", + Run: func(cmd *Command, args []string) { + }, + } + cmd.AddCommand(first) + + second := &Command{ + Use: "second", + Run: func(cmd *Command, args []string) { + fmt.Fprintf(cmd.Out(), "%v", args) + }, + } + first.AddCommand(second) + + result := simpleTester(cmd, "first second first third") + + expectedOutput := fmt.Sprintf("%v", []string{"first third"}) + if result.Output != expectedOutput { + t.Errorf("exptected %v, got %v", expectedOutput, result.Output) + } +} + func TestPersistentFlags(t *testing.T) { - fullSetupTest("echo -s something more here") + fullSetupTest("echo -s something -p more here") // persistentFlag should act like normal flag on it's own command if strings.Join(te, " ") != "more here" { t.Errorf("flags didn't leave proper args remaining..%s given", te) } - - // persistentFlag should act like normal flag on it's own command if flags1 != "something" { t.Errorf("string flag didn't get correct value, had %v", flags1) } + if !flagbp { + t.Errorf("persistent bool flag not parsed correctly. Expected true, had %v", flagbp) + } - fullSetupTest("echo times -s again -c test here") + // persistentFlag should act like normal flag on it's own command + fullSetupTest("echo times -s again -c -p test here") if strings.Join(tt, " ") != "test here" { t.Errorf("flags didn't leave proper args remaining..%s given", tt) @@ -375,17 +581,35 @@ func TestPersistentFlags(t *testing.T) { t.Errorf("string flag didn't get correct value, had %v", flags1) } - if flagb2 != true { - t.Errorf("local flag not parsed correctly. Expected false, had %v", flagb2) + if !flagb2 { + t.Errorf("local flag not parsed correctly. Expected true, had %v", flagb2) + } + if !flagbp { + t.Errorf("persistent bool flag not parsed correctly. Expected true, had %v", flagbp) } } func TestHelpCommand(t *testing.T) { - c := fullSetupTest("help echo") - checkResultContains(t, c, cmdEcho.Long) + x := fullSetupTest("help") + checkResultContains(t, x, cmdRootWithRun.Long) - r := fullSetupTest("help echo times") - checkResultContains(t, r, cmdTimes.Long) + x = fullSetupTest("help echo") + checkResultContains(t, x, cmdEcho.Long) + + x = fullSetupTest("help echo times") + checkResultContains(t, x, cmdTimes.Long) +} + +func TestChildCommandHelp(t *testing.T) { + c := noRRSetupTest("print --help") + checkResultContains(t, c, strtwoParentHelp) + r := noRRSetupTest("echo times --help") + checkResultContains(t, r, strtwoChildHelp) +} + +func TestNonRunChildHelp(t *testing.T) { + x := noRRSetupTest("subnorun") + checkResultContains(t, x, cmdSubNoRun.Long) } func TestRunnableRootCommand(t *testing.T) { @@ -396,6 +620,53 @@ func TestRunnableRootCommand(t *testing.T) { } } +func TestRunnableRootCommandNilInput(t *testing.T) { + empty_arg := make([]string, 0) + c := initializeWithRootCmd() + + buf := new(bytes.Buffer) + // Testing flag with invalid input + c.SetOutput(buf) + cmdEcho.AddCommand(cmdTimes) + c.AddCommand(cmdPrint, cmdEcho) + c.SetArgs(empty_arg) + + c.Execute() + + if rootcalled != true { + t.Errorf("Root Function was not called") + } +} + +func TestRunnableRootCommandEmptyInput(t *testing.T) { + args := make([]string, 3) + args[0] = "" + args[1] = "--introot=12" + args[2] = "" + c := initializeWithRootCmd() + + buf := new(bytes.Buffer) + // Testing flag with invalid input + c.SetOutput(buf) + cmdEcho.AddCommand(cmdTimes) + c.AddCommand(cmdPrint, cmdEcho) + c.SetArgs(args) + + c.Execute() + + if rootcalled != true { + t.Errorf("Root Function was not called.\n\nOutput was:\n\n%s\n", buf) + } +} + +func TestInvalidSubcommandWhenArgsAllowed(t *testing.T) { + fullSetupTest("echo invalid-sub") + + if te[0] != "invalid-sub" { + t.Errorf("Subcommand didn't work...") + } +} + func TestRootFlags(t *testing.T) { fullSetupTest("-i 17 -b") @@ -412,14 +683,24 @@ func TestRootHelp(t *testing.T) { x := fullSetupTest("--help") checkResultContains(t, x, "Available Commands:") + checkResultContains(t, x, "for more information about a command") if strings.Contains(x.Output, "unknown flag: --help") { t.Errorf("--help shouldn't trigger an error, Got: \n %s", x.Output) } + if strings.Contains(x.Output, cmdEcho.Use) { + t.Errorf("--help shouldn't display subcommand's usage, Got: \n %s", x.Output) + } + x = fullSetupTest("echo --help") + if strings.Contains(x.Output, cmdTimes.Use) { + t.Errorf("--help shouldn't display subsubcommand's usage, Got: \n %s", x.Output) + } + checkResultContains(t, x, "Available Commands:") + checkResultContains(t, x, "for more information about a command") if strings.Contains(x.Output, "unknown flag: --help") { t.Errorf("--help shouldn't trigger an error, Got: \n %s", x.Output) @@ -427,6 +708,78 @@ func TestRootHelp(t *testing.T) { } +func TestFlagAccess(t *testing.T) { + initialize() + + local := cmdTimes.LocalFlags() + inherited := cmdTimes.InheritedFlags() + + for _, f := range []string{"inttwo", "strtwo", "booltwo"} { + if local.Lookup(f) == nil { + t.Errorf("LocalFlags expected to contain %s, Got: nil", f) + } + } + if inherited.Lookup("strone") == nil { + t.Errorf("InheritedFlags expected to contain strone, Got: nil") + } + if inherited.Lookup("strtwo") != nil { + t.Errorf("InheritedFlags shouldn not contain overwritten flag strtwo") + + } +} + +func TestNoNRunnableRootCommandNilInput(t *testing.T) { + args := make([]string, 0) + c := initialize() + + buf := new(bytes.Buffer) + // Testing flag with invalid input + c.SetOutput(buf) + cmdEcho.AddCommand(cmdTimes) + c.AddCommand(cmdPrint, cmdEcho) + c.SetArgs(args) + + c.Execute() + + if !strings.Contains(buf.String(), cmdRootNoRun.Long) { + t.Errorf("Expected to get help output, Got: \n %s", buf) + } +} + +func TestRootNoCommandHelp(t *testing.T) { + x := rootOnlySetupTest("--help") + + checkResultOmits(t, x, "Available Commands:") + checkResultOmits(t, x, "for more information about a command") + + if strings.Contains(x.Output, "unknown flag: --help") { + t.Errorf("--help shouldn't trigger an error, Got: \n %s", x.Output) + } + + x = rootOnlySetupTest("echo --help") + + checkResultOmits(t, x, "Available Commands:") + checkResultOmits(t, x, "for more information about a command") + + if strings.Contains(x.Output, "unknown flag: --help") { + t.Errorf("--help shouldn't trigger an error, Got: \n %s", x.Output) + } +} + +func TestRootUnknownCommand(t *testing.T) { + r := noRRSetupTest("bogus") + s := "Error: unknown command \"bogus\" for \"cobra-test\"\nRun 'cobra-test --help' for usage.\n" + + if r.Output != s { + t.Errorf("Unexpected response.\nExpecting to be:\n %q\nGot:\n %q\n", s, r.Output) + } + + r = noRRSetupTest("--strtwo=a bogus") + if r.Output != s { + t.Errorf("Unexpected response.\nExpecting to be:\n %q\nGot:\n %q\n", s, r.Output) + } +} + func TestFlagsBeforeCommand(t *testing.T) { // short without space x := fullSetupTest("-i10 echo") @@ -451,7 +804,7 @@ func TestFlagsBeforeCommand(t *testing.T) { // With parsing error properly reported x = fullSetupTest("-i10E echo") - if !strings.Contains(x.Output, "invalid argument \"10E\" for -i10E") { + if !strings.Contains(x.Output, "invalid argument \"10E\" for i10E") { t.Errorf("Wrong error message displayed, \n %s", x.Output) } @@ -480,3 +833,133 @@ func TestFlagsBeforeCommand(t *testing.T) { } } + +func TestRemoveCommand(t *testing.T) { + versionUsed = 0 + c := initializeWithRootCmd() + c.AddCommand(cmdVersion1) + c.RemoveCommand(cmdVersion1) + x := fullTester(c, "version") + if x.Error == nil { + t.Errorf("Removed command should not have been called\n") + return + } +} + +func TestCommandWithoutSubcommands(t *testing.T) { + c := initializeWithRootCmd() + + x := simpleTester(c, "") + if x.Error != nil { + t.Errorf("Calling command without subcommands should not have error: %v", x.Error) + return + } +} + +func TestCommandWithoutSubcommandsWithArg(t *testing.T) { + c := initializeWithRootCmd() + expectedArgs := []string{"arg"} + + x := simpleTester(c, "arg") + if x.Error != nil { + t.Errorf("Calling command without subcommands but with arg should not have error: %v", x.Error) + return + } + if !reflect.DeepEqual(expectedArgs, tr) { + t.Errorf("Calling command without subcommands but with arg has wrong args: expected: %v, actual: %v", expectedArgs, tr) + return + } +} + +func TestReplaceCommandWithRemove(t *testing.T) { + versionUsed = 0 + c := initializeWithRootCmd() + c.AddCommand(cmdVersion1) + c.RemoveCommand(cmdVersion1) + c.AddCommand(cmdVersion2) + x := fullTester(c, "version") + if x.Error != nil { + t.Errorf("Valid Input shouldn't have errors, got:\n %q", x.Error) + return + } + if versionUsed == 1 { + t.Errorf("Removed command shouldn't be called\n") + } + if versionUsed != 2 { + t.Errorf("Replacing command should have been called but didn't\n") + } +} + +func TestDeprecatedSub(t *testing.T) { + c := fullSetupTest("deprecated") + + checkResultContains(t, c, cmdDeprecated.Deprecated) +} + +func TestPreRun(t *testing.T) { + noRRSetupTest("echo one two") + if echoPre == nil || echoPersPre == nil { + t.Error("PreRun or PersistentPreRun not called") + } + if rootPersPre != nil || timesPersPre != nil { + t.Error("Wrong *Pre functions called!") + } + + noRRSetupTest("echo times one two") + if timesPersPre == nil { + t.Error("PreRun or PersistentPreRun not called") + } + if echoPre != nil || echoPersPre != nil || rootPersPre != nil { + t.Error("Wrong *Pre functions called!") + } + + noRRSetupTest("print one two") + if rootPersPre == nil { + t.Error("Parent PersistentPreRun not called but should not have been") + } + if echoPre != nil || echoPersPre != nil || timesPersPre != nil { + t.Error("Wrong *Pre functions called!") + } +} + +// Check if cmdEchoSub gets PersistentPreRun from rootCmd even if is added last +func TestPeristentPreRunPropagation(t *testing.T) { + rootCmd := initialize() + + // First add the cmdEchoSub to cmdPrint + cmdPrint.AddCommand(cmdEchoSub) + // Now add cmdPrint to rootCmd + rootCmd.AddCommand(cmdPrint) + + rootCmd.SetArgs(strings.Split("print echosub lala", " ")) + rootCmd.Execute() + + if rootPersPre == nil || len(rootPersPre) == 0 || rootPersPre[0] != "lala" { + t.Error("RootCmd PersistentPreRun not called but should have been") + } +} + +func TestGlobalNormFuncPropagation(t *testing.T) { + normFunc := func(f *pflag.FlagSet, name string) pflag.NormalizedName { + return pflag.NormalizedName(name) + } + + rootCmd := initialize() + rootCmd.SetGlobalNormalizationFunc(normFunc) + if reflect.ValueOf(normFunc) != reflect.ValueOf(rootCmd.GlobalNormalizationFunc()) { + t.Error("rootCmd seems to have a wrong normalization function") + } + + // First add the cmdEchoSub to cmdPrint + cmdPrint.AddCommand(cmdEchoSub) + if cmdPrint.GlobalNormalizationFunc() != nil && cmdEchoSub.GlobalNormalizationFunc() != nil { + t.Error("cmdPrint and cmdEchoSub should had no normalization functions") + } + + // Now add cmdPrint to rootCmd + rootCmd.AddCommand(cmdPrint) + if reflect.ValueOf(cmdPrint.GlobalNormalizationFunc()).Pointer() != reflect.ValueOf(rootCmd.GlobalNormalizationFunc()).Pointer() || + reflect.ValueOf(cmdEchoSub.GlobalNormalizationFunc()).Pointer() != reflect.ValueOf(rootCmd.GlobalNormalizationFunc()).Pointer() { + t.Error("cmdPrint and cmdEchoSub should had the normalization function of rootCmd") + } +} diff --git a/vendor/_nuts/github.com/spf13/cobra/command.go b/vendor/_nuts/github.com/spf13/cobra/command.go index 621e5a2c..aa1dcd46 100644 --- a/vendor/_nuts/github.com/spf13/cobra/command.go +++ b/vendor/_nuts/github.com/spf13/cobra/command.go @@ -11,9 +11,8 @@ // See the License for the specific language governing permissions and // limitations under the License. -// Commands similar to git, go tools and other modern CLI tools -// inspired by go, go-Commander, gh and subcommand - +//Package cobra is a commander providing a simple interface to create powerful modern CLI interfaces. +//In addition to providing an interface, Cobra simultaneously provides a controller to organize your application code. package cobra import ( @@ -21,8 +20,11 @@ import ( "fmt" "io" "os" + "runtime" "strings" + "time" + "github.com/github/git-lfs/vendor/_nuts/github.com/inconshreveable/mousetrap" flag "github.com/github/git-lfs/vendor/_nuts/github.com/spf13/pflag" ) @@ -35,17 +37,43 @@ type Command struct { name string // The one-line usage message. Use string + // An array of aliases that can be used instead of the first word in Use. + Aliases []string // The short description shown in the 'help' output. Short string // The long message shown in the 'help ' output. Long string - // Set of flags specific to this command. + // Examples of how to use the command + Example string + // List of all valid non-flag arguments, used for bash completions *TODO* actually validate these + ValidArgs []string + // Custom functions used by the bash autocompletion generator + BashCompletionFunction string + // Is this command deprecated and should print this string when used? + Deprecated string + // Full set of flags flags *flag.FlagSet - // Set of flags children commands will inherit + // Set of flags childrens of this command will inherit pflags *flag.FlagSet - // Run runs the command. - // The args are the arguments after the command name. + // Flags that are declared specifically by this command (not inherited). + lflags *flag.FlagSet + // The *Run functions are executed in the following order: + // * PersistentPreRun() + // * PreRun() + // * Run() + // * PostRun() + // * PersistentPostRun() + // All functions get the same args, the arguments after the command name + // PersistentPreRun: children of this command will inherit and execute + PersistentPreRun func(cmd *Command, args []string) + // PreRun: children of this command will not inherit. + PreRun func(cmd *Command, args []string) + // Run: Typically the actual work function. Most commands will only implement this Run func(cmd *Command, args []string) + // PostRun: run after the Run command. + PostRun func(cmd *Command, args []string) + // PersistentPostRun: children of this command will inherit and execute after PostRun + PersistentPostRun func(cmd *Command, args []string) // Commands is the list of commands supported by this program. commands []*Command // Parent Command for this command @@ -53,10 +81,11 @@ type Command struct { // max lengths of commands' string lengths for use in padding commandsMaxUseLen int commandsMaxCommandPathLen int + commandsMaxNameLen int flagErrorBuf *bytes.Buffer - args []string + args []string // actual args parsed from flags output *io.Writer // nil means stderr; use Out() method instead usageFunc func(*Command) error // Usage can be defined by application usageTemplate string // Can be defined by Application @@ -64,6 +93,8 @@ type Command struct { helpFunc func(*Command, []string) // Help can be defined by application helpCommand *Command // The help command helpFlagVal bool + // The global normalization function that we can use on every pFlag set and children commands + globNormFunc func(f *flag.FlagSet, name string) flag.NormalizedName } // os.Args[1:] by default, if desired, can be overridden @@ -72,7 +103,7 @@ func (c *Command) SetArgs(a []string) { c.args = a } -func (c *Command) Out() io.Writer { +func (c *Command) getOut(def io.Writer) io.Writer { if c.output != nil { return *c.output } @@ -80,10 +111,18 @@ func (c *Command) Out() io.Writer { if c.HasParent() { return c.parent.Out() } else { - return os.Stderr + return def } } +func (c *Command) Out() io.Writer { + return c.getOut(os.Stderr) +} + +func (c *Command) getOutOrStdout() io.Writer { + return c.getOut(os.Stdout) +} + // SetOutput sets the destination for usage and error messages. // If output is nil, os.Stderr is used. func (c *Command) SetOutput(output io.Writer) { @@ -114,6 +153,19 @@ func (c *Command) SetHelpTemplate(s string) { c.helpTemplate = s } +// SetGlobalNormalizationFunc sets a normalization function to all flag sets and also to child commands. +// The user should not have a cyclic dependency on commands. +func (c *Command) SetGlobalNormalizationFunc(n func(f *flag.FlagSet, name string) flag.NormalizedName) { + c.Flags().SetNormalizeFunc(n) + c.PersistentFlags().SetNormalizeFunc(n) + c.LocalFlags().SetNormalizeFunc(n) + c.globNormFunc = n + + for _, command := range c.commands { + command.SetGlobalNormalizationFunc(n) + } +} + func (c *Command) UsageFunc() (f func(*Command) error) { if c.usageFunc != nil { return c.usageFunc @@ -139,7 +191,7 @@ func (c *Command) HelpFunc() func(*Command, []string) { return func(c *Command, args []string) { if len(args) == 0 { // Help called without any topic, calling on root - c.Root().Usage() + c.Root().Help() return } @@ -170,6 +222,7 @@ func (c *Command) UsagePadding() int { var minCommandPathPadding int = 11 +// func (c *Command) CommandPathPadding() int { if c.parent == nil || minCommandPathPadding > c.parent.commandsMaxCommandPathLen { return minCommandPathPadding @@ -178,6 +231,16 @@ func (c *Command) CommandPathPadding() int { } } +var minNamePadding int = 11 + +func (c *Command) NamePadding() int { + if c.parent == nil || minNamePadding > c.parent.commandsMaxNameLen { + return minNamePadding + } else { + return c.parent.commandsMaxNameLen + } +} + func (c *Command) UsageTemplate() string { if c.usageTemplate != "" { return c.usageTemplate @@ -189,18 +252,29 @@ func (c *Command) UsageTemplate() string { return `{{ $cmd := . }} Usage: {{if .Runnable}} {{.UseLine}}{{if .HasFlags}} [flags]{{end}}{{end}}{{if .HasSubCommands}} - {{ .CommandPath}} [command]{{end}} -{{ if .HasSubCommands}} -Available Commands: {{range .Commands}}{{if .Runnable}} - {{rpad .Use .UsagePadding }} {{.Short}}{{end}}{{end}} -{{end}} -{{ if .HasFlags}} Available Flags: -{{.Flags.FlagUsages}}{{end}}{{if .HasParent}}{{if and (gt .Commands 0) (gt .Parent.Commands 1) }} -Additional help topics: {{if gt .Commands 0 }}{{range .Commands}}{{if not .Runnable}} {{rpad .CommandPath .CommandPathPadding}} {{.Short}}{{end}}{{end}}{{end}}{{if gt .Parent.Commands 1 }}{{range .Parent.Commands}}{{if .Runnable}}{{if not (eq .Name $cmd.Name) }}{{end}} - {{rpad .CommandPath .CommandPathPadding}} {{.Short}}{{end}}{{end}}{{end}}{{end}} -{{end}} -Use "{{.Root.Name}} help [command]" for more information about that command. -` + {{ .CommandPath}} [command]{{end}}{{if gt .Aliases 0}} + +Aliases: + {{.NameAndAliases}} +{{end}}{{if .HasExample}} + +Examples: +{{ .Example }}{{end}}{{ if .HasNonHelpSubCommands}} + +Available Commands: {{range .Commands}}{{if (not .IsHelpCommand)}} + {{rpad .Name .NamePadding }} {{.Short}}{{end}}{{end}}{{end}}{{ if .HasLocalFlags}} + +Flags: +{{.LocalFlags.FlagUsages}}{{end}}{{ if .HasInheritedFlags}} + +Global Flags: +{{.InheritedFlags.FlagUsages}}{{end}}{{if .HasHelpSubCommands}} + +Additional help topics: {{range .Commands}}{{if .IsHelpCommand}} + {{rpad .CommandPath .CommandPathPadding}} {{.Short}}{{end}}}{{end}}{{end}}{{ if .HasSubCommands }} + +Use "{{.CommandPath}} [command] --help" for more information about a command. +{{end}}` } } @@ -212,8 +286,8 @@ func (c *Command) HelpTemplate() string { if c.HasParent() { return c.parent.HelpTemplate() } else { - return `{{.Long | trim}} -{{if .Runnable}}{{.UsageString}}{{end}} + return `{{with or .Long .Short }}{{. | trim}}{{end}} +{{if or .Runnable .HasSubCommands}}{{.UsageString}}{{end}} ` } } @@ -225,14 +299,36 @@ func (c *Command) resetChildrensParents() { } } -func stripFlags(args []string) []string { +// Test if the named flag is a boolean flag. +func isBooleanFlag(name string, f *flag.FlagSet) bool { + flag := f.Lookup(name) + if flag == nil { + return false + } + return flag.Value.Type() == "bool" +} + +// Test if the named flag is a boolean flag. +func isBooleanShortFlag(name string, f *flag.FlagSet) bool { + result := false + f.VisitAll(func(f *flag.Flag) { + if f.Shorthand == name && f.Value.Type() == "bool" { + result = true + } + }) + return result +} + +func stripFlags(args []string, c *Command) []string { if len(args) < 1 { return args } + c.mergePersistentFlags() commands := []string{} inQuote := false + inFlag := false for _, y := range args { if !inQuote { switch { @@ -240,8 +336,18 @@ func stripFlags(args []string) []string { inQuote = true case strings.Contains(y, "=\""): inQuote = true + case strings.HasPrefix(y, "--") && !strings.Contains(y, "="): + // TODO: this isn't quite right, we should really check ahead for 'true' or 'false' + inFlag = !isBooleanFlag(y[2:], c.Flags()) + case strings.HasPrefix(y, "-") && !strings.Contains(y, "=") && len(y) == 2 && !isBooleanShortFlag(y[1:], c.Flags()): + inFlag = true + case inFlag: + inFlag = false + case y == "": + // strip empty commands, as the go tests expect this to be ok.... case !strings.HasPrefix(y, "-"): commands = append(commands, y) + inFlag = false } } @@ -253,58 +359,70 @@ func stripFlags(args []string) []string { return commands } -func argsMinusX(args []string, x string) []string { - newargs := []string{} - - for _, y := range args { - if x != y { - newargs = append(newargs, y) +// argsMinusFirstX removes only the first x from args. Otherwise, commands that look like +// openshift admin policy add-role-to-user admin my-user, lose the admin argument (arg[4]). +func argsMinusFirstX(args []string, x string) []string { + for i, y := range args { + if x == y { + ret := []string{} + ret = append(ret, args[:i]...) + ret = append(ret, args[i+1:]...) + return ret } } - return newargs + return args } // find the target command given the args and command tree // Meant to be run on the highest node. Only searches down. -func (c *Command) Find(arrs []string) (*Command, []string, error) { +func (c *Command) Find(args []string) (*Command, []string, error) { if c == nil { return nil, nil, fmt.Errorf("Called find() on a nil Command") } - if len(arrs) == 0 { - return c.Root(), arrs, nil - } - var innerfind func(*Command, []string) (*Command, []string) - innerfind = func(c *Command, args []string) (*Command, []string) { - if len(args) > 0 && c.HasSubCommands() { - argsWOflags := stripFlags(args) - if len(argsWOflags) > 0 { - matches := make([]*Command, 0) - for _, cmd := range c.commands { - if cmd.Name() == argsWOflags[0] { // exact name match - return innerfind(cmd, argsMinusX(args, cmd.Name())) - } else if strings.HasPrefix(cmd.Name(), argsWOflags[0]) { // prefix match + innerfind = func(c *Command, innerArgs []string) (*Command, []string) { + argsWOflags := stripFlags(innerArgs, c) + if len(argsWOflags) == 0 { + return c, innerArgs + } + nextSubCmd := argsWOflags[0] + matches := make([]*Command, 0) + for _, cmd := range c.commands { + if cmd.Name() == nextSubCmd || cmd.HasAlias(nextSubCmd) { // exact name or alias match + return innerfind(cmd, argsMinusFirstX(innerArgs, nextSubCmd)) + } + if EnablePrefixMatching { + if strings.HasPrefix(cmd.Name(), nextSubCmd) { // prefix match + matches = append(matches, cmd) + } + for _, x := range cmd.Aliases { + if strings.HasPrefix(x, nextSubCmd) { matches = append(matches, cmd) } } - - // only accept a single prefix match - multiple matches would be ambiguous - if len(matches) == 1 { - return innerfind(matches[0], argsMinusX(args, argsWOflags[0])) - } } } - return c, args + // only accept a single prefix match - multiple matches would be ambiguous + if len(matches) == 1 { + return innerfind(matches[0], argsMinusFirstX(innerArgs, argsWOflags[0])) + } + + return c, innerArgs } - commandFound, a := innerfind(c, arrs) + commandFound, a := innerfind(c, args) + argsWOflags := stripFlags(a, commandFound) - // if commander returned and not appropriately matched return nil & error - if commandFound.Name() == c.Name() && !strings.HasPrefix(commandFound.Name(), arrs[0]) { - return nil, a, fmt.Errorf("unknown command %q\nRun 'help' for usage.\n", a[0]) + // no subcommand, always take args + if !commandFound.HasSubCommands() { + return commandFound, a, nil + } + // root command with subcommands, do subcommand checking + if commandFound == c && len(argsWOflags) > 0 { + return commandFound, a, fmt.Errorf("unknown command %q for %q", argsWOflags[0], commandFound.CommandPath()) } return commandFound, a, nil @@ -324,37 +442,51 @@ func (c *Command) Root() *Command { return findRoot(c) } -// execute the command determined by args and the command tree -func (c *Command) findAndExecute(args []string) (err error) { - - cmd, a, e := c.Find(args) - if e != nil { - return e - } - return cmd.execute(a) -} - func (c *Command) execute(a []string) (err error) { if c == nil { return fmt.Errorf("Called Execute() on a nil Command") } - err = c.ParseFlags(a) + if len(c.Deprecated) > 0 { + c.Printf("Command %q is deprecated, %s\n", c.Name(), c.Deprecated) + } + err = c.ParseFlags(a) if err != nil { return err - } else { - // If help is called, regardless of other flags, we print that - if c.helpFlagVal { - c.Help() - return nil - } - - c.preRun() - argWoFlags := c.Flags().Args() - c.Run(c, argWoFlags) - return nil } + // If help is called, regardless of other flags, return we want help + // Also say we need help if c.Run is nil. + if c.helpFlagVal || !c.Runnable() { + return flag.ErrHelp + } + + c.preRun() + argWoFlags := c.Flags().Args() + + for p := c; p != nil; p = p.Parent() { + if p.PersistentPreRun != nil { + p.PersistentPreRun(c, argWoFlags) + break + } + } + if c.PreRun != nil { + c.PreRun(c, argWoFlags) + } + + c.Run(c, argWoFlags) + + if c.PostRun != nil { + c.PostRun(c, argWoFlags) + } + for p := c; p != nil; p = p.Parent() { + if p.PersistentPostRun != nil { + p.PersistentPostRun(c, argWoFlags) + break + } + } + + return nil } func (c *Command) preRun() { @@ -385,6 +517,14 @@ func (c *Command) Execute() (err error) { return c.Root().Execute() } + if EnableWindowsMouseTrap && runtime.GOOS == "windows" { + if mousetrap.StartedByExplorer() { + c.Print(MousetrapHelpText) + time.Sleep(5 * time.Second) + os.Exit(1) + } + } + // initialize help as the last point possible to allow for user // overriding c.initHelp() @@ -397,54 +537,25 @@ func (c *Command) Execute() (err error) { args = c.args } - if len(args) == 0 { - // Only the executable is called and the root is runnable, run it - if c.Runnable() { - err = c.execute([]string(nil)) - } else { - c.Usage() - } - } else { - err = c.findAndExecute(args) - } - - // Now handle the case where the root is runnable and only flags are provided - if err != nil && c.Runnable() { - // This is pretty much a custom version of the *Command.execute method - // with a few differences because it's the final command (no fall back) - e := c.ParseFlags(args) - if e != nil { - // Flags parsing had an error. - // If an error happens here, we have to report it to the user - c.Println(c.errorMsgFromParse()) - c.Usage() - return e - } else { - // If help is called, regardless of other flags, we print that - if c.helpFlagVal { - c.Help() - return nil - } - - argWoFlags := c.Flags().Args() - if len(argWoFlags) > 0 { - // If there are arguments (not flags) one of the earlier - // cases should have caught it.. It means invalid usage - // print the usage - c.Usage() - } else { - // Only flags left... Call root.Run - c.preRun() - c.Run(c, argWoFlags) - err = nil - } - } - } - + cmd, flags, err := c.Find(args) if err != nil { + // If found parse to a subcommand and then failed, talk about the subcommand + if cmd != nil { + c = cmd + } + c.Println("Error:", err.Error()) + c.Printf("Run '%v --help' for usage.\n", c.CommandPath()) + return err + } + + err = cmd.execute(flags) + if err != nil { + if err == flag.ErrHelp { + cmd.Help() + return nil + } + c.Println(cmd.UsageString()) c.Println("Error:", err.Error()) - c.Printf("%v: invalid command %#q\n", c.Root().Name(), os.Args[1:]) - c.Printf("Run '%v help' for usage\n", c.Root().Name()) } return @@ -452,12 +563,18 @@ func (c *Command) Execute() (err error) { func (c *Command) initHelp() { if c.helpCommand == nil { + if !c.HasSubCommands() { + return + } + c.helpCommand = &Command{ Use: "help [command]", Short: "Help about any command", Long: `Help provides help for any command in the application. Simply type ` + c.Name() + ` help [path to command] for full details.`, - Run: c.HelpFunc(), + Run: c.HelpFunc(), + PersistentPreRun: func(cmd *Command, args []string) {}, + PersistentPostRun: func(cmd *Command, args []string) {}, } } c.AddCommand(c.helpCommand) @@ -466,13 +583,15 @@ func (c *Command) initHelp() { // Used for testing func (c *Command) ResetCommands() { c.commands = nil + c.helpCommand = nil } +//Commands returns a slice of child commands. func (c *Command) Commands() []*Command { return c.commands } -// Add one or many commands as children of this +// AddCommand adds one or more commands to this parent command. func (c *Command) AddCommand(cmds ...*Command) { for i, x := range cmds { if cmds[i] == c { @@ -488,10 +607,52 @@ func (c *Command) AddCommand(cmds ...*Command) { if commandPathLen > c.commandsMaxCommandPathLen { c.commandsMaxCommandPathLen = commandPathLen } + nameLen := len(x.Name()) + if nameLen > c.commandsMaxNameLen { + c.commandsMaxNameLen = nameLen + } + // If glabal normalization function exists, update all children + if c.globNormFunc != nil { + x.SetGlobalNormalizationFunc(c.globNormFunc) + } c.commands = append(c.commands, x) } } +// AddCommand removes one or more commands from a parent command. +func (c *Command) RemoveCommand(cmds ...*Command) { + commands := []*Command{} +main: + for _, command := range c.commands { + for _, cmd := range cmds { + if command == cmd { + command.parent = nil + continue main + } + } + commands = append(commands, command) + } + c.commands = commands + // recompute all lengths + c.commandsMaxUseLen = 0 + c.commandsMaxCommandPathLen = 0 + c.commandsMaxNameLen = 0 + for _, command := range c.commands { + usageLen := len(command.Use) + if usageLen > c.commandsMaxUseLen { + c.commandsMaxUseLen = usageLen + } + commandPathLen := len(command.CommandPath()) + if commandPathLen > c.commandsMaxCommandPathLen { + c.commandsMaxCommandPathLen = commandPathLen + } + nameLen := len(command.Name()) + if nameLen > c.commandsMaxNameLen { + c.commandsMaxNameLen = nameLen + } + } +} + // Convenience method to Print to the defined output func (c *Command) Print(i ...interface{}) { fmt.Fprint(c.Out(), i...) @@ -523,7 +684,7 @@ func (c *Command) Usage() error { // by the default HelpFunc in the commander func (c *Command) Help() error { c.mergePersistentFlags() - err := tmpl(c.Out(), c.HelpTemplate(), c) + err := tmpl(c.getOutOrStdout(), c.HelpTemplate(), c) return err } @@ -536,7 +697,7 @@ func (c *Command) UsageString() string { return bb.String() } -// The full path to this command +// CommandPath returns the full path to this command. func (c *Command) CommandPath() string { str := c.Name() x := c @@ -614,6 +775,24 @@ func (c *Command) Name() string { return name } +// Determine if a given string is an alias of the command. +func (c *Command) HasAlias(s string) bool { + for _, a := range c.Aliases { + if a == s { + return true + } + } + return false +} + +func (c *Command) NameAndAliases() string { + return strings.Join(append([]string{c.Name()}, c.Aliases...), ", ") +} + +func (c *Command) HasExample() bool { + return len(c.Example) > 0 +} + // Determine if the command is itself runnable func (c *Command) Runnable() bool { return c.Run != nil @@ -624,12 +803,56 @@ func (c *Command) HasSubCommands() bool { return len(c.commands) > 0 } +func (c *Command) IsHelpCommand() bool { + if c.Runnable() { + return false + } + for _, sub := range c.commands { + if len(sub.Deprecated) != 0 { + continue + } + if !sub.IsHelpCommand() { + return false + } + } + return true +} + +func (c *Command) HasHelpSubCommands() bool { + for _, sub := range c.commands { + if len(sub.Deprecated) != 0 { + continue + } + if sub.IsHelpCommand() { + return true + } + } + return false +} + +func (c *Command) HasNonHelpSubCommands() bool { + for _, sub := range c.commands { + if len(sub.Deprecated) != 0 { + continue + } + if !sub.IsHelpCommand() { + return true + } + } + return false +} + // Determine if the command is a child command func (c *Command) HasParent() bool { return c.parent != nil } -// Get the Commands FlagSet +// GlobalNormalizationFunc returns the global normalization function or nil if doesn't exists +func (c *Command) GlobalNormalizationFunc() func(f *flag.FlagSet, name string) flag.NormalizedName { + return c.globNormFunc +} + +// Get the complete FlagSet that applies to this command (local and persistent declared here and by all parents) func (c *Command) Flags() *flag.FlagSet { if c.flags == nil { c.flags = flag.NewFlagSet(c.Name(), flag.ContinueOnError) @@ -637,12 +860,57 @@ func (c *Command) Flags() *flag.FlagSet { c.flagErrorBuf = new(bytes.Buffer) } c.flags.SetOutput(c.flagErrorBuf) - c.flags.BoolVar(&c.helpFlagVal, "help", false, "help for "+c.Name()) + c.PersistentFlags().BoolVarP(&c.helpFlagVal, "help", "h", false, "help for "+c.Name()) } return c.flags } -// Get the Commands Persistent FlagSet +// Get the local FlagSet specifically set in the current command +func (c *Command) LocalFlags() *flag.FlagSet { + c.mergePersistentFlags() + + local := flag.NewFlagSet(c.Name(), flag.ContinueOnError) + c.lflags.VisitAll(func(f *flag.Flag) { + local.AddFlag(f) + }) + return local +} + +// All Flags which were inherited from parents commands +func (c *Command) InheritedFlags() *flag.FlagSet { + c.mergePersistentFlags() + + inherited := flag.NewFlagSet(c.Name(), flag.ContinueOnError) + local := c.LocalFlags() + + var rmerge func(x *Command) + + rmerge = func(x *Command) { + if x.HasPersistentFlags() { + x.PersistentFlags().VisitAll(func(f *flag.Flag) { + if inherited.Lookup(f.Name) == nil && local.Lookup(f.Name) == nil { + inherited.AddFlag(f) + } + }) + } + if x.HasParent() { + rmerge(x.parent) + } + } + + if c.HasParent() { + rmerge(c.parent) + } + + return inherited +} + +// All Flags which were not inherited from parent commands +func (c *Command) NonInheritedFlags() *flag.FlagSet { + return c.LocalFlags() +} + +// Get the Persistent FlagSet specifically set in the current command func (c *Command) PersistentFlags() *flag.FlagSet { if c.pflags == nil { c.pflags = flag.NewFlagSet(c.Name(), flag.ContinueOnError) @@ -664,7 +932,7 @@ func (c *Command) ResetFlags() { c.pflags.SetOutput(c.flagErrorBuf) } -// Does the command contain flags (local not persistent) +// Does the command contain any flags (local plus persistent from the entire structure) func (c *Command) HasFlags() bool { return c.Flags().HasFlags() } @@ -674,6 +942,15 @@ func (c *Command) HasPersistentFlags() bool { return c.PersistentFlags().HasFlags() } +// Does the command has flags specifically declared locally +func (c *Command) HasLocalFlags() bool { + return c.LocalFlags().HasFlags() +} + +func (c *Command) HasInheritedFlags() bool { + return c.InheritedFlags().HasFlags() +} + // Climbs up the command tree looking for matching flag func (c *Command) Flag(name string) (flag *flag.Flag) { flag = c.Flags().Lookup(name) @@ -701,22 +978,37 @@ func (c *Command) persistentFlag(name string) (flag *flag.Flag) { func (c *Command) ParseFlags(args []string) (err error) { c.mergePersistentFlags() err = c.Flags().Parse(args) + return +} - // The upstream library adds spaces to the error - // response regardless of success. - // Handling it here until fixing upstream - if len(strings.TrimSpace(c.flagErrorBuf.String())) > 1 { - return fmt.Errorf("%s", c.flagErrorBuf.String()) - } - - //always return nil because upstream library is inconsistent & we always check the error buffer anyway - return nil +func (c *Command) Parent() *Command { + return c.parent } func (c *Command) mergePersistentFlags() { var rmerge func(x *Command) + // Save the set of local flags + if c.lflags == nil { + c.lflags = flag.NewFlagSet(c.Name(), flag.ContinueOnError) + if c.flagErrorBuf == nil { + c.flagErrorBuf = new(bytes.Buffer) + } + c.lflags.SetOutput(c.flagErrorBuf) + addtolocal := func(f *flag.Flag) { + c.lflags.AddFlag(f) + } + c.Flags().VisitAll(addtolocal) + c.PersistentFlags().VisitAll(addtolocal) + } rmerge = func(x *Command) { + if !x.HasParent() { + flag.CommandLine.VisitAll(func(f *flag.Flag) { + if x.PersistentFlags().Lookup(f.Name) == nil { + x.PersistentFlags().AddFlag(f) + } + }) + } if x.HasPersistentFlags() { x.PersistentFlags().VisitAll(func(f *flag.Flag) { if c.Flags().Lookup(f.Name) == nil { @@ -731,7 +1023,3 @@ func (c *Command) mergePersistentFlags() { rmerge(c) } - -func (c *Command) Parent() *Command { - return c.parent -} diff --git a/vendor/_nuts/github.com/spf13/cobra/command_test.go b/vendor/_nuts/github.com/spf13/cobra/command_test.go new file mode 100644 index 00000000..477d84e7 --- /dev/null +++ b/vendor/_nuts/github.com/spf13/cobra/command_test.go @@ -0,0 +1,90 @@ +package cobra + +import ( + "reflect" + "testing" +) + +func TestStripFlags(t *testing.T) { + tests := []struct { + input []string + output []string + }{ + { + []string{"foo", "bar"}, + []string{"foo", "bar"}, + }, + { + []string{"foo", "--bar", "-b"}, + []string{"foo"}, + }, + { + []string{"-b", "foo", "--bar", "bar"}, + []string{}, + }, + { + []string{"-i10", "echo"}, + []string{"echo"}, + }, + { + []string{"-i=10", "echo"}, + []string{"echo"}, + }, + { + []string{"--int=100", "echo"}, + []string{"echo"}, + }, + { + []string{"-ib", "echo", "-bfoo", "baz"}, + []string{"echo", "baz"}, + }, + { + []string{"-i=baz", "bar", "-i", "foo", "blah"}, + []string{"bar", "blah"}, + }, + { + []string{"--int=baz", "-bbar", "-i", "foo", "blah"}, + []string{"blah"}, + }, + { + []string{"--cat", "bar", "-i", "foo", "blah"}, + []string{"bar", "blah"}, + }, + { + []string{"-c", "bar", "-i", "foo", "blah"}, + []string{"bar", "blah"}, + }, + { + []string{"--persist", "bar"}, + []string{"bar"}, + }, + { + []string{"-p", "bar"}, + []string{"bar"}, + }, + } + + cmdPrint := &Command{ + Use: "print [string to print]", + Short: "Print anything to the screen", + Long: `an utterly useless command for testing.`, + Run: func(cmd *Command, args []string) { + tp = args + }, + } + + var flagi int + var flagstr string + var flagbool bool + cmdPrint.PersistentFlags().BoolVarP(&flagbool, "persist", "p", false, "help for persistent one") + cmdPrint.Flags().IntVarP(&flagi, "int", "i", 345, "help message for flag int") + cmdPrint.Flags().StringVarP(&flagstr, "bar", "b", "bar", "help message for flag string") + cmdPrint.Flags().BoolVarP(&flagbool, "cat", "c", false, "help message for flag bool") + + for _, test := range tests { + output := stripFlags(test.input, cmdPrint) + if !reflect.DeepEqual(test.output, output) { + t.Errorf("expected: %v, got: %v", test.output, output) + } + } +} diff --git a/vendor/_nuts/github.com/spf13/cobra/md_docs.go b/vendor/_nuts/github.com/spf13/cobra/md_docs.go new file mode 100644 index 00000000..6092c85a --- /dev/null +++ b/vendor/_nuts/github.com/spf13/cobra/md_docs.go @@ -0,0 +1,138 @@ +//Copyright 2015 Red Hat Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package cobra + +import ( + "bytes" + "fmt" + "os" + "sort" + "strings" + "time" +) + +func printOptions(out *bytes.Buffer, cmd *Command, name string) { + flags := cmd.NonInheritedFlags() + flags.SetOutput(out) + if flags.HasFlags() { + fmt.Fprintf(out, "### Options\n\n```\n") + flags.PrintDefaults() + fmt.Fprintf(out, "```\n\n") + } + + parentFlags := cmd.InheritedFlags() + parentFlags.SetOutput(out) + if parentFlags.HasFlags() { + fmt.Fprintf(out, "### Options inherited from parent commands\n\n```\n") + parentFlags.PrintDefaults() + fmt.Fprintf(out, "```\n\n") + } +} + +type byName []*Command + +func (s byName) Len() int { return len(s) } +func (s byName) Swap(i, j int) { s[i], s[j] = s[j], s[i] } +func (s byName) Less(i, j int) bool { return s[i].Name() < s[j].Name() } + +func GenMarkdown(cmd *Command, out *bytes.Buffer) { + GenMarkdownCustom(cmd, out, func(s string) string { return s }) +} + +func GenMarkdownCustom(cmd *Command, out *bytes.Buffer, linkHandler func(string) string) { + name := cmd.CommandPath() + + short := cmd.Short + long := cmd.Long + if len(long) == 0 { + long = short + } + + fmt.Fprintf(out, "## %s\n\n", name) + fmt.Fprintf(out, "%s\n\n", short) + fmt.Fprintf(out, "### Synopsis\n\n") + fmt.Fprintf(out, "\n%s\n\n", long) + + if cmd.Runnable() { + fmt.Fprintf(out, "```\n%s\n```\n\n", cmd.UseLine()) + } + + if len(cmd.Example) > 0 { + fmt.Fprintf(out, "### Examples\n\n") + fmt.Fprintf(out, "```\n%s\n```\n\n", cmd.Example) + } + + printOptions(out, cmd, name) + + if len(cmd.Commands()) > 0 || cmd.HasParent() { + fmt.Fprintf(out, "### SEE ALSO\n") + if cmd.HasParent() { + parent := cmd.Parent() + pname := parent.CommandPath() + link := pname + ".md" + link = strings.Replace(link, " ", "_", -1) + fmt.Fprintf(out, "* [%s](%s)\t - %s\n", pname, linkHandler(link), parent.Short) + } + + children := cmd.Commands() + sort.Sort(byName(children)) + + for _, child := range children { + if len(child.Deprecated) > 0 { + continue + } + cname := name + " " + child.Name() + link := cname + ".md" + link = strings.Replace(link, " ", "_", -1) + fmt.Fprintf(out, "* [%s](%s)\t - %s\n", cname, linkHandler(link), child.Short) + } + fmt.Fprintf(out, "\n") + } + + fmt.Fprintf(out, "###### Auto generated by spf13/cobra at %s\n", time.Now().UTC()) +} + +func GenMarkdownTree(cmd *Command, dir string) { + identity := func(s string) string { return s } + emptyStr := func(s string) string { return "" } + GenMarkdownTreeCustom(cmd, dir, emptyStr, identity) +} + +func GenMarkdownTreeCustom(cmd *Command, dir string, filePrepender func(string) string, linkHandler func(string) string) { + for _, c := range cmd.Commands() { + GenMarkdownTreeCustom(c, dir, filePrepender, linkHandler) + } + out := new(bytes.Buffer) + + GenMarkdownCustom(cmd, out, linkHandler) + + filename := cmd.CommandPath() + filename = dir + strings.Replace(filename, " ", "_", -1) + ".md" + outFile, err := os.Create(filename) + if err != nil { + fmt.Println(err) + os.Exit(1) + } + defer outFile.Close() + _, err = outFile.WriteString(filePrepender(filename)) + if err != nil { + fmt.Println(err) + os.Exit(1) + } + _, err = outFile.Write(out.Bytes()) + if err != nil { + fmt.Println(err) + os.Exit(1) + } +} diff --git a/vendor/_nuts/github.com/spf13/cobra/md_docs.md b/vendor/_nuts/github.com/spf13/cobra/md_docs.md new file mode 100644 index 00000000..3a0d55ab --- /dev/null +++ b/vendor/_nuts/github.com/spf13/cobra/md_docs.md @@ -0,0 +1,81 @@ +# Generating Markdown Docs For Your Own cobra.Command + +## Generate markdown docs for the entire command tree + +This program can actually generate docs for the kubectl command in the kubernetes project + +```go +package main + +import ( + "io/ioutil" + "os" + + "github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl/cmd" + "github.com/spf13/cobra" +) + +func main() { + kubectl := cmd.NewFactory(nil).NewKubectlCommand(os.Stdin, ioutil.Discard, ioutil.Discard) + cobra.GenMarkdownTree(kubectl, "./") +} +``` + +This will generate a whole series of files, one for each command in the tree, in the directory specified (in this case "./") + +## Generate markdown docs for a single command + +You may wish to have more control over the output, or only generate for a single command, instead of the entire command tree. If this is the case you may prefer to `GenMarkdown` instead of `GenMarkdownTree` + +```go + out := new(bytes.Buffer) + cobra.GenMarkdown(cmd, out) +``` + +This will write the markdown doc for ONLY "cmd" into the out, buffer. + +## Customize the output + +Both `GenMarkdown` and `GenMarkdownTree` have alternate versions with callbacks to get some control of the output: + +```go +func GenMarkdownTreeCustom(cmd *Command, dir string, filePrepender func(string) string, linkHandler func(string) string) { + //... +} +``` + +```go +func GenMarkdownCustom(cmd *Command, out *bytes.Buffer, linkHandler func(string) string) { + //... +} +``` + +The `filePrepender` will prepend the return value given the full filepath to the rendered Markdown file. A common use case is to add front matter to use the generated documentation with [Hugo](http://gohugo.io/): + +```go +const fmTemplate = `--- +date: %s +title: "%s" +slug: %s +url: %s +--- +` + +filePrepender := func(filename string) string { + now := time.Now().Format(time.RFC3339) + name := filepath.Base(filename) + base := strings.TrimSuffix(name, path.Ext(name)) + url := "/commands/" + strings.ToLower(base) + "/" + return fmt.Sprintf(fmTemplate, now, strings.Replace(base, "_", " ", -1), base, url) +} +``` + +The `linkHandler` can be used to customize the rendered internal links to the commands, given a filename: + +```go +linkHandler := func(name string) string { + base := strings.TrimSuffix(name, path.Ext(name)) + return "/commands/" + strings.ToLower(base) + "/" +} +``` + diff --git a/vendor/_nuts/github.com/spf13/cobra/md_docs_test.go b/vendor/_nuts/github.com/spf13/cobra/md_docs_test.go new file mode 100644 index 00000000..defc9411 --- /dev/null +++ b/vendor/_nuts/github.com/spf13/cobra/md_docs_test.go @@ -0,0 +1,67 @@ +package cobra + +import ( + "bytes" + "fmt" + "os" + "strings" + "testing" +) + +var _ = fmt.Println +var _ = os.Stderr + +func TestGenMdDoc(t *testing.T) { + c := initializeWithRootCmd() + // Need two commands to run the command alphabetical sort + cmdEcho.AddCommand(cmdTimes, cmdEchoSub, cmdDeprecated) + c.AddCommand(cmdPrint, cmdEcho) + cmdRootWithRun.PersistentFlags().StringVarP(&flags2a, "rootflag", "r", "two", strtwoParentHelp) + + out := new(bytes.Buffer) + + // We generate on s subcommand so we have both subcommands and parents + GenMarkdown(cmdEcho, out) + found := out.String() + + // Our description + expected := cmdEcho.Long + if !strings.Contains(found, expected) { + t.Errorf("Unexpected response.\nExpecting to contain: \n %q\nGot:\n %q\n", expected, found) + } + + // Better have our example + expected = cmdEcho.Example + if !strings.Contains(found, expected) { + t.Errorf("Unexpected response.\nExpecting to contain: \n %q\nGot:\n %q\n", expected, found) + } + + // A local flag + expected = "boolone" + if !strings.Contains(found, expected) { + t.Errorf("Unexpected response.\nExpecting to contain: \n %q\nGot:\n %q\n", expected, found) + } + + // persistent flag on parent + expected = "rootflag" + if !strings.Contains(found, expected) { + t.Errorf("Unexpected response.\nExpecting to contain: \n %q\nGot:\n %q\n", expected, found) + } + + // We better output info about our parent + expected = cmdRootWithRun.Short + if !strings.Contains(found, expected) { + t.Errorf("Unexpected response.\nExpecting to contain: \n %q\nGot:\n %q\n", expected, found) + } + + // And about subcommands + expected = cmdEchoSub.Short + if !strings.Contains(found, expected) { + t.Errorf("Unexpected response.\nExpecting to contain: \n %q\nGot:\n %q\n", expected, found) + } + + unexpected := cmdDeprecated.Short + if strings.Contains(found, unexpected) { + t.Errorf("Unexpected response.\nFound: %v\nBut should not have!!\n", unexpected) + } +} diff --git a/vendor/_nuts/github.com/spf13/pflag/.travis.yml b/vendor/_nuts/github.com/spf13/pflag/.travis.yml new file mode 100644 index 00000000..c4d88e37 --- /dev/null +++ b/vendor/_nuts/github.com/spf13/pflag/.travis.yml @@ -0,0 +1,8 @@ +sudo: false + +language: go + +go: + - 1.3 + - 1.4 + - tip diff --git a/vendor/_nuts/github.com/spf13/pflag/README.md b/vendor/_nuts/github.com/spf13/pflag/README.md index a12d94df..deee9316 100644 --- a/vendor/_nuts/github.com/spf13/pflag/README.md +++ b/vendor/_nuts/github.com/spf13/pflag/README.md @@ -1,3 +1,5 @@ +[![Build Status](https://travis-ci.org/spf13/pflag.svg?branch=master)](https://travis-ci.org/spf13/pflag) + ## Description pflag is a drop-in replacement for Go's flag package, implementing @@ -18,11 +20,11 @@ pflag is available using the standard `go get` command. Install by running: - go get github.com/ogier/pflag + go get github.com/spf13/pflag Run tests by running: - go test github.com/ogier/pflag + go test github.com/spf13/pflag ## Usage @@ -31,7 +33,7 @@ pflag under the name "flag" then all code should continue to function with no changes. ``` go -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 @@ -82,6 +84,16 @@ 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 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. @@ -109,29 +121,56 @@ 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 only +--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. +letters for flags. All but the last shorthand letter must be boolean flags +or a flag with a default value ``` -// boolean flags +// boolean or flags where the 'no option default value' is set -f +-f=true -abc +but +-b true is INVALID -// non-boolean flags +// non-boolean and flags without a 'no option default value' -n 1234 --Ifile +-n=1234 +-n1234 // mixed -abcs "hello" --abcn1234 +-absd="hello" +-abcs1234 ``` Flag parsing stops after the terminator "--". Unlike the flag package, @@ -143,6 +182,40 @@ 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) +``` + ## More info You can see the full reference documentation of the pflag package diff --git a/vendor/_nuts/github.com/spf13/pflag/bool.go b/vendor/_nuts/github.com/spf13/pflag/bool.go index 010576c3..04c9b5af 100644 --- a/vendor/_nuts/github.com/spf13/pflag/bool.go +++ b/vendor/_nuts/github.com/spf13/pflag/bool.go @@ -5,6 +5,13 @@ 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 @@ -25,34 +32,49 @@ func (b *boolValue) Type() string { func (b *boolValue) String() string { return fmt.Sprintf("%v", *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.VarP(newBoolValue(value, p), name, "", usage) + f.BoolVarP(p, name, "", value, usage) } // 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) { - f.VarP(newBoolValue(value, p), name, shorthand, usage) + 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) { - CommandLine.VarP(newBoolValue(value, p), name, "", usage) + BoolVarP(p, name, "", value, usage) } // 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) { - CommandLine.VarP(newBoolValue(value, p), name, shorthand, usage) + 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 { - p := new(bool) - f.BoolVarP(p, name, "", value, usage) - return p + return f.BoolP(name, "", value, usage) } // Like Bool, but accepts a shorthand letter that can be used after a single dash. @@ -65,10 +87,11 @@ func (f *FlagSet) BoolP(name, shorthand string, value bool, usage string) *bool // 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 CommandLine.BoolP(name, "", value, usage) + return BoolP(name, "", value, usage) } // 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 { - return CommandLine.BoolP(name, shorthand, value, usage) + b := CommandLine.BoolP(name, shorthand, value, usage) + return b } diff --git a/vendor/_nuts/github.com/ogier/pflag/bool_test.go b/vendor/_nuts/github.com/spf13/pflag/bool_test.go similarity index 87% rename from vendor/_nuts/github.com/ogier/pflag/bool_test.go rename to vendor/_nuts/github.com/spf13/pflag/bool_test.go index a2e1c5dc..afd25ae2 100644 --- a/vendor/_nuts/github.com/ogier/pflag/bool_test.go +++ b/vendor/_nuts/github.com/spf13/pflag/bool_test.go @@ -51,7 +51,7 @@ func (v *triStateValue) String() string { return fmt.Sprintf("%v", bool(*v == triStateTrue)) } -// The type of the flag as requred by the pflag.Value interface +// The type of the flag as required by the pflag.Value interface func (v *triStateValue) Type() string { return "version" } @@ -59,7 +59,8 @@ func (v *triStateValue) Type() string { func setUpFlagSet(tristate *triStateValue) *FlagSet { f := NewFlagSet("test", ContinueOnError) *tristate = triStateFalse - f.VarP(tristate, "tristate", "t", "tristate value (true, maybe or false)") + flag := f.VarPF(tristate, "tristate", "t", "tristate value (true, maybe or false)") + flag.NoOptDefVal = "true" return f } @@ -162,3 +163,18 @@ func TestInvalidValue(t *testing.T) { 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=%s", b) + } + if *c != false { + t.Errorf("expect c=false got c=%s", c) + } +} diff --git a/vendor/_nuts/github.com/spf13/pflag/count.go b/vendor/_nuts/github.com/spf13/pflag/count.go new file mode 100644 index 00000000..d0613688 --- /dev/null +++ b/vendor/_nuts/github.com/spf13/pflag/count.go @@ -0,0 +1,84 @@ +package pflag + +import ( + "fmt" + "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 fmt.Sprintf("%v", *i) } + +func countConv(sval string) (interface{}, error) { + i, err := strconv.Atoi(sval) + if err != nil { + return nil, err + } + return i, nil +} + +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 +} + +func (f *FlagSet) CountVar(p *int, name string, usage string) { + f.CountVarP(p, name, "", usage) +} + +func (f *FlagSet) CountVarP(p *int, name, shorthand string, usage string) { + flag := f.VarPF(newCountValue(0, p), name, shorthand, usage) + flag.NoOptDefVal = "-1" +} + +func CountVar(p *int, name string, usage string) { + CommandLine.CountVar(p, name, usage) +} + +func CountVarP(p *int, name, shorthand string, usage string) { + CommandLine.CountVarP(p, name, shorthand, usage) +} + +func (f *FlagSet) Count(name string, usage string) *int { + p := new(int) + f.CountVarP(p, name, "", usage) + return p +} + +func (f *FlagSet) CountP(name, shorthand string, usage string) *int { + p := new(int) + f.CountVarP(p, name, shorthand, usage) + return p +} + +func Count(name string, usage string) *int { + return CommandLine.CountP(name, "", usage) +} + +func CountP(name, shorthand string, usage string) *int { + return CommandLine.CountP(name, shorthand, usage) +} diff --git a/vendor/_nuts/github.com/spf13/pflag/count_test.go b/vendor/_nuts/github.com/spf13/pflag/count_test.go new file mode 100644 index 00000000..716765cb --- /dev/null +++ b/vendor/_nuts/github.com/spf13/pflag/count_test.go @@ -0,0 +1,55 @@ +package pflag + +import ( + "fmt" + "os" + "testing" +) + +var _ = fmt.Printf + +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) + } + } + } +} diff --git a/vendor/_nuts/github.com/spf13/pflag/duration.go b/vendor/_nuts/github.com/spf13/pflag/duration.go index 66ed7ac9..382ffd3c 100644 --- a/vendor/_nuts/github.com/spf13/pflag/duration.go +++ b/vendor/_nuts/github.com/spf13/pflag/duration.go @@ -1,6 +1,8 @@ package pflag -import "time" +import ( + "time" +) // -- time.Duration Value type durationValue time.Duration @@ -22,6 +24,19 @@ func (d *durationValue) Type() string { 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) { diff --git a/vendor/_nuts/github.com/spf13/pflag/example_test.go b/vendor/_nuts/github.com/spf13/pflag/example_test.go index 54f91165..c5940394 100644 --- a/vendor/_nuts/github.com/spf13/pflag/example_test.go +++ b/vendor/_nuts/github.com/spf13/pflag/example_test.go @@ -11,7 +11,7 @@ import ( "strings" "time" - flag "github.com/github/git-lfs/vendor/_nuts/github.com/ogier/pflag" + flag "github.com/github/git-lfs/vendor/_nuts/github.com/spf13/pflag" ) // Example 1: A single string flag called "species" with default value "gopher". @@ -29,6 +29,10 @@ func (i *interval) String() string { return fmt.Sprint(*i) } +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. diff --git a/vendor/_nuts/github.com/spf13/pflag/flag.go b/vendor/_nuts/github.com/spf13/pflag/flag.go index 47761a0e..c45ad0f0 100644 --- a/vendor/_nuts/github.com/spf13/pflag/flag.go +++ b/vendor/_nuts/github.com/spf13/pflag/flag.go @@ -120,6 +120,10 @@ const ( 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. @@ -127,26 +131,30 @@ type FlagSet struct { // a custom error handler. Usage func() - name string - parsed bool - actual map[string]*Flag - formal map[string]*Flag - shorthands map[byte]*Flag - args []string // arguments after flags - 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 + name string + parsed bool + actual map[NormalizedName]*Flag + formal map[NormalizedName]*Flag + shorthands map[byte]*Flag + args []string // arguments after flags + 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 + 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) + 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 + Annotations map[string][]string // used by cobra.Command bash autocomple code } // Value is the interface to the dynamic value stored in a flag. @@ -158,21 +166,43 @@ type Value interface { } // sortFlags returns the flags as a slice in lexicographical sorted order. -func sortFlags(flags map[string]*Flag) []*Flag { +func sortFlags(flags map[NormalizedName]*Flag) []*Flag { list := make(sort.StringSlice, len(flags)) i := 0 - for _, f := range flags { - list[i] = f.Name + for k := range flags { + list[i] = string(k) i++ } list.Sort() result := make([]*Flag, len(list)) for i, name := range list { - result[i] = flags[name] + result[i] = flags[NormalizedName(name)] } return result } +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 + v.Name = string(nname) + } +} + +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 @@ -220,18 +250,55 @@ func Visit(fn func(*Flag)) { // 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)) +} + +// 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 +} + +// Mark a flag deprecated in your program +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) + } + flag.Deprecated = usageMessage + 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.formal[name] + return CommandLine.Lookup(name) } // Set sets the value of the named flag. func (f *FlagSet) Set(name, value string) error { - flag, ok := f.formal[name] + normalName := f.normalizeFlagName(name) + flag, ok := f.formal[normalName] if !ok { return fmt.Errorf("no such flag -%v", name) } @@ -240,13 +307,38 @@ func (f *FlagSet) Set(name, value string) error { return err } if f.actual == nil { - f.actual = make(map[string]*Flag) + f.actual = make(map[NormalizedName]*Flag) + } + f.actual[normalName] = flag + flag.Changed = true + if len(flag.Deprecated) > 0 { + fmt.Fprintf(os.Stderr, "Flag --%s has been deprecated, %s\n", flag.Name, flag.Deprecated) } - f.actual[name] = flag - f.Lookup(name).Changed = true return nil } +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 +} + +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) @@ -256,16 +348,28 @@ func Set(name, value string) error { // otherwise, the default values of all defined flags in the set. func (f *FlagSet) PrintDefaults() { f.VisitAll(func(flag *Flag) { - format := "--%s=%s: %s\n" - if _, ok := flag.Value.(*stringValue); ok { - // put quotes on the value - format = "--%s=%q: %s\n" + if len(flag.Deprecated) > 0 { + return } + format := "" + // ex: w/ option string argument '-%s, --%s[=%q]: %s\n' if len(flag.Shorthand) > 0 { - format = " -%s, " + format + format = " -%s, --%s" } else { - format = " %s " + format + format = " %s --%s" } + if len(flag.NoOptDefVal) > 0 { + format = format + "[" + } + if _, ok := flag.Value.(*stringValue); ok { + format = format + "=%q" + } else { + format = format + "=%s" + } + if len(flag.NoOptDefVal) > 0 { + format = format + "]" + } + format = format + ": %s\n" fmt.Fprintf(f.out(), format, flag.Shorthand, flag.Name, flag.DefValue, flag.Usage) }) } @@ -274,6 +378,9 @@ func (f *FlagSet) FlagUsages() string { x := new(bytes.Buffer) f.VisitAll(func(flag *Flag) { + if len(flag.Deprecated) > 0 { + return + } format := "--%s=%s: %s\n" if _, ok := flag.Value.(*stringValue); ok { // put quotes on the value @@ -355,24 +462,41 @@ func (f *FlagSet) Var(value Value, name string, usage string) { f.VarP(value, name, "", usage) } +// 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 +} + // 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) { - // Remember the default value as a string; it won't change. - flag := &Flag{name, shorthand, usage, value, value.String(), false} - f.AddFlag(flag) + _ = f.VarPF(value, name, shorthand, usage) } func (f *FlagSet) AddFlag(flag *Flag) { - _, alreadythere := f.formal[flag.Name] + // Call normalizeFlagName function only once + var normalizedFlagName NormalizedName = 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[string]*Flag) + f.formal = make(map[NormalizedName]*Flag) } - f.formal[flag.Name] = flag + + flag.Name = string(normalizedFlagName) + f.formal[normalizedFlagName] = flag if len(flag.Shorthand) == 0 { return @@ -435,19 +559,18 @@ func (f *FlagSet) setFlag(flag *Flag, value string, origArg string) error { } // mark as visited for Visit() if f.actual == nil { - f.actual = make(map[string]*Flag) + f.actual = make(map[NormalizedName]*Flag) } - f.actual[flag.Name] = 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) + } return nil } func (f *FlagSet) parseLongArg(s string, args []string) (a []string, err error) { a = args - if len(s) == 2 { // "--" terminates the flags - f.args = append(f.args, args...) - return - } name := s[2:] if len(name) == 0 || name[0] == '-' || name[0] == '=' { err = f.failf("bad flag syntax: %s", s) @@ -455,73 +578,80 @@ func (f *FlagSet) parseLongArg(s string, args []string) (a []string, err error) } split := strings.SplitN(name, "=", 2) name = split[0] - m := f.formal - flag, alreadythere := m[name] // BUG + flag, alreadythere := f.formal[f.normalizeFlagName(name)] if !alreadythere { if name == "help" { // special case for nice help message. f.usage() - return args, ErrHelp + return a, ErrHelp } err = f.failf("unknown flag: --%s", name) return } - if len(split) == 1 { - if _, ok := flag.Value.(*boolValue); !ok { - err = f.failf("flag needs an argument: %s", s) - return - } - f.setFlag(flag, "true", s) + var value string + if len(split) == 2 { + // '--flag=arg' + value = split[1] + } else if len(flag.NoOptDefVal) > 0 { + // '--flag' (arg was optional) + value = flag.NoOptDefVal + } else if len(a) > 0 { + // '--flag arg' + value = a[0] + a = a[1:] } else { - if e := f.setFlag(flag, split[1], s); e != nil { - err = e + // '--flag' (arg was required) + err = f.failf("flag needs an argument: %s", s) + return + } + err = f.setFlag(flag, value, s) + return +} + +func (f *FlagSet) parseSingleShortArg(shorthands string, args []string) (outShorts string, outArgs []string, err error) { + outArgs = args + outShorts = shorthands[1:] + c := shorthands[0] + + flag, alreadythere := f.shorthands[c] + if !alreadythere { + 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 } - return args, nil + var value string + if len(shorthands) > 2 && shorthands[1] == '=' { + value = shorthands[2:] + outShorts = "" + } else if len(flag.NoOptDefVal) > 0 { + value = flag.NoOptDefVal + } else if len(shorthands) > 1 { + value = shorthands[1:] + outShorts = "" + } else if len(args) > 0 { + value = args[0] + outArgs = args[1:] + } else { + err = f.failf("flag needs an argument: %q in -%s", c, shorthands) + return + } + err = f.setFlag(flag, value, shorthands) + return } func (f *FlagSet) parseShortArg(s string, args []string) (a []string, err error) { a = args shorthands := s[1:] - for i := 0; i < len(shorthands); i++ { - c := shorthands[i] - flag, alreadythere := f.shorthands[c] - if !alreadythere { - 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) - if len(args) == 0 { - return - } + for len(shorthands) > 0 { + shorthands, a, err = f.parseSingleShortArg(shorthands, args) + if err != nil { + return } - if alreadythere { - if _, ok := flag.Value.(*boolValue); ok { - f.setFlag(flag, "true", s) - continue - } - if i < len(shorthands)-1 { - if e := f.setFlag(flag, shorthands[i+1:], s); e != nil { - err = e - return - } - break - } - if len(args) == 0 { - err = f.failf("flag needs an argument: %q in -%s", c, shorthands) - return - } - if e := f.setFlag(flag, args[0], s); e != nil { - err = e - return - } - } - a = args[1:] - break // should be unnecessary } return @@ -542,10 +672,17 @@ func (f *FlagSet) parseArgs(args []string) (err error) { } if s[1] == '-' { + if len(s) == 2 { // "--" terminates the flags + f.args = append(f.args, args...) + break + } args, err = f.parseLongArg(s, args) } else { args, err = f.parseShortArg(s, args) } + if err != nil { + return + } } return } diff --git a/vendor/_nuts/github.com/spf13/pflag/flag_test.go b/vendor/_nuts/github.com/spf13/pflag/flag_test.go index 209c4f46..e654553c 100644 --- a/vendor/_nuts/github.com/spf13/pflag/flag_test.go +++ b/vendor/_nuts/github.com/spf13/pflag/flag_test.go @@ -2,30 +2,33 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -package pflag_test +package pflag import ( "bytes" "fmt" + "io" "io/ioutil" + "net" "os" + "reflect" "sort" "strings" "testing" "time" - - . "github.com/github/git-lfs/vendor/_nuts/github.com/spf13/pflag" ) var ( - test_bool = Bool("test_bool", false, "bool value") - test_int = Int("test_int", 0, "int value") - test_int64 = Int64("test_int64", 0, "int64 value") - test_uint = Uint("test_uint", 0, "uint value") - test_uint64 = Uint64("test_uint64", 0, "uint64 value") - test_string = String("test_string", "0", "string value") - test_float64 = Float64("test_float64", 0, "float64 value") - test_duration = Duration("test_duration", 0, "time.Duration value") + test_bool = Bool("test_bool", false, "bool value") + test_int = Int("test_int", 0, "int value") + test_int64 = Int64("test_int64", 0, "int64 value") + test_uint = Uint("test_uint", 0, "uint value") + test_uint64 = Uint64("test_uint64", 0, "uint64 value") + test_string = String("test_string", "0", "string value") + test_float64 = Float64("test_float64", 0, "float64 value") + test_duration = Duration("test_duration", 0, "time.Duration value") + test_optional_int = Int("test_optional_int", 0, "optional int value") + normalizeFlagNameInvocations = 0 ) func boolString(s string) string { @@ -56,7 +59,7 @@ func TestEverything(t *testing.T) { } } VisitAll(visitor) - if len(m) != 8 { + if len(m) != 9 { t.Error("VisitAll misses some flags") for k, v := range m { t.Log(k, *v) @@ -79,9 +82,10 @@ func TestEverything(t *testing.T) { Set("test_string", "1") Set("test_float64", "1") Set("test_duration", "1s") + Set("test_optional_int", "1") desired = "1" Visit(visitor) - if len(m) != 8 { + if len(m) != 9 { t.Error("Visit fails after set") for k, v := range m { t.Log(k, *v) @@ -106,6 +110,37 @@ func TestUsage(t *testing.T) { } } +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") @@ -114,24 +149,46 @@ func testParse(f *FlagSet, t *testing.T) { 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", + "--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 { @@ -143,6 +200,9 @@ func testParse(f *FlagSet, t *testing.T) { 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) } @@ -152,24 +212,102 @@ func testParse(f *FlagSet, t *testing.T) { 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 but maskFlag 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 { @@ -185,7 +323,9 @@ func TestShorthand(t *testing.T) { boolaFlag := f.BoolP("boola", "a", false, "bool value") boolbFlag := f.BoolP("boolb", "b", false, "bool2 value") boolcFlag := f.BoolP("boolc", "c", false, "bool3 value") - stringFlag := f.StringP("string", "s", "0", "string 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{ @@ -193,12 +333,14 @@ func TestShorthand(t *testing.T) { extra, "-cs", "hello", + "-z=something", + "-d=true", "--", notaflag, } f.SetOutput(ioutil.Discard) - if err := f.Parse(args); err == nil { - t.Error("--i-look-like-a-flag should throw an error") + if err := f.Parse(args); err != nil { + t.Error("expected no error, got ", err) } if !f.Parsed() { t.Error("f.Parse() = false after Parse") @@ -212,8 +354,14 @@ func TestShorthand(t *testing.T) { if *boolcFlag != true { t.Error("boolc flag should be true, is ", *boolcFlag) } - if *stringFlag != "hello" { - t.Error("string flag should be `hello`, is ", *stringFlag) + 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())) @@ -233,6 +381,165 @@ 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!") + } +} + +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 @@ -245,6 +552,10 @@ func (f *flagVar) Set(value string) error { return nil } +func (f *flagVar) Type() string { + return "flagVar" +} + func TestUserDefined(t *testing.T) { var flags FlagSet flags.Init("test", ContinueOnError) @@ -352,3 +663,121 @@ func TestNoInterspersed(t *testing.T) { 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]) + } +} + +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 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 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) + } +} diff --git a/vendor/_nuts/github.com/spf13/pflag/float32.go b/vendor/_nuts/github.com/spf13/pflag/float32.go index b7ad67d9..30174cb2 100644 --- a/vendor/_nuts/github.com/spf13/pflag/float32.go +++ b/vendor/_nuts/github.com/spf13/pflag/float32.go @@ -25,6 +25,23 @@ func (f *float32Value) Type() string { func (f *float32Value) String() string { return fmt.Sprintf("%v", *f) } +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) { diff --git a/vendor/_nuts/github.com/spf13/pflag/float64.go b/vendor/_nuts/github.com/spf13/pflag/float64.go index 03155123..10e17e4b 100644 --- a/vendor/_nuts/github.com/spf13/pflag/float64.go +++ b/vendor/_nuts/github.com/spf13/pflag/float64.go @@ -25,6 +25,19 @@ func (f *float64Value) Type() string { func (f *float64Value) String() string { return fmt.Sprintf("%v", *f) } +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) { diff --git a/vendor/_nuts/github.com/spf13/pflag/int.go b/vendor/_nuts/github.com/spf13/pflag/int.go index dca9da6e..23f70ddd 100644 --- a/vendor/_nuts/github.com/spf13/pflag/int.go +++ b/vendor/_nuts/github.com/spf13/pflag/int.go @@ -25,6 +25,19 @@ func (i *intValue) Type() string { func (i *intValue) String() string { return fmt.Sprintf("%v", *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) { diff --git a/vendor/_nuts/github.com/spf13/pflag/int32.go b/vendor/_nuts/github.com/spf13/pflag/int32.go index 18eaacd6..515f90bb 100644 --- a/vendor/_nuts/github.com/spf13/pflag/int32.go +++ b/vendor/_nuts/github.com/spf13/pflag/int32.go @@ -25,6 +25,23 @@ func (i *int32Value) Type() string { func (i *int32Value) String() string { return fmt.Sprintf("%v", *i) } +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) { diff --git a/vendor/_nuts/github.com/spf13/pflag/int64.go b/vendor/_nuts/github.com/spf13/pflag/int64.go index 0114aaaa..b77ade41 100644 --- a/vendor/_nuts/github.com/spf13/pflag/int64.go +++ b/vendor/_nuts/github.com/spf13/pflag/int64.go @@ -25,6 +25,19 @@ func (i *int64Value) Type() string { func (i *int64Value) String() string { return fmt.Sprintf("%v", *i) } +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) { diff --git a/vendor/_nuts/github.com/spf13/pflag/int8.go b/vendor/_nuts/github.com/spf13/pflag/int8.go index aab1022f..c51cb4ff 100644 --- a/vendor/_nuts/github.com/spf13/pflag/int8.go +++ b/vendor/_nuts/github.com/spf13/pflag/int8.go @@ -25,6 +25,23 @@ func (i *int8Value) Type() string { func (i *int8Value) String() string { return fmt.Sprintf("%v", *i) } +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) { diff --git a/vendor/_nuts/github.com/spf13/pflag/int_slice.go b/vendor/_nuts/github.com/spf13/pflag/int_slice.go new file mode 100644 index 00000000..7c6ed79f --- /dev/null +++ b/vendor/_nuts/github.com/spf13/pflag/int_slice.go @@ -0,0 +1,128 @@ +package 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) +} + +// 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) +} + +// 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 := make([]int, 0) + f.IntSliceVarP(&p, name, "", value, usage) + return &p +} + +// 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 := make([]int, 0) + 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) +} + +// 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) +} diff --git a/vendor/_nuts/github.com/spf13/pflag/int_slice_test.go b/vendor/_nuts/github.com/spf13/pflag/int_slice_test.go new file mode 100644 index 00000000..2b7f68da --- /dev/null +++ b/vendor/_nuts/github.com/spf13/pflag/int_slice_test.go @@ -0,0 +1,162 @@ +// 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 seperated list!") + return f +} + +func setUpISFlagSetWithDefault(isp *[]int) *FlagSet { + f := NewFlagSet("test", ContinueOnError) + f.IntSliceVar(isp, "is", []int{0, 1}, "Command seperated 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") + 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 %s but got: %s", 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 %s from GetIntSlice but got: %s", 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 %s but got: %s", 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 %s from GetIntSlice but got: %s", 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 %s but got: %s", i, expected[i], v) + } + } +} diff --git a/vendor/_nuts/github.com/spf13/pflag/ip.go b/vendor/_nuts/github.com/spf13/pflag/ip.go index 9d53bd3e..baa442b5 100644 --- a/vendor/_nuts/github.com/spf13/pflag/ip.go +++ b/vendor/_nuts/github.com/spf13/pflag/ip.go @@ -3,8 +3,11 @@ package pflag import ( "fmt" "net" + "strings" ) +var _ = strings.TrimSpace + // -- net.IP value type ipValue net.IP @@ -15,21 +18,35 @@ func newIPValue(val net.IP, p *net.IP) *ipValue { func (i *ipValue) String() string { return net.IP(*i).String() } func (i *ipValue) Set(s string) error { - ip := net.ParseIP(s) + 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) Get() interface{} { - return net.IP(*i) -} 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) { diff --git a/vendor/_nuts/github.com/spf13/pflag/ip_test.go b/vendor/_nuts/github.com/spf13/pflag/ip_test.go new file mode 100644 index 00000000..1fec50e4 --- /dev/null +++ b/vendor/_nuts/github.com/spf13/pflag/ip_test.go @@ -0,0 +1,63 @@ +package 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()) + } + } + } +} diff --git a/vendor/_nuts/github.com/spf13/pflag/ipmask.go b/vendor/_nuts/github.com/spf13/pflag/ipmask.go index 6f85be9b..1b10efb4 100644 --- a/vendor/_nuts/github.com/spf13/pflag/ipmask.go +++ b/vendor/_nuts/github.com/spf13/pflag/ipmask.go @@ -3,6 +3,7 @@ package pflag import ( "fmt" "net" + "strconv" ) // -- net.IPMask value @@ -22,9 +23,6 @@ func (i *ipMaskValue) Set(s string) error { *i = ipMaskValue(ip) return nil } -func (i *ipMaskValue) Get() interface{} { - return net.IPMask(*i) -} func (i *ipMaskValue) Type() string { return "ipMask" @@ -35,11 +33,46 @@ func (i *ipMaskValue) Type() string { func ParseIPv4Mask(s string) net.IPMask { mask := net.ParseIP(s) if mask == nil { - return 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) { diff --git a/vendor/_nuts/github.com/spf13/pflag/ipnet.go b/vendor/_nuts/github.com/spf13/pflag/ipnet.go new file mode 100644 index 00000000..23b7fd3c --- /dev/null +++ b/vendor/_nuts/github.com/spf13/pflag/ipnet.go @@ -0,0 +1,100 @@ +package 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" +} + +var _ = strings.TrimSpace + +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) +} + +// 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) +} + +// 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 +} + +// 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) +} + +// 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) +} diff --git a/vendor/_nuts/github.com/spf13/pflag/ipnet_test.go b/vendor/_nuts/github.com/spf13/pflag/ipnet_test.go new file mode 100644 index 00000000..335b6fa1 --- /dev/null +++ b/vendor/_nuts/github.com/spf13/pflag/ipnet_test.go @@ -0,0 +1,70 @@ +package 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()) + } + } + } +} diff --git a/vendor/_nuts/github.com/spf13/pflag/string.go b/vendor/_nuts/github.com/spf13/pflag/string.go index 362fbf8a..f89ea8b5 100644 --- a/vendor/_nuts/github.com/spf13/pflag/string.go +++ b/vendor/_nuts/github.com/spf13/pflag/string.go @@ -20,6 +20,19 @@ func (s *stringValue) Type() string { func (s *stringValue) String() string { return fmt.Sprintf("%s", *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) { diff --git a/vendor/_nuts/github.com/spf13/pflag/string_slice.go b/vendor/_nuts/github.com/spf13/pflag/string_slice.go new file mode 100644 index 00000000..848bea89 --- /dev/null +++ b/vendor/_nuts/github.com/spf13/pflag/string_slice.go @@ -0,0 +1,105 @@ +package pflag + +import ( + "fmt" + "strings" +) + +var _ = fmt.Fprint + +// -- 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 (s *stringSliceValue) Set(val string) error { + v := strings.Split(val, ",") + 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 { return "[" + strings.Join(*s.value, ",") + "]" } + +func stringSliceConv(sval string) (interface{}, error) { + sval = strings.Trim(sval, "[]") + // An empty string would cause a slice with one (empty) string + if len(sval) == 0 { + return []string{}, nil + } + v := strings.Split(sval, ",") + return v, nil +} + +// 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) +} + +// 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) +} + +// 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 := make([]string, 0) + f.StringSliceVarP(&p, name, "", value, usage) + return &p +} + +// 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 := make([]string, 0) + 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) +} + +// 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) +} diff --git a/vendor/_nuts/github.com/spf13/pflag/string_slice_test.go b/vendor/_nuts/github.com/spf13/pflag/string_slice_test.go new file mode 100644 index 00000000..e8847d54 --- /dev/null +++ b/vendor/_nuts/github.com/spf13/pflag/string_slice_test.go @@ -0,0 +1,141 @@ +// 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 seperated list!") + return f +} + +func setUpSSFlagSetWithDefault(ssp *[]string) *FlagSet { + f := NewFlagSet("test", ContinueOnError) + f.StringSliceVar(ssp, "ss", []string{"default", "values"}, "Command seperated 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 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) + } + for i, v := range ss { + if expected[i] != v { + t.Fatalf("expected ss[%d] to be %s but got: %s", i, expected[i], v) + } + } +} diff --git a/vendor/_nuts/github.com/spf13/pflag/uint.go b/vendor/_nuts/github.com/spf13/pflag/uint.go index c063fe7c..d6f8e5be 100644 --- a/vendor/_nuts/github.com/spf13/pflag/uint.go +++ b/vendor/_nuts/github.com/spf13/pflag/uint.go @@ -25,6 +25,23 @@ func (i *uintValue) Type() string { func (i *uintValue) String() string { return fmt.Sprintf("%v", *i) } +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) { diff --git a/vendor/_nuts/github.com/spf13/pflag/uint16.go b/vendor/_nuts/github.com/spf13/pflag/uint16.go index ec14ab0c..1cdc3dfb 100644 --- a/vendor/_nuts/github.com/spf13/pflag/uint16.go +++ b/vendor/_nuts/github.com/spf13/pflag/uint16.go @@ -19,14 +19,27 @@ func (i *uint16Value) Set(s string) error { return err } -func (i *uint16Value) Get() interface{} { - return uint16(*i) -} - func (i *uint16Value) Type() string { return "uint16" } +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) { diff --git a/vendor/_nuts/github.com/spf13/pflag/uint32.go b/vendor/_nuts/github.com/spf13/pflag/uint32.go index 05bc3bd0..1326e4ab 100644 --- a/vendor/_nuts/github.com/spf13/pflag/uint32.go +++ b/vendor/_nuts/github.com/spf13/pflag/uint32.go @@ -18,14 +18,28 @@ func (i *uint32Value) Set(s string) error { *i = uint32Value(v) return err } -func (i *uint32Value) Get() interface{} { - return uint32(*i) -} func (i *uint32Value) Type() string { return "uint32" } +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) { diff --git a/vendor/_nuts/github.com/spf13/pflag/uint64.go b/vendor/_nuts/github.com/spf13/pflag/uint64.go index 99c7e805..6788bbf8 100644 --- a/vendor/_nuts/github.com/spf13/pflag/uint64.go +++ b/vendor/_nuts/github.com/spf13/pflag/uint64.go @@ -25,6 +25,23 @@ func (i *uint64Value) Type() string { func (i *uint64Value) String() string { return fmt.Sprintf("%v", *i) } +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) { diff --git a/vendor/_nuts/github.com/spf13/pflag/uint8.go b/vendor/_nuts/github.com/spf13/pflag/uint8.go index 6fef508d..560c569b 100644 --- a/vendor/_nuts/github.com/spf13/pflag/uint8.go +++ b/vendor/_nuts/github.com/spf13/pflag/uint8.go @@ -25,6 +25,23 @@ func (i *uint8Value) Type() string { func (i *uint8Value) String() string { return fmt.Sprintf("%v", *i) } +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) {