escort 0.0.1 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (76) hide show
  1. checksums.yaml +15 -0
  2. data/.gitignore +1 -0
  3. data/.irbrc +1 -0
  4. data/.rspec +3 -0
  5. data/.rvmrc +22 -0
  6. data/README.md +31 -56
  7. data/TODO.md +152 -0
  8. data/escort.gemspec +6 -2
  9. data/examples/1_1_basic.rb +15 -0
  10. data/examples/1_2_basic_requires_arguments.rb +15 -0
  11. data/examples/2_2_command.rb +18 -0
  12. data/examples/2_2_command_requires_arguments.rb +20 -0
  13. data/examples/2_3_nested_commands.rb +26 -0
  14. data/examples/3_validations.rb +31 -0
  15. data/examples/4_1_config_file.rb +42 -0
  16. data/examples/argument_handling/basic.rb +12 -0
  17. data/examples/argument_handling/basic_command.rb +18 -0
  18. data/examples/argument_handling/no_arguments.rb +14 -0
  19. data/examples/argument_handling/no_arguments_command.rb +20 -0
  20. data/examples/basic/app.rb +16 -0
  21. data/examples/command_aliases/app.rb +31 -0
  22. data/examples/config_file/.apprc2 +16 -0
  23. data/examples/config_file/app.rb +78 -0
  24. data/examples/config_file/sub_commands.rb +35 -0
  25. data/examples/default_command/app.rb +20 -0
  26. data/examples/sub_commands/app.rb +18 -0
  27. data/examples/validation_basic/app.rb +31 -0
  28. data/lib/escort.rb +51 -4
  29. data/lib/escort/action_command/base.rb +79 -0
  30. data/lib/escort/action_command/escort_utility_command.rb +53 -0
  31. data/lib/escort/app.rb +89 -36
  32. data/lib/escort/arguments.rb +20 -0
  33. data/lib/escort/auto_options.rb +71 -0
  34. data/lib/escort/error/error.rb +50 -0
  35. data/lib/escort/formatter/borderless_table.rb +102 -0
  36. data/lib/escort/formatter/common.rb +58 -0
  37. data/lib/escort/formatter/default_help_formatter.rb +106 -0
  38. data/lib/escort/formatter/options.rb +13 -0
  39. data/lib/escort/formatter/string_splitter.rb +30 -0
  40. data/lib/escort/formatter/terminal.rb +22 -0
  41. data/lib/escort/formatter/terminal_formatter.rb +52 -0
  42. data/lib/escort/global_pre_parser.rb +43 -0
  43. data/lib/escort/logger.rb +75 -0
  44. data/lib/escort/option_parser.rb +145 -0
  45. data/lib/escort/setup/configuration/generator.rb +75 -0
  46. data/lib/escort/setup/configuration/instance.rb +33 -0
  47. data/lib/escort/setup/configuration/loader.rb +37 -0
  48. data/lib/escort/setup/configuration/locator/base.rb +19 -0
  49. data/lib/escort/setup/configuration/locator/descending_to_home.rb +23 -0
  50. data/lib/escort/setup/configuration/merge_tool.rb +38 -0
  51. data/lib/escort/setup/configuration/reader.rb +36 -0
  52. data/lib/escort/setup/configuration/writer.rb +44 -0
  53. data/lib/escort/setup/dsl/action.rb +17 -0
  54. data/lib/escort/setup/dsl/command.rb +74 -0
  55. data/lib/escort/setup/dsl/config_file.rb +13 -0
  56. data/lib/escort/setup/dsl/global.rb +84 -0
  57. data/lib/escort/setup/dsl/options.rb +25 -0
  58. data/lib/escort/setup/dsl/validations.rb +25 -0
  59. data/lib/escort/setup_accessor.rb +194 -0
  60. data/lib/escort/trollop.rb +15 -4
  61. data/lib/escort/utils.rb +21 -0
  62. data/lib/escort/validator.rb +42 -0
  63. data/lib/escort/version.rb +1 -1
  64. data/spec/helpers/execute_action_matcher.rb +21 -0
  65. data/spec/helpers/exit_with_code_matcher.rb +21 -0
  66. data/spec/helpers/give_option_to_action_with_value_matcher.rb +22 -0
  67. data/spec/integration/basic_options_spec.rb +53 -0
  68. data/spec/integration/basic_spec.rb +24 -0
  69. data/spec/lib/escort/formatter/string_splitter_spec.rb +38 -0
  70. data/spec/lib/escort/setup_accessor_spec.rb +42 -0
  71. data/spec/lib/escort/utils_spec.rb +30 -0
  72. data/spec/spec_helper.rb +22 -0
  73. metadata +128 -16
  74. data/lib/escort/command.rb +0 -23
  75. data/lib/escort/dsl.rb +0 -20
  76. data/lib/escort/global_dsl.rb +0 -11
