escort 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (86) hide show
  1. checksums.yaml +8 -8
  2. data/.travis.yml +8 -0
  3. data/README.md +365 -14
  4. data/TODO.md +157 -44
  5. data/escort.gemspec +1 -0
  6. data/examples/{1_1_basic.rb → attic/1_1_basic.rb} +0 -0
  7. data/examples/{1_2_basic_requires_arguments.rb → attic/1_2_basic_requires_arguments.rb} +0 -0
  8. data/examples/{2_2_command.rb → attic/2_2_command.rb} +0 -0
  9. data/examples/{2_2_command_requires_arguments.rb → attic/2_2_command_requires_arguments.rb} +0 -0
  10. data/examples/{2_3_nested_commands.rb → attic/2_3_nested_commands.rb} +0 -0
  11. data/examples/{3_validations.rb → attic/3_validations.rb} +0 -0
  12. data/examples/{4_1_config_file.rb → attic/4_1_config_file.rb} +0 -0
  13. data/examples/{argument_handling → attic/argument_handling}/basic.rb +0 -0
  14. data/examples/{argument_handling → attic/argument_handling}/basic_command.rb +0 -0
  15. data/examples/{argument_handling → attic/argument_handling}/no_arguments.rb +0 -0
  16. data/examples/{argument_handling → attic/argument_handling}/no_arguments_command.rb +0 -0
  17. data/examples/{command_aliases → attic/command_aliases}/app.rb +0 -0
  18. data/examples/{config_file → attic/config_file}/.apprc2 +0 -0
  19. data/examples/{config_file → attic/config_file}/app.rb +0 -0
  20. data/examples/{config_file → attic/config_file}/sub_commands.rb +0 -0
  21. data/examples/{default_command → attic/default_command}/app.rb +0 -0
  22. data/examples/{sub_commands → attic/sub_commands}/app.rb +0 -0
  23. data/examples/{validation_basic → attic/validation_basic}/app.rb +0 -0
  24. data/examples/basic +10 -0
  25. data/examples/basic_conflicts +17 -0
  26. data/examples/basic_depends_on +25 -0
  27. data/examples/basic_flags +15 -0
  28. data/examples/basic_options +14 -0
  29. data/examples/basic_options_multi +15 -0
  30. data/examples/basic_require_arguments +17 -0
  31. data/examples/basic_texts +21 -0
  32. data/examples/basic_validations +21 -0
  33. data/examples/command +19 -0
  34. data/examples/commands/example_command.rb +13 -0
  35. data/lib/escort/action_command/base.rb +4 -0
  36. data/lib/escort/app.rb +33 -11
  37. data/lib/escort/formatter/borderless_table.rb +4 -0
  38. data/lib/escort/formatter/command.rb +87 -0
  39. data/lib/escort/formatter/commands.rb +36 -0
  40. data/lib/escort/formatter/default_help_formatter.rb +68 -73
  41. data/lib/escort/formatter/global_command.rb +17 -0
  42. data/lib/escort/formatter/option.rb +138 -0
  43. data/lib/escort/formatter/options.rb +17 -3
  44. data/lib/escort/formatter/shell_command_executor.rb +49 -0
  45. data/lib/escort/formatter/terminal.rb +17 -9
  46. data/lib/escort/formatter/terminal_formatter.rb +6 -0
  47. data/lib/escort/logger.rb +4 -4
  48. data/lib/escort/option_dependency_validator.rb +83 -0
  49. data/lib/escort/option_parser.rb +11 -1
  50. data/lib/escort/setup/configuration/reader.rb +0 -2
  51. data/lib/escort/setup/configuration/writer.rb +0 -2
  52. data/lib/escort/setup/dsl/command.rb +2 -7
  53. data/lib/escort/setup/dsl/global.rb +2 -9
  54. data/lib/escort/setup/dsl/options.rb +56 -0
  55. data/lib/escort/setup_accessor.rb +23 -6
  56. data/lib/escort/trollop.rb +4 -3
  57. data/lib/escort/validator.rb +4 -1
  58. data/lib/escort/version.rb +1 -1
  59. data/lib/escort.rb +8 -1
  60. data/spec/integration/basic_conflicts_spec.rb +47 -0
  61. data/spec/integration/basic_depends_on_spec.rb +275 -0
  62. data/spec/integration/basic_options_spec.rb +9 -21
  63. data/spec/integration/basic_options_with_multi_spec.rb +30 -0
  64. data/spec/integration/basic_spec.rb +5 -6
  65. data/spec/integration/basic_validations_spec.rb +77 -0
  66. data/spec/integration/basic_with_arguments_spec.rb +33 -0
  67. data/spec/integration/basic_with_text_fields_spec.rb +21 -0
  68. data/spec/lib/escort/formatter/command_spec.rb +238 -0
  69. data/spec/lib/escort/formatter/global_command_spec.rb +50 -0
  70. data/spec/lib/escort/formatter/option_spec.rb +300 -0
  71. data/spec/lib/escort/formatter/shell_command_executor_spec.rb +59 -0
  72. data/spec/lib/escort/formatter/string_splitter_spec.rb +12 -0
  73. data/spec/lib/escort/formatter/terminal_spec.rb +19 -0
  74. data/spec/lib/escort/setup_accessor_spec.rb +1 -0
  75. data/spec/spec_helper.rb +9 -3
  76. data/spec/support/integration_helpers.rb +2 -0
  77. data/spec/{helpers/execute_action_matcher.rb → support/matchers/execute_action_for_command_matcher.rb} +3 -3
  78. data/spec/support/matchers/execute_action_with_arguments_matcher.rb +25 -0
  79. data/spec/support/matchers/execute_action_with_options_matcher.rb +29 -0
  80. data/spec/support/matchers/exit_with_code_matcher.rb +29 -0
  81. data/spec/support/shared_contexts/integration_setup.rb +34 -0
  82. metadata +86 -28
  83. data/examples/basic/app.rb +0 -16
  84. data/lib/escort/formatter/common.rb +0 -58
  85. data/spec/helpers/exit_with_code_matcher.rb +0 -21
  86. data/spec/helpers/give_option_to_action_with_value_matcher.rb +0 -22
