escort 0.0.1 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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