@@ -0,0 +1,24 @@
1
+ describe "Escort basic app with no options defined" do
2
+ subject { Escort::App.create(option_string, &app_configuration) }
3
+ let(:result) { [] }
4
+
5
+ let(:app_configuration) do
6
+ ->(app) do
7
+ app.action do |options, arguments|
8
+ result << :global
9
+ end
10
+ end
11
+ end
12
+
13
+ context "when called with empty option string" do
14
+ let(:option_string) { "" }
15
+ it("should exit with code 0") { expect{ subject }.to exit_with_code(0) }
16
+ it("should execute the global action") { expect{subject}.to execute_action(:global, result) }
17
+ end
18
+
19
+ context "when called with non-empty option string" do
20
+ let(:option_string) { "hello" }
21
+ it("exit code should be 0") { expect{ subject }.to exit_with_code(0) }
22
+ it("should execute the global action") { expect{subject}.to execute_action(:global, result) }
23
+ end
24
+ end
@@ -0,0 +1,38 @@
1
+ describe Escort::Formatter::StringSplitter do
2
+ let(:splitter) {Escort::Formatter::StringSplitter.new(max_segment_width)}
3
+
4
+ describe "#split" do
5
+ subject {splitter.split(string)}
6
+
7
+ context "when segment width is 10" do
8
+ let(:max_segment_width) { 10 }
9
+
10
+ context "and string is 'abc123'" do
11
+ let(:string) {'abc123'}
12
+ it("should produce 1 segment") { subject.size.should == 1 }
13
+ it("first segment should be 'abc123'") { subject[0].should == 'abc123' }
14
+ end
15
+
16
+ context "and string is 'abc1234567'" do
17
+ let(:string) {'abc1234567'}
18
+ it("should produce 1 segment") { subject.size.should == 1 }
19
+ it("first segment should be 'abc1234567'") { subject[0].should == 'abc1234567' }
20
+ end
21
+
22
+ context "and string is 'abc123abc456'" do
23
+ let(:string) {'abc123abc456'}
24
+ it("should produce 2 segments") { subject.size.should == 2 }
25
+ it("first segment should be 'abc123abc4'") { subject[0].should == 'abc123abc4' }
26
+ it("first segment should be '56'") { subject[1].should == '56' }
27
+ end
28
+
29
+ context "and string is 'abc123abc456bbbcccddd'" do
30
+ let(:string) {'abc123abc456bbbcccddd'}
31
+ it("should produce 3 segments") { subject.size.should == 3 }
32
+ it("first segment should be 'abc123abc4'") { subject[0].should == 'abc123abc4' }
33
+ it("first segment should be '56bbbcccdd'") { subject[1].should == '56bbbcccdd' }
34
+ it("first segment should be 'd'") { subject[2].should == 'd' }
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,42 @@
1
+ describe Escort::SetupAccessor do
2
+ let(:setup) { Escort::SetupAccessor.new(app_configuration) }
3
+ let(:global_app_configuration) do
4
+ Escort::Setup::Dsl::Global.new do |app|
5
+ app.options do |opts|
6
+ opts.opt :option1, "option1", :short => :none, :long => '--option1', :type => :string
7
+ end
8
+
9
+ app.action do |options, arguments|
10
+ end
11
+ end
12
+ end
13
+
14
+ let(:command_app_configuration) do
15
+ end
16
+
17
+ let(:sub_command_app_configuration) do
18
+ end
19
+
20
+ #context is nil
21
+ #no context supplied at all
22
+ #context is not an array
23
+ describe '#options_for' do
24
+ subject {setup.options_for(context)}
25
+
26
+ context "when app has no sub commands" do
27
+ let(:app_configuration) {global_app_configuration}
28
+
29
+ context "and context is global" do
30
+ let(:context) { [] }
31
+ it(":option1 should be present") {subject[:option1].should_not be_nil}
32
+ end
33
+
34
+ context "and context is an unknown command" do
35
+ let(:context) { ['hello'] }
36
+ it("should not raise an exception") { expect{subject}.to_not raise_error }
37
+ it("result should be a hash") { subject.class.should == Hash }
38
+ it("result should be empty") { subject.should be_empty }
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,30 @@
1
+ describe Escort::Utils do
2
+ describe '::symbolize_keys' do
3
+ subject {Escort::Utils.symbolize_keys(hash)}
4
+
5
+ context "when single level hash" do
6
+ let(:hash) { {'a' => 1, :b => 2} }
7
+ it("the :a key should be a symbol") {subject[:a].should == 1}
8
+ it("the :b key should be a symbol") {subject[:b].should == 2}
9
+ end
10
+
11
+ context "when hash has nested hashes" do
12
+ let(:hash) { {'a' => 1, :b => {'c' => {'d' => 2}}} }
13
+ it("the :a key should be a symbol") {subject[:a].should == 1}
14
+ it("the nested keys, :b, :c and :d should all be symbols") {subject[:b][:c][:d].should == 2}
15
+ end
16
+ end
17
+
18
+ describe '::tokenize_option_string' do
19
+ subject {Escort::Utils.tokenize_option_string(option_string)}
20
+
21
+ context "when option string has short option, long option and argument" do
22
+ let(:option_string) {"-a 1 --foo='bar blah' yadda"}
23
+ it("tokenized string should have 4 values") {subject.size.should == 4}
24
+ it("the short option should be a separate token") {subject[0].should == '-a'}
25
+ it("the short option value should be a separate token") {subject[1].should == '1'}
26
+ it("the long option and value should be one token") {subject[2].should == '--foo=bar blah'}
27
+ it("the argument should be a separate token") {subject[3].should == 'yadda'}
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,22 @@
1
+ require 'escort'
2
+ #helpers
3
+ require 'helpers/exit_with_code_matcher'
4
+ require 'helpers/execute_action_matcher'
5
+ require 'helpers/give_option_to_action_with_value_matcher'
6
+ # This file was generated by the `rspec --init` command. Conventionally, all
7
+ # specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
8
+ # Require this file using `require "spec_helper"` to ensure that it is only
9
+ # loaded once.
10
+ #
11
+ # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
12
+ RSpec.configure do |config|
13
+ config.treat_symbols_as_metadata_keys_with_true_values = true
14
+ config.run_all_when_everything_filtered = true
15
+ config.filter_run :focus
16
+
17
+ # Run specs in random order to surface order dependencies. If you find an
18
+ # order dependency and want to debug it, you can fix the order by providing
19
+ # the seed, which is printed after each run.
20
+ # --seed 1234
21
+ config.order = 'random'
22
+ end
metadata CHANGED
@@ -1,19 +1,61 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: escort
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
5
- prerelease:
4
+ version: 0.1.0
6
5
  platform: ruby
