aboutsummaryrefslogtreecommitdiff
path: root/vendor/github.com/spf13
diff options
context:
space:
mode:
authorNiall Sheridan <nsheridan@gmail.com>2017-10-18 13:15:14 +0100
committerNiall Sheridan <niall@intercom.io>2017-10-18 13:25:46 +0100
commit7b320119ba532fd409ec7dade7ad02011c309599 (patch)
treea39860f35b55e6cc499f8f5bfa969138c5dd6b73 /vendor/github.com/spf13
parent7c99874c7a3e7a89716f3ee0cdf696532e35ae35 (diff)
Update dependencies
Diffstat (limited to 'vendor/github.com/spf13')
-rw-r--r--vendor/github.com/spf13/afero/README.md13
-rw-r--r--vendor/github.com/spf13/afero/appveyor.yml2
-rw-r--r--vendor/github.com/spf13/afero/cacheOnReadFs.go9
-rw-r--r--vendor/github.com/spf13/afero/match.go110
-rw-r--r--vendor/github.com/spf13/afero/mem/file.go40
-rw-r--r--vendor/github.com/spf13/afero/memmap.go10
-rw-r--r--vendor/github.com/spf13/afero/memradix.go14
-rw-r--r--vendor/github.com/spf13/cast/cast.go6
-rw-r--r--vendor/github.com/spf13/cast/caste.go29
-rw-r--r--vendor/github.com/spf13/jwalterweatherman/log_counter.go1
-rw-r--r--vendor/github.com/spf13/jwalterweatherman/notepad.go89
-rw-r--r--vendor/github.com/spf13/pflag/README.md25
-rw-r--r--vendor/github.com/spf13/pflag/count.go16
-rw-r--r--vendor/github.com/spf13/pflag/flag.go230
-rw-r--r--vendor/github.com/spf13/pflag/int16.go88
-rw-r--r--vendor/github.com/spf13/viper/README.md50
-rw-r--r--vendor/github.com/spf13/viper/viper.go86
17 files changed, 590 insertions, 228 deletions
diff --git a/vendor/github.com/spf13/afero/README.md b/vendor/github.com/spf13/afero/README.md
index d9e3327..0c9b04b 100644
--- a/vendor/github.com/spf13/afero/README.md
+++ b/vendor/github.com/spf13/afero/README.md
@@ -61,11 +61,11 @@ import "github.com/spf13/afero"
First define a package variable and set it to a pointer to a filesystem.
```go
-var AppFs afero.Fs = afero.NewMemMapFs()
+var AppFs = afero.NewMemMapFs()
or
-var AppFs afero.Fs = afero.NewOsFs()
+var AppFs = afero.NewOsFs()
```
It is important to note that if you repeat the composite literal you
will be using a completely new and isolated filesystem. In the case of
@@ -81,7 +81,10 @@ So if my application before had:
```go
os.Open('/tmp/foo')
```
-We would replace it with a call to `AppFs.Open('/tmp/foo')`.
+We would replace it with:
+```go
+AppFs.Open('/tmp/foo')
+```
`AppFs` being the variable we defined above.
@@ -166,8 +169,8 @@ f, err := afero.TempFile(fs,"", "ioutil-test")
### Calling via Afero
```go
-fs := afero.NewMemMapFs
-afs := &Afero{Fs: fs}
+fs := afero.NewMemMapFs()
+afs := &afero.Afero{Fs: fs}
f, err := afs.TempFile("", "ioutil-test")
```
diff --git a/vendor/github.com/spf13/afero/appveyor.yml b/vendor/github.com/spf13/afero/appveyor.yml
index 006f315..a633ad5 100644
--- a/vendor/github.com/spf13/afero/appveyor.yml
+++ b/vendor/github.com/spf13/afero/appveyor.yml
@@ -12,4 +12,4 @@ build_script:
go build github.com/spf13/afero
test_script:
-- cmd: go test -v github.com/spf13/afero
+- cmd: go test -race -v github.com/spf13/afero/...
diff --git a/vendor/github.com/spf13/afero/cacheOnReadFs.go b/vendor/github.com/spf13/afero/cacheOnReadFs.go
index e54a4f8..b026e0d 100644
--- a/vendor/github.com/spf13/afero/cacheOnReadFs.go
+++ b/vendor/github.com/spf13/afero/cacheOnReadFs.go
@@ -64,15 +64,10 @@ func (u *CacheOnReadFs) cacheStatus(name string) (state cacheState, fi os.FileIn
return cacheHit, lfi, nil
}
- if err == syscall.ENOENT {
+ if err == syscall.ENOENT || os.IsNotExist(err) {
return cacheMiss, nil, nil
}
- var ok bool
- if err, ok = err.(*os.PathError); ok {
- if err == os.ErrNotExist {
- return cacheMiss, nil, nil
- }
- }
+
return cacheMiss, nil, err
}
diff --git a/vendor/github.com/spf13/afero/match.go b/vendor/github.com/spf13/afero/match.go
new file mode 100644
index 0000000..08b3b7e
--- /dev/null
+++ b/vendor/github.com/spf13/afero/match.go
@@ -0,0 +1,110 @@
+// Copyright © 2014 Steve Francia <spf@spf13.com>.
+// Copyright 2009 The Go Authors. 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 afero
+
+import (
+ "path/filepath"
+ "sort"
+ "strings"
+)
+
+// Glob returns the names of all files matching pattern or nil
+// if there is no matching file. The syntax of patterns is the same
+// as in Match. The pattern may describe hierarchical names such as
+// /usr/*/bin/ed (assuming the Separator is '/').
+//
+// Glob ignores file system errors such as I/O errors reading directories.
+// The only possible returned error is ErrBadPattern, when pattern
+// is malformed.
+//
+// This was adapted from (http://golang.org/pkg/path/filepath) and uses several
+// 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 {
+ return nil, nil
+ }
+ return []string{pattern}, nil
+ }
+
+ dir, file := filepath.Split(pattern)
+ switch dir {
+ case "":
+ dir = "."
+ case string(filepath.Separator):
+ // nothing
+ default:
+ dir = dir[0 : len(dir)-1] // chop off trailing separator
+ }
+
+ if !hasMeta(dir) {
+ return glob(fs, dir, file, nil)
+ }
+
+ var m []string
+ m, err = Glob(fs, dir)
+ if err != nil {
+ return
+ }
+ for _, d := range m {
+ matches, err = glob(fs, d, file, matches)
+ if err != nil {
+ return
+ }
+ }
+ return
+}
+
+// glob searches for files matching pattern in the directory dir
+// and appends them to matches. If the directory cannot be
+// opened, it returns the existing matches. New matches are
+// added in lexicographical order.
+func glob(fs Fs, dir, pattern string, matches []string) (m []string, e error) {
+ m = matches
+ fi, err := fs.Stat(dir)
+ if err != nil {
+ return
+ }
+ if !fi.IsDir() {
+ return
+ }
+ d, err := fs.Open(dir)
+ if err != nil {
+ return
+ }
+ defer d.Close()
+
+ names, _ := d.Readdirnames(-1)
+ sort.Strings(names)
+
+ for _, n := range names {
+ matched, err := filepath.Match(pattern, n)
+ if err != nil {
+ return m, err
+ }
+ if matched {
+ m = append(m, filepath.Join(dir, n))
+ }
+ }
+ return
+}
+
+// hasMeta reports whether path contains any of the magic characters
+// recognized by Match.
+func hasMeta(path string) bool {
+ // TODO(niemeyer): Should other magic characters be added here?
+ return strings.IndexAny(path, "*?[") >= 0
+}
diff --git a/vendor/github.com/spf13/afero/mem/file.go b/vendor/github.com/spf13/afero/mem/file.go
index e41e012..5401a3b 100644
--- a/vendor/github.com/spf13/afero/mem/file.go
+++ b/vendor/github.com/spf13/afero/mem/file.go
@@ -74,14 +74,24 @@ func CreateDir(name string) *FileData {
}
func ChangeFileName(f *FileData, newname string) {
+ f.Lock()
f.name = newname
+ f.Unlock()
}
func SetMode(f *FileData, mode os.FileMode) {
+ f.Lock()
f.mode = mode
+ f.Unlock()
}
func SetModTime(f *FileData, mtime time.Time) {
+ f.Lock()
+ setModTime(f, mtime)
+ f.Unlock()
+}
+
+func setModTime(f *FileData, mtime time.Time) {
f.modtime = mtime
}
@@ -102,7 +112,7 @@ func (f *File) Close() error {
f.fileData.Lock()
f.closed = true
if !f.readOnly {
- SetModTime(f.fileData, time.Now())
+ setModTime(f.fileData, time.Now())
}
f.fileData.Unlock()
return nil
@@ -197,7 +207,7 @@ func (f *File) Truncate(size int64) error {
} else {
f.fileData.data = f.fileData.data[0:size]
}
- SetModTime(f.fileData, time.Now())
+ setModTime(f.fileData, time.Now())
return nil
}
@@ -236,7 +246,7 @@ func (f *File) Write(b []byte) (n int, err error) {
f.fileData.data = append(f.fileData.data[:cur], b...)
f.fileData.data = append(f.fileData.data, tail...)
}
- SetModTime(f.fileData, time.Now())
+ setModTime(f.fileData, time.Now())
atomic.StoreInt64(&f.at, int64(len(f.fileData.data)))
return
@@ -261,17 +271,33 @@ type FileInfo struct {
// Implements os.FileInfo
func (s *FileInfo) Name() string {
+ s.Lock()
_, name := filepath.Split(s.name)
+ s.Unlock()
return name
}
-func (s *FileInfo) Mode() os.FileMode { return s.mode }
-func (s *FileInfo) ModTime() time.Time { return s.modtime }
-func (s *FileInfo) IsDir() bool { return s.dir }
-func (s *FileInfo) Sys() interface{} { return nil }
+func (s *FileInfo) Mode() os.FileMode {
+ s.Lock()
+ defer s.Unlock()
+ return s.mode
+}
+func (s *FileInfo) ModTime() time.Time {
+ s.Lock()
+ defer s.Unlock()
+ return s.modtime
+}
+func (s *FileInfo) IsDir() bool {
+ s.Lock()
+ defer s.Unlock()
+ return s.dir
+}
+func (s *FileInfo) Sys() interface{} { return nil }
func (s *FileInfo) Size() int64 {
if s.IsDir() {
return int64(42)
}
+ s.Lock()
+ defer s.Unlock()
return int64(len(s.data))
}
diff --git a/vendor/github.com/spf13/afero/memmap.go b/vendor/github.com/spf13/afero/memmap.go
index 767ac1d..09498e7 100644
--- a/vendor/github.com/spf13/afero/memmap.go
+++ b/vendor/github.com/spf13/afero/memmap.go
@@ -66,7 +66,10 @@ func (m *MemMapFs) unRegisterWithParent(fileName string) error {
if parent == nil {
log.Panic("parent of ", f.Name(), " is nil")
}
+
+ parent.Lock()
mem.RemoveFromMemDir(parent, f)
+ parent.Unlock()
return nil
}
@@ -99,8 +102,10 @@ func (m *MemMapFs) registerWithParent(f *mem.FileData) {
}
}
+ parent.Lock()
mem.InitializeDir(parent)
mem.AddToMemDir(parent, f)
+ parent.Unlock()
}
func (m *MemMapFs) lockfreeMkdir(name string, perm os.FileMode) error {
@@ -136,7 +141,7 @@ func (m *MemMapFs) Mkdir(name string, perm os.FileMode) error {
m.registerWithParent(item)
m.mu.Unlock()
- m.Chmod(name, perm)
+ m.Chmod(name, perm|os.ModeDir)
return nil
}
@@ -146,9 +151,8 @@ func (m *MemMapFs) MkdirAll(path string, perm os.FileMode) error {
if err != nil {
if err.(*os.PathError).Err == ErrFileExists {
return nil
- } else {
- return err
}
+ return err
}
return nil
}
diff --git a/vendor/github.com/spf13/afero/memradix.go b/vendor/github.com/spf13/afero/memradix.go
deleted file mode 100644
index 87527f3..0000000
--- a/vendor/github.com/spf13/afero/memradix.go
+++ /dev/null
@@ -1,14 +0,0 @@
-// Copyright © 2014 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
diff --git a/vendor/github.com/spf13/cast/cast.go b/vendor/github.com/spf13/cast/cast.go
index dc504b4..8b8c208 100644
--- a/vendor/github.com/spf13/cast/cast.go
+++ b/vendor/github.com/spf13/cast/cast.go
@@ -151,3 +151,9 @@ func ToIntSlice(i interface{}) []int {
v, _ := ToIntSliceE(i)
return v
}
+
+// ToDurationSlice casts an interface to a []time.Duration type.
+func ToDurationSlice(i interface{}) []time.Duration {
+ v, _ := ToDurationSliceE(i)
+ return v
+}
diff --git a/vendor/github.com/spf13/cast/caste.go b/vendor/github.com/spf13/cast/caste.go
index 4e75f64..81511fe 100644
--- a/vendor/github.com/spf13/cast/caste.go
+++ b/vendor/github.com/spf13/cast/caste.go
@@ -1077,6 +1077,35 @@ func ToIntSliceE(i interface{}) ([]int, error) {
}
}
+// ToDurationSliceE casts an interface to a []time.Duration type.
+func ToDurationSliceE(i interface{}) ([]time.Duration, error) {
+ if i == nil {
+ return []time.Duration{}, fmt.Errorf("unable to cast %#v of type %T to []time.Duration", i, i)
+ }
+
+ switch v := i.(type) {
+ case []time.Duration:
+ return v, nil
+ }
+
+ kind := reflect.TypeOf(i).Kind()
+ switch kind {
+ case reflect.Slice, reflect.Array:
+ s := reflect.ValueOf(i)
+ a := make([]time.Duration, s.Len())
+ for j := 0; j < s.Len(); j++ {
+ val, err := ToDurationE(s.Index(j).Interface())
+ if err != nil {
+ return []time.Duration{}, fmt.Errorf("unable to cast %#v of type %T to []time.Duration", i, i)
+ }
+ a[j] = val
+ }
+ return a, nil
+ default:
+ return []time.Duration{}, fmt.Errorf("unable to cast %#v of type %T to []time.Duration", i, i)
+ }
+}
+
// StringToDate attempts to parse a string into a time.Time type using a
// predefined list of formats. If no suitable format is found, an error is
// returned.
diff --git a/vendor/github.com/spf13/jwalterweatherman/log_counter.go b/vendor/github.com/spf13/jwalterweatherman/log_counter.go
index 570db1d..11423ac 100644
--- a/vendor/github.com/spf13/jwalterweatherman/log_counter.go
+++ b/vendor/github.com/spf13/jwalterweatherman/log_counter.go
@@ -27,7 +27,6 @@ func (c *logCounter) getCount() uint64 {
func (c *logCounter) Write(p []byte) (n int, err error) {
c.incr()
-
return len(p), nil
}
diff --git a/vendor/github.com/spf13/jwalterweatherman/notepad.go b/vendor/github.com/spf13/jwalterweatherman/notepad.go
index 5a623f4..ae5aaf7 100644
--- a/vendor/github.com/spf13/jwalterweatherman/notepad.go
+++ b/vendor/github.com/spf13/jwalterweatherman/notepad.go
@@ -9,7 +9,6 @@ import (
"fmt"
"io"
"log"
- "os"
)
type Threshold int
@@ -38,11 +37,7 @@ var prefixes map[Threshold]string = map[Threshold]string{
LevelFatal: "FATAL",
}
-func prefix(t Threshold) string {
- return t.String() + " "
-}
-
-// Notepad is where you leave a note !
+// Notepad is where you leave a note!
type Notepad struct {
TRACE *log.Logger
DEBUG *log.Logger
@@ -55,7 +50,7 @@ type Notepad struct {
LOG *log.Logger
FEEDBACK *Feedback
- loggers []**log.Logger
+ loggers [7]**log.Logger
logHandle io.Writer
outHandle io.Writer
logThreshold Threshold
@@ -71,11 +66,11 @@ type Notepad struct {
func NewNotepad(outThreshold Threshold, logThreshold Threshold, outHandle, logHandle io.Writer, prefix string, flags int) *Notepad {
n := &Notepad{}
- n.loggers = append(n.loggers, &n.TRACE, &n.DEBUG, &n.INFO, &n.WARN, &n.ERROR, &n.CRITICAL, &n.FATAL)
- n.logHandle = logHandle
+ n.loggers = [7]**log.Logger{&n.TRACE, &n.DEBUG, &n.INFO, &n.WARN, &n.ERROR, &n.CRITICAL, &n.FATAL}
n.outHandle = outHandle
- n.logThreshold = logThreshold
+ n.logHandle = logHandle
n.stdoutThreshold = outThreshold
+ n.logThreshold = logThreshold
if len(prefix) != 0 {
n.prefix = "[" + prefix + "] "
@@ -88,54 +83,48 @@ func NewNotepad(outThreshold Threshold, logThreshold Threshold, outHandle, logHa
n.LOG = log.New(n.logHandle,
"LOG: ",
n.flags)
-
- n.FEEDBACK = &Feedback{n}
+ n.FEEDBACK = &Feedback{out: log.New(outHandle, "", 0), log: n.LOG}
n.init()
-
return n
}
-// Feedback is special. It writes plainly to the output while
-// logging with the standard extra information (date, file, etc)
-// Only Println and Printf are currently provided for this
-type Feedback struct {
- *Notepad
-}
-
-// init create the loggers for each level depending on the notepad thresholds
+// init creates the loggers for each level depending on the notepad thresholds.
func (n *Notepad) init() {
- bothHandle := io.MultiWriter(n.outHandle, n.logHandle)
+ logAndOut := io.MultiWriter(n.outHandle, n.logHandle)
for t, logger := range n.loggers {
threshold := Threshold(t)
counter := &logCounter{}
n.logCounters[t] = counter
+ prefix := n.prefix + threshold.String() + " "
switch {
case threshold >= n.logThreshold && threshold >= n.stdoutThreshold:
- *logger = log.New(io.MultiWriter(counter, bothHandle), n.prefix+prefix(threshold), n.flags)
+ *logger = log.New(io.MultiWriter(counter, logAndOut), prefix, n.flags)
case threshold >= n.logThreshold:
- *logger = log.New(io.MultiWriter(counter, n.logHandle), n.prefix+prefix(threshold), n.flags)
+ *logger = log.New(io.MultiWriter(counter, n.logHandle), prefix, n.flags)
case threshold >= n.stdoutThreshold:
- *logger = log.New(io.MultiWriter(counter, os.Stdout), n.prefix+prefix(threshold), n.flags)
+ *logger = log.New(io.MultiWriter(counter, n.outHandle), prefix, n.flags)
default:
- *logger = log.New(counter, n.prefix+prefix(threshold), n.flags)
+ // counter doesn't care about prefix and flags, so don't use them
+ // for performance.
+ *logger = log.New(counter, "", 0)
}
}
}
-// SetLogThreshold change the threshold above which messages are written to the
-// log file
+// SetLogThreshold changes the threshold above which messages are written to the
+// log file.
func (n *Notepad) SetLogThreshold(threshold Threshold) {
n.logThreshold = threshold
n.init()
}
-// SetLogOutput change the file where log messages are written
+// SetLogOutput changes the file where log messages are written.
func (n *Notepad) SetLogOutput(handle io.Writer) {
n.logHandle = handle
n.init()
@@ -146,8 +135,8 @@ func (n *Notepad) GetLogThreshold() Threshold {
return n.logThreshold
}
-// SetStdoutThreshold change the threshold above which messages are written to the
-// standard output
+// SetStdoutThreshold changes the threshold above which messages are written to the
+// standard output.
func (n *Notepad) SetStdoutThreshold(threshold Threshold) {
n.stdoutThreshold = threshold
n.init()
@@ -158,8 +147,8 @@ func (n *Notepad) GetStdoutThreshold() Threshold {
return n.stdoutThreshold
}
-// SetPrefix change the prefix used by the notepad. Prefixes are displayed between
-// brackets at the begining of the line. An empty prefix won't be displayed at all.
+// SetPrefix changes the prefix used by the notepad. Prefixes are displayed between
+// brackets at the beginning of the line. An empty prefix won't be displayed at all.
func (n *Notepad) SetPrefix(prefix string) {
if len(prefix) != 0 {
n.prefix = "[" + prefix + "] "
@@ -176,20 +165,30 @@ func (n *Notepad) SetFlags(flags int) {
n.init()
}
-// Feedback is special. It writes plainly to the output while
-// logging with the standard extra information (date, file, etc)
-// Only Println and Printf are currently provided for this
+// Feedback writes plainly to the outHandle while
+// logging with the standard extra information (date, file, etc).
+type Feedback struct {
+ out *log.Logger
+ log *log.Logger
+}
+
func (fb *Feedback) Println(v ...interface{}) {
- s := fmt.Sprintln(v...)
- fmt.Print(s)
- fb.LOG.Output(2, s)
+ fb.output(fmt.Sprintln(v...))
}
-// Feedback is special. It writes plainly to the output while
-// logging with the standard extra information (date, file, etc)
-// Only Println and Printf are currently provided for this
func (fb *Feedback) Printf(format string, v ...interface{}) {
- s := fmt.Sprintf(format, v...)
- fmt.Print(s)
- fb.LOG.Output(2, s)
+ fb.output(fmt.Sprintf(format, v...))
+}
+
+func (fb *Feedback) Print(v ...interface{}) {
+ fb.output(fmt.Sprint(v...))
+}
+
+func (fb *Feedback) output(s string) {
+ if fb.out != nil {
+ fb.out.Output(2, s)
+ }
+ if fb.log != nil {
+ fb.log.Output(2, s)
+ }
}
diff --git a/vendor/github.com/spf13/pflag/README.md b/vendor/github.com/spf13/pflag/README.md
index eefb46d..b052414 100644
--- a/vendor/github.com/spf13/pflag/README.md
+++ b/vendor/github.com/spf13/pflag/README.md
@@ -246,6 +246,25 @@ It is possible to mark a flag as hidden, meaning it will still function as norma
flags.MarkHidden("secretFlag")
```
+## Disable sorting of flags
+`pflag` allows you to disable sorting of flags for help and usage message.
+
+**Example**:
+```go
+flags.BoolP("verbose", "v", false, "verbose output")
+flags.String("coolflag", "yeaah", "it's really cool flag")
+flags.Int("usefulflag", 777, "sometimes it's very useful")
+flags.SortFlags = false
+flags.PrintDefaults()
+```
+**Output**:
+```
+ -v, --verbose verbose output
+ --coolflag string it's really cool flag (default "yeaah")
+ --usefulflag int sometimes it's very useful (default 777)
+```
+
+
## Supporting Go flags when using pflag
In order to support flags defined using Go's `flag` package, they must be added to the `pflag` flagset. This is usually necessary
to support flags defined by third-party dependencies (e.g. `golang/glog`).
@@ -270,8 +289,8 @@ func main() {
You can see the full reference documentation of the pflag package
[at godoc.org][3], or through go's standard documentation system by
running `godoc -http=:6060` and browsing to
-[http://localhost:6060/pkg/github.com/ogier/pflag][2] after
+[http://localhost:6060/pkg/github.com/spf13/pflag][2] after
installation.
-[2]: http://localhost:6060/pkg/github.com/ogier/pflag
-[3]: http://godoc.org/github.com/ogier/pflag
+[2]: http://localhost:6060/pkg/github.com/spf13/pflag
+[3]: http://godoc.org/github.com/spf13/pflag
diff --git a/vendor/github.com/spf13/pflag/count.go b/vendor/github.com/spf13/pflag/count.go
index d22be41..aa126e4 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
@@ -83,7 +83,9 @@ func (f *FlagSet) CountP(name, shorthand string, usage string) *int {
return p
}
-// Count like Count only the flag is placed on the CommandLine isntead of a given flag set
+// Count defines a count flag with specified name, default value, and usage string.
+// The return value is the address of an int variable that stores the value of the flag.
+// A count flag will add 1 to its value evey time it is found on the command line
func Count(name string, usage string) *int {
return CommandLine.CountP(name, "", usage)
}
diff --git a/vendor/github.com/spf13/pflag/flag.go b/vendor/github.com/spf13/pflag/flag.go
index 3a2e255..187e4c9 100644
--- a/vendor/github.com/spf13/pflag/flag.go
+++ b/vendor/github.com/spf13/pflag/flag.go
@@ -16,9 +16,9 @@ pflag is a drop-in replacement of Go's native flag package. If you import
pflag under the name "flag" then all code should continue to function
with no changes.
- import flag "github.com/ogier/pflag"
+ import flag "github.com/spf13/pflag"
- There is one exception to this: if you directly instantiate the Flag struct
+There is one exception to this: if you directly instantiate the Flag struct
there is one more field "Shorthand" that you will need to set.
Most code never instantiates this struct directly, and instead uses
functions such as String(), BoolVar(), and Var(), and is therefore
@@ -142,12 +142,13 @@ type FlagSet struct {
parsed bool
actual map[NormalizedName]*Flag
orderedActual []*Flag
+ sortedActual []*Flag
formal map[NormalizedName]*Flag
orderedFormal []*Flag
+ sortedFormal []*Flag
shorthands map[byte]*Flag
args []string // arguments after flags
argsLenAtDash int // len(args) when a '--' was located when parsing, or -1 if no --
- exitOnError bool // does the program exit if there's an error?
errorHandling ErrorHandling
output io.Writer // nil means stderr; use out() accessor
interspersed bool // allow interspersed option/non-option args
@@ -200,12 +201,19 @@ func sortFlags(flags map[NormalizedName]*Flag) []*Flag {
// "--getUrl" which may also be translated to "geturl" and everything will work.
func (f *FlagSet) SetNormalizeFunc(n func(f *FlagSet, name string) NormalizedName) {
f.normalizeNameFunc = n
- for k, v := range f.orderedFormal {
- delete(f.formal, NormalizedName(v.Name))
- nname := f.normalizeFlagName(v.Name)
- v.Name = string(nname)
- f.formal[nname] = v
- f.orderedFormal[k] = v
+ f.sortedFormal = f.sortedFormal[:0]
+ for fname, flag := range f.formal {
+ nname := f.normalizeFlagName(flag.Name)
+ if fname == nname {
+ continue
+ }
+ flag.Name = string(nname)
+ delete(f.formal, fname)
+ f.formal[nname] = flag
+ if _, set := f.actual[fname]; set {
+ delete(f.actual, fname)
+ f.actual[nname] = flag
+ }
}
}
@@ -240,9 +248,16 @@ func (f *FlagSet) SetOutput(output io.Writer) {
// in primordial order if f.SortFlags is false, calling fn for each.
// It visits all flags, even those not set.
func (f *FlagSet) VisitAll(fn func(*Flag)) {
+ if len(f.formal) == 0 {
+ return
+ }
+
var flags []*Flag
if f.SortFlags {
- flags = sortFlags(f.formal)
+ if len(f.formal) != len(f.sortedFormal) {
+ f.sortedFormal = sortFlags(f.formal)
+ }
+ flags = f.sortedFormal
} else {
flags = f.orderedFormal
}
@@ -279,9 +294,16 @@ func VisitAll(fn func(*Flag)) {
// in primordial order if f.SortFlags is false, calling fn for each.
// It visits only those flags that have been set.
func (f *FlagSet) Visit(fn func(*Flag)) {
+ if len(f.actual) == 0 {
+ return
+ }
+
var flags []*Flag
if f.SortFlags {
- flags = sortFlags(f.actual)
+ if len(f.actual) != len(f.sortedActual) {
+ f.sortedActual = sortFlags(f.actual)
+ }
+ flags = f.sortedActual
} else {
flags = f.orderedActual
}
@@ -303,6 +325,22 @@ func (f *FlagSet) Lookup(name string) *Flag {
return f.lookup(f.normalizeFlagName(name))
}
+// ShorthandLookup returns the Flag structure of the short handed flag,
+// returning nil if none exists.
+// It panics, if len(name) > 1.
+func (f *FlagSet) ShorthandLookup(name string) *Flag {
+ if name == "" {
+ return nil
+ }
+ if len(name) > 1 {
+ msg := fmt.Sprintf("can not look up shorthand which is more than one ASCII character: %q", name)
+ fmt.Fprintf(f.out(), msg)
+ panic(msg)
+ }
+ c := name[0]
+ return f.shorthands[c]
+}
+
// lookup returns the Flag structure of the named flag, returning nil if none exists.
func (f *FlagSet) lookup(name NormalizedName) *Flag {
return f.formal[name]
@@ -344,7 +382,7 @@ func (f *FlagSet) MarkDeprecated(name string, usageMessage string) error {
if flag == nil {
return fmt.Errorf("flag %q does not exist", name)
}
- if len(usageMessage) == 0 {
+ if usageMessage == "" {
return fmt.Errorf("deprecated message for flag %q must be set", name)
}
flag.Deprecated = usageMessage
@@ -359,7 +397,7 @@ func (f *FlagSet) MarkShorthandDeprecated(name string, usageMessage string) erro
if flag == nil {
return fmt.Errorf("flag %q does not exist", name)
}
- if len(usageMessage) == 0 {
+ if usageMessage == "" {
return fmt.Errorf("deprecated message for flag %q must be set", name)
}
flag.ShorthandDeprecated = usageMessage
@@ -383,6 +421,12 @@ func Lookup(name string) *Flag {
return CommandLine.Lookup(name)
}
+// ShorthandLookup returns the Flag structure of the short handed flag,
+// returning nil if none exists.
+func ShorthandLookup(name string) *Flag {
+ return CommandLine.ShorthandLookup(name)
+}
+
// Set sets the value of the named flag.
func (f *FlagSet) Set(name, value string) error {
normalName := f.normalizeFlagName(name)
@@ -390,18 +434,30 @@ func (f *FlagSet) Set(name, value string) error {
if !ok {
return fmt.Errorf("no such flag -%v", name)
}
+
err := flag.Value.Set(value)
if err != nil {
- return err
+ var flagName string
+ if flag.Shorthand != "" && flag.ShorthandDeprecated == "" {
+ flagName = fmt.Sprintf("-%s, --%s", flag.Shorthand, flag.Name)
+ } else {
+ flagName = fmt.Sprintf("--%s", flag.Name)
+ }
+ return fmt.Errorf("invalid argument %q for %q flag: %v", value, flagName, err)
}
- if f.actual == nil {
- f.actual = make(map[NormalizedName]*Flag)
+
+ 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
}
- f.actual[normalName] = flag
- f.orderedActual = append(f.orderedActual, flag)
- flag.Changed = true
- if len(flag.Deprecated) > 0 {
- fmt.Fprintf(os.Stderr, "Flag --%s has been deprecated, %s\n", flag.Name, flag.Deprecated)
+
+ if flag.Deprecated != "" {
+ fmt.Fprintf(f.out(), "Flag --%s has been deprecated, %s\n", flag.Name, flag.Deprecated)
}
return nil
}
@@ -508,6 +564,10 @@ func UnquoteUsage(flag *Flag) (name string, usage string) {
name = "int"
case "uint64":
name = "uint"
+ case "stringSlice":
+ name = "strings"
+ case "intSlice":
+ name = "ints"
}
return
@@ -583,28 +643,28 @@ func wrap(i, w int, s string) string {
// for all flags in the FlagSet. Wrapped to `cols` columns (0 for no
// wrapping)
func (f *FlagSet) FlagUsagesWrapped(cols int) string {
- x := new(bytes.Buffer)
+ buf := new(bytes.Buffer)
lines := make([]string, 0, len(f.formal))
maxlen := 0
f.VisitAll(func(flag *Flag) {
- if len(flag.Deprecated) > 0 || flag.Hidden {
+ if flag.Deprecated != "" || flag.Hidden {
return
}
line := ""
- if len(flag.Shorthand) > 0 && len(flag.ShorthandDeprecated) == 0 {
+ if flag.Shorthand != "" && flag.ShorthandDeprecated == "" {
line = fmt.Sprintf(" -%s, --%s", flag.Shorthand, flag.Name)
} else {
line = fmt.Sprintf(" --%s", flag.Name)
}
varname, usage := UnquoteUsage(flag)
- if len(varname) > 0 {
+ if varname != "" {
line += " " + varname
}
- if len(flag.NoOptDefVal) > 0 {
+ if flag.NoOptDefVal != "" {
switch flag.Value.Type() {
case "string":
line += fmt.Sprintf("[=\"%s\"]", flag.NoOptDefVal)
@@ -612,6 +672,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)
}
@@ -640,10 +704,10 @@ func (f *FlagSet) FlagUsagesWrapped(cols int) string {
sidx := strings.Index(line, "\x00")
spacing := strings.Repeat(" ", maxlen-sidx)
// maxlen + 2 comes from + 1 for the \x00 and + 1 for the (deliberate) off-by-one in maxlen-sidx
- fmt.Fprintln(x, line[:sidx], spacing, wrap(maxlen+2, cols, line[sidx+1:]))
+ fmt.Fprintln(buf, line[:sidx], spacing, wrap(maxlen+2, cols, line[sidx+1:]))
}
- return x.String()
+ return buf.String()
}
// FlagUsages returns a string containing the usage information for all flags in
@@ -740,11 +804,10 @@ func (f *FlagSet) VarP(value Value, name, shorthand, usage string) {
// AddFlag will add the flag to the FlagSet
func (f *FlagSet) AddFlag(flag *Flag) {
- // Call normalizeFlagName function only once
normalizedFlagName := f.normalizeFlagName(flag.Name)
- _, alreadythere := f.formal[normalizedFlagName]
- if alreadythere {
+ _, alreadyThere := f.formal[normalizedFlagName]
+ if alreadyThere {
msg := fmt.Sprintf("%s flag redefined: %s", f.name, flag.Name)
fmt.Fprintln(f.out(), msg)
panic(msg) // Happens only if flags are declared with identical names
@@ -757,27 +820,29 @@ func (f *FlagSet) AddFlag(flag *Flag) {
f.formal[normalizedFlagName] = flag
f.orderedFormal = append(f.orderedFormal, flag)
- if len(flag.Shorthand) == 0 {
+ if flag.Shorthand == "" {
return
}
if len(flag.Shorthand) > 1 {
- fmt.Fprintf(f.out(), "%s shorthand more than ASCII character: %s\n", f.name, flag.Shorthand)
- panic("shorthand is more than one character")
+ msg := fmt.Sprintf("%q shorthand is more than one ASCII character", flag.Shorthand)
+ fmt.Fprintf(f.out(), msg)
+ panic(msg)
}
if f.shorthands == nil {
f.shorthands = make(map[byte]*Flag)
}
c := flag.Shorthand[0]
- old, alreadythere := f.shorthands[c]
- if alreadythere {
- fmt.Fprintf(f.out(), "%s shorthand reused: %q for %s already used for %s\n", f.name, c, flag.Name, old.Name)
- panic("shorthand redefinition")
+ used, alreadyThere := f.shorthands[c]
+ if alreadyThere {
+ msg := fmt.Sprintf("unable to redefine %q shorthand in %q flagset: it's already used for %q flag", c, f.name, used.Name)
+ fmt.Fprintf(f.out(), msg)
+ panic(msg)
}
f.shorthands[c] = flag
}
// AddFlagSet adds one FlagSet to another. If a flag is already present in f
-// the flag from newSet will be ignored
+// the flag from newSet will be ignored.
func (f *FlagSet) AddFlagSet(newSet *FlagSet) {
if newSet == nil {
return
@@ -825,35 +890,6 @@ func (f *FlagSet) usage() {
}
}
-func (f *FlagSet) setFlag(flag *Flag, value string, origArg string) error {
- if err := flag.Value.Set(value); err != nil {
- return f.failf("invalid argument %q for %s: %v", value, origArg, err)
- }
- // mark as visited for Visit()
- if f.actual == nil {
- f.actual = make(map[NormalizedName]*Flag)
- }
- f.actual[f.normalizeFlagName(flag.Name)] = flag
- f.orderedActual = append(f.orderedActual, flag)
- flag.Changed = true
- if len(flag.Deprecated) > 0 {
- fmt.Fprintf(os.Stderr, "Flag --%s has been deprecated, %s\n", flag.Name, flag.Deprecated)
- }
- if len(flag.ShorthandDeprecated) > 0 && containsShorthand(origArg, flag.Shorthand) {
- fmt.Fprintf(os.Stderr, "Flag shorthand -%s has been deprecated, %s\n", flag.Shorthand, flag.ShorthandDeprecated)
- }
- return nil
-}
-
-func containsShorthand(arg, shorthand string) bool {
- // filter out flags --<flag_name>
- if strings.HasPrefix(arg, "-") {
- return false
- }
- arg = strings.SplitN(arg, "=", 2)[0]
- return strings.Contains(arg, shorthand)
-}
-
func (f *FlagSet) parseLongArg(s string, args []string, fn parseFunc) (a []string, err error) {
a = args
name := s[2:]
@@ -861,10 +897,11 @@ func (f *FlagSet) parseLongArg(s string, args []string, fn parseFunc) (a []strin
err = f.failf("bad flag syntax: %s", s)
return
}
+
split := strings.SplitN(name, "=", 2)
name = split[0]
- flag, alreadythere := f.formal[f.normalizeFlagName(name)]
- if !alreadythere {
+ flag, exists := f.formal[f.normalizeFlagName(name)]
+ if !exists {
if name == "help" { // special case for nice help message.
f.usage()
return a, ErrHelp
@@ -872,11 +909,12 @@ func (f *FlagSet) parseLongArg(s string, args []string, fn parseFunc) (a []strin
err = f.failf("unknown flag: --%s", name)
return
}
+
var value string
if len(split) == 2 {
// '--flag=arg'
value = split[1]
- } else if len(flag.NoOptDefVal) > 0 {
+ } else if flag.NoOptDefVal != "" {
// '--flag' (arg was optional)
value = flag.NoOptDefVal
} else if len(a) > 0 {
@@ -888,7 +926,11 @@ func (f *FlagSet) parseLongArg(s string, args []string, fn parseFunc) (a []strin
err = f.failf("flag needs an argument: %s", s)
return
}
- err = fn(flag, value, s)
+
+ err = fn(flag, value)
+ if err != nil {
+ f.failf(err.Error())
+ }
return
}
@@ -896,38 +938,52 @@ func (f *FlagSet) parseSingleShortArg(shorthands string, args []string, fn parse
if strings.HasPrefix(shorthands, "test.") {
return
}
+
outArgs = args
outShorts = shorthands[1:]
c := shorthands[0]
- flag, alreadythere := f.shorthands[c]
- if !alreadythere {
+ flag, exists := f.shorthands[c]
+ if !exists {
if c == 'h' { // special case for nice help message.
f.usage()
err = ErrHelp
return
}
- //TODO continue on error
err = f.failf("unknown shorthand flag: %q in -%s", c, shorthands)
return
}
+
var value string
if len(shorthands) > 2 && shorthands[1] == '=' {
+ // '-f=arg'
value = shorthands[2:]
outShorts = ""
- } else if len(flag.NoOptDefVal) > 0 {
+ } else if flag.NoOptDefVal != "" {
+ // '-f' (arg was optional)
value = flag.NoOptDefVal
} else if len(shorthands) > 1 {
+ // '-farg'
value = shorthands[1:]
outShorts = ""
} else if len(args) > 0 {
+ // '-f arg'
value = args[0]
outArgs = args[1:]
} else {
+ // '-f' (arg was required)
err = f.failf("flag needs an argument: %q in -%s", c, shorthands)
return
}
- err = fn(flag, value, shorthands)
+
+ if flag.ShorthandDeprecated != "" {
+ fmt.Fprintf(f.out(), "Flag shorthand -%s has been deprecated, %s\n", flag.Shorthand, flag.ShorthandDeprecated)
+ }
+
+ err = fn(flag, value)
+ if err != nil {
+ f.failf(err.Error())
+ }
return
}
@@ -935,6 +991,7 @@ func (f *FlagSet) parseShortArg(s string, args []string, fn parseFunc) (a []stri
a = args
shorthands := s[1:]
+ // "shorthands" can be a series of shorthand letters of flags (e.g. "-vvv").
for len(shorthands) > 0 {
shorthands, a, err = f.parseSingleShortArg(shorthands, args, fn)
if err != nil {
@@ -982,13 +1039,18 @@ func (f *FlagSet) parseArgs(args []string, fn parseFunc) (err error) {
// The return value will be ErrHelp if -help was set but not defined.
func (f *FlagSet) Parse(arguments []string) error {
f.parsed = true
+
+ if len(arguments) < 0 {
+ return nil
+ }
+
f.args = make([]string, 0, len(arguments))
- assign := func(flag *Flag, value, origArg string) error {
- return f.setFlag(flag, value, origArg)
+ set := func(flag *Flag, value string) error {
+ return f.Set(flag.Name, value)
}
- err := f.parseArgs(arguments, assign)
+ err := f.parseArgs(arguments, set)
if err != nil {
switch f.errorHandling {
case ContinueOnError:
@@ -1002,7 +1064,7 @@ func (f *FlagSet) Parse(arguments []string) error {
return nil
}
-type parseFunc func(flag *Flag, value, origArg string) error
+type parseFunc func(flag *Flag, value string) error
// ParseAll parses flag definitions from the argument list, which should not
// include the command name. The arguments for fn are flag and value. Must be
@@ -1013,11 +1075,7 @@ func (f *FlagSet) ParseAll(arguments []string, fn func(flag *Flag, value string)
f.parsed = true
f.args = make([]string, 0, len(arguments))
- assign := func(flag *Flag, value, origArg string) error {
- return fn(flag, value)
- }
-
- err := f.parseArgs(arguments, assign)
+ err := f.parseArgs(arguments, fn)
if err != nil {
switch f.errorHandling {
case ContinueOnError:
diff --git a/vendor/github.com/spf13/pflag/int16.go b/vendor/github.com/spf13/pflag/int16.go
new file mode 100644
index 0000000..f1a01d0
--- /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/viper/README.md b/vendor/github.com/spf13/viper/README.md
index 25181df..848d92d 100644
--- a/vendor/github.com/spf13/viper/README.md
+++ b/vendor/github.com/spf13/viper/README.md
@@ -6,18 +6,19 @@ Many Go projects are built using Viper including:
* [Hugo](http://gohugo.io)
* [EMC RexRay](http://rexray.readthedocs.org/en/stable/)
-* [Imgur's Incus](https://github.com/Imgur/incus)
+* [Imgur’s Incus](https://github.com/Imgur/incus)
* [Nanobox](https://github.com/nanobox-io/nanobox)/[Nanopack](https://github.com/nanopack)
* [Docker Notary](https://github.com/docker/Notary)
* [BloomApi](https://www.bloomapi.com/)
* [doctl](https://github.com/digitalocean/doctl)
+* [Clairctl](https://github.com/jgsqware/clairctl)
[![Build Status](https://travis-ci.org/spf13/viper.svg)](https://travis-ci.org/spf13/viper) [![Join the chat at https://gitter.im/spf13/viper](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/spf13/viper?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![GoDoc](https://godoc.org/github.com/spf13/viper?status.svg)](https://godoc.org/github.com/spf13/viper)
## What is Viper?
-Viper is a complete configuration solution for go applications including 12 factor apps. It is designed
+Viper is a complete configuration solution for Go applications including 12-Factor apps. It is designed
to work within an application, and can handle all types of configuration needs
and formats. It supports:
@@ -68,7 +69,7 @@ Viper configuration keys are case insensitive.
### Establishing Defaults
A good configuration system will support default values. A default value is not
-required for a key, but it's useful in the event that a key hasn’t been set via
+required for a key, but it’s useful in the event that a key hasn’t been set via
config file, environment variable, remote configuration or flag.
Examples:
@@ -116,10 +117,10 @@ Optionally you can provide a function for Viper to run each time a change occurs
**Make sure you add all of the configPaths prior to calling `WatchConfig()`**
```go
- viper.WatchConfig()
- viper.OnConfigChange(func(e fsnotify.Event) {
- fmt.Println("Config file changed:", e.Name)
- })
+viper.WatchConfig()
+viper.OnConfigChange(func(e fsnotify.Event) {
+ fmt.Println("Config file changed:", e.Name)
+})
```
### Reading Config from io.Reader
@@ -236,7 +237,7 @@ Like `BindEnv`, the value is not set when the binding method is called, but when
it is accessed. This means you can bind as early as you want, even in an
`init()` function.
-The `BindPFlag()` method provides this functionality.
+For individual flags, the `BindPFlag()` method provides this functionality.
Example:
@@ -245,6 +246,19 @@ serverCmd.Flags().Int("port", 1138, "Port to run Application server on")
viper.BindPFlag("port", serverCmd.Flags().Lookup("port"))
```
+You can also bind an existing set of pflags (pflag.FlagSet):
+
+Example:
+
+```go
+pflag.Int("flagname", 1234, "help message for flagname")
+
+pflag.Parse()
+viper.BindPFlags(pflag.CommandLine)
+
+i := viper.GetInt("flagname") // retrieve values from viper instead of pflag
+```
+
The use of [pflag](https://github.com/spf13/pflag/) in Viper does not preclude
the use of other packages that use the [flag](https://golang.org/pkg/flag/)
package from the standard library. The pflag package can handle the flags
@@ -263,15 +277,23 @@ import (
)
func main() {
+
+ // using standard library "flag" package
+ flag.Int("flagname", 1234, "help message for flagname")
+
pflag.CommandLine.AddGoFlagSet(flag.CommandLine)
pflag.Parse()
- ...
+ viper.BindPFlags(pflag.CommandLine)
+
+ i := viper.GetInt("flagname") // retrieve value from viper
+
+ ...
}
```
#### Flag interfaces
-Viper provides two Go interfaces to bind other flag systems if you don't use `Pflags`.
+Viper provides two Go interfaces to bind other flag systems if you don’t use `Pflags`.
`FlagValue` represents a single flag. This is a very simple example on how to implement this interface:
@@ -401,7 +423,7 @@ go func(){
## Getting Values From Viper
-In Viper, there are a few ways to get a value depending on the value's type.
+In Viper, there are a few ways to get a value depending on the value’s type.
The following functions and methods exist:
* `Get(key string) : interface{}`
@@ -531,7 +553,7 @@ func NewCache(cfg *Viper) *Cache {...}
```
which creates a cache based on config information formatted as `subv`.
-Now it's easy to create these 2 caches separately as:
+Now it’s easy to create these 2 caches separately as:
```go
cfg1 := viper.Sub("app.cache1")
@@ -575,13 +597,13 @@ initialization needed to begin using Viper. Since most applications will want
to use a single central repository for their configuration, the viper package
provides this. It is similar to a singleton.
-In all of the examples above, they demonstrate using viper in it's singleton
+In all of the examples above, they demonstrate using viper in its singleton
style approach.
### Working with multiple vipers
You can also create many different vipers for use in your application. Each will
-have it’s own unique set of configurations and values. Each can read from a
+have its own unique set of configurations and values. Each can read from a
different config file, key value store, etc. All of the functions that viper
package supports are mirrored as methods on a viper.
diff --git a/vendor/github.com/spf13/viper/viper.go b/vendor/github.com/spf13/viper/viper.go
index 5ca66ae..963861a 100644
--- a/vendor/github.com/spf13/viper/viper.go
+++ b/vendor/github.com/spf13/viper/viper.go
@@ -21,6 +21,7 @@ package viper
import (
"bytes"
+ "encoding/csv"
"fmt"
"io"
"log"
@@ -52,7 +53,7 @@ func init() {
type remoteConfigFactory interface {
Get(rp RemoteProvider) (io.Reader, error)
Watch(rp RemoteProvider) (io.Reader, error)
- WatchChannel(rp RemoteProvider)(<-chan *RemoteResponse, chan bool)
+ WatchChannel(rp RemoteProvider) (<-chan *RemoteResponse, chan bool)
}
// RemoteConfig is optional, see the remote package
@@ -68,8 +69,7 @@ func (str UnsupportedConfigError) Error() string {
}
// UnsupportedRemoteProviderError denotes encountering an unsupported remote
-// provider. Currently only etcd and Consul are
-// supported.
+// provider. Currently only etcd and Consul are supported.
type UnsupportedRemoteProviderError string
// Error returns the formatted remote provider error.
@@ -282,8 +282,8 @@ func (v *Viper) WatchConfig() {
}()
}
-// SetConfigFile explicitly defines the path, name and extension of the config file
-// Viper will use this and not check any of the config paths
+// SetConfigFile explicitly defines the path, name and extension of the config file.
+// Viper will use this and not check any of the config paths.
func SetConfigFile(in string) { v.SetConfigFile(in) }
func (v *Viper) SetConfigFile(in string) {
if in != "" {
@@ -292,8 +292,8 @@ func (v *Viper) SetConfigFile(in string) {
}
// SetEnvPrefix defines a prefix that ENVIRONMENT variables will use.
-// E.g. if your prefix is "spf", the env registry
-// will look for env. variables that start with "SPF_"
+// E.g. if your prefix is "spf", the env registry will look for env
+// variables that start with "SPF_".
func SetEnvPrefix(in string) { v.SetEnvPrefix(in) }
func (v *Viper) SetEnvPrefix(in string) {
if in != "" {
@@ -311,11 +311,11 @@ func (v *Viper) mergeWithEnvPrefix(in string) string {
// TODO: should getEnv logic be moved into find(). Can generalize the use of
// rewriting keys many things, Ex: Get('someKey') -> some_key
-// (cammel case to snake case for JSON keys perhaps)
+// (camel case to snake case for JSON keys perhaps)
// getEnv is a wrapper around os.Getenv which replaces characters in the original
-// key. This allows env vars which have different keys then the config object
-// keys
+// key. This allows env vars which have different keys than the config object
+// keys.
func (v *Viper) getEnv(key string) string {
if v.envKeyReplacer != nil {
key = v.envKeyReplacer.Replace(key)
@@ -323,7 +323,7 @@ func (v *Viper) getEnv(key string) string {
return os.Getenv(key)
}
-// ConfigFileUsed returns the file used to populate the config registry
+// ConfigFileUsed returns the file used to populate the config registry.
func ConfigFileUsed() string { return v.ConfigFileUsed() }
func (v *Viper) ConfigFileUsed() string { return v.configFile }
@@ -596,32 +596,33 @@ func (v *Viper) Get(key string) interface{} {
return nil
}
- valType := val
if v.typeByDefValue {
// TODO(bep) this branch isn't covered by a single test.
+ valType := val
path := strings.Split(lcaseKey, v.keyDelim)
defVal := v.searchMap(v.defaults, path)
if defVal != nil {
valType = defVal
}
- }
- switch valType.(type) {
- case bool:
- return cast.ToBool(val)
- case string:
- return cast.ToString(val)
- case int64, int32, int16, int8, int:
- return cast.ToInt(val)
- case float64, float32:
- return cast.ToFloat64(val)
- case time.Time:
- return cast.ToTime(val)
- case time.Duration:
- return cast.ToDuration(val)
- case []string:
- return cast.ToStringSlice(val)
+ switch valType.(type) {
+ case bool:
+ return cast.ToBool(val)
+ case string:
+ return cast.ToString(val)
+ case int64, int32, int16, int8, int:
+ return cast.ToInt(val)
+ case float64, float32:
+ return cast.ToFloat64(val)
+ case time.Time:
+ return cast.ToTime(val)
+ case time.Duration:
+ return cast.ToDuration(val)
+ case []string:
+ return cast.ToStringSlice(val)
+ }
}
+
return val
}
@@ -746,13 +747,16 @@ func (v *Viper) Unmarshal(rawVal interface{}) error {
}
// defaultDecoderConfig returns default mapsstructure.DecoderConfig with suppot
-// of time.Duration values
+// of time.Duration values & string slices
func defaultDecoderConfig(output interface{}) *mapstructure.DecoderConfig {
return &mapstructure.DecoderConfig{
Metadata: nil,
Result: output,
WeaklyTypedInput: true,
- DecodeHook: mapstructure.StringToTimeDurationHookFunc(),
+ DecodeHook: mapstructure.ComposeDecodeHookFunc(
+ mapstructure.StringToTimeDurationHookFunc(),
+ mapstructure.StringToSliceHookFunc(","),
+ ),
}
}
@@ -813,7 +817,7 @@ func (v *Viper) BindFlagValues(flags FlagValueSet) (err error) {
}
// BindFlagValue binds a specific key to a FlagValue.
-// Example(where serverCmd is a Cobra instance):
+// Example (where serverCmd is a Cobra instance):
//
// serverCmd.Flags().Int("port", 1138, "Port to run Application server on")
// Viper.BindFlagValue("port", serverCmd.Flags().Lookup("port"))
@@ -894,7 +898,9 @@ func (v *Viper) find(lcaseKey string) interface{} {
return cast.ToBool(flag.ValueString())
case "stringSlice":
s := strings.TrimPrefix(flag.ValueString(), "[")
- return strings.TrimSuffix(s, "]")
+ s = strings.TrimSuffix(s, "]")
+ res, _ := readAsCSV(s)
+ return res
default:
return flag.ValueString()
}
@@ -961,7 +967,9 @@ func (v *Viper) find(lcaseKey string) interface{} {
return cast.ToBool(flag.ValueString())
case "stringSlice":
s := strings.TrimPrefix(flag.ValueString(), "[")
- return strings.TrimSuffix(s, "]")
+ s = strings.TrimSuffix(s, "]")
+ res, _ := readAsCSV(s)
+ return res
default:
return flag.ValueString()
}
@@ -971,6 +979,15 @@ func (v *Viper) find(lcaseKey string) interface{} {
return nil
}
+func readAsCSV(val string) ([]string, error) {
+ if val == "" {
+ return []string{}, nil
+ }
+ stringReader := strings.NewReader(val)
+ csvReader := csv.NewReader(stringReader)
+ return csvReader.Read()
+}
+
// IsSet checks to see if the key has been set in any of the data locations.
// IsSet is case-insensitive for a key.
func IsSet(key string) bool { return v.IsSet(key) }
@@ -1273,7 +1290,7 @@ func (v *Viper) WatchRemoteConfigOnChannel() error {
return v.watchKeyValueConfigOnChannel()
}
-// Unmarshall a Reader into a map.
+// Unmarshal a Reader into a map.
// Should probably be an unexported function.
func unmarshalReader(in io.Reader, c map[string]interface{}) error {
return v.unmarshalReader(in, c)
@@ -1532,7 +1549,6 @@ func (v *Viper) searchInPath(in string) (filename string) {
// Search all configPaths for any config file.
// Returns the first path that exists (and is a config file).
func (v *Viper) findConfigFile() (string, error) {
-
jww.INFO.Println("Searching for config in ", v.configPaths)
for _, cp := range v.configPaths {