cliqr 1.1.0 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (60) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +128 -1
  3. data/README.md +97 -71
  4. data/examples/README.md +12 -0
  5. data/examples/hbase +58 -0
  6. data/examples/my-command +63 -0
  7. data/examples/numbers +55 -0
  8. data/examples/vagrant +90 -0
  9. data/lib/cliqr.rb +17 -2
  10. data/lib/cliqr/argument_validation/argument_type_validator.rb +2 -2
  11. data/lib/cliqr/argument_validation/validator.rb +1 -1
  12. data/lib/cliqr/cli/argument_operator.rb +44 -0
  13. data/lib/cliqr/cli/argument_operator_context.rb +20 -0
  14. data/lib/cliqr/cli/command.rb +1 -1
  15. data/lib/cliqr/cli/command_context.rb +93 -12
  16. data/lib/cliqr/cli/command_runner_factory.rb +2 -2
  17. data/lib/cliqr/cli/config.rb +301 -33
  18. data/lib/cliqr/cli/executor.rb +14 -9
  19. data/lib/cliqr/cli/interface.rb +22 -7
  20. data/lib/cliqr/cli/router.rb +6 -2
  21. data/lib/cliqr/cli/shell_command.rb +69 -0
  22. data/lib/cliqr/cli/usage_builder.rb +185 -0
  23. data/lib/cliqr/config_validation/validator_factory.rb +59 -5
  24. data/lib/cliqr/error.rb +10 -4
  25. data/lib/cliqr/parser/action_token.rb +23 -0
  26. data/lib/cliqr/parser/argument_parser.rb +1 -1
  27. data/lib/cliqr/parser/argument_token.rb +1 -4
  28. data/lib/cliqr/parser/argument_tree_walker.rb +40 -8
  29. data/lib/cliqr/parser/option_token.rb +2 -1
  30. data/lib/cliqr/parser/parsed_input.rb +21 -2
  31. data/lib/cliqr/parser/parsed_input_builder.rb +11 -7
  32. data/lib/cliqr/parser/token.rb +3 -9
  33. data/lib/cliqr/parser/token_factory.rb +1 -1
  34. data/lib/cliqr/util.rb +135 -0
  35. data/lib/cliqr/version.rb +1 -1
  36. data/spec/argument_parser_spec_helper.rb +15 -0
  37. data/spec/config/action_config_validator_spec.rb +146 -0
  38. data/spec/config/config_finalize_spec.rb +1 -1
  39. data/spec/config/config_validator_spec.rb +29 -19
  40. data/spec/config/option_config_validator_spec.rb +13 -13
  41. data/spec/dsl/interface_spec.rb +1 -168
  42. data/spec/dsl/usage_spec.rb +705 -0
  43. data/spec/executor/action_executor_spec.rb +205 -0
  44. data/spec/executor/executor_spec.rb +405 -17
  45. data/spec/executor/help_executor_spec.rb +424 -0
  46. data/spec/executor/shell_executor_spec.rb +233 -0
  47. data/spec/fixtures/action_reader_command.rb +12 -0
  48. data/spec/fixtures/csv_argument_operator.rb +8 -0
  49. data/spec/fixtures/test_option_type_checker_command.rb +8 -0
  50. data/spec/parser/action_argument_parser_spec.rb +113 -0
  51. data/spec/parser/argument_parser_spec.rb +37 -44
  52. data/spec/spec_helper.rb +1 -0
  53. data/spec/validation/action_argument_validator_spec.rb +50 -0
  54. data/spec/validation/{argument_validation_spec.rb → command_argument_validation_spec.rb} +36 -18
  55. data/spec/validation/error_spec.rb +1 -1
  56. data/tasks/rdoc.rake +16 -0
  57. data/tasks/rubucop.rake +14 -0
  58. data/tasks/yard.rake +21 -0
  59. data/templates/usage.erb +39 -0
  60. metadata +48 -11
