diff --git a/vendor/github.com/mitchellh/cli/README.md b/vendor/github.com/mitchellh/cli/README.md index dd211cf0e..8f02cdd0a 100644 --- a/vendor/github.com/mitchellh/cli/README.md +++ b/vendor/github.com/mitchellh/cli/README.md @@ -18,6 +18,9 @@ cli is the library that powers the CLI for * Optional support for default subcommands so `cli` does something other than error. +* Support for shell autocompletion of subcommands, flags, and arguments + with callbacks in Go. You don't need to write any shell code. + * Automatic help generation for listing subcommands * Automatic help flag recognition of `-h`, `--help`, etc. diff --git a/vendor/github.com/mitchellh/cli/autocomplete.go b/vendor/github.com/mitchellh/cli/autocomplete.go new file mode 100644 index 000000000..3bec6258f --- /dev/null +++ b/vendor/github.com/mitchellh/cli/autocomplete.go @@ -0,0 +1,43 @@ +package cli + +import ( + "github.com/posener/complete/cmd/install" +) + +// autocompleteInstaller is an interface to be implemented to perform the +// autocomplete installation and uninstallation with a CLI. +// +// This interface is not exported because it only exists for unit tests +// to be able to test that the installation is called properly. +type autocompleteInstaller interface { + Install(string) error + Uninstall(string) error +} + +// realAutocompleteInstaller uses the real install package to do the +// install/uninstall. +type realAutocompleteInstaller struct{} + +func (i *realAutocompleteInstaller) Install(cmd string) error { + return install.Install(cmd) +} + +func (i *realAutocompleteInstaller) Uninstall(cmd string) error { + return install.Uninstall(cmd) +} + +// mockAutocompleteInstaller is used for tests to record the install/uninstall. +type mockAutocompleteInstaller struct { + InstallCalled bool + UninstallCalled bool +} + +func (i *mockAutocompleteInstaller) Install(cmd string) error { + i.InstallCalled = true + return nil +} + +func (i *mockAutocompleteInstaller) Uninstall(cmd string) error { + i.UninstallCalled = true + return nil +} diff --git a/vendor/github.com/mitchellh/cli/cli.go b/vendor/github.com/mitchellh/cli/cli.go index 6051ad57a..651a0b283 100644 --- a/vendor/github.com/mitchellh/cli/cli.go +++ b/vendor/github.com/mitchellh/cli/cli.go @@ -11,6 +11,7 @@ import ( "text/template" "github.com/armon/go-radix" + "github.com/posener/complete" ) // CLI contains the state necessary to run subcommands and parse the @@ -66,6 +67,36 @@ type CLI struct { // Version of the CLI. Version string + // Autocomplete enables or disables subcommand auto-completion support. + // This is enabled by default when NewCLI is called. Otherwise, this + // must enabled explicitly. + // + // Autocomplete requires the "Name" option to be set on CLI. This name + // should be set exactly to the binary name that is autocompleted. + // + // Autocompletion is supported via the github.com/posener/complete + // library. This library supports both bash and zsh. To add support + // for other shells, please see that library. + // + // AutocompleteInstall and AutocompleteUninstall are the global flag + // names for installing and uninstalling the autocompletion handlers + // for the user's shell. The flag should omit the hyphen(s) in front of + // the value. Both single and double hyphens will automatically be supported + // for the flag name. These default to `autocomplete-install` and + // `autocomplete-uninstall` respectively. + // + // AutocompleteNoDefaultFlags is a boolean which controls if the default auto- + // complete flags like -help and -version are added to the output. + // + // AutocompleteGlobalFlags are a mapping of global flags for + // autocompletion. The help and version flags are automatically added. + Autocomplete bool + AutocompleteInstall string + AutocompleteUninstall string + AutocompleteNoDefaultFlags bool + AutocompleteGlobalFlags complete.Flags + autocompleteInstaller autocompleteInstaller // For tests + // HelpFunc and HelpWriter are used to output help information, if // requested. // @@ -78,23 +109,32 @@ type CLI struct { HelpFunc HelpFunc HelpWriter io.Writer + //--------------------------------------------------------------- + // Internal fields set automatically + once sync.Once + autocomplete *complete.Complete commandTree *radix.Tree commandNested bool - isHelp bool subcommand string subcommandArgs []string topFlags []string - isVersion bool + // These are true when special global flags are set. We can/should + // probably use a bitset for this one day. + isHelp bool + isVersion bool + isAutocompleteInstall bool + isAutocompleteUninstall bool } // NewClI returns a new CLI instance with sensible defaults. func NewCLI(app, version string) *CLI { return &CLI{ - Name: app, - Version: version, - HelpFunc: BasicHelpFunc(app), + Name: app, + Version: version, + HelpFunc: BasicHelpFunc(app), + Autocomplete: true, } } @@ -117,6 +157,14 @@ func (c *CLI) IsVersion() bool { func (c *CLI) Run() (int, error) { c.once.Do(c.init) + // If this is a autocompletion request, satisfy it. This must be called + // first before anything else since its possible to be autocompleting + // -help or -version or other flags and we want to show completions + // and not actually write the help or version. + if c.Autocomplete && c.autocomplete.Complete() { + return 0, nil + } + // Just show the version and exit if instructed. if c.IsVersion() && c.Version != "" { c.HelpWriter.Write([]byte(c.Version + "\n")) @@ -125,10 +173,44 @@ func (c *CLI) Run() (int, error) { // 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")) + c.HelpWriter.Write([]byte(c.HelpFunc(c.helpCommands(c.Subcommand())) + "\n")) return 0, nil } + // If we're attempting to install or uninstall autocomplete then handle + if c.Autocomplete { + // Autocomplete requires the "Name" to be set so that we know what + // command to setup the autocomplete on. + if c.Name == "" { + return 1, fmt.Errorf( + "internal error: CLI.Name must be specified for autocomplete to work") + } + + // If both install and uninstall flags are specified, then error + if c.isAutocompleteInstall && c.isAutocompleteUninstall { + return 1, fmt.Errorf( + "Either the autocomplete install or uninstall flag may " + + "be specified, but not both.") + } + + // If the install flag is specified, perform the install or uninstall + if c.isAutocompleteInstall { + if err := c.autocompleteInstaller.Install(c.Name); err != nil { + return 1, err + } + + return 0, nil + } + + if c.isAutocompleteUninstall { + if err := c.autocompleteInstaller.Uninstall(c.Name); err != nil { + return 1, err + } + + return 0, nil + } + } + // Attempt to get the factory function for creating the command // implementation. If the command is invalid or blank, it is an error. raw, ok := c.commandTree.Get(c.Subcommand()) @@ -268,10 +350,108 @@ func (c *CLI) init() { } } + // Setup autocomplete if we have it enabled. We have to do this after + // the command tree is setup so we can use the radix tree to easily find + // all subcommands. + if c.Autocomplete { + c.initAutocomplete() + } + // Process the args c.processArgs() } +func (c *CLI) initAutocomplete() { + if c.AutocompleteInstall == "" { + c.AutocompleteInstall = defaultAutocompleteInstall + } + + if c.AutocompleteUninstall == "" { + c.AutocompleteUninstall = defaultAutocompleteUninstall + } + + if c.autocompleteInstaller == nil { + c.autocompleteInstaller = &realAutocompleteInstaller{} + } + + // Build the root command + cmd := c.initAutocompleteSub("") + + // For the root, we add the global flags to the "Flags". This way + // they don't show up on every command. + if !c.AutocompleteNoDefaultFlags { + cmd.Flags = map[string]complete.Predictor{ + "-" + c.AutocompleteInstall: complete.PredictNothing, + "-" + c.AutocompleteUninstall: complete.PredictNothing, + "-help": complete.PredictNothing, + "-version": complete.PredictNothing, + } + } + cmd.GlobalFlags = c.AutocompleteGlobalFlags + + c.autocomplete = complete.New(c.Name, cmd) +} + +// initAutocompleteSub creates the complete.Command for a subcommand with +// the given prefix. This will continue recursively for all subcommands. +// The prefix "" (empty string) can be used for the root command. +func (c *CLI) initAutocompleteSub(prefix string) complete.Command { + var cmd complete.Command + walkFn := func(k string, raw interface{}) bool { + // Keep track of the full key so that we can nest further if necessary + fullKey := k + + if len(prefix) > 0 { + // If we have a prefix, trim the prefix + 1 (for the space) + // Example: turns "sub one" to "one" with prefix "sub" + k = k[len(prefix)+1:] + } + + if idx := strings.Index(k, " "); idx >= 0 { + // If there is a space, we trim up to the space. This turns + // "sub sub2 sub3" into "sub". The prefix trim above will + // trim our current depth properly. + k = k[:idx] + } + + if _, ok := cmd.Sub[k]; ok { + // If we already tracked this subcommand then ignore + return false + } + + if cmd.Sub == nil { + cmd.Sub = complete.Commands(make(map[string]complete.Command)) + } + subCmd := c.initAutocompleteSub(fullKey) + + // Instantiate the command so that we can check if the command is + // a CommandAutocomplete implementation. If there is an error + // creating the command, we just ignore it since that will be caught + // later. + impl, err := raw.(CommandFactory)() + if err != nil { + impl = nil + } + + // Check if it implements ComandAutocomplete. If so, setup the autocomplete + if c, ok := impl.(CommandAutocomplete); ok { + subCmd.Args = c.AutocompleteArgs() + subCmd.Flags = c.AutocompleteFlags() + } + + cmd.Sub[k] = subCmd + return false + } + + walkPrefix := prefix + if walkPrefix != "" { + walkPrefix += " " + } + + c.commandTree.WalkPrefix(walkPrefix, walkFn) + return cmd +} + func (c *CLI) commandHelp(command Command) { // Get the template to use tpl := strings.TrimSpace(defaultHelpTemplate) @@ -398,6 +578,25 @@ func (c *CLI) processArgs() { break } + // Check for help flags. + if arg == "-h" || arg == "-help" || arg == "--help" { + c.isHelp = true + continue + } + + // Check for autocomplete flags + if c.Autocomplete { + if arg == "-"+c.AutocompleteInstall || arg == "--"+c.AutocompleteInstall { + c.isAutocompleteInstall = true + continue + } + + if arg == "-"+c.AutocompleteUninstall || arg == "--"+c.AutocompleteUninstall { + c.isAutocompleteUninstall = true + continue + } + } + if c.subcommand == "" { // Check for version flags if not in a subcommand. if arg == "-v" || arg == "-version" || arg == "--version" { @@ -405,12 +604,6 @@ func (c *CLI) processArgs() { continue } - // Check for help flags. - if arg == "-h" || arg == "-help" || arg == "--help" { - c.isHelp = true - continue - } - if arg != "" && arg[0] == '-' { // Record the arg... c.topFlags = append(c.topFlags, arg) @@ -456,6 +649,11 @@ func (c *CLI) processArgs() { } } +// defaultAutocompleteInstall and defaultAutocompleteUninstall are the +// default values for the autocomplete install and uninstall flags. +const defaultAutocompleteInstall = "autocomplete-install" +const defaultAutocompleteUninstall = "autocomplete-uninstall" + const defaultHelpTemplate = ` {{.Help}}{{if gt (len .Subcommands) 0}} diff --git a/vendor/github.com/mitchellh/cli/command.go b/vendor/github.com/mitchellh/cli/command.go index b4924eb00..bed11faf5 100644 --- a/vendor/github.com/mitchellh/cli/command.go +++ b/vendor/github.com/mitchellh/cli/command.go @@ -1,5 +1,9 @@ package cli +import ( + "github.com/posener/complete" +) + const ( // RunResultHelp is a value that can be returned from Run to signal // to the CLI to render the help output. @@ -26,6 +30,22 @@ type Command interface { Synopsis() string } +// CommandAutocomplete is an extension of Command that enables fine-grained +// autocompletion. Subcommand autocompletion will work even if this interface +// is not implemented. By implementing this interface, more advanced +// autocompletion is enabled. +type CommandAutocomplete interface { + // AutocompleteArgs returns the argument predictor for this command. + // If argument completion is not supported, this should return + // complete.PredictNothing. + AutocompleteArgs() complete.Predictor + + // AutocompleteFlags returns a mapping of supported flags and autocomplete + // options for this command. The map key for the Flags map should be the + // complete flag such as "-foo" or "--foo". + AutocompleteFlags() complete.Flags +} + // CommandHelpTemplate is an extension of Command that also has a function // for returning a template for the help rather than the help itself. In // this scenario, both Help and HelpTemplate should be implemented. diff --git a/vendor/github.com/mitchellh/cli/command_mock.go b/vendor/github.com/mitchellh/cli/command_mock.go index 6371e573b..7a584b7e9 100644 --- a/vendor/github.com/mitchellh/cli/command_mock.go +++ b/vendor/github.com/mitchellh/cli/command_mock.go @@ -1,5 +1,9 @@ package cli +import ( + "github.com/posener/complete" +) + // MockCommand is an implementation of Command that can be used for tests. // It is publicly exported from this package in case you want to use it // externally. @@ -29,6 +33,23 @@ func (c *MockCommand) Synopsis() string { return c.SynopsisText } +// MockCommandAutocomplete is an implementation of CommandAutocomplete. +type MockCommandAutocomplete struct { + MockCommand + + // Settable + AutocompleteArgsValue complete.Predictor + AutocompleteFlagsValue complete.Flags +} + +func (c *MockCommandAutocomplete) AutocompleteArgs() complete.Predictor { + return c.AutocompleteArgsValue +} + +func (c *MockCommandAutocomplete) AutocompleteFlags() complete.Flags { + return c.AutocompleteFlagsValue +} + // MockCommandHelpTemplate is an implementation of CommandHelpTemplate. type MockCommandHelpTemplate struct { MockCommand diff --git a/vendor/github.com/mitchellh/cli/ui_mock.go b/vendor/github.com/mitchellh/cli/ui_mock.go index bdae2a664..0bfe0a191 100644 --- a/vendor/github.com/mitchellh/cli/ui_mock.go +++ b/vendor/github.com/mitchellh/cli/ui_mock.go @@ -100,8 +100,12 @@ func (b *syncBuffer) Reset() { } func (b *syncBuffer) String() string { + return string(b.Bytes()) +} + +func (b *syncBuffer) Bytes() []byte { b.RLock() data := b.b.Bytes() b.RUnlock() - return string(data) + return data } diff --git a/vendor/github.com/posener/complete/LICENSE.txt b/vendor/github.com/posener/complete/LICENSE.txt new file mode 100644 index 000000000..16249b4a1 --- /dev/null +++ b/vendor/github.com/posener/complete/LICENSE.txt @@ -0,0 +1,21 @@ +The MIT License + +Copyright (c) 2017 Eyal Posener + +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 diff --git a/vendor/github.com/posener/complete/args.go b/vendor/github.com/posener/complete/args.go new file mode 100644 index 000000000..73c356d76 --- /dev/null +++ b/vendor/github.com/posener/complete/args.go @@ -0,0 +1,75 @@ +package complete + +import ( + "os" + "path/filepath" +) + +// Args describes command line arguments +type Args struct { + // All lists of all arguments in command line (not including the command itself) + All []string + // Completed lists of all completed arguments in command line, + // If the last one is still being typed - no space after it, + // it won't appear in this list of arguments. + Completed []string + // Last argument in command line, the one being typed, if the last + // character in the command line is a space, this argument will be empty, + // otherwise this would be the last word. + Last string + // LastCompleted is the last argument that was fully typed. + // If the last character in the command line is space, this would be the + // last word, otherwise, it would be the word before that. + LastCompleted string +} + +// Directory gives the directory of the current written +// last argument if it represents a file name being written. +// in case that it is not, we fall back to the current directory. +func (a Args) Directory() string { + if info, err := os.Stat(a.Last); err == nil && info.IsDir() { + return fixPathForm(a.Last, a.Last) + } + dir := filepath.Dir(a.Last) + if info, err := os.Stat(dir); err != nil || !info.IsDir() { + return "./" + } + return fixPathForm(a.Last, dir) +} + +func newArgs(line []string) Args { + completed := removeLast(line[1:]) + return Args{ + All: line[1:], + Completed: completed, + Last: last(line), + LastCompleted: last(completed), + } +} + +func (a Args) from(i int) Args { + if i > len(a.All) { + i = len(a.All) + } + a.All = a.All[i:] + + if i > len(a.Completed) { + i = len(a.Completed) + } + a.Completed = a.Completed[i:] + return a +} + +func removeLast(a []string) []string { + if len(a) > 0 { + return a[:len(a)-1] + } + return a +} + +func last(args []string) (last string) { + if len(args) > 0 { + last = args[len(args)-1] + } + return +} diff --git a/vendor/github.com/posener/complete/cmd/cmd.go b/vendor/github.com/posener/complete/cmd/cmd.go new file mode 100644 index 000000000..7137dee17 --- /dev/null +++ b/vendor/github.com/posener/complete/cmd/cmd.go @@ -0,0 +1,128 @@ +// Package cmd used for command line options for the complete tool +package cmd + +import ( + "errors" + "flag" + "fmt" + "os" + "strings" + + "github.com/posener/complete/cmd/install" +) + +// CLI for command line +type CLI struct { + Name string + InstallName string + UninstallName string + + install bool + uninstall bool + yes bool +} + +const ( + defaultInstallName = "install" + defaultUninstallName = "uninstall" +) + +// Run is used when running complete in command line mode. +// this is used when the complete is not completing words, but to +// install it or uninstall it. +func (f *CLI) Run() bool { + err := f.validate() + if err != nil { + os.Stderr.WriteString(err.Error() + "\n") + os.Exit(1) + } + + switch { + case f.install: + f.prompt() + err = install.Install(f.Name) + case f.uninstall: + f.prompt() + err = install.Uninstall(f.Name) + default: + // non of the action flags matched, + // returning false should make the real program execute + return false + } + + if err != nil { + fmt.Printf("%s failed! %s\n", f.action(), err) + os.Exit(3) + } + fmt.Println("Done!") + return true +} + +// prompt use for approval +// exit if approval was not given +func (f *CLI) prompt() { + defer fmt.Println(f.action() + "ing...") + if f.yes { + return + } + fmt.Printf("%s completion for %s? ", f.action(), f.Name) + var answer string + fmt.Scanln(&answer) + + switch strings.ToLower(answer) { + case "y", "yes": + return + default: + fmt.Println("Cancelling...") + os.Exit(1) + } +} + +// AddFlags adds the CLI flags to the flag set. +// If flags is nil, the default command line flags will be taken. +// Pass non-empty strings as installName and uninstallName to override the default +// flag names. +func (f *CLI) AddFlags(flags *flag.FlagSet) { + if flags == nil { + flags = flag.CommandLine + } + + if f.InstallName == "" { + f.InstallName = defaultInstallName + } + if f.UninstallName == "" { + f.UninstallName = defaultUninstallName + } + + if flags.Lookup(f.InstallName) == nil { + flags.BoolVar(&f.install, f.InstallName, false, + fmt.Sprintf("Install completion for %s command", f.Name)) + } + if flags.Lookup(f.UninstallName) == nil { + flags.BoolVar(&f.uninstall, f.UninstallName, false, + fmt.Sprintf("Uninstall completion for %s command", f.Name)) + } + if flags.Lookup("y") == nil { + flags.BoolVar(&f.yes, "y", false, "Don't prompt user for typing 'yes'") + } +} + +// validate the CLI +func (f *CLI) validate() error { + if f.install && f.uninstall { + return errors.New("Install and uninstall are mutually exclusive") + } + return nil +} + +// action name according to the CLI values. +func (f *CLI) action() string { + switch { + case f.install: + return "Install" + case f.uninstall: + return "Uninstall" + default: + return "unknown" + } +} diff --git a/vendor/github.com/posener/complete/cmd/install/bash.go b/vendor/github.com/posener/complete/cmd/install/bash.go new file mode 100644 index 000000000..a287f9986 --- /dev/null +++ b/vendor/github.com/posener/complete/cmd/install/bash.go @@ -0,0 +1,32 @@ +package install + +import "fmt" + +// (un)install in bash +// basically adds/remove from .bashrc: +// +// complete -C +type bash struct { + rc string +} + +func (b bash) Install(cmd, bin string) error { + completeCmd := b.cmd(cmd, bin) + if lineInFile(b.rc, completeCmd) { + return fmt.Errorf("already installed in %s", b.rc) + } + return appendToFile(b.rc, completeCmd) +} + +func (b bash) Uninstall(cmd, bin string) error { + completeCmd := b.cmd(cmd, bin) + if !lineInFile(b.rc, completeCmd) { + return fmt.Errorf("does not installed in %s", b.rc) + } + + return removeFromFile(b.rc, completeCmd) +} + +func (bash) cmd(cmd, bin string) string { + return fmt.Sprintf("complete -C %s %s", bin, cmd) +} diff --git a/vendor/github.com/posener/complete/cmd/install/install.go b/vendor/github.com/posener/complete/cmd/install/install.go new file mode 100644 index 000000000..fb44b2b7e --- /dev/null +++ b/vendor/github.com/posener/complete/cmd/install/install.go @@ -0,0 +1,92 @@ +package install + +import ( + "errors" + "os" + "os/user" + "path/filepath" + + "github.com/hashicorp/go-multierror" +) + +type installer interface { + Install(cmd, bin string) error + Uninstall(cmd, bin string) error +} + +// Install complete command given: +// cmd: is the command name +func Install(cmd string) error { + is := installers() + if len(is) == 0 { + return errors.New("Did not found any shells to install") + } + bin, err := getBinaryPath() + if err != nil { + return err + } + + for _, i := range is { + errI := i.Install(cmd, bin) + if errI != nil { + err = multierror.Append(err, errI) + } + } + + return err +} + +// Uninstall complete command given: +// cmd: is the command name +func Uninstall(cmd string) error { + is := installers() + if len(is) == 0 { + return errors.New("Did not found any shells to uninstall") + } + bin, err := getBinaryPath() + if err != nil { + return err + } + + for _, i := range is { + errI := i.Uninstall(cmd, bin) + if errI != nil { + multierror.Append(err, errI) + } + } + + return err +} + +func installers() (i []installer) { + for _, rc := range [...]string{".bashrc", ".bash_profile"} { + if f := rcFile(rc); f != "" { + i = append(i, bash{f}) + break + } + } + if f := rcFile(".zshrc"); f != "" { + i = append(i, zsh{f}) + } + return +} + +func getBinaryPath() (string, error) { + bin, err := os.Executable() + if err != nil { + return "", err + } + return filepath.Abs(bin) +} + +func rcFile(name string) string { + u, err := user.Current() + if err != nil { + return "" + } + path := filepath.Join(u.HomeDir, name) + if _, err := os.Stat(path); err != nil { + return "" + } + return path +} diff --git a/vendor/github.com/posener/complete/cmd/install/utils.go b/vendor/github.com/posener/complete/cmd/install/utils.go new file mode 100644 index 000000000..2c8b44cab --- /dev/null +++ b/vendor/github.com/posener/complete/cmd/install/utils.go @@ -0,0 +1,118 @@ +package install + +import ( + "bufio" + "fmt" + "io" + "io/ioutil" + "os" +) + +func lineInFile(name string, lookFor string) bool { + f, err := os.Open(name) + if err != nil { + return false + } + defer f.Close() + r := bufio.NewReader(f) + prefix := []byte{} + for { + line, isPrefix, err := r.ReadLine() + if err == io.EOF { + return false + } + if err != nil { + return false + } + if isPrefix { + prefix = append(prefix, line...) + continue + } + line = append(prefix, line...) + if string(line) == lookFor { + return true + } + prefix = prefix[:0] + } +} + +func appendToFile(name string, content string) error { + f, err := os.OpenFile(name, os.O_RDWR|os.O_APPEND, 0) + if err != nil { + return err + } + defer f.Close() + _, err = f.WriteString(fmt.Sprintf("\n%s\n", content)) + return err +} + +func removeFromFile(name string, content string) error { + backup := name + ".bck" + err := copyFile(name, backup) + if err != nil { + return err + } + temp, err := removeContentToTempFile(name, content) + if err != nil { + return err + } + + err = copyFile(temp, name) + if err != nil { + return err + } + + return os.Remove(backup) +} + +func removeContentToTempFile(name, content string) (string, error) { + rf, err := os.Open(name) + if err != nil { + return "", err + } + defer rf.Close() + wf, err := ioutil.TempFile("/tmp", "complete-") + if err != nil { + return "", err + } + defer wf.Close() + + r := bufio.NewReader(rf) + prefix := []byte{} + for { + line, isPrefix, err := r.ReadLine() + if err == io.EOF { + break + } + if err != nil { + return "", err + } + if isPrefix { + prefix = append(prefix, line...) + continue + } + line = append(prefix, line...) + str := string(line) + if str == content { + continue + } + wf.WriteString(str + "\n") + prefix = prefix[:0] + } + return wf.Name(), nil +} + +func copyFile(src string, dst string) error { + in, err := os.Open(src) + if err != nil { + return err + } + defer in.Close() + out, err := os.Create(dst) + if err != nil { + return err + } + defer out.Close() + _, err = io.Copy(out, in) + return err +} diff --git a/vendor/github.com/posener/complete/cmd/install/zsh.go b/vendor/github.com/posener/complete/cmd/install/zsh.go new file mode 100644 index 000000000..a625f53cf --- /dev/null +++ b/vendor/github.com/posener/complete/cmd/install/zsh.go @@ -0,0 +1,39 @@ +package install + +import "fmt" + +// (un)install in zsh +// basically adds/remove from .zshrc: +// +// autoload -U +X bashcompinit && bashcompinit" +// complete -C +type zsh struct { + rc string +} + +func (z zsh) Install(cmd, bin string) error { + completeCmd := z.cmd(cmd, bin) + if lineInFile(z.rc, completeCmd) { + return fmt.Errorf("already installed in %s", z.rc) + } + + bashCompInit := "autoload -U +X bashcompinit && bashcompinit" + if !lineInFile(z.rc, bashCompInit) { + completeCmd = bashCompInit + "\n" + completeCmd + } + + return appendToFile(z.rc, completeCmd) +} + +func (z zsh) Uninstall(cmd, bin string) error { + completeCmd := z.cmd(cmd, bin) + if !lineInFile(z.rc, completeCmd) { + return fmt.Errorf("does not installed in %s", z.rc) + } + + return removeFromFile(z.rc, completeCmd) +} + +func (zsh) cmd(cmd, bin string) string { + return fmt.Sprintf("complete -o nospace -C %s %s", bin, cmd) +} diff --git a/vendor/github.com/posener/complete/command.go b/vendor/github.com/posener/complete/command.go new file mode 100644 index 000000000..6de48e960 --- /dev/null +++ b/vendor/github.com/posener/complete/command.go @@ -0,0 +1,118 @@ +package complete + +import "github.com/posener/complete/match" + +// Command represents a command line +// It holds the data that enables auto completion of command line +// Command can also be a sub command. +type Command struct { + // Sub is map of sub commands of the current command + // The key refer to the sub command name, and the value is it's + // Command descriptive struct. + Sub Commands + + // Flags is a map of flags that the command accepts. + // The key is the flag name, and the value is it's predictions. + Flags Flags + + // GlobalFlags is a map of flags that the command accepts. + // Global flags that can appear also after a sub command. + GlobalFlags Flags + + // Args are extra arguments that the command accepts, those who are + // given without any flag before. + Args Predictor +} + +// Predict returns all possible predictions for args according to the command struct +func (c *Command) Predict(a Args) (predictions []string) { + predictions, _ = c.predict(a) + return +} + +// Commands is the type of Sub member, it maps a command name to a command struct +type Commands map[string]Command + +// Predict completion of sub command names names according to command line arguments +func (c Commands) Predict(a Args) (prediction []string) { + for sub := range c { + if match.Prefix(sub, a.Last) { + prediction = append(prediction, sub) + } + } + return +} + +// Flags is the type Flags of the Flags member, it maps a flag name to the flag predictions. +type Flags map[string]Predictor + +// Predict completion of flags names according to command line arguments +func (f Flags) Predict(a Args) (prediction []string) { + for flag := range f { + // If the flag starts with a hyphen, we avoid emitting the prediction + // unless the last typed arg contains a hyphen as well. + flagHyphenStart := len(flag) != 0 && flag[0] == '-' + lastHyphenStart := len(a.Last) != 0 && a.Last[0] == '-' + if flagHyphenStart && !lastHyphenStart { + continue + } + + if match.Prefix(flag, a.Last) { + prediction = append(prediction, flag) + } + } + return +} + +// predict options +// only is set to true if no more options are allowed to be returned +// those are in cases of special flag that has specific completion arguments, +// and other flags or sub commands can't come after it. +func (c *Command) predict(a Args) (options []string, only bool) { + + // search sub commands for predictions first + subCommandFound := false + for i, arg := range a.Completed { + if cmd, ok := c.Sub[arg]; ok { + subCommandFound = true + + // recursive call for sub command + options, only = cmd.predict(a.from(i)) + if only { + return + } + + // We matched so stop searching. Continuing to search can accidentally + // match a subcommand with current set of commands, see issue #46. + break + } + } + + // if last completed word is a global flag that we need to complete + if predictor, ok := c.GlobalFlags[a.LastCompleted]; ok && predictor != nil { + Log("Predicting according to global flag %s", a.LastCompleted) + return predictor.Predict(a), true + } + + options = append(options, c.GlobalFlags.Predict(a)...) + + // if a sub command was entered, we won't add the parent command + // completions and we return here. + if subCommandFound { + return + } + + // if last completed word is a command flag that we need to complete + if predictor, ok := c.Flags[a.LastCompleted]; ok && predictor != nil { + Log("Predicting according to flag %s", a.LastCompleted) + return predictor.Predict(a), true + } + + options = append(options, c.Sub.Predict(a)...) + options = append(options, c.Flags.Predict(a)...) + if c.Args != nil { + options = append(options, c.Args.Predict(a)...) + } + + return +} diff --git a/vendor/github.com/posener/complete/complete.go b/vendor/github.com/posener/complete/complete.go new file mode 100644 index 000000000..1df66170b --- /dev/null +++ b/vendor/github.com/posener/complete/complete.go @@ -0,0 +1,86 @@ +// Package complete provides a tool for bash writing bash completion in go. +// +// Writing bash completion scripts is a hard work. This package provides an easy way +// to create bash completion scripts for any command, and also an easy way to install/uninstall +// the completion of the command. +package complete + +import ( + "flag" + "fmt" + "os" + "strings" + + "github.com/posener/complete/cmd" +) + +const ( + envComplete = "COMP_LINE" + envDebug = "COMP_DEBUG" +) + +// Complete structs define completion for a command with CLI options +type Complete struct { + Command Command + cmd.CLI +} + +// New creates a new complete command. +// name is the name of command we want to auto complete. +// IMPORTANT: it must be the same name - if the auto complete +// completes the 'go' command, name must be equal to "go". +// command is the struct of the command completion. +func New(name string, command Command) *Complete { + return &Complete{ + Command: command, + CLI: cmd.CLI{Name: name}, + } +} + +// Run runs the completion and add installation flags beforehand. +// The flags are added to the main flag CommandLine variable. +func (c *Complete) Run() bool { + c.AddFlags(nil) + flag.Parse() + return c.Complete() +} + +// Complete a command from completion line in environment variable, +// and print out the complete options. +// returns success if the completion ran or if the cli matched +// any of the given flags, false otherwise +// For installation: it assumes that flags were added and parsed before +// it was called. +func (c *Complete) Complete() bool { + line, ok := getLine() + if !ok { + // make sure flags parsed, + // in case they were not added in the main program + return c.CLI.Run() + } + Log("Completing line: %s", line) + + a := newArgs(line) + + options := c.Command.Predict(a) + + Log("Completion: %s", options) + output(options) + return true +} + +func getLine() ([]string, bool) { + line := os.Getenv(envComplete) + if line == "" { + return nil, false + } + return strings.Split(line, " "), true +} + +func output(options []string) { + Log("") + // stdout of program defines the complete options + for _, option := range options { + fmt.Println(option) + } +} diff --git a/vendor/github.com/posener/complete/log.go b/vendor/github.com/posener/complete/log.go new file mode 100644 index 000000000..797a80ced --- /dev/null +++ b/vendor/github.com/posener/complete/log.go @@ -0,0 +1,23 @@ +package complete + +import ( + "io" + "io/ioutil" + "log" + "os" +) + +// Log is used for debugging purposes +// since complete is running on tab completion, it is nice to +// have logs to the stderr (when writing your own completer) +// to write logs, set the COMP_DEBUG environment variable and +// use complete.Log in the complete program +var Log = getLogger() + +func getLogger() func(format string, args ...interface{}) { + var logfile io.Writer = ioutil.Discard + if os.Getenv(envDebug) != "" { + logfile = os.Stderr + } + return log.New(logfile, "complete ", log.Flags()).Printf +} diff --git a/vendor/github.com/posener/complete/match/file.go b/vendor/github.com/posener/complete/match/file.go new file mode 100644 index 000000000..051171e8a --- /dev/null +++ b/vendor/github.com/posener/complete/match/file.go @@ -0,0 +1,19 @@ +package match + +import "strings" + +// File returns true if prefix can match the file +func File(file, prefix string) bool { + // special case for current directory completion + if file == "./" && (prefix == "." || prefix == "") { + return true + } + if prefix == "." && strings.HasPrefix(file, ".") { + return true + } + + file = strings.TrimPrefix(file, "./") + prefix = strings.TrimPrefix(prefix, "./") + + return strings.HasPrefix(file, prefix) +} diff --git a/vendor/github.com/posener/complete/match/match.go b/vendor/github.com/posener/complete/match/match.go new file mode 100644 index 000000000..812fcac96 --- /dev/null +++ b/vendor/github.com/posener/complete/match/match.go @@ -0,0 +1,6 @@ +package match + +// Match matches two strings +// it is used for comparing a term to the last typed +// word, the prefix, and see if it is a possible auto complete option. +type Match func(term, prefix string) bool diff --git a/vendor/github.com/posener/complete/match/prefix.go b/vendor/github.com/posener/complete/match/prefix.go new file mode 100644 index 000000000..9a01ba63a --- /dev/null +++ b/vendor/github.com/posener/complete/match/prefix.go @@ -0,0 +1,9 @@ +package match + +import "strings" + +// Prefix is a simple Matcher, if the word is it's prefix, there is a match +// Match returns true if a has the prefix as prefix +func Prefix(long, prefix string) bool { + return strings.HasPrefix(long, prefix) +} diff --git a/vendor/github.com/posener/complete/metalinter.json b/vendor/github.com/posener/complete/metalinter.json new file mode 100644 index 000000000..799c1d03f --- /dev/null +++ b/vendor/github.com/posener/complete/metalinter.json @@ -0,0 +1,21 @@ +{ + "Vendor": true, + "DisableAll": true, + "Enable": [ + "gofmt", + "goimports", + "interfacer", + "goconst", + "misspell", + "unconvert", + "gosimple", + "golint", + "structcheck", + "deadcode", + "vet" + ], + "Exclude": [ + "initTests is unused" + ], + "Deadline": "2m" +} diff --git a/vendor/github.com/posener/complete/predict.go b/vendor/github.com/posener/complete/predict.go new file mode 100644 index 000000000..820706325 --- /dev/null +++ b/vendor/github.com/posener/complete/predict.go @@ -0,0 +1,41 @@ +package complete + +// Predictor implements a predict method, in which given +// command line arguments returns a list of options it predicts. +type Predictor interface { + Predict(Args) []string +} + +// PredictOr unions two predicate functions, so that the result predicate +// returns the union of their predication +func PredictOr(predictors ...Predictor) Predictor { + return PredictFunc(func(a Args) (prediction []string) { + for _, p := range predictors { + if p == nil { + continue + } + prediction = append(prediction, p.Predict(a)...) + } + return + }) +} + +// PredictFunc determines what terms can follow a command or a flag +// It is used for auto completion, given last - the last word in the already +// in the command line, what words can complete it. +type PredictFunc func(Args) []string + +// Predict invokes the predict function and implements the Predictor interface +func (p PredictFunc) Predict(a Args) []string { + if p == nil { + return nil + } + return p(a) +} + +// PredictNothing does not expect anything after. +var PredictNothing Predictor + +// PredictAnything expects something, but nothing particular, such as a number +// or arbitrary name. +var PredictAnything = PredictFunc(func(Args) []string { return nil }) diff --git a/vendor/github.com/posener/complete/predict_files.go b/vendor/github.com/posener/complete/predict_files.go new file mode 100644 index 000000000..c8adf7e80 --- /dev/null +++ b/vendor/github.com/posener/complete/predict_files.go @@ -0,0 +1,108 @@ +package complete + +import ( + "io/ioutil" + "os" + "path/filepath" + "strings" + + "github.com/posener/complete/match" +) + +// PredictDirs will search for directories in the given started to be typed +// path, if no path was started to be typed, it will complete to directories +// in the current working directory. +func PredictDirs(pattern string) Predictor { + return files(pattern, false) +} + +// PredictFiles will search for files matching the given pattern in the started to +// be typed path, if no path was started to be typed, it will complete to files that +// match the pattern in the current working directory. +// To match any file, use "*" as pattern. To match go files use "*.go", and so on. +func PredictFiles(pattern string) Predictor { + return files(pattern, true) +} + +func files(pattern string, allowFiles bool) PredictFunc { + + // search for files according to arguments, + // if only one directory has matched the result, search recursively into + // this directory to give more results. + return func(a Args) (prediction []string) { + prediction = predictFiles(a, pattern, allowFiles) + + // if the number of prediction is not 1, we either have many results or + // have no results, so we return it. + if len(prediction) != 1 { + return + } + + // only try deeper, if the one item is a directory + if stat, err := os.Stat(prediction[0]); err != nil || !stat.IsDir() { + return + } + + a.Last = prediction[0] + return predictFiles(a, pattern, allowFiles) + } +} + +func predictFiles(a Args, pattern string, allowFiles bool) []string { + if strings.HasSuffix(a.Last, "/..") { + return nil + } + + dir := a.Directory() + files := listFiles(dir, pattern, allowFiles) + + // add dir if match + files = append(files, dir) + + return PredictFilesSet(files).Predict(a) +} + +// PredictFilesSet predict according to file rules to a given set of file names +func PredictFilesSet(files []string) PredictFunc { + return func(a Args) (prediction []string) { + // add all matching files to prediction + for _, f := range files { + f = fixPathForm(a.Last, f) + + // test matching of file to the argument + if match.File(f, a.Last) { + prediction = append(prediction, f) + } + } + return + } +} + +func listFiles(dir, pattern string, allowFiles bool) []string { + // set of all file names + m := map[string]bool{} + + // list files + if files, err := filepath.Glob(filepath.Join(dir, pattern)); err == nil { + for _, f := range files { + if stat, err := os.Stat(f); err != nil || stat.IsDir() || allowFiles { + m[f] = true + } + } + } + + // list directories + if dirs, err := ioutil.ReadDir(dir); err == nil { + for _, d := range dirs { + if d.IsDir() { + m[filepath.Join(dir, d.Name())] = true + } + } + } + + list := make([]string, 0, len(m)) + for k := range m { + list = append(list, k) + } + return list +} diff --git a/vendor/github.com/posener/complete/predict_set.go b/vendor/github.com/posener/complete/predict_set.go new file mode 100644 index 000000000..8fc59d714 --- /dev/null +++ b/vendor/github.com/posener/complete/predict_set.go @@ -0,0 +1,19 @@ +package complete + +import "github.com/posener/complete/match" + +// PredictSet expects specific set of terms, given in the options argument. +func PredictSet(options ...string) Predictor { + return predictSet(options) +} + +type predictSet []string + +func (p predictSet) Predict(a Args) (prediction []string) { + for _, m := range p { + if match.Prefix(m, a.Last) { + prediction = append(prediction, m) + } + } + return +} diff --git a/vendor/github.com/posener/complete/readme.md b/vendor/github.com/posener/complete/readme.md new file mode 100644 index 000000000..74077e357 --- /dev/null +++ b/vendor/github.com/posener/complete/readme.md @@ -0,0 +1,116 @@ +# complete + +[![Build Status](https://travis-ci.org/posener/complete.svg?branch=master)](https://travis-ci.org/posener/complete) +[![codecov](https://codecov.io/gh/posener/complete/branch/master/graph/badge.svg)](https://codecov.io/gh/posener/complete) +[![GoDoc](https://godoc.org/github.com/posener/complete?status.svg)](http://godoc.org/github.com/posener/complete) +[![Go Report Card](https://goreportcard.com/badge/github.com/posener/complete)](https://goreportcard.com/report/github.com/posener/complete) + +A tool for bash writing bash completion in go. + +Writing bash completion scripts is a hard work. This package provides an easy way +to create bash completion scripts for any command, and also an easy way to install/uninstall +the completion of the command. + +## go command bash completion + +In [gocomplete](./gocomplete) there is an example for bash completion for the `go` command line. + +This is an example that uses the `complete` package on the `go` command - the `complete` package +can also be used to implement any completions, see [Usage](#usage). + +### Install + +1. Type in your shell: +``` +go get -u github.com/posener/complete/gocomplete +gocomplete -install +``` + +2. Restart your shell + +Uninstall by `gocomplete -uninstall` + +### Features + +- Complete `go` command, including sub commands and all flags. +- Complete packages names or `.go` files when necessary. +- Complete test names after `-run` flag. + +## complete package + +Supported shells: + +- [x] bash +- [x] zsh + +### Usage + +Assuming you have program called `run` and you want to have bash completion +for it, meaning, if you type `run` then space, then press the `Tab` key, +the shell will suggest relevant complete options. + +In that case, we will create a program called `runcomplete`, a go program, +with a `func main()` and so, that will make the completion of the `run` +program. Once the `runcomplete` will be in a binary form, we could +`runcomplete -install` and that will add to our shell all the bash completion +options for `run`. + +So here it is: + +```go +import "github.com/posener/complete" + +func main() { + + // create a Command object, that represents the command we want + // to complete. + run := complete.Command{ + + // Sub defines a list of sub commands of the program, + // this is recursive, since every command is of type command also. + Sub: complete.Commands{ + + // add a build sub command + "build": complete.Command { + + // define flags of the build sub command + Flags: complete.Flags{ + // build sub command has a flag '-cpus', which + // expects number of cpus after it. in that case + // anything could complete this flag. + "-cpus": complete.PredictAnything, + }, + }, + }, + + // define flags of the 'run' main command + Flags: complete.Flags{ + // a flag -o, which expects a file ending with .out after + // it, the tab completion will auto complete for files matching + // the given pattern. + "-o": complete.PredictFiles("*.out"), + }, + + // define global flags of the 'run' main command + // those will show up also when a sub command was entered in the + // command line + GlobalFlags: complete.Flags{ + + // a flag '-h' which does not expects anything after it + "-h": complete.PredictNothing, + }, + } + + // run the command completion, as part of the main() function. + // this triggers the autocompletion when needed. + // name must be exactly as the binary that we want to complete. + complete.New("run", run).Run() +} +``` + +### Self completing program + +In case that the program that we want to complete is written in go we +can make it self completing. + +Here is an [example](./example/self/main.go) diff --git a/vendor/github.com/posener/complete/test.sh b/vendor/github.com/posener/complete/test.sh new file mode 100755 index 000000000..56bfcf15d --- /dev/null +++ b/vendor/github.com/posener/complete/test.sh @@ -0,0 +1,12 @@ +#!/usr/bin/env bash + +set -e +echo "" > coverage.txt + +for d in $(go list ./... | grep -v vendor); do + go test -v -race -coverprofile=profile.out -covermode=atomic $d + if [ -f profile.out ]; then + cat profile.out >> coverage.txt + rm profile.out + fi +done \ No newline at end of file diff --git a/vendor/github.com/posener/complete/utils.go b/vendor/github.com/posener/complete/utils.go new file mode 100644 index 000000000..58b8b7927 --- /dev/null +++ b/vendor/github.com/posener/complete/utils.go @@ -0,0 +1,46 @@ +package complete + +import ( + "os" + "path/filepath" + "strings" +) + +// fixPathForm changes a file name to a relative name +func fixPathForm(last string, file string) string { + // get wording directory for relative name + workDir, err := os.Getwd() + if err != nil { + return file + } + + abs, err := filepath.Abs(file) + if err != nil { + return file + } + + // if last is absolute, return path as absolute + if filepath.IsAbs(last) { + return fixDirPath(abs) + } + + rel, err := filepath.Rel(workDir, abs) + if err != nil { + return file + } + + // fix ./ prefix of path + if rel != "." && strings.HasPrefix(last, ".") { + rel = "./" + rel + } + + return fixDirPath(rel) +} + +func fixDirPath(path string) string { + info, err := os.Stat(path) + if err == nil && info.IsDir() && !strings.HasSuffix(path, "/") { + path += "/" + } + return path +} diff --git a/vendor/vendor.json b/vendor/vendor.json index c9faca447..f9e2f7c47 100644 --- a/vendor/vendor.json +++ b/vendor/vendor.json @@ -2,89 +2,93 @@ "comment": "", "ignore": "test appengine", "package": [ - {"path":"github.com/DataDog/datadog-go/statsd","checksumSHA1":"JhyS/zIicgtrSasHSZ6WtXGWJVk=","revision":"cc2f4770f4d61871e19bfee967bc767fe730b0d9","revisionTime":"2016-03-29T13:52:53Z"}, - {"path":"github.com/Microsoft/go-winio","checksumSHA1":"AzjRkOQtVBTwIw4RJLTygFhJs3s=","revision":"c4dc1301f1dc0307acd38e611aa375a64dfe0642","revisionTime":"2017-07-12T04:46:15Z"}, - {"path":"github.com/StackExchange/wmi","checksumSHA1":"9NR0rrcAT5J76C5xMS4AVksS9o0=","revision":"e54cbda6595d7293a7a468ccf9525f6bc8887f99","revisionTime":"2016-08-11T21:45:55Z"}, - {"path":"github.com/armon/circbuf","checksumSHA1":"l0iFqayYAaEip6Olaq3/LCOa/Sg=","revision":"bbbad097214e2918d8543d5201d12bfd7bca254d","revisionTime":"2015-08-27T00:49:46Z"}, - {"path":"github.com/armon/go-metrics","checksumSHA1":"0et4hA6AYqZCgYiY+c6Z17t3k3k=","revision":"023a4bbe4bb9bfb23ee7e1afc8d0abad217641f3","revisionTime":"2017-08-09T01:16:44Z"}, - {"path":"github.com/armon/go-metrics/circonus","checksumSHA1":"xCsGGM9TKBogZDfSN536KtQdLko=","revision":"ded85ed431a7aee3f3af79f082b704d948058f64","revisionTime":"2017-08-07T19:17:41Z"}, - {"path":"github.com/armon/go-metrics/datadog","checksumSHA1":"Dt0n1sSivvvdZQdzc4Hu/yOG+T0=","revision":"ded85ed431a7aee3f3af79f082b704d948058f64","revisionTime":"2017-08-07T19:17:41Z"}, - {"path":"github.com/armon/go-radix","checksumSHA1":"gNO0JNpLzYOdInGeq7HqMZUzx9M=","revision":"4239b77079c7b5d1243b7b4736304ce8ddb6f0f2","revisionTime":"2016-01-15T23:47:25Z"}, - {"path":"github.com/bgentry/speakeasy","checksumSHA1":"dvd7Su+WNmHRP1+w1HezrPUCDsc=","revision":"e1439544d8ecd0f3e9373a636d447668096a8f81","revisionTime":"2016-05-20T23:26:10Z"}, - {"path":"github.com/bgentry/speakeasy/example","checksumSHA1":"twtRfb6484vfr2qqjiFkLThTjcQ=","revision":"e1439544d8ecd0f3e9373a636d447668096a8f81","revisionTime":"2016-05-20T23:26:10Z"}, - {"path":"github.com/boltdb/bolt","checksumSHA1":"C1BwfmTAUmldO4V3++tvYWzT49Y=","comment":"v1.2.1","revision":"dfb21201d9270c1082d5fb0f07f500311ff72f18","revisionTime":"2016-05-16T15:40:46Z","version":"v1.2.1","versionExact":"v1.2.1"}, - {"path":"github.com/circonus-labs/circonus-gometrics","checksumSHA1":"szvY4u7TlXkrQ3PW8wmyJaIFy0U=","revision":"d17a8420c36e800fcb46bbd4d2a15b93c68605ea","revisionTime":"2016-11-09T19:23:37Z"}, - {"path":"github.com/circonus-labs/circonus-gometrics/api","checksumSHA1":"WUE6oF152uN5FcLmmq+nO3Yl7pU=","revision":"d17a8420c36e800fcb46bbd4d2a15b93c68605ea","revisionTime":"2016-11-09T19:23:37Z"}, - {"path":"github.com/circonus-labs/circonus-gometrics/checkmgr","checksumSHA1":"beRBHHy2+V6Ht4cACIMmZOCnzgg=","revision":"d17a8420c36e800fcb46bbd4d2a15b93c68605ea","revisionTime":"2016-11-09T19:23:37Z"}, - {"path":"github.com/circonus-labs/circonusllhist","checksumSHA1":"C4Z7+l5GOpOCW5DcvNYzheGvQRE=","revision":"365d370cc1459bdcaceda3499453668373dea1d0","revisionTime":"2016-11-10T00:26:50Z"}, - {"path":"github.com/elazarl/go-bindata-assetfs","checksumSHA1":"5ftkjfUwI9A6xCQ1PwIAd5+qlo0=","revision":"e1a2a7ec64b07d04ac9ebb072404fe8b7b60de1b","revisionTime":"2016-08-03T19:23:04Z"}, - {"path":"github.com/elazarl/go-bindata-assetfs/go-bindata-assetfs","checksumSHA1":"CaThXbumVxZtNlItiXma5B78PwQ=","revision":"e1a2a7ec64b07d04ac9ebb072404fe8b7b60de1b","revisionTime":"2016-08-03T19:23:04Z"}, - {"path":"github.com/go-ole/go-ole","checksumSHA1":"oyULO1B/l2OLy2xereo+2w3hYk4=","revision":"02d3668a0cf01f58411cc85cd37c174c257ec7c2","revisionTime":"2017-06-01T13:56:11Z"}, - {"path":"github.com/go-ole/go-ole/oleutil","checksumSHA1":"IvdiJE1NIogRmGi3WmteEKZQJB8=","revision":"5e9c030faf78847db7aa77e3661b9cc449de29b7","revisionTime":"2016-11-16T06:46:58Z"}, - {"path":"github.com/google/gofuzz","checksumSHA1":"PFtXkXPO7pwRtykVUUXtc07wc7U=","revision":"24818f796faf91cd76ec7bddd72458fbced7a6c1","revisionTime":"2017-06-12T17:47:53Z"}, - {"path":"github.com/hashicorp/errwrap","checksumSHA1":"cdOCt0Yb+hdErz8NAQqayxPmRsY=","revision":"7554cd9344cec97297fa6649b055a8c98c2a1e55","revisionTime":"2014-10-28T05:47:10Z"}, - {"path":"github.com/hashicorp/go-checkpoint","checksumSHA1":"nd3S1qkFv7zZxA9be0bw4nT0pe0=","revision":"e4b2dc34c0f698ee04750bf2035d8b9384233e1b","revisionTime":"2015-10-22T18:15:14Z"}, - {"path":"github.com/hashicorp/go-cleanhttp","checksumSHA1":"b8F628srIitj5p7Y130xc9k0QWs=","revision":"3573b8b52aa7b37b9358d966a898feb387f62437","revisionTime":"2017-02-11T01:34:15Z"}, - {"path":"github.com/hashicorp/go-discover","checksumSHA1":"uNoQWG5h2hzWHjaLi376ZXVaCr4=","revision":"21b26b722865b64ae5809a532d2c18f3a3800129","revisionTime":"2017-08-16T16:53:52Z"}, - {"path":"github.com/hashicorp/go-discover/provider/aws","checksumSHA1":"6wdwVsYyTqW4ReHsWs4mEwoz1FI=","revision":"21b26b722865b64ae5809a532d2c18f3a3800129","revisionTime":"2017-08-16T16:53:52Z","tree":true}, - {"path":"github.com/hashicorp/go-discover/provider/azure","checksumSHA1":"r97P32e+VmNMh2vwLkZa1zPEDQU=","revision":"b518491d039b6782035b8881502b4f5e9fcc887b","revisionTime":"2017-08-01T15:32:04Z","tree":true}, - {"path":"github.com/hashicorp/go-discover/provider/gce","checksumSHA1":"KC/MepQsQF17904UShiM61jmaEs=","revision":"b518491d039b6782035b8881502b4f5e9fcc887b","revisionTime":"2017-08-01T15:32:04Z","tree":true}, - {"path":"github.com/hashicorp/go-discover/provider/softlayer","checksumSHA1":"SIyZ44AHIUTBfI336ACpCeybsLg=","revision":"b518491d039b6782035b8881502b4f5e9fcc887b","revisionTime":"2017-08-01T15:32:04Z","tree":true}, - {"path":"github.com/hashicorp/go-immutable-radix","checksumSHA1":"Cas2nprG6pWzf05A2F/OlnjUu2Y=","revision":"8aac2701530899b64bdea735a1de8da899815220","revisionTime":"2017-07-25T22:12:15Z"}, - {"path":"github.com/hashicorp/go-memdb","checksumSHA1":"T65qvYBTy4rYks7oN+U0muEqtRw=","revision":"2b2d6c35e14e7557ea1003e707d5e179fa315028","revisionTime":"2017-07-25T22:15:03Z"}, - {"path":"github.com/hashicorp/go-msgpack/codec","checksumSHA1":"TNlVzNR1OaajcNi3CbQ3bGbaLGU=","revision":"fa3f63826f7c23912c15263591e65d54d080b458","revisionTime":"2015-05-18T23:42:57Z"}, - {"path":"github.com/hashicorp/go-multierror","checksumSHA1":"lrSl49G23l6NhfilxPM0XFs5rZo=","revision":"d30f09973e19c1dfcd120b2d9c4f168e68d6b5d5","revisionTime":"2015-09-16T20:57:42Z"}, - {"path":"github.com/hashicorp/go-retryablehttp","checksumSHA1":"ErJHGU6AVPZM9yoY/xV11TwSjQs=","revision":"6e85be8fee1dcaa02c0eaaac2df5a8fbecf94145","revisionTime":"2016-09-30T03:51:02Z"}, - {"path":"github.com/hashicorp/go-rootcerts","checksumSHA1":"A1PcINvF3UiwHRKn8UcgARgvGRs=","revision":"6bb64b370b90e7ef1fa532be9e591a81c3493e00","revisionTime":"2016-05-03T14:34:40Z"}, - {"path":"github.com/hashicorp/go-sockaddr","checksumSHA1":"GP24Vz4EmZAL1ZH2TYTkDiiCO94=","revision":"2d10d7c10258d11196c0ebf2943509e4afd06cd4","revisionTime":"2017-05-23T22:50:28Z"}, - {"path":"github.com/hashicorp/go-sockaddr/template","checksumSHA1":"mIUCMmRHslN2bxQZ0uObMnXxk9E=","revision":"2d10d7c10258d11196c0ebf2943509e4afd06cd4","revisionTime":"2017-05-23T22:50:28Z"}, - {"path":"github.com/hashicorp/go-syslog","checksumSHA1":"xZ7Ban1x//6uUIU1xtrTbCYNHBc=","revision":"42a2b573b664dbf281bd48c3cc12c086b17a39ba","revisionTime":"2015-02-18T18:19:46Z"}, - {"path":"github.com/hashicorp/go-uuid","checksumSHA1":"mAkPa/RLuIwN53GbwIEMATexams=","revision":"64130c7a86d732268a38cb04cfbaf0cc987fda98","revisionTime":"2016-07-17T02:21:40Z"}, - {"path":"github.com/hashicorp/go-version","checksumSHA1":"tUGxc7rfX0cmhOOUDhMuAZ9rWsA=","revision":"03c5bf6be031b6dd45afec16b1cf94fc8938bc77","revisionTime":"2017-02-02T08:07:59Z"}, - {"path":"github.com/hashicorp/golang-lru","checksumSHA1":"d9PxF1XQGLMJZRct2R8qVM/eYlE=","revision":"a0d98a5f288019575c6d1f4bb1573fef2d1fcdc4","revisionTime":"2016-02-07T21:47:19Z"}, - {"path":"github.com/hashicorp/golang-lru/simplelru","checksumSHA1":"2nOpYjx8Sn57bqlZq17yM4YJuM4=","revision":"a0d98a5f288019575c6d1f4bb1573fef2d1fcdc4","revisionTime":"2016-02-07T21:47:19Z"}, - {"path":"github.com/hashicorp/hcl","checksumSHA1":"ydHBPi04mEh+Tir+2JkpSIMckcw=","revision":"d8c773c4cba11b11539e3d45f93daeaa5dcf1fa1","revisionTime":"2016-07-11T23:17:52Z"}, - {"path":"github.com/hashicorp/hcl/hcl/ast","checksumSHA1":"IxyvRpCFeoJBGl2obLKJV7RCGjg=","revision":"d8c773c4cba11b11539e3d45f93daeaa5dcf1fa1","revisionTime":"2016-07-11T23:17:52Z"}, - {"path":"github.com/hashicorp/hcl/hcl/parser","checksumSHA1":"l2oQxBsZRwn6eZjf+whXr8c9+8c=","revision":"d8c773c4cba11b11539e3d45f93daeaa5dcf1fa1","revisionTime":"2016-07-11T23:17:52Z"}, - {"path":"github.com/hashicorp/hcl/hcl/scanner","checksumSHA1":"vjhDQVlgHhdxml1V8/cj0vOe+j8=","revision":"d8c773c4cba11b11539e3d45f93daeaa5dcf1fa1","revisionTime":"2016-07-11T23:17:52Z"}, - {"path":"github.com/hashicorp/hcl/hcl/strconv","checksumSHA1":"JlZmnzqdmFFyb1+2afLyR3BOE/8=","revision":"d8c773c4cba11b11539e3d45f93daeaa5dcf1fa1","revisionTime":"2016-07-11T23:17:52Z"}, - {"path":"github.com/hashicorp/hcl/hcl/token","checksumSHA1":"c6yprzj06ASwCo18TtbbNNBHljA=","revision":"d8c773c4cba11b11539e3d45f93daeaa5dcf1fa1","revisionTime":"2016-07-11T23:17:52Z"}, - {"path":"github.com/hashicorp/hcl/json/parser","checksumSHA1":"jQ45CCc1ed/nlV7bbSnx6z72q1M=","revision":"d8c773c4cba11b11539e3d45f93daeaa5dcf1fa1","revisionTime":"2016-07-11T23:17:52Z"}, - {"path":"github.com/hashicorp/hcl/json/scanner","checksumSHA1":"S1e0F9ZKSnqgOLfjDTYazRL28tA=","revision":"d8c773c4cba11b11539e3d45f93daeaa5dcf1fa1","revisionTime":"2016-07-11T23:17:52Z"}, - {"path":"github.com/hashicorp/hcl/json/token","checksumSHA1":"fNlXQCQEnb+B3k5UDL/r15xtSJY=","revision":"d8c773c4cba11b11539e3d45f93daeaa5dcf1fa1","revisionTime":"2016-07-11T23:17:52Z"}, - {"path":"github.com/hashicorp/hil","checksumSHA1":"kqCMCHy2b+RBMKC+ER+OPqp8C3E=","revision":"1e86c6b523c55d1fa6c6e930ce80b548664c95c2","revisionTime":"2016-07-11T23:18:37Z"}, - {"path":"github.com/hashicorp/hil/ast","checksumSHA1":"UICubs001+Q4MsUf9zl2vcMzWQQ=","revision":"1e86c6b523c55d1fa6c6e930ce80b548664c95c2","revisionTime":"2016-07-11T23:18:37Z"}, - {"path":"github.com/hashicorp/logutils","checksumSHA1":"vt+P9D2yWDO3gdvdgCzwqunlhxU=","revision":"0dc08b1671f34c4250ce212759ebd880f743d883","revisionTime":"2015-06-09T07:04:31Z"}, - {"path":"github.com/hashicorp/memberlist","checksumSHA1":"ml0MTqOsKTrsqv/mZhy78Vz4SfA=","revision":"d6c1fb0b99c33d0a8e22acea9da9709b369b5d39","revisionTime":"2017-08-15T22:46:17Z"}, - {"path":"github.com/hashicorp/net-rpc-msgpackrpc","checksumSHA1":"qnlqWJYV81ENr61SZk9c65R1mDo=","revision":"a14192a58a694c123d8fe5481d4a4727d6ae82f3","revisionTime":"2015-11-16T02:03:38Z"}, - {"path":"github.com/hashicorp/raft","checksumSHA1":"f2QYddVWZ2eWxdlCEhearTH4XOs=","revision":"c837e57a6077e74a4a3749959fb6cfefc26d7705","revisionTime":"2017-08-30T14:31:53Z","version":"library-v2-stage-one","versionExact":"library-v2-stage-one"}, - {"path":"github.com/hashicorp/raft-boltdb","checksumSHA1":"QAxukkv54/iIvLfsUP6IK4R0m/A=","revision":"d1e82c1ec3f15ee991f7cc7ffd5b67ff6f5bbaee","revisionTime":"2015-02-01T20:08:39Z"}, - {"path":"github.com/hashicorp/serf/coordinate","checksumSHA1":"/oss17GO4hXGM7QnUdI3VzcAHzA=","comment":"v0.7.0-66-g6c4672d","revision":"c2e4be24cdc9031eb0ad869c5d160775efdf7d7a","revisionTime":"2017-05-25T23:15:04Z"}, - {"path":"github.com/hashicorp/serf/serf","checksumSHA1":"3WPnGSL9ZK6EmkAE6tEW5SCxrd8=","comment":"v0.7.0-66-g6c4672d","revision":"b84a66cc5575994cb672940d244a2404141688c0","revisionTime":"2017-08-17T21:22:02Z"}, - {"path":"github.com/hashicorp/yamux","checksumSHA1":"ZhK6IO2XN81Y+3RAjTcVm1Ic7oU=","revision":"d1caa6c97c9fc1cc9e83bbe34d0603f9ff0ce8bd","revisionTime":"2016-07-20T23:31:40Z"}, - {"path":"github.com/mattn/go-isatty","checksumSHA1":"xZuhljnmBysJPta/lMyYmJdujCg=","revision":"66b8e73f3f5cda9f96b69efd03dd3d7fc4a5cdb8","revisionTime":"2016-08-06T12:27:52Z"}, - {"path":"github.com/miekg/dns","checksumSHA1":"OUZ1FFXyKs+Cfg9M9rmXqqweQck=","revision":"db96a2b759cdef4f11a34506a42eb8d1290c598e","revisionTime":"2016-07-26T03:20:27Z"}, - {"path":"github.com/mitchellh/cli","checksumSHA1":"bUuI7AVR3IZPLlBaEKmw/ke7wqA=","revision":"b481eac70eea3ad671b7c360a013f89bb759b252","revisionTime":"2017-05-23T17:27:49Z"}, - {"path":"github.com/mitchellh/copystructure","checksumSHA1":"86nE93o1VIND0Doe8PuhCXnhUx0=","revision":"cdac8253d00f2ecf0a0b19fbff173a9a72de4f82","revisionTime":"2016-08-04T03:23:30Z"}, - {"path":"github.com/mitchellh/go-homedir","checksumSHA1":"V/quM7+em2ByJbWBLOsEwnY3j/Q=","revision":"b8bc1bf767474819792c23f32d8286a45736f1c6","revisionTime":"2016-12-03T19:45:07Z"}, - {"path":"github.com/mitchellh/mapstructure","checksumSHA1":"LUrnGREfnifW4WDMaavmc9MlLI0=","revision":"ca63d7c062ee3c9f34db231e352b60012b4fd0c1","revisionTime":"2016-08-08T18:12:53Z"}, - {"path":"github.com/mitchellh/reflectwalk","checksumSHA1":"mrqMlK6gqe//WsJSrJ1HgkPM0lM=","revision":"eecf4c70c626c7cfbb95c90195bc34d386c74ac6","revisionTime":"2015-05-27T15:31:53Z"}, - {"path":"github.com/pascaldekloe/goe/verify","checksumSHA1":"5h+ERzHw3Rl2G0kFPxoJzxiA9s0=","revision":"07ebd1e2481f616a278ab431cf04cc5cf5ab3ebe","revisionTime":"2017-03-28T18:37:59Z"}, - {"path":"github.com/pkg/errors","checksumSHA1":"ynJSWoF6v+3zMnh9R0QmmG6iGV8=","revision":"ff09b135c25aae272398c51a07235b90a75aa4f0","revisionTime":"2017-03-16T20:15:38Z","tree":true}, - {"path":"github.com/ryanuber/columnize","checksumSHA1":"ExnVEVNT8APpFTm26cUb5T09yR4=","comment":"v2.0.1-8-g983d3a5","revision":"9b3edd62028f107d7cabb19353292afd29311a4e","revisionTime":"2016-07-12T16:32:29Z"}, - {"path":"github.com/sean-/seed","checksumSHA1":"A/YUMbGg1LHIeK2+NLZBt+MIAao=","revision":"3c72d44db0c567f7c901f9c5da5fe68392227750","revisionTime":"2017-02-08T16:47:21Z"}, - {"path":"github.com/shirou/gopsutil/cpu","checksumSHA1":"zW2k8E1gkuySzTz2eXuSEDhpffY=","revision":"32b6636de04b303274daac3ca2b10d3b0e4afc35","revisionTime":"2017-02-04T05:36:48Z"}, - {"path":"github.com/shirou/gopsutil/host","checksumSHA1":"GsqEEmGv6sj8DreS2SYXRkoZ9NI=","revision":"b62e301a8b9958eebb7299683eb57fab229a9501","revisionTime":"2017-02-08T02:55:55Z"}, - {"path":"github.com/shirou/gopsutil/internal/common","checksumSHA1":"hz9RxkaV3Tnju2eiHBWO/Yv7n5c=","revision":"32b6636de04b303274daac3ca2b10d3b0e4afc35","revisionTime":"2017-02-04T05:36:48Z"}, - {"path":"github.com/shirou/gopsutil/mem","checksumSHA1":"XQwjGKI51Y3aQ3/jNyRh9Gnprgg=","revision":"32b6636de04b303274daac3ca2b10d3b0e4afc35","revisionTime":"2017-02-04T05:36:48Z"}, - {"path":"github.com/shirou/gopsutil/net","checksumSHA1":"OSvOZs5uK5iolCOeS46nB2InVy8=","revision":"32b6636de04b303274daac3ca2b10d3b0e4afc35","revisionTime":"2017-02-04T05:36:48Z"}, - {"path":"github.com/shirou/gopsutil/process","checksumSHA1":"JX0bRK/BdKVfbm4XOxMducVdY58=","revision":"32b6636de04b303274daac3ca2b10d3b0e4afc35","revisionTime":"2017-02-04T05:36:48Z"}, - {"path":"github.com/shirou/w32","checksumSHA1":"Nve7SpDmjsv6+rhkXAkfg/UQx94=","revision":"bb4de0191aa41b5507caa14b0650cdbddcd9280b","revisionTime":"2016-09-30T03:27:40Z"}, - {"path":"github.com/tonnerre/golang-text","checksumSHA1":"t24KnvC9jRxiANVhpw2pqFpmEu8=","revision":"048ed3d792f7104850acbc8cfc01e5a6070f4c04","revisionTime":"2013-09-25T19:58:46Z"}, - {"path":"golang.org/x/net/context","checksumSHA1":"9jjO5GjLa0XF/nfWihF02RoH4qc=","revision":"075e191f18186a8ff2becaf64478e30f4545cdad","revisionTime":"2016-08-05T06:12:51Z"}, - {"path":"golang.org/x/net/context/ctxhttp","checksumSHA1":"WHc3uByvGaMcnSoI21fhzYgbOgg=","revision":"075e191f18186a8ff2becaf64478e30f4545cdad","revisionTime":"2016-08-05T06:12:51Z"}, - {"path":"golang.org/x/sys/unix","checksumSHA1":"vlicYp+fe4ECQ+5QqpAk36VRA3s=","revision":"cd2c276457edda6df7fb04895d3fd6a6add42926","revisionTime":"2017-07-17T10:05:24Z"}, - {"path":"golang.org/x/time/rate","checksumSHA1":"vGfePfr0+weQUeTM/71mu+LCFuE=","revision":"8be79e1e0910c292df4e79c241bb7e8f7e725959","revisionTime":"2017-04-24T23:28:54Z"} + {"checksumSHA1":"JhyS/zIicgtrSasHSZ6WtXGWJVk=","path":"github.com/DataDog/datadog-go/statsd","revision":"cc2f4770f4d61871e19bfee967bc767fe730b0d9","revisionTime":"2016-03-29T13:52:53Z"}, + {"checksumSHA1":"AzjRkOQtVBTwIw4RJLTygFhJs3s=","path":"github.com/Microsoft/go-winio","revision":"c4dc1301f1dc0307acd38e611aa375a64dfe0642","revisionTime":"2017-07-12T04:46:15Z"}, + {"checksumSHA1":"9NR0rrcAT5J76C5xMS4AVksS9o0=","path":"github.com/StackExchange/wmi","revision":"e54cbda6595d7293a7a468ccf9525f6bc8887f99","revisionTime":"2016-08-11T21:45:55Z"}, + {"checksumSHA1":"l0iFqayYAaEip6Olaq3/LCOa/Sg=","path":"github.com/armon/circbuf","revision":"bbbad097214e2918d8543d5201d12bfd7bca254d","revisionTime":"2015-08-27T00:49:46Z"}, + {"checksumSHA1":"0et4hA6AYqZCgYiY+c6Z17t3k3k=","path":"github.com/armon/go-metrics","revision":"023a4bbe4bb9bfb23ee7e1afc8d0abad217641f3","revisionTime":"2017-08-09T01:16:44Z"}, + {"checksumSHA1":"xCsGGM9TKBogZDfSN536KtQdLko=","path":"github.com/armon/go-metrics/circonus","revision":"ded85ed431a7aee3f3af79f082b704d948058f64","revisionTime":"2017-08-07T19:17:41Z"}, + {"checksumSHA1":"Dt0n1sSivvvdZQdzc4Hu/yOG+T0=","path":"github.com/armon/go-metrics/datadog","revision":"ded85ed431a7aee3f3af79f082b704d948058f64","revisionTime":"2017-08-07T19:17:41Z"}, + {"checksumSHA1":"gNO0JNpLzYOdInGeq7HqMZUzx9M=","path":"github.com/armon/go-radix","revision":"4239b77079c7b5d1243b7b4736304ce8ddb6f0f2","revisionTime":"2016-01-15T23:47:25Z"}, + {"checksumSHA1":"dvd7Su+WNmHRP1+w1HezrPUCDsc=","path":"github.com/bgentry/speakeasy","revision":"e1439544d8ecd0f3e9373a636d447668096a8f81","revisionTime":"2016-05-20T23:26:10Z"}, + {"checksumSHA1":"twtRfb6484vfr2qqjiFkLThTjcQ=","path":"github.com/bgentry/speakeasy/example","revision":"e1439544d8ecd0f3e9373a636d447668096a8f81","revisionTime":"2016-05-20T23:26:10Z"}, + {"checksumSHA1":"C1BwfmTAUmldO4V3++tvYWzT49Y=","comment":"v1.2.1","path":"github.com/boltdb/bolt","revision":"dfb21201d9270c1082d5fb0f07f500311ff72f18","revisionTime":"2016-05-16T15:40:46Z","version":"v1.2.1","versionExact":"v1.2.1"}, + {"checksumSHA1":"szvY4u7TlXkrQ3PW8wmyJaIFy0U=","path":"github.com/circonus-labs/circonus-gometrics","revision":"d17a8420c36e800fcb46bbd4d2a15b93c68605ea","revisionTime":"2016-11-09T19:23:37Z"}, + {"checksumSHA1":"WUE6oF152uN5FcLmmq+nO3Yl7pU=","path":"github.com/circonus-labs/circonus-gometrics/api","revision":"d17a8420c36e800fcb46bbd4d2a15b93c68605ea","revisionTime":"2016-11-09T19:23:37Z"}, + {"checksumSHA1":"beRBHHy2+V6Ht4cACIMmZOCnzgg=","path":"github.com/circonus-labs/circonus-gometrics/checkmgr","revision":"d17a8420c36e800fcb46bbd4d2a15b93c68605ea","revisionTime":"2016-11-09T19:23:37Z"}, + {"checksumSHA1":"C4Z7+l5GOpOCW5DcvNYzheGvQRE=","path":"github.com/circonus-labs/circonusllhist","revision":"365d370cc1459bdcaceda3499453668373dea1d0","revisionTime":"2016-11-10T00:26:50Z"}, + {"checksumSHA1":"5ftkjfUwI9A6xCQ1PwIAd5+qlo0=","path":"github.com/elazarl/go-bindata-assetfs","revision":"e1a2a7ec64b07d04ac9ebb072404fe8b7b60de1b","revisionTime":"2016-08-03T19:23:04Z"}, + {"checksumSHA1":"CaThXbumVxZtNlItiXma5B78PwQ=","path":"github.com/elazarl/go-bindata-assetfs/go-bindata-assetfs","revision":"e1a2a7ec64b07d04ac9ebb072404fe8b7b60de1b","revisionTime":"2016-08-03T19:23:04Z"}, + {"checksumSHA1":"oyULO1B/l2OLy2xereo+2w3hYk4=","path":"github.com/go-ole/go-ole","revision":"02d3668a0cf01f58411cc85cd37c174c257ec7c2","revisionTime":"2017-06-01T13:56:11Z"}, + {"checksumSHA1":"IvdiJE1NIogRmGi3WmteEKZQJB8=","path":"github.com/go-ole/go-ole/oleutil","revision":"5e9c030faf78847db7aa77e3661b9cc449de29b7","revisionTime":"2016-11-16T06:46:58Z"}, + {"checksumSHA1":"PFtXkXPO7pwRtykVUUXtc07wc7U=","path":"github.com/google/gofuzz","revision":"24818f796faf91cd76ec7bddd72458fbced7a6c1","revisionTime":"2017-06-12T17:47:53Z"}, + {"checksumSHA1":"cdOCt0Yb+hdErz8NAQqayxPmRsY=","path":"github.com/hashicorp/errwrap","revision":"7554cd9344cec97297fa6649b055a8c98c2a1e55","revisionTime":"2014-10-28T05:47:10Z"}, + {"checksumSHA1":"nd3S1qkFv7zZxA9be0bw4nT0pe0=","path":"github.com/hashicorp/go-checkpoint","revision":"e4b2dc34c0f698ee04750bf2035d8b9384233e1b","revisionTime":"2015-10-22T18:15:14Z"}, + {"checksumSHA1":"b8F628srIitj5p7Y130xc9k0QWs=","path":"github.com/hashicorp/go-cleanhttp","revision":"3573b8b52aa7b37b9358d966a898feb387f62437","revisionTime":"2017-02-11T01:34:15Z"}, + {"checksumSHA1":"uNoQWG5h2hzWHjaLi376ZXVaCr4=","path":"github.com/hashicorp/go-discover","revision":"21b26b722865b64ae5809a532d2c18f3a3800129","revisionTime":"2017-08-16T16:53:52Z"}, + {"checksumSHA1":"6wdwVsYyTqW4ReHsWs4mEwoz1FI=","path":"github.com/hashicorp/go-discover/provider/aws","revision":"21b26b722865b64ae5809a532d2c18f3a3800129","revisionTime":"2017-08-16T16:53:52Z","tree":true}, + {"checksumSHA1":"r97P32e+VmNMh2vwLkZa1zPEDQU=","path":"github.com/hashicorp/go-discover/provider/azure","revision":"b518491d039b6782035b8881502b4f5e9fcc887b","revisionTime":"2017-08-01T15:32:04Z","tree":true}, + {"checksumSHA1":"KC/MepQsQF17904UShiM61jmaEs=","path":"github.com/hashicorp/go-discover/provider/gce","revision":"b518491d039b6782035b8881502b4f5e9fcc887b","revisionTime":"2017-08-01T15:32:04Z","tree":true}, + {"checksumSHA1":"SIyZ44AHIUTBfI336ACpCeybsLg=","path":"github.com/hashicorp/go-discover/provider/softlayer","revision":"b518491d039b6782035b8881502b4f5e9fcc887b","revisionTime":"2017-08-01T15:32:04Z","tree":true}, + {"checksumSHA1":"Cas2nprG6pWzf05A2F/OlnjUu2Y=","path":"github.com/hashicorp/go-immutable-radix","revision":"8aac2701530899b64bdea735a1de8da899815220","revisionTime":"2017-07-25T22:12:15Z"}, + {"checksumSHA1":"T65qvYBTy4rYks7oN+U0muEqtRw=","path":"github.com/hashicorp/go-memdb","revision":"2b2d6c35e14e7557ea1003e707d5e179fa315028","revisionTime":"2017-07-25T22:15:03Z"}, + {"checksumSHA1":"TNlVzNR1OaajcNi3CbQ3bGbaLGU=","path":"github.com/hashicorp/go-msgpack/codec","revision":"fa3f63826f7c23912c15263591e65d54d080b458","revisionTime":"2015-05-18T23:42:57Z"}, + {"checksumSHA1":"lrSl49G23l6NhfilxPM0XFs5rZo=","path":"github.com/hashicorp/go-multierror","revision":"d30f09973e19c1dfcd120b2d9c4f168e68d6b5d5","revisionTime":"2015-09-16T20:57:42Z"}, + {"checksumSHA1":"ErJHGU6AVPZM9yoY/xV11TwSjQs=","path":"github.com/hashicorp/go-retryablehttp","revision":"6e85be8fee1dcaa02c0eaaac2df5a8fbecf94145","revisionTime":"2016-09-30T03:51:02Z"}, + {"checksumSHA1":"A1PcINvF3UiwHRKn8UcgARgvGRs=","path":"github.com/hashicorp/go-rootcerts","revision":"6bb64b370b90e7ef1fa532be9e591a81c3493e00","revisionTime":"2016-05-03T14:34:40Z"}, + {"checksumSHA1":"GP24Vz4EmZAL1ZH2TYTkDiiCO94=","path":"github.com/hashicorp/go-sockaddr","revision":"2d10d7c10258d11196c0ebf2943509e4afd06cd4","revisionTime":"2017-05-23T22:50:28Z"}, + {"checksumSHA1":"mIUCMmRHslN2bxQZ0uObMnXxk9E=","path":"github.com/hashicorp/go-sockaddr/template","revision":"2d10d7c10258d11196c0ebf2943509e4afd06cd4","revisionTime":"2017-05-23T22:50:28Z"}, + {"checksumSHA1":"xZ7Ban1x//6uUIU1xtrTbCYNHBc=","path":"github.com/hashicorp/go-syslog","revision":"42a2b573b664dbf281bd48c3cc12c086b17a39ba","revisionTime":"2015-02-18T18:19:46Z"}, + {"checksumSHA1":"mAkPa/RLuIwN53GbwIEMATexams=","path":"github.com/hashicorp/go-uuid","revision":"64130c7a86d732268a38cb04cfbaf0cc987fda98","revisionTime":"2016-07-17T02:21:40Z"}, + {"checksumSHA1":"tUGxc7rfX0cmhOOUDhMuAZ9rWsA=","path":"github.com/hashicorp/go-version","revision":"03c5bf6be031b6dd45afec16b1cf94fc8938bc77","revisionTime":"2017-02-02T08:07:59Z"}, + {"checksumSHA1":"d9PxF1XQGLMJZRct2R8qVM/eYlE=","path":"github.com/hashicorp/golang-lru","revision":"a0d98a5f288019575c6d1f4bb1573fef2d1fcdc4","revisionTime":"2016-02-07T21:47:19Z"}, + {"checksumSHA1":"2nOpYjx8Sn57bqlZq17yM4YJuM4=","path":"github.com/hashicorp/golang-lru/simplelru","revision":"a0d98a5f288019575c6d1f4bb1573fef2d1fcdc4","revisionTime":"2016-02-07T21:47:19Z"}, + {"checksumSHA1":"ydHBPi04mEh+Tir+2JkpSIMckcw=","path":"github.com/hashicorp/hcl","revision":"d8c773c4cba11b11539e3d45f93daeaa5dcf1fa1","revisionTime":"2016-07-11T23:17:52Z"}, + {"checksumSHA1":"IxyvRpCFeoJBGl2obLKJV7RCGjg=","path":"github.com/hashicorp/hcl/hcl/ast","revision":"d8c773c4cba11b11539e3d45f93daeaa5dcf1fa1","revisionTime":"2016-07-11T23:17:52Z"}, + {"checksumSHA1":"l2oQxBsZRwn6eZjf+whXr8c9+8c=","path":"github.com/hashicorp/hcl/hcl/parser","revision":"d8c773c4cba11b11539e3d45f93daeaa5dcf1fa1","revisionTime":"2016-07-11T23:17:52Z"}, + {"checksumSHA1":"vjhDQVlgHhdxml1V8/cj0vOe+j8=","path":"github.com/hashicorp/hcl/hcl/scanner","revision":"d8c773c4cba11b11539e3d45f93daeaa5dcf1fa1","revisionTime":"2016-07-11T23:17:52Z"}, + {"checksumSHA1":"JlZmnzqdmFFyb1+2afLyR3BOE/8=","path":"github.com/hashicorp/hcl/hcl/strconv","revision":"d8c773c4cba11b11539e3d45f93daeaa5dcf1fa1","revisionTime":"2016-07-11T23:17:52Z"}, + {"checksumSHA1":"c6yprzj06ASwCo18TtbbNNBHljA=","path":"github.com/hashicorp/hcl/hcl/token","revision":"d8c773c4cba11b11539e3d45f93daeaa5dcf1fa1","revisionTime":"2016-07-11T23:17:52Z"}, + {"checksumSHA1":"jQ45CCc1ed/nlV7bbSnx6z72q1M=","path":"github.com/hashicorp/hcl/json/parser","revision":"d8c773c4cba11b11539e3d45f93daeaa5dcf1fa1","revisionTime":"2016-07-11T23:17:52Z"}, + {"checksumSHA1":"S1e0F9ZKSnqgOLfjDTYazRL28tA=","path":"github.com/hashicorp/hcl/json/scanner","revision":"d8c773c4cba11b11539e3d45f93daeaa5dcf1fa1","revisionTime":"2016-07-11T23:17:52Z"}, + {"checksumSHA1":"fNlXQCQEnb+B3k5UDL/r15xtSJY=","path":"github.com/hashicorp/hcl/json/token","revision":"d8c773c4cba11b11539e3d45f93daeaa5dcf1fa1","revisionTime":"2016-07-11T23:17:52Z"}, + {"checksumSHA1":"kqCMCHy2b+RBMKC+ER+OPqp8C3E=","path":"github.com/hashicorp/hil","revision":"1e86c6b523c55d1fa6c6e930ce80b548664c95c2","revisionTime":"2016-07-11T23:18:37Z"}, + {"checksumSHA1":"UICubs001+Q4MsUf9zl2vcMzWQQ=","path":"github.com/hashicorp/hil/ast","revision":"1e86c6b523c55d1fa6c6e930ce80b548664c95c2","revisionTime":"2016-07-11T23:18:37Z"}, + {"checksumSHA1":"vt+P9D2yWDO3gdvdgCzwqunlhxU=","path":"github.com/hashicorp/logutils","revision":"0dc08b1671f34c4250ce212759ebd880f743d883","revisionTime":"2015-06-09T07:04:31Z"}, + {"checksumSHA1":"ml0MTqOsKTrsqv/mZhy78Vz4SfA=","path":"github.com/hashicorp/memberlist","revision":"d6c1fb0b99c33d0a8e22acea9da9709b369b5d39","revisionTime":"2017-08-15T22:46:17Z"}, + {"checksumSHA1":"qnlqWJYV81ENr61SZk9c65R1mDo=","path":"github.com/hashicorp/net-rpc-msgpackrpc","revision":"a14192a58a694c123d8fe5481d4a4727d6ae82f3","revisionTime":"2015-11-16T02:03:38Z"}, + {"checksumSHA1":"f2QYddVWZ2eWxdlCEhearTH4XOs=","path":"github.com/hashicorp/raft","revision":"c837e57a6077e74a4a3749959fb6cfefc26d7705","revisionTime":"2017-08-30T14:31:53Z","version":"library-v2-stage-one","versionExact":"library-v2-stage-one"}, + {"checksumSHA1":"QAxukkv54/iIvLfsUP6IK4R0m/A=","path":"github.com/hashicorp/raft-boltdb","revision":"d1e82c1ec3f15ee991f7cc7ffd5b67ff6f5bbaee","revisionTime":"2015-02-01T20:08:39Z"}, + {"checksumSHA1":"/oss17GO4hXGM7QnUdI3VzcAHzA=","comment":"v0.7.0-66-g6c4672d","path":"github.com/hashicorp/serf/coordinate","revision":"c2e4be24cdc9031eb0ad869c5d160775efdf7d7a","revisionTime":"2017-05-25T23:15:04Z"}, + {"checksumSHA1":"3WPnGSL9ZK6EmkAE6tEW5SCxrd8=","comment":"v0.7.0-66-g6c4672d","path":"github.com/hashicorp/serf/serf","revision":"b84a66cc5575994cb672940d244a2404141688c0","revisionTime":"2017-08-17T21:22:02Z"}, + {"checksumSHA1":"ZhK6IO2XN81Y+3RAjTcVm1Ic7oU=","path":"github.com/hashicorp/yamux","revision":"d1caa6c97c9fc1cc9e83bbe34d0603f9ff0ce8bd","revisionTime":"2016-07-20T23:31:40Z"}, + {"checksumSHA1":"xZuhljnmBysJPta/lMyYmJdujCg=","path":"github.com/mattn/go-isatty","revision":"66b8e73f3f5cda9f96b69efd03dd3d7fc4a5cdb8","revisionTime":"2016-08-06T12:27:52Z"}, + {"checksumSHA1":"OUZ1FFXyKs+Cfg9M9rmXqqweQck=","path":"github.com/miekg/dns","revision":"db96a2b759cdef4f11a34506a42eb8d1290c598e","revisionTime":"2016-07-26T03:20:27Z"}, + {"checksumSHA1":"GzfpPGtV2UJH9hFsKwzGjKrhp/A=","path":"github.com/mitchellh/cli","revision":"dff723fff508858a44c1f4bd0911f00d73b0202f","revisionTime":"2017-09-05T22:10:09Z"}, + {"checksumSHA1":"86nE93o1VIND0Doe8PuhCXnhUx0=","path":"github.com/mitchellh/copystructure","revision":"cdac8253d00f2ecf0a0b19fbff173a9a72de4f82","revisionTime":"2016-08-04T03:23:30Z"}, + {"checksumSHA1":"V/quM7+em2ByJbWBLOsEwnY3j/Q=","path":"github.com/mitchellh/go-homedir","revision":"b8bc1bf767474819792c23f32d8286a45736f1c6","revisionTime":"2016-12-03T19:45:07Z"}, + {"checksumSHA1":"LUrnGREfnifW4WDMaavmc9MlLI0=","path":"github.com/mitchellh/mapstructure","revision":"ca63d7c062ee3c9f34db231e352b60012b4fd0c1","revisionTime":"2016-08-08T18:12:53Z"}, + {"checksumSHA1":"mrqMlK6gqe//WsJSrJ1HgkPM0lM=","path":"github.com/mitchellh/reflectwalk","revision":"eecf4c70c626c7cfbb95c90195bc34d386c74ac6","revisionTime":"2015-05-27T15:31:53Z"}, + {"checksumSHA1":"5h+ERzHw3Rl2G0kFPxoJzxiA9s0=","path":"github.com/pascaldekloe/goe/verify","revision":"07ebd1e2481f616a278ab431cf04cc5cf5ab3ebe","revisionTime":"2017-03-28T18:37:59Z"}, + {"checksumSHA1":"ynJSWoF6v+3zMnh9R0QmmG6iGV8=","path":"github.com/pkg/errors","revision":"ff09b135c25aae272398c51a07235b90a75aa4f0","revisionTime":"2017-03-16T20:15:38Z","tree":true}, + {"checksumSHA1":"rTNABfFJ9wtLQRH8uYNkEZGQOrY=","path":"github.com/posener/complete","revision":"9f41f7636a724791a3b8b1d35e84caa1124f0d3c","revisionTime":"2017-08-29T17:11:12Z"}, + {"checksumSHA1":"NB7uVS0/BJDmNu68vPAlbrq4TME=","path":"github.com/posener/complete/cmd","revision":"9f41f7636a724791a3b8b1d35e84caa1124f0d3c","revisionTime":"2017-08-29T17:11:12Z"}, + {"checksumSHA1":"gSX86Xl0w9hvtntdT8h23DZtSag=","path":"github.com/posener/complete/cmd/install","revision":"9f41f7636a724791a3b8b1d35e84caa1124f0d3c","revisionTime":"2017-08-29T17:11:12Z"}, + {"checksumSHA1":"DMo94FwJAm9ZCYCiYdJU2+bh4no=","path":"github.com/posener/complete/match","revision":"9f41f7636a724791a3b8b1d35e84caa1124f0d3c","revisionTime":"2017-08-29T17:11:12Z"}, + {"checksumSHA1":"ExnVEVNT8APpFTm26cUb5T09yR4=","comment":"v2.0.1-8-g983d3a5","path":"github.com/ryanuber/columnize","revision":"9b3edd62028f107d7cabb19353292afd29311a4e","revisionTime":"2016-07-12T16:32:29Z"}, + {"checksumSHA1":"A/YUMbGg1LHIeK2+NLZBt+MIAao=","path":"github.com/sean-/seed","revision":"3c72d44db0c567f7c901f9c5da5fe68392227750","revisionTime":"2017-02-08T16:47:21Z"}, + {"checksumSHA1":"zW2k8E1gkuySzTz2eXuSEDhpffY=","path":"github.com/shirou/gopsutil/cpu","revision":"32b6636de04b303274daac3ca2b10d3b0e4afc35","revisionTime":"2017-02-04T05:36:48Z"}, + {"checksumSHA1":"GsqEEmGv6sj8DreS2SYXRkoZ9NI=","path":"github.com/shirou/gopsutil/host","revision":"b62e301a8b9958eebb7299683eb57fab229a9501","revisionTime":"2017-02-08T02:55:55Z"}, + {"checksumSHA1":"hz9RxkaV3Tnju2eiHBWO/Yv7n5c=","path":"github.com/shirou/gopsutil/internal/common","revision":"32b6636de04b303274daac3ca2b10d3b0e4afc35","revisionTime":"2017-02-04T05:36:48Z"}, + {"checksumSHA1":"XQwjGKI51Y3aQ3/jNyRh9Gnprgg=","path":"github.com/shirou/gopsutil/mem","revision":"32b6636de04b303274daac3ca2b10d3b0e4afc35","revisionTime":"2017-02-04T05:36:48Z"}, + {"checksumSHA1":"OSvOZs5uK5iolCOeS46nB2InVy8=","path":"github.com/shirou/gopsutil/net","revision":"32b6636de04b303274daac3ca2b10d3b0e4afc35","revisionTime":"2017-02-04T05:36:48Z"}, + {"checksumSHA1":"JX0bRK/BdKVfbm4XOxMducVdY58=","path":"github.com/shirou/gopsutil/process","revision":"32b6636de04b303274daac3ca2b10d3b0e4afc35","revisionTime":"2017-02-04T05:36:48Z"}, + {"checksumSHA1":"Nve7SpDmjsv6+rhkXAkfg/UQx94=","path":"github.com/shirou/w32","revision":"bb4de0191aa41b5507caa14b0650cdbddcd9280b","revisionTime":"2016-09-30T03:27:40Z"}, + {"checksumSHA1":"t24KnvC9jRxiANVhpw2pqFpmEu8=","path":"github.com/tonnerre/golang-text","revision":"048ed3d792f7104850acbc8cfc01e5a6070f4c04","revisionTime":"2013-09-25T19:58:46Z"}, + {"checksumSHA1":"9jjO5GjLa0XF/nfWihF02RoH4qc=","path":"golang.org/x/net/context","revision":"075e191f18186a8ff2becaf64478e30f4545cdad","revisionTime":"2016-08-05T06:12:51Z"}, + {"checksumSHA1":"WHc3uByvGaMcnSoI21fhzYgbOgg=","path":"golang.org/x/net/context/ctxhttp","revision":"075e191f18186a8ff2becaf64478e30f4545cdad","revisionTime":"2016-08-05T06:12:51Z"}, + {"checksumSHA1":"vlicYp+fe4ECQ+5QqpAk36VRA3s=","path":"golang.org/x/sys/unix","revision":"cd2c276457edda6df7fb04895d3fd6a6add42926","revisionTime":"2017-07-17T10:05:24Z"}, + {"checksumSHA1":"vGfePfr0+weQUeTM/71mu+LCFuE=","path":"golang.org/x/time/rate","revision":"8be79e1e0910c292df4e79c241bb7e8f7e725959","revisionTime":"2017-04-24T23:28:54Z"} ], "rootPath": "github.com/hashicorp/consul" -} +} \ No newline at end of file