escort 0.2.1 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (69) hide show
  1. checksums.yaml +8 -8
  2. data/.irbrc +2 -0
  3. data/.travis.yml +1 -1
  4. data/README.md +272 -3
  5. data/TODO.md +118 -71
  6. data/examples/.my_apprc +24 -0
  7. data/examples/basic_config_file +16 -0
  8. data/examples/basic_conflicts +1 -1
  9. data/examples/basic_with_everything +30 -0
  10. data/examples/suite_complex +65 -0
  11. data/examples/{command → suite_simple} +0 -0
  12. data/examples/suite_with_sub_commands +94 -0
  13. data/lib/escort.rb +6 -4
  14. data/lib/escort/action_command/base.rb +7 -5
  15. data/lib/escort/app.rb +2 -8
  16. data/lib/escort/auto_options.rb +5 -3
  17. data/lib/escort/formatter/cursor_position.rb +29 -0
  18. data/lib/escort/formatter/default_help_formatter.rb +37 -32
  19. data/lib/escort/formatter/option.rb +1 -1
  20. data/lib/escort/formatter/stream_output_formatter.rb +88 -0
  21. data/lib/escort/formatter/{borderless_table.rb → string_grid.rb} +21 -19
  22. data/lib/escort/formatter/string_splitter.rb +24 -4
  23. data/lib/escort/setup/configuration/loader.rb +8 -2
  24. data/lib/escort/setup/configuration/locator/chaining.rb +29 -0
  25. data/lib/escort/setup/configuration/locator/executing_script_directory.rb +15 -0
  26. data/lib/escort/setup/configuration/locator/specified_directory.rb +21 -0
  27. data/lib/escort/setup/configuration/reader.rb +4 -2
  28. data/lib/escort/setup/configuration/writer.rb +6 -2
  29. data/lib/escort/setup/dsl/command.rb +7 -8
  30. data/lib/escort/setup/dsl/global.rb +3 -51
  31. data/lib/escort/version.rb +1 -1
  32. data/spec/integration/basic_config_file_spec.rb +82 -0
  33. data/spec/integration/suite_simple_spec.rb +45 -0
  34. data/spec/integration/suite_sub_command_spec.rb +51 -0
  35. data/spec/lib/escort/action_command/base_spec.rb +200 -0
  36. data/spec/lib/escort/formatter/option_spec.rb +2 -2
  37. data/spec/lib/escort/formatter/stream_output_formatter_spec.rb +214 -0
  38. data/spec/lib/escort/formatter/string_grid_spec.rb +59 -0
  39. data/spec/lib/escort/setup/configuration/generator_spec.rb +101 -0
  40. data/spec/lib/escort/setup/configuration/loader_spec.rb +79 -0
  41. data/spec/lib/escort/setup/configuration/locator/chaining_spec.rb +81 -0
  42. data/spec/lib/escort/setup/configuration/locator/descending_to_home_spec.rb +57 -0
  43. data/spec/lib/escort/setup/configuration/locator/executing_script_directory_spec.rb +29 -0
  44. data/spec/lib/escort/setup/configuration/locator/specified_directory_spec.rb +33 -0
  45. data/spec/lib/escort/setup/configuration/merge_tool_spec.rb +41 -0
  46. data/spec/lib/escort/setup/configuration/reader_spec.rb +41 -0
  47. data/spec/lib/escort/setup/configuration/writer_spec.rb +75 -0
  48. data/spec/spec_helper.rb +2 -1
  49. metadata +44 -24
  50. data/examples/attic/1_1_basic.rb +0 -15
  51. data/examples/attic/1_2_basic_requires_arguments.rb +0 -15
  52. data/examples/attic/2_2_command.rb +0 -18
  53. data/examples/attic/2_2_command_requires_arguments.rb +0 -20
  54. data/examples/attic/2_3_nested_commands.rb +0 -26
  55. data/examples/attic/3_validations.rb +0 -31
  56. data/examples/attic/4_1_config_file.rb +0 -42
  57. data/examples/attic/argument_handling/basic.rb +0 -12
  58. data/examples/attic/argument_handling/basic_command.rb +0 -18
  59. data/examples/attic/argument_handling/no_arguments.rb +0 -14
  60. data/examples/attic/argument_handling/no_arguments_command.rb +0 -20
  61. data/examples/attic/command_aliases/app.rb +0 -31
  62. data/examples/attic/config_file/.apprc2 +0 -16
  63. data/examples/attic/config_file/app.rb +0 -78
  64. data/examples/attic/config_file/sub_commands.rb +0 -35
  65. data/examples/attic/default_command/app.rb +0 -20
  66. data/examples/attic/sub_commands/app.rb +0 -18
  67. data/examples/attic/validation_basic/app.rb +0 -31
  68. data/lib/escort/formatter/terminal_formatter.rb +0 -58
  69. data/lib/escort/setup/dsl/validations.rb +0 -25