@@ -0,0 +1,705 @@
1
+ # encoding: utf-8
2
+
3
+ require 'spec_helper'
4
+
5
+ require 'fixtures/test_command'
6
+ require 'fixtures/action_reader_command'
7
+ require 'fixtures/csv_argument_operator'
8
+
9
+ describe Cliqr::CLI::UsageBuilder do
10
+ ################ BASE COMMAND ################
11
+
12
+ it 'builds a base command with name' do
13
+ cli = Cliqr.interface do
14
+ name 'my-command'
15
+ description 'a command used to test cliqr'
16
+ handler TestCommand
17
+ arguments :disable
18
+ help :disable
19
+ end
20
+
21
+ expect(cli.usage).to eq <<-EOS
22
+ my-command -- a command used to test cliqr
23
+
24
+ USAGE:
25
+ my-command
26
+ EOS
27
+ end
28
+
29
+ it 'only makes name and handler to be required' do
30
+ cli = Cliqr.interface do
31
+ name 'my-command'
32
+ handler TestCommand
33
+ arguments :disable
34
+ help :disable
35
+ end
36
+
37
+ expect(cli.usage).to eq <<-EOS
38
+ my-command
39
+
40
+ USAGE:
41
+ my-command
42
+ EOS
43
+ end
44
+
45
+ ################ OPTION ################
46
+
47
+ it 'allows options for a command' do
48
+ cli = Cliqr.interface do
49
+ name 'my-command'
50
+ description 'a command used to test cliqr'
51
+ handler TestCommand
52
+ arguments :disable
53
+ help :disable
54
+
55
+ option 'option-1' do
56
+ short 'p'
57
+ description 'a nice option to have'
58
+ end
59
+ end
60
+
61
+ expect(cli.usage).to eq <<-EOS
62
+ my-command -- a command used to test cliqr
63
+
64
+ USAGE:
65
+ my-command [options]
66
+
67
+ Available options:
68
+
69
+ --option-1, -p : a nice option to have
70
+ EOS
71
+ end
72
+
73
+ it 'allows command options to optionally have description, type and short name' do
74
+ cli = Cliqr.interface do
75
+ name 'my-command'
76
+ description 'a command used to test cliqr'
77
+ handler TestCommand
78
+ arguments :disable
79
+ help :disable
80
+
81
+ option 'option-1'
82
+ end
83
+
84
+ expect(cli.usage).to eq <<-EOS
85
+ my-command -- a command used to test cliqr
86
+
87
+ USAGE:
88
+ my-command [options]
89
+
90
+ Available options:
91
+
92
+ --option-1
93
+ EOS
94
+ end
95
+
96
+ it 'has options if added during build phase' do
97
+ cli = Cliqr.interface do
98
+ name 'my-command'
99
+ description 'a command used to test cliqr'
100
+ handler TestCommand
101
+
102
+ option 'option-1' do
103
+ short 'p'
104
+ description 'a nice option to have'
105
+ end
106
+ end
107
+ expect(cli.config.options?).to be_truthy
108
+ end
109
+
110
+ ################ OPTION TYPES ################
111
+
112
+ it 'allows command options to have a numeric value type' do
113
+ cli = Cliqr.interface do
114
+ name 'my-command'
115
+ description 'a command used to test cliqr'
116
+ handler TestCommand
117
+ arguments :disable
118
+ help :disable
119
+
120
+ option 'option-1' do
121
+ description 'a numeric option'
122
+ short 'p'
123
+ type :numeric
124
+ end
125
+ end
126
+
127
+ expect(cli.usage).to eq <<-EOS
128
+ my-command -- a command used to test cliqr
129
+
130
+ USAGE:
131
+ my-command [options]
132
+
133
+ Available options:
134
+
135
+ --option-1, -p : <numeric> a numeric option (default => 0)
136
+ EOS
137
+ end
138
+
139
+ it 'allows command options to have a boolean value type' do
140
+ cli = Cliqr.interface do
141
+ name 'my-command'
142
+ description 'a command used to test cliqr'
143
+ handler TestCommand
144
+ arguments :disable
145
+ help :disable
146
+
147
+ option 'option-1' do
148
+ description 'a boolean option'
149
+ short 'p'
150
+ type :boolean
151
+ end
152
+ end
153
+
154
+ expect(cli.usage).to eq <<-EOS
155
+ my-command -- a command used to test cliqr
156
+
157
+ USAGE:
158
+ my-command [options]
159
+
160
+ Available options:
161
+
162
+ --[no-]option-1, -p : <boolean> a boolean option (default => false)
163
+ EOS
164
+ end
165
+
166
+ it 'allows command options to have a boolean value type and no description' do
167
+ cli = Cliqr.interface do
168
+ name 'my-command'
169
+ description 'a command used to test cliqr'
170
+ handler TestCommand
171
+ arguments :disable
172
+ help :disable
173
+
174
+ option 'option-1' do
175
+ short 'p'
176
+ type :boolean
177
+ end
178
+ end
179
+
180
+ expect(cli.usage).to eq <<-EOS
181
+ my-command -- a command used to test cliqr
182
+
183
+ USAGE:
184
+ my-command [options]
185
+
186
+ Available options:
187
+
188
+ --[no-]option-1, -p : <boolean> (default => false)
189
+ EOS
190
+ end
191
+
192
+ ################ ARGUMENTS ################
193
+
194
+ it 'allows interface to enable arbitrary argument list parsing without options' do
195
+ cli = Cliqr.interface do
196
+ name 'my-command'
197
+ handler TestCommand
198
+ arguments :enable
199
+ help :disable
200
+ end
201
+
202
+ expect(cli.usage).to eq <<-EOS
203
+ my-command
204
+
205
+ USAGE:
206
+ my-command [arguments]
207
+ EOS
208
+ end
209
+
210
+ it 'allows interface to enable arbitrary argument list parsing' do
211
+ cli = Cliqr.interface do
212
+ name 'my-command'
213
+ handler TestCommand
214
+ arguments :enable
215
+ help :disable
216
+
217
+ option 'option-1'
218
+ end
219
+
220
+ expect(cli.usage).to eq <<-EOS
221
+ my-command
222
+
223
+ USAGE:
224
+ my-command [options] [arguments]
225
+
226
+ Available options:
227
+
228
+ --option-1
229
+ EOS
230
+ end
231
+
232
+ ################ ACTIONS ################
233
+
234
+ it 'allows command to have an action' do
235
+ cli = Cliqr.interface do
236
+ name 'my-command'
237
+ handler TestCommand
238
+ help :disable
239
+ shell :disable
240
+
241
+ action 'my-action' do
242
+ handler TestCommand
243
+ arguments :disable
244
+ end
245
+ end
246
+
247
+ expect(cli.usage).to eq <<-EOS
248
+ my-command
249
+
250
+ USAGE:
251
+ my-command [actions] [arguments]
252
+
253
+ Available actions:
254
+
255
+ my-action
256
+ EOS
257
+ end
258
+
259
+ it 'allows command to have an action with description' do
260
+ cli = Cliqr.interface do
261
+ name 'my-command'
262
+ handler TestCommand
263
+ help :disable
264
+ shell :disable
265
+
266
+ action 'my-action' do
267
+ handler TestCommand
268
+ description 'this is a test action'
269
+ arguments :disable
270
+ end
271
+ end
272
+
273
+ expect(cli.usage).to eq <<-EOS
274
+ my-command
275
+
276
+ USAGE:
277
+ my-command [actions] [arguments]
278
+
279
+ Available actions:
280
+
281
+ my-action -- this is a test action
282
+ EOS
283
+ end
284
+
285
+ it 'allows command to have an action and an option' do
286
+ cli = Cliqr.interface do
287
+ name 'my-command'
288
+ handler TestCommand
289
+ help :disable
290
+ shell :disable
291
+
292
+ action 'my-action' do
293
+ handler TestCommand
294
+ description 'this is a test action'
295
+ arguments :disable
296
+ end
297
+
298
+ option 'option-1'
299
+ end
300
+
301
+ expect(cli.usage).to eq <<-EOS
302
+ my-command
303
+
304
+ USAGE:
305
+ my-command [actions] [options] [arguments]
306
+
307
+ Available options:
308
+
309
+ --option-1
310
+
311
+ Available actions:
312
+
313
+ my-action -- this is a test action
314
+ EOS
315
+ end
316
+
317
+ it 'allows command to have an action with options' do
318
+ cli = Cliqr.interface do
319
+ name 'my-command'
320
+ handler TestCommand
321
+ help :disable
322
+ shell :disable
323
+
324
+ action 'my-action' do
325
+ handler TestCommand
326
+ description 'this is a test action'
327
+
328
+ option 'action-option'
329
+ end
330
+
331
+ option 'option-1'
332
+ end
333
+
334
+ expect(cli.usage).to eq <<-EOS
335
+ my-command
336
+
337
+ USAGE:
338
+ my-command [actions] [options] [arguments]
339
+
340
+ Available options:
341
+
342
+ --option-1
343
+
344
+ Available actions:
345
+
346
+ my-action -- this is a test action
347
+ EOS
348
+ end
349
+
350
+ it 'allows command to have multiple actions and multiple options' do
351
+ cli = Cliqr.interface do
352
+ name 'my-command'
353
+ handler TestCommand
354
+ help :disable
355
+ shell :disable
356
+
357
+ option 'option-1'
358
+
359
+ action 'my-action' do
360
+ handler TestCommand
361
+ description 'this is a test action'
362
+
363
+ option 'action-option'
364
+ end
365
+
366
+ option 'option-2'
367
+
368
+ action 'another-action' do
369
+ handler TestCommand
370
+ description 'this is another test action'
371
+ arguments :disable
372
+ end
373
+
374
+ option 'option-3'
375
+ end
376
+
377
+ expect(cli.usage).to eq <<-EOS
378
+ my-command
379
+
380
+ USAGE:
381
+ my-command [actions] [options] [arguments]
382
+
383
+ Available options:
384
+
385
+ --option-1
386
+ --option-2
387
+ --option-3
388
+
389
+ Available actions:
390
+
391
+ my-action -- this is a test action
392
+
393
+ another-action -- this is another test action
394
+ EOS
395
+ end
396
+
397
+ it 'allows nested actions with a mix of same options and same names' do
398
+ def define_interface
399
+ Cliqr.interface do
400
+ name 'my-command'
401
+ handler TestCommand
402
+ help :disable
403
+ shell :disable
404
+
405
+ option 'test-option-1'
406
+ option 'test-option-2'
407
+
408
+ action 'my-action-1' do
409
+ handler ActionReaderCommand
410
+
411
+ action 'my-action-1' do
412
+ handler ActionReaderCommand
413
+
414
+ option 'test-option-1'
415
+ option 'test-option-2'
416
+
417
+ action 'my-action-1' do
418
+ handler ActionReaderCommand
419
+
420
+ option 'test-option-1'
421
+ option 'test-option-2'
422
+ end
423
+ end
424
+ end
425
+
426
+ action 'another-action' do
427
+ handler ActionReaderCommand
428
+ arguments :disable
429
+ end
430
+ end
431
+ end
432
+ expect(define_interface.usage).to eq <<-EOS
433
+ my-command
434
+
435
+ USAGE:
436
+ my-command [actions] [options] [arguments]
437
+
438
+ Available options:
439
+
440
+ --test-option-1
441
+ --test-option-2
442
+
443
+ Available actions:
444
+
445
+ my-action-1
446
+
447
+ another-action
448
+ EOS
449
+ end
450
+
451
+ ################ DEFAULT OPTION VALUES ################
452
+
453
+ it 'allows options to have default value' do
454
+ cli = Cliqr.interface do
455
+ name 'my-command'
456
+ handler TestCommand
457
+ help :disable
458
+
459
+ option 'test-option' do
460
+ default :a_symbol
461
+ end
462
+
463
+ option :another do
464
+ short 'a'
465
+ description 'another option'
466
+ type :numeric
467
+ default %w(test array default)
468
+
469
+ operator CSVArgumentOperator
470
+ end
471
+
472
+ option 'nil-option' do
473
+ default nil
474
+ end
475
+
476
+ option 'string-option' do
477
+ default 'string'
478
+ end
479
+
480
+ option 'hash-option' do
481
+ default(:key => 'val')
482
+ end
483
+ end
484
+
485
+ expect(cli.usage).to eq <<-EOS
486
+ my-command
487
+
488
+ USAGE:
489
+ my-command [options] [arguments]
490
+
491
+ Available options:
492
+
493
+ --test-option : (default => :a_symbol)
494
+ --another, -a : <numeric> another option (default => [\"test\", \"array\", \"default\"])
495
+ --nil-option
496
+ --string-option : (default => "string")
497
+ --hash-option : (default => {:key=>"val"})
498
+ EOS
499
+ end
500
+
501
+ it 'boolean option is false by default' do
502
+ cli = Cliqr.interface do
503
+ name 'my-command'
504
+ handler TestCommand
505
+ help :disable
506
+
507
+ option :another do
508
+ short 'a'
509
+ description 'another option'
510
+ type :boolean
511
+
512
+ operator CSVArgumentOperator
513
+ end
514
+ end
515
+
516
+ expect(cli.usage).to eq <<-EOS
517
+ my-command
518
+
519
+ USAGE:
520
+ my-command [options] [arguments]
521
+
522
+ Available options:
523
+
524
+ --[no-]another, -a : <boolean> another option (default => false)
525
+ EOS
526
+ end
527
+
528
+ it 'numeric option is 0 by default' do
529
+ cli = Cliqr.interface do
530
+ name 'my-command'
531
+ handler TestCommand
532
+ help :disable
533
+
534
+ option :another do
535
+ short 'a'
536
+ description 'another option'
537
+ type :numeric
538
+
539
+ operator CSVArgumentOperator
540
+ end
541
+ end
542
+
543
+ expect(cli.usage).to eq <<-EOS
544
+ my-command
545
+
546
+ USAGE:
547
+ my-command [options] [arguments]
548
+
549
+ Available options:
550
+
551
+ --another, -a : <numeric> another option (default => 0)
552
+ EOS
553
+ end
554
+
555
+ it 'boolean option can be made default true' do
556
+ cli = Cliqr.interface do
557
+ name 'my-command'
558
+ handler TestCommand
559
+ help :disable
560
+
561
+ option :another do
562
+ short 'a'
563
+ description 'another option'
564
+ type :boolean
565
+ default true
566
+
567
+ operator CSVArgumentOperator
568
+ end
569
+ end
570
+
571
+ expect(cli.usage).to eq <<-EOS
572
+ my-command
573
+
574
+ USAGE:
575
+ my-command [options] [arguments]
576
+
577
+ Available options:
578
+
579
+ --[no-]another, -a : <boolean> another option (default => true)
580
+ EOS
581
+ end
582
+
583
+ ################ SHELL ACTION ################
584
+
585
+ it 'adds shell action to the base command only when there are sub actions' do
586
+ cli = Cliqr.interface do
587
+ name 'my-command'
588
+ handler TestCommand
589
+ help :disable
590
+
591
+ action :bla
592
+ end
593
+
594
+ expect(cli.usage).to eq <<-EOS
595
+ my-command
596
+
597
+ USAGE:
598
+ my-command [actions] [arguments]
599
+
600
+ Available actions:
601
+
602
+ bla
603
+
604
+ shell -- Execute a shell in the context of "my-command" command.
605
+ EOS
606
+ end
607
+
608
+ it 'does not add shell action to the base command if it does not have actions' do
609
+ cli = Cliqr.interface do
610
+ name 'my-command'
611
+ handler TestCommand
612
+ help :disable
613
+ end
614
+
615
+ expect(cli.usage).to eq <<-EOS
616
+ my-command
617
+
618
+ USAGE:
619
+ my-command [arguments]
620
+ EOS
621
+ end
622
+
623
+ it 'can add shell action to a sub-action which does not have actions' do
624
+ cli = Cliqr.interface do
625
+ name 'my-command'
626
+
627
+ action :bla do
628
+ shell :enable
629
+ end
630
+ end
631
+ result = cli.execute_internal %w(my-command bla), output: :buffer
632
+ expect(result[:stdout]).to eq <<-EOS
633
+ my-command bla
634
+
635
+ USAGE:
636
+ my-command bla [actions] [options] [arguments]
637
+
638
+ Available options:
639
+
640
+ --help, -h : Get helpful information for action "my-command bla" along with its usage information.
641
+
642
+ Available actions:
643
+ [ Type "my-command bla help [action-name]" to get more information about that action ]
644
+
645
+ shell -- Execute a shell in the context of "my-command bla" command.
646
+
647
+ help -- The help action for command "my-command bla" which provides details and usage information on how to use the command.
648
+ EOS
649
+ end
650
+
651
+ it 'can add version to base command' do
652
+ cli = Cliqr.interface do
653
+ name 'my-command'
654
+ version '1234'
655
+ end
656
+ result = cli.execute_internal %w(help), output: :buffer
657
+ expect(result[:stdout]).to eq <<-EOS
658
+ my-command
659
+
660
+ USAGE:
661
+ my-command [actions] [options] [arguments]
662
+
663
+ Available options:
664
+
665
+ --version, -v : Get version information for command "my-command".
666
+ --help, -h : Get helpful information for action "my-command" along with its usage information.
667
+
668
+ Available actions:
669
+ [ Type "my-command help [action-name]" to get more information about that action ]
670
+
671
+ version -- Get version information for command "my-command".
672
+
673
+ help -- The help action for command "my-command" which provides details and usage information on how to use the command.
674
+ EOS
675
+ end
676
+
677
+ it 'can add version to any action' do
678
+ cli = Cliqr.interface do
679
+ name 'my-command'
680
+
681
+ action :bla do
682
+ version '1234'
683
+ end
684
+ end
685
+ result = cli.execute_internal %w(bla help), output: :buffer
686
+ expect(result[:stdout]).to eq <<-EOS
687
+ my-command bla
688
+
689
+ USAGE:
690
+ my-command bla [actions] [options] [arguments]
691
+
692
+ Available options:
693
+
694
+ --version, -v : Get version information for command "my-command bla".
695
+ --help, -h : Get helpful information for action "my-command bla" along with its usage information.
696
+
697
+ Available actions:
698
+ [ Type "my-command bla help [action-name]" to get more information about that action ]
699
+
700
+ version -- Get version information for command "my-command bla".
701
+
702
+ help -- The help action for command "my-command bla" which provides details and usage information on how to use the command.
703
+ EOS
704
+ end
705
+ end