aboutsummaryrefslogtreecommitdiffhomepage
path: root/vendor/github.com/mitchellh
diff options
context:
space:
mode:
authorAlex Pilon <apilon@hashicorp.com>2019-02-22 18:24:37 -0500
committerAlex Pilon <apilon@hashicorp.com>2019-02-22 18:24:37 -0500
commit15c0b25d011f37e7c20aeca9eaf461f78285b8d9 (patch)
tree255c250a5c9d4801c74092d33b7337d8c14438ff /vendor/github.com/mitchellh
parent07971ca38143c5faf951d152fba370ddcbe26ad5 (diff)
downloadterraform-provider-statuscake-15c0b25d011f37e7c20aeca9eaf461f78285b8d9.tar.gz
terraform-provider-statuscake-15c0b25d011f37e7c20aeca9eaf461f78285b8d9.tar.zst
terraform-provider-statuscake-15c0b25d011f37e7c20aeca9eaf461f78285b8d9.zip
deps: github.com/hashicorp/terraform@sdk-v0.11-with-go-modules
Updated via: go get github.com/hashicorp/terraform@sdk-v0.11-with-go-modules and go mod tidy
Diffstat (limited to 'vendor/github.com/mitchellh')
-rw-r--r--vendor/github.com/mitchellh/cli/.travis.yml13
-rw-r--r--vendor/github.com/mitchellh/cli/LICENSE354
-rw-r--r--vendor/github.com/mitchellh/cli/Makefile20
-rw-r--r--vendor/github.com/mitchellh/cli/README.md67
-rw-r--r--vendor/github.com/mitchellh/cli/autocomplete.go43
-rw-r--r--vendor/github.com/mitchellh/cli/cli.go715
-rw-r--r--vendor/github.com/mitchellh/cli/command.go67
-rw-r--r--vendor/github.com/mitchellh/cli/command_mock.go63
-rw-r--r--vendor/github.com/mitchellh/cli/help.go79
-rw-r--r--vendor/github.com/mitchellh/cli/ui.go187
-rw-r--r--vendor/github.com/mitchellh/cli/ui_colored.go69
-rw-r--r--vendor/github.com/mitchellh/cli/ui_concurrent.go54
-rw-r--r--vendor/github.com/mitchellh/cli/ui_mock.go111
-rw-r--r--vendor/github.com/mitchellh/cli/ui_writer.go18
-rw-r--r--vendor/github.com/mitchellh/copystructure/copystructure.go87
-rw-r--r--vendor/github.com/mitchellh/go-testing-interface/.travis.yml12
-rw-r--r--vendor/github.com/mitchellh/go-testing-interface/LICENSE21
-rw-r--r--vendor/github.com/mitchellh/go-testing-interface/README.md52
-rw-r--r--vendor/github.com/mitchellh/go-testing-interface/testing.go84
-rw-r--r--vendor/github.com/mitchellh/go-testing-interface/testing_go19.go80
-rw-r--r--vendor/github.com/mitchellh/go-wordwrap/LICENSE.md21
-rw-r--r--vendor/github.com/mitchellh/go-wordwrap/README.md39
-rw-r--r--vendor/github.com/mitchellh/go-wordwrap/wordwrap.go73
-rw-r--r--vendor/github.com/mitchellh/reflectwalk/location.go2
-rw-r--r--vendor/github.com/mitchellh/reflectwalk/location_string.go8
-rw-r--r--vendor/github.com/mitchellh/reflectwalk/reflectwalk.go108
26 files changed, 2412 insertions, 35 deletions
diff --git a/vendor/github.com/mitchellh/cli/.travis.yml b/vendor/github.com/mitchellh/cli/.travis.yml
new file mode 100644
index 0000000..974234b
--- /dev/null
+++ b/vendor/github.com/mitchellh/cli/.travis.yml
@@ -0,0 +1,13 @@
1sudo: false
2
3language: go
4
5go:
6 - 1.8
7 - 1.9
8
9branches:
10 only:
11 - master
12
13script: make updatedeps test testrace
diff --git a/vendor/github.com/mitchellh/cli/LICENSE b/vendor/github.com/mitchellh/cli/LICENSE
new file mode 100644
index 0000000..c33dcc7
--- /dev/null
+++ b/vendor/github.com/mitchellh/cli/LICENSE
@@ -0,0 +1,354 @@
1Mozilla Public License, version 2.0
2
31. Definitions
4
51.1. “Contributor”
6
7 means each individual or legal entity that creates, contributes to the
8 creation of, or owns Covered Software.
9
101.2. “Contributor Version”
11
12 means the combination of the Contributions of others (if any) used by a
13 Contributor and that particular Contributor’s Contribution.
14
151.3. “Contribution”
16
17 means Covered Software of a particular Contributor.
18
191.4. “Covered Software”
20
21 means Source Code Form to which the initial Contributor has attached the
22 notice in Exhibit A, the Executable Form of such Source Code Form, and
23 Modifications of such Source Code Form, in each case including portions
24 thereof.
25
261.5. “Incompatible With Secondary Licenses”
27 means
28
29 a. that the initial Contributor has attached the notice described in
30 Exhibit B to the Covered Software; or
31
32 b. that the Covered Software was made available under the terms of version
33 1.1 or earlier of the License, but not also under the terms of a
34 Secondary License.
35
361.6. “Executable Form”
37
38 means any form of the work other than Source Code Form.
39
401.7. “Larger Work”
41
42 means a work that combines Covered Software with other material, in a separate
43 file or files, that is not Covered Software.
44
451.8. “License”
46
47 means this document.
48
491.9. “Licensable”
50
51 means having the right to grant, to the maximum extent possible, whether at the
52 time of the initial grant or subsequently, any and all of the rights conveyed by
53 this License.
54
551.10. “Modifications”
56
57 means any of the following:
58
59 a. any file in Source Code Form that results from an addition to, deletion
60 from, or modification of the contents of Covered Software; or
61
62 b. any new file in Source Code Form that contains any Covered Software.
63
641.11. “Patent Claims” of a Contributor
65
66 means any patent claim(s), including without limitation, method, process,
67 and apparatus claims, in any patent Licensable by such Contributor that
68 would be infringed, but for the grant of the License, by the making,
69 using, selling, offering for sale, having made, import, or transfer of
70 either its Contributions or its Contributor Version.
71
721.12. “Secondary License”
73
74 means either the GNU General Public License, Version 2.0, the GNU Lesser
75 General Public License, Version 2.1, the GNU Affero General Public
76 License, Version 3.0, or any later versions of those licenses.
77
781.13. “Source Code Form”
79
80 means the form of the work preferred for making modifications.
81
821.14. “You” (or “Your”)
83
84 means an individual or a legal entity exercising rights under this
85 License. For legal entities, “You” includes any entity that controls, is
86 controlled by, or is under common control with You. For purposes of this
87 definition, “control” means (a) the power, direct or indirect, to cause
88 the direction or management of such entity, whether by contract or
89 otherwise, or (b) ownership of more than fifty percent (50%) of the
90 outstanding shares or beneficial ownership of such entity.
91
92
932. License Grants and Conditions
94
952.1. Grants
96
97 Each Contributor hereby grants You a world-wide, royalty-free,
98 non-exclusive license:
99
100 a. under intellectual property rights (other than patent or trademark)
101 Licensable by such Contributor to use, reproduce, make available,
102 modify, display, perform, distribute, and otherwise exploit its
103 Contributions, either on an unmodified basis, with Modifications, or as
104 part of a Larger Work; and
105
106 b. under Patent Claims of such Contributor to make, use, sell, offer for
107 sale, have made, import, and otherwise transfer either its Contributions
108 or its Contributor Version.
109
1102.2. Effective Date
111
112 The licenses granted in Section 2.1 with respect to any Contribution become
113 effective for each Contribution on the date the Contributor first distributes
114 such Contribution.
115
1162.3. Limitations on Grant Scope
117
118 The licenses granted in this Section 2 are the only rights granted under this
119 License. No additional rights or licenses will be implied from the distribution
120 or licensing of Covered Software under this License. Notwithstanding Section
121 2.1(b) above, no patent license is granted by a Contributor:
122
123 a. for any code that a Contributor has removed from Covered Software; or
124
125 b. for infringements caused by: (i) Your and any other third party’s
126 modifications of Covered Software, or (ii) the combination of its
127 Contributions with other software (except as part of its Contributor
128 Version); or
129
130 c. under Patent Claims infringed by Covered Software in the absence of its
131 Contributions.
132
133 This License does not grant any rights in the trademarks, service marks, or
134 logos of any Contributor (except as may be necessary to comply with the
135 notice requirements in Section 3.4).
136
1372.4. Subsequent Licenses
138
139 No Contributor makes additional grants as a result of Your choice to
140 distribute the Covered Software under a subsequent version of this License
141 (see Section 10.2) or under the terms of a Secondary License (if permitted
142 under the terms of Section 3.3).
143
1442.5. Representation
145
146 Each Contributor represents that the Contributor believes its Contributions
147 are its original creation(s) or it has sufficient rights to grant the
148 rights to its Contributions conveyed by this License.
149
1502.6. Fair Use
151
152 This License is not intended to limit any rights You have under applicable
153 copyright doctrines of fair use, fair dealing, or other equivalents.
154
1552.7. Conditions
156
157 Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted in
158 Section 2.1.
159
160
1613. Responsibilities
162
1633.1. Distribution of Source Form
164
165 All distribution of Covered Software in Source Code Form, including any
166 Modifications that You create or to which You contribute, must be under the
167 terms of this License. You must inform recipients that the Source Code Form
168 of the Covered Software is governed by the terms of this License, and how
169 they can obtain a copy of this License. You may not attempt to alter or
170 restrict the recipients’ rights in the Source Code Form.
171
1723.2. Distribution of Executable Form
173
174 If You distribute Covered Software in Executable Form then:
175
176 a. such Covered Software must also be made available in Source Code Form,
177 as described in Section 3.1, and You must inform recipients of the
178 Executable Form how they can obtain a copy of such Source Code Form by
179 reasonable means in a timely manner, at a charge no more than the cost
180 of distribution to the recipient; and
181
182 b. You may distribute such Executable Form under the terms of this License,
183 or sublicense it under different terms, provided that the license for
184 the Executable Form does not attempt to limit or alter the recipients’
185 rights in the Source Code Form under this License.
186
1873.3. Distribution of a Larger Work
188
189 You may create and distribute a Larger Work under terms of Your choice,
190 provided that You also comply with the requirements of this License for the
191 Covered Software. If the Larger Work is a combination of Covered Software
192 with a work governed by one or more Secondary Licenses, and the Covered
193 Software is not Incompatible With Secondary Licenses, this License permits
194 You to additionally distribute such Covered Software under the terms of
195 such Secondary License(s), so that the recipient of the Larger Work may, at
196 their option, further distribute the Covered Software under the terms of
197 either this License or such Secondary License(s).
198
1993.4. Notices
200
201 You may not remove or alter the substance of any license notices (including
202 copyright notices, patent notices, disclaimers of warranty, or limitations
203 of liability) contained within the Source Code Form of the Covered
204 Software, except that You may alter any license notices to the extent
205 required to remedy known factual inaccuracies.
206
2073.5. Application of Additional Terms
208
209 You may choose to offer, and to charge a fee for, warranty, support,
210 indemnity or liability obligations to one or more recipients of Covered
211 Software. However, You may do so only on Your own behalf, and not on behalf
212 of any Contributor. You must make it absolutely clear that any such
213 warranty, support, indemnity, or liability obligation is offered by You
214 alone, and You hereby agree to indemnify every Contributor for any
215 liability incurred by such Contributor as a result of warranty, support,
216 indemnity or liability terms You offer. You may include additional
217 disclaimers of warranty and limitations of liability specific to any
218 jurisdiction.
219
2204. Inability to Comply Due to Statute or Regulation
221
222 If it is impossible for You to comply with any of the terms of this License
223 with respect to some or all of the Covered Software due to statute, judicial
224 order, or regulation then You must: (a) comply with the terms of this License
225 to the maximum extent possible; and (b) describe the limitations and the code
226 they affect. Such description must be placed in a text file included with all
227 distributions of the Covered Software under this License. Except to the
228 extent prohibited by statute or regulation, such description must be
229 sufficiently detailed for a recipient of ordinary skill to be able to
230 understand it.
231
2325. Termination
233
2345.1. The rights granted under this License will terminate automatically if You
235 fail to comply with any of its terms. However, if You become compliant,
236 then the rights granted under this License from a particular Contributor
237 are reinstated (a) provisionally, unless and until such Contributor
238 explicitly and finally terminates Your grants, and (b) on an ongoing basis,
239 if such Contributor fails to notify You of the non-compliance by some
240 reasonable means prior to 60 days after You have come back into compliance.
241 Moreover, Your grants from a particular Contributor are reinstated on an
242 ongoing basis if such Contributor notifies You of the non-compliance by
243 some reasonable means, this is the first time You have received notice of
244 non-compliance with this License from such Contributor, and You become
245 compliant prior to 30 days after Your receipt of the notice.
246
2475.2. If You initiate litigation against any entity by asserting a patent
248 infringement claim (excluding declaratory judgment actions, counter-claims,
249 and cross-claims) alleging that a Contributor Version directly or
250 indirectly infringes any patent, then the rights granted to You by any and
251 all Contributors for the Covered Software under Section 2.1 of this License
252 shall terminate.
253
2545.3. In the event of termination under Sections 5.1 or 5.2 above, all end user
255 license agreements (excluding distributors and resellers) which have been
256 validly granted by You or Your distributors under this License prior to
257 termination shall survive termination.
258
2596. Disclaimer of Warranty
260
261 Covered Software is provided under this License on an “as is” basis, without
262 warranty of any kind, either expressed, implied, or statutory, including,
263 without limitation, warranties that the Covered Software is free of defects,
264 merchantable, fit for a particular purpose or non-infringing. The entire
265 risk as to the quality and performance of the Covered Software is with You.
266 Should any Covered Software prove defective in any respect, You (not any
267 Contributor) assume the cost of any necessary servicing, repair, or
268 correction. This disclaimer of warranty constitutes an essential part of this
269 License. No use of any Covered Software is authorized under this License
270 except under this disclaimer.
271
2727. Limitation of Liability
273
274 Under no circumstances and under no legal theory, whether tort (including
275 negligence), contract, or otherwise, shall any Contributor, or anyone who
276 distributes Covered Software as permitted above, be liable to You for any
277 direct, indirect, special, incidental, or consequential damages of any
278 character including, without limitation, damages for lost profits, loss of
279 goodwill, work stoppage, computer failure or malfunction, or any and all
280 other commercial damages or losses, even if such party shall have been
281 informed of the possibility of such damages. This limitation of liability
282 shall not apply to liability for death or personal injury resulting from such
283 party’s negligence to the extent applicable law prohibits such limitation.
284 Some jurisdictions do not allow the exclusion or limitation of incidental or
285 consequential damages, so this exclusion and limitation may not apply to You.
286
2878. Litigation
288
289 Any litigation relating to this License may be brought only in the courts of
290 a jurisdiction where the defendant maintains its principal place of business
291 and such litigation shall be governed by laws of that jurisdiction, without
292 reference to its conflict-of-law provisions. Nothing in this Section shall
293 prevent a party’s ability to bring cross-claims or counter-claims.
294
2959. Miscellaneous
296
297 This License represents the complete agreement concerning the subject matter
298 hereof. If any provision of this License is held to be unenforceable, such
299 provision shall be reformed only to the extent necessary to make it
300 enforceable. Any law or regulation which provides that the language of a
301 contract shall be construed against the drafter shall not be used to construe
302 this License against a Contributor.
303
304
30510. Versions of the License
306
30710.1. New Versions
308
309 Mozilla Foundation is the license steward. Except as provided in Section
310 10.3, no one other than the license steward has the right to modify or
311 publish new versions of this License. Each version will be given a
312 distinguishing version number.
313
31410.2. Effect of New Versions
315
316 You may distribute the Covered Software under the terms of the version of
317 the License under which You originally received the Covered Software, or
318 under the terms of any subsequent version published by the license
319 steward.
320
32110.3. Modified Versions
322
323 If you create software not governed by this License, and you want to
324 create a new license for such software, you may create and use a modified
325 version of this License if you rename the license and remove any
326 references to the name of the license steward (except to note that such
327 modified license differs from this License).
328
32910.4. Distributing Source Code Form that is Incompatible With Secondary Licenses
330 If You choose to distribute Source Code Form that is Incompatible With
331 Secondary Licenses under the terms of this version of the License, the
332 notice described in Exhibit B of this License must be attached.
333
334Exhibit A - Source Code Form License Notice
335
336 This Source Code Form is subject to the
337 terms of the Mozilla Public License, v.
338 2.0. If a copy of the MPL was not
339 distributed with this file, You can
340 obtain one at
341 http://mozilla.org/MPL/2.0/.
342
343If it is not possible or desirable to put the notice in a particular file, then
344You may include the notice in a location (such as a LICENSE file in a relevant
345directory) where a recipient would be likely to look for such a notice.
346
347You may add additional accurate notices of copyright ownership.
348
349Exhibit B - “Incompatible With Secondary Licenses” Notice
350
351 This Source Code Form is “Incompatible
352 With Secondary Licenses”, as defined by
353 the Mozilla Public License, v. 2.0.
354
diff --git a/vendor/github.com/mitchellh/cli/Makefile b/vendor/github.com/mitchellh/cli/Makefile
new file mode 100644
index 0000000..4874b00
--- /dev/null
+++ b/vendor/github.com/mitchellh/cli/Makefile
@@ -0,0 +1,20 @@
1TEST?=./...
2
3default: test
4
5# test runs the test suite and vets the code
6test:
7 go list $(TEST) | xargs -n1 go test -timeout=60s -parallel=10 $(TESTARGS)
8
9# testrace runs the race checker
10testrace:
11 go list $(TEST) | xargs -n1 go test -race $(TESTARGS)
12
13# updatedeps installs all the dependencies to run and build
14updatedeps:
15 go list ./... \
16 | xargs go list -f '{{ join .Deps "\n" }}{{ printf "\n" }}{{ join .TestImports "\n" }}' \
17 | grep -v github.com/mitchellh/cli \
18 | xargs go get -f -u -v
19
20.PHONY: test testrace updatedeps
diff --git a/vendor/github.com/mitchellh/cli/README.md b/vendor/github.com/mitchellh/cli/README.md
new file mode 100644
index 0000000..8f02cdd
--- /dev/null
+++ b/vendor/github.com/mitchellh/cli/README.md
@@ -0,0 +1,67 @@
1# Go CLI Library [![GoDoc](https://godoc.org/github.com/mitchellh/cli?status.png)](https://godoc.org/github.com/mitchellh/cli)
2
3cli is a library for implementing powerful command-line interfaces in Go.
4cli is the library that powers the CLI for
5[Packer](https://github.com/mitchellh/packer),
6[Serf](https://github.com/hashicorp/serf),
7[Consul](https://github.com/hashicorp/consul),
8[Vault](https://github.com/hashicorp/vault),
9[Terraform](https://github.com/hashicorp/terraform), and
10[Nomad](https://github.com/hashicorp/nomad).
11
12## Features
13
14* Easy sub-command based CLIs: `cli foo`, `cli bar`, etc.
15
16* Support for nested subcommands such as `cli foo bar`.
17
18* Optional support for default subcommands so `cli` does something
19 other than error.
20
21* Support for shell autocompletion of subcommands, flags, and arguments
22 with callbacks in Go. You don't need to write any shell code.
23
24* Automatic help generation for listing subcommands
25
26* Automatic help flag recognition of `-h`, `--help`, etc.
27
28* Automatic version flag recognition of `-v`, `--version`.
29
30* Helpers for interacting with the terminal, such as outputting information,
31 asking for input, etc. These are optional, you can always interact with the
32 terminal however you choose.
33
34* Use of Go interfaces/types makes augmenting various parts of the library a
35 piece of cake.
36
37## Example
38
39Below is a simple example of creating and running a CLI
40
41```go
42package main
43
44import (
45 "log"
46 "os"
47
48 "github.com/mitchellh/cli"
49)
50
51func main() {
52 c := cli.NewCLI("app", "1.0.0")
53 c.Args = os.Args[1:]
54 c.Commands = map[string]cli.CommandFactory{
55 "foo": fooCommandFactory,
56 "bar": barCommandFactory,
57 }
58
59 exitStatus, err := c.Run()
60 if err != nil {
61 log.Println(err)
62 }
63
64 os.Exit(exitStatus)
65}
66```
67
diff --git a/vendor/github.com/mitchellh/cli/autocomplete.go b/vendor/github.com/mitchellh/cli/autocomplete.go
new file mode 100644
index 0000000..3bec625
--- /dev/null
+++ b/vendor/github.com/mitchellh/cli/autocomplete.go
@@ -0,0 +1,43 @@
1package cli
2
3import (
4 "github.com/posener/complete/cmd/install"
5)
6
7// autocompleteInstaller is an interface to be implemented to perform the
8// autocomplete installation and uninstallation with a CLI.
9//
10// This interface is not exported because it only exists for unit tests
11// to be able to test that the installation is called properly.
12type autocompleteInstaller interface {
13 Install(string) error
14 Uninstall(string) error
15}
16
17// realAutocompleteInstaller uses the real install package to do the
18// install/uninstall.
19type realAutocompleteInstaller struct{}
20
21func (i *realAutocompleteInstaller) Install(cmd string) error {
22 return install.Install(cmd)
23}
24
25func (i *realAutocompleteInstaller) Uninstall(cmd string) error {
26 return install.Uninstall(cmd)
27}
28
29// mockAutocompleteInstaller is used for tests to record the install/uninstall.
30type mockAutocompleteInstaller struct {
31 InstallCalled bool
32 UninstallCalled bool
33}
34
35func (i *mockAutocompleteInstaller) Install(cmd string) error {
36 i.InstallCalled = true
37 return nil
38}
39
40func (i *mockAutocompleteInstaller) Uninstall(cmd string) error {
41 i.UninstallCalled = true
42 return nil
43}
diff --git a/vendor/github.com/mitchellh/cli/cli.go b/vendor/github.com/mitchellh/cli/cli.go
new file mode 100644
index 0000000..a25a582
--- /dev/null
+++ b/vendor/github.com/mitchellh/cli/cli.go
@@ -0,0 +1,715 @@
1package cli
2
3import (
4 "fmt"
5 "io"
6 "os"
7 "regexp"
8 "sort"
9 "strings"
10 "sync"
11 "text/template"
12
13 "github.com/armon/go-radix"
14 "github.com/posener/complete"
15)
16
17// CLI contains the state necessary to run subcommands and parse the
18// command line arguments.
19//
20// CLI also supports nested subcommands, such as "cli foo bar". To use
21// nested subcommands, the key in the Commands mapping below contains the
22// full subcommand. In this example, it would be "foo bar".
23//
24// If you use a CLI with nested subcommands, some semantics change due to
25// ambiguities:
26//
27// * We use longest prefix matching to find a matching subcommand. This
28// means if you register "foo bar" and the user executes "cli foo qux",
29// the "foo" command will be executed with the arg "qux". It is up to
30// you to handle these args. One option is to just return the special
31// help return code `RunResultHelp` to display help and exit.
32//
33// * The help flag "-h" or "-help" will look at all args to determine
34// the help function. For example: "otto apps list -h" will show the
35// help for "apps list" but "otto apps -h" will show it for "apps".
36// In the normal CLI, only the first subcommand is used.
37//
38// * The help flag will list any subcommands that a command takes
39// as well as the command's help itself. If there are no subcommands,
40// it will note this. If the CLI itself has no subcommands, this entire
41// section is omitted.
42//
43// * Any parent commands that don't exist are automatically created as
44// no-op commands that just show help for other subcommands. For example,
45// if you only register "foo bar", then "foo" is automatically created.
46//
47type CLI struct {
48 // Args is the list of command-line arguments received excluding
49 // the name of the app. For example, if the command "./cli foo bar"
50 // was invoked, then Args should be []string{"foo", "bar"}.
51 Args []string
52
53 // Commands is a mapping of subcommand names to a factory function
54 // for creating that Command implementation. If there is a command
55 // with a blank string "", then it will be used as the default command
56 // if no subcommand is specified.
57 //
58 // If the key has a space in it, this will create a nested subcommand.
59 // For example, if the key is "foo bar", then to access it our CLI
60 // must be accessed with "./cli foo bar". See the docs for CLI for
61 // notes on how this changes some other behavior of the CLI as well.
62 //
63 // The factory should be as cheap as possible, ideally only allocating
64 // a struct. The factory may be called multiple times in the course
65 // of a command execution and certain events such as help require the
66 // instantiation of all commands. Expensive initialization should be
67 // deferred to function calls within the interface implementation.
68 Commands map[string]CommandFactory
69
70 // HiddenCommands is a list of commands that are "hidden". Hidden
71 // commands are not given to the help function callback and do not
72 // show up in autocomplete. The values in the slice should be equivalent
73 // to the keys in the command map.
74 HiddenCommands []string
75
76 // Name defines the name of the CLI.
77 Name string
78
79 // Version of the CLI.
80 Version string
81
82 // Autocomplete enables or disables subcommand auto-completion support.
83 // This is enabled by default when NewCLI is called. Otherwise, this
84 // must enabled explicitly.
85 //
86 // Autocomplete requires the "Name" option to be set on CLI. This name
87 // should be set exactly to the binary name that is autocompleted.
88 //
89 // Autocompletion is supported via the github.com/posener/complete
90 // library. This library supports both bash and zsh. To add support
91 // for other shells, please see that library.
92 //
93 // AutocompleteInstall and AutocompleteUninstall are the global flag
94 // names for installing and uninstalling the autocompletion handlers
95 // for the user's shell. The flag should omit the hyphen(s) in front of
96 // the value. Both single and double hyphens will automatically be supported
97 // for the flag name. These default to `autocomplete-install` and
98 // `autocomplete-uninstall` respectively.
99 //
100 // AutocompleteNoDefaultFlags is a boolean which controls if the default auto-
101 // complete flags like -help and -version are added to the output.
102 //
103 // AutocompleteGlobalFlags are a mapping of global flags for
104 // autocompletion. The help and version flags are automatically added.
105 Autocomplete bool
106 AutocompleteInstall string
107 AutocompleteUninstall string
108 AutocompleteNoDefaultFlags bool
109 AutocompleteGlobalFlags complete.Flags
110 autocompleteInstaller autocompleteInstaller // For tests
111
112 // HelpFunc and HelpWriter are used to output help information, if
113 // requested.
114 //
115 // HelpFunc is the function called to generate the generic help
116 // text that is shown if help must be shown for the CLI that doesn't
117 // pertain to a specific command.
118 //
119 // HelpWriter is the Writer where the help text is outputted to. If
120 // not specified, it will default to Stderr.
121 HelpFunc HelpFunc
122 HelpWriter io.Writer
123
124 //---------------------------------------------------------------
125 // Internal fields set automatically
126
127 once sync.Once
128 autocomplete *complete.Complete
129 commandTree *radix.Tree
130 commandNested bool
131 commandHidden map[string]struct{}
132 subcommand string
133 subcommandArgs []string
134 topFlags []string
135
136 // These are true when special global flags are set. We can/should
137 // probably use a bitset for this one day.
138 isHelp bool
139 isVersion bool
140 isAutocompleteInstall bool
141 isAutocompleteUninstall bool
142}
143
144// NewClI returns a new CLI instance with sensible defaults.
145func NewCLI(app, version string) *CLI {
146 return &CLI{
147 Name: app,
148 Version: version,
149 HelpFunc: BasicHelpFunc(app),
150 Autocomplete: true,
151 }
152
153}
154
155// IsHelp returns whether or not the help flag is present within the
156// arguments.
157func (c *CLI) IsHelp() bool {
158 c.once.Do(c.init)
159 return c.isHelp
160}
161
162// IsVersion returns whether or not the version flag is present within the
163// arguments.
164func (c *CLI) IsVersion() bool {
165 c.once.Do(c.init)
166 return c.isVersion
167}
168
169// Run runs the actual CLI based on the arguments given.
170func (c *CLI) Run() (int, error) {
171 c.once.Do(c.init)
172
173 // If this is a autocompletion request, satisfy it. This must be called
174 // first before anything else since its possible to be autocompleting
175 // -help or -version or other flags and we want to show completions
176 // and not actually write the help or version.
177 if c.Autocomplete && c.autocomplete.Complete() {
178 return 0, nil
179 }
180
181 // Just show the version and exit if instructed.
182 if c.IsVersion() && c.Version != "" {
183 c.HelpWriter.Write([]byte(c.Version + "\n"))
184 return 0, nil
185 }
186
187 // Just print the help when only '-h' or '--help' is passed.
188 if c.IsHelp() && c.Subcommand() == "" {
189 c.HelpWriter.Write([]byte(c.HelpFunc(c.helpCommands(c.Subcommand())) + "\n"))
190 return 0, nil
191 }
192
193 // If we're attempting to install or uninstall autocomplete then handle
194 if c.Autocomplete {
195 // Autocomplete requires the "Name" to be set so that we know what
196 // command to setup the autocomplete on.
197 if c.Name == "" {
198 return 1, fmt.Errorf(
199 "internal error: CLI.Name must be specified for autocomplete to work")
200 }
201
202 // If both install and uninstall flags are specified, then error
203 if c.isAutocompleteInstall && c.isAutocompleteUninstall {
204 return 1, fmt.Errorf(
205 "Either the autocomplete install or uninstall flag may " +
206 "be specified, but not both.")
207 }
208
209 // If the install flag is specified, perform the install or uninstall
210 if c.isAutocompleteInstall {
211 if err := c.autocompleteInstaller.Install(c.Name); err != nil {
212 return 1, err
213 }
214
215 return 0, nil
216 }
217
218 if c.isAutocompleteUninstall {
219 if err := c.autocompleteInstaller.Uninstall(c.Name); err != nil {
220 return 1, err
221 }
222
223 return 0, nil
224 }
225 }
226
227 // Attempt to get the factory function for creating the command
228 // implementation. If the command is invalid or blank, it is an error.
229 raw, ok := c.commandTree.Get(c.Subcommand())
230 if !ok {
231 c.HelpWriter.Write([]byte(c.HelpFunc(c.helpCommands(c.subcommandParent())) + "\n"))
232 return 127, nil
233 }
234
235 command, err := raw.(CommandFactory)()
236 if err != nil {
237 return 1, err
238 }
239
240 // If we've been instructed to just print the help, then print it
241 if c.IsHelp() {
242 c.commandHelp(command)
243 return 0, nil
244 }
245
246 // If there is an invalid flag, then error
247 if len(c.topFlags) > 0 {
248 c.HelpWriter.Write([]byte(
249 "Invalid flags before the subcommand. If these flags are for\n" +
250 "the subcommand, please put them after the subcommand.\n\n"))
251 c.commandHelp(command)
252 return 1, nil
253 }
254
255 code := command.Run(c.SubcommandArgs())
256 if code == RunResultHelp {
257 // Requesting help
258 c.commandHelp(command)
259 return 1, nil
260 }
261
262 return code, nil
263}
264
265// Subcommand returns the subcommand that the CLI would execute. For
266// example, a CLI from "--version version --help" would return a Subcommand
267// of "version"
268func (c *CLI) Subcommand() string {
269 c.once.Do(c.init)
270 return c.subcommand
271}
272
273// SubcommandArgs returns the arguments that will be passed to the
274// subcommand.
275func (c *CLI) SubcommandArgs() []string {
276 c.once.Do(c.init)
277 return c.subcommandArgs
278}
279
280// subcommandParent returns the parent of this subcommand, if there is one.
281// If there isn't on, "" is returned.
282func (c *CLI) subcommandParent() string {
283 // Get the subcommand, if it is "" alread just return
284 sub := c.Subcommand()
285 if sub == "" {
286 return sub
287 }
288
289 // Clear any trailing spaces and find the last space
290 sub = strings.TrimRight(sub, " ")
291 idx := strings.LastIndex(sub, " ")
292
293 if idx == -1 {
294 // No space means our parent is root
295 return ""
296 }
297
298 return sub[:idx]
299}
300
301func (c *CLI) init() {
302 if c.HelpFunc == nil {
303 c.HelpFunc = BasicHelpFunc("app")
304
305 if c.Name != "" {
306 c.HelpFunc = BasicHelpFunc(c.Name)
307 }
308 }
309
310 if c.HelpWriter == nil {
311 c.HelpWriter = os.Stderr
312 }
313
314 // Build our hidden commands
315 if len(c.HiddenCommands) > 0 {
316 c.commandHidden = make(map[string]struct{})
317 for _, h := range c.HiddenCommands {
318 c.commandHidden[h] = struct{}{}
319 }
320 }
321
322 // Build our command tree
323 c.commandTree = radix.New()
324 c.commandNested = false
325 for k, v := range c.Commands {
326 k = strings.TrimSpace(k)
327 c.commandTree.Insert(k, v)
328 if strings.ContainsRune(k, ' ') {
329 c.commandNested = true
330 }
331 }
332
333 // Go through the key and fill in any missing parent commands
334 if c.commandNested {
335 var walkFn radix.WalkFn
336 toInsert := make(map[string]struct{})
337 walkFn = func(k string, raw interface{}) bool {
338 idx := strings.LastIndex(k, " ")
339 if idx == -1 {
340 // If there is no space, just ignore top level commands
341 return false
342 }
343
344 // Trim up to that space so we can get the expected parent
345 k = k[:idx]
346 if _, ok := c.commandTree.Get(k); ok {
347 // Yay we have the parent!
348 return false
349 }
350
351 // We're missing the parent, so let's insert this
352 toInsert[k] = struct{}{}
353
354 // Call the walk function recursively so we check this one too
355 return walkFn(k, nil)
356 }
357
358 // Walk!
359 c.commandTree.Walk(walkFn)
360
361 // Insert any that we're missing
362 for k := range toInsert {
363 var f CommandFactory = func() (Command, error) {
364 return &MockCommand{
365 HelpText: "This command is accessed by using one of the subcommands below.",
366 RunResult: RunResultHelp,
367 }, nil
368 }
369
370 c.commandTree.Insert(k, f)
371 }
372 }
373
374 // Setup autocomplete if we have it enabled. We have to do this after
375 // the command tree is setup so we can use the radix tree to easily find
376 // all subcommands.
377 if c.Autocomplete {
378 c.initAutocomplete()
379 }
380
381 // Process the args
382 c.processArgs()
383}
384
385func (c *CLI) initAutocomplete() {
386 if c.AutocompleteInstall == "" {
387 c.AutocompleteInstall = defaultAutocompleteInstall
388 }
389
390 if c.AutocompleteUninstall == "" {
391 c.AutocompleteUninstall = defaultAutocompleteUninstall
392 }
393
394 if c.autocompleteInstaller == nil {
395 c.autocompleteInstaller = &realAutocompleteInstaller{}
396 }
397
398 // Build the root command
399 cmd := c.initAutocompleteSub("")
400
401 // For the root, we add the global flags to the "Flags". This way
402 // they don't show up on every command.
403 if !c.AutocompleteNoDefaultFlags {
404 cmd.Flags = map[string]complete.Predictor{
405 "-" + c.AutocompleteInstall: complete.PredictNothing,
406 "-" + c.AutocompleteUninstall: complete.PredictNothing,
407 "-help": complete.PredictNothing,
408 "-version": complete.PredictNothing,
409 }
410 }
411 cmd.GlobalFlags = c.AutocompleteGlobalFlags
412
413 c.autocomplete = complete.New(c.Name, cmd)
414}
415
416// initAutocompleteSub creates the complete.Command for a subcommand with
417// the given prefix. This will continue recursively for all subcommands.
418// The prefix "" (empty string) can be used for the root command.
419func (c *CLI) initAutocompleteSub(prefix string) complete.Command {
420 var cmd complete.Command
421 walkFn := func(k string, raw interface{}) bool {
422 // Keep track of the full key so that we can nest further if necessary
423 fullKey := k
424
425 if len(prefix) > 0 {
426 // If we have a prefix, trim the prefix + 1 (for the space)
427 // Example: turns "sub one" to "one" with prefix "sub"
428 k = k[len(prefix)+1:]
429 }
430
431 if idx := strings.Index(k, " "); idx >= 0 {
432 // If there is a space, we trim up to the space. This turns
433 // "sub sub2 sub3" into "sub". The prefix trim above will
434 // trim our current depth properly.
435 k = k[:idx]
436 }
437
438 if _, ok := cmd.Sub[k]; ok {
439 // If we already tracked this subcommand then ignore
440 return false
441 }
442
443 // If the command is hidden, don't record it at all
444 if _, ok := c.commandHidden[fullKey]; ok {
445 return false
446 }
447
448 if cmd.Sub == nil {
449 cmd.Sub = complete.Commands(make(map[string]complete.Command))
450 }
451 subCmd := c.initAutocompleteSub(fullKey)
452
453 // Instantiate the command so that we can check if the command is
454 // a CommandAutocomplete implementation. If there is an error
455 // creating the command, we just ignore it since that will be caught
456 // later.
457 impl, err := raw.(CommandFactory)()
458 if err != nil {
459 impl = nil
460 }
461
462 // Check if it implements ComandAutocomplete. If so, setup the autocomplete
463 if c, ok := impl.(CommandAutocomplete); ok {
464 subCmd.Args = c.AutocompleteArgs()
465 subCmd.Flags = c.AutocompleteFlags()
466 }
467
468 cmd.Sub[k] = subCmd
469 return false
470 }
471
472 walkPrefix := prefix
473 if walkPrefix != "" {
474 walkPrefix += " "
475 }
476
477 c.commandTree.WalkPrefix(walkPrefix, walkFn)
478 return cmd
479}
480
481func (c *CLI) commandHelp(command Command) {
482 // Get the template to use
483 tpl := strings.TrimSpace(defaultHelpTemplate)
484 if t, ok := command.(CommandHelpTemplate); ok {
485 tpl = t.HelpTemplate()
486 }
487 if !strings.HasSuffix(tpl, "\n") {
488 tpl += "\n"
489 }
490
491 // Parse it
492 t, err := template.New("root").Parse(tpl)
493 if err != nil {
494 t = template.Must(template.New("root").Parse(fmt.Sprintf(
495 "Internal error! Failed to parse command help template: %s\n", err)))
496 }
497
498 // Template data
499 data := map[string]interface{}{
500 "Name": c.Name,
501 "Help": command.Help(),
502 }
503
504 // Build subcommand list if we have it
505 var subcommandsTpl []map[string]interface{}
506 if c.commandNested {
507 // Get the matching keys
508 subcommands := c.helpCommands(c.Subcommand())
509 keys := make([]string, 0, len(subcommands))
510 for k := range subcommands {
511 keys = append(keys, k)
512 }
513
514 // Sort the keys
515 sort.Strings(keys)
516
517 // Figure out the padding length
518 var longest int
519 for _, k := range keys {
520 if v := len(k); v > longest {
521 longest = v
522 }
523 }
524
525 // Go through and create their structures
526 subcommandsTpl = make([]map[string]interface{}, 0, len(subcommands))
527 for _, k := range keys {
528 // Get the command
529 raw, ok := subcommands[k]
530 if !ok {
531 c.HelpWriter.Write([]byte(fmt.Sprintf(
532 "Error getting subcommand %q", k)))
533 }
534 sub, err := raw()
535 if err != nil {
536 c.HelpWriter.Write([]byte(fmt.Sprintf(
537 "Error instantiating %q: %s", k, err)))
538 }
539
540 // Find the last space and make sure we only include that last part
541 name := k
542 if idx := strings.LastIndex(k, " "); idx > -1 {
543 name = name[idx+1:]
544 }
545
546 subcommandsTpl = append(subcommandsTpl, map[string]interface{}{
547 "Name": name,
548 "NameAligned": name + strings.Repeat(" ", longest-len(k)),
549 "Help": sub.Help(),
550 "Synopsis": sub.Synopsis(),
551 })
552 }
553 }
554 data["Subcommands"] = subcommandsTpl
555
556 // Write
557 err = t.Execute(c.HelpWriter, data)
558 if err == nil {
559 return
560 }
561
562 // An error, just output...
563 c.HelpWriter.Write([]byte(fmt.Sprintf(
564 "Internal error rendering help: %s", err)))
565}
566
567// helpCommands returns the subcommands for the HelpFunc argument.
568// This will only contain immediate subcommands.
569func (c *CLI) helpCommands(prefix string) map[string]CommandFactory {
570 // If our prefix isn't empty, make sure it ends in ' '
571 if prefix != "" && prefix[len(prefix)-1] != ' ' {
572 prefix += " "
573 }
574
575 // Get all the subkeys of this command
576 var keys []string
577 c.commandTree.WalkPrefix(prefix, func(k string, raw interface{}) bool {
578 // Ignore any sub-sub keys, i.e. "foo bar baz" when we want "foo bar"
579 if !strings.Contains(k[len(prefix):], " ") {
580 keys = append(keys, k)
581 }
582
583 return false
584 })
585
586 // For each of the keys return that in the map
587 result := make(map[string]CommandFactory, len(keys))
588 for _, k := range keys {
589 raw, ok := c.commandTree.Get(k)
590 if !ok {
591 // We just got it via WalkPrefix above, so we just panic
592 panic("not found: " + k)
593 }
594
595 // If this is a hidden command, don't show it
596 if _, ok := c.commandHidden[k]; ok {
597 continue
598 }
599
600 result[k] = raw.(CommandFactory)
601 }
602
603 return result
604}
605
606func (c *CLI) processArgs() {
607 for i, arg := range c.Args {
608 if arg == "--" {
609 break
610 }
611
612 // Check for help flags.
613 if arg == "-h" || arg == "-help" || arg == "--help" {
614 c.isHelp = true
615 continue
616 }
617
618 // Check for autocomplete flags
619 if c.Autocomplete {
620 if arg == "-"+c.AutocompleteInstall || arg == "--"+c.AutocompleteInstall {
621 c.isAutocompleteInstall = true
622 continue
623 }
624
625 if arg == "-"+c.AutocompleteUninstall || arg == "--"+c.AutocompleteUninstall {
626 c.isAutocompleteUninstall = true
627 continue
628 }
629 }
630
631 if c.subcommand == "" {
632 // Check for version flags if not in a subcommand.
633 if arg == "-v" || arg == "-version" || arg == "--version" {
634 c.isVersion = true
635 continue
636 }
637
638 if arg != "" && arg[0] == '-' {
639 // Record the arg...
640 c.topFlags = append(c.topFlags, arg)
641 }
642 }
643
644 // If we didn't find a subcommand yet and this is the first non-flag
645 // argument, then this is our subcommand.
646 if c.subcommand == "" && arg != "" && arg[0] != '-' {
647 c.subcommand = arg
648 if c.commandNested {
649 // If the command has a space in it, then it is invalid.
650 // Set a blank command so that it fails.
651 if strings.ContainsRune(arg, ' ') {
652 c.subcommand = ""
653 return
654 }
655
656 // Determine the argument we look to to end subcommands.
657 // We look at all arguments until one has a space. This
658 // disallows commands like: ./cli foo "bar baz". An argument
659 // with a space is always an argument.
660 j := 0
661 for k, v := range c.Args[i:] {
662 if strings.ContainsRune(v, ' ') {
663 break
664 }
665
666 j = i + k + 1
667 }
668
669 // Nested CLI, the subcommand is actually the entire
670 // arg list up to a flag that is still a valid subcommand.
671 searchKey := strings.Join(c.Args[i:j], " ")
672 k, _, ok := c.commandTree.LongestPrefix(searchKey)
673 if ok {
674 // k could be a prefix that doesn't contain the full
675 // command such as "foo" instead of "foobar", so we
676 // need to verify that we have an entire key. To do that,
677 // we look for an ending in a space or an end of string.
678 reVerify := regexp.MustCompile(regexp.QuoteMeta(k) + `( |$)`)
679 if reVerify.MatchString(searchKey) {
680 c.subcommand = k
681 i += strings.Count(k, " ")
682 }
683 }
684 }
685
686 // The remaining args the subcommand arguments
687 c.subcommandArgs = c.Args[i+1:]
688 }
689 }
690
691 // If we never found a subcommand and support a default command, then
692 // switch to using that.
693 if c.subcommand == "" {
694 if _, ok := c.Commands[""]; ok {
695 args := c.topFlags
696 args = append(args, c.subcommandArgs...)
697 c.topFlags = nil
698 c.subcommandArgs = args
699 }
700 }
701}
702
703// defaultAutocompleteInstall and defaultAutocompleteUninstall are the
704// default values for the autocomplete install and uninstall flags.
705const defaultAutocompleteInstall = "autocomplete-install"
706const defaultAutocompleteUninstall = "autocomplete-uninstall"
707
708const defaultHelpTemplate = `
709{{.Help}}{{if gt (len .Subcommands) 0}}
710
711Subcommands:
712{{- range $value := .Subcommands }}
713 {{ $value.NameAligned }} {{ $value.Synopsis }}{{ end }}
714{{- end }}
715`
diff --git a/vendor/github.com/mitchellh/cli/command.go b/vendor/github.com/mitchellh/cli/command.go
new file mode 100644
index 0000000..bed11fa
--- /dev/null
+++ b/vendor/github.com/mitchellh/cli/command.go
@@ -0,0 +1,67 @@
1package cli
2
3import (
4 "github.com/posener/complete"
5)
6
7const (
8 // RunResultHelp is a value that can be returned from Run to signal
9 // to the CLI to render the help output.
10 RunResultHelp = -18511
11)
12
13// A command is a runnable sub-command of a CLI.
14type Command interface {
15 // Help should return long-form help text that includes the command-line
16 // usage, a brief few sentences explaining the function of the command,
17 // and the complete list of flags the command accepts.
18 Help() string
19
20 // Run should run the actual command with the given CLI instance and
21 // command-line arguments. It should return the exit status when it is
22 // finished.
23 //
24 // There are a handful of special exit codes this can return documented
25 // above that change behavior.
26 Run(args []string) int
27
28 // Synopsis should return a one-line, short synopsis of the command.
29 // This should be less than 50 characters ideally.
30 Synopsis() string
31}
32
33// CommandAutocomplete is an extension of Command that enables fine-grained
34// autocompletion. Subcommand autocompletion will work even if this interface
35// is not implemented. By implementing this interface, more advanced
36// autocompletion is enabled.
37type CommandAutocomplete interface {
38 // AutocompleteArgs returns the argument predictor for this command.
39 // If argument completion is not supported, this should return
40 // complete.PredictNothing.
41 AutocompleteArgs() complete.Predictor
42
43 // AutocompleteFlags returns a mapping of supported flags and autocomplete
44 // options for this command. The map key for the Flags map should be the
45 // complete flag such as "-foo" or "--foo".
46 AutocompleteFlags() complete.Flags
47}
48
49// CommandHelpTemplate is an extension of Command that also has a function
50// for returning a template for the help rather than the help itself. In
51// this scenario, both Help and HelpTemplate should be implemented.
52//
53// If CommandHelpTemplate isn't implemented, the Help is output as-is.
54type CommandHelpTemplate interface {
55 // HelpTemplate is the template in text/template format to use for
56 // displaying the Help. The keys available are:
57 //
58 // * ".Help" - The help text itself
59 // * ".Subcommands"
60 //
61 HelpTemplate() string
62}
63
64// CommandFactory is a type of function that is a factory for commands.
65// We need a factory because we may need to setup some state on the
66// struct that implements the command itself.
67type CommandFactory func() (Command, error)
diff --git a/vendor/github.com/mitchellh/cli/command_mock.go b/vendor/github.com/mitchellh/cli/command_mock.go
new file mode 100644
index 0000000..7a584b7
--- /dev/null
+++ b/vendor/github.com/mitchellh/cli/command_mock.go
@@ -0,0 +1,63 @@
1package cli
2
3import (
4 "github.com/posener/complete"
5)
6
7// MockCommand is an implementation of Command that can be used for tests.
8// It is publicly exported from this package in case you want to use it
9// externally.
10type MockCommand struct {
11 // Settable
12 HelpText string
13 RunResult int
14 SynopsisText string
15
16 // Set by the command
17 RunCalled bool
18 RunArgs []string
19}
20
21func (c *MockCommand) Help() string {
22 return c.HelpText
23}
24
25func (c *MockCommand) Run(args []string) int {
26 c.RunCalled = true
27 c.RunArgs = args
28
29 return c.RunResult
30}
31
32func (c *MockCommand) Synopsis() string {
33 return c.SynopsisText
34}
35
36// MockCommandAutocomplete is an implementation of CommandAutocomplete.
37type MockCommandAutocomplete struct {
38 MockCommand
39
40 // Settable
41 AutocompleteArgsValue complete.Predictor
42 AutocompleteFlagsValue complete.Flags
43}
44
45func (c *MockCommandAutocomplete) AutocompleteArgs() complete.Predictor {
46 return c.AutocompleteArgsValue
47}
48
49func (c *MockCommandAutocomplete) AutocompleteFlags() complete.Flags {
50 return c.AutocompleteFlagsValue
51}
52
53// MockCommandHelpTemplate is an implementation of CommandHelpTemplate.
54type MockCommandHelpTemplate struct {
55 MockCommand
56
57 // Settable
58 HelpTemplateText string
59}
60
61func (c *MockCommandHelpTemplate) HelpTemplate() string {
62 return c.HelpTemplateText
63}
diff --git a/vendor/github.com/mitchellh/cli/help.go b/vendor/github.com/mitchellh/cli/help.go
new file mode 100644
index 0000000..f5ca58f
--- /dev/null
+++ b/vendor/github.com/mitchellh/cli/help.go
@@ -0,0 +1,79 @@
1package cli
2
3import (
4 "bytes"
5 "fmt"
6 "log"
7 "sort"
8 "strings"
9)
10
11// HelpFunc is the type of the function that is responsible for generating
12// the help output when the CLI must show the general help text.
13type HelpFunc func(map[string]CommandFactory) string
14
15// BasicHelpFunc generates some basic help output that is usually good enough
16// for most CLI applications.
17func BasicHelpFunc(app string) HelpFunc {
18 return func(commands map[string]CommandFactory) string {
19 var buf bytes.Buffer
20 buf.WriteString(fmt.Sprintf(
21 "Usage: %s [--version] [--help] <command> [<args>]\n\n",
22 app))
23 buf.WriteString("Available commands are:\n")
24
25 // Get the list of keys so we can sort them, and also get the maximum
26 // key length so they can be aligned properly.
27 keys := make([]string, 0, len(commands))
28 maxKeyLen := 0
29 for key := range commands {
30 if len(key) > maxKeyLen {
31 maxKeyLen = len(key)
32 }
33
34 keys = append(keys, key)
35 }
36 sort.Strings(keys)
37
38 for _, key := range keys {
39 commandFunc, ok := commands[key]
40 if !ok {
41 // This should never happen since we JUST built the list of
42 // keys.
43 panic("command not found: " + key)
44 }
45
46 command, err := commandFunc()
47 if err != nil {
48 log.Printf("[ERR] cli: Command '%s' failed to load: %s",
49 key, err)
50 continue
51 }
52
53 key = fmt.Sprintf("%s%s", key, strings.Repeat(" ", maxKeyLen-len(key)))
54 buf.WriteString(fmt.Sprintf(" %s %s\n", key, command.Synopsis()))
55 }
56
57 return buf.String()
58 }
59}
60
61// FilteredHelpFunc will filter the commands to only include the keys
62// in the include parameter.
63func FilteredHelpFunc(include []string, f HelpFunc) HelpFunc {
64 return func(commands map[string]CommandFactory) string {
65 set := make(map[string]struct{})
66 for _, k := range include {
67 set[k] = struct{}{}
68 }
69
70 filtered := make(map[string]CommandFactory)
71 for k, f := range commands {
72 if _, ok := set[k]; ok {
73 filtered[k] = f
74 }
75 }
76
77 return f(filtered)
78 }
79}
diff --git a/vendor/github.com/mitchellh/cli/ui.go b/vendor/github.com/mitchellh/cli/ui.go
new file mode 100644
index 0000000..a2d6f94
--- /dev/null
+++ b/vendor/github.com/mitchellh/cli/ui.go
@@ -0,0 +1,187 @@
1package cli
2
3import (
4 "bufio"
5 "errors"
6 "fmt"
7 "io"
8 "os"
9 "os/signal"
10 "strings"
11
12 "github.com/bgentry/speakeasy"
13 "github.com/mattn/go-isatty"
14)
15
16// Ui is an interface for interacting with the terminal, or "interface"
17// of a CLI. This abstraction doesn't have to be used, but helps provide
18// a simple, layerable way to manage user interactions.
19type Ui interface {
20 // Ask asks the user for input using the given query. The response is
21 // returned as the given string, or an error.
22 Ask(string) (string, error)
23
24 // AskSecret asks the user for input using the given query, but does not echo
25 // the keystrokes to the terminal.
26 AskSecret(string) (string, error)
27
28 // Output is called for normal standard output.
29 Output(string)
30
31 // Info is called for information related to the previous output.
32 // In general this may be the exact same as Output, but this gives
33 // Ui implementors some flexibility with output formats.
34 Info(string)
35
36 // Error is used for any error messages that might appear on standard
37 // error.
38 Error(string)
39
40 // Warn is used for any warning messages that might appear on standard
41 // error.
42 Warn(string)
43}
44
45// BasicUi is an implementation of Ui that just outputs to the given
46// writer. This UI is not threadsafe by default, but you can wrap it
47// in a ConcurrentUi to make it safe.
48type BasicUi struct {
49 Reader io.Reader
50 Writer io.Writer
51 ErrorWriter io.Writer
52}
53
54func (u *BasicUi) Ask(query string) (string, error) {
55 return u.ask(query, false)
56}
57
58func (u *BasicUi) AskSecret(query string) (string, error) {
59 return u.ask(query, true)
60}
61
62func (u *BasicUi) ask(query string, secret bool) (string, error) {
63 if _, err := fmt.Fprint(u.Writer, query+" "); err != nil {
64 return "", err
65 }
66
67 // Register for interrupts so that we can catch it and immediately
68 // return...
69 sigCh := make(chan os.Signal, 1)
70 signal.Notify(sigCh, os.Interrupt)
71 defer signal.Stop(sigCh)
72
73 // Ask for input in a go-routine so that we can ignore it.
74 errCh := make(chan error, 1)
75 lineCh := make(chan string, 1)
76 go func() {
77 var line string
78 var err error
79 if secret && isatty.IsTerminal(os.Stdin.Fd()) {
80 line, err = speakeasy.Ask("")
81 } else {
82 r := bufio.NewReader(u.Reader)
83 line, err = r.ReadString('\n')
84 }
85 if err != nil {
86 errCh <- err
87 return
88 }
89
90 lineCh <- strings.TrimRight(line, "\r\n")
91 }()
92
93 select {
94 case err := <-errCh:
95 return "", err
96 case line := <-lineCh:
97 return line, nil
98 case <-sigCh:
99 // Print a newline so that any further output starts properly
100 // on a new line.
101 fmt.Fprintln(u.Writer)
102
103 return "", errors.New("interrupted")
104 }
105}
106
107func (u *BasicUi) Error(message string) {
108 w := u.Writer
109 if u.ErrorWriter != nil {
110 w = u.ErrorWriter
111 }
112
113 fmt.Fprint(w, message)
114 fmt.Fprint(w, "\n")
115}
116
117func (u *BasicUi) Info(message string) {
118 u.Output(message)
119}
120
121func (u *BasicUi) Output(message string) {
122 fmt.Fprint(u.Writer, message)
123 fmt.Fprint(u.Writer, "\n")
124}
125
126func (u *BasicUi) Warn(message string) {
127 u.Error(message)
128}
129
130// PrefixedUi is an implementation of Ui that prefixes messages.
131type PrefixedUi struct {
132 AskPrefix string
133 AskSecretPrefix string
134 OutputPrefix string
135 InfoPrefix string
136 ErrorPrefix string
137 WarnPrefix string
138 Ui Ui
139}
140
141func (u *PrefixedUi) Ask(query string) (string, error) {
142 if query != "" {
143 query = fmt.Sprintf("%s%s", u.AskPrefix, query)
144 }
145
146 return u.Ui.Ask(query)
147}
148
149func (u *PrefixedUi) AskSecret(query string) (string, error) {
150 if query != "" {
151 query = fmt.Sprintf("%s%s", u.AskSecretPrefix, query)
152 }
153
154 return u.Ui.AskSecret(query)
155}
156
157func (u *PrefixedUi) Error(message string) {
158 if message != "" {
159 message = fmt.Sprintf("%s%s", u.ErrorPrefix, message)
160 }
161
162 u.Ui.Error(message)
163}
164
165func (u *PrefixedUi) Info(message string) {
166 if message != "" {
167 message = fmt.Sprintf("%s%s", u.InfoPrefix, message)
168 }
169
170 u.Ui.Info(message)
171}
172
173func (u *PrefixedUi) Output(message string) {
174 if message != "" {
175 message = fmt.Sprintf("%s%s", u.OutputPrefix, message)
176 }
177
178 u.Ui.Output(message)
179}
180
181func (u *PrefixedUi) Warn(message string) {
182 if message != "" {
183 message = fmt.Sprintf("%s%s", u.WarnPrefix, message)
184 }
185
186 u.Ui.Warn(message)
187}
diff --git a/vendor/github.com/mitchellh/cli/ui_colored.go b/vendor/github.com/mitchellh/cli/ui_colored.go
new file mode 100644
index 0000000..e3d5131
--- /dev/null
+++ b/vendor/github.com/mitchellh/cli/ui_colored.go
@@ -0,0 +1,69 @@
1package cli
2
3import (
4 "fmt"
5)
6
7// UiColor is a posix shell color code to use.
8type UiColor struct {
9 Code int
10 Bold bool
11}
12
13// A list of colors that are useful. These are all non-bolded by default.
14var (
15 UiColorNone UiColor = UiColor{-1, false}
16 UiColorRed = UiColor{31, false}
17 UiColorGreen = UiColor{32, false}
18 UiColorYellow = UiColor{33, false}
19 UiColorBlue = UiColor{34, false}
20 UiColorMagenta = UiColor{35, false}
21 UiColorCyan = UiColor{36, false}
22)
23
24// ColoredUi is a Ui implementation that colors its output according
25// to the given color schemes for the given type of output.
26type ColoredUi struct {
27 OutputColor UiColor
28 InfoColor UiColor
29 ErrorColor UiColor
30 WarnColor UiColor
31 Ui Ui
32}
33
34func (u *ColoredUi) Ask(query string) (string, error) {
35 return u.Ui.Ask(u.colorize(query, u.OutputColor))
36}
37
38func (u *ColoredUi) AskSecret(query string) (string, error) {
39 return u.Ui.AskSecret(u.colorize(query, u.OutputColor))
40}
41
42func (u *ColoredUi) Output(message string) {
43 u.Ui.Output(u.colorize(message, u.OutputColor))
44}
45
46func (u *ColoredUi) Info(message string) {
47 u.Ui.Info(u.colorize(message, u.InfoColor))
48}
49
50func (u *ColoredUi) Error(message string) {
51 u.Ui.Error(u.colorize(message, u.ErrorColor))
52}
53
54func (u *ColoredUi) Warn(message string) {
55 u.Ui.Warn(u.colorize(message, u.WarnColor))
56}
57
58func (u *ColoredUi) colorize(message string, color UiColor) string {
59 if color.Code == -1 {
60 return message
61 }
62
63 attr := 0
64 if color.Bold {
65 attr = 1
66 }
67
68 return fmt.Sprintf("\033[%d;%dm%s\033[0m", attr, color.Code, message)
69}
diff --git a/vendor/github.com/mitchellh/cli/ui_concurrent.go b/vendor/github.com/mitchellh/cli/ui_concurrent.go
new file mode 100644
index 0000000..b4f4dbf
--- /dev/null
+++ b/vendor/github.com/mitchellh/cli/ui_concurrent.go
@@ -0,0 +1,54 @@
1package cli
2
3import (
4 "sync"
5)
6
7// ConcurrentUi is a wrapper around a Ui interface (and implements that
8// interface) making the underlying Ui concurrency safe.
9type ConcurrentUi struct {
10 Ui Ui
11 l sync.Mutex
12}
13
14func (u *ConcurrentUi) Ask(query string) (string, error) {
15 u.l.Lock()
16 defer u.l.Unlock()
17
18 return u.Ui.Ask(query)
19}
20
21func (u *ConcurrentUi) AskSecret(query string) (string, error) {
22 u.l.Lock()
23 defer u.l.Unlock()
24
25 return u.Ui.AskSecret(query)
26}
27
28func (u *ConcurrentUi) Error(message string) {
29 u.l.Lock()
30 defer u.l.Unlock()
31
32 u.Ui.Error(message)
33}
34
35func (u *ConcurrentUi) Info(message string) {
36 u.l.Lock()
37 defer u.l.Unlock()
38
39 u.Ui.Info(message)
40}
41
42func (u *ConcurrentUi) Output(message string) {
43 u.l.Lock()
44 defer u.l.Unlock()
45
46 u.Ui.Output(message)
47}
48
49func (u *ConcurrentUi) Warn(message string) {
50 u.l.Lock()
51 defer u.l.Unlock()
52
53 u.Ui.Warn(message)
54}
diff --git a/vendor/github.com/mitchellh/cli/ui_mock.go b/vendor/github.com/mitchellh/cli/ui_mock.go
new file mode 100644
index 0000000..0bfe0a1
--- /dev/null
+++ b/vendor/github.com/mitchellh/cli/ui_mock.go
@@ -0,0 +1,111 @@
1package cli
2
3import (
4 "bytes"
5 "fmt"
6 "io"
7 "sync"
8)
9
10// NewMockUi returns a fully initialized MockUi instance
11// which is safe for concurrent use.
12func NewMockUi() *MockUi {
13 m := new(MockUi)
14 m.once.Do(m.init)
15 return m
16}
17
18// MockUi is a mock UI that is used for tests and is exported publicly
19// for use in external tests if needed as well. Do not instantite this
20// directly since the buffers will be initialized on the first write. If
21// there is no write then you will get a nil panic. Please use the
22// NewMockUi() constructor function instead. You can fix your code with
23//
24// sed -i -e 's/new(cli.MockUi)/cli.NewMockUi()/g' *_test.go
25type MockUi struct {
26 InputReader io.Reader
27 ErrorWriter *syncBuffer
28 OutputWriter *syncBuffer
29
30 once sync.Once
31}
32
33func (u *MockUi) Ask(query string) (string, error) {
34 u.once.Do(u.init)
35
36 var result string
37 fmt.Fprint(u.OutputWriter, query)
38 if _, err := fmt.Fscanln(u.InputReader, &result); err != nil {
39 return "", err
40 }
41
42 return result, nil
43}
44
45func (u *MockUi) AskSecret(query string) (string, error) {
46 return u.Ask(query)
47}
48
49func (u *MockUi) Error(message string) {
50 u.once.Do(u.init)
51
52 fmt.Fprint(u.ErrorWriter, message)
53 fmt.Fprint(u.ErrorWriter, "\n")
54}
55
56func (u *MockUi) Info(message string) {
57 u.Output(message)
58}
59
60func (u *MockUi) Output(message string) {
61 u.once.Do(u.init)
62
63 fmt.Fprint(u.OutputWriter, message)
64 fmt.Fprint(u.OutputWriter, "\n")
65}
66
67func (u *MockUi) Warn(message string) {
68 u.once.Do(u.init)
69
70 fmt.Fprint(u.ErrorWriter, message)
71 fmt.Fprint(u.ErrorWriter, "\n")
72}
73
74func (u *MockUi) init() {
75 u.ErrorWriter = new(syncBuffer)
76 u.OutputWriter = new(syncBuffer)
77}
78
79type syncBuffer struct {
80 sync.RWMutex
81 b bytes.Buffer
82}
83
84func (b *syncBuffer) Write(data []byte) (int, error) {
85 b.Lock()
86 defer b.Unlock()
87 return b.b.Write(data)
88}
89
90func (b *syncBuffer) Read(data []byte) (int, error) {
91 b.RLock()
92 defer b.RUnlock()
93 return b.b.Read(data)
94}
95
96func (b *syncBuffer) Reset() {
97 b.Lock()
98 b.b.Reset()
99 b.Unlock()
100}
101
102func (b *syncBuffer) String() string {
103 return string(b.Bytes())
104}
105
106func (b *syncBuffer) Bytes() []byte {
107 b.RLock()
108 data := b.b.Bytes()
109 b.RUnlock()
110 return data
111}
diff --git a/vendor/github.com/mitchellh/cli/ui_writer.go b/vendor/github.com/mitchellh/cli/ui_writer.go
new file mode 100644
index 0000000..1e1db3c
--- /dev/null
+++ b/vendor/github.com/mitchellh/cli/ui_writer.go
@@ -0,0 +1,18 @@
1package cli
2
3// UiWriter is an io.Writer implementation that can be used with
4// loggers that writes every line of log output data to a Ui at the
5// Info level.
6type UiWriter struct {
7 Ui Ui
8}
9
10func (w *UiWriter) Write(p []byte) (n int, err error) {
11 n = len(p)
12 if n > 0 && p[n-1] == '\n' {
13 p = p[:n-1]
14 }
15
16 w.Ui.Info(string(p))
17 return n, nil
18}
diff --git a/vendor/github.com/mitchellh/copystructure/copystructure.go b/vendor/github.com/mitchellh/copystructure/copystructure.go
index 0e725ea..1404352 100644
--- a/vendor/github.com/mitchellh/copystructure/copystructure.go
+++ b/vendor/github.com/mitchellh/copystructure/copystructure.go
@@ -156,9 +156,13 @@ func (w *walker) Exit(l reflectwalk.Location) error {
156 } 156 }
157 157
158 switch l { 158 switch l {
159 case reflectwalk.Array:
160 fallthrough
159 case reflectwalk.Map: 161 case reflectwalk.Map:
160 fallthrough 162 fallthrough
161 case reflectwalk.Slice: 163 case reflectwalk.Slice:
164 w.replacePointerMaybe()
165
162 // Pop map off our container 166 // Pop map off our container
163 w.cs = w.cs[:len(w.cs)-1] 167 w.cs = w.cs[:len(w.cs)-1]
164 case reflectwalk.MapValue: 168 case reflectwalk.MapValue:
@@ -171,16 +175,27 @@ func (w *walker) Exit(l reflectwalk.Location) error {
171 // or in this case never adds it. We need to create a properly typed 175 // or in this case never adds it. We need to create a properly typed
172 // zero value so that this key can be set. 176 // zero value so that this key can be set.
173 if !mv.IsValid() { 177 if !mv.IsValid() {
174 mv = reflect.Zero(m.Type().Elem()) 178 mv = reflect.Zero(m.Elem().Type().Elem())
179 }
180 m.Elem().SetMapIndex(mk, mv)
181 case reflectwalk.ArrayElem:
182 // Pop off the value and the index and set it on the array
183 v := w.valPop()
184 i := w.valPop().Interface().(int)
185 if v.IsValid() {
186 a := w.cs[len(w.cs)-1]
187 ae := a.Elem().Index(i) // storing array as pointer on stack - so need Elem() call
188 if ae.CanSet() {
189 ae.Set(v)
190 }
175 } 191 }
176 m.SetMapIndex(mk, mv)
177 case reflectwalk.SliceElem: 192 case reflectwalk.SliceElem:
178 // Pop off the value and the index and set it on the slice 193 // Pop off the value and the index and set it on the slice
179 v := w.valPop() 194 v := w.valPop()
180 i := w.valPop().Interface().(int) 195 i := w.valPop().Interface().(int)
181 if v.IsValid() { 196 if v.IsValid() {
182 s := w.cs[len(w.cs)-1] 197 s := w.cs[len(w.cs)-1]
183 se := s.Index(i) 198 se := s.Elem().Index(i)
184 if se.CanSet() { 199 if se.CanSet() {
185 se.Set(v) 200 se.Set(v)
186 } 201 }
@@ -220,9 +235,9 @@ func (w *walker) Map(m reflect.Value) error {
220 // Create the map. If the map itself is nil, then just make a nil map 235 // Create the map. If the map itself is nil, then just make a nil map
221 var newMap reflect.Value 236 var newMap reflect.Value
222 if m.IsNil() { 237 if m.IsNil() {
223 newMap = reflect.Indirect(reflect.New(m.Type())) 238 newMap = reflect.New(m.Type())
224 } else { 239 } else {
225 newMap = reflect.MakeMap(m.Type()) 240 newMap = wrapPtr(reflect.MakeMap(m.Type()))
226 } 241 }
227 242
228 w.cs = append(w.cs, newMap) 243 w.cs = append(w.cs, newMap)
@@ -287,9 +302,9 @@ func (w *walker) Slice(s reflect.Value) error {
287 302
288 var newS reflect.Value 303 var newS reflect.Value
289 if s.IsNil() { 304 if s.IsNil() {
290 newS = reflect.Indirect(reflect.New(s.Type())) 305 newS = reflect.New(s.Type())
291 } else { 306 } else {
292 newS = reflect.MakeSlice(s.Type(), s.Len(), s.Cap()) 307 newS = wrapPtr(reflect.MakeSlice(s.Type(), s.Len(), s.Cap()))
293 } 308 }
294 309
295 w.cs = append(w.cs, newS) 310 w.cs = append(w.cs, newS)
@@ -309,6 +324,31 @@ func (w *walker) SliceElem(i int, elem reflect.Value) error {
309 return nil 324 return nil
310} 325}
311 326
327func (w *walker) Array(a reflect.Value) error {
328 if w.ignoring() {
329 return nil
330 }
331 w.lock(a)
332
333 newA := reflect.New(a.Type())
334
335 w.cs = append(w.cs, newA)
336 w.valPush(newA)
337 return nil
338}
339
340func (w *walker) ArrayElem(i int, elem reflect.Value) error {
341 if w.ignoring() {
342 return nil
343 }
344
345 // We don't write the array here because elem might still be
346 // arbitrarily complex. Just record the index and continue on.
347 w.valPush(reflect.ValueOf(i))
348
349 return nil
350}
351
312func (w *walker) Struct(s reflect.Value) error { 352func (w *walker) Struct(s reflect.Value) error {
313 if w.ignoring() { 353 if w.ignoring() {
314 return nil 354 return nil
@@ -326,7 +366,10 @@ func (w *walker) Struct(s reflect.Value) error {
326 return err 366 return err
327 } 367 }
328 368
329 v = reflect.ValueOf(dup) 369 // We need to put a pointer to the value on the value stack,
370 // so allocate a new pointer and set it.
371 v = reflect.New(s.Type())
372 reflect.Indirect(v).Set(reflect.ValueOf(dup))
330 } else { 373 } else {
331 // No copier, we copy ourselves and allow reflectwalk to guide 374 // No copier, we copy ourselves and allow reflectwalk to guide
332 // us deeper into the structure for copying. 375 // us deeper into the structure for copying.
@@ -405,6 +448,23 @@ func (w *walker) replacePointerMaybe() {
405 } 448 }
406 449
407 v := w.valPop() 450 v := w.valPop()
451
452 // If the expected type is a pointer to an interface of any depth,
453 // such as *interface{}, **interface{}, etc., then we need to convert
454 // the value "v" from *CONCRETE to *interface{} so types match for
455 // Set.
456 //
457 // Example if v is type *Foo where Foo is a struct, v would become
458 // *interface{} instead. This only happens if we have an interface expectation
459 // at this depth.
460 //
461 // For more info, see GH-16
462 if iType, ok := w.ifaceTypes[ifaceKey(w.ps[w.depth], w.depth)]; ok && iType.Kind() == reflect.Interface {
463 y := reflect.New(iType) // Create *interface{}
464 y.Elem().Set(reflect.Indirect(v)) // Assign "Foo" to interface{} (dereferenced)
465 v = y // v is now typed *interface{} (where *v = Foo)
466 }
467
408 for i := 1; i < w.ps[w.depth]; i++ { 468 for i := 1; i < w.ps[w.depth]; i++ {
409 if iType, ok := w.ifaceTypes[ifaceKey(w.ps[w.depth]-i, w.depth)]; ok { 469 if iType, ok := w.ifaceTypes[ifaceKey(w.ps[w.depth]-i, w.depth)]; ok {
410 iface := reflect.New(iType).Elem() 470 iface := reflect.New(iType).Elem()
@@ -475,3 +535,14 @@ func (w *walker) lock(v reflect.Value) {
475 locker.Lock() 535 locker.Lock()
476 w.locks[w.depth] = locker 536 w.locks[w.depth] = locker
477} 537}
538
539// wrapPtr is a helper that takes v and always make it *v. copystructure
540// stores things internally as pointers until the last moment before unwrapping
541func wrapPtr(v reflect.Value) reflect.Value {
542 if !v.IsValid() {
543 return v
544 }
545 vPtr := reflect.New(v.Type())
546 vPtr.Elem().Set(v)
547 return vPtr
548}
diff --git a/vendor/github.com/mitchellh/go-testing-interface/.travis.yml b/vendor/github.com/mitchellh/go-testing-interface/.travis.yml
new file mode 100644
index 0000000..4c83109
--- /dev/null
+++ b/vendor/github.com/mitchellh/go-testing-interface/.travis.yml
@@ -0,0 +1,12 @@
1language: go
2
3go:
4 - 1.8
5 - tip
6
7script:
8 - go test
9
10matrix:
11 allow_failures:
12 - go: tip
diff --git a/vendor/github.com/mitchellh/go-testing-interface/LICENSE b/vendor/github.com/mitchellh/go-testing-interface/LICENSE
new file mode 100644
index 0000000..a3866a2
--- /dev/null
+++ b/vendor/github.com/mitchellh/go-testing-interface/LICENSE
@@ -0,0 +1,21 @@
1The MIT License (MIT)
2
3Copyright (c) 2016 Mitchell Hashimoto
4
5Permission is hereby granted, free of charge, to any person obtaining a copy
6of this software and associated documentation files (the "Software"), to deal
7in the Software without restriction, including without limitation the rights
8to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9copies of the Software, and to permit persons to whom the Software is
10furnished to do so, subject to the following conditions:
11
12The above copyright notice and this permission notice shall be included in
13all copies or substantial portions of the Software.
14
15THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21THE SOFTWARE.
diff --git a/vendor/github.com/mitchellh/go-testing-interface/README.md b/vendor/github.com/mitchellh/go-testing-interface/README.md
new file mode 100644
index 0000000..26781bb
--- /dev/null
+++ b/vendor/github.com/mitchellh/go-testing-interface/README.md
@@ -0,0 +1,52 @@
1# go-testing-interface
2
3go-testing-interface is a Go library that exports an interface that
4`*testing.T` implements as well as a runtime version you can use in its
5place.
6
7The purpose of this library is so that you can export test helpers as a
8public API without depending on the "testing" package, since you can't
9create a `*testing.T` struct manually. This lets you, for example, use the
10public testing APIs to generate mock data at runtime, rather than just at
11test time.
12
13## Usage & Example
14
15For usage and examples see the [Godoc](http://godoc.org/github.com/mitchellh/go-testing-interface).
16
17Given a test helper written using `go-testing-interface` like this:
18
19 import "github.com/mitchellh/go-testing-interface"
20
21 func TestHelper(t testing.T) {
22 t.Fatal("I failed")
23 }
24
25You can call the test helper in a real test easily:
26
27 import "testing"
28
29 func TestThing(t *testing.T) {
30 TestHelper(t)
31 }
32
33You can also call the test helper at runtime if needed:
34
35 import "github.com/mitchellh/go-testing-interface"
36
37 func main() {
38 TestHelper(&testing.RuntimeT{})
39 }
40
41## Why?!
42
43**Why would I call a test helper that takes a *testing.T at runtime?**
44
45You probably shouldn't. The only use case I've seen (and I've had) for this
46is to implement a "dev mode" for a service where the test helpers are used
47to populate mock data, create a mock DB, perhaps run service dependencies
48in-memory, etc.
49
50Outside of a "dev mode", I've never seen a use case for this and I think
51there shouldn't be one since the point of the `testing.T` interface is that
52you can fail immediately.
diff --git a/vendor/github.com/mitchellh/go-testing-interface/testing.go b/vendor/github.com/mitchellh/go-testing-interface/testing.go
new file mode 100644
index 0000000..204afb4
--- /dev/null
+++ b/vendor/github.com/mitchellh/go-testing-interface/testing.go
@@ -0,0 +1,84 @@
1// +build !go1.9
2
3package testing
4
5import (
6 "fmt"
7 "log"
8)
9
10// T is the interface that mimics the standard library *testing.T.
11//
12// In unit tests you can just pass a *testing.T struct. At runtime, outside
13// of tests, you can pass in a RuntimeT struct from this package.
14type T interface {
15 Error(args ...interface{})
16 Errorf(format string, args ...interface{})
17 Fail()
18 FailNow()
19 Failed() bool
20 Fatal(args ...interface{})
21 Fatalf(format string, args ...interface{})
22 Log(args ...interface{})
23 Logf(format string, args ...interface{})
24 Name() string
25 Skip(args ...interface{})
26 SkipNow()
27 Skipf(format string, args ...interface{})
28 Skipped() bool
29}
30
31// RuntimeT implements T and can be instantiated and run at runtime to
32// mimic *testing.T behavior. Unlike *testing.T, this will simply panic
33// for calls to Fatal. For calls to Error, you'll have to check the errors
34// list to determine whether to exit yourself. Name and Skip methods are
35// unimplemented noops.
36type RuntimeT struct {
37 failed bool
38}
39
40func (t *RuntimeT) Error(args ...interface{}) {
41 log.Println(fmt.Sprintln(args...))
42 t.Fail()
43}
44
45func (t *RuntimeT) Errorf(format string, args ...interface{}) {
46 log.Println(fmt.Sprintf(format, args...))
47 t.Fail()
48}
49
50func (t *RuntimeT) Fatal(args ...interface{}) {
51 log.Println(fmt.Sprintln(args...))
52 t.FailNow()
53}
54
55func (t *RuntimeT) Fatalf(format string, args ...interface{}) {
56 log.Println(fmt.Sprintf(format, args...))
57 t.FailNow()
58}
59
60func (t *RuntimeT) Fail() {
61 t.failed = true
62}
63
64func (t *RuntimeT) FailNow() {
65 panic("testing.T failed, see logs for output (if any)")
66}
67
68func (t *RuntimeT) Failed() bool {
69 return t.failed
70}
71
72func (t *RuntimeT) Log(args ...interface{}) {
73 log.Println(fmt.Sprintln(args...))
74}
75
76func (t *RuntimeT) Logf(format string, args ...interface{}) {
77 log.Println(fmt.Sprintf(format, args...))
78}
79
80func (t *RuntimeT) Name() string { return "" }
81func (t *RuntimeT) Skip(args ...interface{}) {}
82func (t *RuntimeT) SkipNow() {}
83func (t *RuntimeT) Skipf(format string, args ...interface{}) {}
84func (t *RuntimeT) Skipped() bool { return false }
diff --git a/vendor/github.com/mitchellh/go-testing-interface/testing_go19.go b/vendor/github.com/mitchellh/go-testing-interface/testing_go19.go
new file mode 100644
index 0000000..07fbcb5
--- /dev/null
+++ b/vendor/github.com/mitchellh/go-testing-interface/testing_go19.go
@@ -0,0 +1,80 @@
1// +build go1.9
2
3// NOTE: This is a temporary copy of testing.go for Go 1.9 with the addition
4// of "Helper" to the T interface. Go 1.9 at the time of typing is in RC
5// and is set for release shortly. We'll support this on master as the default
6// as soon as 1.9 is released.
7
8package testing
9
10import (
11 "fmt"
12 "log"
13)
14
15// T is the interface that mimics the standard library *testing.T.
16//
17// In unit tests you can just pass a *testing.T struct. At runtime, outside
18// of tests, you can pass in a RuntimeT struct from this package.
19type T interface {
20 Error(args ...interface{})
21 Errorf(format string, args ...interface{})
22 Fatal(args ...interface{})
23 Fatalf(format string, args ...interface{})
24 Fail()
25 FailNow()
26 Failed() bool
27 Helper()
28 Log(args ...interface{})
29 Logf(format string, args ...interface{})
30}
31
32// RuntimeT implements T and can be instantiated and run at runtime to
33// mimic *testing.T behavior. Unlike *testing.T, this will simply panic
34// for calls to Fatal. For calls to Error, you'll have to check the errors
35// list to determine whether to exit yourself.
36type RuntimeT struct {
37 failed bool
38}
39
40func (t *RuntimeT) Error(args ...interface{}) {
41 log.Println(fmt.Sprintln(args...))
42 t.Fail()
43}
44
45func (t *RuntimeT) Errorf(format string, args ...interface{}) {
46 log.Println(fmt.Sprintf(format, args...))
47 t.Fail()
48}
49
50func (t *RuntimeT) Fatal(args ...interface{}) {
51 log.Println(fmt.Sprintln(args...))
52 t.FailNow()
53}
54
55func (t *RuntimeT) Fatalf(format string, args ...interface{}) {
56 log.Println(fmt.Sprintf(format, args...))
57 t.FailNow()
58}
59
60func (t *RuntimeT) Fail() {
61 t.failed = true
62}
63
64func (t *RuntimeT) FailNow() {
65 panic("testing.T failed, see logs for output (if any)")
66}
67
68func (t *RuntimeT) Failed() bool {
69 return t.failed
70}
71
72func (t *RuntimeT) Helper() {}
73
74func (t *RuntimeT) Log(args ...interface{}) {
75 log.Println(fmt.Sprintln(args...))
76}
77
78func (t *RuntimeT) Logf(format string, args ...interface{}) {
79 log.Println(fmt.Sprintf(format, args...))
80}
diff --git a/vendor/github.com/mitchellh/go-wordwrap/LICENSE.md b/vendor/github.com/mitchellh/go-wordwrap/LICENSE.md
new file mode 100644
index 0000000..2298515
--- /dev/null
+++ b/vendor/github.com/mitchellh/go-wordwrap/LICENSE.md
@@ -0,0 +1,21 @@
1The MIT License (MIT)
2
3Copyright (c) 2014 Mitchell Hashimoto
4
5Permission is hereby granted, free of charge, to any person obtaining a copy
6of this software and associated documentation files (the "Software"), to deal
7in the Software without restriction, including without limitation the rights
8to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9copies of the Software, and to permit persons to whom the Software is
10furnished to do so, subject to the following conditions:
11
12The above copyright notice and this permission notice shall be included in
13all copies or substantial portions of the Software.
14
15THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21THE SOFTWARE.
diff --git a/vendor/github.com/mitchellh/go-wordwrap/README.md b/vendor/github.com/mitchellh/go-wordwrap/README.md
new file mode 100644
index 0000000..60ae311
--- /dev/null
+++ b/vendor/github.com/mitchellh/go-wordwrap/README.md
@@ -0,0 +1,39 @@
1# go-wordwrap
2
3`go-wordwrap` (Golang package: `wordwrap`) is a package for Go that
4automatically wraps words into multiple lines. The primary use case for this
5is in formatting CLI output, but of course word wrapping is a generally useful
6thing to do.
7
8## Installation and Usage
9
10Install using `go get github.com/mitchellh/go-wordwrap`.
11
12Full documentation is available at
13http://godoc.org/github.com/mitchellh/go-wordwrap
14
15Below is an example of its usage ignoring errors:
16
17```go
18wrapped := wordwrap.WrapString("foo bar baz", 3)
19fmt.Println(wrapped)
20```
21
22Would output:
23
24```
25foo
26bar
27baz
28```
29
30## Word Wrap Algorithm
31
32This library doesn't use any clever algorithm for word wrapping. The wrapping
33is actually very naive: whenever there is whitespace or an explicit linebreak.
34The goal of this library is for word wrapping CLI output, so the input is
35typically pretty well controlled human language. Because of this, the naive
36approach typically works just fine.
37
38In the future, we'd like to make the algorithm more advanced. We would do
39so without breaking the API.
diff --git a/vendor/github.com/mitchellh/go-wordwrap/wordwrap.go b/vendor/github.com/mitchellh/go-wordwrap/wordwrap.go
new file mode 100644
index 0000000..ac67205
--- /dev/null
+++ b/vendor/github.com/mitchellh/go-wordwrap/wordwrap.go
@@ -0,0 +1,73 @@
1package wordwrap
2
3import (
4 "bytes"
5 "unicode"
6)
7
8// WrapString wraps the given string within lim width in characters.
9//
10// Wrapping is currently naive and only happens at white-space. A future
11// version of the library will implement smarter wrapping. This means that
12// pathological cases can dramatically reach past the limit, such as a very
13// long word.
14func WrapString(s string, lim uint) string {
15 // Initialize a buffer with a slightly larger size to account for breaks
16 init := make([]byte, 0, len(s))
17 buf := bytes.NewBuffer(init)
18
19 var current uint
20 var wordBuf, spaceBuf bytes.Buffer
21
22 for _, char := range s {
23 if char == '\n' {
24 if wordBuf.Len() == 0 {
25 if current+uint(spaceBuf.Len()) > lim {
26 current = 0
27 } else {
28 current += uint(spaceBuf.Len())
29 spaceBuf.WriteTo(buf)
30 }
31 spaceBuf.Reset()
32 } else {
33 current += uint(spaceBuf.Len() + wordBuf.Len())
34 spaceBuf.WriteTo(buf)
35 spaceBuf.Reset()
36 wordBuf.WriteTo(buf)
37 wordBuf.Reset()
38 }
39 buf.WriteRune(char)
40 current = 0
41 } else if unicode.IsSpace(char) {
42 if spaceBuf.Len() == 0 || wordBuf.Len() > 0 {
43 current += uint(spaceBuf.Len() + wordBuf.Len())
44 spaceBuf.WriteTo(buf)
45 spaceBuf.Reset()
46 wordBuf.WriteTo(buf)
47 wordBuf.Reset()
48 }
49
50 spaceBuf.WriteRune(char)
51 } else {
52
53 wordBuf.WriteRune(char)
54
55 if current+uint(spaceBuf.Len()+wordBuf.Len()) > lim && uint(wordBuf.Len()) < lim {
56 buf.WriteRune('\n')
57 current = 0
58 spaceBuf.Reset()
59 }
60 }
61 }
62
63 if wordBuf.Len() == 0 {
64 if current+uint(spaceBuf.Len()) <= lim {
65 spaceBuf.WriteTo(buf)
66 }
67 } else {
68 spaceBuf.WriteTo(buf)
69 wordBuf.WriteTo(buf)
70 }
71
72 return buf.String()
73}
diff --git a/vendor/github.com/mitchellh/reflectwalk/location.go b/vendor/github.com/mitchellh/reflectwalk/location.go
index 7c59d76..6a7f176 100644
--- a/vendor/github.com/mitchellh/reflectwalk/location.go
+++ b/vendor/github.com/mitchellh/reflectwalk/location.go
@@ -11,6 +11,8 @@ const (
11 MapValue 11 MapValue
12 Slice 12 Slice
13 SliceElem 13 SliceElem
14 Array
15 ArrayElem
14 Struct 16 Struct
15 StructField 17 StructField
16 WalkLoc 18 WalkLoc
diff --git a/vendor/github.com/mitchellh/reflectwalk/location_string.go b/vendor/github.com/mitchellh/reflectwalk/location_string.go
index d3cfe85..70760cf 100644
--- a/vendor/github.com/mitchellh/reflectwalk/location_string.go
+++ b/vendor/github.com/mitchellh/reflectwalk/location_string.go
@@ -1,15 +1,15 @@
1// generated by stringer -type=Location location.go; DO NOT EDIT 1// Code generated by "stringer -type=Location location.go"; DO NOT EDIT.
2 2
3package reflectwalk 3package reflectwalk
4 4
5import "fmt" 5import "fmt"
6 6
7const _Location_name = "NoneMapMapKeyMapValueSliceSliceElemStructStructFieldWalkLoc" 7const _Location_name = "NoneMapMapKeyMapValueSliceSliceElemArrayArrayElemStructStructFieldWalkLoc"
8 8
9var _Location_index = [...]uint8{0, 4, 7, 13, 21, 26, 35, 41, 52, 59} 9var _Location_index = [...]uint8{0, 4, 7, 13, 21, 26, 35, 40, 49, 55, 66, 73}
10 10
11func (i Location) String() string { 11func (i Location) String() string {
12 if i+1 >= Location(len(_Location_index)) { 12 if i >= Location(len(_Location_index)-1) {
13 return fmt.Sprintf("Location(%d)", i) 13 return fmt.Sprintf("Location(%d)", i)
14 } 14 }
15 return _Location_name[_Location_index[i]:_Location_index[i+1]] 15 return _Location_name[_Location_index[i]:_Location_index[i+1]]
diff --git a/vendor/github.com/mitchellh/reflectwalk/reflectwalk.go b/vendor/github.com/mitchellh/reflectwalk/reflectwalk.go
index ec0a623..d7ab7b6 100644
--- a/vendor/github.com/mitchellh/reflectwalk/reflectwalk.go
+++ b/vendor/github.com/mitchellh/reflectwalk/reflectwalk.go
@@ -39,6 +39,13 @@ type SliceWalker interface {
39 SliceElem(int, reflect.Value) error 39 SliceElem(int, reflect.Value) error
40} 40}
41 41
42// ArrayWalker implementations are able to handle array elements found
43// within complex structures.
44type ArrayWalker interface {
45 Array(reflect.Value) error
46 ArrayElem(int, reflect.Value) error
47}
48
42// StructWalker is an interface that has methods that are called for 49// StructWalker is an interface that has methods that are called for
43// structs when a Walk is done. 50// structs when a Walk is done.
44type StructWalker interface { 51type StructWalker interface {
@@ -65,6 +72,7 @@ type PointerWalker interface {
65// SkipEntry can be returned from walk functions to skip walking 72// SkipEntry can be returned from walk functions to skip walking
66// the value of this field. This is only valid in the following functions: 73// the value of this field. This is only valid in the following functions:
67// 74//
75// - Struct: skips all fields from being walked
68// - StructField: skips walking the struct value 76// - StructField: skips walking the struct value
69// 77//
70var SkipEntry = errors.New("skip this entry") 78var SkipEntry = errors.New("skip this entry")
@@ -179,6 +187,9 @@ func walk(v reflect.Value, w interface{}) (err error) {
179 case reflect.Struct: 187 case reflect.Struct:
180 err = walkStruct(v, w) 188 err = walkStruct(v, w)
181 return 189 return
190 case reflect.Array:
191 err = walkArray(v, w)
192 return
182 default: 193 default:
183 panic("unsupported type: " + k.String()) 194 panic("unsupported type: " + k.String())
184 } 195 }
@@ -286,48 +297,99 @@ func walkSlice(v reflect.Value, w interface{}) (err error) {
286 return nil 297 return nil
287} 298}
288 299
300func walkArray(v reflect.Value, w interface{}) (err error) {
301 ew, ok := w.(EnterExitWalker)
302 if ok {
303 ew.Enter(Array)
304 }
305
306 if aw, ok := w.(ArrayWalker); ok {
307 if err := aw.Array(v); err != nil {
308 return err
309 }
310 }
311
312 for i := 0; i < v.Len(); i++ {
313 elem := v.Index(i)
314
315 if aw, ok := w.(ArrayWalker); ok {
316 if err := aw.ArrayElem(i, elem); err != nil {
317 return err
318 }
319 }
320
321 ew, ok := w.(EnterExitWalker)
322 if ok {
323 ew.Enter(ArrayElem)
324 }
325
326 if err := walk(elem, w); err != nil {
327 return err
328 }
329
330 if ok {
331 ew.Exit(ArrayElem)
332 }
333 }
334
335 ew, ok = w.(EnterExitWalker)
336 if ok {
337 ew.Exit(Array)
338 }
339
340 return nil
341}
342
289func walkStruct(v reflect.Value, w interface{}) (err error) { 343func walkStruct(v reflect.Value, w interface{}) (err error) {
290 ew, ewok := w.(EnterExitWalker) 344 ew, ewok := w.(EnterExitWalker)
291 if ewok { 345 if ewok {
292 ew.Enter(Struct) 346 ew.Enter(Struct)
293 } 347 }
294 348
349 skip := false
295 if sw, ok := w.(StructWalker); ok { 350 if sw, ok := w.(StructWalker); ok {
296 if err = sw.Struct(v); err != nil { 351 err = sw.Struct(v)
352 if err == SkipEntry {
353 skip = true
354 err = nil
355 }
356 if err != nil {
297 return 357 return
298 } 358 }
299 } 359 }
300 360
301 vt := v.Type() 361 if !skip {
302 for i := 0; i < vt.NumField(); i++ { 362 vt := v.Type()
303 sf := vt.Field(i) 363 for i := 0; i < vt.NumField(); i++ {
304 f := v.FieldByIndex([]int{i}) 364 sf := vt.Field(i)
365 f := v.FieldByIndex([]int{i})
305 366
306 if sw, ok := w.(StructWalker); ok { 367 if sw, ok := w.(StructWalker); ok {
307 err = sw.StructField(sf, f) 368 err = sw.StructField(sf, f)
308 369
309 // SkipEntry just pretends this field doesn't even exist 370 // SkipEntry just pretends this field doesn't even exist
310 if err == SkipEntry { 371 if err == SkipEntry {
311 continue 372 continue
373 }
374
375 if err != nil {
376 return
377 }
378 }
379
380 ew, ok := w.(EnterExitWalker)
381 if ok {
382 ew.Enter(StructField)
312 } 383 }
313 384
385 err = walk(f, w)
314 if err != nil { 386 if err != nil {
315 return 387 return
316 } 388 }
317 }
318
319 ew, ok := w.(EnterExitWalker)
320 if ok {
321 ew.Enter(StructField)
322 }
323 389
324 err = walk(f, w) 390 if ok {
325 if err != nil { 391 ew.Exit(StructField)
326 return 392 }
327 }
328
329 if ok {
330 ew.Exit(StructField)
331 } 393 }
332 } 394 }
333 395