7
6
  authors:
8
7
  - Alan Skorkin
9
8
  autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
- date: 2013-01-04 00:00:00.000000000 Z
13
- dependencies: []
14
- description: Basically we take the excellent Trollop command line options parser and
15
- dress it up a little with some DSL to make writing CLI apps a bit nicer, but still
16
- retain the full power of the awesome Trollop.
11
+ date: 2013-02-28 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rspec
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ! '>='
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ! '>='
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: fakefs
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ! '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ! '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rake
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ! '>='
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ! '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ description: Writing even complex command-line apps should be quick, easy and fun.
56
+ Escort takes the excellent Trollop option parser and adds a whole bunch of awesome
57
+ features to produce a library you will always want to turn to when a 'quick script'
58
+ is in order.
17
59
  email:
18
60
  - alan@skorks.com
19
61
  executables: []
@@ -21,40 +63,110 @@ extensions: []
21
63
  extra_rdoc_files: []
22
64
  files:
23
65
  - .gitignore
66
+ - .irbrc
67
+ - .rspec
68
+ - .rvmrc
24
69
  - Gemfile
25
70
  - LICENSE.txt
26
71
  - README.md
27
72
  - Rakefile
73
+ - TODO.md
28
74
  - escort.gemspec
75
+ - examples/1_1_basic.rb
76
+ - examples/1_2_basic_requires_arguments.rb
77
+ - examples/2_2_command.rb
78
+ - examples/2_2_command_requires_arguments.rb
79
+ - examples/2_3_nested_commands.rb
80
+ - examples/3_validations.rb
81
+ - examples/4_1_config_file.rb
82
+ - examples/argument_handling/basic.rb
83
+ - examples/argument_handling/basic_command.rb
84
+ - examples/argument_handling/no_arguments.rb
85
+ - examples/argument_handling/no_arguments_command.rb
86
+ - examples/basic/app.rb
87
+ - examples/command_aliases/app.rb
88
+ - examples/config_file/.apprc2
89
+ - examples/config_file/app.rb
90
+ - examples/config_file/sub_commands.rb
91
+ - examples/default_command/app.rb
92
+ - examples/sub_commands/app.rb
93
+ - examples/validation_basic/app.rb
29
94
  - lib/escort.rb
