add vendor

This commit is contained in:
Malar Invention
2022-04-03 09:37:16 +05:30
parent f96ba5f172
commit 00ebcd295e
2339 changed files with 705854 additions and 0 deletions

16
vendor/github.com/mitchellh/cli/.travis.yml generated vendored Normal file
View File

@ -0,0 +1,16 @@
sudo: false
language: go
env:
- GO111MODULE=on
go:
- "1.14"
- "1.15"
branches:
only:
- master
script: make updatedeps test testrace

354
vendor/github.com/mitchellh/cli/LICENSE generated vendored Normal file
View File

@ -0,0 +1,354 @@
Mozilla Public License, version 2.0
1. Definitions
1.1. “Contributor”
means each individual or legal entity that creates, contributes to the
creation of, or owns Covered Software.
1.2. “Contributor Version”
means the combination of the Contributions of others (if any) used by a
Contributor and that particular Contributors Contribution.
1.3. “Contribution”
means Covered Software of a particular Contributor.
1.4. “Covered Software”
means Source Code Form to which the initial Contributor has attached the
notice in Exhibit A, the Executable Form of such Source Code Form, and
Modifications of such Source Code Form, in each case including portions
thereof.
1.5. “Incompatible With Secondary Licenses”
means
a. that the initial Contributor has attached the notice described in
Exhibit B to the Covered Software; or
b. that the Covered Software was made available under the terms of version
1.1 or earlier of the License, but not also under the terms of a
Secondary License.
1.6. “Executable Form”
means any form of the work other than Source Code Form.
1.7. “Larger Work”
means a work that combines Covered Software with other material, in a separate
file or files, that is not Covered Software.
1.8. “License”
means this document.
1.9. “Licensable”
means having the right to grant, to the maximum extent possible, whether at the
time of the initial grant or subsequently, any and all of the rights conveyed by
this License.
1.10. “Modifications”
means any of the following:
a. any file in Source Code Form that results from an addition to, deletion
from, or modification of the contents of Covered Software; or
b. any new file in Source Code Form that contains any Covered Software.
1.11. “Patent Claims” of a Contributor
means any patent claim(s), including without limitation, method, process,
and apparatus claims, in any patent Licensable by such Contributor that
would be infringed, but for the grant of the License, by the making,
using, selling, offering for sale, having made, import, or transfer of
either its Contributions or its Contributor Version.
1.12. “Secondary License”
means either the GNU General Public License, Version 2.0, the GNU Lesser
General Public License, Version 2.1, the GNU Affero General Public
License, Version 3.0, or any later versions of those licenses.
1.13. “Source Code Form”
means the form of the work preferred for making modifications.
1.14. “You” (or “Your”)
means an individual or a legal entity exercising rights under this
License. For legal entities, “You” includes any entity that controls, is
controlled by, or is under common control with You. For purposes of this
definition, “control” means (a) the power, direct or indirect, to cause
the direction or management of such entity, whether by contract or
otherwise, or (b) ownership of more than fifty percent (50%) of the
outstanding shares or beneficial ownership of such entity.
2. License Grants and Conditions
2.1. Grants
Each Contributor hereby grants You a world-wide, royalty-free,
non-exclusive license:
a. under intellectual property rights (other than patent or trademark)
Licensable by such Contributor to use, reproduce, make available,
modify, display, perform, distribute, and otherwise exploit its
Contributions, either on an unmodified basis, with Modifications, or as
part of a Larger Work; and
b. under Patent Claims of such Contributor to make, use, sell, offer for
sale, have made, import, and otherwise transfer either its Contributions
or its Contributor Version.
2.2. Effective Date
The licenses granted in Section 2.1 with respect to any Contribution become
effective for each Contribution on the date the Contributor first distributes
such Contribution.
2.3. Limitations on Grant Scope
The licenses granted in this Section 2 are the only rights granted under this
License. No additional rights or licenses will be implied from the distribution
or licensing of Covered Software under this License. Notwithstanding Section
2.1(b) above, no patent license is granted by a Contributor:
a. for any code that a Contributor has removed from Covered Software; or
b. for infringements caused by: (i) Your and any other third partys
modifications of Covered Software, or (ii) the combination of its
Contributions with other software (except as part of its Contributor
Version); or
c. under Patent Claims infringed by Covered Software in the absence of its
Contributions.
This License does not grant any rights in the trademarks, service marks, or
logos of any Contributor (except as may be necessary to comply with the
notice requirements in Section 3.4).
2.4. Subsequent Licenses
No Contributor makes additional grants as a result of Your choice to
distribute the Covered Software under a subsequent version of this License
(see Section 10.2) or under the terms of a Secondary License (if permitted
under the terms of Section 3.3).
2.5. Representation
Each Contributor represents that the Contributor believes its Contributions
are its original creation(s) or it has sufficient rights to grant the
rights to its Contributions conveyed by this License.
2.6. Fair Use
This License is not intended to limit any rights You have under applicable
copyright doctrines of fair use, fair dealing, or other equivalents.
2.7. Conditions
Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted in
Section 2.1.
3. Responsibilities
3.1. Distribution of Source Form
All distribution of Covered Software in Source Code Form, including any
Modifications that You create or to which You contribute, must be under the
terms of this License. You must inform recipients that the Source Code Form
of the Covered Software is governed by the terms of this License, and how
they can obtain a copy of this License. You may not attempt to alter or
restrict the recipients rights in the Source Code Form.
3.2. Distribution of Executable Form
If You distribute Covered Software in Executable Form then:
a. such Covered Software must also be made available in Source Code Form,
as described in Section 3.1, and You must inform recipients of the
Executable Form how they can obtain a copy of such Source Code Form by
reasonable means in a timely manner, at a charge no more than the cost
of distribution to the recipient; and
b. You may distribute such Executable Form under the terms of this License,
or sublicense it under different terms, provided that the license for
the Executable Form does not attempt to limit or alter the recipients
rights in the Source Code Form under this License.
3.3. Distribution of a Larger Work
You may create and distribute a Larger Work under terms of Your choice,
provided that You also comply with the requirements of this License for the
Covered Software. If the Larger Work is a combination of Covered Software
with a work governed by one or more Secondary Licenses, and the Covered
Software is not Incompatible With Secondary Licenses, this License permits
You to additionally distribute such Covered Software under the terms of
such Secondary License(s), so that the recipient of the Larger Work may, at
their option, further distribute the Covered Software under the terms of
either this License or such Secondary License(s).
3.4. Notices
You may not remove or alter the substance of any license notices (including
copyright notices, patent notices, disclaimers of warranty, or limitations
of liability) contained within the Source Code Form of the Covered
Software, except that You may alter any license notices to the extent
required to remedy known factual inaccuracies.
3.5. Application of Additional Terms
You may choose to offer, and to charge a fee for, warranty, support,
indemnity or liability obligations to one or more recipients of Covered
Software. However, You may do so only on Your own behalf, and not on behalf
of any Contributor. You must make it absolutely clear that any such
warranty, support, indemnity, or liability obligation is offered by You
alone, and You hereby agree to indemnify every Contributor for any
liability incurred by such Contributor as a result of warranty, support,
indemnity or liability terms You offer. You may include additional
disclaimers of warranty and limitations of liability specific to any
jurisdiction.
4. Inability to Comply Due to Statute or Regulation
If it is impossible for You to comply with any of the terms of this License
with respect to some or all of the Covered Software due to statute, judicial
order, or regulation then You must: (a) comply with the terms of this License
to the maximum extent possible; and (b) describe the limitations and the code
they affect. Such description must be placed in a text file included with all
distributions of the Covered Software under this License. Except to the
extent prohibited by statute or regulation, such description must be
sufficiently detailed for a recipient of ordinary skill to be able to
understand it.
5. Termination
5.1. The rights granted under this License will terminate automatically if You
fail to comply with any of its terms. However, if You become compliant,
then the rights granted under this License from a particular Contributor
are reinstated (a) provisionally, unless and until such Contributor
explicitly and finally terminates Your grants, and (b) on an ongoing basis,
if such Contributor fails to notify You of the non-compliance by some
reasonable means prior to 60 days after You have come back into compliance.
Moreover, Your grants from a particular Contributor are reinstated on an
ongoing basis if such Contributor notifies You of the non-compliance by
some reasonable means, this is the first time You have received notice of
non-compliance with this License from such Contributor, and You become
compliant prior to 30 days after Your receipt of the notice.
5.2. If You initiate litigation against any entity by asserting a patent
infringement claim (excluding declaratory judgment actions, counter-claims,
and cross-claims) alleging that a Contributor Version directly or
indirectly infringes any patent, then the rights granted to You by any and
all Contributors for the Covered Software under Section 2.1 of this License
shall terminate.
5.3. In the event of termination under Sections 5.1 or 5.2 above, all end user
license agreements (excluding distributors and resellers) which have been
validly granted by You or Your distributors under this License prior to
termination shall survive termination.
6. Disclaimer of Warranty
Covered Software is provided under this License on an “as is” basis, without
warranty of any kind, either expressed, implied, or statutory, including,
without limitation, warranties that the Covered Software is free of defects,
merchantable, fit for a particular purpose or non-infringing. The entire
risk as to the quality and performance of the Covered Software is with You.
Should any Covered Software prove defective in any respect, You (not any
Contributor) assume the cost of any necessary servicing, repair, or
correction. This disclaimer of warranty constitutes an essential part of this
License. No use of any Covered Software is authorized under this License
except under this disclaimer.
7. Limitation of Liability
Under no circumstances and under no legal theory, whether tort (including
negligence), contract, or otherwise, shall any Contributor, or anyone who
distributes Covered Software as permitted above, be liable to You for any
direct, indirect, special, incidental, or consequential damages of any
character including, without limitation, damages for lost profits, loss of
goodwill, work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses, even if such party shall have been
informed of the possibility of such damages. This limitation of liability
shall not apply to liability for death or personal injury resulting from such
partys negligence to the extent applicable law prohibits such limitation.
Some jurisdictions do not allow the exclusion or limitation of incidental or
consequential damages, so this exclusion and limitation may not apply to You.
8. Litigation
Any litigation relating to this License may be brought only in the courts of
a jurisdiction where the defendant maintains its principal place of business
and such litigation shall be governed by laws of that jurisdiction, without
reference to its conflict-of-law provisions. Nothing in this Section shall
prevent a partys ability to bring cross-claims or counter-claims.
9. Miscellaneous
This License represents the complete agreement concerning the subject matter
hereof. If any provision of this License is held to be unenforceable, such
provision shall be reformed only to the extent necessary to make it
enforceable. Any law or regulation which provides that the language of a
contract shall be construed against the drafter shall not be used to construe
this License against a Contributor.
10. Versions of the License
10.1. New Versions
Mozilla Foundation is the license steward. Except as provided in Section
10.3, no one other than the license steward has the right to modify or
publish new versions of this License. Each version will be given a
distinguishing version number.
10.2. Effect of New Versions
You may distribute the Covered Software under the terms of the version of
the License under which You originally received the Covered Software, or
under the terms of any subsequent version published by the license
steward.
10.3. Modified Versions
If you create software not governed by this License, and you want to
create a new license for such software, you may create and use a modified
version of this License if you rename the license and remove any
references to the name of the license steward (except to note that such
modified license differs from this License).
10.4. Distributing Source Code Form that is Incompatible With Secondary Licenses
If You choose to distribute Source Code Form that is Incompatible With
Secondary Licenses under the terms of this version of the License, the
notice described in Exhibit B of this License must be attached.
Exhibit A - Source Code Form License Notice
This Source Code Form is subject to the
terms of the Mozilla Public License, v.
2.0. If a copy of the MPL was not
distributed with this file, You can
obtain one at
http://mozilla.org/MPL/2.0/.
If it is not possible or desirable to put the notice in a particular file, then
You may include the notice in a location (such as a LICENSE file in a relevant
directory) where a recipient would be likely to look for such a notice.
You may add additional accurate notices of copyright ownership.
Exhibit B - “Incompatible With Secondary Licenses” Notice
This Source Code Form is “Incompatible
With Secondary Licenses”, as defined by
the Mozilla Public License, v. 2.0.