data/TODO.md CHANGED
@@ -1,62 +1,107 @@
1
1
  ROADMAP
2
2
 
3
- v0.1.0
4
- - some spec infrastructure DONE
5
- - a couple of basic specs DONE
6
- - some integration test infrastructure DONE
7
- - a couple of basic integration tests DONE
8
- - pull classes for formatting out into files DONE
9
- - summary and description for commands DONE
10
- - include command summary and description in help formatter DONE
11
- - rework how help is displayed for commands with summary and description DONE
12
- - the sub commands for command should use summary instead of description DONE
13
- - do for validation and action what I did for option within the dsl DONE
14
- - look again at conflicts support in dsl, we can probably do better naming for it DONE
15
- - up the version to 0.1.0
3
+ v0.2.0
4
+ - up the version to 0.2.0
16
5
  - tag and release
17
6
 
18
- v0.9.0
19
- - a few more tests
20
- - a few more integration tests
21
- - refactor the formatting code some more
22
- - pull some formatting code into separate classes
23
- - test some of the utility formatting code
24
- - up the version to 0.9.0
7
+
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
56
+
57
+ 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
64
+ - 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
+ - up the version to 0.4.0
25
71
  - tag and release
26
72
 
73
+
27
74
  v1.0.0
28
- - rewrite the readme to explain:
29
- - a basic app with no options
30
- - a basic app with options
31
- - supplying multiple of the same parameter using multi
32
- - a basic app with require arguments
33
- - a basic app specifying version, description and summary
34
- - a basic app with options and validations
35
- - implementing and action for a basic app
36
- - a basic app with config file (don't worry about explaining all the helper stuff that gets created)
37
- - a basic app with conflicting options
38
- - a basic app with dependent options
39
- - a command app with options, validations, description, summary, require arguments and config file
40
- - a sub command app with options, validations, description, summary, require arguments and config file
41
- - rework the examples again to show of some/most of the features (along the lines of the integration tests and readme)
42
- - extract all the dsl command stuff into a helper module so that global and command can be handled by the same code
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
+ - 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
+ - a few more integration tests (test that basic app automatically gets help and other automatic options)
43
82
  - up the version to 1.0.0
44
83
  - tag and release
45
84
  - get the blog updated with a new theme
46
85
  - put a new subscriber count widget on blog
47
86
  - blog Build Command-Line Apps Like a Pro Using Ruby and Escort
48
87
 
88
+ - rework the examples again to show of some/most of the features (along the lines of the integration tests and readme) DONE
89
+ - 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
+ - readme for a basic app with conflicting options DONE
91
+ - readme for a basic app with dependent options DONE
92
+
49
93
  v1.0.1
50
- - more specs (setup accessor etc)
94
+ - more specs
51
95
  - more integration specs (more specs for the different types of options)
52
- - rework the integration specs and matchers so there are less moving parts (perhaps push some stuff down into a base class etc.)
53
96
  - lots more logging at different levels for debug purposes
54
- - add validation messages to help text
55
97
  - a way have helpers available when you don't want to have to create a command
56
98
  - the config auto option should not be included in the config file, same with other auto options
57
99
  - 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
58
- - rewrite the help formatter to be a bit easier to understand (more like man output for output)
59
- - add depends support to dsl
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)
101
+
102
+ - rework the integration specs and matchers so there are less moving parts (perhaps push some stuff down into a base class etc.) DONE
103
+ - rewrite the help formatter to be a bit easier to understand (more like man output for output) DONE
104
+ - add depends support to dsl DONE
60
105
 