95
+ - lib/escort/action_command/base.rb
96
+ - lib/escort/action_command/escort_utility_command.rb
30
97
  - lib/escort/app.rb
31
- - lib/escort/command.rb
32
- - lib/escort/dsl.rb
33
- - lib/escort/global_dsl.rb
98
+ - lib/escort/arguments.rb
99
+ - lib/escort/auto_options.rb
100
+ - lib/escort/error/error.rb
101
+ - lib/escort/formatter/borderless_table.rb
102
+ - lib/escort/formatter/common.rb
103
+ - lib/escort/formatter/default_help_formatter.rb
104
+ - lib/escort/formatter/options.rb
105
+ - lib/escort/formatter/string_splitter.rb
106
+ - lib/escort/formatter/terminal.rb
107
+ - lib/escort/formatter/terminal_formatter.rb
108
+ - lib/escort/global_pre_parser.rb
109
+ - lib/escort/logger.rb
110
+ - lib/escort/option_parser.rb
111
+ - lib/escort/setup/configuration/generator.rb
112
+ - lib/escort/setup/configuration/instance.rb
113
+ - lib/escort/setup/configuration/loader.rb
114
+ - lib/escort/setup/configuration/locator/base.rb
115
+ - lib/escort/setup/configuration/locator/descending_to_home.rb
116
+ - lib/escort/setup/configuration/merge_tool.rb
117
+ - lib/escort/setup/configuration/reader.rb
118
+ - lib/escort/setup/configuration/writer.rb
119
+ - lib/escort/setup/dsl/action.rb
120
+ - lib/escort/setup/dsl/command.rb
121
+ - lib/escort/setup/dsl/config_file.rb
122
+ - lib/escort/setup/dsl/global.rb
123
+ - lib/escort/setup/dsl/options.rb
124
+ - lib/escort/setup/dsl/validations.rb
125
+ - lib/escort/setup_accessor.rb
34
126
  - lib/escort/trollop.rb
