summaryrefslogtreecommitdiff
path: root/vendor/github.com/spf13
diff options
context:
space:
mode:
authorDave Henderson <dhenderson@gmail.com>2018-05-24 07:56:38 -0400
committerDave Henderson <dhenderson@gmail.com>2018-05-24 08:26:44 -0400
commit3eb83ecdcbf81a03caea389da5918b38e3dd1ff2 (patch)
tree5a5d2cdc1d4c4d72c5245d7b7ef163835980924f /vendor/github.com/spf13
parent1fd414ba42cc32d79036a31d0faaeebe44720412 (diff)
Updating vendored packages
Signed-off-by: Dave Henderson <dhenderson@gmail.com>
Diffstat (limited to 'vendor/github.com/spf13')
-rw-r--r--vendor/github.com/spf13/afero/basepath.go47
-rw-r--r--vendor/github.com/spf13/afero/cacheOnReadFs.go6
-rw-r--r--vendor/github.com/spf13/afero/copyOnWriteFs.go53
-rw-r--r--vendor/github.com/spf13/afero/lstater.go27
-rw-r--r--vendor/github.com/spf13/afero/match.go4
-rw-r--r--vendor/github.com/spf13/afero/os.go7
-rw-r--r--vendor/github.com/spf13/afero/path.go18
-rw-r--r--vendor/github.com/spf13/afero/readonlyfs.go10
-rw-r--r--vendor/github.com/spf13/afero/unionFile.go189
-rw-r--r--vendor/github.com/spf13/cobra/args.go25
-rw-r--r--vendor/github.com/spf13/cobra/bash_completions.go167
-rw-r--r--vendor/github.com/spf13/cobra/cobra.go12
-rw-r--r--vendor/github.com/spf13/cobra/command.go130
-rw-r--r--vendor/github.com/spf13/pflag/bytes.go105
-rw-r--r--vendor/github.com/spf13/pflag/count.go12
-rw-r--r--vendor/github.com/spf13/pflag/duration_slice.go128
-rw-r--r--vendor/github.com/spf13/pflag/flag.go155
-rw-r--r--vendor/github.com/spf13/pflag/golangflag.go4
-rw-r--r--vendor/github.com/spf13/pflag/int16.go88
-rw-r--r--vendor/github.com/spf13/pflag/string_array.go8
-rw-r--r--vendor/github.com/spf13/pflag/string_slice.go20
21 files changed, 979 insertions, 236 deletions
diff --git a/vendor/github.com/spf13/afero/basepath.go b/vendor/github.com/spf13/afero/basepath.go
index 5e4fc2ec..616ff8ff 100644
--- a/vendor/github.com/spf13/afero/basepath.go
+++ b/vendor/github.com/spf13/afero/basepath.go
@@ -1,7 +1,6 @@
package afero
import (
- "errors"
"os"
"path/filepath"
"runtime"
@@ -9,6 +8,8 @@ import (
"time"
)
+var _ Lstater = (*BasePathFs)(nil)
+
// The BasePathFs restricts all operations to a given path within an Fs.
// The given file name to the operations on this Fs will be prepended with
// the base path before calling the base Fs.
@@ -22,6 +23,16 @@ type BasePathFs struct {
path string
}
+type BasePathFile struct {
+ File
+ path string
+}
+
+func (f *BasePathFile) Name() string {
+ sourcename := f.File.Name()
+ return strings.TrimPrefix(sourcename, filepath.Clean(f.path))
+}
+
func NewBasePathFs(source Fs, path string) Fs {
return &BasePathFs{source: source, path: path}
}
@@ -30,7 +41,7 @@ func NewBasePathFs(source Fs, path string) Fs {
// else the given file with the base path prepended
func (b *BasePathFs) RealPath(name string) (path string, err error) {
if err := validateBasePathName(name); err != nil {
- return "", err
+ return name, err
}
bpath := filepath.Clean(b.path)
@@ -52,7 +63,7 @@ func validateBasePathName(name string) error {
// On Windows a common mistake would be to provide an absolute OS path
// We could strip out the base part, but that would not be very portable.
if filepath.IsAbs(name) {
- return &os.PathError{Op: "realPath", Path: name, Err: errors.New("got a real OS path instead of a virtual")}
+ return os.ErrNotExist
}
return nil
@@ -111,14 +122,22 @@ func (b *BasePathFs) OpenFile(name string, flag int, mode os.FileMode) (f File,
if name, err = b.RealPath(name); err != nil {
return nil, &os.PathError{Op: "openfile", Path: name, Err: err}
}
- return b.source.OpenFile(name, flag, mode)
+ sourcef, err := b.source.OpenFile(name, flag, mode)
+ if err != nil {
+ return nil, err
+ }
+ return &BasePathFile{sourcef, b.path}, nil
}
func (b *BasePathFs) Open(name string) (f File, err error) {
if name, err = b.RealPath(name); err != nil {
return nil, &os.PathError{Op: "open", Path: name, Err: err}
}
- return b.source.Open(name)
+ sourcef, err := b.source.Open(name)
+ if err != nil {
+ return nil, err
+ }
+ return &BasePathFile{File: sourcef, path: b.path}, nil
}
func (b *BasePathFs) Mkdir(name string, mode os.FileMode) (err error) {
@@ -139,7 +158,23 @@ func (b *BasePathFs) Create(name string) (f File, err error) {
if name, err = b.RealPath(name); err != nil {
return nil, &os.PathError{Op: "create", Path: name, Err: err}
}
- return b.source.Create(name)
+ sourcef, err := b.source.Create(name)
+ if err != nil {
+ return nil, err
+ }
+ return &BasePathFile{File: sourcef, path: b.path}, nil
+}
+
+func (b *BasePathFs) LstatIfPossible(name string) (os.FileInfo, bool, error) {
+ name, err := b.RealPath(name)
+ if err != nil {
+ return nil, false, &os.PathError{Op: "lstat", Path: name, Err: err}
+ }
+ if lstater, ok := b.source.(Lstater); ok {
+ return lstater.LstatIfPossible(name)
+ }
+ fi, err := b.source.Stat(name)
+ return fi, false, err
}
// vim: ts=4 sw=4 noexpandtab nolist syn=go
diff --git a/vendor/github.com/spf13/afero/cacheOnReadFs.go b/vendor/github.com/spf13/afero/cacheOnReadFs.go
index b026e0de..29a26c67 100644
--- a/vendor/github.com/spf13/afero/cacheOnReadFs.go
+++ b/vendor/github.com/spf13/afero/cacheOnReadFs.go
@@ -205,7 +205,7 @@ func (u *CacheOnReadFs) OpenFile(name string, flag int, perm os.FileMode) (File,
bfi.Close() // oops, what if O_TRUNC was set and file opening in the layer failed...?
return nil, err
}
- return &UnionFile{base: bfi, layer: lfi}, nil
+ return &UnionFile{Base: bfi, Layer: lfi}, nil
}
return u.layer.OpenFile(name, flag, perm)
}
@@ -251,7 +251,7 @@ func (u *CacheOnReadFs) Open(name string) (File, error) {
if err != nil && bfile == nil {
return nil, err
}
- return &UnionFile{base: bfile, layer: lfile}, nil
+ return &UnionFile{Base: bfile, Layer: lfile}, nil
}
func (u *CacheOnReadFs) Mkdir(name string, perm os.FileMode) error {
@@ -286,5 +286,5 @@ func (u *CacheOnReadFs) Create(name string) (File, error) {
bfh.Close()
return nil, err
}
- return &UnionFile{base: bfh, layer: lfh}, nil
+ return &UnionFile{Base: bfh, Layer: lfh}, nil
}
diff --git a/vendor/github.com/spf13/afero/copyOnWriteFs.go b/vendor/github.com/spf13/afero/copyOnWriteFs.go
index f2ebcd22..9aef3979 100644
--- a/vendor/github.com/spf13/afero/copyOnWriteFs.go
+++ b/vendor/github.com/spf13/afero/copyOnWriteFs.go
@@ -8,6 +8,8 @@ import (
"time"
)
+var _ Lstater = (*CopyOnWriteFs)(nil)
+
// The CopyOnWriteFs is a union filesystem: a read only base file system with
// a possibly writeable layer on top. Changes to the file system will only
// be made in the overlay: Changing an existing file in the base layer which
@@ -76,18 +78,55 @@ func (u *CopyOnWriteFs) Chmod(name string, mode os.FileMode) error {
func (u *CopyOnWriteFs) Stat(name string) (os.FileInfo, error) {
fi, err := u.layer.Stat(name)
if err != nil {
- origErr := err
- if e, ok := err.(*os.PathError); ok {
- err = e.Err
- }
- if err == os.ErrNotExist || err == syscall.ENOENT || err == syscall.ENOTDIR {
+ isNotExist := u.isNotExist(err)
+ if isNotExist {
return u.base.Stat(name)
}
- return nil, origErr
+ return nil, err
}
return fi, nil
}
+func (u *CopyOnWriteFs) LstatIfPossible(name string) (os.FileInfo, bool, error) {
+ llayer, ok1 := u.layer.(Lstater)
+ lbase, ok2 := u.base.(Lstater)
+
+ if ok1 {
+ fi, b, err := llayer.LstatIfPossible(name)
+ if err == nil {
+ return fi, b, nil
+ }
+
+ if !u.isNotExist(err) {
+ return nil, b, err
+ }
+ }
+
+ if ok2 {
+ fi, b, err := lbase.LstatIfPossible(name)
+ if err == nil {
+ return fi, b, nil
+ }
+ if !u.isNotExist(err) {
+ return nil, b, err
+ }
+ }
+
+ fi, err := u.Stat(name)
+
+ return fi, false, err
+}
+
+func (u *CopyOnWriteFs) isNotExist(err error) bool {
+ if e, ok := err.(*os.PathError); ok {
+ err = e.Err
+ }
+ if err == os.ErrNotExist || err == syscall.ENOENT || err == syscall.ENOTDIR {
+ return true
+ }
+ return false
+}
+
// Renaming files present only in the base layer is not permitted
func (u *CopyOnWriteFs) Rename(oldname, newname string) error {
b, err := u.isBaseFile(oldname)
@@ -219,7 +258,7 @@ func (u *CopyOnWriteFs) Open(name string) (File, error) {
return nil, fmt.Errorf("BaseErr: %v\nOverlayErr: %v", bErr, lErr)
}
- return &UnionFile{base: bfile, layer: lfile}, nil
+ return &UnionFile{Base: bfile, Layer: lfile}, nil
}
func (u *CopyOnWriteFs) Mkdir(name string, perm os.FileMode) error {
diff --git a/vendor/github.com/spf13/afero/lstater.go b/vendor/github.com/spf13/afero/lstater.go
new file mode 100644
index 00000000..89c1bfc0
--- /dev/null
+++ b/vendor/github.com/spf13/afero/lstater.go
@@ -0,0 +1,27 @@
+// Copyright © 2018 Steve Francia <spf@spf13.com>.
+//
+// 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 afero
+
+import (
+ "os"
+)
+
+// Lstater is an optional interface in Afero. It is only implemented by the
+// filesystems saying so.
+// It will call Lstat if the filesystem iself is, or it delegates to, the os filesystem.
+// Else it will call Stat.
+// In addtion to the FileInfo, it will return a boolean telling whether Lstat was called or not.
+type Lstater interface {
+ LstatIfPossible(name string) (os.FileInfo, bool, error)
+}
diff --git a/vendor/github.com/spf13/afero/match.go b/vendor/github.com/spf13/afero/match.go
index 08b3b7e0..c18a87fb 100644
--- a/vendor/github.com/spf13/afero/match.go
+++ b/vendor/github.com/spf13/afero/match.go
@@ -33,8 +33,8 @@ import (
// built-ins from that package.
func Glob(fs Fs, pattern string) (matches []string, err error) {
if !hasMeta(pattern) {
- // afero does not support Lstat directly.
- if _, err = lstatIfOs(fs, pattern); err != nil {
+ // Lstat not supported by a ll filesystems.
+ if _, err = lstatIfPossible(fs, pattern); err != nil {
return nil, nil
}
return []string{pattern}, nil
diff --git a/vendor/github.com/spf13/afero/os.go b/vendor/github.com/spf13/afero/os.go
index 6b8bce1c..13cc1b84 100644
--- a/vendor/github.com/spf13/afero/os.go
+++ b/vendor/github.com/spf13/afero/os.go
@@ -19,6 +19,8 @@ import (
"time"
)
+var _ Lstater = (*OsFs)(nil)
+
// OsFs is a Fs implementation that uses functions provided by the os package.
//
// For details in any method, check the documentation of the os package
@@ -92,3 +94,8 @@ func (OsFs) Chmod(name string, mode os.FileMode) error {
func (OsFs) Chtimes(name string, atime time.Time, mtime time.Time) error {
return os.Chtimes(name, atime, mtime)
}
+
+func (OsFs) LstatIfPossible(name string) (os.FileInfo, bool, error) {
+ fi, err := os.Lstat(name)
+ return fi, true, err
+}
diff --git a/vendor/github.com/spf13/afero/path.go b/vendor/github.com/spf13/afero/path.go
index 1d90e46d..18f60a0f 100644
--- a/vendor/github.com/spf13/afero/path.go
+++ b/vendor/github.com/spf13/afero/path.go
@@ -60,7 +60,7 @@ func walk(fs Fs, path string, info os.FileInfo, walkFn filepath.WalkFunc) error
for _, name := range names {
filename := filepath.Join(path, name)
- fileInfo, err := lstatIfOs(fs, filename)
+ fileInfo, err := lstatIfPossible(fs, filename)
if err != nil {
if err := walkFn(filename, fileInfo, err); err != nil && err != filepath.SkipDir {
return err
@@ -77,15 +77,13 @@ func walk(fs Fs, path string, info os.FileInfo, walkFn filepath.WalkFunc) error
return nil
}
-// if the filesystem is OsFs use Lstat, else use fs.Stat
-func lstatIfOs(fs Fs, path string) (info os.FileInfo, err error) {
- _, ok := fs.(*OsFs)
- if ok {
- info, err = os.Lstat(path)
- } else {
- info, err = fs.Stat(path)
+// if the filesystem supports it, use Lstat, else use fs.Stat
+func lstatIfPossible(fs Fs, path string) (os.FileInfo, error) {
+ if lfs, ok := fs.(Lstater); ok {
+ fi, _, err := lfs.LstatIfPossible(path)
+ return fi, err
}
- return
+ return fs.Stat(path)
}
// Walk walks the file tree rooted at root, calling walkFn for each file or
@@ -100,7 +98,7 @@ func (a Afero) Walk(root string, walkFn filepath.WalkFunc) error {
}
func Walk(fs Fs, root string, walkFn filepath.WalkFunc) error {
- info, err := lstatIfOs(fs, root)
+ info, err := lstatIfPossible(fs, root)
if err != nil {
return walkFn(root, nil, err)
}
diff --git a/vendor/github.com/spf13/afero/readonlyfs.go b/vendor/github.com/spf13/afero/readonlyfs.go
index f1fa55bc..c6376ec3 100644
--- a/vendor/github.com/spf13/afero/readonlyfs.go
+++ b/vendor/github.com/spf13/afero/readonlyfs.go
@@ -6,6 +6,8 @@ import (
"time"
)
+var _ Lstater = (*ReadOnlyFs)(nil)
+
type ReadOnlyFs struct {
source Fs
}
@@ -34,6 +36,14 @@ func (r *ReadOnlyFs) Stat(name string) (os.FileInfo, error) {
return r.source.Stat(name)
}
+func (r *ReadOnlyFs) LstatIfPossible(name string) (os.FileInfo, bool, error) {
+ if lsf, ok := r.source.(Lstater); ok {
+ return lsf.LstatIfPossible(name)
+ }
+ fi, err := r.Stat(name)
+ return fi, false, err
+}
+
func (r *ReadOnlyFs) Rename(o, n string) error {
return syscall.EPERM
}
diff --git a/vendor/github.com/spf13/afero/unionFile.go b/vendor/github.com/spf13/afero/unionFile.go
index 99f9e5db..1e78f7d1 100644
--- a/vendor/github.com/spf13/afero/unionFile.go
+++ b/vendor/github.com/spf13/afero/unionFile.go
@@ -21,32 +21,33 @@ import (
// successful read in the overlay will move the cursor position in the base layer
// by the number of bytes read.
type UnionFile struct {
- base File
- layer File
- off int
- files []os.FileInfo
+ Base File
+ Layer File
+ Merger DirsMerger
+ off int
+ files []os.FileInfo
}
func (f *UnionFile) Close() error {
// first close base, so we have a newer timestamp in the overlay. If we'd close
// the overlay first, we'd get a cacheStale the next time we access this file
// -> cache would be useless ;-)
- if f.base != nil {
- f.base.Close()
+ if f.Base != nil {
+ f.Base.Close()
}
- if f.layer != nil {
- return f.layer.Close()
+ if f.Layer != nil {
+ return f.Layer.Close()
}
return BADFD
}
func (f *UnionFile) Read(s []byte) (int, error) {
- if f.layer != nil {
- n, err := f.layer.Read(s)
- if (err == nil || err == io.EOF) && f.base != nil {
+ if f.Layer != nil {
+ n, err := f.Layer.Read(s)
+ if (err == nil || err == io.EOF) && f.Base != nil {
// advance the file position also in the base file, the next
// call may be a write at this position (or a seek with SEEK_CUR)
- if _, seekErr := f.base.Seek(int64(n), os.SEEK_CUR); seekErr != nil {
+ if _, seekErr := f.Base.Seek(int64(n), os.SEEK_CUR); seekErr != nil {
// only overwrite err in case the seek fails: we need to
// report an eventual io.EOF to the caller
err = seekErr
@@ -54,105 +55,135 @@ func (f *UnionFile) Read(s []byte) (int, error) {
}
return n, err
}
- if f.base != nil {
- return f.base.Read(s)
+ if f.Base != nil {
+ return f.Base.Read(s)
}
return 0, BADFD
}
func (f *UnionFile) ReadAt(s []byte, o int64) (int, error) {
- if f.layer != nil {
- n, err := f.layer.ReadAt(s, o)
- if (err == nil || err == io.EOF) && f.base != nil {
- _, err = f.base.Seek(o+int64(n), os.SEEK_SET)
+ if f.Layer != nil {
+ n, err := f.Layer.ReadAt(s, o)
+ if (err == nil || err == io.EOF) && f.Base != nil {
+ _, err = f.Base.Seek(o+int64(n), os.SEEK_SET)
}
return n, err
}
- if f.base != nil {
- return f.base.ReadAt(s, o)
+ if f.Base != nil {
+ return f.Base.ReadAt(s, o)
}
return 0, BADFD
}
func (f *UnionFile) Seek(o int64, w int) (pos int64, err error) {
- if f.layer != nil {
- pos, err = f.layer.Seek(o, w)
- if (err == nil || err == io.EOF) && f.base != nil {
- _, err = f.base.Seek(o, w)
+ if f.Layer != nil {
+ pos, err = f.Layer.Seek(o, w)
+ if (err == nil || err == io.EOF) && f.Base != nil {
+ _, err = f.Base.Seek(o, w)
}
return pos, err
}
- if f.base != nil {
- return f.base.Seek(o, w)
+ if f.Base != nil {
+ return f.Base.Seek(o, w)
}
return 0, BADFD
}
func (f *UnionFile) Write(s []byte) (n int, err error) {
- if f.layer != nil {
- n, err = f.layer.Write(s)
- if err == nil && f.base != nil { // hmm, do we have fixed size files where a write may hit the EOF mark?
- _, err = f.base.Write(s)
+ if f.Layer != nil {
+ n, err = f.Layer.Write(s)
+ if err == nil && f.Base != nil { // hmm, do we have fixed size files where a write may hit the EOF mark?
+ _, err = f.Base.Write(s)
}
return n, err
}
- if f.base != nil {
- return f.base.Write(s)
+ if f.Base != nil {
+ return f.Base.Write(s)
}
return 0, BADFD
}
func (f *UnionFile) WriteAt(s []byte, o int64) (n int, err error) {
- if f.layer != nil {
- n, err = f.layer.WriteAt(s, o)
- if err == nil && f.base != nil {
- _, err = f.base.WriteAt(s, o)
+ if f.Layer != nil {
+ n, err = f.Layer.WriteAt(s, o)
+ if err == nil && f.Base != nil {
+ _, err = f.Base.WriteAt(s, o)
}
return n, err
}
- if f.base != nil {
- return f.base.WriteAt(s, o)
+ if f.Base != nil {
+ return f.Base.WriteAt(s, o)
}
return 0, BADFD
}
func (f *UnionFile) Name() string {
- if f.layer != nil {
- return f.layer.Name()
+ if f.Layer != nil {
+ return f.Layer.Name()
}
- return f.base.Name()
+ return f.Base.Name()
+}
+
+// DirsMerger is how UnionFile weaves two directories together.
+// It takes the FileInfo slices from the layer and the base and returns a
+// single view.
+type DirsMerger func(lofi, bofi []os.FileInfo) ([]os.FileInfo, error)
+
+var defaultUnionMergeDirsFn = func(lofi, bofi []os.FileInfo) ([]os.FileInfo, error) {
+ var files = make(map[string]os.FileInfo)
+
+ for _, fi := range lofi {
+ files[fi.Name()] = fi
+ }
+
+ for _, fi := range bofi {
+ if _, exists := files[fi.Name()]; !exists {
+ files[fi.Name()] = fi
+ }
+ }
+
+ rfi := make([]os.FileInfo, len(files))
+
+ i := 0
+ for _, fi := range files {
+ rfi[i] = fi
+ i++
+ }
+
+ return rfi, nil
+
}
// Readdir will weave the two directories together and
// return a single view of the overlayed directories
func (f *UnionFile) Readdir(c int) (ofi []os.FileInfo, err error) {
+ var merge DirsMerger = f.Merger
+ if merge == nil {
+ merge = defaultUnionMergeDirsFn
+ }
+
if f.off == 0 {
- var files = make(map[string]os.FileInfo)
- var rfi []os.FileInfo
- if f.layer != nil {
- rfi, err = f.layer.Readdir(-1)
+ var lfi []os.FileInfo
+ if f.Layer != nil {
+ lfi, err = f.Layer.Readdir(-1)
if err != nil {
return nil, err
}
- for _, fi := range rfi {
- files[fi.Name()] = fi
- }
}
- if f.base != nil {
- rfi, err = f.base.Readdir(-1)
+ var bfi []os.FileInfo
+ if f.Base != nil {
+ bfi, err = f.Base.Readdir(-1)
if err != nil {
return nil, err
}
- for _, fi := range rfi {
- if _, exists := files[fi.Name()]; !exists {
- files[fi.Name()] = fi
- }
- }
+
}
- for _, fi := range files {
- f.files = append(f.files, fi)
+ merged, err := merge(lfi, bfi)
+ if err != nil {
+ return nil, err
}
+ f.files = append(f.files, merged...)
}
if c == -1 {
return f.files[f.off:], nil
@@ -174,53 +205,53 @@ func (f *UnionFile) Readdirnames(c int) ([]string, error) {
}
func (f *UnionFile) Stat() (os.FileInfo, error) {
- if f.layer != nil {
- return f.layer.Stat()
+ if f.Layer != nil {
+ return f.Layer.Stat()
}
- if f.base != nil {
- return f.base.Stat()
+ if f.Base != nil {
+ return f.Base.Stat()
}
return nil, BADFD
}
func (f *UnionFile) Sync() (err error) {
- if f.layer != nil {
- err = f.layer.Sync()
- if err == nil && f.base != nil {
- err = f.base.Sync()
+ if f.Layer != nil {
+ err = f.Layer.Sync()
+ if err == nil && f.Base != nil {
+ err = f.Base.Sync()
}
return err
}
- if f.base != nil {
- return f.base.Sync()
+ if f.Base != nil {
+ return f.Base.Sync()
}
return BADFD
}
func (f *UnionFile) Truncate(s int64) (err error) {
- if f.layer != nil {
- err = f.layer.Truncate(s)
- if err == nil && f.base != nil {
- err = f.base.Truncate(s)
+ if f.Layer != nil {
+ err = f.Layer.Truncate(s)
+ if err == nil && f.Base != nil {
+ err = f.Base.Truncate(s)
}
return err
}
- if f.base != nil {
- return f.base.Truncate(s)
+ if f.Base != nil {
+ return f.Base.Truncate(s)
}
return BADFD
}
func (f *UnionFile) WriteString(s string) (n int, err error) {
- if f.layer != nil {
- n, err = f.layer.WriteString(s)
- if err == nil && f.base != nil {
- _, err = f.base.WriteString(s)
+ if f.Layer != nil {
+ n, err = f.Layer.WriteString(s)
+ if err == nil && f.Base != nil {
+ _, err = f.Base.WriteString(s)
}
return n, err
}
- if f.base != nil {
- return f.base.WriteString(s)
+ if f.Base != nil {
+ return f.Base.WriteString(s)
}
return 0, BADFD
}
diff --git a/vendor/github.com/spf13/cobra/args.go b/vendor/github.com/spf13/cobra/args.go
index 94a6ca27..a5d8a927 100644
--- a/vendor/github.com/spf13/cobra/args.go
+++ b/vendor/github.com/spf13/cobra/args.go
@@ -16,14 +16,14 @@ func legacyArgs(cmd *Command, args []string) error {
return nil
}
- // root command with subcommands, do subcommand checking
+ // root command with subcommands, do subcommand checking.
if !cmd.HasParent() && len(args) > 0 {
return fmt.Errorf("unknown command %q for %q%s", args[0], cmd.CommandPath(), cmd.findSuggestions(args[0]))
}
return nil
}
-// NoArgs returns an error if any args are included
+// NoArgs returns an error if any args are included.
func NoArgs(cmd *Command, args []string) error {
if len(args) > 0 {
return fmt.Errorf("unknown command %q for %q", args[0], cmd.CommandPath())
@@ -31,7 +31,7 @@ func NoArgs(cmd *Command, args []string) error {
return nil
}
-// OnlyValidArgs returns an error if any args are not in the list of ValidArgs
+// OnlyValidArgs returns an error if any args are not in the list of ValidArgs.
func OnlyValidArgs(cmd *Command, args []string) error {
if len(cmd.ValidArgs) > 0 {
for _, v := range args {
@@ -43,21 +43,12 @@ func OnlyValidArgs(cmd *Command, args []string) error {
return nil
}
-func stringInSlice(a string, list []string) bool {
- for _, b := range list {
- if b == a {
- return true
- }
- }
- return false
-}
-
-// ArbitraryArgs never returns an error
+// ArbitraryArgs never returns an error.
func ArbitraryArgs(cmd *Command, args []string) error {
return nil
}
-// MinimumNArgs returns an error if there is not at least N args
+// MinimumNArgs returns an error if there is not at least N args.
func MinimumNArgs(n int) PositionalArgs {
return func(cmd *Command, args []string) error {
if len(args) < n {
@@ -67,7 +58,7 @@ func MinimumNArgs(n int) PositionalArgs {
}
}
-// MaximumNArgs returns an error if there are more than N args
+// MaximumNArgs returns an error if there are more than N args.
func MaximumNArgs(n int) PositionalArgs {
return func(cmd *Command, args []string) error {
if len(args) > n {
@@ -77,7 +68,7 @@ func MaximumNArgs(n int) PositionalArgs {
}
}
-// ExactArgs returns an error if there are not exactly n args
+// ExactArgs returns an error if there are not exactly n args.
func ExactArgs(n int) PositionalArgs {
return func(cmd *Command, args []string) error {
if len(args) != n {
@@ -87,7 +78,7 @@ func ExactArgs(n int) PositionalArgs {
}
}
-// RangeArgs returns an error if the number of args is not within the expected range
+// RangeArgs returns an error if the number of args is not within the expected range.
func RangeArgs(min int, max int) PositionalArgs {
return func(cmd *Command, args []string) error {
if len(args) < min || len(args) > max {
diff --git a/vendor/github.com/spf13/cobra/bash_completions.go b/vendor/github.com/spf13/cobra/bash_completions.go
index c19fe7a0..8fa8f486 100644
--- a/vendor/github.com/spf13/cobra/bash_completions.go
+++ b/vendor/github.com/spf13/cobra/bash_completions.go
@@ -21,8 +21,8 @@ const (
func writePreamble(buf *bytes.Buffer, name string) {
buf.WriteString(fmt.Sprintf("# bash completion for %-36s -*- shell-script -*-\n", name))
- buf.WriteString(`
-__debug()
+ buf.WriteString(fmt.Sprintf(`
+__%[1]s_debug()
{
if [[ -n ${BASH_COMP_DEBUG_FILE} ]]; then
echo "$*" >> "${BASH_COMP_DEBUG_FILE}"
@@ -31,13 +31,13 @@ __debug()
# Homebrew on Macs have version 1.3 of bash-completion which doesn't include
# _init_completion. This is a very minimal version of that function.
-__my_init_completion()
+__%[1]s_init_completion()
{
COMPREPLY=()
_get_comp_words_by_ref "$@" cur prev words cword
}
-__index_of_word()
+__%[1]s_index_of_word()
{
local w word=$1
shift
@@ -49,7 +49,7 @@ __index_of_word()
index=-1
}
-__contains_word()
+__%[1]s_contains_word()
{
local w word=$1; shift
for w in "$@"; do
@@ -58,9 +58,9 @@ __contains_word()
return 1
}
-__handle_reply()
+__%[1]s_handle_reply()
{
- __debug "${FUNCNAME[0]}"
+ __%[1]s_debug "${FUNCNAME[0]}"
case $cur in
-*)
if [[ $(type -t compopt) = "builtin" ]]; then
@@ -85,7 +85,7 @@ __handle_reply()
local index flag
flag="${cur%%=*}"
- __index_of_word "${flag}" "${flags_with_completion[@]}"
+ __%[1]s_index_of_word "${flag}" "${flags_with_completion[@]}"
COMPREPLY=()
if [[ ${index} -ge 0 ]]; then
PREFIX=""
@@ -103,7 +103,7 @@ __handle_reply()
# check if we are handling a flag with special work handling
local index
- __index_of_word "${prev}" "${flags_with_completion[@]}"
+ __%[1]s_index_of_word "${prev}" "${flags_with_completion[@]}"
if [[ ${index} -ge 0 ]]; then
${flags_completion[${index}]}
return
@@ -136,24 +136,30 @@ __handle_reply()
if declare -F __ltrim_colon_completions >/dev/null; then
__ltrim_colon_completions "$cur"
fi
+
+ # If there is only 1 completion and it is a flag with an = it will be completed
+ # but we don't want a space after the =
+ if [[ "${#COMPREPLY[@]}" -eq "1" ]] && [[ $(type -t compopt) = "builtin" ]] && [[ "${COMPREPLY[0]}" == --*= ]]; then
+ compopt -o nospace
+ fi
}
# The arguments should be in the form "ext1|ext2|extn"
-__handle_filename_extension_flag()
+__%[1]s_handle_filename_extension_flag()
{
local ext="$1"
_filedir "@(${ext})"
}
-__handle_subdirs_in_dir_flag()
+__%[1]s_handle_subdirs_in_dir_flag()
{
local dir="$1"
pushd "${dir}" >/dev/null 2>&1 && _filedir -d && popd >/dev/null 2>&1
}
-__handle_flag()
+__%[1]s_handle_flag()
{
- __debug "${FUNCNAME[0]}: c is $c words[c] is ${words[c]}"
+ __%[1]s_debug "${FUNCNAME[0]}: 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]}
@@ -164,27 +170,30 @@ __handle_flag()
flagname=${flagname%%=*} # strip everything after the =
flagname="${flagname}=" # but put the = back
fi
- __debug "${FUNCNAME[0]}: looking for ${flagname}"
- if __contains_word "${flagname}" "${must_have_one_flag[@]}"; then
+ __%[1]s_debug "${FUNCNAME[0]}: looking for ${flagname}"
+ if __%[1]s_contains_word "${flagname}" "${must_have_one_flag[@]}"; then
must_have_one_flag=()
fi
# if you set a flag which only applies to this command, don't show subcommands
- if __contains_word "${flagname}" "${local_nonpersistent_flags[@]}"; then
+ if __%[1]s_contains_word "${flagname}" "${local_nonpersistent_flags[@]}"; then
commands=()
fi
# keep flag value with flagname as flaghash
- if [ -n "${flagvalue}" ] ; then
- flaghash[${flagname}]=${flagvalue}
- elif [ -n "${words[ $((c+1)) ]}" ] ; then
- flaghash[${flagname}]=${words[ $((c+1)) ]}
- else
- flaghash[${flagname}]="true" # pad "true" for bool flag
+ # flaghash variable is an associative array which is only supported in bash > 3.
+ if [[ -z "${BASH_VERSION}" || "${BASH_VERSINFO[0]}" -gt 3 ]]; then
+ if [ -n "${flagvalue}" ] ; then
+ flaghash[${flagname}]=${flagvalue}
+ elif [ -n "${words[ $((c+1)) ]}" ] ; then
+ flaghash[${flagname}]=${words[ $((c+1)) ]}
+ else
+ flaghash[${flagname}]="true" # pad "true" for bool flag
+ fi
fi
# skip the argument to a two word flag
- if __contains_word "${words[c]}" "${two_word_flags[@]}"; then
+ if __%[1]s_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
@@ -196,13 +205,13 @@ __handle_flag()
}
-__handle_noun()
+__%[1]s_handle_noun()
{
- __debug "${FUNCNAME[0]}: c is $c words[c] is ${words[c]}"
+ __%[1]s_debug "${FUNCNAME[0]}: c is $c words[c] is ${words[c]}"
- if __contains_word "${words[c]}" "${must_have_one_noun[@]}"; then
+ if __%[1]s_contains_word "${words[c]}" "${must_have_one_noun[@]}"; then
must_have_one_noun=()
- elif __contains_word "${words[c]}" "${noun_aliases[@]}"; then
+ elif __%[1]s_contains_word "${words[c]}" "${noun_aliases[@]}"; then
must_have_one_noun=()
fi
@@ -210,45 +219,53 @@ __handle_noun()
c=$((c+1))
}
-__handle_command()
+__%[1]s_handle_command()
{
- __debug "${FUNCNAME[0]}: c is $c words[c] is ${words[c]}"
+ __%[1]s_debug "${FUNCNAME[0]}: c is $c words[c] is ${words[c]}"
local next_command
if [[ -n ${last_command} ]]; then
next_command="_${last_command}_${words[c]//:/__}"
else
if [[ $c -eq 0 ]]; then
- next_command="_$(basename "${words[c]//:/__}")"
+ next_command="_%[1]s_root_command"
else
next_command="_${words[c]//:/__}"
fi
fi
c=$((c+1))
- __debug "${FUNCNAME[0]}: looking for ${next_command}"
+ __%[1]s_debug "${FUNCNAME[0]}: looking for ${next_command}"
declare -F "$next_command" >/dev/null && $next_command
}
-__handle_word()
+__%[1]s_handle_word()
{
if [[ $c -ge $cword ]]; then
- __handle_reply
+ __%[1]s_handle_reply
return
fi
- __debug "${FUNCNAME[0]}: c is $c words[c] is ${words[c]}"
+ __%[1]s_debug "${FUNCNAME[0]}: c is $c words[c] is ${words[c]}"
if [[ "${words[c]}" == -* ]]; then
- __handle_flag
- elif __contains_word "${words[c]}" "${commands[@]}"; then
- __handle_command
- elif [[ $c -eq 0 ]] && __contains_word "$(basename "${words[c]}")" "${commands[@]}"; then
- __handle_command
+ __%[1]s_handle_flag
+ elif __%[1]s_contains_word "${words[c]}" "${commands[@]}"; then
+ __%[1]s_handle_command
+ elif [[ $c -eq 0 ]]; then
+ __%[1]s_handle_command
+ elif __%[1]s_contains_word "${words[c]}" "${command_aliases[@]}"; then
+ # aliashash variable is an associative array which is only supported in bash > 3.
+ if [[ -z "${BASH_VERSION}" || "${BASH_VERSINFO[0]}" -gt 3 ]]; then
+ words[c]=${aliashash[${words[c]}]}
+ __%[1]s_handle_command
+ else
+ __%[1]s_handle_noun
+ fi
else
- __handle_noun
+ __%[1]s_handle_noun
fi
- __handle_word
+ __%[1]s_handle_word
}
-`)
+`, name))
}
func writePostscript(buf *bytes.Buffer, name string) {
@@ -257,10 +274,11 @@ func writePostscript(buf *bytes.Buffer, name string) {
buf.WriteString(fmt.Sprintf(`{
local cur prev words cword
declare -A flaghash 2>/dev/null || :
+ declare -A aliashash 2>/dev/null || :
if declare -F _init_completion >/dev/null 2>&1; then
_init_completion -s || return
else
- __my_init_completion -n "=" || return
+ __%[1]s_init_completion -n "=" || return
fi
local c=0
@@ -269,13 +287,13 @@ func writePostscript(buf *bytes.Buffer, name string) {
local local_nonpersistent_flags=()
local flags_with_completion=()
local flags_completion=()
- local commands=("%s")
+ local commands=("%[1]s")
local must_have_one_flag=()
local must_have_one_noun=()
local last_command
local nouns=()
- __handle_word
+ __%[1]s_handle_word
}
`, name))
@@ -296,11 +314,12 @@ func writeCommands(buf *bytes.Buffer, cmd *Command) {
continue
}
buf.WriteString(fmt.Sprintf(" commands+=(%q)\n", c.Name()))
+ writeCmdAliases(buf, c)
}
buf.WriteString("\n")
}
-func writeFlagHandler(buf *bytes.Buffer, name string, annotations map[string][]string) {
+func writeFlagHandler(buf *bytes.Buffer, name string, annotations map[string][]string, cmd *Command) {
for key, value := range annotations {
switch key {
case BashCompFilenameExt:
@@ -308,7 +327,7 @@ func writeFlagHandler(buf *bytes.Buffer, name string, annotations map[string][]s
var ext string
if len(value) > 0 {
- ext = "__handle_filename_extension_flag " + strings.Join(value, "|")
+ ext = fmt.Sprintf("__%s_handle_filename_extension_flag ", cmd.Root().Name()) + strings.Join(value, "|")
} else {
ext = "_filedir"
}
@@ -326,7 +345,7 @@ func writeFlagHandler(buf *bytes.Buffer, name string, annotations map[string][]s
var ext string
if len(value) == 1 {
- ext = "__handle_subdirs_in_dir_flag " + value[0]
+ ext = fmt.Sprintf("__%s_handle_subdirs_in_dir_flag ", cmd.Root().Name()) + value[0]
} else {
ext = "_filedir -d"
}
@@ -335,7 +354,7 @@ func writeFlagHandler(buf *bytes.Buffer, name string, annotations map[string][]s
}
}
-func writeShortFlag(buf *bytes.Buffer, flag *pflag.Flag) {
+func writeShortFlag(buf *bytes.Buffer, flag *pflag.Flag, cmd *Command) {
name := flag.Shorthand
format := " "
if len(flag.NoOptDefVal) == 0 {
@@ -343,10 +362,10 @@ func writeShortFlag(buf *bytes.Buffer, flag *pflag.Flag) {
}
format += "flags+=(\"-%s\")\n"
buf.WriteString(fmt.Sprintf(format, name))
- writeFlagHandler(buf, "-"+name, flag.Annotations)
+ writeFlagHandler(buf, "-"+name, flag.Annotations, cmd)
}
-func writeFlag(buf *bytes.Buffer, flag *pflag.Flag) {
+func writeFlag(buf *bytes.Buffer, flag *pflag.Flag, cmd *Command) {
name := flag.Name
format := " flags+=(\"--%s"
if len(flag.NoOptDefVal) == 0 {
@@ -354,7 +373,7 @@ func writeFlag(buf *bytes.Buffer, flag *pflag.Flag) {
}
format += "\")\n"
buf.WriteString(fmt.Sprintf(format, name))
- writeFlagHandler(buf, "--"+name, flag.Annotations)
+ writeFlagHandler(buf, "--"+name, flag.Annotations, cmd)
}
func writeLocalNonPersistentFlag(buf *bytes.Buffer, flag *pflag.Flag) {
@@ -380,9 +399,9 @@ func writeFlags(buf *bytes.Buffer, cmd *Command) {
if nonCompletableFlag(flag) {
return
}
- writeFlag(buf, flag)
+ writeFlag(buf, flag, cmd)
if len(flag.Shorthand) > 0 {
- writeShortFlag(buf, flag)
+ writeShortFlag(buf, flag, cmd)
}
if localNonPersistentFlags.Lookup(flag.Name) != nil {
writeLocalNonPersistentFlag(buf, flag)
@@ -392,9 +411,9 @@ func writeFlags(buf *bytes.Buffer, cmd *Command) {
if nonCompletableFlag(flag) {
return
}
- writeFlag(buf, flag)
+ writeFlag(buf, flag, cmd)
if len(flag.Shorthand) > 0 {
- writeShortFlag(buf, flag)
+ writeShortFlag(buf, flag, cmd)
}
})
@@ -434,6 +453,21 @@ func writeRequiredNouns(buf *bytes.Buffer, cmd *Command) {
}
}
+func writeCmdAliases(buf *bytes.Buffer, cmd *Command) {
+ if len(cmd.Aliases) == 0 {
+ return
+ }
+
+ sort.Sort(sort.StringSlice(cmd.Aliases))
+
+ buf.WriteString(fmt.Sprint(` if [[ -z "${BASH_VERSION}" || "${BASH_VERSINFO[0]}" -gt 3 ]]; then`, "\n"))
+ for _, value := range cmd.Aliases {
+ buf.WriteString(fmt.Sprintf(" command_aliases+=(%q)\n", value))
+ buf.WriteString(fmt.Sprintf(" aliashash[%q]=%q\n", value, cmd.Name()))
+ }
+ buf.WriteString(` fi`)
+ buf.WriteString("\n")
+}
func writeArgAliases(buf *bytes.Buffer, cmd *Command) {
buf.WriteString(" noun_aliases=()\n")
sort.Sort(sort.StringSlice(cmd.ArgAliases))
@@ -452,8 +486,18 @@ func gen(buf *bytes.Buffer, cmd *Command) {
commandName := cmd.CommandPath()
commandName = strings.Replace(commandName, " ", "_", -1)
commandName = strings.Replace(commandName, ":", "__", -1)
- buf.WriteString(fmt.Sprintf("_%s()\n{\n", commandName))
+
+ if cmd.Root() == cmd {
+ buf.WriteString(fmt.Sprintf("_%s_root_command()\n{\n", commandName))
+ } else {
+ buf.WriteString(fmt.Sprintf("_%s()\n{\n", commandName))
+ }
+
buf.WriteString(fmt.Sprintf(" last_command=%q\n", commandName))
+ buf.WriteString("\n")
+ buf.WriteString(" command_aliases=()\n")
+ buf.WriteString("\n")
+
writeCommands(buf, cmd)
writeFlags(buf, cmd)
writeRequiredFlag(buf, cmd)
@@ -491,17 +535,20 @@ func (c *Command) GenBashCompletionFile(filename string) error {
return c.GenBashCompletion(outFile)
}
-// MarkFlagRequired adds the BashCompOneRequiredFlag annotation to the named flag, if it exists.
+// MarkFlagRequired adds the BashCompOneRequiredFlag annotation to the named flag if it exists,
+// and causes your command to report an error if invoked without the flag.
func (c *Command) MarkFlagRequired(name string) error {
return MarkFlagRequired(c.Flags(), name)
}
-// MarkPersistentFlagRequired adds the BashCompOneRequiredFlag annotation to the named persistent flag, if it exists.
+// MarkPersistentFlagRequired adds the BashCompOneRequiredFlag annotation to the named persistent flag if it exists,
+// and causes your command to report an error if invoked without the flag.
func (c *Command) MarkPersistentFlagRequired(name string) error {
return MarkFlagRequired(c.PersistentFlags(), name)
}
-// MarkFlagRequired adds the BashCompOneRequiredFlag annotation to the named flag in the flag set, if it exists.
+// MarkFlagRequired adds the BashCompOneRequiredFlag annotation to the named flag if it exists,
+// and causes your command to report an error if invoked without the flag.
func MarkFlagRequired(flags *pflag.FlagSet, name string) error {
return flags.SetAnnotation(name, BashCompOneRequiredFlag, []string{"true"})
}
diff --git a/vendor/github.com/spf13/cobra/cobra.go b/vendor/github.com/spf13/cobra/cobra.go
index 8928cefc..7010fd15 100644
--- a/vendor/github.com/spf13/cobra/cobra.go
+++ b/vendor/github.com/spf13/cobra/cobra.go
@@ -70,7 +70,8 @@ func AddTemplateFuncs(tmplFuncs template.FuncMap) {
}
}
-// OnInitialize takes a series of func() arguments and appends them to a slice of func().
+// OnInitialize sets the passed functions to be run when each command's
+// Execute method is called.
func OnInitialize(y ...func()) {
initializers = append(initializers, y...)
}
@@ -188,3 +189,12 @@ func ld(s, t string, ignoreCase bool) int {
}
return d[len(s)][len(t)]
}
+
+func stringInSlice(a string, list []string) bool {
+ for _, b := range list {
+ if b == a {
+ return true
+ }
+ }
+ return false
+}
diff --git a/vendor/github.com/spf13/cobra/command.go b/vendor/github.com/spf13/cobra/command.go
index 58e6ceb0..34d1bf36 100644
--- a/vendor/github.com/spf13/cobra/command.go
+++ b/vendor/github.com/spf13/cobra/command.go
@@ -27,6 +27,9 @@ import (
flag "github.com/spf13/pflag"
)
+// FParseErrWhitelist configures Flag parse errors to be ignored
+type FParseErrWhitelist flag.ParseErrorsWhitelist
+
// Command is just that, a command for your application.
// E.g. 'go run ...' - 'run' is the command. Cobra requires
// you to define the usage and description as part of your command
@@ -75,6 +78,11 @@ type Command struct {
// group commands.
Annotations map[string]string
+ // Version defines the version for this command. If this value is non-empty and the command does not
+ // define a "version" flag, a "version" boolean flag will be added to the command and, if specified,
+ // will print content of the "Version" variable.
+ Version string
+
// The *Run functions are executed in the following order:
// * PersistentPreRun()
// * PreRun()
@@ -118,6 +126,10 @@ type Command struct {
// will be printed by generating docs for this command.
DisableAutoGenTag bool
+ // DisableFlagsInUseLine will disable the addition of [flags] to the usage
+ // line of a command when printing help or generating docs
+ DisableFlagsInUseLine bool
+
// DisableSuggestions disables the suggestions based on Levenshtein distance
// that go along with 'unknown command' messages.
DisableSuggestions bool
@@ -128,6 +140,9 @@ type Command struct {
// TraverseChildren parses flags on all parents before executing child command.
TraverseChildren bool
+ //FParseErrWhitelist flag parse errors to be ignored
+ FParseErrWhitelist FParseErrWhitelist
+
// commands is the list of commands supported by this program.
commands []*Command
// parent is a parent command for this command.
@@ -138,6 +153,11 @@ type Command struct {
commandsMaxNameLen int
// commandsAreSorted defines, if command slice are sorted or not.
commandsAreSorted bool
+ // commandCalledAs is the name or alias value used to call this command.
+ commandCalledAs struct {
+ name string
+ called bool
+ }
// args is actual args parsed from flags.
args []string
@@ -173,6 +193,8 @@ type Command struct {
// helpCommand is command with usage 'help'. If it's not defined by user,
// cobra uses default help command.
helpCommand *Command
+ // versionTemplate is the version template defined by user.
+ versionTemplate string
}
// SetArgs sets arguments for the command. It is set to os.Args[1:] by default, if desired, can be overridden
@@ -218,6 +240,11 @@ func (c *Command) SetHelpTemplate(s string) {
c.helpTemplate = s
}
+// SetVersionTemplate sets version template to be used. Application can use it to set custom template.
+func (c *Command) SetVersionTemplate(s string) {
+ c.versionTemplate = 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) {
@@ -407,6 +434,19 @@ func (c *Command) HelpTemplate() string {
{{end}}{{if or .Runnable .HasSubCommands}}{{.UsageString}}{{end}}`
}
+// VersionTemplate return version template for the command.
+func (c *Command) VersionTemplate() string {
+ if c.versionTemplate != "" {
+ return c.versionTemplate
+ }
+
+ if c.HasParent() {
+ return c.parent.VersionTemplate()
+ }
+ return `{{with .Name}}{{printf "%s " .}}{{end}}{{printf "version %s" .Version}}
+`
+}
+
func hasNoOptDefVal(name string, fs *flag.FlagSet) bool {
flag := fs.Lookup(name)
if flag == nil {
@@ -441,6 +481,9 @@ Loop:
s := args[0]
args = args[1:]
switch {
+ case s == "--":
+ // "--" terminates the flags
+ break Loop
case strings.HasPrefix(s, "--") && !strings.Contains(s, "=") && !hasNoOptDefVal(s[2:], flags):
// If '--flag arg' then
// delete arg from args.
@@ -528,6 +571,7 @@ func (c *Command) findNext(next string) *Command {
matches := make([]*Command, 0)
for _, cmd := range c.commands {
if cmd.Name() == next || cmd.HasAlias(next) {
+ cmd.commandCalledAs.name = next
return cmd
}
if EnablePrefixMatching && cmd.hasNameOrAliasPrefix(next) {
@@ -538,6 +582,7 @@ func (c *Command) findNext(next string) *Command {
if len(matches) == 1 {
return matches[0]
}
+
return nil
}
@@ -621,10 +666,8 @@ func (c *Command) Root() *Command {
return c
}
-// ArgsLenAtDash will return the length of f.Args at the moment when a -- was
-// found during arg parsing. This allows your program to know which args were
-// before the -- and which came after. (Description from
-// https://godoc.org/github.com/spf13/pflag#FlagSet.ArgsLenAtDash).
+// ArgsLenAtDash will return the length of c.Flags().Args at the moment
+// when a -- was found during args parsing.
func (c *Command) ArgsLenAtDash() int {
return c.Flags().ArgsLenAtDash()
}
@@ -638,9 +681,10 @@ func (c *Command) execute(a []string) (err error) {
c.Printf("Command %q is deprecated, %s\n", c.Name(), c.Deprecated)
}
- // initialize help flag as the last point possible to allow for user
+ // initialize help and version flag at the last point possible to allow for user
// overriding
c.InitDefaultHelpFlag()
+ c.InitDefaultVersionFlag()
err = c.ParseFlags(a)
if err != nil {
@@ -657,7 +701,27 @@ func (c *Command) execute(a []string) (err error) {
return err
}
- if helpVal || !c.Runnable() {
+ if helpVal {
+ return flag.ErrHelp
+ }
+
+ // for back-compat, only add version flag behavior if version is defined
+ if c.Version != "" {
+ versionVal, err := c.Flags().GetBool("version")
+ if err != nil {
+ c.Println("\"version\" flag declared as non-bool. Please correct your code")
+ return err
+ }
+ if versionVal {
+ err := tmpl(c.OutOrStdout(), c.VersionTemplate(), c)
+ if err != nil {
+ c.Println(err)
+ }
+ return err
+ }
+ }
+
+ if !c.Runnable() {
return flag.ErrHelp
}
@@ -780,6 +844,11 @@ func (c *Command) ExecuteC() (cmd *Command, err error) {
return c, err
}
+ cmd.commandCalledAs.called = true
+ if cmd.commandCalledAs.name == "" {
+ cmd.commandCalledAs.name = cmd.Name()
+ }
+
err = cmd.execute(flags)
if err != nil {
// Always show help if requested, even if SilenceErrors is in
@@ -825,7 +894,7 @@ func (c *Command) validateRequiredFlags() error {
})
if len(missingFlagNames) > 0 {
- return fmt.Errorf(`Required flag(s) "%s" have/has not been set`, strings.Join(missingFlagNames, `", "`))
+ return fmt.Errorf(`required flag(s) "%s" not set`, strings.Join(missingFlagNames, `", "`))
}
return nil
}
@@ -846,6 +915,27 @@ func (c *Command) InitDefaultHelpFlag() {
}
}
+// InitDefaultVersionFlag adds default version flag to c.
+// It is called automatically by executing the c.
+// If c already has a version flag, it will do nothing.
+// If c.Version is empty, it will do nothing.
+func (c *Command) InitDefaultVersionFlag() {
+ if c.Version == "" {
+ return
+ }
+
+ c.mergePersistentFlags()
+ if c.Flags().Lookup("version") == nil {
+ usage := "version for "
+ if c.Name() == "" {
+ usage += "this command"
+ } else {
+ usage += c.Name()
+ }
+ c.Flags().Bool("version", false, usage)
+ }
+}
+
// InitDefaultHelpCmd adds default help command to c.
// It is called automatically by executing the c or by calling help and usage.
// If c already has help command or c has no subcommands, it will do nothing.
@@ -877,7 +967,7 @@ Simply type ` + c.Name() + ` help [path to command] for full details.`,
c.AddCommand(c.helpCommand)
}
-// ResetCommands used for testing.
+// ResetCommands delete parent, subcommand and help command from c.
func (c *Command) ResetCommands() {
c.parent = nil
c.commands = nil
@@ -996,6 +1086,9 @@ func (c *Command) UseLine() string {
} else {
useline = c.Use
}
+ if c.DisableFlagsInUseLine {
+ return useline
+ }
if c.HasAvailableFlags() && !strings.Contains(useline, "[flags]") {
useline += " [flags]"
}
@@ -1063,14 +1156,25 @@ func (c *Command) HasAlias(s string) bool {
return false
}
+// CalledAs returns the command name or alias that was used to invoke
+// this command or an empty string if the command has not been called.
+func (c *Command) CalledAs() string {
+ if c.commandCalledAs.called {
+ return c.commandCalledAs.name
+ }
+ return ""
+}
+
// hasNameOrAliasPrefix returns true if the Name or any of aliases start
// with prefix
func (c *Command) hasNameOrAliasPrefix(prefix string) bool {
if strings.HasPrefix(c.Name(), prefix) {
+ c.commandCalledAs.name = c.Name()
return true
}
for _, alias := range c.Aliases {
if strings.HasPrefix(alias, prefix) {
+ c.commandCalledAs.name = alias
return true
}
}
@@ -1163,7 +1267,7 @@ func (c *Command) HasAvailableSubCommands() bool {
}
}
- // the command either has no sub comamnds, or no available (non deprecated/help/hidden)
+ // the command either has no sub commands, or no available (non deprecated/help/hidden)
// sub commands
return false
}
@@ -1173,7 +1277,7 @@ func (c *Command) HasParent() bool {
return c.parent != nil
}
-// GlobalNormalizationFunc returns the global normalization function or nil if doesn't exists.
+// GlobalNormalizationFunc returns the global normalization function or nil if it doesn't exist.
func (c *Command) GlobalNormalizationFunc() func(f *flag.FlagSet, name string) flag.NormalizedName {
return c.globNormFunc
}
@@ -1273,7 +1377,7 @@ func (c *Command) PersistentFlags() *flag.FlagSet {
return c.pflags
}
-// ResetFlags is used in testing.
+// ResetFlags deletes all flags from command.
func (c *Command) ResetFlags() {
c.flagErrorBuf = new(bytes.Buffer)
c.flagErrorBuf.Reset()
@@ -1365,6 +1469,10 @@ func (c *Command) ParseFlags(args []string) error {
}
beforeErrorBufLen := c.flagErrorBuf.Len()
c.mergePersistentFlags()
+
+ //do it here after merging all flags and just before parse
+ c.Flags().ParseErrorsWhitelist = flag.ParseErrorsWhitelist(c.FParseErrWhitelist)
+
err := c.Flags().Parse(args)
// Print warnings if they occurred (e.g. deprecated flag messages).
if c.flagErrorBuf.Len()-beforeErrorBufLen > 0 && err == nil {
diff --git a/vendor/github.com/spf13/pflag/bytes.go b/vendor/github.com/spf13/pflag/bytes.go
new file mode 100644
index 00000000..12c58db9
--- /dev/null
+++ b/vendor/github.com/spf13/pflag/bytes.go
@@ -0,0 +1,105 @@
+package pflag
+
+import (
+ "encoding/hex"
+ "fmt"
+ "strings"
+)
+
+// BytesHex adapts []byte for use as a flag. Value of flag is HEX encoded
+type bytesHexValue []byte
+
+func (bytesHex bytesHexValue) String() string {
+ return fmt.Sprintf("%X", []byte(bytesHex))
+}
+
+func (bytesHex *bytesHexValue) Set(value string) error {
+ bin, err := hex.DecodeString(strings.TrimSpace(value))
+
+ if err != nil {
+ return err
+ }
+
+ *bytesHex = bin
+
+ return nil
+}
+
+func (*bytesHexValue) Type() string {
+ return "bytesHex"
+}
+
+func newBytesHexValue(val []byte, p *[]byte) *bytesHexValue {
+ *p = val
+ return (*bytesHexValue)(p)
+}
+
+func bytesHexConv(sval string) (interface{}, error) {
+
+ bin, err := hex.DecodeString(sval)
+
+ if err == nil {
+ return bin, nil
+ }
+
+ return nil, fmt.Errorf("invalid string being converted to Bytes: %s %s", sval, err)
+}
+
+// GetBytesHex return the []byte value of a flag with the given name
+func (f *FlagSet) GetBytesHex(name string) ([]byte, error) {
+ val, err := f.getFlagType(name, "bytesHex", bytesHexConv)
+
+ if err != nil {
+ return []byte{}, err
+ }
+
+ return val.([]byte), nil
+}
+
+// BytesHexVar defines an []byte flag with specified name, default value, and usage string.
+// The argument p points to an []byte variable in which to store the value of the flag.
+func (f *FlagSet) BytesHexVar(p *[]byte, name string, value []byte, usage string) {
+ f.VarP(newBytesHexValue(value, p), name, "", usage)
+}
+
+// BytesHexVarP is like BytesHexVar, but accepts a shorthand letter that can be used after a single dash.
+func (f *FlagSet) BytesHexVarP(p *[]byte, name, shorthand string, value []byte, usage string) {
+ f.VarP(newBytesHexValue(value, p), name, shorthand, usage)
+}
+
+// BytesHexVar defines an []byte flag with specified name, default value, and usage string.
+// The argument p points to an []byte variable in which to store the value of the flag.
+func BytesHexVar(p *[]byte, name string, value []byte, usage string) {
+ CommandLine.VarP(newBytesHexValue(value, p), name, "", usage)
+}
+
+// BytesHexVarP is like BytesHexVar, but accepts a shorthand letter that can be used after a single dash.
+func BytesHexVarP(p *[]byte, name, shorthand string, value []byte, usage string) {
+ CommandLine.VarP(newBytesHexValue(value, p), name, shorthand, usage)
+}
+
+// BytesHex defines an []byte flag with specified name, default value, and usage string.
+// The return value is the address of an []byte variable that stores the value of the flag.
+func (f *FlagSet) BytesHex(name string, value []byte, usage string) *[]byte {
+ p := new([]byte)
+ f.BytesHexVarP(p, name, "", value, usage)
+ return p
+}
+
+// BytesHexP is like BytesHex, but accepts a shorthand letter that can be used after a single dash.
+func (f *FlagSet) BytesHexP(name, shorthand string, value []byte, usage string) *[]byte {
+ p := new([]byte)
+ f.BytesHexVarP(p, name, shorthand, value, usage)
+ return p
+}
+
+// BytesHex defines an []byte flag with specified name, default value, and usage string.
+// The return value is the address of an []byte variable that stores the value of the flag.
+func BytesHex(name string, value []byte, usage string) *[]byte {
+ return CommandLine.BytesHexP(name, "", value, usage)
+}
+
+// BytesHexP is like BytesHex, but accepts a shorthand letter that can be used after a single dash.
+func BytesHexP(name, shorthand string, value []byte, usage string) *[]byte {
+ return CommandLine.BytesHexP(name, shorthand, value, usage)
+}
diff --git a/vendor/github.com/spf13/pflag/count.go b/vendor/github.com/spf13/pflag/count.go
index 250a4381..aa126e44 100644
--- a/vendor/github.com/spf13/pflag/count.go
+++ b/vendor/github.com/spf13/pflag/count.go
@@ -11,13 +11,13 @@ func newCountValue(val int, p *int) *countValue {
}
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 {
+ // "+1" means that no specific value was passed, so increment
+ if s == "+1" {
*i = countValue(*i + 1)
- } else {
- *i = countValue(v)
+ return nil
}
+ v, err := strconv.ParseInt(s, 0, 0)
+ *i = countValue(v)
return err
}
@@ -54,7 +54,7 @@ func (f *FlagSet) CountVar(p *int, name string, usage string) {
// CountVarP is like CountVar only take a shorthand for the flag name.
func (f *FlagSet) CountVarP(p *int, name, shorthand string, usage string) {
flag := f.VarPF(newCountValue(0, p), name, shorthand, usage)
- flag.NoOptDefVal = "-1"
+ flag.NoOptDefVal = "+1"
}
// CountVar like CountVar only the flag is placed on the CommandLine instead of a given flag set
diff --git a/vendor/github.com/spf13/pflag/duration_slice.go b/vendor/github.com/spf13/pflag/duration_slice.go
new file mode 100644
index 00000000..52c6b6dc
--- /dev/null
+++ b/vendor/github.com/spf13/pflag/duration_slice.go
@@ -0,0 +1,128 @@
+package pflag
+
+import (
+ "fmt"
+ "strings"
+ "time"
+)
+
+// -- durationSlice Value
+type durationSliceValue struct {
+ value *[]time.Duration
+ changed bool
+}
+
+func newDurationSliceValue(val []time.Duration, p *[]time.Duration) *durationSliceValue {
+ dsv := new(durationSliceValue)
+ dsv.value = p
+ *dsv.value = val
+ return dsv
+}
+
+func (s *durationSliceValue) Set(val string) error {
+ ss := strings.Split(val, ",")
+ out := make([]time.Duration, len(ss))
+ for i, d := range ss {
+ var err error
+ out[i], err = time.ParseDuration(d)
+ if err != nil {
+ return err
+ }
+
+ }
+ if !s.changed {
+ *s.value = out
+ } else {
+ *s.value = append(*s.value, out...)
+ }
+ s.changed = true
+ return nil
+}
+
+func (s *durationSliceValue) Type() string {
+ return "durationSlice"
+}
+
+func (s *durationSliceValue) String() string {
+ out := make([]string, len(*s.value))
+ for i, d := range *s.value {
+ out[i] = fmt.Sprintf("%s", d)
+ }
+ return "[" + strings.Join(out, ",") + "]"
+}
+
+func durationSliceConv(val string) (interface{}, error) {
+ val = strings.Trim(val, "[]")
+ // Empty string would cause a slice with one (empty) entry
+ if len(val) == 0 {
+ return []time.Duration{}, nil
+ }
+ ss := strings.Split(val, ",")
+ out := make([]time.Duration, len(ss))
+ for i, d := range ss {
+ var err error
+ out[i], err = time.ParseDuration(d)
+ if err != nil {
+ return nil, err
+ }
+
+ }
+ return out, nil
+}
+
+// GetDurationSlice returns the []time.Duration value of a flag with the given name
+func (f *FlagSet) GetDurationSlice(name string) ([]time.Duration, error) {
+ val, err := f.getFlagType(name, "durationSlice", durationSliceConv)
+ if err != nil {
+ return []time.Duration{}, err
+ }
+ return val.([]time.Duration), nil
+}
+
+// DurationSliceVar defines a durationSlice flag with specified name, default value, and usage string.
+// The argument p points to a []time.Duration variable in which to store the value of the flag.
+func (f *FlagSet) DurationSliceVar(p *[]time.Duration, name string, value []time.Duration, usage string) {
+ f.VarP(newDurationSliceValue(value, p), name, "", usage)
+}
+
+// DurationSliceVarP is like DurationSliceVar, but accepts a shorthand letter that can be used after a single dash.
+func (f *FlagSet) DurationSliceVarP(p *[]time.Duration, name, shorthand string, value []time.Duration, usage string) {
+ f.VarP(newDurationSliceValue(value, p), name, shorthand, usage)
+}
+
+// DurationSliceVar defines a duration[] flag with specified name, default value, and usage string.
+// The argument p points to a duration[] variable in which to store the value of the flag.
+func DurationSliceVar(p *[]time.Duration, name string, value []time.Duration, usage string) {
+ CommandLine.VarP(newDurationSliceValue(value, p), name, "", usage)
+}
+
+// DurationSliceVarP is like DurationSliceVar, but accepts a shorthand letter that can be used after a single dash.
+func DurationSliceVarP(p *[]time.Duration, name, shorthand string, value []time.Duration, usage string) {
+ CommandLine.VarP(newDurationSliceValue(value, p), name, shorthand, usage)
+}
+
+// DurationSlice defines a []time.Duration flag with specified name, default value, and usage string.
+// The return value is the address of a []time.Duration variable that stores the value of the flag.
+func (f *FlagSet) DurationSlice(name string, value []time.Duration, usage string) *[]time.Duration {
+ p := []time.Duration{}
+ f.DurationSliceVarP(&p, name, "", value, usage)
+ return &p
+}
+
+// DurationSliceP is like DurationSlice, but accepts a shorthand letter that can be used after a single dash.
+func (f *FlagSet) DurationSliceP(name, shorthand string, value []time.Duration, usage string) *[]time.Duration {
+ p := []time.Duration{}
+ f.DurationSliceVarP(&p, name, shorthand, value, usage)
+ return &p
+}
+
+// DurationSlice defines a []time.Duration flag with specified name, default value, and usage string.
+// The return value is the address of a []time.Duration variable that stores the value of the flag.
+func DurationSlice(name string, value []time.Duration, usage string) *[]time.Duration {
+ return CommandLine.DurationSliceP(name, "", value, usage)
+}
+
+// DurationSliceP is like DurationSlice, but accepts a shorthand letter that can be used after a single dash.
+func DurationSliceP(name, shorthand string, value []time.Duration, usage string) *[]time.Duration {
+ return CommandLine.DurationSliceP(name, shorthand, value, usage)
+}
diff --git a/vendor/github.com/spf13/pflag/flag.go b/vendor/github.com/spf13/pflag/flag.go
index 6f1fc300..5eadc84e 100644
--- a/vendor/github.com/spf13/pflag/flag.go
+++ b/vendor/github.com/spf13/pflag/flag.go
@@ -101,6 +101,7 @@ package pflag
import (
"bytes"
"errors"
+ goflag "flag"
"fmt"
"io"
"os"
@@ -123,6 +124,12 @@ const (
PanicOnError
)
+// ParseErrorsWhitelist defines the parsing errors that can be ignored
+type ParseErrorsWhitelist struct {
+ // UnknownFlags will ignore unknown flags errors and continue parsing rest of the flags
+ UnknownFlags bool
+}
+
// NormalizedName is a flag name that has been normalized according to rules
// for the FlagSet (e.g. making '-' and '_' equivalent).
type NormalizedName string
@@ -138,6 +145,9 @@ type FlagSet struct {
// help/usage messages.
SortFlags bool
+ // ParseErrorsWhitelist is used to configure a whitelist of errors
+ ParseErrorsWhitelist ParseErrorsWhitelist
+
name string
parsed bool
actual map[NormalizedName]*Flag
@@ -153,6 +163,8 @@ type FlagSet struct {
output io.Writer // nil means stderr; use out() accessor
interspersed bool // allow interspersed option/non-option args
normalizeNameFunc func(f *FlagSet, name string) NormalizedName
+
+ addedGoFlagSets []*goflag.FlagSet
}
// A Flag represents the state of a flag.
@@ -202,12 +214,18 @@ func sortFlags(flags map[NormalizedName]*Flag) []*Flag {
func (f *FlagSet) SetNormalizeFunc(n func(f *FlagSet, name string) NormalizedName) {
f.normalizeNameFunc = n
f.sortedFormal = f.sortedFormal[:0]
- for k, v := range f.orderedFormal {
- delete(f.formal, NormalizedName(v.Name))
- nname := f.normalizeFlagName(v.Name)
- v.Name = string(nname)
- f.formal[nname] = v
- f.orderedFormal[k] = v
+ for fname, flag := range f.formal {
+ nname := f.normalizeFlagName(flag.Name)
+ if fname == nname {
+ continue
+ }
+ flag.Name = string(nname)
+ delete(f.formal, fname)
+ f.formal[nname] = flag
+ if _, set := f.actual[fname]; set {
+ delete(f.actual, fname)
+ f.actual[nname] = flag
+ }
}
}
@@ -261,16 +279,16 @@ func (f *FlagSet) VisitAll(fn func(*Flag)) {
}
}
-// HasFlags returns a bool to indicate if the FlagSet has any flags definied.
+// HasFlags returns a bool to indicate if the FlagSet has any flags defined.
func (f *FlagSet) HasFlags() bool {
return len(f.formal) > 0
}
// HasAvailableFlags returns a bool to indicate if the FlagSet has any flags
-// definied that are not hidden or deprecated.
+// that are not hidden.
func (f *FlagSet) HasAvailableFlags() bool {
for _, flag := range f.formal {
- if !flag.Hidden && len(flag.Deprecated) == 0 {
+ if !flag.Hidden {
return true
}
}
@@ -380,6 +398,7 @@ func (f *FlagSet) MarkDeprecated(name string, usageMessage string) error {
return fmt.Errorf("deprecated message for flag %q must be set", name)
}
flag.Deprecated = usageMessage
+ flag.Hidden = true
return nil
}
@@ -440,13 +459,15 @@ func (f *FlagSet) Set(name, value string) error {
return fmt.Errorf("invalid argument %q for %q flag: %v", value, flagName, err)
}
- if f.actual == nil {
- f.actual = make(map[NormalizedName]*Flag)
- }
- f.actual[normalName] = flag
- f.orderedActual = append(f.orderedActual, flag)
+ if !flag.Changed {
+ if f.actual == nil {
+ f.actual = make(map[NormalizedName]*Flag)
+ }
+ f.actual[normalName] = flag
+ f.orderedActual = append(f.orderedActual, flag)
- flag.Changed = true
+ flag.Changed = true
+ }
if flag.Deprecated != "" {
fmt.Fprintf(f.out(), "Flag --%s has been deprecated, %s\n", flag.Name, flag.Deprecated)
@@ -556,6 +577,14 @@ func UnquoteUsage(flag *Flag) (name string, usage string) {
name = "int"
case "uint64":
name = "uint"
+ case "stringSlice":
+ name = "strings"
+ case "intSlice":
+ name = "ints"
+ case "uintSlice":
+ name = "uints"
+ case "boolSlice":
+ name = "bools"
}
return
@@ -570,11 +599,14 @@ func wrapN(i, slop int, s string) (string, string) {
return s, ""
}
- w := strings.LastIndexAny(s[:i], " \t")
+ w := strings.LastIndexAny(s[:i], " \t\n")
if w <= 0 {
return s, ""
}
-
+ nlPos := strings.LastIndex(s[:i], "\n")
+ if nlPos > 0 && nlPos < w {
+ return s[:nlPos], s[nlPos+1:]
+ }
return s[:w], s[w+1:]
}
@@ -583,7 +615,7 @@ func wrapN(i, slop int, s string) (string, string) {
// caller). Pass `w` == 0 to do no wrapping
func wrap(i, w int, s string) string {
if w == 0 {
- return s
+ return strings.Replace(s, "\n", "\n"+strings.Repeat(" ", i), -1)
}
// space between indent i and end of line width w into which
@@ -601,7 +633,7 @@ func wrap(i, w int, s string) string {
}
// If still not enough space then don't even try to wrap.
if wrap < 24 {
- return s
+ return strings.Replace(s, "\n", r, -1)
}
// Try to avoid short orphan words on the final line, by
@@ -613,14 +645,14 @@ func wrap(i, w int, s string) string {
// Handle first line, which is indented by the caller (or the
// special case above)
l, s = wrapN(wrap, slop, s)
- r = r + l
+ r = r + strings.Replace(l, "\n", "\n"+strings.Repeat(" ", i), -1)
// Now wrap the rest
for s != "" {
var t string
t, s = wrapN(wrap, slop, s)
- r = r + "\n" + strings.Repeat(" ", i) + t
+ r = r + "\n" + strings.Repeat(" ", i) + strings.Replace(t, "\n", "\n"+strings.Repeat(" ", i), -1)
}
return r
@@ -637,7 +669,7 @@ func (f *FlagSet) FlagUsagesWrapped(cols int) string {
maxlen := 0
f.VisitAll(func(flag *Flag) {
- if flag.Deprecated != "" || flag.Hidden {
+ if flag.Hidden {
return
}
@@ -660,6 +692,10 @@ func (f *FlagSet) FlagUsagesWrapped(cols int) string {
if flag.NoOptDefVal != "true" {
line += fmt.Sprintf("[=%s]", flag.NoOptDefVal)
}
+ case "count":
+ if flag.NoOptDefVal != "+1" {
+ line += fmt.Sprintf("[=%s]", flag.NoOptDefVal)
+ }
default:
line += fmt.Sprintf("[=%s]", flag.NoOptDefVal)
}
@@ -680,6 +716,9 @@ func (f *FlagSet) FlagUsagesWrapped(cols int) string {
line += fmt.Sprintf(" (default %s)", flag.DefValue)
}
}
+ if len(flag.Deprecated) != 0 {
+ line += fmt.Sprintf(" (DEPRECATED: %s)", flag.Deprecated)
+ }
lines = append(lines, line)
})
@@ -857,8 +896,10 @@ func VarP(value Value, name, shorthand, usage string) {
// returns the error.
func (f *FlagSet) failf(format string, a ...interface{}) error {
err := fmt.Errorf(format, a...)
- fmt.Fprintln(f.out(), err)
- f.usage()
+ if f.errorHandling != ContinueOnError {
+ fmt.Fprintln(f.out(), err)
+ f.usage()
+ }
return err
}
@@ -874,6 +915,25 @@ func (f *FlagSet) usage() {
}
}
+//--unknown (args will be empty)
+//--unknown --next-flag ... (args will be --next-flag ...)
+//--unknown arg ... (args will be arg ...)
+func stripUnknownFlagValue(args []string) []string {
+ if len(args) == 0 {
+ //--unknown
+ return args
+ }
+
+ first := args[0]
+ if first[0] == '-' {
+ //--unknown --next-flag ...
+ return args
+ }
+
+ //--unknown arg ... (args will be arg ...)
+ return args[1:]
+}
+
func (f *FlagSet) parseLongArg(s string, args []string, fn parseFunc) (a []string, err error) {
a = args
name := s[2:]
@@ -885,13 +945,24 @@ func (f *FlagSet) parseLongArg(s string, args []string, fn parseFunc) (a []strin
split := strings.SplitN(name, "=", 2)
name = split[0]
flag, exists := f.formal[f.normalizeFlagName(name)]
+
if !exists {
- if name == "help" { // special case for nice help message.
+ switch {
+ case name == "help":
f.usage()
return a, ErrHelp
+ case f.ParseErrorsWhitelist.UnknownFlags:
+ // --unknown=unknownval arg ...
+ // we do not want to lose arg in this case
+ if len(split) >= 2 {
+ return a, nil
+ }
+
+ return stripUnknownFlagValue(a), nil
+ default:
+ err = f.failf("unknown flag: --%s", name)
+ return
}
- err = f.failf("unknown flag: --%s", name)
- return
}
var value string
@@ -912,6 +983,9 @@ func (f *FlagSet) parseLongArg(s string, args []string, fn parseFunc) (a []strin
}
err = fn(flag, value)
+ if err != nil {
+ f.failf(err.Error())
+ }
return
}
@@ -926,13 +1000,25 @@ func (f *FlagSet) parseSingleShortArg(shorthands string, args []string, fn parse
flag, exists := f.shorthands[c]
if !exists {
- if c == 'h' { // special case for nice help message.
+ switch {
+ case c == 'h':
f.usage()
err = ErrHelp
return
+ case f.ParseErrorsWhitelist.UnknownFlags:
+ // '-f=arg arg ...'
+ // we do not want to lose arg in this case
+ if len(shorthands) > 2 && shorthands[1] == '=' {
+ outShorts = ""
+ return
+ }
+
+ outArgs = stripUnknownFlagValue(outArgs)
+ return
+ default:
+ err = f.failf("unknown shorthand flag: %q in -%s", c, shorthands)
+ return
}
- err = f.failf("unknown shorthand flag: %q in -%s", c, shorthands)
- return
}
var value string
@@ -962,6 +1048,9 @@ func (f *FlagSet) parseSingleShortArg(shorthands string, args []string, fn parse
}
err = fn(flag, value)
+ if err != nil {
+ f.failf(err.Error())
+ }
return
}
@@ -1016,6 +1105,11 @@ func (f *FlagSet) parseArgs(args []string, fn parseFunc) (err error) {
// are defined and before flags are accessed by the program.
// The return value will be ErrHelp if -help was set but not defined.
func (f *FlagSet) Parse(arguments []string) error {
+ if f.addedGoFlagSets != nil {
+ for _, goFlagSet := range f.addedGoFlagSets {
+ goFlagSet.Parse(nil)
+ }
+ }
f.parsed = true
if len(arguments) < 0 {
@@ -1034,6 +1128,7 @@ func (f *FlagSet) Parse(arguments []string) error {
case ContinueOnError:
return err
case ExitOnError:
+ fmt.Println(err)
os.Exit(2)
case PanicOnError:
panic(err)
diff --git a/vendor/github.com/spf13/pflag/golangflag.go b/vendor/github.com/spf13/pflag/golangflag.go
index c4f47ebe..d3dd72b7 100644
--- a/vendor/github.com/spf13/pflag/golangflag.go
+++ b/vendor/github.com/spf13/pflag/golangflag.go
@@ -98,4 +98,8 @@ func (f *FlagSet) AddGoFlagSet(newSet *goflag.FlagSet) {
newSet.VisitAll(func(goflag *goflag.Flag) {
f.AddGoFlag(goflag)
})
+ if f.addedGoFlagSets == nil {
+ f.addedGoFlagSets = make([]*goflag.FlagSet, 0)
+ }
+ f.addedGoFlagSets = append(f.addedGoFlagSets, newSet)
}
diff --git a/vendor/github.com/spf13/pflag/int16.go b/vendor/github.com/spf13/pflag/int16.go
new file mode 100644
index 00000000..f1a01d05
--- /dev/null
+++ b/vendor/github.com/spf13/pflag/int16.go
@@ -0,0 +1,88 @@
+package pflag
+
+import "strconv"
+
+// -- int16 Value
+type int16Value int16
+
+func newInt16Value(val int16, p *int16) *int16Value {
+ *p = val
+ return (*int16Value)(p)
+}
+
+func (i *int16Value) Set(s string) error {
+ v, err := strconv.ParseInt(s, 0, 16)
+ *i = int16Value(v)
+ return err
+}
+
+func (i *int16Value) Type() string {
+ return "int16"
+}
+
+func (i *int16Value) String() string { return strconv.FormatInt(int64(*i), 10) }
+
+func int16Conv(sval string) (interface{}, error) {
+ v, err := strconv.ParseInt(sval, 0, 16)
+ if err != nil {
+ return 0, err
+ }
+ return int16(v), nil
+}
+
+// GetInt16 returns the int16 value of a flag with the given name
+func (f *FlagSet) GetInt16(name string) (int16, error) {
+ val, err := f.getFlagType(name, "int16", int16Conv)
+ if err != nil {
+ return 0, err
+ }
+ return val.(int16), nil
+}
+
+// Int16Var defines an int16 flag with specified name, default value, and usage string.
+// The argument p points to an int16 variable in which to store the value of the flag.
+func (f *FlagSet) Int16Var(p *int16, name string, value int16, usage string) {
+ f.VarP(newInt16Value(value, p), name, "", usage)
+}
+
+// Int16VarP is like Int16Var, but accepts a shorthand letter that can be used after a single dash.
+func (f *FlagSet) Int16VarP(p *int16, name, shorthand string, value int16, usage string) {
+ f.VarP(newInt16Value(value, p), name, shorthand, usage)
+}
+
+// Int16Var defines an int16 flag with specified name, default value, and usage string.
+// The argument p points to an int16 variable in which to store the value of the flag.
+func Int16Var(p *int16, name string, value int16, usage string) {
+ CommandLine.VarP(newInt16Value(value, p), name, "", usage)
+}
+
+// Int16VarP is like Int16Var, but accepts a shorthand letter that can be used after a single dash.
+func Int16VarP(p *int16, name, shorthand string, value int16, usage string) {
+ CommandLine.VarP(newInt16Value(value, p), name, shorthand, usage)
+}
+
+// Int16 defines an int16 flag with specified name, default value, and usage string.
+// The return value is the address of an int16 variable that stores the value of the flag.
+func (f *FlagSet) Int16(name string, value int16, usage string) *int16 {
+ p := new(int16)
+ f.Int16VarP(p, name, "", value, usage)
+ return p
+}
+
+// Int16P is like Int16, but accepts a shorthand letter that can be used after a single dash.
+func (f *FlagSet) Int16P(name, shorthand string, value int16, usage string) *int16 {
+ p := new(int16)
+ f.Int16VarP(p, name, shorthand, value, usage)
+ return p
+}
+
+// Int16 defines an int16 flag with specified name, default value, and usage string.
+// The return value is the address of an int16 variable that stores the value of the flag.
+func Int16(name string, value int16, usage string) *int16 {
+ return CommandLine.Int16P(name, "", value, usage)
+}
+
+// Int16P is like Int16, but accepts a shorthand letter that can be used after a single dash.
+func Int16P(name, shorthand string, value int16, usage string) *int16 {
+ return CommandLine.Int16P(name, shorthand, value, usage)
+}
diff --git a/vendor/github.com/spf13/pflag/string_array.go b/vendor/github.com/spf13/pflag/string_array.go
index 276b7ed4..fa7bc601 100644
--- a/vendor/github.com/spf13/pflag/string_array.go
+++ b/vendor/github.com/spf13/pflag/string_array.go
@@ -52,7 +52,7 @@ func (f *FlagSet) GetStringArray(name string) ([]string, error) {
// StringArrayVar defines a string flag with specified name, default value, and usage string.
// The argument p points to a []string variable in which to store the values of the multiple flags.
-// The value of each argument will not try to be separated by comma
+// The value of each argument will not try to be separated by comma. Use a StringSlice for that.
func (f *FlagSet) StringArrayVar(p *[]string, name string, value []string, usage string) {
f.VarP(newStringArrayValue(value, p), name, "", usage)
}
@@ -64,7 +64,7 @@ func (f *FlagSet) StringArrayVarP(p *[]string, name, shorthand string, value []s
// StringArrayVar defines a string flag with specified name, default value, and usage string.
// The argument p points to a []string variable in which to store the value of the flag.
-// The value of each argument will not try to be separated by comma
+// The value of each argument will not try to be separated by comma. Use a StringSlice for that.
func StringArrayVar(p *[]string, name string, value []string, usage string) {
CommandLine.VarP(newStringArrayValue(value, p), name, "", usage)
}
@@ -76,7 +76,7 @@ func StringArrayVarP(p *[]string, name, shorthand string, value []string, usage
// StringArray defines a string flag with specified name, default value, and usage string.
// The return value is the address of a []string variable that stores the value of the flag.
-// The value of each argument will not try to be separated by comma
+// The value of each argument will not try to be separated by comma. Use a StringSlice for that.
func (f *FlagSet) StringArray(name string, value []string, usage string) *[]string {
p := []string{}
f.StringArrayVarP(&p, name, "", value, usage)
@@ -92,7 +92,7 @@ func (f *FlagSet) StringArrayP(name, shorthand string, value []string, usage str
// StringArray defines a string flag with specified name, default value, and usage string.
// The return value is the address of a []string variable that stores the value of the flag.
-// The value of each argument will not try to be separated by comma
+// The value of each argument will not try to be separated by comma. Use a StringSlice for that.
func StringArray(name string, value []string, usage string) *[]string {
return CommandLine.StringArrayP(name, "", value, usage)
}
diff --git a/vendor/github.com/spf13/pflag/string_slice.go b/vendor/github.com/spf13/pflag/string_slice.go
index 05eee754..0cd3ccc0 100644
--- a/vendor/github.com/spf13/pflag/string_slice.go
+++ b/vendor/github.com/spf13/pflag/string_slice.go
@@ -82,6 +82,11 @@ func (f *FlagSet) GetStringSlice(name string) ([]string, error) {
// StringSliceVar defines a string flag with specified name, default value, and usage string.
// The argument p points to a []string variable in which to store the value of the flag.
+// Compared to StringArray flags, StringSlice flags take comma-separated value as arguments and split them accordingly.
+// For example:
+// --ss="v1,v2" -ss="v3"
+// will result in
+// []string{"v1", "v2", "v3"}
func (f *FlagSet) StringSliceVar(p *[]string, name string, value []string, usage string) {
f.VarP(newStringSliceValue(value, p), name, "", usage)
}
@@ -93,6 +98,11 @@ func (f *FlagSet) StringSliceVarP(p *[]string, name, shorthand string, value []s
// StringSliceVar defines a string flag with specified name, default value, and usage string.
// The argument p points to a []string variable in which to store the value of the flag.
+// Compared to StringArray flags, StringSlice flags take comma-separated value as arguments and split them accordingly.
+// For example:
+// --ss="v1,v2" -ss="v3"
+// will result in
+// []string{"v1", "v2", "v3"}
func StringSliceVar(p *[]string, name string, value []string, usage string) {
CommandLine.VarP(newStringSliceValue(value, p), name, "", usage)
}
@@ -104,6 +114,11 @@ func StringSliceVarP(p *[]string, name, shorthand string, value []string, usage
// StringSlice defines a string flag with specified name, default value, and usage string.
// The return value is the address of a []string variable that stores the value of the flag.
+// Compared to StringArray flags, StringSlice flags take comma-separated value as arguments and split them accordingly.
+// For example:
+// --ss="v1,v2" -ss="v3"
+// will result in
+// []string{"v1", "v2", "v3"}
func (f *FlagSet) StringSlice(name string, value []string, usage string) *[]string {
p := []string{}
f.StringSliceVarP(&p, name, "", value, usage)
@@ -119,6 +134,11 @@ func (f *FlagSet) StringSliceP(name, shorthand string, value []string, usage str
// StringSlice defines a string flag with specified name, default value, and usage string.
// The return value is the address of a []string variable that stores the value of the flag.
+// Compared to StringArray flags, StringSlice flags take comma-separated value as arguments and split them accordingly.
+// For example:
+// --ss="v1,v2" -ss="v3"
+// will result in
+// []string{"v1", "v2", "v3"}
func StringSlice(name string, value []string, usage string) *[]string {
return CommandLine.StringSliceP(name, "", value, usage)
}