You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mynewt.apache.org by cc...@apache.org on 2015/11/21 01:42:33 UTC
[08/42] incubator-mynewt-newt git commit: Move newt source into a
"newt" subdirectory.
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/e95057f4/newt/Godeps/_workspace/src/github.com/spf13/pflag/string_slice_test.go
----------------------------------------------------------------------
diff --git a/newt/Godeps/_workspace/src/github.com/spf13/pflag/string_slice_test.go b/newt/Godeps/_workspace/src/github.com/spf13/pflag/string_slice_test.go
new file mode 100644
index 0000000..c37a91a
--- /dev/null
+++ b/newt/Godeps/_workspace/src/github.com/spf13/pflag/string_slice_test.go
@@ -0,0 +1,44 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package pflag
+
+import (
+ "fmt"
+ "strings"
+ "testing"
+)
+
+func setUpSSFlagSet(ssp *[]string) *FlagSet {
+ f := NewFlagSet("test", ContinueOnError)
+ f.StringSliceVar(ssp, "ss", []string{}, "Command seperated list!")
+ return f
+}
+
+func TestSS(t *testing.T) {
+ var ss []string
+ f := setUpSSFlagSet(&ss)
+
+ vals := []string{"one", "two", "4", "3"}
+ arg := fmt.Sprintf("--ss=%s", strings.Join(vals, ","))
+ err := f.Parse([]string{arg})
+ if err != nil {
+ t.Fatal("expected no error; got", err)
+ }
+ for i, v := range ss {
+ if vals[i] != v {
+ t.Fatal("expected ss[%d] to be %s but got: %s", i, vals[i], v)
+ }
+ }
+
+ getSS, err := f.GetStringSlice("ss")
+ if err != nil {
+ t.Fatal("got an error from GetStringSlice(): %v", err)
+ }
+ for i, v := range getSS {
+ if vals[i] != v {
+ t.Fatal("expected ss[%d] to be %s from GetStringSlice but got: %s", i, vals[i], v)
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/e95057f4/newt/Godeps/_workspace/src/github.com/spf13/pflag/uint.go
----------------------------------------------------------------------
diff --git a/newt/Godeps/_workspace/src/github.com/spf13/pflag/uint.go b/newt/Godeps/_workspace/src/github.com/spf13/pflag/uint.go
new file mode 100644
index 0000000..d6f8e5b
--- /dev/null
+++ b/newt/Godeps/_workspace/src/github.com/spf13/pflag/uint.go
@@ -0,0 +1,91 @@
+package pflag
+
+import (
+ "fmt"
+ "strconv"
+)
+
+// -- uint Value
+type uintValue uint
+
+func newUintValue(val uint, p *uint) *uintValue {
+ *p = val
+ return (*uintValue)(p)
+}
+
+func (i *uintValue) Set(s string) error {
+ v, err := strconv.ParseUint(s, 0, 64)
+ *i = uintValue(v)
+ return err
+}
+
+func (i *uintValue) Type() string {
+ return "uint"
+}
+
+func (i *uintValue) String() string { return fmt.Sprintf("%v", *i) }
+
+func uintConv(sval string) (interface{}, error) {
+ v, err := strconv.ParseUint(sval, 0, 0)
+ if err != nil {
+ return 0, err
+ }
+ return uint(v), nil
+}
+
+// GetUint return the uint value of a flag with the given name
+func (f *FlagSet) GetUint(name string) (uint, error) {
+ val, err := f.getFlagType(name, "uint", uintConv)
+ if err != nil {
+ return 0, err
+ }
+ return val.(uint), nil
+}
+
+// UintVar defines a uint flag with specified name, default value, and usage string.
+// The argument p points to a uint variable in which to store the value of the flag.
+func (f *FlagSet) UintVar(p *uint, name string, value uint, usage string) {
+ f.VarP(newUintValue(value, p), name, "", usage)
+}
+
+// Like UintVar, but accepts a shorthand letter that can be used after a single dash.
+func (f *FlagSet) UintVarP(p *uint, name, shorthand string, value uint, usage string) {
+ f.VarP(newUintValue(value, p), name, shorthand, usage)
+}
+
+// UintVar defines a uint flag with specified name, default value, and usage string.
+// The argument p points to a uint variable in which to store the value of the flag.
+func UintVar(p *uint, name string, value uint, usage string) {
+ CommandLine.VarP(newUintValue(value, p), name, "", usage)
+}
+
+// Like UintVar, but accepts a shorthand letter that can be used after a single dash.
+func UintVarP(p *uint, name, shorthand string, value uint, usage string) {
+ CommandLine.VarP(newUintValue(value, p), name, shorthand, usage)
+}
+
+// Uint defines a uint flag with specified name, default value, and usage string.
+// The return value is the address of a uint variable that stores the value of the flag.
+func (f *FlagSet) Uint(name string, value uint, usage string) *uint {
+ p := new(uint)
+ f.UintVarP(p, name, "", value, usage)
+ return p
+}
+
+// Like Uint, but accepts a shorthand letter that can be used after a single dash.
+func (f *FlagSet) UintP(name, shorthand string, value uint, usage string) *uint {
+ p := new(uint)
+ f.UintVarP(p, name, shorthand, value, usage)
+ return p
+}
+
+// Uint defines a uint flag with specified name, default value, and usage string.
+// The return value is the address of a uint variable that stores the value of the flag.
+func Uint(name string, value uint, usage string) *uint {
+ return CommandLine.UintP(name, "", value, usage)
+}
+
+// Like Uint, but accepts a shorthand letter that can be used after a single dash.
+func UintP(name, shorthand string, value uint, usage string) *uint {
+ return CommandLine.UintP(name, shorthand, value, usage)
+}
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/e95057f4/newt/Godeps/_workspace/src/github.com/spf13/pflag/uint16.go
----------------------------------------------------------------------
diff --git a/newt/Godeps/_workspace/src/github.com/spf13/pflag/uint16.go b/newt/Godeps/_workspace/src/github.com/spf13/pflag/uint16.go
new file mode 100644
index 0000000..1cdc3df
--- /dev/null
+++ b/newt/Godeps/_workspace/src/github.com/spf13/pflag/uint16.go
@@ -0,0 +1,89 @@
+package pflag
+
+import (
+ "fmt"
+ "strconv"
+)
+
+// -- uint16 value
+type uint16Value uint16
+
+func newUint16Value(val uint16, p *uint16) *uint16Value {
+ *p = val
+ return (*uint16Value)(p)
+}
+func (i *uint16Value) String() string { return fmt.Sprintf("%d", *i) }
+func (i *uint16Value) Set(s string) error {
+ v, err := strconv.ParseUint(s, 0, 16)
+ *i = uint16Value(v)
+ return err
+}
+
+func (i *uint16Value) Type() string {
+ return "uint16"
+}
+
+func uint16Conv(sval string) (interface{}, error) {
+ v, err := strconv.ParseUint(sval, 0, 16)
+ if err != nil {
+ return 0, err
+ }
+ return uint16(v), nil
+}
+
+// GetUint16 return the uint16 value of a flag with the given name
+func (f *FlagSet) GetUint16(name string) (uint16, error) {
+ val, err := f.getFlagType(name, "uint16", uint16Conv)
+ if err != nil {
+ return 0, err
+ }
+ return val.(uint16), nil
+}
+
+// Uint16Var defines a uint flag with specified name, default value, and usage string.
+// The argument p points to a uint variable in which to store the value of the flag.
+func (f *FlagSet) Uint16Var(p *uint16, name string, value uint16, usage string) {
+ f.VarP(newUint16Value(value, p), name, "", usage)
+}
+
+// Like Uint16Var, but accepts a shorthand letter that can be used after a single dash.
+func (f *FlagSet) Uint16VarP(p *uint16, name, shorthand string, value uint16, usage string) {
+ f.VarP(newUint16Value(value, p), name, shorthand, usage)
+}
+
+// Uint16Var defines a uint flag with specified name, default value, and usage string.
+// The argument p points to a uint variable in which to store the value of the flag.
+func Uint16Var(p *uint16, name string, value uint16, usage string) {
+ CommandLine.VarP(newUint16Value(value, p), name, "", usage)
+}
+
+// Like Uint16Var, but accepts a shorthand letter that can be used after a single dash.
+func Uint16VarP(p *uint16, name, shorthand string, value uint16, usage string) {
+ CommandLine.VarP(newUint16Value(value, p), name, shorthand, usage)
+}
+
+// Uint16 defines a uint flag with specified name, default value, and usage string.
+// The return value is the address of a uint variable that stores the value of the flag.
+func (f *FlagSet) Uint16(name string, value uint16, usage string) *uint16 {
+ p := new(uint16)
+ f.Uint16VarP(p, name, "", value, usage)
+ return p
+}
+
+// Like Uint16, but accepts a shorthand letter that can be used after a single dash.
+func (f *FlagSet) Uint16P(name, shorthand string, value uint16, usage string) *uint16 {
+ p := new(uint16)
+ f.Uint16VarP(p, name, shorthand, value, usage)
+ return p
+}
+
+// Uint16 defines a uint flag with specified name, default value, and usage string.
+// The return value is the address of a uint variable that stores the value of the flag.
+func Uint16(name string, value uint16, usage string) *uint16 {
+ return CommandLine.Uint16P(name, "", value, usage)
+}
+
+// Like Uint16, but accepts a shorthand letter that can be used after a single dash.
+func Uint16P(name, shorthand string, value uint16, usage string) *uint16 {
+ return CommandLine.Uint16P(name, shorthand, value, usage)
+}
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/e95057f4/newt/Godeps/_workspace/src/github.com/spf13/pflag/uint32.go
----------------------------------------------------------------------
diff --git a/newt/Godeps/_workspace/src/github.com/spf13/pflag/uint32.go b/newt/Godeps/_workspace/src/github.com/spf13/pflag/uint32.go
new file mode 100644
index 0000000..1326e4a
--- /dev/null
+++ b/newt/Godeps/_workspace/src/github.com/spf13/pflag/uint32.go
@@ -0,0 +1,89 @@
+package pflag
+
+import (
+ "fmt"
+ "strconv"
+)
+
+// -- uint16 value
+type uint32Value uint32
+
+func newUint32Value(val uint32, p *uint32) *uint32Value {
+ *p = val
+ return (*uint32Value)(p)
+}
+func (i *uint32Value) String() string { return fmt.Sprintf("%d", *i) }
+func (i *uint32Value) Set(s string) error {
+ v, err := strconv.ParseUint(s, 0, 32)
+ *i = uint32Value(v)
+ return err
+}
+
+func (i *uint32Value) Type() string {
+ return "uint32"
+}
+
+func uint32Conv(sval string) (interface{}, error) {
+ v, err := strconv.ParseUint(sval, 0, 32)
+ if err != nil {
+ return 0, err
+ }
+ return uint32(v), nil
+}
+
+// GetUint32 return the uint32 value of a flag with the given name
+func (f *FlagSet) GetUint32(name string) (uint32, error) {
+ val, err := f.getFlagType(name, "uint32", uint32Conv)
+ if err != nil {
+ return 0, err
+ }
+ return val.(uint32), nil
+}
+
+// Uint32Var defines a uint32 flag with specified name, default value, and usage string.
+// The argument p points to a uint32 variable in which to store the value of the flag.
+func (f *FlagSet) Uint32Var(p *uint32, name string, value uint32, usage string) {
+ f.VarP(newUint32Value(value, p), name, "", usage)
+}
+
+// Like Uint32Var, but accepts a shorthand letter that can be used after a single dash.
+func (f *FlagSet) Uint32VarP(p *uint32, name, shorthand string, value uint32, usage string) {
+ f.VarP(newUint32Value(value, p), name, shorthand, usage)
+}
+
+// Uint32Var defines a uint32 flag with specified name, default value, and usage string.
+// The argument p points to a uint32 variable in which to store the value of the flag.
+func Uint32Var(p *uint32, name string, value uint32, usage string) {
+ CommandLine.VarP(newUint32Value(value, p), name, "", usage)
+}
+
+// Like Uint32Var, but accepts a shorthand letter that can be used after a single dash.
+func Uint32VarP(p *uint32, name, shorthand string, value uint32, usage string) {
+ CommandLine.VarP(newUint32Value(value, p), name, shorthand, usage)
+}
+
+// Uint32 defines a uint32 flag with specified name, default value, and usage string.
+// The return value is the address of a uint32 variable that stores the value of the flag.
+func (f *FlagSet) Uint32(name string, value uint32, usage string) *uint32 {
+ p := new(uint32)
+ f.Uint32VarP(p, name, "", value, usage)
+ return p
+}
+
+// Like Uint32, but accepts a shorthand letter that can be used after a single dash.
+func (f *FlagSet) Uint32P(name, shorthand string, value uint32, usage string) *uint32 {
+ p := new(uint32)
+ f.Uint32VarP(p, name, shorthand, value, usage)
+ return p
+}
+
+// Uint32 defines a uint32 flag with specified name, default value, and usage string.
+// The return value is the address of a uint32 variable that stores the value of the flag.
+func Uint32(name string, value uint32, usage string) *uint32 {
+ return CommandLine.Uint32P(name, "", value, usage)
+}
+
+// Like Uint32, but accepts a shorthand letter that can be used after a single dash.
+func Uint32P(name, shorthand string, value uint32, usage string) *uint32 {
+ return CommandLine.Uint32P(name, shorthand, value, usage)
+}
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/e95057f4/newt/Godeps/_workspace/src/github.com/spf13/pflag/uint64.go
----------------------------------------------------------------------
diff --git a/newt/Godeps/_workspace/src/github.com/spf13/pflag/uint64.go b/newt/Godeps/_workspace/src/github.com/spf13/pflag/uint64.go
new file mode 100644
index 0000000..6788bbf
--- /dev/null
+++ b/newt/Godeps/_workspace/src/github.com/spf13/pflag/uint64.go
@@ -0,0 +1,91 @@
+package pflag
+
+import (
+ "fmt"
+ "strconv"
+)
+
+// -- uint64 Value
+type uint64Value uint64
+
+func newUint64Value(val uint64, p *uint64) *uint64Value {
+ *p = val
+ return (*uint64Value)(p)
+}
+
+func (i *uint64Value) Set(s string) error {
+ v, err := strconv.ParseUint(s, 0, 64)
+ *i = uint64Value(v)
+ return err
+}
+
+func (i *uint64Value) Type() string {
+ return "uint64"
+}
+
+func (i *uint64Value) String() string { return fmt.Sprintf("%v", *i) }
+
+func uint64Conv(sval string) (interface{}, error) {
+ v, err := strconv.ParseUint(sval, 0, 64)
+ if err != nil {
+ return 0, err
+ }
+ return uint64(v), nil
+}
+
+// GetUint64 return the uint64 value of a flag with the given name
+func (f *FlagSet) GetUint64(name string) (uint64, error) {
+ val, err := f.getFlagType(name, "uint64", uint64Conv)
+ if err != nil {
+ return 0, err
+ }
+ return val.(uint64), nil
+}
+
+// Uint64Var defines a uint64 flag with specified name, default value, and usage string.
+// The argument p points to a uint64 variable in which to store the value of the flag.
+func (f *FlagSet) Uint64Var(p *uint64, name string, value uint64, usage string) {
+ f.VarP(newUint64Value(value, p), name, "", usage)
+}
+
+// Like Uint64Var, but accepts a shorthand letter that can be used after a single dash.
+func (f *FlagSet) Uint64VarP(p *uint64, name, shorthand string, value uint64, usage string) {
+ f.VarP(newUint64Value(value, p), name, shorthand, usage)
+}
+
+// Uint64Var defines a uint64 flag with specified name, default value, and usage string.
+// The argument p points to a uint64 variable in which to store the value of the flag.
+func Uint64Var(p *uint64, name string, value uint64, usage string) {
+ CommandLine.VarP(newUint64Value(value, p), name, "", usage)
+}
+
+// Like Uint64Var, but accepts a shorthand letter that can be used after a single dash.
+func Uint64VarP(p *uint64, name, shorthand string, value uint64, usage string) {
+ CommandLine.VarP(newUint64Value(value, p), name, shorthand, usage)
+}
+
+// Uint64 defines a uint64 flag with specified name, default value, and usage string.
+// The return value is the address of a uint64 variable that stores the value of the flag.
+func (f *FlagSet) Uint64(name string, value uint64, usage string) *uint64 {
+ p := new(uint64)
+ f.Uint64VarP(p, name, "", value, usage)
+ return p
+}
+
+// Like Uint64, but accepts a shorthand letter that can be used after a single dash.
+func (f *FlagSet) Uint64P(name, shorthand string, value uint64, usage string) *uint64 {
+ p := new(uint64)
+ f.Uint64VarP(p, name, shorthand, value, usage)
+ return p
+}
+
+// Uint64 defines a uint64 flag with specified name, default value, and usage string.
+// The return value is the address of a uint64 variable that stores the value of the flag.
+func Uint64(name string, value uint64, usage string) *uint64 {
+ return CommandLine.Uint64P(name, "", value, usage)
+}
+
+// Like Uint64, but accepts a shorthand letter that can be used after a single dash.
+func Uint64P(name, shorthand string, value uint64, usage string) *uint64 {
+ return CommandLine.Uint64P(name, shorthand, value, usage)
+}
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/e95057f4/newt/Godeps/_workspace/src/github.com/spf13/pflag/uint8.go
----------------------------------------------------------------------
diff --git a/newt/Godeps/_workspace/src/github.com/spf13/pflag/uint8.go b/newt/Godeps/_workspace/src/github.com/spf13/pflag/uint8.go
new file mode 100644
index 0000000..560c569
--- /dev/null
+++ b/newt/Godeps/_workspace/src/github.com/spf13/pflag/uint8.go
@@ -0,0 +1,91 @@
+package pflag
+
+import (
+ "fmt"
+ "strconv"
+)
+
+// -- uint8 Value
+type uint8Value uint8
+
+func newUint8Value(val uint8, p *uint8) *uint8Value {
+ *p = val
+ return (*uint8Value)(p)
+}
+
+func (i *uint8Value) Set(s string) error {
+ v, err := strconv.ParseUint(s, 0, 8)
+ *i = uint8Value(v)
+ return err
+}
+
+func (i *uint8Value) Type() string {
+ return "uint8"
+}
+
+func (i *uint8Value) String() string { return fmt.Sprintf("%v", *i) }
+
+func uint8Conv(sval string) (interface{}, error) {
+ v, err := strconv.ParseUint(sval, 0, 8)
+ if err != nil {
+ return 0, err
+ }
+ return uint8(v), nil
+}
+
+// GetUint8 return the uint8 value of a flag with the given name
+func (f *FlagSet) GetUint8(name string) (uint8, error) {
+ val, err := f.getFlagType(name, "uint8", uint8Conv)
+ if err != nil {
+ return 0, err
+ }
+ return val.(uint8), nil
+}
+
+// Uint8Var defines a uint8 flag with specified name, default value, and usage string.
+// The argument p points to a uint8 variable in which to store the value of the flag.
+func (f *FlagSet) Uint8Var(p *uint8, name string, value uint8, usage string) {
+ f.VarP(newUint8Value(value, p), name, "", usage)
+}
+
+// Like Uint8Var, but accepts a shorthand letter that can be used after a single dash.
+func (f *FlagSet) Uint8VarP(p *uint8, name, shorthand string, value uint8, usage string) {
+ f.VarP(newUint8Value(value, p), name, shorthand, usage)
+}
+
+// Uint8Var defines a uint8 flag with specified name, default value, and usage string.
+// The argument p points to a uint8 variable in which to store the value of the flag.
+func Uint8Var(p *uint8, name string, value uint8, usage string) {
+ CommandLine.VarP(newUint8Value(value, p), name, "", usage)
+}
+
+// Like Uint8Var, but accepts a shorthand letter that can be used after a single dash.
+func Uint8VarP(p *uint8, name, shorthand string, value uint8, usage string) {
+ CommandLine.VarP(newUint8Value(value, p), name, shorthand, usage)
+}
+
+// Uint8 defines a uint8 flag with specified name, default value, and usage string.
+// The return value is the address of a uint8 variable that stores the value of the flag.
+func (f *FlagSet) Uint8(name string, value uint8, usage string) *uint8 {
+ p := new(uint8)
+ f.Uint8VarP(p, name, "", value, usage)
+ return p
+}
+
+// Like Uint8, but accepts a shorthand letter that can be used after a single dash.
+func (f *FlagSet) Uint8P(name, shorthand string, value uint8, usage string) *uint8 {
+ p := new(uint8)
+ f.Uint8VarP(p, name, shorthand, value, usage)
+ return p
+}
+
+// Uint8 defines a uint8 flag with specified name, default value, and usage string.
+// The return value is the address of a uint8 variable that stores the value of the flag.
+func Uint8(name string, value uint8, usage string) *uint8 {
+ return CommandLine.Uint8P(name, "", value, usage)
+}
+
+// Like Uint8, but accepts a shorthand letter that can be used after a single dash.
+func Uint8P(name, shorthand string, value uint8, usage string) *uint8 {
+ return CommandLine.Uint8P(name, shorthand, value, usage)
+}
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/e95057f4/newt/Godeps/_workspace/src/github.com/spf13/viper/.gitignore
----------------------------------------------------------------------
diff --git a/newt/Godeps/_workspace/src/github.com/spf13/viper/.gitignore b/newt/Godeps/_workspace/src/github.com/spf13/viper/.gitignore
new file mode 100644
index 0000000..8365624
--- /dev/null
+++ b/newt/Godeps/_workspace/src/github.com/spf13/viper/.gitignore
@@ -0,0 +1,23 @@
+# Compiled Object files, Static and Dynamic libs (Shared Objects)
+*.o
+*.a
+*.so
+
+# Folders
+_obj
+_test
+
+# Architecture specific extensions/prefixes
+*.[568vq]
+[568vq].out
+
+*.cgo1.go
+*.cgo2.c
+_cgo_defun.c
+_cgo_gotypes.go
+_cgo_export.*
+
+_testmain.go
+
+*.exe
+*.test
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/e95057f4/newt/Godeps/_workspace/src/github.com/spf13/viper/.travis.yml
----------------------------------------------------------------------
diff --git a/newt/Godeps/_workspace/src/github.com/spf13/viper/.travis.yml b/newt/Godeps/_workspace/src/github.com/spf13/viper/.travis.yml
new file mode 100644
index 0000000..ae1f68e
--- /dev/null
+++ b/newt/Godeps/_workspace/src/github.com/spf13/viper/.travis.yml
@@ -0,0 +1,8 @@
+language: go
+go:
+ - 1.3
+ - release
+ - tip
+
+script:
+ - go test -v ./...
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/e95057f4/newt/Godeps/_workspace/src/github.com/spf13/viper/LICENSE
----------------------------------------------------------------------
diff --git a/newt/Godeps/_workspace/src/github.com/spf13/viper/LICENSE b/newt/Godeps/_workspace/src/github.com/spf13/viper/LICENSE
new file mode 100644
index 0000000..4527efb
--- /dev/null
+++ b/newt/Godeps/_workspace/src/github.com/spf13/viper/LICENSE
@@ -0,0 +1,21 @@
+The MIT License (MIT)
+
+Copyright (c) 2014 Steve Francia
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/e95057f4/newt/Godeps/_workspace/src/github.com/spf13/viper/README.md
----------------------------------------------------------------------
diff --git a/newt/Godeps/_workspace/src/github.com/spf13/viper/README.md b/newt/Godeps/_workspace/src/github.com/spf13/viper/README.md
new file mode 100644
index 0000000..76e1071
--- /dev/null
+++ b/newt/Godeps/_workspace/src/github.com/spf13/viper/README.md
@@ -0,0 +1,445 @@
+viper [![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)
+
+Go configuration with fangs
+
+## What is Viper?
+
+Viper is a complete configuration solution for go applications. It has
+been designed to work within an application to handle all types of
+configuration. It supports
+
+* setting defaults
+* reading from json, toml and yaml config files
+* reading from environment variables
+* reading from remote config systems (Etcd or Consul), watching changes
+* reading from command line flags
+* reading from buffer
+* setting explicit values
+
+It can be thought of as a registry for all of your applications
+configuration needs.
+
+## Why Viper?
+
+When building a modern application, you don’t want to have to worry about
+configuration file formats; you want to focus on building awesome software.
+Viper is here to help with that.
+
+Viper does the following for you:
+
+1. Find, load and marshal a configuration file in JSON, TOML or YAML.
+2. Provide a mechanism to set default values for your different
+ configuration options.
+3. Provide a mechanism to set override values for options specified
+ through command line flags.
+4. Provide an alias system to easily rename parameters without breaking
+ existing code.
+5. Make it easy to tell the difference between when a user has provided
+ a command line or config file which is the same as the default.
+
+Viper uses the following precedence order. Each item takes precedence
+over the item below it:
+
+ * explicit call to Set
+ * flag
+ * env
+ * config
+ * key/value store
+ * default
+
+Viper configuration keys are case insensitive.
+
+## Putting Values into Viper
+
+### Establishing Defaults
+
+A good configuration system will support default values. A default value
+is not required for a key, but can establish a default to be used in the
+event that the key hasn’t be set via config file, environment variable,
+remote configuration or flag.
+
+Examples:
+
+ viper.SetDefault("ContentDir", "content")
+ viper.SetDefault("LayoutDir", "layouts")
+ viper.SetDefault("Taxonomies", map[string]string{"tag": "tags", "category": "categories"})
+
+### Reading Config Files
+
+If you want to support a config file, Viper requires a minimal
+configuration so it knows where to look for the config file. Viper
+supports json, toml and yaml files. Viper can search multiple paths, but
+currently a single viper only supports a single config file.
+
+ viper.SetConfigName("config") // name of config file (without extension)
+ viper.AddConfigPath("/etc/appname/") // path to look for the config file in
+ viper.AddConfigPath("$HOME/.appname") // call multiple times to add many search paths
+ err := viper.ReadInConfig() // Find and read the config file
+ if err != nil { // Handle errors reading the config file
+ panic(fmt.Errorf("Fatal error config file: %s \n", err))
+ }
+
+### Reading Config from io.Reader
+
+Viper predefined many configuration sources, such as files, environment variables, flags and
+remote K/V store. But you are not bound to them. You can also implement your own way to
+require configuration and feed it to viper.
+
+````go
+viper.SetConfigType("yaml") // or viper.SetConfigType("YAML")
+
+// any approach to require this configuration into your program.
+var yamlExample = []byte(`
+Hacker: true
+name: steve
+hobbies:
+- skateboarding
+- snowboarding
+- go
+clothing:
+ jacket: leather
+ trousers: denim
+age: 35
+eyes : brown
+beard: true
+`)
+
+viper.ReadConfig(bytes.NewBuffer(yamlExample))
+
+viper.Get("name") // this would be "steve"
+````
+
+### Setting Overrides
+
+These could be from a command line flag, or from your own application logic.
+
+ viper.Set("Verbose", true)
+ viper.Set("LogFile", LogFile)
+
+### Registering and Using Aliases
+
+Aliases permit a single value to be referenced by multiple keys
+
+ viper.RegisterAlias("loud", "Verbose")
+
+ viper.Set("verbose", true) // same result as next line
+ viper.Set("loud", true) // same result as prior line
+
+ viper.GetBool("loud") // true
+ viper.GetBool("verbose") // true
+
+### Working with Environment Variables
+
+Viper has full support for environment variables. This enables 12 factor
+applications out of the box. There are four methods that exist to aid
+with working with ENV:
+
+ * AutomaticEnv()
+ * BindEnv(string...) : error
+ * SetEnvPrefix(string)
+ * SetEnvReplacer(string...) *strings.Replacer
+
+_When working with ENV variables, it’s important to recognize that Viper
+treats ENV variables as case sensitive._
+
+Viper provides a mechanism to try to ensure that ENV variables are
+unique. By using SetEnvPrefix, you can tell Viper to use add a prefix
+while reading from the environment variables. Both BindEnv and
+AutomaticEnv will use this prefix.
+
+BindEnv takes one or two parameters. The first parameter is the key
+name, the second is the name of the environment variable. The name of
+the environment variable is case sensitive. If the ENV variable name is
+not provided, then Viper will automatically assume that the key name
+matches the ENV variable name but the ENV variable is IN ALL CAPS. When
+you explicitly provide the ENV variable name, it **does not**
+automatically add the prefix.
+
+One important thing to recognize when working with ENV variables is that
+the value will be read each time it is accessed. It does not fix the
+value when the BindEnv is called.
+
+AutomaticEnv is a powerful helper especially when combined with
+SetEnvPrefix. When called, Viper will check for an environment variable
+any time a viper.Get request is made. It will apply the following rules.
+It will check for a environment variable with a name matching the key
+uppercased and prefixed with the EnvPrefix if set.
+
+SetEnvReplacer allows you to use a `strings.Replacer` object to rewrite Env keys
+to an extent. This is useful if you want to use `-` or something in your Get()
+calls, but want your environmental variables to use `_` delimiters. An example
+of using it can be found in `viper_test.go`.
+
+#### Env example
+
+ SetEnvPrefix("spf") // will be uppercased automatically
+ BindEnv("id")
+
+ os.Setenv("SPF_ID", "13") // typically done outside of the app
+
+ id := Get("id") // 13
+
+
+### Working with Flags
+
+Viper has the ability to bind to flags. Specifically, Viper supports
+Pflags as used in the [Cobra](https://github.com/spf13/cobra) library.
+
+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.
+
+Example:
+
+ serverCmd.Flags().Int("port", 1138, "Port to run Application server on")
+ viper.BindPFlag("port", serverCmd.Flags().Lookup("port"))
+
+
+### Remote Key/Value Store Support
+
+To enable remote support in Viper, do a blank import of the `viper/remote` package:
+
+`import _ github.com/spf13/viper/remote`
+
+Viper will read a config string (as JSON, TOML, or YAML) retrieved from a
+path in a Key/Value store such as Etcd or Consul. These values take precedence
+over default values, but are overriden by configuration values retrieved from disk,
+flags, or environment variables.
+
+Viper uses [crypt](https://github.com/xordataexchange/crypt) to retrieve configuration
+from the K/V store, which means that you can store your configuration values
+encrypted and have them automatically decrypted if you have the correct
+gpg keyring. Encryption is optional.
+
+You can use remote configuration in conjunction with local configuration, or
+independently of it.
+
+`crypt` has a command-line helper that you can use to put configurations
+in your K/V store. `crypt` defaults to etcd on http://127.0.0.1:4001.
+
+ go get github.com/xordataexchange/crypt/bin/crypt
+ crypt set -plaintext /config/hugo.json /Users/hugo/settings/config.json
+
+Confirm that your value was set:
+
+ crypt get -plaintext /config/hugo.json
+
+See the `crypt` documentation for examples of how to set encrypted values, or how
+to use Consul.
+
+### Remote Key/Value Store Example - Unencrypted
+
+ viper.AddRemoteProvider("etcd", "http://127.0.0.1:4001","/config/hugo.json")
+ viper.SetConfigType("json") // because there is no file extension in a stream of bytes
+ err := viper.ReadRemoteConfig()
+
+### Remote Key/Value Store Example - Encrypted
+
+ viper.AddSecureRemoteProvider("etcd","http://127.0.0.1:4001","/config/hugo.json","/etc/secrets/mykeyring.gpg")
+ viper.SetConfigType("json") // because there is no file extension in a stream of bytes
+ err := viper.ReadRemoteConfig()
+
+### Watching Changes in Etcd - Unencrypted
+
+ // alternatively, you can create a new viper instance.
+ var runtime_viper = viper.New()
+
+ runtime_viper.AddRemoteProvider("etcd", "http://127.0.0.1:4001", "/config/hugo.yml")
+ runtime_viper.SetConfigType("yaml") // because there is no file extension in a stream of bytes
+
+ // read from remote config the first time.
+ err := runtime_viper.ReadRemoteConfig()
+
+ // marshal config
+ runtime_viper.Marshal(&runtime_conf)
+
+ // open a goroutine to wath remote changes forever
+ go func(){
+ for {
+ time.Sleep(time.Second * 5) // delay after each request
+
+ // currenlty, only tested with etcd support
+ err := runtime_viper.WatchRemoteConfig()
+ if err != nil {
+ log.Errorf("unable to read remote config: %v", err)
+ continue
+ }
+
+ // marshal new config into our runtime config struct. you can also use channel
+ // to implement a signal to notify the system of the changes
+ runtime_viper.Marshal(&runtime_conf)
+ }
+ }()
+
+
+## Getting Values From Viper
+
+In Viper, there are a few ways to get a value depending on what type of value you want to retrieved.
+The following functions and methods exist:
+
+ * Get(key string) : interface{}
+ * GetBool(key string) : bool
+ * GetFloat64(key string) : float64
+ * GetInt(key string) : int
+ * GetString(key string) : string
+ * GetStringMap(key string) : map[string]interface{}
+ * GetStringMapString(key string) : map[string]string
+ * GetStringSlice(key string) : []string
+ * GetTime(key string) : time.Time
+ * GetDuration(key string) : time.Duration
+ * IsSet(key string) : bool
+
+One important thing to recognize is that each Get function will return
+its zero value if it’s not found. To check if a given key exists, the IsSet()
+method has been provided.
+
+Example:
+
+ viper.GetString("logfile") // case-insensitive Setting & Getting
+ if viper.GetBool("verbose") {
+ fmt.Println("verbose enabled")
+ }
+
+### Accessing nested keys
+
+The accessor methods also accept formatted paths to deeply nested keys.
+For example, if the following JSON file is loaded:
+
+```
+{
+ "host": {
+ "address": "localhost",
+ "port": 5799
+ },
+ "datastore": {
+ "metric": {
+ "host": "127.0.0.1",
+ "port": 3099
+ },
+ "warehouse": {
+ "host": "198.0.0.1",
+ "port": 2112
+ }
+ }
+}
+
+```
+
+Viper can access a nested field by passing a `.` delimited path of keys:
+```
+GetString("datastore.metric.host") // (returns "127.0.0.1")
+```
+
+This obeys the precendense rules established above; the search for the root key
+(in this examole, `datastore`) will cascade through the remaining configuration registries
+until found. The search for the subkeys (`metric` and `host`), however, will not.
+
+For example, if the `metric` key was not defined in the configuration loaded
+from file, but was defined in the defaults, Viper would return the zero value.
+
+On the other hand, if the primary key was not defined, Viper would go through the
+remaining registries looking for it.
+
+Lastly, if there exists a key that matches the delimited key path, its value will
+be returned instead. E.g.
+
+```
+{
+ "datastore.metric.host": "0.0.0.0",
+ "host": {
+ "address": "localhost",
+ "port": 5799
+ },
+ "datastore": {
+ "metric": {
+ "host": "127.0.0.1",
+ "port": 3099
+ },
+ "warehouse": {
+ "host": "198.0.0.1",
+ "port": 2112
+ }
+ }
+}
+
+GetString("datastore.metric.host") //returns "0.0.0.0"
+```
+
+### Marshaling
+
+You also have the option of Marshaling all or a specific value to a struct, map, etc.
+
+There are two methods to do this:
+
+ * Marshal(rawVal interface{}) : error
+ * MarshalKey(key string, rawVal interface{}) : error
+
+Example:
+
+ type config struct {
+ Port int
+ Name string
+ }
+
+ var C config
+
+ err := Marshal(&C)
+ if err != nil {
+ t.Fatalf("unable to decode into struct, %v", err)
+ }
+
+
+## Viper or Vipers?
+
+Viper comes ready to use out of the box. There is no configuration or
+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 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 different config file, key value store, etc. All of the
+functions that viper package supports are mirrored as methods on a viper.
+
+Example:
+
+ x := viper.New()
+ y := viper.New()
+
+ x.SetDefault("ContentDir", "content")
+ y.SetDefault("ContentDir", "foobar")
+
+ ...
+
+When working with multiple vipers, it is up to the user to keep track of
+the different vipers.
+
+## Q & A
+
+Q: Why not INI files?
+
+A: Ini files are pretty awful. There’s no standard format, and they are hard to
+validate. Viper is designed to work with JSON, TOML or YAML files. If someone
+really wants to add this feature, I’d be happy to merge it. It’s easy to
+specify which formats your application will permit.
+
+Q: Why is it called “Viper”?
+
+A: Viper is designed to be a [companion](http://en.wikipedia.org/wiki/Viper_(G.I._Joe)) to
+[Cobra](https://github.com/spf13/cobra). While both can operate completely
+independently, together they make a powerful pair to handle much of your
+application foundation needs.
+
+Q: Why is it called “Cobra”?
+
+A: Is there a better name for a [commander](http://en.wikipedia.org/wiki/Cobra_Commander)?
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/e95057f4/newt/Godeps/_workspace/src/github.com/spf13/viper/remote/remote.go
----------------------------------------------------------------------
diff --git a/newt/Godeps/_workspace/src/github.com/spf13/viper/remote/remote.go b/newt/Godeps/_workspace/src/github.com/spf13/viper/remote/remote.go
new file mode 100644
index 0000000..faaf3b3
--- /dev/null
+++ b/newt/Godeps/_workspace/src/github.com/spf13/viper/remote/remote.go
@@ -0,0 +1,77 @@
+// Copyright © 2015 Steve Francia <sp...@spf13.com>.
+//
+// Use of this source code is governed by an MIT-style
+// license that can be found in the LICENSE file.
+
+// Package remote integrates the remote features of Viper.
+package remote
+
+import (
+ "bytes"
+ "github.com/spf13/viper"
+ crypt "github.com/xordataexchange/crypt/config"
+ "io"
+ "os"
+)
+
+type remoteConfigProvider struct{}
+
+func (rc remoteConfigProvider) Get(rp viper.RemoteProvider) (io.Reader, error) {
+ cm, err := getConfigManager(rp)
+ if err != nil {
+ return nil, err
+ }
+ b, err := cm.Get(rp.Path())
+ if err != nil {
+ return nil, err
+ }
+ return bytes.NewReader(b), nil
+}
+
+func (rc remoteConfigProvider) Watch(rp viper.RemoteProvider) (io.Reader, error) {
+ cm, err := getConfigManager(rp)
+ if err != nil {
+ return nil, err
+ }
+ resp := <-cm.Watch(rp.Path(), nil)
+ err = resp.Error
+ if err != nil {
+ return nil, err
+ }
+
+ return bytes.NewReader(resp.Value), nil
+}
+
+func getConfigManager(rp viper.RemoteProvider) (crypt.ConfigManager, error) {
+
+ var cm crypt.ConfigManager
+ var err error
+
+ if rp.SecretKeyring() != "" {
+ kr, err := os.Open(rp.SecretKeyring())
+ defer kr.Close()
+ if err != nil {
+ return nil, err
+ }
+ if rp.Provider() == "etcd" {
+ cm, err = crypt.NewEtcdConfigManager([]string{rp.Endpoint()}, kr)
+ } else {
+ cm, err = crypt.NewConsulConfigManager([]string{rp.Endpoint()}, kr)
+ }
+ } else {
+ if rp.Provider() == "etcd" {
+ cm, err = crypt.NewStandardEtcdConfigManager([]string{rp.Endpoint()})
+ } else {
+ cm, err = crypt.NewStandardConsulConfigManager([]string{rp.Endpoint()})
+ }
+ }
+ if err != nil {
+ return nil, err
+ }
+ return cm, nil
+
+}
+
+func init() {
+ viper.RemoteConfig = &remoteConfigProvider{}
+}
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/e95057f4/newt/Godeps/_workspace/src/github.com/spf13/viper/util.go
----------------------------------------------------------------------
diff --git a/newt/Godeps/_workspace/src/github.com/spf13/viper/util.go b/newt/Godeps/_workspace/src/github.com/spf13/viper/util.go
new file mode 100644
index 0000000..7904b1a
--- /dev/null
+++ b/newt/Godeps/_workspace/src/github.com/spf13/viper/util.go
@@ -0,0 +1,198 @@
+// Copyright © 2014 Steve Francia <sp...@spf13.com>.
+//
+// Use of this source code is governed by an MIT-style
+// license that can be found in the LICENSE file.
+
+// Viper is a application configuration system.
+// It believes that applications can be configured a variety of ways
+// via flags, ENVIRONMENT variables, configuration files retrieved
+// from the file system, or a remote key/value store.
+
+package viper
+
+import (
+ "bytes"
+ "encoding/json"
+ "fmt"
+ "io"
+ "os"
+ "path/filepath"
+ "runtime"
+ "strings"
+ "unicode"
+
+ "github.com/BurntSushi/toml"
+ "github.com/magiconair/properties"
+ "github.com/spf13/cast"
+ jww "github.com/spf13/jwalterweatherman"
+ "gopkg.in/yaml.v2"
+)
+
+func insensitiviseMap(m map[string]interface{}) {
+ for key, val := range m {
+ lower := strings.ToLower(key)
+ if key != lower {
+ delete(m, key)
+ m[lower] = val
+ }
+ }
+}
+
+func absPathify(inPath string) string {
+ jww.INFO.Println("Trying to resolve absolute path to", inPath)
+
+ if strings.HasPrefix(inPath, "$HOME") {
+ inPath = userHomeDir() + inPath[5:]
+ }
+
+ if strings.HasPrefix(inPath, "$") {
+ end := strings.Index(inPath, string(os.PathSeparator))
+ inPath = os.Getenv(inPath[1:end]) + inPath[end:]
+ }
+
+ if filepath.IsAbs(inPath) {
+ return filepath.Clean(inPath)
+ }
+
+ p, err := filepath.Abs(inPath)
+ if err == nil {
+ return filepath.Clean(p)
+ } else {
+ jww.ERROR.Println("Couldn't discover absolute path")
+ jww.ERROR.Println(err)
+ }
+ return ""
+}
+
+// Check if File / Directory Exists
+func exists(path string) (bool, error) {
+ _, err := os.Stat(path)
+ if err == nil {
+ return true, nil
+ }
+ if os.IsNotExist(err) {
+ return false, nil
+ }
+ return false, err
+}
+
+func stringInSlice(a string, list []string) bool {
+ for _, b := range list {
+ if b == a {
+ return true
+ }
+ }
+ return false
+}
+
+func userHomeDir() string {
+ if runtime.GOOS == "windows" {
+ home := os.Getenv("HOMEDRIVE") + os.Getenv("HOMEPATH")
+ if home == "" {
+ home = os.Getenv("USERPROFILE")
+ }
+ return home
+ }
+ return os.Getenv("HOME")
+}
+
+func findCWD() (string, error) {
+ serverFile, err := filepath.Abs(os.Args[0])
+
+ if err != nil {
+ return "", fmt.Errorf("Can't get absolute path for executable: %v", err)
+ }
+
+ path := filepath.Dir(serverFile)
+ realFile, err := filepath.EvalSymlinks(serverFile)
+
+ if err != nil {
+ if _, err = os.Stat(serverFile + ".exe"); err == nil {
+ realFile = filepath.Clean(serverFile + ".exe")
+ }
+ }
+
+ if err == nil && realFile != serverFile {
+ path = filepath.Dir(realFile)
+ }
+
+ return path, nil
+}
+
+func marshallConfigReader(in io.Reader, c map[string]interface{}, configType string) {
+ buf := new(bytes.Buffer)
+ buf.ReadFrom(in)
+
+ switch strings.ToLower(configType) {
+ case "yaml", "yml":
+ if err := yaml.Unmarshal(buf.Bytes(), &c); err != nil {
+ jww.ERROR.Fatalf("Error parsing config: %s", err)
+ }
+
+ case "json":
+ if err := json.Unmarshal(buf.Bytes(), &c); err != nil {
+ jww.ERROR.Fatalf("Error parsing config: %s", err)
+ }
+
+ case "toml":
+ if _, err := toml.Decode(buf.String(), &c); err != nil {
+ jww.ERROR.Fatalf("Error parsing config: %s", err)
+ }
+
+ case "properties", "props", "prop":
+ var p *properties.Properties
+ var err error
+ if p, err = properties.Load(buf.Bytes(), properties.UTF8); err != nil {
+ jww.ERROR.Fatalf("Error parsing config: %s", err)
+ }
+ for _, key := range p.Keys() {
+ value, _ := p.Get(key)
+ c[key] = value
+ }
+ }
+
+ insensitiviseMap(c)
+}
+
+func safeMul(a, b uint) uint {
+ c := a * b
+ if a > 1 && b > 1 && c/b != a {
+ return 0
+ }
+ return c
+}
+
+// parseSizeInBytes converts strings like 1GB or 12 mb into an unsigned integer number of bytes
+func parseSizeInBytes(sizeStr string) uint {
+ sizeStr = strings.TrimSpace(sizeStr)
+ lastChar := len(sizeStr) - 1
+ multiplier := uint(1)
+
+ if lastChar > 0 {
+ if sizeStr[lastChar] == 'b' || sizeStr[lastChar] == 'B' {
+ if lastChar > 1 {
+ switch unicode.ToLower(rune(sizeStr[lastChar-1])) {
+ case 'k':
+ multiplier = 1 << 10
+ sizeStr = strings.TrimSpace(sizeStr[:lastChar-1])
+ case 'm':
+ multiplier = 1 << 20
+ sizeStr = strings.TrimSpace(sizeStr[:lastChar-1])
+ case 'g':
+ multiplier = 1 << 30
+ sizeStr = strings.TrimSpace(sizeStr[:lastChar-1])
+ default:
+ multiplier = 1
+ sizeStr = strings.TrimSpace(sizeStr[:lastChar])
+ }
+ }
+ }
+ }
+
+ size := cast.ToInt(sizeStr)
+ if size < 0 {
+ size = 0
+ }
+
+ return safeMul(uint(size), multiplier)
+}
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/e95057f4/newt/Godeps/_workspace/src/github.com/spf13/viper/viper.go
----------------------------------------------------------------------
diff --git a/newt/Godeps/_workspace/src/github.com/spf13/viper/viper.go b/newt/Godeps/_workspace/src/github.com/spf13/viper/viper.go
new file mode 100644
index 0000000..3db9cd2
--- /dev/null
+++ b/newt/Godeps/_workspace/src/github.com/spf13/viper/viper.go
@@ -0,0 +1,982 @@
+// Copyright © 2014 Steve Francia <sp...@spf13.com>.
+//
+// Use of this source code is governed by an MIT-style
+// license that can be found in the LICENSE file.
+
+// Viper is a application configuration system.
+// It believes that applications can be configured a variety of ways
+// via flags, ENVIRONMENT variables, configuration files retrieved
+// from the file system, or a remote key/value store.
+
+// Each item takes precedence over the item below it:
+
+// overrides
+// flag
+// env
+// config
+// key/value store
+// default
+
+package viper
+
+import (
+ "bytes"
+ "fmt"
+ "io"
+ "io/ioutil"
+ "os"
+ "path/filepath"
+ "reflect"
+ "strings"
+ "time"
+
+ "github.com/kr/pretty"
+ "github.com/mitchellh/mapstructure"
+ "github.com/spf13/cast"
+ jww "github.com/spf13/jwalterweatherman"
+ "github.com/spf13/pflag"
+)
+
+var v *Viper
+
+func init() {
+ v = New()
+}
+
+type remoteConfigFactory interface {
+ Get(rp RemoteProvider) (io.Reader, error)
+ Watch(rp RemoteProvider) (io.Reader, error)
+}
+
+// RemoteConfig is optional, see the remote package
+var RemoteConfig remoteConfigFactory
+
+// Denotes encountering an unsupported
+// configuration filetype.
+type UnsupportedConfigError string
+
+// Returns the formatted configuration error.
+func (str UnsupportedConfigError) Error() string {
+ return fmt.Sprintf("Unsupported Config Type %q", string(str))
+}
+
+// Denotes encountering an unsupported remote
+// provider. Currently only Etcd and Consul are
+// supported.
+type UnsupportedRemoteProviderError string
+
+// Returns the formatted remote provider error.
+func (str UnsupportedRemoteProviderError) Error() string {
+ return fmt.Sprintf("Unsupported Remote Provider Type %q", string(str))
+}
+
+// Denotes encountering an error while trying to
+// pull the configuration from the remote provider.
+type RemoteConfigError string
+
+// Returns the formatted remote provider error
+func (rce RemoteConfigError) Error() string {
+ return fmt.Sprintf("Remote Configurations Error: %s", string(rce))
+}
+
+// Viper is a prioritized configuration registry. It
+// maintains a set of configuration sources, fetches
+// values to populate those, and provides them according
+// to the source's priority.
+// The priority of the sources is the following:
+// 1. overrides
+// 2. flags
+// 3. env. variables
+// 4. config file
+// 5. key/value store
+// 6. defaults
+//
+// For example, if values from the following sources were loaded:
+//
+// Defaults : {
+// "secret": "",
+// "user": "default",
+// "endpoint": "https://localhost"
+// }
+// Config : {
+// "user": "root"
+// "secret": "defaultsecret"
+// }
+// Env : {
+// "secret": "somesecretkey"
+// }
+//
+// The resulting config will have the following values:
+//
+// {
+// "secret": "somesecretkey",
+// "user": "root",
+// "endpoint": "https://localhost"
+// }
+type Viper struct {
+ // Delimiter that separates a list of keys
+ // used to access a nested value in one go
+ keyDelim string
+
+ // A set of paths to look for the config file in
+ configPaths []string
+
+ // A set of remote providers to search for the configuration
+ remoteProviders []*defaultRemoteProvider
+
+ // Name of file to look for inside the path
+ configName string
+ configFile string
+ configType string
+ envPrefix string
+
+ automaticEnvApplied bool
+ envKeyReplacer *strings.Replacer
+
+ config map[string]interface{}
+ override map[string]interface{}
+ defaults map[string]interface{}
+ kvstore map[string]interface{}
+ pflags map[string]*pflag.Flag
+ env map[string]string
+ aliases map[string]string
+}
+
+// Returns an initialized Viper instance.
+func New() *Viper {
+ v := new(Viper)
+ v.keyDelim = "."
+ v.configName = "config"
+ v.config = make(map[string]interface{})
+ v.override = make(map[string]interface{})
+ v.defaults = make(map[string]interface{})
+ v.kvstore = make(map[string]interface{})
+ v.pflags = make(map[string]*pflag.Flag)
+ v.env = make(map[string]string)
+ v.aliases = make(map[string]string)
+
+ return v
+}
+
+// Intended for testing, will reset all to default settings.
+// In the public interface for the viper package so applications
+// can use it in their testing as well.
+func Reset() {
+ v = New()
+ SupportedExts = []string{"json", "toml", "yaml", "yml"}
+ SupportedRemoteProviders = []string{"etcd", "consul"}
+}
+
+type defaultRemoteProvider struct {
+ provider string
+ endpoint string
+ path string
+ secretKeyring string
+}
+
+func (rp defaultRemoteProvider) Provider() string {
+ return rp.provider
+}
+
+func (rp defaultRemoteProvider) Endpoint() string {
+ return rp.endpoint
+}
+
+func (rp defaultRemoteProvider) Path() string {
+ return rp.path
+}
+
+func (rp defaultRemoteProvider) SecretKeyring() string {
+ return rp.secretKeyring
+}
+
+// RemoteProvider stores the configuration necessary
+// to connect to a remote key/value store.
+// Optional secretKeyring to unencrypt encrypted values
+// can be provided.
+type RemoteProvider interface {
+ Provider() string
+ Endpoint() string
+ Path() string
+ SecretKeyring() string
+}
+
+// Universally supported extensions.
+var SupportedExts []string = []string{"json", "toml", "yaml", "yml", "properties", "props", "prop"}
+
+// Universally supported remote providers.
+var SupportedRemoteProviders []string = []string{"etcd", "consul"}
+
+// Explicitly define 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 != "" {
+ v.configFile = in
+ }
+}
+
+// Define 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_"
+func SetEnvPrefix(in string) { v.SetEnvPrefix(in) }
+func (v *Viper) SetEnvPrefix(in string) {
+ if in != "" {
+ v.envPrefix = in
+ }
+}
+
+func (v *Viper) mergeWithEnvPrefix(in string) string {
+ if v.envPrefix != "" {
+ return strings.ToUpper(v.envPrefix + "_" + in)
+ }
+
+ return strings.ToUpper(in)
+}
+
+// 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)
+
+// getEnv s 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
+func (v *Viper) getEnv(key string) string {
+ if v.envKeyReplacer != nil {
+ key = v.envKeyReplacer.Replace(key)
+ }
+ return os.Getenv(key)
+}
+
+// Return the file used to populate the config registry
+func ConfigFileUsed() string { return v.ConfigFileUsed() }
+func (v *Viper) ConfigFileUsed() string { return v.configFile }
+
+// Add a path for Viper to search for the config file in.
+// Can be called multiple times to define multiple search paths.
+func AddConfigPath(in string) { v.AddConfigPath(in) }
+func (v *Viper) AddConfigPath(in string) {
+ if in != "" {
+ absin := absPathify(in)
+ jww.INFO.Println("adding", absin, "to paths to search")
+ if !stringInSlice(absin, v.configPaths) {
+ v.configPaths = append(v.configPaths, absin)
+ }
+ }
+}
+
+// AddRemoteProvider adds a remote configuration source.
+// Remote Providers are searched in the order they are added.
+// provider is a string value, "etcd" or "consul" are currently supported.
+// endpoint is the url. etcd requires http://ip:port consul requires ip:port
+// path is the path in the k/v store to retrieve configuration
+// To retrieve a config file called myapp.json from /configs/myapp.json
+// you should set path to /configs and set config name (SetConfigName()) to
+// "myapp"
+func AddRemoteProvider(provider, endpoint, path string) error {
+ return v.AddRemoteProvider(provider, endpoint, path)
+}
+func (v *Viper) AddRemoteProvider(provider, endpoint, path string) error {
+ if !stringInSlice(provider, SupportedRemoteProviders) {
+ return UnsupportedRemoteProviderError(provider)
+ }
+ if provider != "" && endpoint != "" {
+ jww.INFO.Printf("adding %s:%s to remote provider list", provider, endpoint)
+ rp := &defaultRemoteProvider{
+ endpoint: endpoint,
+ provider: provider,
+ path: path,
+ }
+ if !v.providerPathExists(rp) {
+ v.remoteProviders = append(v.remoteProviders, rp)
+ }
+ }
+ return nil
+}
+
+// AddSecureRemoteProvider adds a remote configuration source.
+// Secure Remote Providers are searched in the order they are added.
+// provider is a string value, "etcd" or "consul" are currently supported.
+// endpoint is the url. etcd requires http://ip:port consul requires ip:port
+// secretkeyring is the filepath to your openpgp secret keyring. e.g. /etc/secrets/myring.gpg
+// path is the path in the k/v store to retrieve configuration
+// To retrieve a config file called myapp.json from /configs/myapp.json
+// you should set path to /configs and set config name (SetConfigName()) to
+// "myapp"
+// Secure Remote Providers are implemented with github.com/xordataexchange/crypt
+func AddSecureRemoteProvider(provider, endpoint, path, secretkeyring string) error {
+ return v.AddSecureRemoteProvider(provider, endpoint, path, secretkeyring)
+}
+
+func (v *Viper) AddSecureRemoteProvider(provider, endpoint, path, secretkeyring string) error {
+ if !stringInSlice(provider, SupportedRemoteProviders) {
+ return UnsupportedRemoteProviderError(provider)
+ }
+ if provider != "" && endpoint != "" {
+ jww.INFO.Printf("adding %s:%s to remote provider list", provider, endpoint)
+ rp := &defaultRemoteProvider{
+ endpoint: endpoint,
+ provider: provider,
+ path: path,
+ secretKeyring: secretkeyring,
+ }
+ if !v.providerPathExists(rp) {
+ v.remoteProviders = append(v.remoteProviders, rp)
+ }
+ }
+ return nil
+}
+
+func (v *Viper) providerPathExists(p *defaultRemoteProvider) bool {
+ for _, y := range v.remoteProviders {
+ if reflect.DeepEqual(y, p) {
+ return true
+ }
+ }
+ return false
+}
+
+func (v *Viper) searchMap(source map[string]interface{}, path []string) interface{} {
+
+ if len(path) == 0 {
+ return source
+ }
+
+ if next, ok := source[path[0]]; ok {
+ switch next.(type) {
+ case map[interface{}]interface{}:
+ return v.searchMap(cast.ToStringMap(next), path[1:])
+ case map[string]interface{}:
+ // Type assertion is safe here since it is only reached
+ // if the type of `next` is the same as the type being asserted
+ return v.searchMap(next.(map[string]interface{}), path[1:])
+ default:
+ return next
+ }
+ } else {
+ return nil
+ }
+}
+
+// Viper is essentially repository for configurations
+// Get can retrieve any value given the key to use
+// Get has the behavior of returning the value associated with the first
+// place from where it is set. Viper will check in the following order:
+// override, flag, env, config file, key/value store, default
+//
+// Get returns an interface. For a specific value use one of the Get____ methods.
+func Get(key string) interface{} { return v.Get(key) }
+func (v *Viper) Get(key string) interface{} {
+ path := strings.Split(key, v.keyDelim)
+
+ val := v.find(strings.ToLower(key))
+
+ if val == nil {
+ source := v.find(path[0])
+ if source == nil {
+ return nil
+ }
+
+ if reflect.TypeOf(source).Kind() == reflect.Map {
+ val = v.searchMap(cast.ToStringMap(source), path[1:])
+ }
+ }
+
+ switch val.(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 val
+ }
+ return val
+}
+
+// Returns the value associated with the key as a string
+func GetString(key string) string { return v.GetString(key) }
+func (v *Viper) GetString(key string) string {
+ return cast.ToString(v.Get(key))
+}
+
+// Returns the value associated with the key asa boolean
+func GetBool(key string) bool { return v.GetBool(key) }
+func (v *Viper) GetBool(key string) bool {
+ return cast.ToBool(v.Get(key))
+}
+
+// Returns the value associated with the key as an integer
+func GetInt(key string) int { return v.GetInt(key) }
+func (v *Viper) GetInt(key string) int {
+ return cast.ToInt(v.Get(key))
+}
+
+// Returns the value associated with the key as a float64
+func GetFloat64(key string) float64 { return v.GetFloat64(key) }
+func (v *Viper) GetFloat64(key string) float64 {
+ return cast.ToFloat64(v.Get(key))
+}
+
+// Returns the value associated with the key as time
+func GetTime(key string) time.Time { return v.GetTime(key) }
+func (v *Viper) GetTime(key string) time.Time {
+ return cast.ToTime(v.Get(key))
+}
+
+// Returns the value associated with the key as a duration
+func GetDuration(key string) time.Duration { return v.GetDuration(key) }
+func (v *Viper) GetDuration(key string) time.Duration {
+ return cast.ToDuration(v.Get(key))
+}
+
+// Returns the value associated with the key as a slice of strings
+func GetStringSlice(key string) []string { return v.GetStringSlice(key) }
+func (v *Viper) GetStringSlice(key string) []string {
+ return cast.ToStringSlice(v.Get(key))
+}
+
+// Returns the value associated with the key as a map of interfaces
+func GetStringMap(key string) map[string]interface{} { return v.GetStringMap(key) }
+func (v *Viper) GetStringMap(key string) map[string]interface{} {
+ return cast.ToStringMap(v.Get(key))
+}
+
+// Returns the value associated with the key as a map of strings
+func GetStringMapString(key string) map[string]string { return v.GetStringMapString(key) }
+func (v *Viper) GetStringMapString(key string) map[string]string {
+ return cast.ToStringMapString(v.Get(key))
+}
+
+// Returns the size of the value associated with the given key
+// in bytes.
+func GetSizeInBytes(key string) uint { return v.GetSizeInBytes(key) }
+func (v *Viper) GetSizeInBytes(key string) uint {
+ sizeStr := cast.ToString(v.Get(key))
+ return parseSizeInBytes(sizeStr)
+}
+
+// Takes a single key and marshals it into a Struct
+func MarshalKey(key string, rawVal interface{}) error { return v.MarshalKey(key, rawVal) }
+func (v *Viper) MarshalKey(key string, rawVal interface{}) error {
+ return mapstructure.Decode(v.Get(key), rawVal)
+}
+
+// Marshals the config into a Struct. Make sure that the tags
+// on the fields of the structure are properly set.
+func Marshal(rawVal interface{}) error { return v.Marshal(rawVal) }
+func (v *Viper) Marshal(rawVal interface{}) error {
+ err := mapstructure.WeakDecode(v.AllSettings(), rawVal)
+
+ if err != nil {
+ return err
+ }
+
+ v.insensitiviseMaps()
+
+ return nil
+}
+
+// Bind a full flag set to the configuration, using each flag's long
+// name as the config key.
+func BindPFlags(flags *pflag.FlagSet) (err error) { return v.BindPFlags(flags) }
+func (v *Viper) BindPFlags(flags *pflag.FlagSet) (err error) {
+ flags.VisitAll(func(flag *pflag.Flag) {
+ if err != nil {
+ // an error has been encountered in one of the previous flags
+ return
+ }
+
+ err = v.BindPFlag(flag.Name, flag)
+ switch flag.Value.Type() {
+ case "int", "int8", "int16", "int32", "int64":
+ v.SetDefault(flag.Name, cast.ToInt(flag.Value.String()))
+ case "bool":
+ v.SetDefault(flag.Name, cast.ToBool(flag.Value.String()))
+ default:
+ v.SetDefault(flag.Name, flag.Value.String())
+ }
+ })
+ return
+}
+
+// Bind a specific key to a flag (as used by cobra)
+// Example(where serverCmd is a Cobra instance):
+//
+// serverCmd.Flags().Int("port", 1138, "Port to run Application server on")
+// Viper.BindPFlag("port", serverCmd.Flags().Lookup("port"))
+//
+func BindPFlag(key string, flag *pflag.Flag) (err error) { return v.BindPFlag(key, flag) }
+func (v *Viper) BindPFlag(key string, flag *pflag.Flag) (err error) {
+ if flag == nil {
+ return fmt.Errorf("flag for %q is nil", key)
+ }
+ v.pflags[strings.ToLower(key)] = flag
+
+ switch flag.Value.Type() {
+ case "int", "int8", "int16", "int32", "int64":
+ SetDefault(key, cast.ToInt(flag.Value.String()))
+ case "bool":
+ SetDefault(key, cast.ToBool(flag.Value.String()))
+ default:
+ SetDefault(key, flag.Value.String())
+ }
+ return nil
+}
+
+// Binds a Viper key to a ENV variable
+// ENV variables are case sensitive
+// If only a key is provided, it will use the env key matching the key, uppercased.
+// EnvPrefix will be used when set when env name is not provided.
+func BindEnv(input ...string) (err error) { return v.BindEnv(input...) }
+func (v *Viper) BindEnv(input ...string) (err error) {
+ var key, envkey string
+ if len(input) == 0 {
+ return fmt.Errorf("BindEnv missing key to bind to")
+ }
+
+ key = strings.ToLower(input[0])
+
+ if len(input) == 1 {
+ envkey = v.mergeWithEnvPrefix(key)
+ } else {
+ envkey = input[1]
+ }
+
+ v.env[key] = envkey
+
+ return nil
+}
+
+// Given a key, find the value
+// Viper will check in the following order:
+// flag, env, config file, key/value store, default
+// Viper will check to see if an alias exists first
+func (v *Viper) find(key string) interface{} {
+ var val interface{}
+ var exists bool
+
+ // if the requested key is an alias, then return the proper key
+ key = v.realKey(key)
+
+ // PFlag Override first
+ flag, exists := v.pflags[key]
+ if exists {
+ if flag.Changed {
+ jww.TRACE.Println(key, "found in override (via pflag):", val)
+ return flag.Value.String()
+ }
+ }
+
+ val, exists = v.override[key]
+ if exists {
+ jww.TRACE.Println(key, "found in override:", val)
+ return val
+ }
+
+ if v.automaticEnvApplied {
+ // even if it hasn't been registered, if automaticEnv is used,
+ // check any Get request
+ if val = v.getEnv(v.mergeWithEnvPrefix(key)); val != "" {
+ jww.TRACE.Println(key, "found in environment with val:", val)
+ return val
+ }
+ }
+
+ envkey, exists := v.env[key]
+ if exists {
+ jww.TRACE.Println(key, "registered as env var", envkey)
+ if val = v.getEnv(envkey); val != "" {
+ jww.TRACE.Println(envkey, "found in environment with val:", val)
+ return val
+ } else {
+ jww.TRACE.Println(envkey, "env value unset:")
+ }
+ }
+
+ val, exists = v.config[key]
+ if exists {
+ jww.TRACE.Println(key, "found in config:", val)
+ return val
+ }
+
+ val, exists = v.kvstore[key]
+ if exists {
+ jww.TRACE.Println(key, "found in key/value store:", val)
+ return val
+ }
+
+ val, exists = v.defaults[key]
+ if exists {
+ jww.TRACE.Println(key, "found in defaults:", val)
+ return val
+ }
+
+ return nil
+}
+
+// Check to see if the key has been set in any of the data locations
+func IsSet(key string) bool { return v.IsSet(key) }
+func (v *Viper) IsSet(key string) bool {
+ t := v.Get(key)
+ return t != nil
+}
+
+// Have Viper check ENV variables for all
+// keys set in config, default & flags
+func AutomaticEnv() { v.AutomaticEnv() }
+func (v *Viper) AutomaticEnv() {
+ v.automaticEnvApplied = true
+}
+
+// SetEnvKeyReplacer sets the strings.Replacer on the viper object
+// Useful for mapping an environmental variable to a key that does
+// not match it.
+func SetEnvKeyReplacer(r *strings.Replacer) { v.SetEnvKeyReplacer(r) }
+func (v *Viper) SetEnvKeyReplacer(r *strings.Replacer) {
+ v.envKeyReplacer = r
+}
+
+// Aliases provide another accessor for the same key.
+// This enables one to change a name without breaking the application
+func RegisterAlias(alias string, key string) { v.RegisterAlias(alias, key) }
+func (v *Viper) RegisterAlias(alias string, key string) {
+ v.registerAlias(alias, strings.ToLower(key))
+}
+
+func (v *Viper) registerAlias(alias string, key string) {
+ alias = strings.ToLower(alias)
+ if alias != key && alias != v.realKey(key) {
+ _, exists := v.aliases[alias]
+
+ if !exists {
+ // if we alias something that exists in one of the maps to another
+ // name, we'll never be able to get that value using the original
+ // name, so move the config value to the new realkey.
+ if val, ok := v.config[alias]; ok {
+ delete(v.config, alias)
+ v.config[key] = val
+ }
+ if val, ok := v.kvstore[alias]; ok {
+ delete(v.kvstore, alias)
+ v.kvstore[key] = val
+ }
+ if val, ok := v.defaults[alias]; ok {
+ delete(v.defaults, alias)
+ v.defaults[key] = val
+ }
+ if val, ok := v.override[alias]; ok {
+ delete(v.override, alias)
+ v.override[key] = val
+ }
+ v.aliases[alias] = key
+ }
+ } else {
+ jww.WARN.Println("Creating circular reference alias", alias, key, v.realKey(key))
+ }
+}
+
+func (v *Viper) realKey(key string) string {
+ newkey, exists := v.aliases[key]
+ if exists {
+ jww.DEBUG.Println("Alias", key, "to", newkey)
+ return v.realKey(newkey)
+ } else {
+ return key
+ }
+}
+
+// Check to see if the given key (or an alias) is in the config file
+func InConfig(key string) bool { return v.InConfig(key) }
+func (v *Viper) InConfig(key string) bool {
+ // if the requested key is an alias, then return the proper key
+ key = v.realKey(key)
+
+ _, exists := v.config[key]
+ return exists
+}
+
+// Set the default value for this key.
+// Default only used when no value is provided by the user via flag, config or ENV.
+func SetDefault(key string, value interface{}) { v.SetDefault(key, value) }
+func (v *Viper) SetDefault(key string, value interface{}) {
+ // If alias passed in, then set the proper default
+ key = v.realKey(strings.ToLower(key))
+ v.defaults[key] = value
+}
+
+// Sets the value for the key in the override regiser.
+// Will be used instead of values obtained via
+// flags, config file, ENV, default, or key/value store
+func Set(key string, value interface{}) { v.Set(key, value) }
+func (v *Viper) Set(key string, value interface{}) {
+ // If alias passed in, then set the proper override
+ key = v.realKey(strings.ToLower(key))
+ v.override[key] = value
+}
+
+// Viper will discover and load the configuration file from disk
+// and key/value stores, searching in one of the defined paths.
+func ReadInConfig() error { return v.ReadInConfig() }
+func (v *Viper) ReadInConfig() error {
+ jww.INFO.Println("Attempting to read in config file")
+ if !stringInSlice(v.getConfigType(), SupportedExts) {
+ return UnsupportedConfigError(v.getConfigType())
+ }
+
+ file, err := ioutil.ReadFile(v.getConfigFile())
+ if err != nil {
+ return err
+ }
+
+ v.config = make(map[string]interface{})
+
+ v.marshalReader(bytes.NewReader(file), v.config)
+ return nil
+}
+
+func ReadConfig(in io.Reader) error { return v.ReadConfig(in) }
+func (v *Viper) ReadConfig(in io.Reader) error {
+ v.config = make(map[string]interface{})
+ v.marshalReader(in, v.config)
+ return nil
+}
+
+// func ReadBufConfig(buf *bytes.Buffer) error { return v.ReadBufConfig(buf) }
+// func (v *Viper) ReadBufConfig(buf *bytes.Buffer) error {
+// v.config = make(map[string]interface{})
+// v.marshalReader(buf, v.config)
+// return nil
+// }
+
+// Attempts to get configuration from a remote source
+// and read it in the remote configuration registry.
+func ReadRemoteConfig() error { return v.ReadRemoteConfig() }
+func (v *Viper) ReadRemoteConfig() error {
+ err := v.getKeyValueConfig()
+ if err != nil {
+ return err
+ }
+ return nil
+}
+
+func WatchRemoteConfig() error { return v.WatchRemoteConfig() }
+func (v *Viper) WatchRemoteConfig() error {
+ err := v.watchKeyValueConfig()
+ if err != nil {
+ return err
+ }
+ return nil
+}
+
+// Marshall a Reader into a map
+// Should probably be an unexported function
+func marshalReader(in io.Reader, c map[string]interface{}) { v.marshalReader(in, c) }
+func (v *Viper) marshalReader(in io.Reader, c map[string]interface{}) {
+ marshallConfigReader(in, c, v.getConfigType())
+}
+
+func (v *Viper) insensitiviseMaps() {
+ insensitiviseMap(v.config)
+ insensitiviseMap(v.defaults)
+ insensitiviseMap(v.override)
+ insensitiviseMap(v.kvstore)
+}
+
+// retrieve the first found remote configuration
+func (v *Viper) getKeyValueConfig() error {
+ if RemoteConfig == nil {
+ return RemoteConfigError("Enable the remote features by doing a blank import of the viper/remote package: '_ github.com/spf13/viper/remote'")
+ }
+
+ for _, rp := range v.remoteProviders {
+ val, err := v.getRemoteConfig(rp)
+ if err != nil {
+ continue
+ }
+ v.kvstore = val
+ return nil
+ }
+ return RemoteConfigError("No Files Found")
+}
+
+func (v *Viper) getRemoteConfig(provider *defaultRemoteProvider) (map[string]interface{}, error) {
+
+ reader, err := RemoteConfig.Get(provider)
+ if err != nil {
+ return nil, err
+ }
+ v.marshalReader(reader, v.kvstore)
+ return v.kvstore, err
+}
+
+// retrieve the first found remote configuration
+func (v *Viper) watchKeyValueConfig() error {
+ for _, rp := range v.remoteProviders {
+ val, err := v.watchRemoteConfig(rp)
+ if err != nil {
+ continue
+ }
+ v.kvstore = val
+ return nil
+ }
+ return RemoteConfigError("No Files Found")
+}
+
+func (v *Viper) watchRemoteConfig(provider *defaultRemoteProvider) (map[string]interface{}, error) {
+ reader, err := RemoteConfig.Watch(provider)
+ if err != nil {
+ return nil, err
+ }
+ v.marshalReader(reader, v.kvstore)
+ return v.kvstore, err
+}
+
+// Return all keys regardless where they are set
+func AllKeys() []string { return v.AllKeys() }
+func (v *Viper) AllKeys() []string {
+ m := map[string]struct{}{}
+
+ for key, _ := range v.defaults {
+ m[key] = struct{}{}
+ }
+
+ for key, _ := range v.config {
+ m[key] = struct{}{}
+ }
+
+ for key, _ := range v.kvstore {
+ m[key] = struct{}{}
+ }
+
+ for key, _ := range v.override {
+ m[key] = struct{}{}
+ }
+
+ a := []string{}
+ for x, _ := range m {
+ a = append(a, x)
+ }
+
+ return a
+}
+
+// Return all settings as a map[string]interface{}
+func AllSettings() map[string]interface{} { return v.AllSettings() }
+func (v *Viper) AllSettings() map[string]interface{} {
+ m := map[string]interface{}{}
+ for _, x := range v.AllKeys() {
+ m[x] = v.Get(x)
+ }
+
+ return m
+}
+
+// Name for the config file.
+// Does not include extension.
+func SetConfigName(in string) { v.SetConfigName(in) }
+func (v *Viper) SetConfigName(in string) {
+ if in != "" {
+ v.configName = in
+ }
+}
+
+// Sets the type of the configuration returned by the
+// remote source, e.g. "json".
+func SetConfigType(in string) { v.SetConfigType(in) }
+func (v *Viper) SetConfigType(in string) {
+ if in != "" {
+ v.configType = in
+ }
+}
+
+func (v *Viper) getConfigType() string {
+ if v.configType != "" {
+ return v.configType
+ }
+
+ cf := v.getConfigFile()
+ ext := filepath.Ext(cf)
+
+ if len(ext) > 1 {
+ return ext[1:]
+ } else {
+ return ""
+ }
+}
+
+func (v *Viper) getConfigFile() string {
+ // if explicitly set, then use it
+ if v.configFile != "" {
+ return v.configFile
+ }
+
+ cf, err := v.findConfigFile()
+ if err != nil {
+ return ""
+ }
+
+ v.configFile = cf
+ return v.getConfigFile()
+}
+
+func (v *Viper) searchInPath(in string) (filename string) {
+ jww.DEBUG.Println("Searching for config in ", in)
+ for _, ext := range SupportedExts {
+ jww.DEBUG.Println("Checking for", filepath.Join(in, v.configName+"."+ext))
+ if b, _ := exists(filepath.Join(in, v.configName+"."+ext)); b {
+ jww.DEBUG.Println("Found: ", filepath.Join(in, v.configName+"."+ext))
+ return filepath.Join(in, v.configName+"."+ext)
+ }
+ }
+
+ return ""
+}
+
+// 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 {
+ file := v.searchInPath(cp)
+ if file != "" {
+ return file, nil
+ }
+ }
+
+ // try the current working directory
+ wd, _ := os.Getwd()
+ file := v.searchInPath(wd)
+ if file != "" {
+ return file, nil
+ }
+ return "", fmt.Errorf("config file not found in: %s", v.configPaths)
+}
+
+// Prints all configuration registries for debugging
+// purposes.
+func Debug() { v.Debug() }
+func (v *Viper) Debug() {
+ fmt.Println("Aliases:")
+ pretty.Println(v.aliases)
+ fmt.Println("Override:")
+ pretty.Println(v.override)
+ fmt.Println("PFlags")
+ pretty.Println(v.pflags)
+ fmt.Println("Env:")
+ pretty.Println(v.env)
+ fmt.Println("Key/Value Store:")
+ pretty.Println(v.kvstore)
+ fmt.Println("Config:")
+ pretty.Println(v.config)
+ fmt.Println("Defaults:")
+ pretty.Println(v.defaults)
+}
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/e95057f4/newt/Godeps/_workspace/src/github.com/spf13/viper/viper_test.go
----------------------------------------------------------------------
diff --git a/newt/Godeps/_workspace/src/github.com/spf13/viper/viper_test.go b/newt/Godeps/_workspace/src/github.com/spf13/viper/viper_test.go
new file mode 100644
index 0000000..8d7d152
--- /dev/null
+++ b/newt/Godeps/_workspace/src/github.com/spf13/viper/viper_test.go
@@ -0,0 +1,559 @@
+// Copyright © 2014 Steve Francia <sp...@spf13.com>.
+//
+// Use of this source code is governed by an MIT-style
+// license that can be found in the LICENSE file.
+
+package viper
+
+import (
+ "bytes"
+ "fmt"
+ "os"
+ "sort"
+ "strings"
+ "testing"
+ "time"
+
+ "github.com/spf13/pflag"
+ "github.com/stretchr/testify/assert"
+)
+
+var yamlExample = []byte(`Hacker: true
+name: steve
+hobbies:
+- skateboarding
+- snowboarding
+- go
+clothing:
+ jacket: leather
+ trousers: denim
+ pants:
+ size: large
+age: 35
+eyes : brown
+beard: true
+`)
+
+var tomlExample = []byte(`
+title = "TOML Example"
+
+[owner]
+organization = "MongoDB"
+Bio = "MongoDB Chief Developer Advocate & Hacker at Large"
+dob = 1979-05-27T07:32:00Z # First class dates? Why not?`)
+
+var jsonExample = []byte(`{
+"id": "0001",
+"type": "donut",
+"name": "Cake",
+"ppu": 0.55,
+"batters": {
+ "batter": [
+ { "type": "Regular" },
+ { "type": "Chocolate" },
+ { "type": "Blueberry" },
+ { "type": "Devil's Food" }
+ ]
+ }
+}`)
+
+var propertiesExample = []byte(`
+p_id: 0001
+p_type: donut
+p_name: Cake
+p_ppu: 0.55
+p_batters.batter.type: Regular
+`)
+
+var remoteExample = []byte(`{
+"id":"0002",
+"type":"cronut",
+"newkey":"remote"
+}`)
+
+func initConfigs() {
+ Reset()
+ SetConfigType("yaml")
+ r := bytes.NewReader(yamlExample)
+ marshalReader(r, v.config)
+
+ SetConfigType("json")
+ r = bytes.NewReader(jsonExample)
+ marshalReader(r, v.config)
+
+ SetConfigType("properties")
+ r = bytes.NewReader(propertiesExample)
+ marshalReader(r, v.config)
+
+ SetConfigType("toml")
+ r = bytes.NewReader(tomlExample)
+ marshalReader(r, v.config)
+
+ SetConfigType("json")
+ remote := bytes.NewReader(remoteExample)
+ marshalReader(remote, v.kvstore)
+}
+
+func initYAML() {
+ Reset()
+ SetConfigType("yaml")
+ r := bytes.NewReader(yamlExample)
+
+ marshalReader(r, v.config)
+}
+
+func initJSON() {
+ Reset()
+ SetConfigType("json")
+ r := bytes.NewReader(jsonExample)
+
+ marshalReader(r, v.config)
+}
+
+func initProperties() {
+ Reset()
+ SetConfigType("properties")
+ r := bytes.NewReader(propertiesExample)
+
+ marshalReader(r, v.config)
+}
+
+func initTOML() {
+ Reset()
+ SetConfigType("toml")
+ r := bytes.NewReader(tomlExample)
+
+ marshalReader(r, v.config)
+}
+
+//stubs for PFlag Values
+type stringValue string
+
+func newStringValue(val string, p *string) *stringValue {
+ *p = val
+ return (*stringValue)(p)
+}
+
+func (s *stringValue) Set(val string) error {
+ *s = stringValue(val)
+ return nil
+}
+
+func (s *stringValue) Type() string {
+ return "string"
+}
+
+func (s *stringValue) String() string {
+ return fmt.Sprintf("%s", *s)
+}
+
+func TestBasics(t *testing.T) {
+ SetConfigFile("/tmp/config.yaml")
+ assert.Equal(t, "/tmp/config.yaml", v.getConfigFile())
+}
+
+func TestDefault(t *testing.T) {
+ SetDefault("age", 45)
+ assert.Equal(t, 45, Get("age"))
+}
+
+func TestMarshalling(t *testing.T) {
+ SetConfigType("yaml")
+ r := bytes.NewReader(yamlExample)
+
+ marshalReader(r, v.config)
+ assert.True(t, InConfig("name"))
+ assert.False(t, InConfig("state"))
+ assert.Equal(t, "steve", Get("name"))
+ assert.Equal(t, []interface{}{"skateboarding", "snowboarding", "go"}, Get("hobbies"))
+ assert.Equal(t, map[interface{}]interface{}{"jacket": "leather", "trousers": "denim", "pants": map[interface{}]interface{}{"size": "large"}}, Get("clothing"))
+ assert.Equal(t, 35, Get("age"))
+}
+
+func TestOverrides(t *testing.T) {
+ Set("age", 40)
+ assert.Equal(t, 40, Get("age"))
+}
+
+func TestDefaultPost(t *testing.T) {
+ assert.NotEqual(t, "NYC", Get("state"))
+ SetDefault("state", "NYC")
+ assert.Equal(t, "NYC", Get("state"))
+}
+
+func TestAliases(t *testing.T) {
+ RegisterAlias("years", "age")
+ assert.Equal(t, 40, Get("years"))
+ Set("years", 45)
+ assert.Equal(t, 45, Get("age"))
+}
+
+func TestAliasInConfigFile(t *testing.T) {
+ // the config file specifies "beard". If we make this an alias for
+ // "hasbeard", we still want the old config file to work with beard.
+ RegisterAlias("beard", "hasbeard")
+ assert.Equal(t, true, Get("hasbeard"))
+ Set("hasbeard", false)
+ assert.Equal(t, false, Get("beard"))
+}
+
+func TestYML(t *testing.T) {
+ initYAML()
+ assert.Equal(t, "steve", Get("name"))
+}
+
+func TestJSON(t *testing.T) {
+ initJSON()
+ assert.Equal(t, "0001", Get("id"))
+}
+
+func TestProperties(t *testing.T) {
+ initProperties()
+ assert.Equal(t, "0001", Get("p_id"))
+}
+
+func TestTOML(t *testing.T) {
+ initTOML()
+ assert.Equal(t, "TOML Example", Get("title"))
+}
+
+func TestRemotePrecedence(t *testing.T) {
+ initJSON()
+
+ remote := bytes.NewReader(remoteExample)
+ assert.Equal(t, "0001", Get("id"))
+ marshalReader(remote, v.kvstore)
+ assert.Equal(t, "0001", Get("id"))
+ assert.NotEqual(t, "cronut", Get("type"))
+ assert.Equal(t, "remote", Get("newkey"))
+ Set("newkey", "newvalue")
+ assert.NotEqual(t, "remote", Get("newkey"))
+ assert.Equal(t, "newvalue", Get("newkey"))
+ Set("newkey", "remote")
+}
+
+func TestEnv(t *testing.T) {
+ initJSON()
+
+ BindEnv("id")
+ BindEnv("f", "FOOD")
+
+ os.Setenv("ID", "13")
+ os.Setenv("FOOD", "apple")
+ os.Setenv("NAME", "crunk")
+
+ assert.Equal(t, "13", Get("id"))
+ assert.Equal(t, "apple", Get("f"))
+ assert.Equal(t, "Cake", Get("name"))
+
+ AutomaticEnv()
+
+ assert.Equal(t, "crunk", Get("name"))
+
+}
+
+func TestEnvPrefix(t *testing.T) {
+ initJSON()
+
+ SetEnvPrefix("foo") // will be uppercased automatically
+ BindEnv("id")
+ BindEnv("f", "FOOD") // not using prefix
+
+ os.Setenv("FOO_ID", "13")
+ os.Setenv("FOOD", "apple")
+ os.Setenv("FOO_NAME", "crunk")
+
+ assert.Equal(t, "13", Get("id"))
+ assert.Equal(t, "apple", Get("f"))
+ assert.Equal(t, "Cake", Get("name"))
+
+ AutomaticEnv()
+
+ assert.Equal(t, "crunk", Get("name"))
+}
+
+func TestAutoEnv(t *testing.T) {
+ Reset()
+
+ AutomaticEnv()
+ os.Setenv("FOO_BAR", "13")
+ assert.Equal(t, "13", Get("foo_bar"))
+}
+
+func TestAutoEnvWithPrefix(t *testing.T) {
+ Reset()
+
+ AutomaticEnv()
+ SetEnvPrefix("Baz")
+ os.Setenv("BAZ_BAR", "13")
+ assert.Equal(t, "13", Get("bar"))
+}
+
+func TestSetEnvReplacer(t *testing.T) {
+ Reset()
+
+ AutomaticEnv()
+ os.Setenv("REFRESH_INTERVAL", "30s")
+
+ replacer := strings.NewReplacer("-", "_")
+ SetEnvKeyReplacer(replacer)
+
+ assert.Equal(t, "30s", Get("refresh-interval"))
+}
+
+func TestAllKeys(t *testing.T) {
+ initConfigs()
+
+ ks := sort.StringSlice{"title", "newkey", "owner", "name", "beard", "ppu", "batters", "hobbies", "clothing", "age", "hacker", "id", "type", "eyes", "p_id", "p_ppu", "p_batters.batter.type", "p_type", "p_name"}
+ dob, _ := time.Parse(time.RFC3339, "1979-05-27T07:32:00Z")
+ all := map[string]interface{}{"owner": map[string]interface{}{"organization": "MongoDB", "Bio": "MongoDB Chief Developer Advocate & Hacker at Large", "dob": dob}, "title": "TOML Example", "ppu": 0.55, "eyes": "brown", "clothing": map[interface{}]interface{}{"trousers": "denim", "jacket": "leather", "pants": map[interface{}]interface{}{"size": "large"}}, "id": "0001", "batters": map[string]interface{}{"batter": []interface{}{map[string]interface{}{"type": "Regular"}, map[string]interface{}{"type": "Chocolate"}, map[string]interface{}{"type": "Blueberry"}, map[string]interface{}{"type": "Devil's Food"}}}, "hacker": true, "beard": true, "hobbies": []interface{}{"skateboarding", "snowboarding", "go"}, "age": 35, "type": "donut", "newkey": "remote", "name": "Cake", "p_id": "0001", "p_ppu": "0.55", "p_name": "Cake", "p_batters.batter.type": "Regular", "p_type": "donut"}
+
+ var allkeys sort.StringSlice
+ allkeys = AllKeys()
+ allkeys.Sort()
+ ks.Sort()
+
+ assert.Equal(t, ks, allkeys)
+ assert.Equal(t, all, AllSettings())
+}
+
+func TestCaseInSensitive(t *testing.T) {
+ assert.Equal(t, true, Get("hacker"))
+ Set("Title", "Checking Case")
+ assert.Equal(t, "Checking Case", Get("tItle"))
+}
+
+func TestAliasesOfAliases(t *testing.T) {
+ RegisterAlias("Foo", "Bar")
+ RegisterAlias("Bar", "Title")
+ assert.Equal(t, "Checking Case", Get("FOO"))
+}
+
+func TestRecursiveAliases(t *testing.T) {
+ RegisterAlias("Baz", "Roo")
+ RegisterAlias("Roo", "baz")
+}
+
+func TestMarshal(t *testing.T) {
+ SetDefault("port", 1313)
+ Set("name", "Steve")
+
+ type config struct {
+ Port int
+ Name string
+ }
+
+ var C config
+
+ err := Marshal(&C)
+ if err != nil {
+ t.Fatalf("unable to decode into struct, %v", err)
+ }
+
+ assert.Equal(t, &C, &config{Name: "Steve", Port: 1313})
+
+ Set("port", 1234)
+ err = Marshal(&C)
+ if err != nil {
+ t.Fatalf("unable to decode into struct, %v", err)
+ }
+ assert.Equal(t, &C, &config{Name: "Steve", Port: 1234})
+}
+
+func TestBindPFlags(t *testing.T) {
+ flagSet := pflag.NewFlagSet("test", pflag.ContinueOnError)
+
+ var testValues = map[string]*string{
+ "host": nil,
+ "port": nil,
+ "endpoint": nil,
+ }
+
+ var mutatedTestValues = map[string]string{
+ "host": "localhost",
+ "port": "6060",
+ "endpoint": "/public",
+ }
+
+ for name, _ := range testValues {
+ testValues[name] = flagSet.String(name, "", "test")
+ }
+
+ err := BindPFlags(flagSet)
+ if err != nil {
+ t.Fatalf("error binding flag set, %v", err)
+ }
+
+ flagSet.VisitAll(func(flag *pflag.Flag) {
+ flag.Value.Set(mutatedTestValues[flag.Name])
+ flag.Changed = true
+ })
+
+ for name, expected := range mutatedTestValues {
+ assert.Equal(t, Get(name), expected)
+ }
+
+}
+
+func TestBindPFlag(t *testing.T) {
+ var testString = "testing"
+ var testValue = newStringValue(testString, &testString)
+
+ flag := &pflag.Flag{
+ Name: "testflag",
+ Value: testValue,
+ Changed: false,
+ }
+
+ BindPFlag("testvalue", flag)
+
+ assert.Equal(t, testString, Get("testvalue"))
+
+ flag.Value.Set("testing_mutate")
+ flag.Changed = true //hack for pflag usage
+
+ assert.Equal(t, "testing_mutate", Get("testvalue"))
+
+}
+
+func TestBoundCaseSensitivity(t *testing.T) {
+
+ assert.Equal(t, "brown", Get("eyes"))
+
+ BindEnv("eYEs", "TURTLE_EYES")
+ os.Setenv("TURTLE_EYES", "blue")
+
+ assert.Equal(t, "blue", Get("eyes"))
+
+ var testString = "green"
+ var testValue = newStringValue(testString, &testString)
+
+ flag := &pflag.Flag{
+ Name: "eyeballs",
+ Value: testValue,
+ Changed: true,
+ }
+
+ BindPFlag("eYEs", flag)
+ assert.Equal(t, "green", Get("eyes"))
+
+}
+
+func TestSizeInBytes(t *testing.T) {
+ input := map[string]uint{
+ "": 0,
+ "b": 0,
+ "12 bytes": 0,
+ "200000000000gb": 0,
+ "12 b": 12,
+ "43 MB": 43 * (1 << 20),
+ "10mb": 10 * (1 << 20),
+ "1gb": 1 << 30,
+ }
+
+ for str, expected := range input {
+ assert.Equal(t, expected, parseSizeInBytes(str), str)
+ }
+}
+
+func TestFindsNestedKeys(t *testing.T) {
+ initConfigs()
+ dob, _ := time.Parse(time.RFC3339, "1979-05-27T07:32:00Z")
+
+ Set("super", map[string]interface{}{
+ "deep": map[string]interface{}{
+ "nested": "value",
+ },
+ })
+
+ expected := map[string]interface{}{
+ "super": map[string]interface{}{
+ "deep": map[string]interface{}{
+ "nested": "value",
+ },
+ },
+ "super.deep": map[string]interface{}{
+ "nested": "value",
+ },
+ "super.deep.nested": "value",
+ "owner.organization": "MongoDB",
+ "batters.batter": []interface{}{
+ map[string]interface{}{
+ "type": "Regular",
+ },
+ map[string]interface{}{
+ "type": "Chocolate",
+ },
+ map[string]interface{}{
+ "type": "Blueberry",
+ },
+ map[string]interface{}{
+ "type": "Devil's Food",
+ },
+ },
+ "hobbies": []interface{}{
+ "skateboarding", "snowboarding", "go",
+ },
+ "title": "TOML Example",
+ "newkey": "remote",
+ "batters": map[string]interface{}{
+ "batter": []interface{}{
+ map[string]interface{}{
+ "type": "Regular",
+ },
+ map[string]interface{}{
+ "type": "Chocolate",
+ }, map[string]interface{}{
+ "type": "Blueberry",
+ }, map[string]interface{}{
+ "type": "Devil's Food",
+ },
+ },
+ },
+ "eyes": "brown",
+ "age": 35,
+ "owner": map[string]interface{}{
+ "organization": "MongoDB",
+ "Bio": "MongoDB Chief Developer Advocate & Hacker at Large",
+ "dob": dob,
+ },
+ "owner.Bio": "MongoDB Chief Developer Advocate & Hacker at Large",
+ "type": "donut",
+ "id": "0001",
+ "name": "Cake",
+ "hacker": true,
+ "ppu": 0.55,
+ "clothing": map[interface{}]interface{}{
+ "jacket": "leather",
+ "trousers": "denim",
+ "pants": map[interface{}]interface{}{
+ "size": "large",
+ },
+ },
+ "clothing.jacket": "leather",
+ "clothing.pants.size": "large",
+ "clothing.trousers": "denim",
+ "owner.dob": dob,
+ "beard": true,
+ }
+
+ for key, expectedValue := range expected {
+
+ assert.Equal(t, expectedValue, v.Get(key))
+ }
+
+}
+
+func TestReadBufConfig(t *testing.T) {
+ v := New()
+ v.SetConfigType("yaml")
+ v.ReadConfig(bytes.NewBuffer(yamlExample))
+ t.Log(v.AllKeys())
+
+ assert.True(t, v.InConfig("name"))
+ assert.False(t, v.InConfig("state"))
+ assert.Equal(t, "steve", v.Get("name"))
+ assert.Equal(t, []interface{}{"skateboarding", "snowboarding", "go"}, v.Get("hobbies"))
+ assert.Equal(t, map[interface{}]interface{}{"jacket": "leather", "trousers": "denim", "pants": map[interface{}]interface{}{"size": "large"}}, v.Get("clothing"))
+ assert.Equal(t, 35, v.Get("age"))
+}