diff options
author | Alex Pilon <apilon@hashicorp.com> | 2019-02-22 18:24:37 -0500 |
---|---|---|
committer | Alex Pilon <apilon@hashicorp.com> | 2019-02-22 18:24:37 -0500 |
commit | 15c0b25d011f37e7c20aeca9eaf461f78285b8d9 (patch) | |
tree | 255c250a5c9d4801c74092d33b7337d8c14438ff /vendor/github.com/mitchellh | |
parent | 07971ca38143c5faf951d152fba370ddcbe26ad5 (diff) | |
download | terraform-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')
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 @@ | |||
1 | sudo: false | ||
2 | |||
3 | language: go | ||
4 | |||
5 | go: | ||
6 | - 1.8 | ||
7 | - 1.9 | ||
8 | |||
9 | branches: | ||
10 | only: | ||
11 | - master | ||
12 | |||
13 | script: 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 @@ | |||
1 | Mozilla Public License, version 2.0 | ||
2 | |||
3 | 1. Definitions | ||
4 | |||
5 | 1.1. “Contributor” | ||
6 | |||
7 | means each individual or legal entity that creates, contributes to the | ||
8 | creation of, or owns Covered Software. | ||
9 | |||
10 | 1.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 | |||
15 | 1.3. “Contribution” | ||
16 | |||
17 | means Covered Software of a particular Contributor. | ||
18 | |||
19 | 1.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 | |||
26 | 1.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 | |||
36 | 1.6. “Executable Form” | ||
37 | |||
38 | means any form of the work other than Source Code Form. | ||
39 | |||
40 | 1.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 | |||
45 | 1.8. “License” | ||
46 | |||
47 | means this document. | ||
48 | |||
49 | 1.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 | |||
55 | 1.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 | |||
64 | 1.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 | |||
72 | 1.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 | |||
78 | 1.13. “Source Code Form” | ||
79 | |||
80 | means the form of the work preferred for making modifications. | ||
81 | |||
82 | 1.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 | |||
93 | 2. License Grants and Conditions | ||
94 | |||
95 | 2.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 | |||
110 | 2.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 | |||
116 | 2.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 | |||
137 | 2.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 | |||
144 | 2.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 | |||
150 | 2.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 | |||
155 | 2.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 | |||
161 | 3. Responsibilities | ||
162 | |||
163 | 3.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 | |||
172 | 3.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 | |||
187 | 3.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 | |||
199 | 3.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 | |||
207 | 3.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 | |||
220 | 4. 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 | |||
232 | 5. Termination | ||
233 | |||
234 | 5.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 | |||
247 | 5.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 | |||
254 | 5.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 | |||
259 | 6. 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 | |||
272 | 7. 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 | |||
287 | 8. 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 | |||
295 | 9. 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 | |||
305 | 10. Versions of the License | ||
306 | |||
307 | 10.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 | |||
314 | 10.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 | |||
321 | 10.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 | |||
329 | 10.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 | |||
334 | Exhibit 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 | |||
343 | If it is not possible or desirable to put the notice in a particular file, then | ||
344 | You may include the notice in a location (such as a LICENSE file in a relevant | ||
345 | directory) where a recipient would be likely to look for such a notice. | ||
346 | |||
347 | You may add additional accurate notices of copyright ownership. | ||
348 | |||
349 | Exhibit 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 @@ | |||
1 | TEST?=./... | ||
2 | |||
3 | default: test | ||
4 | |||
5 | # test runs the test suite and vets the code | ||
6 | test: | ||
7 | go list $(TEST) | xargs -n1 go test -timeout=60s -parallel=10 $(TESTARGS) | ||
8 | |||
9 | # testrace runs the race checker | ||
10 | testrace: | ||
11 | go list $(TEST) | xargs -n1 go test -race $(TESTARGS) | ||
12 | |||
13 | # updatedeps installs all the dependencies to run and build | ||
14 | updatedeps: | ||
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 | |||
3 | cli is a library for implementing powerful command-line interfaces in Go. | ||
4 | cli 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 | |||
39 | Below is a simple example of creating and running a CLI | ||
40 | |||
41 | ```go | ||
42 | package main | ||
43 | |||
44 | import ( | ||
45 | "log" | ||
46 | "os" | ||
47 | |||
48 | "github.com/mitchellh/cli" | ||
49 | ) | ||
50 | |||
51 | func 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 @@ | |||
1 | package cli | ||
2 | |||
3 | import ( | ||
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. | ||
12 | type 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. | ||
19 | type realAutocompleteInstaller struct{} | ||
20 | |||
21 | func (i *realAutocompleteInstaller) Install(cmd string) error { | ||
22 | return install.Install(cmd) | ||
23 | } | ||
24 | |||
25 | func (i *realAutocompleteInstaller) Uninstall(cmd string) error { | ||
26 | return install.Uninstall(cmd) | ||
27 | } | ||
28 | |||
29 | // mockAutocompleteInstaller is used for tests to record the install/uninstall. | ||
30 | type mockAutocompleteInstaller struct { | ||
31 | InstallCalled bool | ||
32 | UninstallCalled bool | ||
33 | } | ||
34 | |||
35 | func (i *mockAutocompleteInstaller) Install(cmd string) error { | ||
36 | i.InstallCalled = true | ||
37 | return nil | ||
38 | } | ||
39 | |||
40 | func (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 @@ | |||
1 | package cli | ||
2 | |||
3 | import ( | ||
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 | // | ||
47 | type 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. | ||
145 | func 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. | ||
157 | func (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. | ||
164 | func (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. | ||
170 | func (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" | ||
268 | func (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. | ||
275 | func (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. | ||
282 | func (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 | |||
301 | func (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 | |||
385 | func (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. | ||
419 | func (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 | |||
481 | func (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. | ||
569 | func (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 | |||
606 | func (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. | ||
705 | const defaultAutocompleteInstall = "autocomplete-install" | ||
706 | const defaultAutocompleteUninstall = "autocomplete-uninstall" | ||
707 | |||
708 | const defaultHelpTemplate = ` | ||
709 | {{.Help}}{{if gt (len .Subcommands) 0}} | ||
710 | |||
711 | Subcommands: | ||
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 @@ | |||
1 | package cli | ||
2 | |||
3 | import ( | ||
4 | "github.com/posener/complete" | ||
5 | ) | ||
6 | |||
7 | const ( | ||
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. | ||
14 | type 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. | ||
37 | type 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. | ||
54 | type 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. | ||
67 | type 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 @@ | |||
1 | package cli | ||
2 | |||
3 | import ( | ||
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. | ||
10 | type 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 | |||
21 | func (c *MockCommand) Help() string { | ||
22 | return c.HelpText | ||
23 | } | ||
24 | |||
25 | func (c *MockCommand) Run(args []string) int { | ||
26 | c.RunCalled = true | ||
27 | c.RunArgs = args | ||
28 | |||
29 | return c.RunResult | ||
30 | } | ||
31 | |||
32 | func (c *MockCommand) Synopsis() string { | ||
33 | return c.SynopsisText | ||
34 | } | ||
35 | |||
36 | // MockCommandAutocomplete is an implementation of CommandAutocomplete. | ||
37 | type MockCommandAutocomplete struct { | ||
38 | MockCommand | ||
39 | |||
40 | // Settable | ||
41 | AutocompleteArgsValue complete.Predictor | ||
42 | AutocompleteFlagsValue complete.Flags | ||
43 | } | ||
44 | |||
45 | func (c *MockCommandAutocomplete) AutocompleteArgs() complete.Predictor { | ||
46 | return c.AutocompleteArgsValue | ||
47 | } | ||
48 | |||
49 | func (c *MockCommandAutocomplete) AutocompleteFlags() complete.Flags { | ||
50 | return c.AutocompleteFlagsValue | ||
51 | } | ||
52 | |||
53 | // MockCommandHelpTemplate is an implementation of CommandHelpTemplate. | ||
54 | type MockCommandHelpTemplate struct { | ||
55 | MockCommand | ||
56 | |||
57 | // Settable | ||
58 | HelpTemplateText string | ||
59 | } | ||
60 | |||
61 | func (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 @@ | |||
1 | package cli | ||
2 | |||
3 | import ( | ||
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. | ||
13 | type HelpFunc func(map[string]CommandFactory) string | ||
14 | |||
15 | // BasicHelpFunc generates some basic help output that is usually good enough | ||
16 | // for most CLI applications. | ||
17 | func 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. | ||
63 | func 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 @@ | |||
1 | package cli | ||
2 | |||
3 | import ( | ||
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. | ||
19 | type 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. | ||
48 | type BasicUi struct { | ||
49 | Reader io.Reader | ||
50 | Writer io.Writer | ||
51 | ErrorWriter io.Writer | ||
52 | } | ||
53 | |||
54 | func (u *BasicUi) Ask(query string) (string, error) { | ||
55 | return u.ask(query, false) | ||
56 | } | ||
57 | |||
58 | func (u *BasicUi) AskSecret(query string) (string, error) { | ||
59 | return u.ask(query, true) | ||
60 | } | ||
61 | |||
62 | func (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 | |||
107 | func (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 | |||
117 | func (u *BasicUi) Info(message string) { | ||
118 | u.Output(message) | ||
119 | } | ||
120 | |||
121 | func (u *BasicUi) Output(message string) { | ||
122 | fmt.Fprint(u.Writer, message) | ||
123 | fmt.Fprint(u.Writer, "\n") | ||
124 | } | ||
125 | |||
126 | func (u *BasicUi) Warn(message string) { | ||
127 | u.Error(message) | ||
128 | } | ||
129 | |||
130 | // PrefixedUi is an implementation of Ui that prefixes messages. | ||
131 | type 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 | |||
141 | func (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 | |||
149 | func (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 | |||
157 | func (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 | |||
165 | func (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 | |||
173 | func (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 | |||
181 | func (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 @@ | |||
1 | package cli | ||
2 | |||
3 | import ( | ||
4 | "fmt" | ||
5 | ) | ||
6 | |||
7 | // UiColor is a posix shell color code to use. | ||
8 | type 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. | ||
14 | var ( | ||
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. | ||
26 | type ColoredUi struct { | ||
27 | OutputColor UiColor | ||
28 | InfoColor UiColor | ||
29 | ErrorColor UiColor | ||
30 | WarnColor UiColor | ||
31 | Ui Ui | ||
32 | } | ||
33 | |||
34 | func (u *ColoredUi) Ask(query string) (string, error) { | ||
35 | return u.Ui.Ask(u.colorize(query, u.OutputColor)) | ||
36 | } | ||
37 | |||
38 | func (u *ColoredUi) AskSecret(query string) (string, error) { | ||
39 | return u.Ui.AskSecret(u.colorize(query, u.OutputColor)) | ||
40 | } | ||
41 | |||
42 | func (u *ColoredUi) Output(message string) { | ||
43 | u.Ui.Output(u.colorize(message, u.OutputColor)) | ||
44 | } | ||
45 | |||
46 | func (u *ColoredUi) Info(message string) { | ||
47 | u.Ui.Info(u.colorize(message, u.InfoColor)) | ||
48 | } | ||
49 | |||
50 | func (u *ColoredUi) Error(message string) { | ||
51 | u.Ui.Error(u.colorize(message, u.ErrorColor)) | ||
52 | } | ||
53 | |||
54 | func (u *ColoredUi) Warn(message string) { | ||
55 | u.Ui.Warn(u.colorize(message, u.WarnColor)) | ||
56 | } | ||
57 | |||
58 | func (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 @@ | |||
1 | package cli | ||
2 | |||
3 | import ( | ||
4 | "sync" | ||
5 | ) | ||
6 | |||
7 | // ConcurrentUi is a wrapper around a Ui interface (and implements that | ||
8 | // interface) making the underlying Ui concurrency safe. | ||
9 | type ConcurrentUi struct { | ||
10 | Ui Ui | ||
11 | l sync.Mutex | ||
12 | } | ||
13 | |||
14 | func (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 | |||
21 | func (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 | |||
28 | func (u *ConcurrentUi) Error(message string) { | ||
29 | u.l.Lock() | ||
30 | defer u.l.Unlock() | ||
31 | |||
32 | u.Ui.Error(message) | ||
33 | } | ||
34 | |||
35 | func (u *ConcurrentUi) Info(message string) { | ||
36 | u.l.Lock() | ||
37 | defer u.l.Unlock() | ||
38 | |||
39 | u.Ui.Info(message) | ||
40 | } | ||
41 | |||
42 | func (u *ConcurrentUi) Output(message string) { | ||
43 | u.l.Lock() | ||
44 | defer u.l.Unlock() | ||
45 | |||
46 | u.Ui.Output(message) | ||
47 | } | ||
48 | |||
49 | func (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 @@ | |||
1 | package cli | ||
2 | |||
3 | import ( | ||
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. | ||
12 | func 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 | ||
25 | type MockUi struct { | ||
26 | InputReader io.Reader | ||
27 | ErrorWriter *syncBuffer | ||
28 | OutputWriter *syncBuffer | ||
29 | |||
30 | once sync.Once | ||
31 | } | ||
32 | |||
33 | func (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 | |||
45 | func (u *MockUi) AskSecret(query string) (string, error) { | ||
46 | return u.Ask(query) | ||
47 | } | ||
48 | |||
49 | func (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 | |||
56 | func (u *MockUi) Info(message string) { | ||
57 | u.Output(message) | ||
58 | } | ||
59 | |||
60 | func (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 | |||
67 | func (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 | |||
74 | func (u *MockUi) init() { | ||
75 | u.ErrorWriter = new(syncBuffer) | ||
76 | u.OutputWriter = new(syncBuffer) | ||
77 | } | ||
78 | |||
79 | type syncBuffer struct { | ||
80 | sync.RWMutex | ||
81 | b bytes.Buffer | ||
82 | } | ||
83 | |||
84 | func (b *syncBuffer) Write(data []byte) (int, error) { | ||
85 | b.Lock() | ||
86 | defer b.Unlock() | ||
87 | return b.b.Write(data) | ||
88 | } | ||
89 | |||
90 | func (b *syncBuffer) Read(data []byte) (int, error) { | ||
91 | b.RLock() | ||
92 | defer b.RUnlock() | ||
93 | return b.b.Read(data) | ||
94 | } | ||
95 | |||
96 | func (b *syncBuffer) Reset() { | ||
97 | b.Lock() | ||
98 | b.b.Reset() | ||
99 | b.Unlock() | ||
100 | } | ||
101 | |||
102 | func (b *syncBuffer) String() string { | ||
103 | return string(b.Bytes()) | ||
104 | } | ||
105 | |||
106 | func (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 @@ | |||
1 | package 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. | ||
6 | type UiWriter struct { | ||
7 | Ui Ui | ||
8 | } | ||
9 | |||
10 | func (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 | ||
327 | func (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 | |||
340 | func (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 | |||
312 | func (w *walker) Struct(s reflect.Value) error { | 352 | func (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 | ||
541 | func 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 @@ | |||
1 | language: go | ||
2 | |||
3 | go: | ||
4 | - 1.8 | ||
5 | - tip | ||
6 | |||
7 | script: | ||
8 | - go test | ||
9 | |||
10 | matrix: | ||
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 @@ | |||
1 | The MIT License (MIT) | ||
2 | |||
3 | Copyright (c) 2016 Mitchell Hashimoto | ||
4 | |||
5 | Permission is hereby granted, free of charge, to any person obtaining a copy | ||
6 | of this software and associated documentation files (the "Software"), to deal | ||
7 | in the Software without restriction, including without limitation the rights | ||
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
9 | copies of the Software, and to permit persons to whom the Software is | ||
10 | furnished to do so, subject to the following conditions: | ||
11 | |||
12 | The above copyright notice and this permission notice shall be included in | ||
13 | all copies or substantial portions of the Software. | ||
14 | |||
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||
21 | THE 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 | |||
3 | go-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 | ||
5 | place. | ||
6 | |||
7 | The purpose of this library is so that you can export test helpers as a | ||
8 | public API without depending on the "testing" package, since you can't | ||
9 | create a `*testing.T` struct manually. This lets you, for example, use the | ||
10 | public testing APIs to generate mock data at runtime, rather than just at | ||
11 | test time. | ||
12 | |||
13 | ## Usage & Example | ||
14 | |||
15 | For usage and examples see the [Godoc](http://godoc.org/github.com/mitchellh/go-testing-interface). | ||
16 | |||
17 | Given 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 | |||
25 | You 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 | |||
33 | You 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 | |||
45 | You probably shouldn't. The only use case I've seen (and I've had) for this | ||
46 | is to implement a "dev mode" for a service where the test helpers are used | ||
47 | to populate mock data, create a mock DB, perhaps run service dependencies | ||
48 | in-memory, etc. | ||
49 | |||
50 | Outside of a "dev mode", I've never seen a use case for this and I think | ||
51 | there shouldn't be one since the point of the `testing.T` interface is that | ||
52 | you 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 | |||
3 | package testing | ||
4 | |||
5 | import ( | ||
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. | ||
14 | type 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. | ||
36 | type RuntimeT struct { | ||
37 | failed bool | ||
38 | } | ||
39 | |||
40 | func (t *RuntimeT) Error(args ...interface{}) { | ||
41 | log.Println(fmt.Sprintln(args...)) | ||
42 | t.Fail() | ||
43 | } | ||
44 | |||
45 | func (t *RuntimeT) Errorf(format string, args ...interface{}) { | ||
46 | log.Println(fmt.Sprintf(format, args...)) | ||
47 | t.Fail() | ||
48 | } | ||
49 | |||
50 | func (t *RuntimeT) Fatal(args ...interface{}) { | ||
51 | log.Println(fmt.Sprintln(args...)) | ||
52 | t.FailNow() | ||
53 | } | ||
54 | |||
55 | func (t *RuntimeT) Fatalf(format string, args ...interface{}) { | ||
56 | log.Println(fmt.Sprintf(format, args...)) | ||
57 | t.FailNow() | ||
58 | } | ||
59 | |||
60 | func (t *RuntimeT) Fail() { | ||
61 | t.failed = true | ||
62 | } | ||
63 | |||
64 | func (t *RuntimeT) FailNow() { | ||
65 | panic("testing.T failed, see logs for output (if any)") | ||
66 | } | ||
67 | |||
68 | func (t *RuntimeT) Failed() bool { | ||
69 | return t.failed | ||
70 | } | ||
71 | |||
72 | func (t *RuntimeT) Log(args ...interface{}) { | ||
73 | log.Println(fmt.Sprintln(args...)) | ||
74 | } | ||
75 | |||
76 | func (t *RuntimeT) Logf(format string, args ...interface{}) { | ||
77 | log.Println(fmt.Sprintf(format, args...)) | ||
78 | } | ||
79 | |||
80 | func (t *RuntimeT) Name() string { return "" } | ||
81 | func (t *RuntimeT) Skip(args ...interface{}) {} | ||
82 | func (t *RuntimeT) SkipNow() {} | ||
83 | func (t *RuntimeT) Skipf(format string, args ...interface{}) {} | ||
84 | func (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 | |||
8 | package testing | ||
9 | |||
10 | import ( | ||
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. | ||
19 | type 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. | ||
36 | type RuntimeT struct { | ||
37 | failed bool | ||
38 | } | ||
39 | |||
40 | func (t *RuntimeT) Error(args ...interface{}) { | ||
41 | log.Println(fmt.Sprintln(args...)) | ||
42 | t.Fail() | ||
43 | } | ||
44 | |||
45 | func (t *RuntimeT) Errorf(format string, args ...interface{}) { | ||
46 | log.Println(fmt.Sprintf(format, args...)) | ||
47 | t.Fail() | ||
48 | } | ||
49 | |||
50 | func (t *RuntimeT) Fatal(args ...interface{}) { | ||
51 | log.Println(fmt.Sprintln(args...)) | ||
52 | t.FailNow() | ||
53 | } | ||
54 | |||
55 | func (t *RuntimeT) Fatalf(format string, args ...interface{}) { | ||
56 | log.Println(fmt.Sprintf(format, args...)) | ||
57 | t.FailNow() | ||
58 | } | ||
59 | |||
60 | func (t *RuntimeT) Fail() { | ||
61 | t.failed = true | ||
62 | } | ||
63 | |||
64 | func (t *RuntimeT) FailNow() { | ||
65 | panic("testing.T failed, see logs for output (if any)") | ||
66 | } | ||
67 | |||
68 | func (t *RuntimeT) Failed() bool { | ||
69 | return t.failed | ||
70 | } | ||
71 | |||
72 | func (t *RuntimeT) Helper() {} | ||
73 | |||
74 | func (t *RuntimeT) Log(args ...interface{}) { | ||
75 | log.Println(fmt.Sprintln(args...)) | ||
76 | } | ||
77 | |||
78 | func (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 @@ | |||
1 | The MIT License (MIT) | ||
2 | |||
3 | Copyright (c) 2014 Mitchell Hashimoto | ||
4 | |||
5 | Permission is hereby granted, free of charge, to any person obtaining a copy | ||
6 | of this software and associated documentation files (the "Software"), to deal | ||
7 | in the Software without restriction, including without limitation the rights | ||
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
9 | copies of the Software, and to permit persons to whom the Software is | ||
10 | furnished to do so, subject to the following conditions: | ||
11 | |||
12 | The above copyright notice and this permission notice shall be included in | ||
13 | all copies or substantial portions of the Software. | ||
14 | |||
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||
21 | THE 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 | ||
4 | automatically wraps words into multiple lines. The primary use case for this | ||
5 | is in formatting CLI output, but of course word wrapping is a generally useful | ||
6 | thing to do. | ||
7 | |||
8 | ## Installation and Usage | ||
9 | |||
10 | Install using `go get github.com/mitchellh/go-wordwrap`. | ||
11 | |||
12 | Full documentation is available at | ||
13 | http://godoc.org/github.com/mitchellh/go-wordwrap | ||
14 | |||
15 | Below is an example of its usage ignoring errors: | ||
16 | |||
17 | ```go | ||
18 | wrapped := wordwrap.WrapString("foo bar baz", 3) | ||
19 | fmt.Println(wrapped) | ||
20 | ``` | ||
21 | |||
22 | Would output: | ||
23 | |||
24 | ``` | ||
25 | foo | ||
26 | bar | ||
27 | baz | ||
28 | ``` | ||
29 | |||
30 | ## Word Wrap Algorithm | ||
31 | |||
32 | This library doesn't use any clever algorithm for word wrapping. The wrapping | ||
33 | is actually very naive: whenever there is whitespace or an explicit linebreak. | ||
34 | The goal of this library is for word wrapping CLI output, so the input is | ||
35 | typically pretty well controlled human language. Because of this, the naive | ||
36 | approach typically works just fine. | ||
37 | |||
38 | In the future, we'd like to make the algorithm more advanced. We would do | ||
39 | so 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 @@ | |||
1 | package wordwrap | ||
2 | |||
3 | import ( | ||
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. | ||
14 | func 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 | ||
3 | package reflectwalk | 3 | package reflectwalk |
4 | 4 | ||
5 | import "fmt" | 5 | import "fmt" |
6 | 6 | ||
7 | const _Location_name = "NoneMapMapKeyMapValueSliceSliceElemStructStructFieldWalkLoc" | 7 | const _Location_name = "NoneMapMapKeyMapValueSliceSliceElemArrayArrayElemStructStructFieldWalkLoc" |
8 | 8 | ||
9 | var _Location_index = [...]uint8{0, 4, 7, 13, 21, 26, 35, 41, 52, 59} | 9 | var _Location_index = [...]uint8{0, 4, 7, 13, 21, 26, 35, 40, 49, 55, 66, 73} |
10 | 10 | ||
11 | func (i Location) String() string { | 11 | func (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. | ||
44 | type 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. |
44 | type StructWalker interface { | 51 | type 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 | // |
70 | var SkipEntry = errors.New("skip this entry") | 78 | var 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 | ||
300 | func 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 | |||
289 | func walkStruct(v reflect.Value, w interface{}) (err error) { | 343 | func 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 | ||