checksums.yaml CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- N2Q0MmJiODEzODNjNWI0NmM3Mzc0ZGFmMGQyYTU5NzFkZWU3NmZjYw==
4
+ MzQ3YWNjMzdhYWVmMjJiNThhYmFkNDlmYTdhZjRiOTk1MTE5MjU0OA==
5
5
  data.tar.gz: !binary |-
6
- YjM4NmE2YmVjOTdkOTg4MDY1MWFmZGRmZGM5NzdiYWIwN2M3NmE2ZQ==
6
+ MDA2MDVmNGQ5M2I2ODRlNGUzODU5YzgzYjI1ZTY3NjU2YzRjMmNiMg==
7
7
  !binary "U0hBNTEy":
8
8
  metadata.gz: !binary |-
9
- ZTYxZWFiZmRmNzhlZjFhMjMyNTcxNzU3MGEzM2U4ZWYxOWZiOGJkOGMxNTli
10
- N2Q0Yjk0ZGVlMmE5OThhOWQwMDU0YmQ2YjlmMjZlMjhlMWNmYjhlMDQ4NGJh
11
- ZTVlYWJiMDZiMzJjYWMzMGNiNWQ0ZTZlYjFhYjg3Yjc4OTQ5M2U=
9
+ ZjBiNWM4N2MyMDQ3NDI2ZmQyZjI4NjBmZjg3YmZhZTRjNGU5ZDFlNjljYzYw
10
+ Y2Q0MThjMDQyYTg5YjAzZWE3ZDQ2NGFhZWIwZDE0MjU2MTZiZTk5MDdmZGVl
11
+ MWVmMTUzMTYzODc5NzcxYmEyZmE5MGI4NmNlNjI3MThkMWEyMDI=
12
12
  data.tar.gz: !binary |-
13
- MDJlNGMwMWM1NTBkYzI3ZTI4MWM0NThhMTEzMDkyNThkZTFmNDEyMTgxYjA0
14
- NDFkNzA3MjQ4MDU2NmM1ZmQ0ZjQxNDU3MTJhNjFhZmI2NjAwOGVmYjAzZTBm
15
- ODYzNjVkMDM2NTM2NGJiY2I2NTlhYjRkMTAzMDA3OGM0ZDdhZTc=
13
+ ODkwMzNlN2Q0NTMwOGY2ZGQzYTA3YjA3ZTNiMjdkYTgzMjBmYmI1ZTVjNDQy
14
+ ZTM0ZGU2ZGZjNmVhYjhiMjdmZTVjY2NiNGY2ZGRmNmUzMTcyNmViMzNmYjQ4
15
+ NzQzN2MxMjlhOGFiN2UxZGE2ODc2MWZmY2IxODAzNjFkM2ViMmQ=
data/.irbrc CHANGED
@@ -1 +1,3 @@
1
+ $:.unshift File.expand_path(File.join(File.dirname(__FILE__), 'lib'))
2
+
1
3
  require './lib/escort'
@@ -4,5 +4,5 @@ rvm:
4
4
  - "1.9.3"
5
5
  - "2.0.0"
6
6
  - jruby-19mode # JRuby in 1.9 mode
7
- - rbx-19mode
7
+ #- rbx-19mode
8
8
  script: bundle exec rspec spec
data/README.md CHANGED
@@ -213,6 +213,22 @@ This will execute fine, but if we do:
213
213
 
214
214
  The app will prompt the user to enter an argument. Pressing `Enter` will allow to enter more arguments. Like with many command-line apps you will need to press `Ctrl-D` to jump out of the prompt and allow the app to execute.
215
215
 