17
vendor/github.com/mitchellh/cli/Makefile generated vendored Normal file
View File

@ -0,0 +1,17 @@
TEST?=./...
default: test
# test runs the test suite and vets the code
test:
go list $(TEST) | xargs -n1 go test -timeout=60s -parallel=10 $(TESTARGS)
# testrace runs the race checker
testrace:
go list $(TEST) | xargs -n1 go test -race $(TESTARGS)
# updatedeps installs all the dependencies to run and build
updatedeps:
go mod download
.PHONY: test testrace updatedeps

67
vendor/github.com/mitchellh/cli/README.md generated vendored Normal file
View File

@ -0,0 +1,67 @@
# Go CLI Library [![GoDoc](https://godoc.org/github.com/mitchellh/cli?status.png)](https://godoc.org/github.com/mitchellh/cli)
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),
[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
* Easy sub-command based CLIs: `cli foo`, `cli bar`, etc.
* Support for nested subcommands such as `cli foo bar`.
* 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.
* Automatic version flag recognition of `-v`, `--version`.
* Helpers for interacting with the terminal, such as outputting information,
asking for input, etc. These are optional, you can always interact with the
terminal however you choose.
* Use of Go interfaces/types makes augmenting various parts of the library a
piece of cake.
## Example
Below is a simple example of creating and running a CLI
```go
package main
import (
"log"
"os"
"github.com/mitchellh/cli"
)
func main() {
c := cli.NewCLI("app", "1.0.0")
c.Args = os.Args[1:]
c.Commands = map[string]cli.CommandFactory{
"foo": fooCommandFactory,
"bar": barCommandFactory,
}
exitStatus, err := c.Run()
if err != nil {
log.Println(err)
}
os.Exit(exitStatus)
}
```

43
vendor/github.com/mitchellh/cli/autocomplete.go generated vendored Normal file
View File

@ -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
}