127
+ - lib/escort/utils.rb
128
+ - lib/escort/validator.rb
35
129
  - lib/escort/version.rb
130
+ - spec/helpers/execute_action_matcher.rb
131
+ - spec/helpers/exit_with_code_matcher.rb
132
+ - spec/helpers/give_option_to_action_with_value_matcher.rb
133
+ - spec/integration/basic_options_spec.rb
134
+ - spec/integration/basic_spec.rb
135
+ - spec/lib/escort/formatter/string_splitter_spec.rb
136
+ - spec/lib/escort/setup_accessor_spec.rb
137
+ - spec/lib/escort/utils_spec.rb
138
+ - spec/spec_helper.rb
36
139
  homepage: https://github.com/skorks/escort
37
140
  licenses: []
141
+ metadata: {}
38
142
  post_install_message:
39
143
  rdoc_options: []
40
144
  require_paths:
41
145
  - lib
42
146
  required_ruby_version: !ruby/object:Gem::Requirement
43
- none: false
44
147
  requirements:
45
148
  - - ! '>='
46
149
  - !ruby/object:Gem::Version
47
150
  version: '0'
48
151
  required_rubygems_version: !ruby/object:Gem::Requirement
49
- none: false
50
152
  requirements:
51
153
  - - ! '>='
52
154
  - !ruby/object:Gem::Version
53
155
  version: '0'
54
156
  requirements: []
55
157
  rubyforge_project:
56
- rubygems_version: 1.8.24
158
+ rubygems_version: 2.0.0
57
159
  signing_key:
58
- specification_version: 3
59
- summary: An escort is still a trollop just dressed up
60
- test_files: []
160
+ specification_version: 4
161
+ summary: A library that makes building command line apps in ruby so easy, you'll feel
162
+ like an expert is guiding you through it
163
+ test_files:
164
+ - spec/helpers/execute_action_matcher.rb
165
+ - spec/helpers/exit_with_code_matcher.rb
166
+ - spec/helpers/give_option_to_action_with_value_matcher.rb
167
+ - spec/integration/basic_options_spec.rb
168
+ - spec/integration/basic_spec.rb
169
+ - spec/lib/escort/formatter/string_splitter_spec.rb
170
+ - spec/lib/escort/setup_accessor_spec.rb
171
+ - spec/lib/escort/utils_spec.rb
172
+ - spec/spec_helper.rb
@@ -1,23 +0,0 @@
1
- module Escort
2
- class Command
3
- include Dsl
4
-
5
- attr_reader :current_options, :name
6
-
7
- def initialize(name, options_string)
8
- @name = name
9
- @options_string = options_string
10
- end
11
-
12
- def parse_options
13
- parser = Trollop::Parser.new(&@options_block)
14
- @current_options = Trollop::with_standard_exception_handling(parser) do
15
- parser.parse @options_string
16
- end
17
- end
18
-
19
- def perform_action(parent_command_options, remaining_arguments)
20
- @action_block.call(parent_command_options, @current_options, remaining_arguments)
21
- end
22
- end
23
- end
@@ -1,20 +0,0 @@
1
- module Escort
2
- module Dsl
3
- attr_reader :command_names
4
-
5
- def options(&block)
6
- @options_block = block
7
- end
8
-
9
- def command(name, &block)
10
- @command_names ||= []
11
- @command_names << name.to_s
12
- @command_blocks ||= {}
13
- @command_blocks[name.to_s] = block
14
- end
15
-
16
- def action(&block)
17
- @action_block = block
18
- end
19
- end
20
- end
@@ -1,11 +0,0 @@
1
- module Escort
2
- module GlobalDsl
3
- def before(&block)
4
- @before_block = block
5
- end
6
-
7
- def on_error(&block)
8
- @error_block = block
9
- end
10
- end
11
- end