From 3caadb37ac972caf14d482a7230b5547c48061b0 Mon Sep 17 00:00:00 2001 From: Frank Schroeder Date: Tue, 23 May 2017 19:35:23 +0200 Subject: [PATCH] vendor: update github.com/mitchellh/cli This pulls in the patch that fixes the nil panic and the data race in MockUi. --- vendor/github.com/mitchellh/cli/README.md | 7 ++- vendor/github.com/mitchellh/cli/cli.go | 53 ++++++++++++++------- vendor/github.com/mitchellh/cli/help.go | 4 +- vendor/github.com/mitchellh/cli/ui_mock.go | 55 +++++++++++++++++++--- vendor/vendor.json | 6 +-- 5 files changed, 96 insertions(+), 29 deletions(-) diff --git a/vendor/github.com/mitchellh/cli/README.md b/vendor/github.com/mitchellh/cli/README.md index 287ecb2469..dd211cf0e7 100644 --- a/vendor/github.com/mitchellh/cli/README.md +++ b/vendor/github.com/mitchellh/cli/README.md @@ -3,8 +3,11 @@ cli is a library for implementing powerful command-line interfaces in Go. cli is the library that powers the CLI for [Packer](https://github.com/mitchellh/packer), -[Serf](https://github.com/hashicorp/serf), and -[Consul](https://github.com/hashicorp/consul). +[Serf](https://github.com/hashicorp/serf), +[Consul](https://github.com/hashicorp/consul), +[Vault](https://github.com/hashicorp/vault), +[Terraform](https://github.com/hashicorp/terraform), and +[Nomad](https://github.com/hashicorp/nomad). ## Features diff --git a/vendor/github.com/mitchellh/cli/cli.go b/vendor/github.com/mitchellh/cli/cli.go index bd663671d4..4a69d176db 100644 --- a/vendor/github.com/mitchellh/cli/cli.go +++ b/vendor/github.com/mitchellh/cli/cli.go @@ -4,6 +4,7 @@ import ( "fmt" "io" "os" + "regexp" "sort" "strings" "sync" @@ -24,7 +25,7 @@ import ( // // * We use longest prefix matching to find a matching subcommand. This // means if you register "foo bar" and the user executes "cli foo qux", -// the "foo" commmand will be executed with the arg "qux". It is up to +// the "foo" command will be executed with the arg "qux". It is up to // you to handle these args. One option is to just return the special // help return code `RunResultHelp` to display help and exit. // @@ -119,7 +120,13 @@ func (c *CLI) Run() (int, error) { // Just show the version and exit if instructed. if c.IsVersion() && c.Version != "" { c.HelpWriter.Write([]byte(c.Version + "\n")) - return 1, nil + return 0, nil + } + + // Just print the help when only '-h' or '--help' is passed. + if c.IsHelp() && c.Subcommand() == "" { + c.HelpWriter.Write([]byte(c.HelpFunc(c.Commands) + "\n")) + return 0, nil } // Attempt to get the factory function for creating the command @@ -132,13 +139,13 @@ func (c *CLI) Run() (int, error) { command, err := raw.(CommandFactory)() if err != nil { - return 0, err + return 1, err } // If we've been instructed to just print the help, then print it if c.IsHelp() { c.commandHelp(command) - return 1, nil + return 0, nil } // If there is an invalid flag, then error @@ -249,7 +256,7 @@ func (c *CLI) init() { c.commandTree.Walk(walkFn) // Insert any that we're missing - for k, _ := range toInsert { + for k := range toInsert { var f CommandFactory = func() (Command, error) { return &MockCommand{ HelpText: "This command is accessed by using one of the subcommands below.", @@ -387,16 +394,22 @@ func (c *CLI) helpCommands(prefix string) map[string]CommandFactory { func (c *CLI) processArgs() { for i, arg := range c.Args { + if arg == "--" { + break + } + + // Check for help flags. + if arg == "-h" || arg == "-help" || arg == "--help" { + c.isHelp = true + continue + } + if c.subcommand == "" { - // Check for version and help flags if not in a subcommand + // Check for version flags if not in a subcommand. if arg == "-v" || arg == "-version" || arg == "--version" { c.isVersion = true continue } - if arg == "-h" || arg == "-help" || arg == "--help" { - c.isHelp = true - continue - } if arg != "" && arg[0] == '-' { // Record the arg... @@ -405,16 +418,24 @@ func (c *CLI) processArgs() { } // If we didn't find a subcommand yet and this is the first non-flag - // argument, then this is our subcommand. j + // argument, then this is our subcommand. if c.subcommand == "" && arg != "" && arg[0] != '-' { c.subcommand = arg if c.commandNested { // Nested CLI, the subcommand is actually the entire // arg list up to a flag that is still a valid subcommand. - k, _, ok := c.commandTree.LongestPrefix(strings.Join(c.Args[i:], " ")) + searchKey := strings.Join(c.Args[i:], " ") + k, _, ok := c.commandTree.LongestPrefix(searchKey) if ok { - c.subcommand = k - i += strings.Count(k, " ") + // k could be a prefix that doesn't contain the full + // command such as "foo" instead of "foobar", so we + // need to verify that we have an entire key. To do that, + // we look for an ending in a space or an end of string. + reVerify := regexp.MustCompile(regexp.QuoteMeta(k) + `( |$)`) + if reVerify.MatchString(searchKey) { + c.subcommand = k + i += strings.Count(k, " ") + } } } @@ -439,7 +460,7 @@ const defaultHelpTemplate = ` {{.Help}}{{if gt (len .Subcommands) 0}} Subcommands: -{{ range $value := .Subcommands }} +{{- range $value := .Subcommands }} {{ $value.NameAligned }} {{ $value.Synopsis }}{{ end }} -{{ end }} +{{- end }} ` diff --git a/vendor/github.com/mitchellh/cli/help.go b/vendor/github.com/mitchellh/cli/help.go index 67ea8c8244..f5ca58f595 100644 --- a/vendor/github.com/mitchellh/cli/help.go +++ b/vendor/github.com/mitchellh/cli/help.go @@ -18,7 +18,7 @@ func BasicHelpFunc(app string) HelpFunc { return func(commands map[string]CommandFactory) string { var buf bytes.Buffer buf.WriteString(fmt.Sprintf( - "usage: %s [--version] [--help] []\n\n", + "Usage: %s [--version] [--help] []\n\n", app)) buf.WriteString("Available commands are:\n") @@ -26,7 +26,7 @@ func BasicHelpFunc(app string) HelpFunc { // key length so they can be aligned properly. keys := make([]string, 0, len(commands)) maxKeyLen := 0 - for key, _ := range commands { + for key := range commands { if len(key) > maxKeyLen { maxKeyLen = len(key) } diff --git a/vendor/github.com/mitchellh/cli/ui_mock.go b/vendor/github.com/mitchellh/cli/ui_mock.go index c46772855e..bdae2a6646 100644 --- a/vendor/github.com/mitchellh/cli/ui_mock.go +++ b/vendor/github.com/mitchellh/cli/ui_mock.go @@ -7,12 +7,25 @@ import ( "sync" ) -// MockUi is a mock UI that is used for tests and is exported publicly for -// use in external tests if needed as well. +// NewMockUi returns a fully initialized MockUi instance +// which is safe for concurrent use. +func NewMockUi() *MockUi { + m := new(MockUi) + m.once.Do(m.init) + return m +} + +// MockUi is a mock UI that is used for tests and is exported publicly +// for use in external tests if needed as well. Do not instantite this +// directly since the buffers will be initialized on the first write. If +// there is no write then you will get a nil panic. Please use the +// NewMockUi() constructor function instead. You can fix your code with +// +// sed -i -e 's/new(cli.MockUi)/cli.NewMockUi()/g' *_test.go type MockUi struct { InputReader io.Reader - ErrorWriter *bytes.Buffer - OutputWriter *bytes.Buffer + ErrorWriter *syncBuffer + OutputWriter *syncBuffer once sync.Once } @@ -59,6 +72,36 @@ func (u *MockUi) Warn(message string) { } func (u *MockUi) init() { - u.ErrorWriter = new(bytes.Buffer) - u.OutputWriter = new(bytes.Buffer) + u.ErrorWriter = new(syncBuffer) + u.OutputWriter = new(syncBuffer) +} + +type syncBuffer struct { + sync.RWMutex + b bytes.Buffer +} + +func (b *syncBuffer) Write(data []byte) (int, error) { + b.Lock() + defer b.Unlock() + return b.b.Write(data) +} + +func (b *syncBuffer) Read(data []byte) (int, error) { + b.RLock() + defer b.RUnlock() + return b.b.Read(data) +} + +func (b *syncBuffer) Reset() { + b.Lock() + b.b.Reset() + b.Unlock() +} + +func (b *syncBuffer) String() string { + b.RLock() + data := b.b.Bytes() + b.RUnlock() + return string(data) } diff --git a/vendor/vendor.json b/vendor/vendor.json index 8f2c0ce3a8..2c94b924ad 100644 --- a/vendor/vendor.json +++ b/vendor/vendor.json @@ -706,10 +706,10 @@ "revisionTime": "2016-07-26T03:20:27Z" }, { - "checksumSHA1": "yF39M9MGatDbq2d2oqlLy44jsRc=", + "checksumSHA1": "bUuI7AVR3IZPLlBaEKmw/ke7wqA=", "path": "github.com/mitchellh/cli", - "revision": "168daae10d6ff81b8b1201b0a4c9607d7e9b82e3", - "revisionTime": "2016-03-23T17:07:00Z" + "revision": "b481eac70eea3ad671b7c360a013f89bb759b252", + "revisionTime": "2017-05-23T17:27:49Z" }, { "checksumSHA1": "86nE93o1VIND0Doe8PuhCXnhUx0=",