61
106
  v1.0.2
62
107
  - more specs
@@ -68,7 +113,7 @@ v1.0.3
68
113
  - an option for setup that indicates it is a project specific CLI app
69
114
  - an options for setup that indicates it is an environment aware CLI app
70
115
  - make the configuration environment aware
71
- - make escort environment aware
116
+ - make escort environment aware (app.environment_aware)
72
117
  - json configuration should support defaults config
73
118
  - much better documentation and usage patterns
74
119
  - pull the terminal formatting stuff into separate gem
@@ -77,6 +122,33 @@ v1.0.3
77
122
 
78
123
 
79
124
  BUCKET
125
+ - dependencies for command options on options from parent commands or global
126
+ - a better way of executing action and servants for the actions
127
+
128
+ - specify the options via classes
129
+ #command.action StreamProvider::Commands::StopServer
130
+ - define servants for actions within context
131
+ #app.before_action :stop, :start, :restart do |action|
132
+ #action.servant :configatron, StreamProvider::Servants::ConfigatronServant
133
+ #end
134
+
135
+ #app.before_action :restart do |action|
136
+ #action.servant :blah, StreamProvider::Servants::BlahServant
137
+ #end
138
+ - a before action without command names in context
139
+ app.before :actions => :this - only action in current context
140
+ app.before :actions => :child - only child action in current context
141
+ app.before :actions => [:this, :child] - this action and child actions
142
+ app.before :actions => :descendant - all actions that descend from this one, but not this one
143
+
144
+ - can split out the shell command executor into a tiny gem for later use
145
+ - get the build working on ruby 1.8.7
146
+ - formatting code should support colours and styles for output
147
+ - formatting code should support a table with borders and stuff
148
+ - formatting code should support a simple progress bar for showing progress
149
+ - formatting code should be more well factored
150
+ - highline support should be added so that values can be asked for
151
+ - values should be asked for before validations are executed, since entered values should be validated
80
152
  - instead of before and after blocks, add before, after filters for commands, maybe
81
153
  - when no action found in the context we want to execute, it should error or at least print an error
82
154
  - can we flatten the configuration (as an option)
@@ -97,9 +169,9 @@ BUCKET
97
169
  - blog about dependencies with bundler, the spermy operator and what version will be chosen
98
170
  - blog about ppjson and how to use it
99
171
 
