cliqr 1.1.0 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +128 -1
- data/README.md +97 -71
- data/examples/README.md +12 -0
- data/examples/hbase +58 -0
- data/examples/my-command +63 -0
- data/examples/numbers +55 -0
- data/examples/vagrant +90 -0
- data/lib/cliqr.rb +17 -2
- data/lib/cliqr/argument_validation/argument_type_validator.rb +2 -2
- data/lib/cliqr/argument_validation/validator.rb +1 -1
- data/lib/cliqr/cli/argument_operator.rb +44 -0
- data/lib/cliqr/cli/argument_operator_context.rb +20 -0
- data/lib/cliqr/cli/command.rb +1 -1
- data/lib/cliqr/cli/command_context.rb +93 -12
- data/lib/cliqr/cli/command_runner_factory.rb +2 -2
- data/lib/cliqr/cli/config.rb +301 -33
- data/lib/cliqr/cli/executor.rb +14 -9
- data/lib/cliqr/cli/interface.rb +22 -7
- data/lib/cliqr/cli/router.rb +6 -2
- data/lib/cliqr/cli/shell_command.rb +69 -0
- data/lib/cliqr/cli/usage_builder.rb +185 -0
- data/lib/cliqr/config_validation/validator_factory.rb +59 -5
- data/lib/cliqr/error.rb +10 -4
- data/lib/cliqr/parser/action_token.rb +23 -0
- data/lib/cliqr/parser/argument_parser.rb +1 -1
- data/lib/cliqr/parser/argument_token.rb +1 -4
- data/lib/cliqr/parser/argument_tree_walker.rb +40 -8
- data/lib/cliqr/parser/option_token.rb +2 -1
- data/lib/cliqr/parser/parsed_input.rb +21 -2
- data/lib/cliqr/parser/parsed_input_builder.rb +11 -7
- data/lib/cliqr/parser/token.rb +3 -9
- data/lib/cliqr/parser/token_factory.rb +1 -1
- data/lib/cliqr/util.rb +135 -0
- data/lib/cliqr/version.rb +1 -1
- data/spec/argument_parser_spec_helper.rb +15 -0
- data/spec/config/action_config_validator_spec.rb +146 -0
- data/spec/config/config_finalize_spec.rb +1 -1
- data/spec/config/config_validator_spec.rb +29 -19
- data/spec/config/option_config_validator_spec.rb +13 -13
- data/spec/dsl/interface_spec.rb +1 -168
- data/spec/dsl/usage_spec.rb +705 -0
- data/spec/executor/action_executor_spec.rb +205 -0
- data/spec/executor/executor_spec.rb +405 -17
- data/spec/executor/help_executor_spec.rb +424 -0
- data/spec/executor/shell_executor_spec.rb +233 -0
- data/spec/fixtures/action_reader_command.rb +12 -0
- data/spec/fixtures/csv_argument_operator.rb +8 -0
- data/spec/fixtures/test_option_type_checker_command.rb +8 -0
- data/spec/parser/action_argument_parser_spec.rb +113 -0
- data/spec/parser/argument_parser_spec.rb +37 -44
- data/spec/spec_helper.rb +1 -0
- data/spec/validation/action_argument_validator_spec.rb +50 -0
- data/spec/validation/{argument_validation_spec.rb → command_argument_validation_spec.rb} +36 -18
- data/spec/validation/error_spec.rb +1 -1
- data/tasks/rdoc.rake +16 -0
- data/tasks/rubucop.rake +14 -0
- data/tasks/yard.rake +21 -0
- data/templates/usage.erb +39 -0
- metadata +48 -11
@@ -0,0 +1,424 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
require 'cliqr/error'
|
6
|
+
|
7
|
+
require 'fixtures/test_command'
|
8
|
+
|
9
|
+
describe Cliqr::CLI::Executor do
|
10
|
+
it 'can execute help action to get help for base command' do
|
11
|
+
cli = Cliqr.interface do
|
12
|
+
name 'my-command'
|
13
|
+
description 'test command has no description'
|
14
|
+
handler TestCommand
|
15
|
+
end
|
16
|
+
|
17
|
+
result = cli.execute_internal ['help'], output: :buffer
|
18
|
+
expect(result[:stdout]).to eq <<-EOS
|
19
|
+
my-command -- test command has no description
|
20
|
+
|
21
|
+
USAGE:
|
22
|
+
my-command [actions] [options] [arguments]
|
23
|
+
|
24
|
+
Available options:
|
25
|
+
|
26
|
+
--help, -h : Get helpful information for action "my-command" along with its usage information.
|
27
|
+
|
28
|
+
Available actions:
|
29
|
+
[ Type "my-command help [action-name]" to get more information about that action ]
|
30
|
+
|
31
|
+
help -- The help action for command "my-command" which provides details and usage information on how to use the command.
|
32
|
+
EOS
|
33
|
+
end
|
34
|
+
|
35
|
+
it 'can execute help option to get help for base command' do
|
36
|
+
cli = Cliqr.interface do
|
37
|
+
name 'my-command'
|
38
|
+
description 'test command has no description'
|
39
|
+
handler TestCommand
|
40
|
+
end
|
41
|
+
|
42
|
+
result = cli.execute_internal ['--help'], output: :buffer
|
43
|
+
expect(result[:stdout]).to eq <<-EOS
|
44
|
+
my-command -- test command has no description
|
45
|
+
|
46
|
+
USAGE:
|
47
|
+
my-command [actions] [options] [arguments]
|
48
|
+
|
49
|
+
Available options:
|
50
|
+
|
51
|
+
--help, -h : Get helpful information for action "my-command" along with its usage information.
|
52
|
+
|
53
|
+
Available actions:
|
54
|
+
[ Type "my-command help [action-name]" to get more information about that action ]
|
55
|
+
|
56
|
+
help -- The help action for command "my-command" which provides details and usage information on how to use the command.
|
57
|
+
EOS
|
58
|
+
end
|
59
|
+
|
60
|
+
it 'can execute help action to get help for a action' do
|
61
|
+
cli = Cliqr.interface do
|
62
|
+
name :my_command
|
63
|
+
description 'test command has no description'
|
64
|
+
handler TestCommand
|
65
|
+
|
66
|
+
action :action_1 do
|
67
|
+
description 'test action'
|
68
|
+
handler TestCommand
|
69
|
+
shell :disable
|
70
|
+
|
71
|
+
action :sub_action do
|
72
|
+
description 'This is a sub action.'
|
73
|
+
handler TestCommand
|
74
|
+
end
|
75
|
+
|
76
|
+
option :temp do
|
77
|
+
description 'temporary option'
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
action :action_2 do
|
82
|
+
description 'another cool action for the base command'
|
83
|
+
handler TestCommand
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
result = cli.execute_internal %w(help action_1), output: :buffer
|
88
|
+
expect(result[:stdout]).to eq <<-EOS
|
89
|
+
my_command action_1 -- test action
|
90
|
+
|
91
|
+
USAGE:
|
92
|
+
my_command action_1 [actions] [options] [arguments]
|
93
|
+
|
94
|
+
Available options:
|
95
|
+
|
96
|
+
--temp : temporary option
|
97
|
+
--help, -h : Get helpful information for action "my_command action_1" along with its usage information.
|
98
|
+
|
99
|
+
Available actions:
|
100
|
+
[ Type "my_command action_1 help [action-name]" to get more information about that action ]
|
101
|
+
|
102
|
+
sub_action -- This is a sub action.
|
103
|
+
|
104
|
+
help -- The help action for command "my_command action_1" which provides details and usage information on how to use the command.
|
105
|
+
EOS
|
106
|
+
end
|
107
|
+
|
108
|
+
it 'can use help option to get help for a action' do
|
109
|
+
cli = Cliqr.interface do
|
110
|
+
name :my_command
|
111
|
+
description 'test command has no description'
|
112
|
+
handler TestCommand
|
113
|
+
|
114
|
+
action :action_1 do
|
115
|
+
description 'test action'
|
116
|
+
handler TestCommand
|
117
|
+
|
118
|
+
action :sub_action do
|
119
|
+
description 'This is a sub action.'
|
120
|
+
handler TestCommand
|
121
|
+
end
|
122
|
+
|
123
|
+
option :temp do
|
124
|
+
description 'temporary option'
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
action :action_2 do
|
129
|
+
description 'another cool action for the base command'
|
130
|
+
handler TestCommand
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
result = cli.execute_internal %w(action_2 --help), output: :buffer
|
135
|
+
expect(result[:stdout]).to eq <<-EOS
|
136
|
+
my_command action_2 -- another cool action for the base command
|
137
|
+
|
138
|
+
USAGE:
|
139
|
+
my_command action_2 [actions] [options] [arguments]
|
140
|
+
|
141
|
+
Available options:
|
142
|
+
|
143
|
+
--help, -h : Get helpful information for action "my_command action_2" along with its usage information.
|
144
|
+
|
145
|
+
Available actions:
|
146
|
+
[ Type "my_command action_2 help [action-name]" to get more information about that action ]
|
147
|
+
|
148
|
+
help -- The help action for command "my_command action_2" which provides details and usage information on how to use the command.
|
149
|
+
EOS
|
150
|
+
end
|
151
|
+
|
152
|
+
it 'can execute help action to get help for base command with multiple actions' do
|
153
|
+
cli = Cliqr.interface do
|
154
|
+
name :my_command
|
155
|
+
description 'test command has no description'
|
156
|
+
handler TestCommand
|
157
|
+
shell :disable
|
158
|
+
|
159
|
+
action :action_1 do
|
160
|
+
description 'test action'
|
161
|
+
handler TestCommand
|
162
|
+
|
163
|
+
action :sub_action do
|
164
|
+
description 'This is a sub action.'
|
165
|
+
handler TestCommand
|
166
|
+
end
|
167
|
+
|
168
|
+
option :temp do
|
169
|
+
description 'temporary option'
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
173
|
+
action :action_2 do
|
174
|
+
description 'another cool action for the base command'
|
175
|
+
handler TestCommand
|
176
|
+
end
|
177
|
+
end
|
178
|
+
|
179
|
+
result = cli.execute_internal %w(help), output: :buffer
|
180
|
+
expect(result[:stdout]).to eq <<-EOS
|
181
|
+
my_command -- test command has no description
|
182
|
+
|
183
|
+
USAGE:
|
184
|
+
my_command [actions] [options] [arguments]
|
185
|
+
|
186
|
+
Available options:
|
187
|
+
|
188
|
+
--help, -h : Get helpful information for action "my_command" along with its usage information.
|
189
|
+
|
190
|
+
Available actions:
|
191
|
+
[ Type "my_command help [action-name]" to get more information about that action ]
|
192
|
+
|
193
|
+
action_1 -- test action
|
194
|
+
|
195
|
+
action_2 -- another cool action for the base command
|
196
|
+
|
197
|
+
help -- The help action for command "my_command" which provides details and usage information on how to use the command.
|
198
|
+
EOS
|
199
|
+
end
|
200
|
+
|
201
|
+
it 'can execute help option to get help for base command' do
|
202
|
+
cli = Cliqr.interface do
|
203
|
+
name 'my-command'
|
204
|
+
description 'test command has no description'
|
205
|
+
handler TestCommand
|
206
|
+
end
|
207
|
+
|
208
|
+
result = cli.execute_internal ['--help'], output: :buffer
|
209
|
+
expect(result[:stdout]).to eq <<-EOS
|
210
|
+
my-command -- test command has no description
|
211
|
+
|
212
|
+
USAGE:
|
213
|
+
my-command [actions] [options] [arguments]
|
214
|
+
|
215
|
+
Available options:
|
216
|
+
|
217
|
+
--help, -h : Get helpful information for action "my-command" along with its usage information.
|
218
|
+
|
219
|
+
Available actions:
|
220
|
+
[ Type "my-command help [action-name]" to get more information about that action ]
|
221
|
+
|
222
|
+
help -- The help action for command "my-command" which provides details and usage information on how to use the command.
|
223
|
+
EOS
|
224
|
+
end
|
225
|
+
|
226
|
+
it 'can execute help option to get help for a action' do
|
227
|
+
cli = Cliqr.interface do
|
228
|
+
name :my_command
|
229
|
+
description 'test command has no description'
|
230
|
+
handler TestCommand
|
231
|
+
|
232
|
+
action :action_1 do
|
233
|
+
handler TestCommand
|
234
|
+
end
|
235
|
+
end
|
236
|
+
|
237
|
+
result = cli.execute_internal %w(--help action_1), output: :buffer
|
238
|
+
expect(result[:stdout]).to eq <<-EOS
|
239
|
+
my_command action_1
|
240
|
+
|
241
|
+
USAGE:
|
242
|
+
my_command action_1 [actions] [options] [arguments]
|
243
|
+
|
244
|
+
Available options:
|
245
|
+
|
246
|
+
--help, -h : Get helpful information for action "my_command action_1" along with its usage information.
|
247
|
+
|
248
|
+
Available actions:
|
249
|
+
[ Type "my_command action_1 help [action-name]" to get more information about that action ]
|
250
|
+
|
251
|
+
help -- The help action for command "my_command action_1" which provides details and usage information on how to use the command.
|
252
|
+
EOS
|
253
|
+
end
|
254
|
+
|
255
|
+
it 'can execute help action on the action itself to get help for a action' do
|
256
|
+
cli = Cliqr.interface do
|
257
|
+
name :my_command
|
258
|
+
description 'test command has no description'
|
259
|
+
handler TestCommand
|
260
|
+
|
261
|
+
action :action_1 do
|
262
|
+
description 'test action'
|
263
|
+
handler TestCommand
|
264
|
+
end
|
265
|
+
end
|
266
|
+
|
267
|
+
result = cli.execute_internal %w(action_1 help), output: :buffer
|
268
|
+
expect(result[:stdout]).to eq <<-EOS
|
269
|
+
my_command action_1 -- test action
|
270
|
+
|
271
|
+
USAGE:
|
272
|
+
my_command action_1 [actions] [options] [arguments]
|
273
|
+
|
274
|
+
Available options:
|
275
|
+
|
276
|
+
--help, -h : Get helpful information for action "my_command action_1" along with its usage information.
|
277
|
+
|
278
|
+
Available actions:
|
279
|
+
[ Type "my_command action_1 help [action-name]" to get more information about that action ]
|
280
|
+
|
281
|
+
help -- The help action for command "my_command action_1" which provides details and usage information on how to use the command.
|
282
|
+
EOS
|
283
|
+
end
|
284
|
+
|
285
|
+
it 'can execute help action on itself' do
|
286
|
+
cli = Cliqr.interface do
|
287
|
+
name :my_command
|
288
|
+
description 'test command has no description'
|
289
|
+
handler TestCommand
|
290
|
+
|
291
|
+
action :action_1 do
|
292
|
+
description 'test action'
|
293
|
+
handler TestCommand
|
294
|
+
end
|
295
|
+
end
|
296
|
+
|
297
|
+
result = cli.execute_internal %w(help help), output: :buffer
|
298
|
+
expect(result[:stdout]).to eq <<-EOS
|
299
|
+
my_command help -- The help action for command "my_command" which provides details and usage information on how to use the command.
|
300
|
+
|
301
|
+
USAGE:
|
302
|
+
my_command help [arguments]
|
303
|
+
EOS
|
304
|
+
end
|
305
|
+
|
306
|
+
it 'does not allow help action to take more than one argument' do
|
307
|
+
cli = Cliqr.interface do
|
308
|
+
name :my_command
|
309
|
+
description 'test command has no description'
|
310
|
+
handler TestCommand
|
311
|
+
|
312
|
+
action :action_1 do
|
313
|
+
description 'test action'
|
314
|
+
handler TestCommand
|
315
|
+
end
|
316
|
+
end
|
317
|
+
|
318
|
+
expect { cli.execute_internal %w(help action_1 arg2), output: :buffer }.to(
|
319
|
+
raise_error(Cliqr::Error::CommandRuntimeError,
|
320
|
+
"command 'my_command help' failed\n\n" \
|
321
|
+
"Cause: Cliqr::Error::IllegalArgumentError - too many arguments for \"my_command help\" command\n"))
|
322
|
+
end
|
323
|
+
|
324
|
+
it 'can forward command to another action' do
|
325
|
+
cli = Cliqr.interface do
|
326
|
+
name :my_command
|
327
|
+
description 'test command has no description'
|
328
|
+
handler TestCommand
|
329
|
+
|
330
|
+
action :action_1 do
|
331
|
+
description 'test action'
|
332
|
+
handler do
|
333
|
+
puts 'in action_1'
|
334
|
+
forward 'my_command action_2 sub-action' # starting with base command name
|
335
|
+
puts 'back in action_1'
|
336
|
+
end
|
337
|
+
end
|
338
|
+
|
339
|
+
action 'action_2' do
|
340
|
+
handler do
|
341
|
+
puts 'in action_2'
|
342
|
+
end
|
343
|
+
|
344
|
+
action 'sub-action' do
|
345
|
+
handler do
|
346
|
+
puts 'in sub-action'
|
347
|
+
forward 'action_2' # not starting with base command name
|
348
|
+
puts 'back in sub-action'
|
349
|
+
end
|
350
|
+
end
|
351
|
+
end
|
352
|
+
end
|
353
|
+
|
354
|
+
result = cli.execute_internal ['action_1'], output: :buffer
|
355
|
+
expect(result[:stdout]).to eq <<-EOS
|
356
|
+
in action_1
|
357
|
+
in sub-action
|
358
|
+
in action_2
|
359
|
+
back in sub-action
|
360
|
+
back in action_1
|
361
|
+
EOS
|
362
|
+
end
|
363
|
+
|
364
|
+
it 'executes help for action without handler' do
|
365
|
+
cli = Cliqr.interface do
|
366
|
+
name :my_command
|
367
|
+
description 'test command has no description'
|
368
|
+
shell :disable
|
369
|
+
|
370
|
+
action :action_1 do
|
371
|
+
description 'test action'
|
372
|
+
handler TestCommand
|
373
|
+
end
|
374
|
+
|
375
|
+
action 'action_2' do
|
376
|
+
shell :disable
|
377
|
+
|
378
|
+
action 'sub-action' do
|
379
|
+
handler TestCommand
|
380
|
+
end
|
381
|
+
end
|
382
|
+
end
|
383
|
+
|
384
|
+
result = cli.execute_internal %w(my_command), output: :buffer
|
385
|
+
expect(result[:stdout]).to eq <<-EOS
|
386
|
+
my_command -- test command has no description
|
387
|
+
|
388
|
+
USAGE:
|
389
|
+
my_command [actions] [options] [arguments]
|
390
|
+
|
391
|
+
Available options:
|
392
|
+
|
393
|
+
--help, -h : Get helpful information for action "my_command" along with its usage information.
|
394
|
+
|
395
|
+
Available actions:
|
396
|
+
[ Type "my_command help [action-name]" to get more information about that action ]
|
397
|
+
|
398
|
+
action_1 -- test action
|
399
|
+
|
400
|
+
action_2
|
401
|
+
|
402
|
+
help -- The help action for command "my_command" which provides details and usage information on how to use the command.
|
403
|
+
EOS
|
404
|
+
|
405
|
+
result = cli.execute_internal %w(my_command action_2), output: :buffer
|
406
|
+
expect(result[:stdout]).to eq <<-EOS
|
407
|
+
my_command action_2
|
408
|
+
|
409
|
+
USAGE:
|
410
|
+
my_command action_2 [actions] [options] [arguments]
|
411
|
+
|
412
|
+
Available options:
|
413
|
+
|
414
|
+
--help, -h : Get helpful information for action "my_command action_2" along with its usage information.
|
415
|
+
|
416
|
+
Available actions:
|
417
|
+
[ Type "my_command action_2 help [action-name]" to get more information about that action ]
|
418
|
+
|
419
|
+
sub-action
|
420
|
+
|
421
|
+
help -- The help action for command "my_command action_2" which provides details and usage information on how to use the command.
|
422
|
+
EOS
|
423
|
+
end
|
424
|
+
end
|
@@ -0,0 +1,233 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
require 'fixtures/test_command'
|
6
|
+
|
7
|
+
describe Cliqr::CLI::Executor do
|
8
|
+
it 'can execute help in command shell' do
|
9
|
+
cli = Cliqr.interface do
|
10
|
+
name 'my-command'
|
11
|
+
handler TestCommand
|
12
|
+
|
13
|
+
action :bla
|
14
|
+
end
|
15
|
+
|
16
|
+
with_input(['help']) do
|
17
|
+
result = cli.execute_internal %w(my-command shell), output: :buffer
|
18
|
+
expect(result[:stdout]).to eq <<-EOS
|
19
|
+
Starting shell for command "my-command"
|
20
|
+
my-command > help.
|
21
|
+
my-command
|
22
|
+
|
23
|
+
USAGE:
|
24
|
+
my-command [actions] [options] [arguments]
|
25
|
+
|
26
|
+
Available options:
|
27
|
+
|
28
|
+
--help, -h : Get helpful information for action "my-command" along with its usage information.
|
29
|
+
|
30
|
+
Available actions:
|
31
|
+
[ Type "my-command help [action-name]" to get more information about that action ]
|
32
|
+
|
33
|
+
bla
|
34
|
+
|
35
|
+
shell -- Execute a shell in the context of "my-command" command.
|
36
|
+
|
37
|
+
help -- The help action for command "my-command" which provides details and usage information on how to use the command.
|
38
|
+
my-command > exit.
|
39
|
+
shell exited with code 0
|
40
|
+
EOS
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
it 'can execute a sub action from shell' do
|
45
|
+
cli = Cliqr.interface do
|
46
|
+
name 'my-command'
|
47
|
+
handler do
|
48
|
+
puts 'base command executed'
|
49
|
+
end
|
50
|
+
|
51
|
+
action :foo do
|
52
|
+
handler do
|
53
|
+
puts 'foo executed'
|
54
|
+
end
|
55
|
+
|
56
|
+
action :bar do
|
57
|
+
handler do
|
58
|
+
puts 'bar executed'
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
with_input(['', 'my-command', 'foo', 'foo bar', 'foo bar help']) do
|
65
|
+
result = cli.execute_internal %w(my-command shell), output: :buffer
|
66
|
+
expect(result[:stdout]).to eq <<-EOS
|
67
|
+
Starting shell for command "my-command"
|
68
|
+
my-command > .
|
69
|
+
base command executed
|
70
|
+
my-command > my-command.
|
71
|
+
base command executed
|
72
|
+
my-command > foo.
|
73
|
+
foo executed
|
74
|
+
my-command > foo bar.
|
75
|
+
bar executed
|
76
|
+
my-command > foo bar help.
|
77
|
+
my-command foo bar
|
78
|
+
|
79
|
+
USAGE:
|
80
|
+
my-command foo bar [actions] [options] [arguments]
|
81
|
+
|
82
|
+
Available options:
|
83
|
+
|
84
|
+
--help, -h : Get helpful information for action "my-command foo bar" along with its usage information.
|
85
|
+
|
86
|
+
Available actions:
|
87
|
+
[ Type "my-command foo bar help [action-name]" to get more information about that action ]
|
88
|
+
|
89
|
+
help -- The help action for command "my-command foo bar" which provides details and usage information on how to use the command.
|
90
|
+
my-command > exit.
|
91
|
+
shell exited with code 0
|
92
|
+
EOS
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
it 'does not allow shell action if shell config is disabled' do
|
97
|
+
cli = Cliqr.interface do
|
98
|
+
name 'my-command'
|
99
|
+
shell :disable
|
100
|
+
arguments :disable
|
101
|
+
end
|
102
|
+
expect { cli.execute_internal %w(my-command shell) }.to(
|
103
|
+
raise_error(Cliqr::Error::IllegalArgumentError, 'invalid command argument "shell"'))
|
104
|
+
end
|
105
|
+
|
106
|
+
it 'can handle errors in shell' do
|
107
|
+
cli = Cliqr.interface do
|
108
|
+
name 'my-command'
|
109
|
+
handler TestCommand
|
110
|
+
arguments :disable
|
111
|
+
|
112
|
+
action :foo do
|
113
|
+
handler do
|
114
|
+
fail StandardError, 'I failed!'
|
115
|
+
end
|
116
|
+
|
117
|
+
action :bar do
|
118
|
+
handler TestCommand
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
with_input(['unknown', '--opt-1 val', 'foo']) do
|
124
|
+
result = cli.execute_internal %w(my-command shell), output: :buffer
|
125
|
+
expect(result[:stdout]).to eq <<-EOS
|
126
|
+
Starting shell for command "my-command"
|
127
|
+
my-command > unknown.
|
128
|
+
invalid command argument "unknown"
|
129
|
+
my-command > --opt-1 val.
|
130
|
+
unknown option "--opt-1"
|
131
|
+
my-command > foo.
|
132
|
+
command 'my-command foo' failed
|
133
|
+
|
134
|
+
Cause: StandardError - I failed!
|
135
|
+
my-command > exit.
|
136
|
+
shell exited with code 0
|
137
|
+
EOS
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
describe 'illegal shell operations' do
|
142
|
+
it 'does not allow shell action if there are no sub-actions' do
|
143
|
+
cli = Cliqr.interface do
|
144
|
+
name 'my-command'
|
145
|
+
help :disable
|
146
|
+
handler TestCommand
|
147
|
+
arguments :disable
|
148
|
+
end
|
149
|
+
expect { cli.execute_internal %w(my-command shell) }.to(
|
150
|
+
raise_error(Cliqr::Error::IllegalArgumentError, 'invalid command argument "shell"'))
|
151
|
+
end
|
152
|
+
|
153
|
+
it 'does not allow shell in shell for base command' do
|
154
|
+
cli = Cliqr.interface do
|
155
|
+
name 'my-command'
|
156
|
+
|
157
|
+
action :foo do
|
158
|
+
action :bar
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
162
|
+
with_input(['shell']) do
|
163
|
+
result = cli.execute_internal %w(my-command shell), output: :buffer
|
164
|
+
expect(result[:stdout]).to eq <<-EOS
|
165
|
+
Starting shell for command "my-command"
|
166
|
+
my-command > shell.
|
167
|
+
command 'my-command shell' failed
|
168
|
+
|
169
|
+
Cause: Cliqr::Error::IllegalCommandError - Cannot run another shell within an already running shell
|
170
|
+
my-command > exit.
|
171
|
+
shell exited with code 0
|
172
|
+
EOS
|
173
|
+
end
|
174
|
+
end
|
175
|
+
|
176
|
+
it 'does not allow shell in shell for sub action' do
|
177
|
+
cli = Cliqr.interface do
|
178
|
+
name 'my-command'
|
179
|
+
|
180
|
+
action :foo do
|
181
|
+
action :bar
|
182
|
+
end
|
183
|
+
end
|
184
|
+
|
185
|
+
with_input(['shell']) do
|
186
|
+
result = cli.execute_internal %w(my-command foo shell), output: :buffer
|
187
|
+
expect(result[:stdout]).to eq <<-EOS
|
188
|
+
Starting shell for command "my-command foo"
|
189
|
+
my-command foo > shell.
|
190
|
+
command 'my-command foo shell' failed
|
191
|
+
|
192
|
+
Cause: Cliqr::Error::IllegalCommandError - Cannot run another shell within an already running shell
|
193
|
+
my-command foo > exit.
|
194
|
+
shell exited with code 0
|
195
|
+
EOS
|
196
|
+
end
|
197
|
+
|
198
|
+
with_input(['foo shell']) do
|
199
|
+
result = cli.execute_internal %w(my-command shell), output: :buffer
|
200
|
+
expect(result[:stdout]).to eq <<-EOS
|
201
|
+
Starting shell for command "my-command"
|
202
|
+
my-command > foo shell.
|
203
|
+
command 'my-command foo shell' failed
|
204
|
+
|
205
|
+
Cause: Cliqr::Error::IllegalCommandError - Cannot run another shell within an already running shell
|
206
|
+
my-command > exit.
|
207
|
+
shell exited with code 0
|
208
|
+
EOS
|
209
|
+
end
|
210
|
+
end
|
211
|
+
end
|
212
|
+
end
|
213
|
+
|
214
|
+
def with_input(lines, &block)
|
215
|
+
old_stdin = $stdin
|
216
|
+
$stdin = TestIO.new(lines)
|
217
|
+
block.call
|
218
|
+
ensure
|
219
|
+
$stdin = old_stdin
|
220
|
+
end
|
221
|
+
|
222
|
+
# A test class for wrapping stdin
|
223
|
+
class TestIO
|
224
|
+
def initialize(lines)
|
225
|
+
@lines = lines.reverse
|
226
|
+
end
|
227
|
+
|
228
|
+
def gets
|
229
|
+
input = "#{@lines.length > 0 ? @lines.pop : 'exit'}"
|
230
|
+
puts "#{input}."
|
231
|
+
"#{input}\n"
|
232
|
+
end
|
233
|
+
end
|