You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@brooklyn.apache.org by ge...@apache.org on 2018/03/23 13:50:47 UTC
[20/25] brooklyn-client git commit: Add vendor file and remove glide
from build/readme
http://git-wip-us.apache.org/repos/asf/brooklyn-client/blob/799e9ccb/cli/vendor/github.com/urfave/cli/context.go
----------------------------------------------------------------------
diff --git a/cli/vendor/github.com/urfave/cli/context.go b/cli/vendor/github.com/urfave/cli/context.go
new file mode 100644
index 0000000..0513d34
--- /dev/null
+++ b/cli/vendor/github.com/urfave/cli/context.go
@@ -0,0 +1,388 @@
+package cli
+
+import (
+ "errors"
+ "flag"
+ "strconv"
+ "strings"
+ "time"
+)
+
+// Context is a type that is passed through to
+// each Handler action in a cli application. Context
+// can be used to retrieve context-specific Args and
+// parsed command-line options.
+type Context struct {
+ App *App
+ Command Command
+ flagSet *flag.FlagSet
+ setFlags map[string]bool
+ globalSetFlags map[string]bool
+ parentContext *Context
+}
+
+// Creates a new context. For use in when invoking an App or Command action.
+func NewContext(app *App, set *flag.FlagSet, parentCtx *Context) *Context {
+ return &Context{App: app, flagSet: set, parentContext: parentCtx}
+}
+
+// Looks up the value of a local int flag, returns 0 if no int flag exists
+func (c *Context) Int(name string) int {
+ return lookupInt(name, c.flagSet)
+}
+
+// Looks up the value of a local time.Duration flag, returns 0 if no time.Duration flag exists
+func (c *Context) Duration(name string) time.Duration {
+ return lookupDuration(name, c.flagSet)
+}
+
+// Looks up the value of a local float64 flag, returns 0 if no float64 flag exists
+func (c *Context) Float64(name string) float64 {
+ return lookupFloat64(name, c.flagSet)
+}
+
+// Looks up the value of a local bool flag, returns false if no bool flag exists
+func (c *Context) Bool(name string) bool {
+ return lookupBool(name, c.flagSet)
+}
+
+// Looks up the value of a local boolT flag, returns false if no bool flag exists
+func (c *Context) BoolT(name string) bool {
+ return lookupBoolT(name, c.flagSet)
+}
+
+// Looks up the value of a local string flag, returns "" if no string flag exists
+func (c *Context) String(name string) string {
+ return lookupString(name, c.flagSet)
+}
+
+// Looks up the value of a local string slice flag, returns nil if no string slice flag exists
+func (c *Context) StringSlice(name string) []string {
+ return lookupStringSlice(name, c.flagSet)
+}
+
+// Looks up the value of a local int slice flag, returns nil if no int slice flag exists
+func (c *Context) IntSlice(name string) []int {
+ return lookupIntSlice(name, c.flagSet)
+}
+
+// Looks up the value of a local generic flag, returns nil if no generic flag exists
+func (c *Context) Generic(name string) interface{} {
+ return lookupGeneric(name, c.flagSet)
+}
+
+// Looks up the value of a global int flag, returns 0 if no int flag exists
+func (c *Context) GlobalInt(name string) int {
+ if fs := lookupGlobalFlagSet(name, c); fs != nil {
+ return lookupInt(name, fs)
+ }
+ return 0
+}
+
+// Looks up the value of a global time.Duration flag, returns 0 if no time.Duration flag exists
+func (c *Context) GlobalDuration(name string) time.Duration {
+ if fs := lookupGlobalFlagSet(name, c); fs != nil {
+ return lookupDuration(name, fs)
+ }
+ return 0
+}
+
+// Looks up the value of a global bool flag, returns false if no bool flag exists
+func (c *Context) GlobalBool(name string) bool {
+ if fs := lookupGlobalFlagSet(name, c); fs != nil {
+ return lookupBool(name, fs)
+ }
+ return false
+}
+
+// Looks up the value of a global string flag, returns "" if no string flag exists
+func (c *Context) GlobalString(name string) string {
+ if fs := lookupGlobalFlagSet(name, c); fs != nil {
+ return lookupString(name, fs)
+ }
+ return ""
+}
+
+// Looks up the value of a global string slice flag, returns nil if no string slice flag exists
+func (c *Context) GlobalStringSlice(name string) []string {
+ if fs := lookupGlobalFlagSet(name, c); fs != nil {
+ return lookupStringSlice(name, fs)
+ }
+ return nil
+}
+
+// Looks up the value of a global int slice flag, returns nil if no int slice flag exists
+func (c *Context) GlobalIntSlice(name string) []int {
+ if fs := lookupGlobalFlagSet(name, c); fs != nil {
+ return lookupIntSlice(name, fs)
+ }
+ return nil
+}
+
+// Looks up the value of a global generic flag, returns nil if no generic flag exists
+func (c *Context) GlobalGeneric(name string) interface{} {
+ if fs := lookupGlobalFlagSet(name, c); fs != nil {
+ return lookupGeneric(name, fs)
+ }
+ return nil
+}
+
+// Returns the number of flags set
+func (c *Context) NumFlags() int {
+ return c.flagSet.NFlag()
+}
+
+// Determines if the flag was actually set
+func (c *Context) IsSet(name string) bool {
+ if c.setFlags == nil {
+ c.setFlags = make(map[string]bool)
+ c.flagSet.Visit(func(f *flag.Flag) {
+ c.setFlags[f.Name] = true
+ })
+ }
+ return c.setFlags[name] == true
+}
+
+// Determines if the global flag was actually set
+func (c *Context) GlobalIsSet(name string) bool {
+ if c.globalSetFlags == nil {
+ c.globalSetFlags = make(map[string]bool)
+ ctx := c
+ if ctx.parentContext != nil {
+ ctx = ctx.parentContext
+ }
+ for ; ctx != nil && c.globalSetFlags[name] == false; ctx = ctx.parentContext {
+ ctx.flagSet.Visit(func(f *flag.Flag) {
+ c.globalSetFlags[f.Name] = true
+ })
+ }
+ }
+ return c.globalSetFlags[name]
+}
+
+// Returns a slice of flag names used in this context.
+func (c *Context) FlagNames() (names []string) {
+ for _, flag := range c.Command.Flags {
+ name := strings.Split(flag.GetName(), ",")[0]
+ if name == "help" {
+ continue
+ }
+ names = append(names, name)
+ }
+ return
+}
+
+// Returns a slice of global flag names used by the app.
+func (c *Context) GlobalFlagNames() (names []string) {
+ for _, flag := range c.App.Flags {
+ name := strings.Split(flag.GetName(), ",")[0]
+ if name == "help" || name == "version" {
+ continue
+ }
+ names = append(names, name)
+ }
+ return
+}
+
+// Returns the parent context, if any
+func (c *Context) Parent() *Context {
+ return c.parentContext
+}
+
+type Args []string
+
+// Returns the command line arguments associated with the context.
+func (c *Context) Args() Args {
+ args := Args(c.flagSet.Args())
+ return args
+}
+
+// Returns the nth argument, or else a blank string
+func (a Args) Get(n int) string {
+ if len(a) > n {
+ return a[n]
+ }
+ return ""
+}
+
+// Returns the first argument, or else a blank string
+func (a Args) First() string {
+ return a.Get(0)
+}
+
+// Return the rest of the arguments (not the first one)
+// or else an empty string slice
+func (a Args) Tail() []string {
+ if len(a) >= 2 {
+ return []string(a)[1:]
+ }
+ return []string{}
+}
+
+// Checks if there are any arguments present
+func (a Args) Present() bool {
+ return len(a) != 0
+}
+
+// Swaps arguments at the given indexes
+func (a Args) Swap(from, to int) error {
+ if from >= len(a) || to >= len(a) {
+ return errors.New("index out of range")
+ }
+ a[from], a[to] = a[to], a[from]
+ return nil
+}
+
+func lookupGlobalFlagSet(name string, ctx *Context) *flag.FlagSet {
+ if ctx.parentContext != nil {
+ ctx = ctx.parentContext
+ }
+ for ; ctx != nil; ctx = ctx.parentContext {
+ if f := ctx.flagSet.Lookup(name); f != nil {
+ return ctx.flagSet
+ }
+ }
+ return nil
+}
+
+func lookupInt(name string, set *flag.FlagSet) int {
+ f := set.Lookup(name)
+ if f != nil {
+ val, err := strconv.Atoi(f.Value.String())
+ if err != nil {
+ return 0
+ }
+ return val
+ }
+
+ return 0
+}
+
+func lookupDuration(name string, set *flag.FlagSet) time.Duration {
+ f := set.Lookup(name)
+ if f != nil {
+ val, err := time.ParseDuration(f.Value.String())
+ if err == nil {
+ return val
+ }
+ }
+
+ return 0
+}
+
+func lookupFloat64(name string, set *flag.FlagSet) float64 {
+ f := set.Lookup(name)
+ if f != nil {
+ val, err := strconv.ParseFloat(f.Value.String(), 64)
+ if err != nil {
+ return 0
+ }
+ return val
+ }
+
+ return 0
+}
+
+func lookupString(name string, set *flag.FlagSet) string {
+ f := set.Lookup(name)
+ if f != nil {
+ return f.Value.String()
+ }
+
+ return ""
+}
+
+func lookupStringSlice(name string, set *flag.FlagSet) []string {
+ f := set.Lookup(name)
+ if f != nil {
+ return (f.Value.(*StringSlice)).Value()
+
+ }
+
+ return nil
+}
+
+func lookupIntSlice(name string, set *flag.FlagSet) []int {
+ f := set.Lookup(name)
+ if f != nil {
+ return (f.Value.(*IntSlice)).Value()
+
+ }
+
+ return nil
+}
+
+func lookupGeneric(name string, set *flag.FlagSet) interface{} {
+ f := set.Lookup(name)
+ if f != nil {
+ return f.Value
+ }
+ return nil
+}
+
+func lookupBool(name string, set *flag.FlagSet) bool {
+ f := set.Lookup(name)
+ if f != nil {
+ val, err := strconv.ParseBool(f.Value.String())
+ if err != nil {
+ return false
+ }
+ return val
+ }
+
+ return false
+}
+
+func lookupBoolT(name string, set *flag.FlagSet) bool {
+ f := set.Lookup(name)
+ if f != nil {
+ val, err := strconv.ParseBool(f.Value.String())
+ if err != nil {
+ return true
+ }
+ return val
+ }
+
+ return false
+}
+
+func copyFlag(name string, ff *flag.Flag, set *flag.FlagSet) {
+ switch ff.Value.(type) {
+ case *StringSlice:
+ default:
+ set.Set(name, ff.Value.String())
+ }
+}
+
+func normalizeFlags(flags []Flag, set *flag.FlagSet) error {
+ visited := make(map[string]bool)
+ set.Visit(func(f *flag.Flag) {
+ visited[f.Name] = true
+ })
+ for _, f := range flags {
+ parts := strings.Split(f.GetName(), ",")
+ if len(parts) == 1 {
+ continue
+ }
+ var ff *flag.Flag
+ for _, name := range parts {
+ name = strings.Trim(name, " ")
+ if visited[name] {
+ if ff != nil {
+ return errors.New("Cannot use two forms of the same flag: " + name + " " + ff.Name)
+ }
+ ff = set.Lookup(name)
+ }
+ }
+ if ff == nil {
+ continue
+ }
+ for _, name := range parts {
+ name = strings.Trim(name, " ")
+ if !visited[name] {
+ copyFlag(name, ff, set)
+ }
+ }
+ }
+ return nil
+}
http://git-wip-us.apache.org/repos/asf/brooklyn-client/blob/799e9ccb/cli/vendor/github.com/urfave/cli/context_test.go
----------------------------------------------------------------------
diff --git a/cli/vendor/github.com/urfave/cli/context_test.go b/cli/vendor/github.com/urfave/cli/context_test.go
new file mode 100644
index 0000000..7f8e928
--- /dev/null
+++ b/cli/vendor/github.com/urfave/cli/context_test.go
@@ -0,0 +1,113 @@
+package cli
+
+import (
+ "flag"
+ "testing"
+ "time"
+)
+
+func TestNewContext(t *testing.T) {
+ set := flag.NewFlagSet("test", 0)
+ set.Int("myflag", 12, "doc")
+ globalSet := flag.NewFlagSet("test", 0)
+ globalSet.Int("myflag", 42, "doc")
+ globalCtx := NewContext(nil, globalSet, nil)
+ command := Command{Name: "mycommand"}
+ c := NewContext(nil, set, globalCtx)
+ c.Command = command
+ expect(t, c.Int("myflag"), 12)
+ expect(t, c.GlobalInt("myflag"), 42)
+ expect(t, c.Command.Name, "mycommand")
+}
+
+func TestContext_Int(t *testing.T) {
+ set := flag.NewFlagSet("test", 0)
+ set.Int("myflag", 12, "doc")
+ c := NewContext(nil, set, nil)
+ expect(t, c.Int("myflag"), 12)
+}
+
+func TestContext_Duration(t *testing.T) {
+ set := flag.NewFlagSet("test", 0)
+ set.Duration("myflag", time.Duration(12*time.Second), "doc")
+ c := NewContext(nil, set, nil)
+ expect(t, c.Duration("myflag"), time.Duration(12*time.Second))
+}
+
+func TestContext_String(t *testing.T) {
+ set := flag.NewFlagSet("test", 0)
+ set.String("myflag", "hello world", "doc")
+ c := NewContext(nil, set, nil)
+ expect(t, c.String("myflag"), "hello world")
+}
+
+func TestContext_Bool(t *testing.T) {
+ set := flag.NewFlagSet("test", 0)
+ set.Bool("myflag", false, "doc")
+ c := NewContext(nil, set, nil)
+ expect(t, c.Bool("myflag"), false)
+}
+
+func TestContext_BoolT(t *testing.T) {
+ set := flag.NewFlagSet("test", 0)
+ set.Bool("myflag", true, "doc")
+ c := NewContext(nil, set, nil)
+ expect(t, c.BoolT("myflag"), true)
+}
+
+func TestContext_Args(t *testing.T) {
+ set := flag.NewFlagSet("test", 0)
+ set.Bool("myflag", false, "doc")
+ c := NewContext(nil, set, nil)
+ set.Parse([]string{"--myflag", "bat", "baz"})
+ expect(t, len(c.Args()), 2)
+ expect(t, c.Bool("myflag"), true)
+}
+
+func TestContext_IsSet(t *testing.T) {
+ set := flag.NewFlagSet("test", 0)
+ set.Bool("myflag", false, "doc")
+ set.String("otherflag", "hello world", "doc")
+ globalSet := flag.NewFlagSet("test", 0)
+ globalSet.Bool("myflagGlobal", true, "doc")
+ globalCtx := NewContext(nil, globalSet, nil)
+ c := NewContext(nil, set, globalCtx)
+ set.Parse([]string{"--myflag", "bat", "baz"})
+ globalSet.Parse([]string{"--myflagGlobal", "bat", "baz"})
+ expect(t, c.IsSet("myflag"), true)
+ expect(t, c.IsSet("otherflag"), false)
+ expect(t, c.IsSet("bogusflag"), false)
+ expect(t, c.IsSet("myflagGlobal"), false)
+}
+
+func TestContext_GlobalIsSet(t *testing.T) {
+ set := flag.NewFlagSet("test", 0)
+ set.Bool("myflag", false, "doc")
+ set.String("otherflag", "hello world", "doc")
+ globalSet := flag.NewFlagSet("test", 0)
+ globalSet.Bool("myflagGlobal", true, "doc")
+ globalSet.Bool("myflagGlobalUnset", true, "doc")
+ globalCtx := NewContext(nil, globalSet, nil)
+ c := NewContext(nil, set, globalCtx)
+ set.Parse([]string{"--myflag", "bat", "baz"})
+ globalSet.Parse([]string{"--myflagGlobal", "bat", "baz"})
+ expect(t, c.GlobalIsSet("myflag"), false)
+ expect(t, c.GlobalIsSet("otherflag"), false)
+ expect(t, c.GlobalIsSet("bogusflag"), false)
+ expect(t, c.GlobalIsSet("myflagGlobal"), true)
+ expect(t, c.GlobalIsSet("myflagGlobalUnset"), false)
+ expect(t, c.GlobalIsSet("bogusGlobal"), false)
+}
+
+func TestContext_NumFlags(t *testing.T) {
+ set := flag.NewFlagSet("test", 0)
+ set.Bool("myflag", false, "doc")
+ set.String("otherflag", "hello world", "doc")
+ globalSet := flag.NewFlagSet("test", 0)
+ globalSet.Bool("myflagGlobal", true, "doc")
+ globalCtx := NewContext(nil, globalSet, nil)
+ c := NewContext(nil, set, globalCtx)
+ set.Parse([]string{"--myflag", "--otherflag=foo"})
+ globalSet.Parse([]string{"--myflagGlobal"})
+ expect(t, c.NumFlags(), 2)
+}
http://git-wip-us.apache.org/repos/asf/brooklyn-client/blob/799e9ccb/cli/vendor/github.com/urfave/cli/flag.go
----------------------------------------------------------------------
diff --git a/cli/vendor/github.com/urfave/cli/flag.go b/cli/vendor/github.com/urfave/cli/flag.go
new file mode 100644
index 0000000..e951c2d
--- /dev/null
+++ b/cli/vendor/github.com/urfave/cli/flag.go
@@ -0,0 +1,546 @@
+package cli
+
+import (
+ "flag"
+ "fmt"
+ "os"
+ "runtime"
+ "strconv"
+ "strings"
+ "time"
+)
+
+// This flag enables bash-completion for all commands and subcommands
+var BashCompletionFlag = BoolFlag{
+ Name: "generate-bash-completion",
+}
+
+// This flag prints the version for the application
+var VersionFlag = BoolFlag{
+ Name: "version, v",
+ Usage: "print the version",
+}
+
+// This flag prints the help for all commands and subcommands
+// Set to the zero value (BoolFlag{}) to disable flag -- keeps subcommand
+// unless HideHelp is set to true)
+var HelpFlag = BoolFlag{
+ Name: "help, h",
+ Usage: "show help",
+}
+
+// Flag is a common interface related to parsing flags in cli.
+// For more advanced flag parsing techniques, it is recommended that
+// this interface be implemented.
+type Flag interface {
+ fmt.Stringer
+ // Apply Flag settings to the given flag set
+ Apply(*flag.FlagSet)
+ GetName() string
+}
+
+func flagSet(name string, flags []Flag) *flag.FlagSet {
+ set := flag.NewFlagSet(name, flag.ContinueOnError)
+
+ for _, f := range flags {
+ f.Apply(set)
+ }
+ return set
+}
+
+func eachName(longName string, fn func(string)) {
+ parts := strings.Split(longName, ",")
+ for _, name := range parts {
+ name = strings.Trim(name, " ")
+ fn(name)
+ }
+}
+
+// Generic is a generic parseable type identified by a specific flag
+type Generic interface {
+ Set(value string) error
+ String() string
+}
+
+// GenericFlag is the flag type for types implementing Generic
+type GenericFlag struct {
+ Name string
+ Value Generic
+ Usage string
+ EnvVar string
+}
+
+// String returns the string representation of the generic flag to display the
+// help text to the user (uses the String() method of the generic flag to show
+// the value)
+func (f GenericFlag) String() string {
+ return withEnvHint(f.EnvVar, fmt.Sprintf("%s %v\t%v", prefixedNames(f.Name), f.FormatValueHelp(), f.Usage))
+}
+
+func (f GenericFlag) FormatValueHelp() string {
+ if f.Value == nil {
+ return ""
+ }
+ s := f.Value.String()
+ if len(s) == 0 {
+ return ""
+ }
+ return fmt.Sprintf("\"%s\"", s)
+}
+
+// Apply takes the flagset and calls Set on the generic flag with the value
+// provided by the user for parsing by the flag
+func (f GenericFlag) Apply(set *flag.FlagSet) {
+ val := f.Value
+ if f.EnvVar != "" {
+ for _, envVar := range strings.Split(f.EnvVar, ",") {
+ envVar = strings.TrimSpace(envVar)
+ if envVal := os.Getenv(envVar); envVal != "" {
+ val.Set(envVal)
+ break
+ }
+ }
+ }
+
+ eachName(f.Name, func(name string) {
+ set.Var(f.Value, name, f.Usage)
+ })
+}
+
+func (f GenericFlag) GetName() string {
+ return f.Name
+}
+
+// StringSlice is an opaque type for []string to satisfy flag.Value
+type StringSlice []string
+
+// Set appends the string value to the list of values
+func (f *StringSlice) Set(value string) error {
+ *f = append(*f, value)
+ return nil
+}
+
+// String returns a readable representation of this value (for usage defaults)
+func (f *StringSlice) String() string {
+ return fmt.Sprintf("%s", *f)
+}
+
+// Value returns the slice of strings set by this flag
+func (f *StringSlice) Value() []string {
+ return *f
+}
+
+// StringSlice is a string flag that can be specified multiple times on the
+// command-line
+type StringSliceFlag struct {
+ Name string
+ Value *StringSlice
+ Usage string
+ EnvVar string
+}
+
+// String returns the usage
+func (f StringSliceFlag) String() string {
+ firstName := strings.Trim(strings.Split(f.Name, ",")[0], " ")
+ pref := prefixFor(firstName)
+ return withEnvHint(f.EnvVar, fmt.Sprintf("%s [%v]\t%v", prefixedNames(f.Name), pref+firstName+" option "+pref+firstName+" option", f.Usage))
+}
+
+// Apply populates the flag given the flag set and environment
+func (f StringSliceFlag) Apply(set *flag.FlagSet) {
+ if f.EnvVar != "" {
+ for _, envVar := range strings.Split(f.EnvVar, ",") {
+ envVar = strings.TrimSpace(envVar)
+ if envVal := os.Getenv(envVar); envVal != "" {
+ newVal := &StringSlice{}
+ for _, s := range strings.Split(envVal, ",") {
+ s = strings.TrimSpace(s)
+ newVal.Set(s)
+ }
+ f.Value = newVal
+ break
+ }
+ }
+ }
+
+ eachName(f.Name, func(name string) {
+ if f.Value == nil {
+ f.Value = &StringSlice{}
+ }
+ set.Var(f.Value, name, f.Usage)
+ })
+}
+
+func (f StringSliceFlag) GetName() string {
+ return f.Name
+}
+
+// StringSlice is an opaque type for []int to satisfy flag.Value
+type IntSlice []int
+
+// Set parses the value into an integer and appends it to the list of values
+func (f *IntSlice) Set(value string) error {
+ tmp, err := strconv.Atoi(value)
+ if err != nil {
+ return err
+ } else {
+ *f = append(*f, tmp)
+ }
+ return nil
+}
+
+// String returns a readable representation of this value (for usage defaults)
+func (f *IntSlice) String() string {
+ return fmt.Sprintf("%d", *f)
+}
+
+// Value returns the slice of ints set by this flag
+func (f *IntSlice) Value() []int {
+ return *f
+}
+
+// IntSliceFlag is an int flag that can be specified multiple times on the
+// command-line
+type IntSliceFlag struct {
+ Name string
+ Value *IntSlice
+ Usage string
+ EnvVar string
+}
+
+// String returns the usage
+func (f IntSliceFlag) String() string {
+ firstName := strings.Trim(strings.Split(f.Name, ",")[0], " ")
+ pref := prefixFor(firstName)
+ return withEnvHint(f.EnvVar, fmt.Sprintf("%s [%v]\t%v", prefixedNames(f.Name), pref+firstName+" option "+pref+firstName+" option", f.Usage))
+}
+
+// Apply populates the flag given the flag set and environment
+func (f IntSliceFlag) Apply(set *flag.FlagSet) {
+ if f.EnvVar != "" {
+ for _, envVar := range strings.Split(f.EnvVar, ",") {
+ envVar = strings.TrimSpace(envVar)
+ if envVal := os.Getenv(envVar); envVal != "" {
+ newVal := &IntSlice{}
+ for _, s := range strings.Split(envVal, ",") {
+ s = strings.TrimSpace(s)
+ err := newVal.Set(s)
+ if err != nil {
+ fmt.Fprintf(os.Stderr, err.Error())
+ }
+ }
+ f.Value = newVal
+ break
+ }
+ }
+ }
+
+ eachName(f.Name, func(name string) {
+ if f.Value == nil {
+ f.Value = &IntSlice{}
+ }
+ set.Var(f.Value, name, f.Usage)
+ })
+}
+
+func (f IntSliceFlag) GetName() string {
+ return f.Name
+}
+
+// BoolFlag is a switch that defaults to false
+type BoolFlag struct {
+ Name string
+ Usage string
+ EnvVar string
+ Destination *bool
+}
+
+// String returns a readable representation of this value (for usage defaults)
+func (f BoolFlag) String() string {
+ return withEnvHint(f.EnvVar, fmt.Sprintf("%s\t%v", prefixedNames(f.Name), f.Usage))
+}
+
+// Apply populates the flag given the flag set and environment
+func (f BoolFlag) Apply(set *flag.FlagSet) {
+ val := false
+ if f.EnvVar != "" {
+ for _, envVar := range strings.Split(f.EnvVar, ",") {
+ envVar = strings.TrimSpace(envVar)
+ if envVal := os.Getenv(envVar); envVal != "" {
+ envValBool, err := strconv.ParseBool(envVal)
+ if err == nil {
+ val = envValBool
+ }
+ break
+ }
+ }
+ }
+
+ eachName(f.Name, func(name string) {
+ if f.Destination != nil {
+ set.BoolVar(f.Destination, name, val, f.Usage)
+ return
+ }
+ set.Bool(name, val, f.Usage)
+ })
+}
+
+func (f BoolFlag) GetName() string {
+ return f.Name
+}
+
+// BoolTFlag this represents a boolean flag that is true by default, but can
+// still be set to false by --some-flag=false
+type BoolTFlag struct {
+ Name string
+ Usage string
+ EnvVar string
+ Destination *bool
+}
+
+// String returns a readable representation of this value (for usage defaults)
+func (f BoolTFlag) String() string {
+ return withEnvHint(f.EnvVar, fmt.Sprintf("%s\t%v", prefixedNames(f.Name), f.Usage))
+}
+
+// Apply populates the flag given the flag set and environment
+func (f BoolTFlag) Apply(set *flag.FlagSet) {
+ val := true
+ if f.EnvVar != "" {
+ for _, envVar := range strings.Split(f.EnvVar, ",") {
+ envVar = strings.TrimSpace(envVar)
+ if envVal := os.Getenv(envVar); envVal != "" {
+ envValBool, err := strconv.ParseBool(envVal)
+ if err == nil {
+ val = envValBool
+ break
+ }
+ }
+ }
+ }
+
+ eachName(f.Name, func(name string) {
+ if f.Destination != nil {
+ set.BoolVar(f.Destination, name, val, f.Usage)
+ return
+ }
+ set.Bool(name, val, f.Usage)
+ })
+}
+
+func (f BoolTFlag) GetName() string {
+ return f.Name
+}
+
+// StringFlag represents a flag that takes as string value
+type StringFlag struct {
+ Name string
+ Value string
+ Usage string
+ EnvVar string
+ Destination *string
+}
+
+// String returns the usage
+func (f StringFlag) String() string {
+ return withEnvHint(f.EnvVar, fmt.Sprintf("%s %v\t%v", prefixedNames(f.Name), f.FormatValueHelp(), f.Usage))
+}
+
+func (f StringFlag) FormatValueHelp() string {
+ s := f.Value
+ if len(s) == 0 {
+ return ""
+ }
+ return fmt.Sprintf("\"%s\"", s)
+}
+
+// Apply populates the flag given the flag set and environment
+func (f StringFlag) Apply(set *flag.FlagSet) {
+ if f.EnvVar != "" {
+ for _, envVar := range strings.Split(f.EnvVar, ",") {
+ envVar = strings.TrimSpace(envVar)
+ if envVal := os.Getenv(envVar); envVal != "" {
+ f.Value = envVal
+ break
+ }
+ }
+ }
+
+ eachName(f.Name, func(name string) {
+ if f.Destination != nil {
+ set.StringVar(f.Destination, name, f.Value, f.Usage)
+ return
+ }
+ set.String(name, f.Value, f.Usage)
+ })
+}
+
+func (f StringFlag) GetName() string {
+ return f.Name
+}
+
+// IntFlag is a flag that takes an integer
+// Errors if the value provided cannot be parsed
+type IntFlag struct {
+ Name string
+ Value int
+ Usage string
+ EnvVar string
+ Destination *int
+}
+
+// String returns the usage
+func (f IntFlag) String() string {
+ return withEnvHint(f.EnvVar, fmt.Sprintf("%s \"%v\"\t%v", prefixedNames(f.Name), f.Value, f.Usage))
+}
+
+// Apply populates the flag given the flag set and environment
+func (f IntFlag) Apply(set *flag.FlagSet) {
+ if f.EnvVar != "" {
+ for _, envVar := range strings.Split(f.EnvVar, ",") {
+ envVar = strings.TrimSpace(envVar)
+ if envVal := os.Getenv(envVar); envVal != "" {
+ envValInt, err := strconv.ParseInt(envVal, 0, 64)
+ if err == nil {
+ f.Value = int(envValInt)
+ break
+ }
+ }
+ }
+ }
+
+ eachName(f.Name, func(name string) {
+ if f.Destination != nil {
+ set.IntVar(f.Destination, name, f.Value, f.Usage)
+ return
+ }
+ set.Int(name, f.Value, f.Usage)
+ })
+}
+
+func (f IntFlag) GetName() string {
+ return f.Name
+}
+
+// DurationFlag is a flag that takes a duration specified in Go's duration
+// format: https://golang.org/pkg/time/#ParseDuration
+type DurationFlag struct {
+ Name string
+ Value time.Duration
+ Usage string
+ EnvVar string
+ Destination *time.Duration
+}
+
+// String returns a readable representation of this value (for usage defaults)
+func (f DurationFlag) String() string {
+ return withEnvHint(f.EnvVar, fmt.Sprintf("%s \"%v\"\t%v", prefixedNames(f.Name), f.Value, f.Usage))
+}
+
+// Apply populates the flag given the flag set and environment
+func (f DurationFlag) Apply(set *flag.FlagSet) {
+ if f.EnvVar != "" {
+ for _, envVar := range strings.Split(f.EnvVar, ",") {
+ envVar = strings.TrimSpace(envVar)
+ if envVal := os.Getenv(envVar); envVal != "" {
+ envValDuration, err := time.ParseDuration(envVal)
+ if err == nil {
+ f.Value = envValDuration
+ break
+ }
+ }
+ }
+ }
+
+ eachName(f.Name, func(name string) {
+ if f.Destination != nil {
+ set.DurationVar(f.Destination, name, f.Value, f.Usage)
+ return
+ }
+ set.Duration(name, f.Value, f.Usage)
+ })
+}
+
+func (f DurationFlag) GetName() string {
+ return f.Name
+}
+
+// Float64Flag is a flag that takes an float value
+// Errors if the value provided cannot be parsed
+type Float64Flag struct {
+ Name string
+ Value float64
+ Usage string
+ EnvVar string
+ Destination *float64
+}
+
+// String returns the usage
+func (f Float64Flag) String() string {
+ return withEnvHint(f.EnvVar, fmt.Sprintf("%s \"%v\"\t%v", prefixedNames(f.Name), f.Value, f.Usage))
+}
+
+// Apply populates the flag given the flag set and environment
+func (f Float64Flag) Apply(set *flag.FlagSet) {
+ if f.EnvVar != "" {
+ for _, envVar := range strings.Split(f.EnvVar, ",") {
+ envVar = strings.TrimSpace(envVar)
+ if envVal := os.Getenv(envVar); envVal != "" {
+ envValFloat, err := strconv.ParseFloat(envVal, 10)
+ if err == nil {
+ f.Value = float64(envValFloat)
+ }
+ }
+ }
+ }
+
+ eachName(f.Name, func(name string) {
+ if f.Destination != nil {
+ set.Float64Var(f.Destination, name, f.Value, f.Usage)
+ return
+ }
+ set.Float64(name, f.Value, f.Usage)
+ })
+}
+
+func (f Float64Flag) GetName() string {
+ return f.Name
+}
+
+func prefixFor(name string) (prefix string) {
+ if len(name) == 1 {
+ prefix = "-"
+ } else {
+ prefix = "--"
+ }
+
+ return
+}
+
+func prefixedNames(fullName string) (prefixed string) {
+ parts := strings.Split(fullName, ",")
+ for i, name := range parts {
+ name = strings.Trim(name, " ")
+ prefixed += prefixFor(name) + name
+ if i < len(parts)-1 {
+ prefixed += ", "
+ }
+ }
+ return
+}
+
+func withEnvHint(envVar, str string) string {
+ envText := ""
+ if envVar != "" {
+ prefix := "$"
+ suffix := ""
+ sep := ", $"
+ if runtime.GOOS == "windows" {
+ prefix = "%"
+ suffix = "%"
+ sep = "%, %"
+ }
+ envText = fmt.Sprintf(" [%s%s%s]", prefix, strings.Join(strings.Split(envVar, ","), sep), suffix)
+ }
+ return str + envText
+}
http://git-wip-us.apache.org/repos/asf/brooklyn-client/blob/799e9ccb/cli/vendor/github.com/urfave/cli/flag_test.go
----------------------------------------------------------------------
diff --git a/cli/vendor/github.com/urfave/cli/flag_test.go b/cli/vendor/github.com/urfave/cli/flag_test.go
new file mode 100644
index 0000000..3caa70a
--- /dev/null
+++ b/cli/vendor/github.com/urfave/cli/flag_test.go
@@ -0,0 +1,859 @@
+package cli
+
+import (
+ "fmt"
+ "os"
+ "reflect"
+ "strings"
+ "testing"
+ "runtime"
+)
+
+var boolFlagTests = []struct {
+ name string
+ expected string
+}{
+ {"help", "--help\t"},
+ {"h", "-h\t"},
+}
+
+func TestBoolFlagHelpOutput(t *testing.T) {
+
+ for _, test := range boolFlagTests {
+ flag := BoolFlag{Name: test.name}
+ output := flag.String()
+
+ if output != test.expected {
+ t.Errorf("%s does not match %s", output, test.expected)
+ }
+ }
+}
+
+var stringFlagTests = []struct {
+ name string
+ value string
+ expected string
+}{
+ {"help", "", "--help \t"},
+ {"h", "", "-h \t"},
+ {"h", "", "-h \t"},
+ {"test", "Something", "--test \"Something\"\t"},
+}
+
+func TestStringFlagHelpOutput(t *testing.T) {
+
+ for _, test := range stringFlagTests {
+ flag := StringFlag{Name: test.name, Value: test.value}
+ output := flag.String()
+
+ if output != test.expected {
+ t.Errorf("%s does not match %s", output, test.expected)
+ }
+ }
+}
+
+func TestStringFlagWithEnvVarHelpOutput(t *testing.T) {
+ os.Clearenv()
+ os.Setenv("APP_FOO", "derp")
+ for _, test := range stringFlagTests {
+ flag := StringFlag{Name: test.name, Value: test.value, EnvVar: "APP_FOO"}
+ output := flag.String()
+
+ expectedSuffix := " [$APP_FOO]"
+ if runtime.GOOS == "windows" {
+ expectedSuffix = " [%APP_FOO%]"
+ }
+ if !strings.HasSuffix(output, expectedSuffix) {
+ t.Errorf("%s does not end with" + expectedSuffix, output)
+ }
+ }
+}
+
+var stringSliceFlagTests = []struct {
+ name string
+ value *StringSlice
+ expected string
+}{
+ {"help", func() *StringSlice {
+ s := &StringSlice{}
+ s.Set("")
+ return s
+ }(), "--help [--help option --help option]\t"},
+ {"h", func() *StringSlice {
+ s := &StringSlice{}
+ s.Set("")
+ return s
+ }(), "-h [-h option -h option]\t"},
+ {"h", func() *StringSlice {
+ s := &StringSlice{}
+ s.Set("")
+ return s
+ }(), "-h [-h option -h option]\t"},
+ {"test", func() *StringSlice {
+ s := &StringSlice{}
+ s.Set("Something")
+ return s
+ }(), "--test [--test option --test option]\t"},
+}
+
+func TestStringSliceFlagHelpOutput(t *testing.T) {
+
+ for _, test := range stringSliceFlagTests {
+ flag := StringSliceFlag{Name: test.name, Value: test.value}
+ output := flag.String()
+
+ if output != test.expected {
+ t.Errorf("%q does not match %q", output, test.expected)
+ }
+ }
+}
+
+func TestStringSliceFlagWithEnvVarHelpOutput(t *testing.T) {
+ os.Clearenv()
+ os.Setenv("APP_QWWX", "11,4")
+ for _, test := range stringSliceFlagTests {
+ flag := StringSliceFlag{Name: test.name, Value: test.value, EnvVar: "APP_QWWX"}
+ output := flag.String()
+
+ expectedSuffix := " [$APP_QWWX]"
+ if runtime.GOOS == "windows" {
+ expectedSuffix = " [%APP_QWWX%]"
+ }
+ if !strings.HasSuffix(output, expectedSuffix) {
+ t.Errorf("%q does not end with" + expectedSuffix, output)
+ }
+ }
+}
+
+var intFlagTests = []struct {
+ name string
+ expected string
+}{
+ {"help", "--help \"0\"\t"},
+ {"h", "-h \"0\"\t"},
+}
+
+func TestIntFlagHelpOutput(t *testing.T) {
+
+ for _, test := range intFlagTests {
+ flag := IntFlag{Name: test.name}
+ output := flag.String()
+
+ if output != test.expected {
+ t.Errorf("%s does not match %s", output, test.expected)
+ }
+ }
+}
+
+func TestIntFlagWithEnvVarHelpOutput(t *testing.T) {
+ os.Clearenv()
+ os.Setenv("APP_BAR", "2")
+ for _, test := range intFlagTests {
+ flag := IntFlag{Name: test.name, EnvVar: "APP_BAR"}
+ output := flag.String()
+
+ expectedSuffix := " [$APP_BAR]"
+ if runtime.GOOS == "windows" {
+ expectedSuffix = " [%APP_BAR%]"
+ }
+ if !strings.HasSuffix(output, expectedSuffix) {
+ t.Errorf("%s does not end with" + expectedSuffix, output)
+ }
+ }
+}
+
+var durationFlagTests = []struct {
+ name string
+ expected string
+}{
+ {"help", "--help \"0\"\t"},
+ {"h", "-h \"0\"\t"},
+}
+
+func TestDurationFlagHelpOutput(t *testing.T) {
+
+ for _, test := range durationFlagTests {
+ flag := DurationFlag{Name: test.name}
+ output := flag.String()
+
+ if output != test.expected {
+ t.Errorf("%s does not match %s", output, test.expected)
+ }
+ }
+}
+
+func TestDurationFlagWithEnvVarHelpOutput(t *testing.T) {
+ os.Clearenv()
+ os.Setenv("APP_BAR", "2h3m6s")
+ for _, test := range durationFlagTests {
+ flag := DurationFlag{Name: test.name, EnvVar: "APP_BAR"}
+ output := flag.String()
+
+ expectedSuffix := " [$APP_BAR]"
+ if runtime.GOOS == "windows" {
+ expectedSuffix = " [%APP_BAR%]"
+ }
+ if !strings.HasSuffix(output, expectedSuffix) {
+ t.Errorf("%s does not end with" + expectedSuffix, output)
+ }
+ }
+}
+
+var intSliceFlagTests = []struct {
+ name string
+ value *IntSlice
+ expected string
+}{
+ {"help", &IntSlice{}, "--help [--help option --help option]\t"},
+ {"h", &IntSlice{}, "-h [-h option -h option]\t"},
+ {"h", &IntSlice{}, "-h [-h option -h option]\t"},
+ {"test", func() *IntSlice {
+ i := &IntSlice{}
+ i.Set("9")
+ return i
+ }(), "--test [--test option --test option]\t"},
+}
+
+func TestIntSliceFlagHelpOutput(t *testing.T) {
+
+ for _, test := range intSliceFlagTests {
+ flag := IntSliceFlag{Name: test.name, Value: test.value}
+ output := flag.String()
+
+ if output != test.expected {
+ t.Errorf("%q does not match %q", output, test.expected)
+ }
+ }
+}
+
+func TestIntSliceFlagWithEnvVarHelpOutput(t *testing.T) {
+ os.Clearenv()
+ os.Setenv("APP_SMURF", "42,3")
+ for _, test := range intSliceFlagTests {
+ flag := IntSliceFlag{Name: test.name, Value: test.value, EnvVar: "APP_SMURF"}
+ output := flag.String()
+
+ expectedSuffix := " [$APP_SMURF]"
+ if runtime.GOOS == "windows" {
+ expectedSuffix = " [%APP_SMURF%]"
+ }
+ if !strings.HasSuffix(output, expectedSuffix) {
+ t.Errorf("%q does not end with" + expectedSuffix, output)
+ }
+ }
+}
+
+var float64FlagTests = []struct {
+ name string
+ expected string
+}{
+ {"help", "--help \"0\"\t"},
+ {"h", "-h \"0\"\t"},
+}
+
+func TestFloat64FlagHelpOutput(t *testing.T) {
+
+ for _, test := range float64FlagTests {
+ flag := Float64Flag{Name: test.name}
+ output := flag.String()
+
+ if output != test.expected {
+ t.Errorf("%s does not match %s", output, test.expected)
+ }
+ }
+}
+
+func TestFloat64FlagWithEnvVarHelpOutput(t *testing.T) {
+ os.Clearenv()
+ os.Setenv("APP_BAZ", "99.4")
+ for _, test := range float64FlagTests {
+ flag := Float64Flag{Name: test.name, EnvVar: "APP_BAZ"}
+ output := flag.String()
+
+ expectedSuffix := " [$APP_BAZ]"
+ if runtime.GOOS == "windows" {
+ expectedSuffix = " [%APP_BAZ%]"
+ }
+ if !strings.HasSuffix(output, expectedSuffix) {
+ t.Errorf("%s does not end with" + expectedSuffix, output)
+ }
+ }
+}
+
+var genericFlagTests = []struct {
+ name string
+ value Generic
+ expected string
+}{
+ {"test", &Parser{"abc", "def"}, "--test \"abc,def\"\ttest flag"},
+ {"t", &Parser{"abc", "def"}, "-t \"abc,def\"\ttest flag"},
+}
+
+func TestGenericFlagHelpOutput(t *testing.T) {
+
+ for _, test := range genericFlagTests {
+ flag := GenericFlag{Name: test.name, Value: test.value, Usage: "test flag"}
+ output := flag.String()
+
+ if output != test.expected {
+ t.Errorf("%q does not match %q", output, test.expected)
+ }
+ }
+}
+
+func TestGenericFlagWithEnvVarHelpOutput(t *testing.T) {
+ os.Clearenv()
+ os.Setenv("APP_ZAP", "3")
+ for _, test := range genericFlagTests {
+ flag := GenericFlag{Name: test.name, EnvVar: "APP_ZAP"}
+ output := flag.String()
+
+ expectedSuffix := " [$APP_ZAP]"
+ if runtime.GOOS == "windows" {
+ expectedSuffix = " [%APP_ZAP%]"
+ }
+ if !strings.HasSuffix(output, expectedSuffix) {
+ t.Errorf("%s does not end with" + expectedSuffix, output)
+ }
+ }
+}
+
+func TestParseMultiString(t *testing.T) {
+ (&App{
+ Flags: []Flag{
+ StringFlag{Name: "serve, s"},
+ },
+ Action: func(ctx *Context) {
+ if ctx.String("serve") != "10" {
+ t.Errorf("main name not set")
+ }
+ if ctx.String("s") != "10" {
+ t.Errorf("short name not set")
+ }
+ },
+ }).Run([]string{"run", "-s", "10"})
+}
+
+func TestParseDestinationString(t *testing.T) {
+ var dest string
+ a := App{
+ Flags: []Flag{
+ StringFlag{
+ Name: "dest",
+ Destination: &dest,
+ },
+ },
+ Action: func(ctx *Context) {
+ if dest != "10" {
+ t.Errorf("expected destination String 10")
+ }
+ },
+ }
+ a.Run([]string{"run", "--dest", "10"})
+}
+
+func TestParseMultiStringFromEnv(t *testing.T) {
+ os.Clearenv()
+ os.Setenv("APP_COUNT", "20")
+ (&App{
+ Flags: []Flag{
+ StringFlag{Name: "count, c", EnvVar: "APP_COUNT"},
+ },
+ Action: func(ctx *Context) {
+ if ctx.String("count") != "20" {
+ t.Errorf("main name not set")
+ }
+ if ctx.String("c") != "20" {
+ t.Errorf("short name not set")
+ }
+ },
+ }).Run([]string{"run"})
+}
+
+func TestParseMultiStringFromEnvCascade(t *testing.T) {
+ os.Clearenv()
+ os.Setenv("APP_COUNT", "20")
+ (&App{
+ Flags: []Flag{
+ StringFlag{Name: "count, c", EnvVar: "COMPAT_COUNT,APP_COUNT"},
+ },
+ Action: func(ctx *Context) {
+ if ctx.String("count") != "20" {
+ t.Errorf("main name not set")
+ }
+ if ctx.String("c") != "20" {
+ t.Errorf("short name not set")
+ }
+ },
+ }).Run([]string{"run"})
+}
+
+func TestParseMultiStringSlice(t *testing.T) {
+ (&App{
+ Flags: []Flag{
+ StringSliceFlag{Name: "serve, s", Value: &StringSlice{}},
+ },
+ Action: func(ctx *Context) {
+ if !reflect.DeepEqual(ctx.StringSlice("serve"), []string{"10", "20"}) {
+ t.Errorf("main name not set")
+ }
+ if !reflect.DeepEqual(ctx.StringSlice("s"), []string{"10", "20"}) {
+ t.Errorf("short name not set")
+ }
+ },
+ }).Run([]string{"run", "-s", "10", "-s", "20"})
+}
+
+func TestParseMultiStringSliceFromEnv(t *testing.T) {
+ os.Clearenv()
+ os.Setenv("APP_INTERVALS", "20,30,40")
+
+ (&App{
+ Flags: []Flag{
+ StringSliceFlag{Name: "intervals, i", Value: &StringSlice{}, EnvVar: "APP_INTERVALS"},
+ },
+ Action: func(ctx *Context) {
+ if !reflect.DeepEqual(ctx.StringSlice("intervals"), []string{"20", "30", "40"}) {
+ t.Errorf("main name not set from env")
+ }
+ if !reflect.DeepEqual(ctx.StringSlice("i"), []string{"20", "30", "40"}) {
+ t.Errorf("short name not set from env")
+ }
+ },
+ }).Run([]string{"run"})
+}
+
+func TestParseMultiStringSliceFromEnvCascade(t *testing.T) {
+ os.Clearenv()
+ os.Setenv("APP_INTERVALS", "20,30,40")
+
+ (&App{
+ Flags: []Flag{
+ StringSliceFlag{Name: "intervals, i", Value: &StringSlice{}, EnvVar: "COMPAT_INTERVALS,APP_INTERVALS"},
+ },
+ Action: func(ctx *Context) {
+ if !reflect.DeepEqual(ctx.StringSlice("intervals"), []string{"20", "30", "40"}) {
+ t.Errorf("main name not set from env")
+ }
+ if !reflect.DeepEqual(ctx.StringSlice("i"), []string{"20", "30", "40"}) {
+ t.Errorf("short name not set from env")
+ }
+ },
+ }).Run([]string{"run"})
+}
+
+func TestParseMultiInt(t *testing.T) {
+ a := App{
+ Flags: []Flag{
+ IntFlag{Name: "serve, s"},
+ },
+ Action: func(ctx *Context) {
+ if ctx.Int("serve") != 10 {
+ t.Errorf("main name not set")
+ }
+ if ctx.Int("s") != 10 {
+ t.Errorf("short name not set")
+ }
+ },
+ }
+ a.Run([]string{"run", "-s", "10"})
+}
+
+func TestParseDestinationInt(t *testing.T) {
+ var dest int
+ a := App{
+ Flags: []Flag{
+ IntFlag{
+ Name: "dest",
+ Destination: &dest,
+ },
+ },
+ Action: func(ctx *Context) {
+ if dest != 10 {
+ t.Errorf("expected destination Int 10")
+ }
+ },
+ }
+ a.Run([]string{"run", "--dest", "10"})
+}
+
+func TestParseMultiIntFromEnv(t *testing.T) {
+ os.Clearenv()
+ os.Setenv("APP_TIMEOUT_SECONDS", "10")
+ a := App{
+ Flags: []Flag{
+ IntFlag{Name: "timeout, t", EnvVar: "APP_TIMEOUT_SECONDS"},
+ },
+ Action: func(ctx *Context) {
+ if ctx.Int("timeout") != 10 {
+ t.Errorf("main name not set")
+ }
+ if ctx.Int("t") != 10 {
+ t.Errorf("short name not set")
+ }
+ },
+ }
+ a.Run([]string{"run"})
+}
+
+func TestParseMultiIntFromEnvCascade(t *testing.T) {
+ os.Clearenv()
+ os.Setenv("APP_TIMEOUT_SECONDS", "10")
+ a := App{
+ Flags: []Flag{
+ IntFlag{Name: "timeout, t", EnvVar: "COMPAT_TIMEOUT_SECONDS,APP_TIMEOUT_SECONDS"},
+ },
+ Action: func(ctx *Context) {
+ if ctx.Int("timeout") != 10 {
+ t.Errorf("main name not set")
+ }
+ if ctx.Int("t") != 10 {
+ t.Errorf("short name not set")
+ }
+ },
+ }
+ a.Run([]string{"run"})
+}
+
+func TestParseMultiIntSlice(t *testing.T) {
+ (&App{
+ Flags: []Flag{
+ IntSliceFlag{Name: "serve, s", Value: &IntSlice{}},
+ },
+ Action: func(ctx *Context) {
+ if !reflect.DeepEqual(ctx.IntSlice("serve"), []int{10, 20}) {
+ t.Errorf("main name not set")
+ }
+ if !reflect.DeepEqual(ctx.IntSlice("s"), []int{10, 20}) {
+ t.Errorf("short name not set")
+ }
+ },
+ }).Run([]string{"run", "-s", "10", "-s", "20"})
+}
+
+func TestParseMultiIntSliceFromEnv(t *testing.T) {
+ os.Clearenv()
+ os.Setenv("APP_INTERVALS", "20,30,40")
+
+ (&App{
+ Flags: []Flag{
+ IntSliceFlag{Name: "intervals, i", Value: &IntSlice{}, EnvVar: "APP_INTERVALS"},
+ },
+ Action: func(ctx *Context) {
+ if !reflect.DeepEqual(ctx.IntSlice("intervals"), []int{20, 30, 40}) {
+ t.Errorf("main name not set from env")
+ }
+ if !reflect.DeepEqual(ctx.IntSlice("i"), []int{20, 30, 40}) {
+ t.Errorf("short name not set from env")
+ }
+ },
+ }).Run([]string{"run"})
+}
+
+func TestParseMultiIntSliceFromEnvCascade(t *testing.T) {
+ os.Clearenv()
+ os.Setenv("APP_INTERVALS", "20,30,40")
+
+ (&App{
+ Flags: []Flag{
+ IntSliceFlag{Name: "intervals, i", Value: &IntSlice{}, EnvVar: "COMPAT_INTERVALS,APP_INTERVALS"},
+ },
+ Action: func(ctx *Context) {
+ if !reflect.DeepEqual(ctx.IntSlice("intervals"), []int{20, 30, 40}) {
+ t.Errorf("main name not set from env")
+ }
+ if !reflect.DeepEqual(ctx.IntSlice("i"), []int{20, 30, 40}) {
+ t.Errorf("short name not set from env")
+ }
+ },
+ }).Run([]string{"run"})
+}
+
+func TestParseMultiFloat64(t *testing.T) {
+ a := App{
+ Flags: []Flag{
+ Float64Flag{Name: "serve, s"},
+ },
+ Action: func(ctx *Context) {
+ if ctx.Float64("serve") != 10.2 {
+ t.Errorf("main name not set")
+ }
+ if ctx.Float64("s") != 10.2 {
+ t.Errorf("short name not set")
+ }
+ },
+ }
+ a.Run([]string{"run", "-s", "10.2"})
+}
+
+func TestParseDestinationFloat64(t *testing.T) {
+ var dest float64
+ a := App{
+ Flags: []Flag{
+ Float64Flag{
+ Name: "dest",
+ Destination: &dest,
+ },
+ },
+ Action: func(ctx *Context) {
+ if dest != 10.2 {
+ t.Errorf("expected destination Float64 10.2")
+ }
+ },
+ }
+ a.Run([]string{"run", "--dest", "10.2"})
+}
+
+func TestParseMultiFloat64FromEnv(t *testing.T) {
+ os.Clearenv()
+ os.Setenv("APP_TIMEOUT_SECONDS", "15.5")
+ a := App{
+ Flags: []Flag{
+ Float64Flag{Name: "timeout, t", EnvVar: "APP_TIMEOUT_SECONDS"},
+ },
+ Action: func(ctx *Context) {
+ if ctx.Float64("timeout") != 15.5 {
+ t.Errorf("main name not set")
+ }
+ if ctx.Float64("t") != 15.5 {
+ t.Errorf("short name not set")
+ }
+ },
+ }
+ a.Run([]string{"run"})
+}
+
+func TestParseMultiFloat64FromEnvCascade(t *testing.T) {
+ os.Clearenv()
+ os.Setenv("APP_TIMEOUT_SECONDS", "15.5")
+ a := App{
+ Flags: []Flag{
+ Float64Flag{Name: "timeout, t", EnvVar: "COMPAT_TIMEOUT_SECONDS,APP_TIMEOUT_SECONDS"},
+ },
+ Action: func(ctx *Context) {
+ if ctx.Float64("timeout") != 15.5 {
+ t.Errorf("main name not set")
+ }
+ if ctx.Float64("t") != 15.5 {
+ t.Errorf("short name not set")
+ }
+ },
+ }
+ a.Run([]string{"run"})
+}
+
+func TestParseMultiBool(t *testing.T) {
+ a := App{
+ Flags: []Flag{
+ BoolFlag{Name: "serve, s"},
+ },
+ Action: func(ctx *Context) {
+ if ctx.Bool("serve") != true {
+ t.Errorf("main name not set")
+ }
+ if ctx.Bool("s") != true {
+ t.Errorf("short name not set")
+ }
+ },
+ }
+ a.Run([]string{"run", "--serve"})
+}
+
+func TestParseDestinationBool(t *testing.T) {
+ var dest bool
+ a := App{
+ Flags: []Flag{
+ BoolFlag{
+ Name: "dest",
+ Destination: &dest,
+ },
+ },
+ Action: func(ctx *Context) {
+ if dest != true {
+ t.Errorf("expected destination Bool true")
+ }
+ },
+ }
+ a.Run([]string{"run", "--dest"})
+}
+
+func TestParseMultiBoolFromEnv(t *testing.T) {
+ os.Clearenv()
+ os.Setenv("APP_DEBUG", "1")
+ a := App{
+ Flags: []Flag{
+ BoolFlag{Name: "debug, d", EnvVar: "APP_DEBUG"},
+ },
+ Action: func(ctx *Context) {
+ if ctx.Bool("debug") != true {
+ t.Errorf("main name not set from env")
+ }
+ if ctx.Bool("d") != true {
+ t.Errorf("short name not set from env")
+ }
+ },
+ }
+ a.Run([]string{"run"})
+}
+
+func TestParseMultiBoolFromEnvCascade(t *testing.T) {
+ os.Clearenv()
+ os.Setenv("APP_DEBUG", "1")
+ a := App{
+ Flags: []Flag{
+ BoolFlag{Name: "debug, d", EnvVar: "COMPAT_DEBUG,APP_DEBUG"},
+ },
+ Action: func(ctx *Context) {
+ if ctx.Bool("debug") != true {
+ t.Errorf("main name not set from env")
+ }
+ if ctx.Bool("d") != true {
+ t.Errorf("short name not set from env")
+ }
+ },
+ }
+ a.Run([]string{"run"})
+}
+
+func TestParseMultiBoolT(t *testing.T) {
+ a := App{
+ Flags: []Flag{
+ BoolTFlag{Name: "serve, s"},
+ },
+ Action: func(ctx *Context) {
+ if ctx.BoolT("serve") != true {
+ t.Errorf("main name not set")
+ }
+ if ctx.BoolT("s") != true {
+ t.Errorf("short name not set")
+ }
+ },
+ }
+ a.Run([]string{"run", "--serve"})
+}
+
+func TestParseDestinationBoolT(t *testing.T) {
+ var dest bool
+ a := App{
+ Flags: []Flag{
+ BoolTFlag{
+ Name: "dest",
+ Destination: &dest,
+ },
+ },
+ Action: func(ctx *Context) {
+ if dest != true {
+ t.Errorf("expected destination BoolT true")
+ }
+ },
+ }
+ a.Run([]string{"run", "--dest"})
+}
+
+func TestParseMultiBoolTFromEnv(t *testing.T) {
+ os.Clearenv()
+ os.Setenv("APP_DEBUG", "0")
+ a := App{
+ Flags: []Flag{
+ BoolTFlag{Name: "debug, d", EnvVar: "APP_DEBUG"},
+ },
+ Action: func(ctx *Context) {
+ if ctx.BoolT("debug") != false {
+ t.Errorf("main name not set from env")
+ }
+ if ctx.BoolT("d") != false {
+ t.Errorf("short name not set from env")
+ }
+ },
+ }
+ a.Run([]string{"run"})
+}
+
+func TestParseMultiBoolTFromEnvCascade(t *testing.T) {
+ os.Clearenv()
+ os.Setenv("APP_DEBUG", "0")
+ a := App{
+ Flags: []Flag{
+ BoolTFlag{Name: "debug, d", EnvVar: "COMPAT_DEBUG,APP_DEBUG"},
+ },
+ Action: func(ctx *Context) {
+ if ctx.BoolT("debug") != false {
+ t.Errorf("main name not set from env")
+ }
+ if ctx.BoolT("d") != false {
+ t.Errorf("short name not set from env")
+ }
+ },
+ }
+ a.Run([]string{"run"})
+}
+
+type Parser [2]string
+
+func (p *Parser) Set(value string) error {
+ parts := strings.Split(value, ",")
+ if len(parts) != 2 {
+ return fmt.Errorf("invalid format")
+ }
+
+ (*p)[0] = parts[0]
+ (*p)[1] = parts[1]
+
+ return nil
+}
+
+func (p *Parser) String() string {
+ return fmt.Sprintf("%s,%s", p[0], p[1])
+}
+
+func TestParseGeneric(t *testing.T) {
+ a := App{
+ Flags: []Flag{
+ GenericFlag{Name: "serve, s", Value: &Parser{}},
+ },
+ Action: func(ctx *Context) {
+ if !reflect.DeepEqual(ctx.Generic("serve"), &Parser{"10", "20"}) {
+ t.Errorf("main name not set")
+ }
+ if !reflect.DeepEqual(ctx.Generic("s"), &Parser{"10", "20"}) {
+ t.Errorf("short name not set")
+ }
+ },
+ }
+ a.Run([]string{"run", "-s", "10,20"})
+}
+
+func TestParseGenericFromEnv(t *testing.T) {
+ os.Clearenv()
+ os.Setenv("APP_SERVE", "20,30")
+ a := App{
+ Flags: []Flag{
+ GenericFlag{Name: "serve, s", Value: &Parser{}, EnvVar: "APP_SERVE"},
+ },
+ Action: func(ctx *Context) {
+ if !reflect.DeepEqual(ctx.Generic("serve"), &Parser{"20", "30"}) {
+ t.Errorf("main name not set from env")
+ }
+ if !reflect.DeepEqual(ctx.Generic("s"), &Parser{"20", "30"}) {
+ t.Errorf("short name not set from env")
+ }
+ },
+ }
+ a.Run([]string{"run"})
+}
+
+func TestParseGenericFromEnvCascade(t *testing.T) {
+ os.Clearenv()
+ os.Setenv("APP_FOO", "99,2000")
+ a := App{
+ Flags: []Flag{
+ GenericFlag{Name: "foos", Value: &Parser{}, EnvVar: "COMPAT_FOO,APP_FOO"},
+ },
+ Action: func(ctx *Context) {
+ if !reflect.DeepEqual(ctx.Generic("foos"), &Parser{"99", "2000"}) {
+ t.Errorf("value not set from env")
+ }
+ },
+ }
+ a.Run([]string{"run"})
+}
http://git-wip-us.apache.org/repos/asf/brooklyn-client/blob/799e9ccb/cli/vendor/github.com/urfave/cli/help.go
----------------------------------------------------------------------
diff --git a/cli/vendor/github.com/urfave/cli/help.go b/cli/vendor/github.com/urfave/cli/help.go
new file mode 100644
index 0000000..15916f8
--- /dev/null
+++ b/cli/vendor/github.com/urfave/cli/help.go
@@ -0,0 +1,248 @@
+package cli
+
+import (
+ "fmt"
+ "io"
+ "strings"
+ "text/tabwriter"
+ "text/template"
+)
+
+// The text template for the Default help topic.
+// cli.go uses text/template to render templates. You can
+// render custom help text by setting this variable.
+var AppHelpTemplate = `NAME:
+ {{.Name}} - {{.Usage}}
+
+USAGE:
+ {{if .UsageText}}{{.UsageText}}{{else}}{{.HelpName}} {{if .Flags}}[global options]{{end}}{{if .Commands}} command [command options]{{end}} {{if .ArgsUsage}}{{.ArgsUsage}}{{else}}[arguments...]{{end}}{{end}}
+ {{if .Version}}
+VERSION:
+ {{.Version}}
+ {{end}}{{if len .Authors}}
+AUTHOR(S):
+ {{range .Authors}}{{ . }}{{end}}
+ {{end}}{{if .Commands}}
+COMMANDS:
+ {{range .Commands}}{{join .Names ", "}}{{ "\t" }}{{.Usage}}
+ {{end}}{{end}}{{if .Flags}}
+GLOBAL OPTIONS:
+ {{range .Flags}}{{.}}
+ {{end}}{{end}}{{if .Copyright }}
+COPYRIGHT:
+ {{.Copyright}}
+ {{end}}
+`
+
+// The text template for the command help topic.
+// cli.go uses text/template to render templates. You can
+// render custom help text by setting this variable.
+var CommandHelpTemplate = `NAME:
+ {{.HelpName}} - {{.Usage}}
+
+USAGE:
+ {{.HelpName}}{{if .Flags}} [command options]{{end}} {{if .ArgsUsage}}{{.ArgsUsage}}{{else}}[arguments...]{{end}}{{if .Description}}
+
+DESCRIPTION:
+ {{.Description}}{{end}}{{if .Flags}}
+
+OPTIONS:
+ {{range .Flags}}{{.}}
+ {{end}}{{ end }}
+`
+
+// The text template for the subcommand help topic.
+// cli.go uses text/template to render templates. You can
+// render custom help text by setting this variable.
+var SubcommandHelpTemplate = `NAME:
+ {{.HelpName}} - {{.Usage}}
+
+USAGE:
+ {{.HelpName}} command{{if .Flags}} [command options]{{end}} {{if .ArgsUsage}}{{.ArgsUsage}}{{else}}[arguments...]{{end}}
+
+COMMANDS:
+ {{range .Commands}}{{join .Names ", "}}{{ "\t" }}{{.Usage}}
+ {{end}}{{if .Flags}}
+OPTIONS:
+ {{range .Flags}}{{.}}
+ {{end}}{{end}}
+`
+
+var helpCommand = Command{
+ Name: "help",
+ Aliases: []string{"h"},
+ Usage: "Shows a list of commands or help for one command",
+ ArgsUsage: "[command]",
+ Action: func(c *Context) {
+ args := c.Args()
+ if args.Present() {
+ ShowCommandHelp(c, args.First())
+ } else {
+ ShowAppHelp(c)
+ }
+ },
+}
+
+var helpSubcommand = Command{
+ Name: "help",
+ Aliases: []string{"h"},
+ Usage: "Shows a list of commands or help for one command",
+ ArgsUsage: "[command]",
+ Action: func(c *Context) {
+ args := c.Args()
+ if args.Present() {
+ ShowCommandHelp(c, args.First())
+ } else {
+ ShowSubcommandHelp(c)
+ }
+ },
+}
+
+// Prints help for the App or Command
+type helpPrinter func(w io.Writer, templ string, data interface{})
+
+var HelpPrinter helpPrinter = printHelp
+
+// Prints version for the App
+var VersionPrinter = printVersion
+
+func ShowAppHelp(c *Context) {
+ HelpPrinter(c.App.Writer, AppHelpTemplate, c.App)
+}
+
+// Prints the list of subcommands as the default app completion method
+func DefaultAppComplete(c *Context) {
+ for _, command := range c.App.Commands {
+ for _, name := range command.Names() {
+ fmt.Fprintln(c.App.Writer, name)
+ }
+ }
+}
+
+// Prints help for the given command
+func ShowCommandHelp(ctx *Context, command string) {
+ // show the subcommand help for a command with subcommands
+ if command == "" {
+ HelpPrinter(ctx.App.Writer, SubcommandHelpTemplate, ctx.App)
+ return
+ }
+
+ for _, c := range ctx.App.Commands {
+ if c.HasName(command) {
+ HelpPrinter(ctx.App.Writer, CommandHelpTemplate, c)
+ return
+ }
+ }
+
+ if ctx.App.CommandNotFound != nil {
+ ctx.App.CommandNotFound(ctx, command)
+ } else {
+ fmt.Fprintf(ctx.App.Writer, "No help topic for '%v'\n", command)
+ }
+}
+
+// Prints help for the given subcommand
+func ShowSubcommandHelp(c *Context) {
+ ShowCommandHelp(c, c.Command.Name)
+}
+
+// Prints the version number of the App
+func ShowVersion(c *Context) {
+ VersionPrinter(c)
+}
+
+func printVersion(c *Context) {
+ fmt.Fprintf(c.App.Writer, "%v version %v\n", c.App.Name, c.App.Version)
+}
+
+// Prints the lists of commands within a given context
+func ShowCompletions(c *Context) {
+ a := c.App
+ if a != nil && a.BashComplete != nil {
+ a.BashComplete(c)
+ }
+}
+
+// Prints the custom completions for a given command
+func ShowCommandCompletions(ctx *Context, command string) {
+ c := ctx.App.Command(command)
+ if c != nil && c.BashComplete != nil {
+ c.BashComplete(ctx)
+ }
+}
+
+func printHelp(out io.Writer, templ string, data interface{}) {
+ funcMap := template.FuncMap{
+ "join": strings.Join,
+ }
+
+ w := tabwriter.NewWriter(out, 0, 8, 1, '\t', 0)
+ t := template.Must(template.New("help").Funcs(funcMap).Parse(templ))
+ err := t.Execute(w, data)
+ if err != nil {
+ // If the writer is closed, t.Execute will fail, and there's nothing
+ // we can do to recover. We could send this to os.Stderr if we need.
+ return
+ }
+ w.Flush()
+}
+
+func checkVersion(c *Context) bool {
+ found := false
+ if VersionFlag.Name != "" {
+ eachName(VersionFlag.Name, func(name string) {
+ if c.GlobalBool(name) || c.Bool(name) {
+ found = true
+ }
+ })
+ }
+ return found
+}
+
+func checkHelp(c *Context) bool {
+ found := false
+ if HelpFlag.Name != "" {
+ eachName(HelpFlag.Name, func(name string) {
+ if c.GlobalBool(name) || c.Bool(name) {
+ found = true
+ }
+ })
+ }
+ return found
+}
+
+func checkCommandHelp(c *Context, name string) bool {
+ if c.Bool("h") || c.Bool("help") {
+ ShowCommandHelp(c, name)
+ return true
+ }
+
+ return false
+}
+
+func checkSubcommandHelp(c *Context) bool {
+ if c.GlobalBool("h") || c.GlobalBool("help") {
+ ShowSubcommandHelp(c)
+ return true
+ }
+
+ return false
+}
+
+func checkCompletions(c *Context) bool {
+ if (c.GlobalBool(BashCompletionFlag.Name) || c.Bool(BashCompletionFlag.Name)) && c.App.EnableBashCompletion {
+ ShowCompletions(c)
+ return true
+ }
+
+ return false
+}
+
+func checkCommandCompletions(c *Context, name string) bool {
+ if c.Bool(BashCompletionFlag.Name) && c.App.EnableBashCompletion {
+ ShowCommandCompletions(c, name)
+ return true
+ }
+
+ return false
+}
http://git-wip-us.apache.org/repos/asf/brooklyn-client/blob/799e9ccb/cli/vendor/github.com/urfave/cli/help_test.go
----------------------------------------------------------------------
diff --git a/cli/vendor/github.com/urfave/cli/help_test.go b/cli/vendor/github.com/urfave/cli/help_test.go
new file mode 100644
index 0000000..350e263
--- /dev/null
+++ b/cli/vendor/github.com/urfave/cli/help_test.go
@@ -0,0 +1,94 @@
+package cli
+
+import (
+ "bytes"
+ "testing"
+)
+
+func Test_ShowAppHelp_NoAuthor(t *testing.T) {
+ output := new(bytes.Buffer)
+ app := NewApp()
+ app.Writer = output
+
+ c := NewContext(app, nil, nil)
+
+ ShowAppHelp(c)
+
+ if bytes.Index(output.Bytes(), []byte("AUTHOR(S):")) != -1 {
+ t.Errorf("expected\n%snot to include %s", output.String(), "AUTHOR(S):")
+ }
+}
+
+func Test_ShowAppHelp_NoVersion(t *testing.T) {
+ output := new(bytes.Buffer)
+ app := NewApp()
+ app.Writer = output
+
+ app.Version = ""
+
+ c := NewContext(app, nil, nil)
+
+ ShowAppHelp(c)
+
+ if bytes.Index(output.Bytes(), []byte("VERSION:")) != -1 {
+ t.Errorf("expected\n%snot to include %s", output.String(), "VERSION:")
+ }
+}
+
+func Test_Help_Custom_Flags(t *testing.T) {
+ oldFlag := HelpFlag
+ defer func() {
+ HelpFlag = oldFlag
+ }()
+
+ HelpFlag = BoolFlag{
+ Name: "help, x",
+ Usage: "show help",
+ }
+
+ app := App{
+ Flags: []Flag{
+ BoolFlag{Name: "foo, h"},
+ },
+ Action: func(ctx *Context) {
+ if ctx.Bool("h") != true {
+ t.Errorf("custom help flag not set")
+ }
+ },
+ }
+ output := new(bytes.Buffer)
+ app.Writer = output
+ app.Run([]string{"test", "-h"})
+ if output.Len() > 0 {
+ t.Errorf("unexpected output: %s", output.String())
+ }
+}
+
+func Test_Version_Custom_Flags(t *testing.T) {
+ oldFlag := VersionFlag
+ defer func() {
+ VersionFlag = oldFlag
+ }()
+
+ VersionFlag = BoolFlag{
+ Name: "version, V",
+ Usage: "show version",
+ }
+
+ app := App{
+ Flags: []Flag{
+ BoolFlag{Name: "foo, v"},
+ },
+ Action: func(ctx *Context) {
+ if ctx.Bool("v") != true {
+ t.Errorf("custom version flag not set")
+ }
+ },
+ }
+ output := new(bytes.Buffer)
+ app.Writer = output
+ app.Run([]string{"test", "-v"})
+ if output.Len() > 0 {
+ t.Errorf("unexpected output: %s", output.String())
+ }
+}
http://git-wip-us.apache.org/repos/asf/brooklyn-client/blob/799e9ccb/cli/vendor/github.com/urfave/cli/helpers_test.go
----------------------------------------------------------------------
diff --git a/cli/vendor/github.com/urfave/cli/helpers_test.go b/cli/vendor/github.com/urfave/cli/helpers_test.go
new file mode 100644
index 0000000..b1b7339
--- /dev/null
+++ b/cli/vendor/github.com/urfave/cli/helpers_test.go
@@ -0,0 +1,19 @@
+package cli
+
+import (
+ "reflect"
+ "testing"
+)
+
+/* Test Helpers */
+func expect(t *testing.T, a interface{}, b interface{}) {
+ if !reflect.DeepEqual(a, b) {
+ t.Errorf("Expected %v (type %v) - Got %v (type %v)", b, reflect.TypeOf(b), a, reflect.TypeOf(a))
+ }
+}
+
+func refute(t *testing.T, a interface{}, b interface{}) {
+ if reflect.DeepEqual(a, b) {
+ t.Errorf("Did not expect %v (type %v) - Got %v (type %v)", b, reflect.TypeOf(b), a, reflect.TypeOf(a))
+ }
+}
http://git-wip-us.apache.org/repos/asf/brooklyn-client/blob/799e9ccb/cli/vendor/golang.org/x/crypto/.gitattributes
----------------------------------------------------------------------
diff --git a/cli/vendor/golang.org/x/crypto/.gitattributes b/cli/vendor/golang.org/x/crypto/.gitattributes
new file mode 100644
index 0000000..d2f212e
--- /dev/null
+++ b/cli/vendor/golang.org/x/crypto/.gitattributes
@@ -0,0 +1,10 @@
+# Treat all files in this repo as binary, with no git magic updating
+# line endings. Windows users contributing to Go will need to use a
+# modern version of git and editors capable of LF line endings.
+#
+# We'll prevent accidental CRLF line endings from entering the repo
+# via the git-review gofmt checks.
+#
+# See golang.org/issue/9281
+
+* -text
http://git-wip-us.apache.org/repos/asf/brooklyn-client/blob/799e9ccb/cli/vendor/golang.org/x/crypto/.gitignore
----------------------------------------------------------------------
diff --git a/cli/vendor/golang.org/x/crypto/.gitignore b/cli/vendor/golang.org/x/crypto/.gitignore
new file mode 100644
index 0000000..8339fd6
--- /dev/null
+++ b/cli/vendor/golang.org/x/crypto/.gitignore
@@ -0,0 +1,2 @@
+# Add no patterns to .hgignore except for files generated by the build.
+last-change
http://git-wip-us.apache.org/repos/asf/brooklyn-client/blob/799e9ccb/cli/vendor/golang.org/x/crypto/AUTHORS
----------------------------------------------------------------------
diff --git a/cli/vendor/golang.org/x/crypto/AUTHORS b/cli/vendor/golang.org/x/crypto/AUTHORS
new file mode 100644
index 0000000..15167cd
--- /dev/null
+++ b/cli/vendor/golang.org/x/crypto/AUTHORS
@@ -0,0 +1,3 @@
+# This source code refers to The Go Authors for copyright purposes.
+# The master list of authors is in the main Go distribution,
+# visible at http://tip.golang.org/AUTHORS.
http://git-wip-us.apache.org/repos/asf/brooklyn-client/blob/799e9ccb/cli/vendor/golang.org/x/crypto/CONTRIBUTING.md
----------------------------------------------------------------------
diff --git a/cli/vendor/golang.org/x/crypto/CONTRIBUTING.md b/cli/vendor/golang.org/x/crypto/CONTRIBUTING.md
new file mode 100644
index 0000000..88dff59
--- /dev/null
+++ b/cli/vendor/golang.org/x/crypto/CONTRIBUTING.md
@@ -0,0 +1,31 @@
+# Contributing to Go
+
+Go is an open source project.
+
+It is the work of hundreds of contributors. We appreciate your help!
+
+
+## Filing issues
+
+When [filing an issue](https://golang.org/issue/new), make sure to answer these five questions:
+
+1. What version of Go are you using (`go version`)?
+2. What operating system and processor architecture are you using?
+3. What did you do?
+4. What did you expect to see?
+5. What did you see instead?
+
+General questions should go to the [golang-nuts mailing list](https://groups.google.com/group/golang-nuts) instead of the issue tracker.
+The gophers there will answer or ask you to file an issue if you've tripped over a bug.
+
+## Contributing code
+
+Please read the [Contribution Guidelines](https://golang.org/doc/contribute.html)
+before sending patches.
+
+**We do not accept GitHub pull requests**
+(we use [Gerrit](https://code.google.com/p/gerrit/) instead for code review).
+
+Unless otherwise noted, the Go source files are distributed under
+the BSD-style license found in the LICENSE file.
+
http://git-wip-us.apache.org/repos/asf/brooklyn-client/blob/799e9ccb/cli/vendor/golang.org/x/crypto/CONTRIBUTORS
----------------------------------------------------------------------
diff --git a/cli/vendor/golang.org/x/crypto/CONTRIBUTORS b/cli/vendor/golang.org/x/crypto/CONTRIBUTORS
new file mode 100644
index 0000000..1c4577e
--- /dev/null
+++ b/cli/vendor/golang.org/x/crypto/CONTRIBUTORS
@@ -0,0 +1,3 @@
+# This source code was written by the Go contributors.
+# The master list of contributors is in the main Go distribution,
+# visible at http://tip.golang.org/CONTRIBUTORS.
http://git-wip-us.apache.org/repos/asf/brooklyn-client/blob/799e9ccb/cli/vendor/golang.org/x/crypto/LICENSE
----------------------------------------------------------------------
diff --git a/cli/vendor/golang.org/x/crypto/LICENSE b/cli/vendor/golang.org/x/crypto/LICENSE
new file mode 100644
index 0000000..6a66aea
--- /dev/null
+++ b/cli/vendor/golang.org/x/crypto/LICENSE
@@ -0,0 +1,27 @@
+Copyright (c) 2009 The Go Authors. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+ * Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above
+copyright notice, this list of conditions and the following disclaimer
+in the documentation and/or other materials provided with the
+distribution.
+ * Neither the name of Google Inc. nor the names of its
+contributors may be used to endorse or promote products derived from
+this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
http://git-wip-us.apache.org/repos/asf/brooklyn-client/blob/799e9ccb/cli/vendor/golang.org/x/crypto/PATENTS
----------------------------------------------------------------------
diff --git a/cli/vendor/golang.org/x/crypto/PATENTS b/cli/vendor/golang.org/x/crypto/PATENTS
new file mode 100644
index 0000000..7330990
--- /dev/null
+++ b/cli/vendor/golang.org/x/crypto/PATENTS
@@ -0,0 +1,22 @@
+Additional IP Rights Grant (Patents)
+
+"This implementation" means the copyrightable works distributed by
+Google as part of the Go project.
+
+Google hereby grants to You a perpetual, worldwide, non-exclusive,
+no-charge, royalty-free, irrevocable (except as stated in this section)
+patent license to make, have made, use, offer to sell, sell, import,
+transfer and otherwise run, modify and propagate the contents of this
+implementation of Go, where such license applies only to those patent
+claims, both currently owned or controlled by Google and acquired in
+the future, licensable by Google that are necessarily infringed by this
+implementation of Go. This grant does not include claims that would be
+infringed only as a consequence of further modification of this
+implementation. If you or your agent or exclusive licensee institute or
+order or agree to the institution of patent litigation against any
+entity (including a cross-claim or counterclaim in a lawsuit) alleging
+that this implementation of Go or any code incorporated within this
+implementation of Go constitutes direct or contributory patent
+infringement, or inducement of patent infringement, then any patent
+rights granted to you under this License for this implementation of Go
+shall terminate as of the date such litigation is filed.
http://git-wip-us.apache.org/repos/asf/brooklyn-client/blob/799e9ccb/cli/vendor/golang.org/x/crypto/README
----------------------------------------------------------------------
diff --git a/cli/vendor/golang.org/x/crypto/README b/cli/vendor/golang.org/x/crypto/README
new file mode 100644
index 0000000..f1e0cbf
--- /dev/null
+++ b/cli/vendor/golang.org/x/crypto/README
@@ -0,0 +1,3 @@
+This repository holds supplementary Go cryptography libraries.
+
+To submit changes to this repository, see http://golang.org/doc/contribute.html.
http://git-wip-us.apache.org/repos/asf/brooklyn-client/blob/799e9ccb/cli/vendor/golang.org/x/crypto/bcrypt/base64.go
----------------------------------------------------------------------
diff --git a/cli/vendor/golang.org/x/crypto/bcrypt/base64.go b/cli/vendor/golang.org/x/crypto/bcrypt/base64.go
new file mode 100644
index 0000000..fc31160
--- /dev/null
+++ b/cli/vendor/golang.org/x/crypto/bcrypt/base64.go
@@ -0,0 +1,35 @@
+// Copyright 2011 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 bcrypt
+
+import "encoding/base64"
+
+const alphabet = "./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
+
+var bcEncoding = base64.NewEncoding(alphabet)
+
+func base64Encode(src []byte) []byte {
+ n := bcEncoding.EncodedLen(len(src))
+ dst := make([]byte, n)
+ bcEncoding.Encode(dst, src)
+ for dst[n-1] == '=' {
+ n--
+ }
+ return dst[:n]
+}
+
+func base64Decode(src []byte) ([]byte, error) {
+ numOfEquals := 4 - (len(src) % 4)
+ for i := 0; i < numOfEquals; i++ {
+ src = append(src, '=')
+ }
+
+ dst := make([]byte, bcEncoding.DecodedLen(len(src)))
+ n, err := bcEncoding.Decode(dst, src)
+ if err != nil {
+ return nil, err
+ }
+ return dst[:n], nil
+}
http://git-wip-us.apache.org/repos/asf/brooklyn-client/blob/799e9ccb/cli/vendor/golang.org/x/crypto/bcrypt/bcrypt.go
----------------------------------------------------------------------
diff --git a/cli/vendor/golang.org/x/crypto/bcrypt/bcrypt.go b/cli/vendor/golang.org/x/crypto/bcrypt/bcrypt.go
new file mode 100644
index 0000000..f8b807f
--- /dev/null
+++ b/cli/vendor/golang.org/x/crypto/bcrypt/bcrypt.go
@@ -0,0 +1,294 @@
+// Copyright 2011 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 bcrypt implements Provos and Mazières's bcrypt adaptive hashing
+// algorithm. See http://www.usenix.org/event/usenix99/provos/provos.pdf
+package bcrypt // import "golang.org/x/crypto/bcrypt"
+
+// The code is a port of Provos and Mazières's C implementation.
+import (
+ "crypto/rand"
+ "crypto/subtle"
+ "errors"
+ "fmt"
+ "golang.org/x/crypto/blowfish"
+ "io"
+ "strconv"
+)
+
+const (
+ MinCost int = 4 // the minimum allowable cost as passed in to GenerateFromPassword
+ MaxCost int = 31 // the maximum allowable cost as passed in to GenerateFromPassword
+ DefaultCost int = 10 // the cost that will actually be set if a cost below MinCost is passed into GenerateFromPassword
+)
+
+// The error returned from CompareHashAndPassword when a password and hash do
+// not match.
+var ErrMismatchedHashAndPassword = errors.New("crypto/bcrypt: hashedPassword is not the hash of the given password")
+
+// The error returned from CompareHashAndPassword when a hash is too short to
+// be a bcrypt hash.
+var ErrHashTooShort = errors.New("crypto/bcrypt: hashedSecret too short to be a bcrypted password")
+
+// The error returned from CompareHashAndPassword when a hash was created with
+// a bcrypt algorithm newer than this implementation.
+type HashVersionTooNewError byte
+
+func (hv HashVersionTooNewError) Error() string {
+ return fmt.Sprintf("crypto/bcrypt: bcrypt algorithm version '%c' requested is newer than current version '%c'", byte(hv), majorVersion)
+}
+
+// The error returned from CompareHashAndPassword when a hash starts with something other than '$'
+type InvalidHashPrefixError byte
+
+func (ih InvalidHashPrefixError) Error() string {
+ return fmt.Sprintf("crypto/bcrypt: bcrypt hashes must start with '$', but hashedSecret started with '%c'", byte(ih))
+}
+
+type InvalidCostError int
+
+func (ic InvalidCostError) Error() string {
+ return fmt.Sprintf("crypto/bcrypt: cost %d is outside allowed range (%d,%d)", int(ic), int(MinCost), int(MaxCost))
+}
+
+const (
+ majorVersion = '2'
+ minorVersion = 'a'
+ maxSaltSize = 16
+ maxCryptedHashSize = 23
+ encodedSaltSize = 22
+ encodedHashSize = 31
+ minHashSize = 59
+)
+
+// magicCipherData is an IV for the 64 Blowfish encryption calls in
+// bcrypt(). It's the string "OrpheanBeholderScryDoubt" in big-endian bytes.
+var magicCipherData = []byte{
+ 0x4f, 0x72, 0x70, 0x68,
+ 0x65, 0x61, 0x6e, 0x42,
+ 0x65, 0x68, 0x6f, 0x6c,
+ 0x64, 0x65, 0x72, 0x53,
+ 0x63, 0x72, 0x79, 0x44,
+ 0x6f, 0x75, 0x62, 0x74,
+}
+
+type hashed struct {
+ hash []byte
+ salt []byte
+ cost int // allowed range is MinCost to MaxCost
+ major byte
+ minor byte
+}
+
+// GenerateFromPassword returns the bcrypt hash of the password at the given
+// cost. If the cost given is less than MinCost, the cost will be set to
+// DefaultCost, instead. Use CompareHashAndPassword, as defined in this package,
+// to compare the returned hashed password with its cleartext version.
+func GenerateFromPassword(password []byte, cost int) ([]byte, error) {
+ p, err := newFromPassword(password, cost)
+ if err != nil {
+ return nil, err
+ }
+ return p.Hash(), nil
+}
+
+// CompareHashAndPassword compares a bcrypt hashed password with its possible
+// plaintext equivalent. Returns nil on success, or an error on failure.
+func CompareHashAndPassword(hashedPassword, password []byte) error {
+ p, err := newFromHash(hashedPassword)
+ if err != nil {
+ return err
+ }
+
+ otherHash, err := bcrypt(password, p.cost, p.salt)
+ if err != nil {
+ return err
+ }
+
+ otherP := &hashed{otherHash, p.salt, p.cost, p.major, p.minor}
+ if subtle.ConstantTimeCompare(p.Hash(), otherP.Hash()) == 1 {
+ return nil
+ }
+
+ return ErrMismatchedHashAndPassword
+}
+
+// Cost returns the hashing cost used to create the given hashed
+// password. When, in the future, the hashing cost of a password system needs
+// to be increased in order to adjust for greater computational power, this
+// function allows one to establish which passwords need to be updated.
+func Cost(hashedPassword []byte) (int, error) {
+ p, err := newFromHash(hashedPassword)
+ if err != nil {
+ return 0, err
+ }
+ return p.cost, nil
+}
+
+func newFromPassword(password []byte, cost int) (*hashed, error) {
+ if cost < MinCost {
+ cost = DefaultCost
+ }
+ p := new(hashed)
+ p.major = majorVersion
+ p.minor = minorVersion
+
+ err := checkCost(cost)
+ if err != nil {
+ return nil, err
+ }
+ p.cost = cost
+
+ unencodedSalt := make([]byte, maxSaltSize)
+ _, err = io.ReadFull(rand.Reader, unencodedSalt)
+ if err != nil {
+ return nil, err
+ }
+
+ p.salt = base64Encode(unencodedSalt)
+ hash, err := bcrypt(password, p.cost, p.salt)
+ if err != nil {
+ return nil, err
+ }
+ p.hash = hash
+ return p, err
+}
+
+func newFromHash(hashedSecret []byte) (*hashed, error) {
+ if len(hashedSecret) < minHashSize {
+ return nil, ErrHashTooShort
+ }
+ p := new(hashed)
+ n, err := p.decodeVersion(hashedSecret)
+ if err != nil {
+ return nil, err
+ }
+ hashedSecret = hashedSecret[n:]
+ n, err = p.decodeCost(hashedSecret)
+ if err != nil {
+ return nil, err
+ }
+ hashedSecret = hashedSecret[n:]
+
+ // The "+2" is here because we'll have to append at most 2 '=' to the salt
+ // when base64 decoding it in expensiveBlowfishSetup().
+ p.salt = make([]byte, encodedSaltSize, encodedSaltSize+2)
+ copy(p.salt, hashedSecret[:encodedSaltSize])
+
+ hashedSecret = hashedSecret[encodedSaltSize:]
+ p.hash = make([]byte, len(hashedSecret))
+ copy(p.hash, hashedSecret)
+
+ return p, nil
+}
+
+func bcrypt(password []byte, cost int, salt []byte) ([]byte, error) {
+ cipherData := make([]byte, len(magicCipherData))
+ copy(cipherData, magicCipherData)
+
+ c, err := expensiveBlowfishSetup(password, uint32(cost), salt)
+ if err != nil {
+ return nil, err
+ }
+
+ for i := 0; i < 24; i += 8 {
+ for j := 0; j < 64; j++ {
+ c.Encrypt(cipherData[i:i+8], cipherData[i:i+8])
+ }
+ }
+
+ // Bug compatibility with C bcrypt implementations. We only encode 23 of
+ // the 24 bytes encrypted.
+ hsh := base64Encode(cipherData[:maxCryptedHashSize])
+ return hsh, nil
+}
+
+func expensiveBlowfishSetup(key []byte, cost uint32, salt []byte) (*blowfish.Cipher, error) {
+
+ csalt, err := base64Decode(salt)
+ if err != nil {
+ return nil, err
+ }
+
+ // Bug compatibility with C bcrypt implementations. They use the trailing
+ // NULL in the key string during expansion.
+ ckey := append(key, 0)
+
+ c, err := blowfish.NewSaltedCipher(ckey, csalt)
+ if err != nil {
+ return nil, err
+ }
+
+ var i, rounds uint64
+ rounds = 1 << cost
+ for i = 0; i < rounds; i++ {
+ blowfish.ExpandKey(ckey, c)
+ blowfish.ExpandKey(csalt, c)
+ }
+
+ return c, nil
+}
+
+func (p *hashed) Hash() []byte {
+ arr := make([]byte, 60)
+ arr[0] = '$'
+ arr[1] = p.major
+ n := 2
+ if p.minor != 0 {
+ arr[2] = p.minor
+ n = 3
+ }
+ arr[n] = '$'
+ n += 1
+ copy(arr[n:], []byte(fmt.Sprintf("%02d", p.cost)))
+ n += 2
+ arr[n] = '$'
+ n += 1
+ copy(arr[n:], p.salt)
+ n += encodedSaltSize
+ copy(arr[n:], p.hash)
+ n += encodedHashSize
+ return arr[:n]
+}
+
+func (p *hashed) decodeVersion(sbytes []byte) (int, error) {
+ if sbytes[0] != '$' {
+ return -1, InvalidHashPrefixError(sbytes[0])
+ }
+ if sbytes[1] > majorVersion {
+ return -1, HashVersionTooNewError(sbytes[1])
+ }
+ p.major = sbytes[1]
+ n := 3
+ if sbytes[2] != '$' {
+ p.minor = sbytes[2]
+ n++
+ }
+ return n, nil
+}
+
+// sbytes should begin where decodeVersion left off.
+func (p *hashed) decodeCost(sbytes []byte) (int, error) {
+ cost, err := strconv.Atoi(string(sbytes[0:2]))
+ if err != nil {
+ return -1, err
+ }
+ err = checkCost(cost)
+ if err != nil {
+ return -1, err
+ }
+ p.cost = cost
+ return 3, nil
+}
+
+func (p *hashed) String() string {
+ return fmt.Sprintf("&{hash: %#v, salt: %#v, cost: %d, major: %c, minor: %c}", string(p.hash), p.salt, p.cost, p.major, p.minor)
+}
+
+func checkCost(cost int) error {
+ if cost < MinCost || cost > MaxCost {
+ return InvalidCostError(cost)
+ }
+ return nil
+}
http://git-wip-us.apache.org/repos/asf/brooklyn-client/blob/799e9ccb/cli/vendor/golang.org/x/crypto/bcrypt/bcrypt_test.go
----------------------------------------------------------------------
diff --git a/cli/vendor/golang.org/x/crypto/bcrypt/bcrypt_test.go b/cli/vendor/golang.org/x/crypto/bcrypt/bcrypt_test.go
new file mode 100644
index 0000000..f08a6f5
--- /dev/null
+++ b/cli/vendor/golang.org/x/crypto/bcrypt/bcrypt_test.go
@@ -0,0 +1,226 @@
+// Copyright 2011 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 bcrypt
+
+import (
+ "bytes"
+ "fmt"
+ "testing"
+)
+
+func TestBcryptingIsEasy(t *testing.T) {
+ pass := []byte("mypassword")
+ hp, err := GenerateFromPassword(pass, 0)
+ if err != nil {
+ t.Fatalf("GenerateFromPassword error: %s", err)
+ }
+
+ if CompareHashAndPassword(hp, pass) != nil {
+ t.Errorf("%v should hash %s correctly", hp, pass)
+ }
+
+ notPass := "notthepass"
+ err = CompareHashAndPassword(hp, []byte(notPass))
+ if err != ErrMismatchedHashAndPassword {
+ t.Errorf("%v and %s should be mismatched", hp, notPass)
+ }
+}
+
+func TestBcryptingIsCorrect(t *testing.T) {
+ pass := []byte("allmine")
+ salt := []byte("XajjQvNhvvRt5GSeFk1xFe")
+ expectedHash := []byte("$2a$10$XajjQvNhvvRt5GSeFk1xFeyqRrsxkhBkUiQeg0dt.wU1qD4aFDcga")
+
+ hash, err := bcrypt(pass, 10, salt)
+ if err != nil {
+ t.Fatalf("bcrypt blew up: %v", err)
+ }
+ if !bytes.HasSuffix(expectedHash, hash) {
+ t.Errorf("%v should be the suffix of %v", hash, expectedHash)
+ }
+
+ h, err := newFromHash(expectedHash)
+ if err != nil {
+ t.Errorf("Unable to parse %s: %v", string(expectedHash), err)
+ }
+
+ // This is not the safe way to compare these hashes. We do this only for
+ // testing clarity. Use bcrypt.CompareHashAndPassword()
+ if err == nil && !bytes.Equal(expectedHash, h.Hash()) {
+ t.Errorf("Parsed hash %v should equal %v", h.Hash(), expectedHash)
+ }
+}
+
+func TestVeryShortPasswords(t *testing.T) {
+ key := []byte("k")
+ salt := []byte("XajjQvNhvvRt5GSeFk1xFe")
+ _, err := bcrypt(key, 10, salt)
+ if err != nil {
+ t.Errorf("One byte key resulted in error: %s", err)
+ }
+}
+
+func TestTooLongPasswordsWork(t *testing.T) {
+ salt := []byte("XajjQvNhvvRt5GSeFk1xFe")
+ // One byte over the usual 56 byte limit that blowfish has
+ tooLongPass := []byte("012345678901234567890123456789012345678901234567890123456")
+ tooLongExpected := []byte("$2a$10$XajjQvNhvvRt5GSeFk1xFe5l47dONXg781AmZtd869sO8zfsHuw7C")
+ hash, err := bcrypt(tooLongPass, 10, salt)
+ if err != nil {
+ t.Fatalf("bcrypt blew up on long password: %v", err)
+ }
+ if !bytes.HasSuffix(tooLongExpected, hash) {
+ t.Errorf("%v should be the suffix of %v", hash, tooLongExpected)
+ }
+}
+
+type InvalidHashTest struct {
+ err error
+ hash []byte
+}
+
+var invalidTests = []InvalidHashTest{
+ {ErrHashTooShort, []byte("$2a$10$fooo")},
+ {ErrHashTooShort, []byte("$2a")},
+ {HashVersionTooNewError('3'), []byte("$3a$10$sssssssssssssssssssssshhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh")},
+ {InvalidHashPrefixError('%'), []byte("%2a$10$sssssssssssssssssssssshhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh")},
+ {InvalidCostError(32), []byte("$2a$32$sssssssssssssssssssssshhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh")},
+}
+
+func TestInvalidHashErrors(t *testing.T) {
+ check := func(name string, expected, err error) {
+ if err == nil {
+ t.Errorf("%s: Should have returned an error", name)
+ }
+ if err != nil && err != expected {
+ t.Errorf("%s gave err %v but should have given %v", name, err, expected)
+ }
+ }
+ for _, iht := range invalidTests {
+ _, err := newFromHash(iht.hash)
+ check("newFromHash", iht.err, err)
+ err = CompareHashAndPassword(iht.hash, []byte("anything"))
+ check("CompareHashAndPassword", iht.err, err)
+ }
+}
+
+func TestUnpaddedBase64Encoding(t *testing.T) {
+ original := []byte{101, 201, 101, 75, 19, 227, 199, 20, 239, 236, 133, 32, 30, 109, 243, 30}
+ encodedOriginal := []byte("XajjQvNhvvRt5GSeFk1xFe")
+
+ encoded := base64Encode(original)
+
+ if !bytes.Equal(encodedOriginal, encoded) {
+ t.Errorf("Encoded %v should have equaled %v", encoded, encodedOriginal)
+ }
+
+ decoded, err := base64Decode(encodedOriginal)
+ if err != nil {
+ t.Fatalf("base64Decode blew up: %s", err)
+ }
+
+ if !bytes.Equal(decoded, original) {
+ t.Errorf("Decoded %v should have equaled %v", decoded, original)
+ }
+}
+
+func TestCost(t *testing.T) {
+ suffix := "XajjQvNhvvRt5GSeFk1xFe5l47dONXg781AmZtd869sO8zfsHuw7C"
+ for _, vers := range []string{"2a", "2"} {
+ for _, cost := range []int{4, 10} {
+ s := fmt.Sprintf("$%s$%02d$%s", vers, cost, suffix)
+ h := []byte(s)
+ actual, err := Cost(h)
+ if err != nil {
+ t.Errorf("Cost, error: %s", err)
+ continue
+ }
+ if actual != cost {
+ t.Errorf("Cost, expected: %d, actual: %d", cost, actual)
+ }
+ }
+ }
+ _, err := Cost([]byte("$a$a$" + suffix))
+ if err == nil {
+ t.Errorf("Cost, malformed but no error returned")
+ }
+}
+
+func TestCostValidationInHash(t *testing.T) {
+ if testing.Short() {
+ return
+ }
+
+ pass := []byte("mypassword")
+
+ for c := 0; c < MinCost; c++ {
+ p, _ := newFromPassword(pass, c)
+ if p.cost != DefaultCost {
+ t.Errorf("newFromPassword should default costs below %d to %d, but was %d", MinCost, DefaultCost, p.cost)
+ }
+ }
+
+ p, _ := newFromPassword(pass, 14)
+ if p.cost != 14 {
+ t.Errorf("newFromPassword should default cost to 14, but was %d", p.cost)
+ }
+
+ hp, _ := newFromHash(p.Hash())
+ if p.cost != hp.cost {
+ t.Errorf("newFromHash should maintain the cost at %d, but was %d", p.cost, hp.cost)
+ }
+
+ _, err := newFromPassword(pass, 32)
+ if err == nil {
+ t.Fatalf("newFromPassword: should return a cost error")
+ }
+ if err != InvalidCostError(32) {
+ t.Errorf("newFromPassword: should return cost error, got %#v", err)
+ }
+}
+
+func TestCostReturnsWithLeadingZeroes(t *testing.T) {
+ hp, _ := newFromPassword([]byte("abcdefgh"), 7)
+ cost := hp.Hash()[4:7]
+ expected := []byte("07$")
+
+ if !bytes.Equal(expected, cost) {
+ t.Errorf("single digit costs in hash should have leading zeros: was %v instead of %v", cost, expected)
+ }
+}
+
+func TestMinorNotRequired(t *testing.T) {
+ noMinorHash := []byte("$2$10$XajjQvNhvvRt5GSeFk1xFeyqRrsxkhBkUiQeg0dt.wU1qD4aFDcga")
+ h, err := newFromHash(noMinorHash)
+ if err != nil {
+ t.Fatalf("No minor hash blew up: %s", err)
+ }
+ if h.minor != 0 {
+ t.Errorf("Should leave minor version at 0, but was %d", h.minor)
+ }
+
+ if !bytes.Equal(noMinorHash, h.Hash()) {
+ t.Errorf("Should generate hash %v, but created %v", noMinorHash, h.Hash())
+ }
+}
+
+func BenchmarkEqual(b *testing.B) {
+ b.StopTimer()
+ passwd := []byte("somepasswordyoulike")
+ hash, _ := GenerateFromPassword(passwd, 10)
+ b.StartTimer()
+ for i := 0; i < b.N; i++ {
+ CompareHashAndPassword(hash, passwd)
+ }
+}
+
+func BenchmarkGeneration(b *testing.B) {
+ b.StopTimer()
+ passwd := []byte("mylongpassword1234")
+ b.StartTimer()
+ for i := 0; i < b.N; i++ {
+ GenerateFromPassword(passwd, 10)
+ }
+}