100
- - improve the terminal formatter, allowing wrapping text to anywhere, and tabular like output without an actual table, allowing configuring terminal of any size not just 80, spin it off a little separate project, with an example of how to possibly build a menu in it or something
101
- - BUG the help formatting is still not quite right as far as respecting the char limits and wrapping properly when doing tabular output!!!!
102
- - do a readme for how trollop was slightly modified to accept a formatter DONE
172
+ - improve the terminal formatter, allowing wrapping text to anywhere, and tabular like output without an actual table, allowing configuring terminal of any size not just 80, spin it off a little separate project, with an example of how to possibly build a menu in it or something DONE
173
+ - BUG the help formatting is still not quite right as far as respecting the char limits and wrapping properly when doing tabular output!!!! DONE
174
+ - do a readme for how trollop was slightly modified to accept a formatter
103
175
  - gemspec summary and description should be taken from the app definition/maybe
104
176
  - perhaps add a copyright with license to readme
105
177
  - via method missing we can make the dsl classes more robust by printing errors and exting when non-dsl methods are attempted
@@ -112,6 +184,32 @@ BUCKET
112
184
  PIE IN SKY
113
185
  - choosing default output format based on where the output is going STDOUT.tty?
114
186
  - look at ruby curses support a bit more closely and maybe use that for terminal stuff instead as it would be much better at it
187
+ - a library for specifying conditions and matching on those conditions
188
+ - possible syntax for conditions library:
189
+ Conditions.new do
190
+ _and do
191
+ _= a, 1
192
+ _not do
193
+ _or do
194
+ _nil :b
195
+ _empty :b
196
+ _false :b
197
+ end
198
+ end
199
+ _present :b
200
+ _present [:c, :d]
201
+ _nil :e
202
+ _empty :f
203
+ _false :g
204
+ _or do
205
+ _= :h, 5
206
+ _and do
207
+ _= :i, 7
208
+ _empty :j
209
+ end
210
+ end
211
+ end
212
+ end
115
213
 
116
214
 
117
215
 
@@ -150,3 +248,18 @@ DONE
150
248
  - better support for on_error blocks with explanations and examples of usage (roll exit code support into here), default handling of errors in block N/A
151
249
  - a convention for how to actually do the code that will handle the commands etc. DONE
152
250
  - support for infinitely nesting sub commands (is this really necessary) DONE
251
+
252
+ v0.1.0
253
+ - some spec infrastructure DONE
254
+ - a couple of basic specs DONE
255
+ - some integration test infrastructure DONE
256
+ - a couple of basic integration tests DONE
257
+ - pull classes for formatting out into files DONE
258
+ - summary and description for commands DONE
259
+ - include command summary and description in help formatter DONE
260
+ - rework how help is displayed for commands with summary and description DONE
261
+ - the sub commands for command should use summary instead of description DONE
262
+ - do for validation and action what I did for option within the dsl DONE
263
+ - look again at conflicts support in dsl, we can probably do better naming for it DONE
264
+ - up the version to 0.1.0 DONE
265
+ - tag and release DONE
data/escort.gemspec CHANGED
@@ -15,6 +15,7 @@ Gem::Specification.new do |gem|
15
15
  gem.add_development_dependency('rspec')
16
16
  gem.add_development_dependency('fakefs')
17
17
  gem.add_development_dependency('rake')
18
+ gem.add_development_dependency('travis-lint')
18
19
 
19
20
  gem.files = `git ls-files`.split($/)
20
21
  gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