741
vendor/github.com/mitchellh/cli/cli.go generated vendored Normal file
View File

@ -0,0 +1,741 @@
package cli
import (
"fmt"
"io"
"io/ioutil"
"os"
"regexp"
"sort"
"strings"
"sync"
"text/template"
"github.com/Masterminds/sprig"
"github.com/armon/go-radix"
"github.com/posener/complete"
)
// CLI contains the state necessary to run subcommands and parse the
// command line arguments.
//
// CLI also supports nested subcommands, such as "cli foo bar". To use
// nested subcommands, the key in the Commands mapping below contains the
// full subcommand. In this example, it would be "foo bar".
//
// If you use a CLI with nested subcommands, some semantics change due to
// ambiguities:
//
// * 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" 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.
//
// * The help flag "-h" or "-help" will look at all args to determine
// the help function. For example: "otto apps list -h" will show the
// help for "apps list" but "otto apps -h" will show it for "apps".
// In the normal CLI, only the first subcommand is used.
//
// * The help flag will list any subcommands that a command takes
// as well as the command's help itself. If there are no subcommands,
// it will note this. If the CLI itself has no subcommands, this entire
// section is omitted.
//
// * Any parent commands that don't exist are automatically created as
// no-op commands that just show help for other subcommands. For example,
// if you only register "foo bar", then "foo" is automatically created.
//
type CLI struct {
// Args is the list of command-line arguments received excluding
// the name of the app. For example, if the command "./cli foo bar"
// was invoked, then Args should be []string{"foo", "bar"}.
Args []string
// Commands is a mapping of subcommand names to a factory function
// for creating that Command implementation. If there is a command
// with a blank string "", then it will be used as the default command
// if no subcommand is specified.
//
// If the key has a space in it, this will create a nested subcommand.
// For example, if the key is "foo bar", then to access it our CLI
// must be accessed with "./cli foo bar". See the docs for CLI for
// notes on how this changes some other behavior of the CLI as well.
//
// The factory should be as cheap as possible, ideally only allocating
// a struct. The factory may be called multiple times in the course
// of a command execution and certain events such as help require the
// instantiation of all commands. Expensive initialization should be
// deferred to function calls within the interface implementation.
Commands map[string]CommandFactory
// HiddenCommands is a list of commands that are "hidden". Hidden
// commands are not given to the help function callback and do not
// show up in autocomplete. The values in the slice should be equivalent
// to the keys in the command map.
HiddenCommands []string
// Name defines the name of the CLI.
Name string
// 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 bash, zsh and fish. 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 is the function called to generate the generic help
// text that is shown if help must be shown for the CLI that doesn't
// pertain to a specific command.
HelpFunc HelpFunc
// HelpWriter is used to print help text and version when requested.
// Defaults to os.Stderr for backwards compatibility.
// It is recommended that you set HelpWriter to os.Stdout, and
// ErrorWriter to os.Stderr.
HelpWriter io.Writer
// ErrorWriter used to output errors when a command can not be run.
// Defaults to the value of HelpWriter for backwards compatibility.
// It is recommended that you set HelpWriter to os.Stdout, and
// ErrorWriter to os.Stderr.
ErrorWriter io.Writer
//---------------------------------------------------------------
// Internal fields set automatically
once sync.Once
autocomplete *complete.Complete
commandTree *radix.Tree
commandNested bool
commandHidden map[string]struct{}
subcommand string
subcommandArgs []string
topFlags []string
// 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),
Autocomplete: true,
}
}
// IsHelp returns whether or not the help flag is present within the
// arguments.
func (c *CLI) IsHelp() bool {
c.once.Do(c.init)
return c.isHelp
}
// IsVersion returns whether or not the version flag is present within the
// arguments.
func (c *CLI) IsVersion() bool {
c.once.Do(c.init)
return c.isVersion
}
// Run runs the actual CLI based on the arguments given.
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"))
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.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())
if !ok {
c.ErrorWriter.Write([]byte(c.HelpFunc(c.helpCommands(c.subcommandParent())) + "\n"))
return 127, nil
}
command, err := raw.(CommandFactory)()
if err != nil {
return 1, err
}
// If we've been instructed to just print the help, then print it
if c.IsHelp() {
c.commandHelp(c.HelpWriter, command)
return 0, nil
}
// If there is an invalid flag, then error
if len(c.topFlags) > 0 {
c.ErrorWriter.Write([]byte(
"Invalid flags before the subcommand. If these flags are for\n" +
"the subcommand, please put them after the subcommand.\n\n"))
c.commandHelp(c.ErrorWriter, command)
return 1, nil
}
code := command.Run(c.SubcommandArgs())
if code == RunResultHelp {
// Requesting help
c.commandHelp(c.ErrorWriter, command)
return 1, nil
}
return code, nil
}
// Subcommand returns the subcommand that the CLI would execute. For
// example, a CLI from "--version version --help" would return a Subcommand
// of "version"
func (c *CLI) Subcommand() string {
c.once.Do(c.init)
return c.subcommand
}
// SubcommandArgs returns the arguments that will be passed to the
// subcommand.
func (c *CLI) SubcommandArgs() []string {
c.once.Do(c.init)
return c.subcommandArgs
}
// subcommandParent returns the parent of this subcommand, if there is one.
// If there isn't on, "" is returned.
func (c *CLI) subcommandParent() string {
// Get the subcommand, if it is "" alread just return
sub := c.Subcommand()
if sub == "" {
return sub
}
// Clear any trailing spaces and find the last space
sub = strings.TrimRight(sub, " ")
idx := strings.LastIndex(sub, " ")
if idx == -1 {
// No space means our parent is root
return ""
}
return sub[:idx]
}
func (c *CLI) init() {
if c.HelpFunc == nil {
c.HelpFunc = BasicHelpFunc("app")
if c.Name != "" {
c.HelpFunc = BasicHelpFunc(c.Name)
}
}
if c.HelpWriter == nil {
c.HelpWriter = os.Stderr
}
if c.ErrorWriter == nil {
c.ErrorWriter = c.HelpWriter
}
// Build our hidden commands
if len(c.HiddenCommands) > 0 {
c.commandHidden = make(map[string]struct{})
for _, h := range c.HiddenCommands {
c.commandHidden[h] = struct{}{}
}
}
// Build our command tree
c.commandTree = radix.New()
c.commandNested = false
for k, v := range c.Commands {
k = strings.TrimSpace(k)
c.commandTree.Insert(k, v)
if strings.ContainsRune(k, ' ') {
c.commandNested = true
}
}
// Go through the key and fill in any missing parent commands
if c.commandNested {
var walkFn radix.WalkFn
toInsert := make(map[string]struct{})
walkFn = func(k string, raw interface{}) bool {
idx := strings.LastIndex(k, " ")
if idx == -1 {
// If there is no space, just ignore top level commands
return false
}
// Trim up to that space so we can get the expected parent
k = k[:idx]
if _, ok := c.commandTree.Get(k); ok {
// Yay we have the parent!
return false
}
// We're missing the parent, so let's insert this
toInsert[k] = struct{}{}
// Call the walk function recursively so we check this one too
return walkFn(k, nil)
}
// Walk!
c.commandTree.Walk(walkFn)
// Insert any that we're missing
for k := range toInsert {
var f CommandFactory = func() (Command, error) {
return &MockCommand{
HelpText: "This command is accessed by using one of the subcommands below.",
RunResult: RunResultHelp,
}, nil
}
c.commandTree.Insert(k, f)
}
}
// 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{}
}
// We first set c.autocomplete to a noop autocompleter that outputs
// to nul so that we can detect if we're autocompleting or not. If we're
// not, then we do nothing. This saves a LOT of compute cycles since
// initAutoCompleteSub has to walk every command.
c.autocomplete = complete.New(c.Name, complete.Command{})
c.autocomplete.Out = ioutil.Discard
if !c.autocomplete.Complete() {
return
}
// 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 {
// Ignore the empty key which can be present for default commands.
if k == "" {
return false
}
// 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 the command is hidden, don't record it at all
if _, ok := c.commandHidden[fullKey]; ok {
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(out io.Writer, command Command) {
// Get the template to use
tpl := strings.TrimSpace(defaultHelpTemplate)
if t, ok := command.(CommandHelpTemplate); ok {
tpl = t.HelpTemplate()
}
if !strings.HasSuffix(tpl, "\n") {
tpl += "\n"
}
// Parse it
t, err := template.New("root").Funcs(sprig.TxtFuncMap()).Parse(tpl)
if err != nil {
t = template.Must(template.New("root").Parse(fmt.Sprintf(
"Internal error! Failed to parse command help template: %s\n", err)))
}
// Template data
data := map[string]interface{}{
"Name": c.Name,
"SubcommandName": c.Subcommand(),
"Help": command.Help(),
}
// Build subcommand list if we have it
var subcommandsTpl []map[string]interface{}
if c.commandNested {
// Get the matching keys
subcommands := c.helpCommands(c.Subcommand())
keys := make([]string, 0, len(subcommands))
for k := range subcommands {
keys = append(keys, k)
}
// Sort the keys
sort.Strings(keys)
// Figure out the padding length
var longest int
for _, k := range keys {
if v := len(k); v > longest {
longest = v
}
}
// Go through and create their structures
subcommandsTpl = make([]map[string]interface{}, 0, len(subcommands))
for _, k := range keys {
// Get the command
raw, ok := subcommands[k]
if !ok {
c.ErrorWriter.Write([]byte(fmt.Sprintf(
"Error getting subcommand %q", k)))
}
sub, err := raw()
if err != nil {
c.ErrorWriter.Write([]byte(fmt.Sprintf(
"Error instantiating %q: %s", k, err)))
}
// Find the last space and make sure we only include that last part
name := k
if idx := strings.LastIndex(k, " "); idx > -1 {
name = name[idx+1:]
}
subcommandsTpl = append(subcommandsTpl, map[string]interface{}{
"Name": name,
"NameAligned": name + strings.Repeat(" ", longest-len(k)),
"Help": sub.Help(),
"Synopsis": sub.Synopsis(),
})
}
}
data["Subcommands"] = subcommandsTpl
// Write
err = t.Execute(out, data)
if err == nil {
return
}
// An error, just output...
c.ErrorWriter.Write([]byte(fmt.Sprintf(
"Internal error rendering help: %s", err)))
}
// helpCommands returns the subcommands for the HelpFunc argument.
// This will only contain immediate subcommands.
func (c *CLI) helpCommands(prefix string) map[string]CommandFactory {
// If our prefix isn't empty, make sure it ends in ' '
if prefix != "" && prefix[len(prefix)-1] != ' ' {
prefix += " "
}
// Get all the subkeys of this command
var keys []string
c.commandTree.WalkPrefix(prefix, func(k string, raw interface{}) bool {
// Ignore any sub-sub keys, i.e. "foo bar baz" when we want "foo bar"
if !strings.Contains(k[len(prefix):], " ") {
keys = append(keys, k)
}
return false
})
// For each of the keys return that in the map
result := make(map[string]CommandFactory, len(keys))
for _, k := range keys {
raw, ok := c.commandTree.Get(k)
if !ok {
// We just got it via WalkPrefix above, so we just panic
panic("not found: " + k)
}
// If this is a hidden command, don't show it
if _, ok := c.commandHidden[k]; ok {
continue
}
result[k] = raw.(CommandFactory)
}
return result
}
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
}
// 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" {
c.isVersion = true
continue
}
if arg != "" && arg[0] == '-' {
// Record the arg...
c.topFlags = append(c.topFlags, arg)
}
}
// If we didn't find a subcommand yet and this is the first non-flag
// argument, then this is our subcommand.
if c.subcommand == "" && arg != "" && arg[0] != '-' {
c.subcommand = arg
if c.commandNested {
// If the command has a space in it, then it is invalid.
// Set a blank command so that it fails.
if strings.ContainsRune(arg, ' ') {
c.subcommand = ""
return
}
// Determine the argument we look to to end subcommands.
// We look at all arguments until one has a space. This
// disallows commands like: ./cli foo "bar baz". An argument
// with a space is always an argument.
j := 0
for k, v := range c.Args[i:] {
if strings.ContainsRune(v, ' ') {
break
}
j = i + k + 1
}
// Nested CLI, the subcommand is actually the entire
// arg list up to a flag that is still a valid subcommand.
searchKey := strings.Join(c.Args[i:j], " ")
k, _, ok := c.commandTree.LongestPrefix(searchKey)
if ok {
// 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, " ")
}
}
}
// The remaining args the subcommand arguments
c.subcommandArgs = c.Args[i+1:]
}
}
// If we never found a subcommand and support a default command, then
// switch to using that.
if c.subcommand == "" {
if _, ok := c.Commands[""]; ok {
args := c.topFlags
args = append(args, c.subcommandArgs...)
c.topFlags = nil
c.subcommandArgs = args
}
}
}
// 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}}
Subcommands:
{{- range $value := .Subcommands }}
{{ $value.NameAligned }} {{ $value.Synopsis }}{{ end }}
{{- end }}
`

67
vendor/github.com/mitchellh/cli/command.go generated vendored Normal file
View File

@ -0,0 +1,67 @@
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.
RunResultHelp = -18511
)
// A command is a runnable sub-command of a CLI.
type Command interface {
// Help should return long-form help text that includes the command-line
// usage, a brief few sentences explaining the function of the command,
// and the complete list of flags the command accepts.
Help() string
// Run should run the actual command with the given CLI instance and
// command-line arguments. It should return the exit status when it is
// finished.
//
// There are a handful of special exit codes this can return documented
// above that change behavior.
Run(args []string) int
// Synopsis should return a one-line, short synopsis of the command.
// This should be less than 50 characters ideally.
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.
//
// If CommandHelpTemplate isn't implemented, the Help is output as-is.
type CommandHelpTemplate interface {
// HelpTemplate is the template in text/template format to use for
// displaying the Help. The keys available are:
//
// * ".Help" - The help text itself
// * ".Subcommands"
//
HelpTemplate() string
}
// CommandFactory is a type of function that is a factory for commands.
// We need a factory because we may need to setup some state on the
// struct that implements the command itself.
type CommandFactory func() (Command, error)

63
vendor/github.com/mitchellh/cli/command_mock.go generated vendored Normal file
View File

@ -0,0 +1,63 @@
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.
type MockCommand struct {
// Settable
HelpText string
RunResult int
SynopsisText string
// Set by the command
RunCalled bool
RunArgs []string
}
func (c *MockCommand) Help() string {
return c.HelpText
}
func (c *MockCommand) Run(args []string) int {
c.RunCalled = true
c.RunArgs = args
return c.RunResult
}
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
// Settable
HelpTemplateText string
}
func (c *MockCommandHelpTemplate) HelpTemplate() string {
return c.HelpTemplateText
}

79
vendor/github.com/mitchellh/cli/help.go generated vendored Normal file
View File

@ -0,0 +1,79 @@
package cli
import (
"bytes"
"fmt"
"log"
"sort"
"strings"
)
// HelpFunc is the type of the function that is responsible for generating
// the help output when the CLI must show the general help text.
type HelpFunc func(map[string]CommandFactory) string
// BasicHelpFunc generates some basic help output that is usually good enough
// for most CLI applications.
func BasicHelpFunc(app string) HelpFunc {
return func(commands map[string]CommandFactory) string {
var buf bytes.Buffer
buf.WriteString(fmt.Sprintf(
"Usage: %s [--version] [--help] <command> [<args>]\n\n",
app))
buf.WriteString("Available commands are:\n")
// Get the list of keys so we can sort them, and also get the maximum
// key length so they can be aligned properly.
keys := make([]string, 0, len(commands))
maxKeyLen := 0
for key := range commands {
if len(key) > maxKeyLen {
maxKeyLen = len(key)
}
keys = append(keys, key)
}
sort.Strings(keys)
for _, key := range keys {
commandFunc, ok := commands[key]
if !ok {
// This should never happen since we JUST built the list of
// keys.
panic("command not found: " + key)
}
command, err := commandFunc()
if err != nil {
log.Printf("[ERR] cli: Command '%s' failed to load: %s",
key, err)
continue
}
key = fmt.Sprintf("%s%s", key, strings.Repeat(" ", maxKeyLen-len(key)))
buf.WriteString(fmt.Sprintf(" %s %s\n", key, command.Synopsis()))
}
return buf.String()
}
}
// FilteredHelpFunc will filter the commands to only include the keys
// in the include parameter.
func FilteredHelpFunc(include []string, f HelpFunc) HelpFunc {
return func(commands map[string]CommandFactory) string {
set := make(map[string]struct{})
for _, k := range include {
set[k] = struct{}{}
}
filtered := make(map[string]CommandFactory)
for k, f := range commands {
if _, ok := set[k]; ok {
filtered[k] = f
}
}
return f(filtered)
}
}

187
vendor/github.com/mitchellh/cli/ui.go generated vendored Normal file
View File

@ -0,0 +1,187 @@
package cli
import (
"bufio"
"errors"
"fmt"
"io"
"os"
"os/signal"
"strings"
"github.com/bgentry/speakeasy"
"github.com/mattn/go-isatty"
)
// Ui is an interface for interacting with the terminal, or "interface"
// of a CLI. This abstraction doesn't have to be used, but helps provide
// a simple, layerable way to manage user interactions.
type Ui interface {
// Ask asks the user for input using the given query. The response is
// returned as the given string, or an error.
Ask(string) (string, error)
// AskSecret asks the user for input using the given query, but does not echo
// the keystrokes to the terminal.
AskSecret(string) (string, error)
// Output is called for normal standard output.
Output(string)
// Info is called for information related to the previous output.
// In general this may be the exact same as Output, but this gives
// Ui implementors some flexibility with output formats.
Info(string)
// Error is used for any error messages that might appear on standard
// error.
Error(string)
// Warn is used for any warning messages that might appear on standard
// error.
Warn(string)
}
// BasicUi is an implementation of Ui that just outputs to the given
// writer. This UI is not threadsafe by default, but you can wrap it
// in a ConcurrentUi to make it safe.
type BasicUi struct {
Reader io.Reader
Writer io.Writer
ErrorWriter io.Writer
}
func (u *BasicUi) Ask(query string) (string, error) {
return u.ask(query, false)
}
func (u *BasicUi) AskSecret(query string) (string, error) {
return u.ask(query, true)
}
func (u *BasicUi) ask(query string, secret bool) (string, error) {
if _, err := fmt.Fprint(u.Writer, query+" "); err != nil {
return "", err
}
// Register for interrupts so that we can catch it and immediately
// return...
sigCh := make(chan os.Signal, 1)
signal.Notify(sigCh, os.Interrupt)
defer signal.Stop(sigCh)
// Ask for input in a go-routine so that we can ignore it.
errCh := make(chan error, 1)
lineCh := make(chan string, 1)
go func() {
var line string
var err error
if secret && isatty.IsTerminal(os.Stdin.Fd()) {
line, err = speakeasy.Ask("")
} else {
r := bufio.NewReader(u.Reader)
line, err = r.ReadString('\n')
}
if err != nil {
errCh <- err
return
}
lineCh <- strings.TrimRight(line, "\r\n")
}()
select {
case err := <-errCh:
return "", err
case line := <-lineCh:
return line, nil
case <-sigCh:
// Print a newline so that any further output starts properly
// on a new line.
fmt.Fprintln(u.Writer)
return "", errors.New("interrupted")
}
}
func (u *BasicUi) Error(message string) {
w := u.Writer
if u.ErrorWriter != nil {
w = u.ErrorWriter
}
fmt.Fprint(w, message)
fmt.Fprint(w, "\n")
}
func (u *BasicUi) Info(message string) {
u.Output(message)
}
func (u *BasicUi) Output(message string) {
fmt.Fprint(u.Writer, message)
fmt.Fprint(u.Writer, "\n")
}
func (u *BasicUi) Warn(message string) {
u.Error(message)
}
// PrefixedUi is an implementation of Ui that prefixes messages.
type PrefixedUi struct {
AskPrefix string
AskSecretPrefix string
OutputPrefix string
InfoPrefix string
ErrorPrefix string
WarnPrefix string
Ui Ui
}
func (u *PrefixedUi) Ask(query string) (string, error) {
if query != "" {
query = fmt.Sprintf("%s%s", u.AskPrefix, query)
}
return u.Ui.Ask(query)
}
func (u *PrefixedUi) AskSecret(query string) (string, error) {
if query != "" {
query = fmt.Sprintf("%s%s", u.AskSecretPrefix, query)
}
return u.Ui.AskSecret(query)
}
func (u *PrefixedUi) Error(message string) {
if message != "" {
message = fmt.Sprintf("%s%s", u.ErrorPrefix, message)
}
u.Ui.Error(message)
}
func (u *PrefixedUi) Info(message string) {
if message != "" {
message = fmt.Sprintf("%s%s", u.InfoPrefix, message)
}
u.Ui.Info(message)
}
func (u *PrefixedUi) Output(message string) {
if message != "" {
message = fmt.Sprintf("%s%s", u.OutputPrefix, message)
}
u.Ui.Output(message)
}
func (u *PrefixedUi) Warn(message string) {
if message != "" {
message = fmt.Sprintf("%s%s", u.WarnPrefix, message)
}
u.Ui.Warn(message)
}

73
vendor/github.com/mitchellh/cli/ui_colored.go generated vendored Normal file
View File

@ -0,0 +1,73 @@
package cli
import (
"github.com/fatih/color"
)
const (
noColor = -1
)
// UiColor is a posix shell color code to use.
type UiColor struct {
Code int
Bold bool
}
// A list of colors that are useful. These are all non-bolded by default.
var (
UiColorNone UiColor = UiColor{noColor, false}
UiColorRed = UiColor{int(color.FgHiRed), false}
UiColorGreen = UiColor{int(color.FgHiGreen), false}
UiColorYellow = UiColor{int(color.FgHiYellow), false}
UiColorBlue = UiColor{int(color.FgHiBlue), false}
UiColorMagenta = UiColor{int(color.FgHiMagenta), false}
UiColorCyan = UiColor{int(color.FgHiCyan), false}
)
// ColoredUi is a Ui implementation that colors its output according
// to the given color schemes for the given type of output.
type ColoredUi struct {
OutputColor UiColor
InfoColor UiColor
ErrorColor UiColor
WarnColor UiColor
Ui Ui
}
func (u *ColoredUi) Ask(query string) (string, error) {
return u.Ui.Ask(u.colorize(query, u.OutputColor))
}
func (u *ColoredUi) AskSecret(query string) (string, error) {
return u.Ui.AskSecret(u.colorize(query, u.OutputColor))
}
func (u *ColoredUi) Output(message string) {
u.Ui.Output(u.colorize(message, u.OutputColor))
}
func (u *ColoredUi) Info(message string) {
u.Ui.Info(u.colorize(message, u.InfoColor))
}
func (u *ColoredUi) Error(message string) {
u.Ui.Error(u.colorize(message, u.ErrorColor))
}
func (u *ColoredUi) Warn(message string) {
u.Ui.Warn(u.colorize(message, u.WarnColor))
}
func (u *ColoredUi) colorize(message string, uc UiColor) string {
if uc.Code == noColor {
return message
}
attr := []color.Attribute{color.Attribute(uc.Code)}
if uc.Bold {
attr = append(attr, color.Bold)
}
return color.New(attr...).SprintFunc()(message)
}

54
vendor/github.com/mitchellh/cli/ui_concurrent.go generated vendored Normal file
View File

@ -0,0 +1,54 @@
package cli
import (
"sync"
)
// ConcurrentUi is a wrapper around a Ui interface (and implements that
// interface) making the underlying Ui concurrency safe.
type ConcurrentUi struct {
Ui Ui
l sync.Mutex
}
func (u *ConcurrentUi) Ask(query string) (string, error) {
u.l.Lock()
defer u.l.Unlock()
return u.Ui.Ask(query)
}
func (u *ConcurrentUi) AskSecret(query string) (string, error) {
u.l.Lock()
defer u.l.Unlock()
return u.Ui.AskSecret(query)
}
func (u *ConcurrentUi) Error(message string) {
u.l.Lock()
defer u.l.Unlock()
u.Ui.Error(message)
}
func (u *ConcurrentUi) Info(message string) {
u.l.Lock()
defer u.l.Unlock()
u.Ui.Info(message)
}
func (u *ConcurrentUi) Output(message string) {
u.l.Lock()
defer u.l.Unlock()
u.Ui.Output(message)
}
func (u *ConcurrentUi) Warn(message string) {
u.l.Lock()
defer u.l.Unlock()
u.Ui.Warn(message)
}

116
vendor/github.com/mitchellh/cli/ui_mock.go generated vendored Normal file
View File

@ -0,0 +1,116 @@
package cli
import (
"bufio"
"bytes"
"fmt"
"io"
"strings"
"sync"
)
// 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 *syncBuffer
OutputWriter *syncBuffer
once sync.Once
}
func (u *MockUi) Ask(query string) (string, error) {
u.once.Do(u.init)
var result string
fmt.Fprint(u.OutputWriter, query)
r := bufio.NewReader(u.InputReader)
line, err := r.ReadString('\n')
if err != nil {
return "", err
}
result = strings.TrimRight(line, "\r\n")
return result, nil
}
func (u *MockUi) AskSecret(query string) (string, error) {
return u.Ask(query)
}
func (u *MockUi) Error(message string) {
u.once.Do(u.init)
fmt.Fprint(u.ErrorWriter, message)
fmt.Fprint(u.ErrorWriter, "\n")
}
func (u *MockUi) Info(message string) {
u.Output(message)
}
func (u *MockUi) Output(message string) {
u.once.Do(u.init)
fmt.Fprint(u.OutputWriter, message)
fmt.Fprint(u.OutputWriter, "\n")
}
func (u *MockUi) Warn(message string) {
u.once.Do(u.init)
fmt.Fprint(u.ErrorWriter, message)
fmt.Fprint(u.ErrorWriter, "\n")
}
func (u *MockUi) init() {
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 {
return string(b.Bytes())
}
func (b *syncBuffer) Bytes() []byte {
b.RLock()
data := b.b.Bytes()
b.RUnlock()
return data
}

18
vendor/github.com/mitchellh/cli/ui_writer.go generated vendored Normal file
View File

@ -0,0 +1,18 @@
package cli
// UiWriter is an io.Writer implementation that can be used with
// loggers that writes every line of log output data to a Ui at the
// Info level.
type UiWriter struct {
Ui Ui
}
func (w *UiWriter) Write(p []byte) (n int, err error) {
n = len(p)
if n > 0 && p[n-1] == '\n' {
p = p[:n-1]
}
w.Ui.Info(string(p))
return n, nil
}