216
+ There is one extra thing to note. If you're writing a command suite (see below for explanation). The `requires_arguments` setting will be inherited by all the sub-commands. You can however easily override the setting for any sub-command and this overridden value will be inherited by all the sub-commands of that command.
217
+
218
+ ```ruby
219
+ ...
220
+ app.command :start do |command|
221
+ command.requires_arguments false
222
+
223
+ command.action do |options, arguments|
224
+ MyApp::ExampleCommand.new(options, arguments).execute
225
+ end
226
+ end
227
+ ...
228
+ ```
229
+
230
+ This way different commands in your app can pick and choose whether or not they want to require arguments or make them optional.
231
+
216
232
 
217
233
  ### Better Help Text
218
234
 
@@ -409,12 +425,265 @@ As you can see you may define multiple validation rules for the same option with
409
425
 
410
426
 
411
427
  ### Configuration File
412
- TODO
413
428
 
414
- ### Commands
429
+ Sometime you have a whole bunch of command line options you need to pass in to your app, but the value of these options hardly ever changes. It's a bit of a drag to have supply these on the command-line every time. This is why we have config file support. You may indicate that your app has a config file like so:
430
+
431
+ ```ruby
432
+ #!/usr/bin/env ruby
433
+
434
+ require 'escort'
435
+ require 'my_app'
436
+
437
+ Escort::App.create do |app|
438
+ app.config_file ".my_apprc", :autocreate => true
439
+
440
+ app.options do |opts|
441
+ opts.opt :option1, "Option1", :short => '-o', :long => '--option1', :type => :string, :default => "option 1"
442
+ end
443
+
444
+ app.action do |options, arguments|
445
+ MyApp::ExampleCommand.new(options, arguments).execute
446
+ end
447
+ end
448
+ ```
449
+
450
+ Essentially we give the config file a name and optionally set the config file to be autocreatable. When the config file is autocreatable, the first time you run the command-line app, a config file with the name your specified will be created in the default location (which is your home directory). The config file format is JSON, and it is structured in a specific way to support infinitely nesting sub commands. The config file for an app like the one above, might look like this:
451
+
452
+ ```
453
+ {
454
+ "global": {
455
+ "options": {
456
+ "option1": "option 1",
457
+ "config": null,
458
+ "verbosity": "WARN",
459
+ "error_output_format": "basic"
460
+ },
461
+ "commands": {
462
+ "escort": {
463
+ "options": {
464
+ "create_config": null,
465
+ "create_default_config": null,
466
+ "update_config": null,
467
+ "update_default_config": null
468
+ },
469
+ "commands": {
470
+ }
471
+ }
472
+ }
473
+ },
474
+ "user": {
475
+ }
476
+ }
477
+ ```
478
+
479
+ All the options you can supply to your app will be present in the config file as well as all the commands and all their options etc (you also get a bunch of options and a single command that get automatically added by escort for your convenience, these will be explained below). You can go and modify the values for all your options in the config file. The config file values, take precedence over the default values that you specified for the options (if any), but if you supply an option value on the command-line, this will still take precedence over the option value you define in the config file. This way you can provide sensible defaults and still override when necessary.
480
+
481
+ Whenever you define an app to have a config file, escort will add some utility options and commands for you to make working with config files easier. Firstly, you will get a global `config` option. This can be used to make your app take a specific config file instead of the default one, this config file will only be valid for the single execution of your command-line app e.g.:
482
+
483
+ ```
484
+ ./app.rb --config='/var/opt/.blahrc' -o yadda
485
+ ```
486
+
487
+ You also get a utility command for working with config files - the `escort` command. This command has 4 options:
488
+
489
+ * `--create-config` - this can be used to create a config file in a specified location
490
+ * `--create-default-config` - this can be used to create a config file in the default location (home directory) if one doesn't already exit
491
+ * `--update-config` - this can be used to update a specific config file (mainly useful during development), if you've added new options/commands using this option will allow your config file to reflect this (it will not blow away any of the values you have set for your options)
492
+ * `--update-default-config` - same as above but will just work with the default config file if it is present (if not, it will create a default config file)
493
+
494
+ These utility options can be very useful as the nested format of the config file can become confusing if you have to update it by hand with new options and commands while you're developing your apps.
495
+
496
+ It is also worth knowing that Escort is quite clever when it comes to working out which config file to use for a particular run of the command-line app. It will not just use the config file in your home directory, but will instead attempt to find a config file closer in the directory hierarchy to the location of the command-line script. The strategy is as follows:
497
+
498
+ * look for a config file in the directory where the command-line script itself lives, if found use that one
499
+ * otherwise look for a config file in the current working directory and use that one
500
+ * if still not found, go down one level of the directory tree from the current working directory and look for a config file there
501
+ * keep going down the directory tree until the home directory is reached, if no config file was found, then no config file exists
502
+ * in which case either create the config file in home directory (if autocreatable) or continue without config file
503
+
504
+ As you can see the config file support is quite extensive and can take your command-line apps to the next level in terms of useability and utility.
505
+
506
+
507
+ ### Command Suites
508
+
509
+ You're not just limited to options for your command-line apps. Escort allows you to turn your command-line apps into command-line suites, with command support. Let's say you want a command-line app to control a process of some sort. Your process is `app.rb`. What you want to be able to do is the following:
510
+
511
+ ```
512
+ ./app.rb start
513
+ ./app.rb stop
514
+ ./app.rb restart
515
+ ```
516
+
517
+ You also want to be able to provide options both to the main process itself as well as to the various commands, e.g.:
518
+
519
+ ```
520
+ ./app.rb -e production start --reload
521
+ ```
522
+
523
+ Escort makes this easy:
524
+
525
+ ```ruby
526
+ #!/usr/bin/env ruby
527
+
528
+ require 'escort'
529
+ require 'my_app'
530
+
531
+ Escort::App.create do |app|
532
+ app.config_file ".my_apprc", :autocreate => true
533
+
534
+ app.options do |opts|
535
+ opts.opt :environment, "Environment", :short => '-e', :long => '--environment', :type => :string, :default => "development"
536
+ end
537
+
538
+ app.command :start do |command|
539
+ command.summary "Start process"
540
+ command.description "Start process"
541
+
542
+ command.options do |opts|
543
+ opts.opt :reload, "Reload", :short => '-r', :long => '--reload', :type => :flag
544
+ end
545
+
546
+ command.action do |options, arguments|
547
+ MyApp::ExampleCommand.new(options, arguments).execute
548
+ end
549
+ end
550
+
551
+ app.command :stop do |command|
552
+ command.summary "Stop process"
553
+ command.description "Stop process"
554
+
555
+ command.action do |options, arguments|
556
+ MyApp::ExampleCommand.new(options, arguments).execute
557
+ end
558
+ end
559
+
560
+ app.command :restart do |command|
561
+ command.summary "Restart process"
562
+ command.description "Restart process"
563
+
564
+ command.action do |options, arguments|
565
+ MyApp::ExampleCommand.new(options, arguments).execute
566
+ end
567
+ end
568
+ end
569
+ ```
570
+
571
+ Of course you would probably use a different `ActionCommand` class to implement each of your defined commands (more on `ActionCommands` below).
572
+
573
+
574
+ ### Command Suites Sub-Commands
575
+
576
+ Of course if one level of commands is good it is only logical that multiple levels of commands is even better. Luckily Escort supports infinitely nesting sub-commands so you can create command-line suites which are truly extensive. Let's say you're writing a command-line utility for your framework, you've named your framework 'Rails' (cause surely that's not taken :P) and your utility is `rails`. You want your utility to be used for generating migrations as well as controllers, something like:
577
+
578
+ ```
579
+ rails generate migration
580
+ rails g controller
581
+ ```
582
+
583
+ Of course you want to be able to supply a set of options to each of the sub-commands when necessary:
584
+
585
+ ```
586
+ rails -e development generate migration --sequel
587
+ ```
588
+
589
+ As we've come to expect, this is very easy:
590
+
591
+ ```ruby
592
+ #!/usr/bin/env ruby
593
+
594
+ require 'escort'
595
+ require 'my_app'
596
+
597
+ Escort::App.create do |app|
598
+ app.config_file ".my_apprc", :autocreate => false
599
+
600
+ app.options do |opts|
601
+ opts.opt :environment, "Environment", :short => '-e', :long => '--environment', :type => :string, :default => "development"
602
+ end
603
+
604
+ app.command :generate, :aliases => [:g] do |command|
605
+ command.command :migration do |command|
606
+ app.options do |opts|
607
+ opts.opt :sequel, "Sequel", :short => '-s', :long => '--sequel', :type => :flag
608
+ end
609
+
610
+ command.action do |options, arguments|
611
+ MyApp::ExampleCommand.new(options, arguments).execute
612
+ end
613
+ end
614
+
615
+ command.command :controller do |command|
616
+ command.action do |options, arguments|
617
+ MyApp::ExampleCommand.new(options, arguments).execute
618
+ end
619
+ end
620
+ end
621
+ end
622
+ ```
623
+
624
+ Of course, you can flesh it out by providing a summary and description for the commands, specifying if arguments are required, conflicts, dependencies etc (this will be reflected in the help text). Just about everything you can do at the global level for apps without sub-commands, you can do at the command level (the only things you currently can't specify at the command level are 'version' and 'config_file', these are global only).
625
+
626
+
627
+ ### Implementing the Actions
628
+
629
+ So far we've seen a lot of examples of how to add various command-line UI features, but what about implementing the actual functionality.
630
+
631
+ If your functionality is a one liner, you can, of course, just dump it into the action block, but we're trying to keep a clean separation between our UI logic and the actual functionality we are trying to implement. We do this by writing `ActionCommand` classes.
632
+
633
+ In all the previous examples you've seen the following:
634
+
635
+ ```ruby
636
+ ...
637
+
638
+ app.action do |options, arguments|
639
+ MyApp::ExampleCommand.new(options, arguments).execute
640
+ end
641
+
642
+ ...
643
+ ```
644
+
645
+ The `ExampleCommand` is an `ActionCommand` and is implemented in a separate class. In the above examples we would `require 'my_app'` with the assumption that it requires the file where `ExampleCommand` is imlpemented. You could of course just require the file with the implementation directly.
646
+
647
+ A command might look like this:
648
+
649
+ ```ruby
650
+ module Escort
651
+ class ExampleCommand < ::Escort::ActionCommand::Base
652
+ def execute
653
+ Escort::Logger.output.puts "Command: #{command_name}"
654
+ Escort::Logger.output.puts "Options: #{options}"
655
+ Escort::Logger.output.puts "Command options: #{command_options}"
656
+ Escort::Logger.output.puts "Arguments: #{arguments}"
657
+ if config
658
+ Escort::Logger.output.puts "User config: #{config}"
659
+ end
660
+ end
661
+ end
662
+ end
663
+ ```
664
+
665
+ As you can see all you need to do is inherit from `::Escort::ActionCommand::Base` and implement the execute method. Inheriting from `Base` gives you access to a bunch of useful methods:
666
+
667
+ * `command_name` - the name of the command that is being executed (or :global if it is the main action)
668
+ * `command_options` - the options for this command
669
+ * `parent_options` - the options for the parent command (if any)
670
+ * `global_options` - the global app options
671
+ * `config` - a hash of the user defined portion of the configuration file
672
+ * `options` - the raw options hash
673
+ * `arguments` - a list of arguments passed to the app
674
+
675
+ These should give you hand in implementing the functionality you need, but most importantly it allows us to keep our actual command-line UI definition clean and separate the useful logic into what is/are essentially pure ruby classes.
676
+
677
+ ## Examples
678
+
679
+ There is an examples directory where you can have a play with a whole bunch of little 'Escort' apps, from a very basic one with no options to more complex nested command suites with all the trimmings. Most of them call the `ExampleCommand` which lives in `examples/commands`. Have a read/play to learn, or just copy/paste bits straight into your apps.
680
+
681
+ ## More In-Depth
682
+
415
683
  TODO
416
684
 
417
- ### Sub-Commands
685
+ ## Command-Line Tools Built With Escort
686
+
418
687
  TODO
419
688
 
420
689
  ## Alternatives
data/TODO.md CHANGED
@@ -1,110 +1,85 @@
1
1
  ROADMAP
2
2
 
3
- v0.2.0
4
- - up the version to 0.2.0
3
+ v0.3.0
5
4
  - tag and release
6
5
 
7
6
 
8
- - test conflicts for non-exstant options (integration) DONE
9
- - test all the new help stuff on option, for conflicts, dependencies, validations DONE
10
- - fix up readme for conflicts block DONE
11
- - rework validations to be part of the options block rather than in their own block DONE
12
- - fix example, fix tests, fix readme DONE
13
- - need to rework conflicts as currently not really very good DONE
14
- - add dependencies to help text DONE
15
- - add conflicts to help text DONE
16
- - add validation texts to help text so that people can see what kind of values are valid DONE
17
- - make sure we check conflicts for non-existant options DONE
18
- - refactor the formatting code some more DONE
19
- - pull some formatting code into separate classes DONE
20
- - test some of the utility formatting code DONE
21
- - fix up help text so that if arguments are mandatory they are shown as mandatory not optional DONE
22
- - basic example with validations DONE
23
- - integration test for validations DONE
24
- - readme for validations DONE
25
- - test the shell command executor, and the terminal class for width command DONE
26
- - improve the readme to explain
27
- - a basic app with no options DONE
28
- - a basic app with options DONE
29
- - supplying multiple of the same parameter using multi DONE
30
- - a basic app with require arguments DONE
31
- - a basic app specifying version, description and summary DONE
32
- - test the readme for flags to make sure it works as expected DONE
33
- - a basic app with dependant options (mention that a deadlock situation can occur if you're not careful) DONE
34
- - example for conflicting options DONE
35
- - integration test for conflicting options DONE
36
- - readme for conflicting options DONE
37
- - for print stacktrace, change it to print in INFO mode so that stacktrace not printed by default DONE
38
- - BUG when a script requires arguments and user doesn't supply any escort treats this as an internal error and asks you to report it, this shouldn't be the case DONE
39
- - depends_on support
40
- - option depends on flag DONE
41
- - flag depends on another flag DONE
42
- - one option depends on another (the other must be not false not nil and not empty) DONE
43
- - one option depends on specific value of another (the other must be of a specific values) DONE
44
- - one option depends on several others (where are must be not false not nil and not empty) DONE
45
- - one option depends on several others where some must have a specific value (some options have specific value, others are not false not nil and not empty) DONE
46
- - error if option for which dependecy is being defined does not exist DONE
47
- - error if depends on non-existant option DONE
48
- - error if depends on itself DONE
49
- - error if dependency not satisfied DONE
50
- - error if missing on condition when specifying dependency DONE
51
- - refactor the options dsl class dependency code DONE
52
- - refactor the option_dependency_validator class to be nicer DONE
53
- - integration test all the permutations of dependency specification with error and success cases etc DONE
54
- - create a shortcut for dependency specification on the opt method options hash itself DONE
55
- - fix up example for basic app with dependencies for options DONE
7
+ - up the version to 0.3.0 DONE
8
+ - test the base command for actions well DONE
9
+ - BUG parent_options when parent of command is global context doesn't seem to work??? DONE
10
+ - integration test for commands DONE
11
+ - integration test for sub-commands DONE
12
+ - readme a basic app with config file, integration test (don't worry about explaining all the helper stuff that gets created) DONE
13
+ - test the configuration loader DONE
14
+ - test the descend to home locator DONE
15
+ - test the configuration merge tool DONE
16
+ - test the configuration generator DONE
17
+ - test all the locators (descend, specfic dir, current script dir, chaining) DONE
18
+ - we should always be using the chaining locator, with more or less sub locators depending on setup DONE
19
+ - create other locators (dir of currently executing script locator, i.e. not the working directory, specified dir locator) DONE
20
+ - create a chaining locator so we can put all our locators together DONE
21
+ - test the configuration reader DONE
22
+ - test the configuration writer DONE
23
+ - a basic app example with all the trimmings DONE
24
+ - app with config file example DONE
25
+ - readme implementing and action for a basic app DONE
26
+ - rejig for betterness the validations help outputs DONE
27
+ - test the string grid DONE
28
+ - start using the new stream output formatter DONE
29
+ - refactor terminal formatter and test it DONE
30
+ - finish testing the output formatter DONE
31
+ - get rid of shell command executor new shell stuff (doesn't work in Jruby and not really needed anyway) DONE
32
+ - extract all the dsl command stuff into a helper module so that global and command can be handled by the same code DONE
56
33
 
57
34
  v0.4.0
58
- - readme a basic app with config file (don't worry about explaining all the helper stuff that gets created)
59
- - readme implementing and action for a basic app
60
- - refactor terminal formatter and test it
61
- - refactor borderless table and test it
62
- - BUG parent_options when parent of command is global context doesn't seem to work???
63
- - test the base command for actions well
35
+ - test all the config file helper stuff
36
+ - a few more tests (setup accessor, all the dsl classes)
64
37
  - fix ppjson so that dependency suport feature is actually used
65
- - readme a command app with options, validations, description, summary, require arguments and config file, integration tests for commands, example
66
- - readme a sub command app with options, validations, description, summary, require arguments and config file
67
- - extract all the dsl command stuff into a helper module so that global and command can be handled by the same code
68
- - delete the stuff from the attic once it is no longer needed
69
- - get rid of shell command executor new shell stuff (doesn't work in Jruby and not really needed anyway)
70
38
  - up the version to 0.4.0
71
39
  - tag and release
72
40
 
73
41
 
42
+ - delete the stuff from the attic once it is no longer needed DONE
43
+ - readme a sub command app with options, validations, description, summary, require arguments and config file, integration tests, example DONE
44
+ - readme for requires arguments overriding and inheritance DONE
45
+ - readme explain all the helper stuff that automatically gets created with config file support DONE
46
+
47
+
74
48
  v1.0.0
75
- - perhaps rework actions with passing a class and having it being auto called
76
- - implement servants for dealing with clumps of functionality, and action commands have access to all servants that were executed before them
77
- - a few more tests (setup accessor, all the dsl classes)
78
- - for borderless table, should be able to create another borderless table within a cell of an existing table
79
49
  - have a think about how to make the integration tests a bit more robust, so that failures don't get swallowed (test for specific exit codes instead of non-zero exit code), fix the existing integration tests
80
- - in trollop when errors are raised they should be wrapped as escort errors and propagate rather than being caught by trollop itself
81
50
  - a few more integration tests (test that basic app automatically gets help and other automatic options)
51
+ - clean up all the extraneous branches
82
52
  - up the version to 1.0.0
83
53
  - tag and release
84
54
  - get the blog updated with a new theme
85
55
  - put a new subscriber count widget on blog
86
56
  - blog Build Command-Line Apps Like a Pro Using Ruby and Escort
87
57
 
58
+
59
+ - in trollop when errors are raised they should be wrapped as escort errors and propagate rather than being caught by trollop itself DONE
88
60
  - rework the examples again to show of some/most of the features (along the lines of the integration tests and readme) DONE
89
61
  - errors coming straigh out of configuration should still be caught by error handlers to only display stack trace when needed (refactor app create method) DONE
90
62
  - readme for a basic app with conflicting options DONE
91
63
  - readme for a basic app with dependent options DONE
92
64
 
93
65
  v1.0.1
94
- - more specs
66
+ - pull out the action execution into a separate class and test it
67
+ - add a section to readme for command line tools built with escort (e.g. ppjson)
68
+ - more specs (all the dsl classes possibly)
95
69
  - more integration specs (more specs for the different types of options)
96
- - lots more logging at different levels for debug purposes
97
70
  - a way have helpers available when you don't want to have to create a command
98
- - the config auto option should not be included in the config file, same with other auto options
71
+ - the config auto option should not be included in the config file, same with other auto options???
99
72
  - readme about how to actually pass the user config through to action and the fact that regardless if you have a config file or not, you can have a config var or not as part of the block variables
100
- - ability to specify a different command based on options declaratively or a convention for how to do different things for the same action based on options (bunch of options that are flags, options that are a clump of values etc)
73
+
101
74
 
102
75
  - rework the integration specs and matchers so there are less moving parts (perhaps push some stuff down into a base class etc.) DONE
103
76
  - rewrite the help formatter to be a bit easier to understand (more like man output for output) DONE
104
77
  - add depends support to dsl DONE
105
78
 
106
79
  v1.0.2
80
+ - refactor the app class so it is a bit nicer etc
107
81
  - more specs
82
+ - need a suite for escort itself using escort to bootstrap etc
108
83
  - scaffold for app with no sub commands
109
84
  - scaffold for app with one level of commands
110
85
  - scaffold for app with nested sub commands
@@ -115,13 +90,32 @@ v1.0.3
115
90
  - make the configuration environment aware
116
91
  - make escort environment aware (app.environment_aware)
117
92
  - json configuration should support defaults config
118
- - much better documentation and usage patterns
119
93
  - pull the terminal formatting stuff into separate gem
94
+ - pull nested exception stuff into separate gem
95
+
96
+
97
+ - much better documentation and usage patterns DONE
98
+
99
+ v2.0.0
100
+ - rework actions with passing a class and having it being auto called
101
+ - implement servants for dealing with clumps of functionality, and action commands have access to all servants that were executed before them
102
+ - ability to break up a big config into chucks, e.g. per command etc. so that it is more modular and easier to read
103
+ - whether or not action is specified things should not blow up
120
104
 
105
+ v2.0.1
106
+ - lots more logging at different levels for debug purposes
121
107
 
122
108
 
123
109
 
124
110
  BUCKET
111
+ - get all tests passing on jruby 1.9
112
+ - get all tests passing on rubinius 1.9
113
+ - get all tests passing on mri 1.8.7
114
+ - configatron support in addition to json config
115
+ - for help current command context is all confused, is the context a parent context or the current context, fixed in help but the class is still confused as it's being used in two different ways
116
+ - genericise the generator concept, so that the current one becomes a nested generator, but we can also have a flat generator
117
+ - genericise the writer and reader, so that the current one becomes json writer/reader, but we can have yaml or whatever we want
118
+ - we should always be working with a nested hash for configuration, its only at writing and reading time do we flatten or whatever
125
119
  - dependencies for command options on options from parent commands or global
126
120
  - a better way of executing action and servants for the actions
127
121
 
@@ -142,6 +136,7 @@ BUCKET
142
136
  app.before :actions => :descendant - all actions that descend from this one, but not this one
143
137
 
144
138
  - can split out the shell command executor into a tiny gem for later use
139
+ - for borderless table, should be able to create another borderless table within a cell of an existing table
145
140
  - get the build working on ruby 1.8.7
146
141
  - formatting code should support colours and styles for output
147
142
  - formatting code should support a table with borders and stuff
@@ -263,3 +258,55 @@ v0.1.0
263
258
  - look again at conflicts support in dsl, we can probably do better naming for it DONE
264
259
  - up the version to 0.1.0 DONE
265
260
  - tag and release DONE
261
+
262
+ v0.2.0
263
+ - up the version to 0.2.0 DONE
264
+ - tag and release DONE
265
+ - test conflicts for non-exstant options (integration) DONE
266
+ - test all the new help stuff on option, for conflicts, dependencies, validations DONE
267
+ - fix up readme for conflicts block DONE
268
+ - rework validations to be part of the options block rather than in their own block DONE
269
+ - fix example, fix tests, fix readme DONE
270
+ - need to rework conflicts as currently not really very good DONE
271
+ - add dependencies to help text DONE
272
+ - add conflicts to help text DONE
273
+ - add validation texts to help text so that people can see what kind of values are valid DONE
274
+ - make sure we check conflicts for non-existant options DONE
275
+ - refactor the formatting code some more DONE
276
+ - pull some formatting code into separate classes DONE
277
+ - test some of the utility formatting code DONE
278
+ - fix up help text so that if arguments are mandatory they are shown as mandatory not optional DONE
279
+ - basic example with validations DONE
280
+ - integration test for validations DONE
281
+ - readme for validations DONE
282
+ - test the shell command executor, and the terminal class for width command DONE
283
+ - improve the readme to explain
284
+ - a basic app with no options DONE
285
+ - a basic app with options DONE
286
+ - supplying multiple of the same parameter using multi DONE
287
+ - a basic app with require arguments DONE
288
+ - a basic app specifying version, description and summary DONE
289
+ - test the readme for flags to make sure it works as expected DONE
290
+ - a basic app with dependant options (mention that a deadlock situation can occur if you're not careful) DONE
291
+ - example for conflicting options DONE
292
+ - integration test for conflicting options DONE
293
+ - readme for conflicting options DONE
294
+ - for print stacktrace, change it to print in INFO mode so that stacktrace not printed by default DONE
295
+ - BUG when a script requires arguments and user doesn't supply any escort treats this as an internal error and asks you to report it, this shouldn't be the case DONE
296
+ - depends_on support
297
+ - option depends on flag DONE
298
+ - flag depends on another flag DONE
299
+ - one option depends on another (the other must be not false not nil and not empty) DONE
300
+ - one option depends on specific value of another (the other must be of a specific values) DONE
301
+ - one option depends on several others (where are must be not false not nil and not empty) DONE
302
+ - one option depends on several others where some must have a specific value (some options have specific value, others are not false not nil and not empty) DONE
303
+ - error if option for which dependecy is being defined does not exist DONE
304
+ - error if depends on non-existant option DONE
305
+ - error if depends on itself DONE
306
+ - error if dependency not satisfied DONE
307
+ - error if missing on condition when specifying dependency DONE
308
+ - refactor the options dsl class dependency code DONE
309
+ - refactor the option_dependency_validator class to be nicer DONE
310
+ - integration test all the permutations of dependency specification with error and success cases etc DONE
311
+ - create a shortcut for dependency specification on the opt method options hash itself DONE
312
+ - fix up example for basic app with dependencies for options DONE