File without changes
File without changes
File without changes
File without changes
data/examples/basic ADDED
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require File.expand_path(File.join(File.expand_path(__FILE__), "..", "..", "lib", "escort"))
4
+ require File.join(File.expand_path(__FILE__), "..", "commands", "example_command")
5
+
6
+ Escort::App.create do |app|
7
+ app.action do |options, arguments|
8
+ Escort::ExampleCommand.new(options, arguments).execute
9
+ end
10
+ end
@@ -0,0 +1,17 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require File.expand_path(File.join(File.expand_path(__FILE__), "..", "..", "lib", "escort"))
4
+ require File.join(File.expand_path(__FILE__), "..", "commands", "example_command")
5
+
6
+ Escort::App.create do |app|
7
+ app.options do |opts|
8
+ opts.opt :flag1, "Flag 1", :short => '-f', :long => '--flag1', :type => :boolean
9
+ opts.opt :flag2, "Flag 2", :short => :none, :long => '--flag2', :type => :boolean
10
+
11
+ opts.conflict :flag1, :flag2, :flag3
12
+ end
13
+
14
+ app.action do |options, arguments|
15
+ Escort::ExampleCommand.new(options, arguments).execute
16
+ end
17
+ end
@@ -0,0 +1,25 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require File.expand_path(File.join(File.expand_path(__FILE__), "..", "..", "lib", "escort"))
4
+ require File.join(File.expand_path(__FILE__), "..", "commands", "example_command")
5
+
6
+ Escort::App.create do |app|
7
+ app.options do |opts|
8
+ opts.opt :flag1, "Flag 1", :short => '-f', :long => '--flag1', :type => :boolean
9
+ opts.opt :flag2, "Flag 2", :short => :none, :long => '--flag2', :type => :boolean, :default => true
10
+ opts.opt :option1, "Option1", :short => '-o', :long => '--option1', :type => :string
11
+ opts.opt :option2, "Option2", :short => :none, :long => '--option2', :type => :string, :multi => true
12
+ opts.opt :option3, "Option3", :short => :none, :long => '--option3', :type => :string
13
+ opts.opt :option4, "Option4", :short => :none, :long => '--option4', :type => :string
14
+
15
+ opts.dependency :option1, :on => :flag1
16
+ opts.dependency :option2, :on => [:flag1, :option1]
17
+ opts.dependency :option3, :on => {:option1 => 'foo'}
18
+ #opts.dependency :option4, :on => [{:flag1 => false}, :option1] #This will get you into big trouble as it can never be fulfilled
19
+ opts.dependency :option4, :on => [{:flag2 => false}, :option1]
20
+ end
21
+
22
+ app.action do |options, arguments|
23
+ Escort::ExampleCommand.new(options, arguments).execute
24
+ end
25
+ end
@@ -0,0 +1,15 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require File.expand_path(File.join(File.expand_path(__FILE__), "..", "..", "lib", "escort"))
4
+ require File.join(File.expand_path(__FILE__), "..", "commands", "example_command")
5
+
6
+ Escort::App.create do |app|
7
+ app.options do |opts|
8
+ opts.opt :flag1, "Flag 1", :short => '-f', :long => '--flag1', :type => :boolean, :default => true
9
+ opts.opt :flag2, "Flag 2", :short => :none, :long => '--flag2', :type => :boolean
10
+ end
11
+
12
+ app.action do |options, arguments|
13
+ Escort::ExampleCommand.new(options, arguments).execute
14
+ end
15
+ end
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require File.expand_path(File.join(File.expand_path(__FILE__), "..", "..", "lib", "escort"))
4
+ require File.join(File.expand_path(__FILE__), "..", "commands", "example_command")
5
+
6
+ Escort::App.create do |app|
7
+ app.options do |opts|
8
+ opts.opt :option1, "Option1", :short => '-o', :long => '--option1', :type => :string, :default => "option 1"
9
+ end
10
+
11
+ app.action do |options, arguments|
12
+ Escort::ExampleCommand.new(options, arguments).execute
13
+ end
14
+ end
@@ -0,0 +1,15 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require File.expand_path(File.join(File.expand_path(__FILE__), "..", "..", "lib", "escort"))
4
+ require File.join(File.expand_path(__FILE__), "..", "commands", "example_command")
5
+
6
+ Escort::App.create do |app|
7
+ app.options do |opts|
8
+ opts.opt :option1, "Option1", :short => '-o', :long => '--option1', :type => :string, :default => "option 1"
9
+ opts.opt :option2, "Option2", :short => :none, :long => '--option2', :type => :string, :multi => true
10
+ end
11
+
12
+ app.action do |options, arguments|
13
+ Escort::ExampleCommand.new(options, arguments).execute
14
+ end
15
+ end
@@ -0,0 +1,17 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require File.expand_path(File.join(File.expand_path(__FILE__), "..", "..", "lib", "escort"))
4
+ require File.join(File.expand_path(__FILE__), "..", "commands", "example_command")
5
+
6
+ Escort::App.create do |app|
7
+ app.requires_arguments
8
+
9
+ app.options do |opts|
10
+ opts.opt :option1, "Option1", :short => '-o', :long => '--option1', :type => :string, :default => "option 1"
11
+ opts.opt :option2, "Option2", :short => :none, :long => '--option2', :type => :string, :multi => true
12
+ end
13
+
14
+ app.action do |options, arguments|
15
+ Escort::ExampleCommand.new(options, arguments).execute
16
+ end
17
+ end
@@ -0,0 +1,21 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require File.expand_path(File.join(File.expand_path(__FILE__), "..", "..", "lib", "escort"))
4
+ require File.join(File.expand_path(__FILE__), "..", "commands", "example_command")
5
+
6
+ Escort::App.create do |app|
7
+ app.version "0.1.1"
8
+ app.summary "Summary 1"
9
+ app.description "Description 1"
10
+
11
+ app.requires_arguments
12
+
13
+ app.options do |opts|
14
+ opts.opt :option1, "Option1", :short => '-o', :long => '--option1', :type => :string, :default => "option 1"
15
+ opts.opt :option2, "Option2", :short => :none, :long => '--option2', :type => :string, :multi => true
16
+ end
17
+
18
+ app.action do |options, arguments|
19
+ Escort::ExampleCommand.new(options, arguments).execute
20
+ end
21
+ end
@@ -0,0 +1,21 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require File.expand_path(File.join(File.expand_path(__FILE__), "..", "..", "lib", "escort"))
4
+ require File.join(File.expand_path(__FILE__), "..", "commands", "example_command")
5
+
6
+ Escort::App.create do |app|
7
+ app.options do |opts|
8
+ opts.opt :option1, "Option 1", :short => '-o', :long => '--option1', :type => :string
9
+ opts.opt :int1, "Int 1", :short => '-i', :long => '--int1', :type => :int
10
+ opts.opt :option2, "Option 2", :short => :none, :long => '--option2', :type => :string
11
+
12
+ opts.validate(:option1, "must be either 'foo' or 'bar'") { |option| ["foo", "bar"].include?(option) }
13
+ opts.validate(:int1, "must be between 10 and 20 exclusive") { |option| option > 10 && option < 20 }
14
+ opts.validate(:option2, "must be two words") {|option| option =~ /\w\s\w/}
15
+ opts.validate(:option2, "must be at least 20 characters long") {|option| option.length >= 20}
16
+ end
17
+
18
+ app.action do |options, arguments|
19
+ Escort::ExampleCommand.new(options, arguments).execute
20
+ end
21
+ end
data/examples/command ADDED
@@ -0,0 +1,19 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require File.expand_path(File.join(File.expand_path(__FILE__), "..", "..", "lib", "escort"))
4
+ require File.join(File.expand_path(__FILE__), "..", "commands", "example_command")
5
+
6
+ Escort::App.create do |app|
7
+ app.command :command1, :aliases => [:c1, :com1] do |command|
8
+ command.summary "Command summary 1"
9
+ command.description "Command description 1"
10
+
11
+ command.action do |options, arguments|
12
+ Escort::ExampleCommand.new(options, arguments).execute
13
+ end
14
+ end
15
+
16
+ app.action do |options, arguments|
17
+ Escort::ExampleCommand.new(options, arguments).execute
18
+ end
19
+ end
@@ -0,0 +1,13 @@
1
+ module Escort
2
+ class ExampleCommand < ::Escort::ActionCommand::Base
3
+ def execute
4
+ Escort::Logger.output.puts "Command: #{command_name}"
5
+ Escort::Logger.output.puts "Options: #{options}"
6
+ Escort::Logger.output.puts "Command options: #{command_options}"
7
+ Escort::Logger.output.puts "Arguments: #{arguments}"
8
+ if config
9
+ Escort::Logger.output.puts "User config: #{config}"
10
+ end
11
+ end
12
+ end
13
+ end
@@ -28,6 +28,10 @@ module Escort
28
28
  @command_context
29
29
  end
30
30
 
31
+ def command_name
32
+ command_context.first || :global
33
+ end
34
+
31
35
  def command_options
32
36
  @command_options ||= context_hash(command_context)[:options] || {}
33
37
  end
data/lib/escort/app.rb CHANGED
@@ -2,20 +2,40 @@ module Escort
2
2
  class App
3
3
  #TODO ensure that every command must have an action
4
4
  class << self
5
+ #def create(option_string = '', &block)
6
+ #cli_app_configuration = Escort::Setup::Dsl::Global.new(&block)
7
+ #setup = Escort::SetupAccessor.new(cli_app_configuration)
8
+ #app = self.new(option_string, setup)
9
+ #app.execute
10
+ #exit(0)
11
+ #end
12
+
5
13
  def create(option_string = '', &block)
6
- cli_app_configuration = Escort::Setup::Dsl::Global.new(&block)
7
- setup = Escort::SetupAccessor.new(cli_app_configuration)
8
- app = self.new(option_string, setup)
9
- app.execute
14
+ self.new(option_string, &block).setup_application.execute
10
15
  exit(0)
11
16
  end
12
17
  end
13
18
 
14
19
  attr_reader :setup, :option_string
15
20
 
16
- def initialize(option_string, setup)
17
- @setup = setup
21
+ def initialize(option_string, &block)
18
22
  @option_string = option_string
23
+ @setup = nil
24
+ @block = block
25
+ end
26
+
27
+ def setup_application
28
+ old_error_sev_threshold = error_logger.sev_threshold
29
+ begin
30
+ error_logger.sev_threshold = ::Logger::DEBUG
31
+ cli_app_configuration = Escort::Setup::Dsl::Global.new(&@block)
32
+ @setup = Escort::SetupAccessor.new(cli_app_configuration)
33
+ self
34
+ rescue => e
35
+ handle_escort_error(e)
36
+ ensure
37
+ error_logger.sev_threshold = old_error_sev_threshold
38
+ end
19
39
  end
20
40
 
21
41
  def execute
@@ -50,7 +70,9 @@ module Escort
50
70
 
51
71
  def execute_action(action, options, arguments, user_config)
52
72
  begin
73
+ #execute before servants here
53
74
  action.call(options, arguments, user_config)
75
+ #execute after servants here
54
76
  rescue => e
55
77
  handle_action_error(e)
56
78
  end
@@ -72,11 +94,11 @@ module Escort
72
94
 
73
95
  def handle_escort_error(e)
74
96
  if e.kind_of?(Escort::UserError)
75
- print_escort_error_message(e)
97
+ print_stacktrace(e)
76
98
  error_logger.debug{ "Escort app failed to execute successfully, due to user error" }
77
99
  exit(Escort::USER_ERROR_EXIT_CODE)
78
100
  elsif e.kind_of?(Escort::ClientError)
79
- print_escort_error_message(e)
101
+ print_stacktrace(e)
80
102
  error_logger.debug{ "Escort app failed to execute successfully, due to client setup error" }
81
103
  exit(Escort::CLIENT_ERROR_EXIT_CODE)
82
104
  else
@@ -99,13 +121,13 @@ module Escort
99
121
  end
100
122
 
101
123
  def print_stacktrace(e)
102
- error_logger.error{ e }
124
+ error_logger.error{ e.message }
125
+ error_logger.debug{ e }
103
126
  end
104
127
 
105
128
  def print_escort_error_message(e)
106
129
  print_stacktrace(e)
107
- error_logger.warn{ "\n\n" }
108
- error_logger.warn{ "An internal Escort error has occurred, you should probably report it by creating an issue on github!" }
130
+ error_logger.warn{ "An internal Escort error has occurred, you should probably report it by creating an issue on github! To get a stacktrace, up the verbosity level to DEBUG and execute your command again. Use --help for details." }
109
131
  end
110
132
  end
111
133
  end
@@ -1,3 +1,7 @@
1
+ #TODO needs some serious testing stuffs
2
+ #split out into many classes VirtuaRow, PhysicalRow, FormatterRow
3
+ #needs method each_formatted_row
4
+ #the printing out should only happen in the outputter class not in the table intself
1
5
  module Escort
2
6
  module Formatter
3
7
  class BorderlessTable