rake_options 0.1.0 → 0.1.2
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.
- checksums.yaml +4 -4
- data/README.md +79 -50
- data/lib/rake_options/cli_parser.rb +43 -11
- data/lib/rake_options/help_generator.rb +17 -6
- data/lib/rake_options/template_engine.rb +8 -5
- data/lib/rake_options/version.rb +1 -1
- data/spec/integration/rake_options_integration_spec.rb +36 -40
- data/spec/rake_options/cli_parser_spec.rb +31 -27
- data/spec/rake_options/help_generator_spec.rb +7 -13
- data/spec/rake_options/template_engine_spec.rb +6 -6
- data/spec/rake_options_spec.rb +10 -9
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: fb24381876d415a7632d456afd8cace19474689f511ec98df623e65967ab1fe1
|
4
|
+
data.tar.gz: 22e3ef52a8f49fc4287a5f5b89ce302a7df74103aca8debcda6a0175452bc3f0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 87e1e28bd9dcf2ee316cbc839d00133d12d0098759f0fdb5e19ccf7ebaecf7299b9b4edf5afaa8fc65dc239fa875747f8e0e28904a66548d52d35c08d4948cbe
|
7
|
+
data.tar.gz: e20bfdf5cb10e26ba2cc9eae12184fa23ca9934980b5b31c96efa35a4f4a09d9d99f32437e393789fc315a6d36f9163dae65a970100646f88b00760f061d0483
|
data/README.md
CHANGED
@@ -31,23 +31,58 @@ require 'rake_options'
|
|
31
31
|
|
32
32
|
desc "Build with custom options"
|
33
33
|
task :build do
|
34
|
-
|
35
|
-
|
36
|
-
"
|
37
|
-
|
34
|
+
# Simple array configuration: [flag_name, type]
|
35
|
+
config = [
|
36
|
+
["with-mysql-lib", :string],
|
37
|
+
["enable-feature", :string],
|
38
|
+
["port", :integer]
|
39
|
+
]
|
38
40
|
|
39
41
|
options = RakeOptions.command_line_args(config)
|
40
42
|
|
41
43
|
puts "MySQL lib path: #{options['with-mysql-lib']}"
|
42
44
|
puts "Feature: #{options['enable-feature']}"
|
45
|
+
puts "Port: #{options['port']}" # Automatically cast to integer
|
43
46
|
end
|
44
47
|
```
|
45
48
|
|
46
49
|
Run with:
|
47
50
|
```bash
|
48
|
-
rake build -- --with-mysql-lib
|
51
|
+
rake build -- --with-mysql-lib=/usr/local/mysql/lib --enable-feature=caching --port=3000
|
49
52
|
```
|
50
53
|
|
54
|
+
For values with spaces, use quotes:
|
55
|
+
```bash
|
56
|
+
rake build -- --with-mysql-lib="/path/with spaces/lib"
|
57
|
+
```
|
58
|
+
|
59
|
+
### Type Casting
|
60
|
+
|
61
|
+
RakeOptions automatically casts values to the specified type:
|
62
|
+
|
63
|
+
```ruby
|
64
|
+
config = [
|
65
|
+
["port", :integer],
|
66
|
+
["enabled", :boolean],
|
67
|
+
["ratio", :float],
|
68
|
+
["name", :string]
|
69
|
+
]
|
70
|
+
|
71
|
+
options = RakeOptions.command_line_args(config)
|
72
|
+
|
73
|
+
# Values are automatically cast:
|
74
|
+
options['port'] # => 3000 (Integer)
|
75
|
+
options['enabled'] # => true (Boolean)
|
76
|
+
options['ratio'] # => 1.5 (Float)
|
77
|
+
options['name'] # => "myapp" (String)
|
78
|
+
```
|
79
|
+
|
80
|
+
Supported types:
|
81
|
+
- `:string` - String values (default)
|
82
|
+
- `:integer` or `:int` - Integer values
|
83
|
+
- `:float` - Float values
|
84
|
+
- `:boolean` or `:bool` - Boolean values (true/false)
|
85
|
+
|
51
86
|
### Bracket-Style Arguments
|
52
87
|
|
53
88
|
```ruby
|
@@ -55,10 +90,10 @@ require 'rake_options'
|
|
55
90
|
|
56
91
|
desc "Deploy with bracket notation"
|
57
92
|
task :deploy do
|
58
|
-
config =
|
59
|
-
"environment"
|
60
|
-
"region"
|
61
|
-
|
93
|
+
config = [
|
94
|
+
["environment", :string],
|
95
|
+
["region", :string]
|
96
|
+
]
|
62
97
|
|
63
98
|
options = RakeOptions.command_line_args(config, notation: :bracket)
|
64
99
|
|
@@ -71,17 +106,6 @@ Run with:
|
|
71
106
|
rake deploy [environment=production] [region=us-west-2]
|
72
107
|
```
|
73
108
|
|
74
|
-
### Multiple Variables in One Template
|
75
|
-
|
76
|
-
```ruby
|
77
|
-
config = {
|
78
|
-
"database" => "--config $file --env $environment"
|
79
|
-
}
|
80
|
-
|
81
|
-
options = RakeOptions.command_line_args(config)
|
82
|
-
# Extracts both file and environment from: --config database.yml --env production
|
83
|
-
```
|
84
|
-
|
85
109
|
### Automatic Help Documentation
|
86
110
|
|
87
111
|
```ruby
|
@@ -91,18 +115,20 @@ readme_content = <<~HELP
|
|
91
115
|
Build Task Help
|
92
116
|
|
93
117
|
Available options:
|
94
|
-
--with-mysql-lib
|
95
|
-
--enable-feature
|
118
|
+
--with-mysql-lib=PATH Specify MySQL library path (string)
|
119
|
+
--enable-feature=NAME Enable a specific feature (string)
|
120
|
+
--port=NUMBER Port number (integer)
|
96
121
|
HELP
|
97
122
|
|
98
123
|
RakeOptions.initialize_readme(readme_content)
|
99
124
|
|
100
125
|
desc "Build with help support"
|
101
126
|
task :build do
|
102
|
-
config =
|
103
|
-
"with-mysql-lib"
|
104
|
-
"enable-feature"
|
105
|
-
|
127
|
+
config = [
|
128
|
+
["with-mysql-lib", :string],
|
129
|
+
["enable-feature", :string],
|
130
|
+
["port", :integer]
|
131
|
+
]
|
106
132
|
|
107
133
|
options = RakeOptions.command_line_args(config)
|
108
134
|
# Your build logic here
|
@@ -128,29 +154,32 @@ options[:with_mysql_lib]
|
|
128
154
|
|
129
155
|
## Configuration Format
|
130
156
|
|
131
|
-
The configuration
|
157
|
+
The configuration is a simple array of tuples:
|
132
158
|
|
133
159
|
```ruby
|
134
|
-
|
135
|
-
"
|
136
|
-
|
160
|
+
[
|
161
|
+
["flag-name", :type],
|
162
|
+
["another-flag", :type]
|
163
|
+
]
|
137
164
|
```
|
138
165
|
|
139
|
-
- **
|
140
|
-
- **
|
141
|
-
- **Variables**: Prefixed with `$` to indicate where values should be extracted
|
166
|
+
- **flag-name**: The CLI flag name (will become `--flag-name`)
|
167
|
+
- **type**: The data type (`:string`, `:integer`, `:float`, `:boolean`)
|
142
168
|
|
143
|
-
###
|
169
|
+
### Examples
|
144
170
|
|
145
171
|
```ruby
|
146
|
-
#
|
147
|
-
"mysql-path"
|
172
|
+
# String values
|
173
|
+
["mysql-path", :string]
|
174
|
+
|
175
|
+
# Integer values
|
176
|
+
["port", :integer]
|
148
177
|
|
149
|
-
#
|
150
|
-
"
|
178
|
+
# Boolean flags
|
179
|
+
["enabled", :boolean]
|
151
180
|
|
152
|
-
#
|
153
|
-
"
|
181
|
+
# Float values
|
182
|
+
["ratio", :float]
|
154
183
|
```
|
155
184
|
|
156
185
|
## Notation Styles
|
@@ -162,8 +191,8 @@ options = RakeOptions.command_line_args(config, notation: :cli)
|
|
162
191
|
```
|
163
192
|
|
164
193
|
Supports:
|
165
|
-
- `--flag
|
166
|
-
- `--flag
|
194
|
+
- `--flag=value`
|
195
|
+
- `--flag="value with spaces"`
|
167
196
|
- Multiple flags in one command
|
168
197
|
|
169
198
|
### Bracket Notation
|
@@ -228,20 +257,20 @@ rake task -- --help
|
|
228
257
|
|
229
258
|
**Solution**: Use quotes around values with spaces:
|
230
259
|
```bash
|
231
|
-
rake task -- --path
|
260
|
+
rake task -- --path="/path/with spaces"
|
232
261
|
```
|
233
262
|
|
234
|
-
###
|
263
|
+
### Flag name mismatch
|
235
264
|
|
236
|
-
**Problem**:
|
265
|
+
**Problem**: Arguments aren't being recognized.
|
237
266
|
|
238
|
-
**Solution**: Ensure
|
267
|
+
**Solution**: Ensure the flag name in ARGV matches the config:
|
239
268
|
```ruby
|
240
|
-
#
|
241
|
-
"option"
|
269
|
+
# Config
|
270
|
+
["my-option", :string]
|
242
271
|
|
243
|
-
# Command line must match
|
244
|
-
rake task -- --option
|
272
|
+
# Command line must match exactly
|
273
|
+
rake task -- --my-option=myvalue
|
245
274
|
```
|
246
275
|
|
247
276
|
## Requirements
|
@@ -5,12 +5,14 @@ require_relative "template_engine"
|
|
5
5
|
module RakeOptions
|
6
6
|
class CLIParser
|
7
7
|
def initialize(config)
|
8
|
-
@config = config
|
8
|
+
@config = normalize_config(config)
|
9
9
|
@parsed_templates = {}
|
10
10
|
|
11
11
|
# Pre-parse all templates
|
12
|
-
@config.each do |key,
|
13
|
-
|
12
|
+
@config.each do |key, type|
|
13
|
+
# Auto-construct the full template from the key
|
14
|
+
full_template = "--#{key} $value"
|
15
|
+
@parsed_templates[key] = TemplateEngine.parse_template(full_template)
|
14
16
|
end
|
15
17
|
end
|
16
18
|
|
@@ -20,18 +22,13 @@ module RakeOptions
|
|
20
22
|
def parse(argv = ARGV)
|
21
23
|
result = {}
|
22
24
|
|
23
|
-
@config.each do |key,
|
25
|
+
@config.each do |key, type|
|
24
26
|
parsed_template = @parsed_templates[key]
|
25
27
|
extracted = TemplateEngine.extract_values(argv, parsed_template)
|
26
28
|
|
27
29
|
if extracted && !extracted.empty?
|
28
|
-
|
29
|
-
|
30
|
-
result[key] = extracted.values.first
|
31
|
-
else
|
32
|
-
# For multiple variables, store the hash
|
33
|
-
result[key] = extracted
|
34
|
-
end
|
30
|
+
raw_value = extracted.values.first
|
31
|
+
result[key] = cast_value(raw_value, type)
|
35
32
|
else
|
36
33
|
result[key] = nil
|
37
34
|
end
|
@@ -39,5 +36,40 @@ module RakeOptions
|
|
39
36
|
|
40
37
|
result
|
41
38
|
end
|
39
|
+
|
40
|
+
private
|
41
|
+
|
42
|
+
# Normalize config to hash format
|
43
|
+
# @param config [Array, Hash] Configuration
|
44
|
+
# @return [Hash] Normalized configuration
|
45
|
+
def normalize_config(config)
|
46
|
+
if config.is_a?(Array)
|
47
|
+
# Convert array of tuples to hash
|
48
|
+
config.to_h
|
49
|
+
else
|
50
|
+
config
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
# Cast value to specified type
|
55
|
+
# @param value [String] Raw string value
|
56
|
+
# @param type [Symbol] Target type
|
57
|
+
# @return [Object] Casted value
|
58
|
+
def cast_value(value, type)
|
59
|
+
return nil if value.nil?
|
60
|
+
|
61
|
+
case type
|
62
|
+
when :string
|
63
|
+
value.to_s
|
64
|
+
when :integer, :int
|
65
|
+
value.to_i
|
66
|
+
when :float
|
67
|
+
value.to_f
|
68
|
+
when :boolean, :bool
|
69
|
+
value.downcase == 'true' || value == '1'
|
70
|
+
else
|
71
|
+
value
|
72
|
+
end
|
73
|
+
end
|
42
74
|
end
|
43
75
|
end
|
@@ -3,7 +3,7 @@
|
|
3
3
|
module RakeOptions
|
4
4
|
class HelpGenerator
|
5
5
|
def initialize(config, readme_content = nil)
|
6
|
-
@config = config
|
6
|
+
@config = normalize_config(config)
|
7
7
|
@readme_content = readme_content
|
8
8
|
end
|
9
9
|
|
@@ -26,13 +26,24 @@ module RakeOptions
|
|
26
26
|
end
|
27
27
|
end
|
28
28
|
|
29
|
+
# Normalize config to hash format
|
30
|
+
# @param config [Array, Hash] Configuration
|
31
|
+
# @return [Hash] Normalized configuration
|
32
|
+
def normalize_config(config)
|
33
|
+
if config.is_a?(Array)
|
34
|
+
config.to_h
|
35
|
+
else
|
36
|
+
config
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
29
40
|
# Auto-generate help from config
|
30
41
|
# @return [String] Auto-generated help text
|
31
42
|
def auto_generate_help
|
32
43
|
help_text = "Available Options:\n\n"
|
33
44
|
|
34
|
-
@config.each do |key,
|
35
|
-
help_text += format_option(key,
|
45
|
+
@config.each do |key, type|
|
46
|
+
help_text += format_option(key, type)
|
36
47
|
end
|
37
48
|
|
38
49
|
help_text
|
@@ -40,10 +51,10 @@ module RakeOptions
|
|
40
51
|
|
41
52
|
# Format individual option for display
|
42
53
|
# @param key [String] Option key
|
43
|
-
# @param
|
54
|
+
# @param type [Symbol] Value type
|
44
55
|
# @return [String] Formatted option line
|
45
|
-
def format_option(key,
|
46
|
-
"
|
56
|
+
def format_option(key, type)
|
57
|
+
" --#{key}=VALUE".ljust(42) + "(#{type})\n"
|
47
58
|
end
|
48
59
|
end
|
49
60
|
end
|
@@ -57,12 +57,15 @@ module RakeOptions
|
|
57
57
|
# @return [Regexp] Regex pattern for matching
|
58
58
|
def self.build_pattern(template, variables)
|
59
59
|
# Replace $variables with capture groups that match:
|
60
|
-
# -
|
61
|
-
#
|
62
|
-
pattern_str = template.gsub(/\$\w+/, '(?:"([^"]+)"|(\S+))')
|
60
|
+
# - Values after = sign: --flag=value
|
61
|
+
# Pattern matches: --flag=value or --flag="value with spaces"
|
63
62
|
|
64
|
-
#
|
65
|
-
pattern_str =
|
63
|
+
# First, escape the template
|
64
|
+
pattern_str = Regexp.escape(template)
|
65
|
+
|
66
|
+
# Then replace escaped $variable patterns with our capture group
|
67
|
+
# The pattern after escaping looks like: \$variable
|
68
|
+
pattern_str = pattern_str.gsub(/\\ \\\$\w+/, '=(?:"([^"]+)"|([^\s]+))')
|
66
69
|
|
67
70
|
Regexp.new(pattern_str)
|
68
71
|
end
|
data/lib/rake_options/version.rb
CHANGED
@@ -5,25 +5,25 @@ require "spec_helper"
|
|
5
5
|
RSpec.describe "RakeOptions Integration Tests" do
|
6
6
|
describe "Full CLI parsing workflow" do
|
7
7
|
let(:config) do
|
8
|
-
|
9
|
-
"with-mysql-lib"
|
10
|
-
"enable-feature"
|
11
|
-
"port"
|
12
|
-
|
8
|
+
[
|
9
|
+
["with-mysql-lib", :string],
|
10
|
+
["enable-feature", :string],
|
11
|
+
["port", :integer]
|
12
|
+
]
|
13
13
|
end
|
14
14
|
|
15
15
|
it "parses multiple CLI arguments in one invocation" do
|
16
|
-
stub_const("ARGV", ["--with-mysql-lib
|
16
|
+
stub_const("ARGV", ["--with-mysql-lib=/usr/local/lib", "--enable-feature=caching", "--port=3000"])
|
17
17
|
|
18
18
|
result = RakeOptions.command_line_args(config, notation: :cli)
|
19
19
|
|
20
20
|
expect(result["with-mysql-lib"]).to eq("/usr/local/lib")
|
21
21
|
expect(result["enable-feature"]).to eq("caching")
|
22
|
-
expect(result["port"]).to eq(
|
22
|
+
expect(result["port"]).to eq(3000)
|
23
23
|
end
|
24
24
|
|
25
25
|
it "handles partial arguments gracefully" do
|
26
|
-
stub_const("ARGV", ["--with-mysql-lib
|
26
|
+
stub_const("ARGV", ["--with-mysql-lib=/usr/local/lib"])
|
27
27
|
|
28
28
|
result = RakeOptions.command_line_args(config, notation: :cli)
|
29
29
|
|
@@ -33,7 +33,7 @@ RSpec.describe "RakeOptions Integration Tests" do
|
|
33
33
|
end
|
34
34
|
|
35
35
|
it "supports quoted values with spaces" do
|
36
|
-
stub_const("ARGV", [
|
36
|
+
stub_const("ARGV", ['--with-mysql-lib="/path/with spaces/lib"'])
|
37
37
|
|
38
38
|
result = RakeOptions.command_line_args(config, notation: :cli)
|
39
39
|
|
@@ -41,7 +41,7 @@ RSpec.describe "RakeOptions Integration Tests" do
|
|
41
41
|
end
|
42
42
|
|
43
43
|
it "allows symbol key access" do
|
44
|
-
stub_const("ARGV", ["--with-mysql-lib
|
44
|
+
stub_const("ARGV", ["--with-mysql-lib=/usr/local/lib"])
|
45
45
|
|
46
46
|
result = RakeOptions.command_line_args(config, notation: :cli)
|
47
47
|
|
@@ -134,20 +134,18 @@ RSpec.describe "RakeOptions Integration Tests" do
|
|
134
134
|
|
135
135
|
describe "Mixed scenarios" do
|
136
136
|
let(:config) do
|
137
|
-
|
138
|
-
"database"
|
139
|
-
"verbose"
|
140
|
-
|
137
|
+
[
|
138
|
+
["database", :string],
|
139
|
+
["verbose", :string]
|
140
|
+
]
|
141
141
|
end
|
142
142
|
|
143
|
-
it "handles
|
144
|
-
stub_const("ARGV", ["--
|
143
|
+
it "handles multiple arguments" do
|
144
|
+
stub_const("ARGV", ["--database=mydb", "--verbose=debug"])
|
145
145
|
|
146
146
|
result = RakeOptions.command_line_args(config, notation: :cli)
|
147
147
|
|
148
|
-
expect(result["database"]).to
|
149
|
-
expect(result["database"]["file"]).to eq("database.yml")
|
150
|
-
expect(result["database"]["environment"]).to eq("production")
|
148
|
+
expect(result["database"]).to eq("mydb")
|
151
149
|
expect(result["verbose"]).to eq("debug")
|
152
150
|
end
|
153
151
|
|
@@ -161,7 +159,7 @@ RSpec.describe "RakeOptions Integration Tests" do
|
|
161
159
|
end
|
162
160
|
|
163
161
|
it "ignores unrecognized arguments" do
|
164
|
-
stub_const("ARGV", ["--unknown-flag
|
162
|
+
stub_const("ARGV", ["--unknown-flag=value", "--verbose=info"])
|
165
163
|
|
166
164
|
result = RakeOptions.command_line_args(config, notation: :cli)
|
167
165
|
|
@@ -172,20 +170,18 @@ RSpec.describe "RakeOptions Integration Tests" do
|
|
172
170
|
|
173
171
|
describe "Error scenarios" do
|
174
172
|
let(:config) do
|
175
|
-
|
176
|
-
"option" => "--option $value"
|
177
|
-
}
|
173
|
+
[["option", :string]]
|
178
174
|
end
|
179
175
|
|
180
176
|
it "raises InvalidNotationError for unsupported notation" do
|
181
|
-
stub_const("ARGV", ["--option
|
177
|
+
stub_const("ARGV", ["--option=value"])
|
182
178
|
|
183
179
|
expect { RakeOptions.command_line_args(config, notation: :invalid) }
|
184
180
|
.to raise_error(RakeOptions::InvalidNotationError, /Invalid notation/)
|
185
181
|
end
|
186
182
|
|
187
183
|
it "provides clear error message with supported notations" do
|
188
|
-
stub_const("ARGV", ["--option
|
184
|
+
stub_const("ARGV", ["--option=value"])
|
189
185
|
|
190
186
|
expect { RakeOptions.command_line_args(config, notation: :xml) }
|
191
187
|
.to raise_error(RakeOptions::InvalidNotationError, /:cli, :bracket/)
|
@@ -195,16 +191,16 @@ RSpec.describe "RakeOptions Integration Tests" do
|
|
195
191
|
describe "Real-world usage scenarios" do
|
196
192
|
context "deployment task" do
|
197
193
|
let(:deploy_config) do
|
198
|
-
|
199
|
-
"environment"
|
200
|
-
"region"
|
201
|
-
"version"
|
202
|
-
"dry-run"
|
203
|
-
|
194
|
+
[
|
195
|
+
["environment", :string],
|
196
|
+
["region", :string],
|
197
|
+
["version", :string],
|
198
|
+
["dry-run", :boolean]
|
199
|
+
]
|
204
200
|
end
|
205
201
|
|
206
202
|
it "handles typical deployment command" do
|
207
|
-
stub_const("ARGV", ["--
|
203
|
+
stub_const("ARGV", ["--environment=production", "--region=us-east-1", "--version=v1.2.3"])
|
208
204
|
|
209
205
|
result = RakeOptions.command_line_args(deploy_config)
|
210
206
|
|
@@ -217,18 +213,18 @@ RSpec.describe "RakeOptions Integration Tests" do
|
|
217
213
|
|
218
214
|
context "build task" do
|
219
215
|
let(:build_config) do
|
220
|
-
|
221
|
-
"with-mysql"
|
222
|
-
"with-ssl"
|
223
|
-
"prefix"
|
224
|
-
|
216
|
+
[
|
217
|
+
["with-mysql", :string],
|
218
|
+
["with-ssl", :string],
|
219
|
+
["prefix", :string]
|
220
|
+
]
|
225
221
|
end
|
226
222
|
|
227
223
|
it "handles build configuration" do
|
228
224
|
stub_const("ARGV", [
|
229
|
-
"--with-mysql
|
230
|
-
"--with-ssl
|
231
|
-
"--prefix
|
225
|
+
"--with-mysql=/usr/local/mysql/lib",
|
226
|
+
"--with-ssl=/usr/local/ssl/lib",
|
227
|
+
"--prefix=/opt/myapp"
|
232
228
|
])
|
233
229
|
|
234
230
|
result = RakeOptions.command_line_args(build_config)
|
@@ -7,14 +7,12 @@ RSpec.describe RakeOptions::CLIParser do
|
|
7
7
|
describe "#parse" do
|
8
8
|
context "with single flag" do
|
9
9
|
let(:config) do
|
10
|
-
|
11
|
-
"with-mysql-lib" => "--with-mysql-lib $path"
|
12
|
-
}
|
10
|
+
[["with-mysql-lib", :string]]
|
13
11
|
end
|
14
12
|
let(:parser) { described_class.new(config) }
|
15
13
|
|
16
14
|
it "parses single flag with value" do
|
17
|
-
argv = ["--with-mysql-lib
|
15
|
+
argv = ["--with-mysql-lib=/usr/local/mysql/lib"]
|
18
16
|
result = parser.parse(argv)
|
19
17
|
|
20
18
|
expect(result["with-mysql-lib"]).to eq("/usr/local/mysql/lib")
|
@@ -30,15 +28,12 @@ RSpec.describe RakeOptions::CLIParser do
|
|
30
28
|
|
31
29
|
context "with multiple flags" do
|
32
30
|
let(:config) do
|
33
|
-
|
34
|
-
"with-mysql-lib" => "--with-mysql-lib $path",
|
35
|
-
"enable-feature" => "--enable-feature $name"
|
36
|
-
}
|
31
|
+
[["with-mysql-lib", :string], ["enable-feature", :string]]
|
37
32
|
end
|
38
33
|
let(:parser) { described_class.new(config) }
|
39
34
|
|
40
35
|
it "parses multiple flags in one invocation" do
|
41
|
-
argv = ["--with-mysql-lib
|
36
|
+
argv = ["--with-mysql-lib=/usr/local/lib", "--enable-feature=caching"]
|
42
37
|
result = parser.parse(argv)
|
43
38
|
|
44
39
|
expect(result["with-mysql-lib"]).to eq("/usr/local/lib")
|
@@ -46,7 +41,7 @@ RSpec.describe RakeOptions::CLIParser do
|
|
46
41
|
end
|
47
42
|
|
48
43
|
it "handles partial arguments" do
|
49
|
-
argv = ["--with-mysql-lib
|
44
|
+
argv = ["--with-mysql-lib=/usr/local/lib"]
|
50
45
|
result = parser.parse(argv)
|
51
46
|
|
52
47
|
expect(result["with-mysql-lib"]).to eq("/usr/local/lib")
|
@@ -56,14 +51,12 @@ RSpec.describe RakeOptions::CLIParser do
|
|
56
51
|
|
57
52
|
context "with quoted values" do
|
58
53
|
let(:config) do
|
59
|
-
|
60
|
-
"message" => "--message $text"
|
61
|
-
}
|
54
|
+
[["message", :string]]
|
62
55
|
end
|
63
56
|
let(:parser) { described_class.new(config) }
|
64
57
|
|
65
58
|
it "handles quoted values with spaces" do
|
66
|
-
argv = [
|
59
|
+
argv = ['--message="Hello World"']
|
67
60
|
result = parser.parse(argv)
|
68
61
|
|
69
62
|
expect(result["message"]).to eq("Hello World")
|
@@ -72,14 +65,12 @@ RSpec.describe RakeOptions::CLIParser do
|
|
72
65
|
|
73
66
|
context "with unknown flags" do
|
74
67
|
let(:config) do
|
75
|
-
|
76
|
-
"known-flag" => "--known-flag $value"
|
77
|
-
}
|
68
|
+
[["known-flag", :string]]
|
78
69
|
end
|
79
70
|
let(:parser) { described_class.new(config) }
|
80
71
|
|
81
72
|
it "ignores unknown flags without raising errors" do
|
82
|
-
argv = ["--unknown-flag
|
73
|
+
argv = ["--unknown-flag=value", "--known-flag=test"]
|
83
74
|
|
84
75
|
expect { parser.parse(argv) }.not_to raise_error
|
85
76
|
result = parser.parse(argv)
|
@@ -87,21 +78,34 @@ RSpec.describe RakeOptions::CLIParser do
|
|
87
78
|
end
|
88
79
|
end
|
89
80
|
|
90
|
-
context "with
|
81
|
+
context "with type casting" do
|
91
82
|
let(:config) do
|
92
|
-
|
93
|
-
"database" => "--config $file --env $environment"
|
94
|
-
}
|
83
|
+
[["port", :integer], ["enabled", :boolean], ["ratio", :float]]
|
95
84
|
end
|
96
85
|
let(:parser) { described_class.new(config) }
|
97
86
|
|
98
|
-
it "
|
99
|
-
argv = ["--
|
87
|
+
it "casts integer values" do
|
88
|
+
argv = ["--port=3000"]
|
100
89
|
result = parser.parse(argv)
|
101
90
|
|
102
|
-
expect(result["
|
103
|
-
expect(result["
|
104
|
-
|
91
|
+
expect(result["port"]).to eq(3000)
|
92
|
+
expect(result["port"]).to be_a(Integer)
|
93
|
+
end
|
94
|
+
|
95
|
+
it "casts boolean values" do
|
96
|
+
argv = ["--enabled=true"]
|
97
|
+
result = parser.parse(argv)
|
98
|
+
|
99
|
+
expect(result["enabled"]).to eq(true)
|
100
|
+
expect(result["enabled"]).to be_a(TrueClass)
|
101
|
+
end
|
102
|
+
|
103
|
+
it "casts float values" do
|
104
|
+
argv = ["--ratio=1.5"]
|
105
|
+
result = parser.parse(argv)
|
106
|
+
|
107
|
+
expect(result["ratio"]).to eq(1.5)
|
108
|
+
expect(result["ratio"]).to be_a(Float)
|
105
109
|
end
|
106
110
|
end
|
107
111
|
end
|
@@ -6,10 +6,7 @@ require "rake_options/help_generator"
|
|
6
6
|
RSpec.describe RakeOptions::HelpGenerator do
|
7
7
|
describe "#display_and_exit" do
|
8
8
|
let(:config) do
|
9
|
-
|
10
|
-
"with-mysql-lib" => "--with-mysql-lib $path",
|
11
|
-
"enable-feature" => "--enable-feature $name"
|
12
|
-
}
|
9
|
+
[["with-mysql-lib", :string], ["enable-feature", :string]]
|
13
10
|
end
|
14
11
|
|
15
12
|
context "with custom README" do
|
@@ -46,10 +43,7 @@ RSpec.describe RakeOptions::HelpGenerator do
|
|
46
43
|
|
47
44
|
describe "#generate_help_text" do
|
48
45
|
let(:config) do
|
49
|
-
|
50
|
-
"option1" => "--option1 $value",
|
51
|
-
"option2" => "--option2 $value"
|
52
|
-
}
|
46
|
+
[["option1", :string], ["option2", :string]]
|
53
47
|
end
|
54
48
|
|
55
49
|
context "with custom README" do
|
@@ -75,12 +69,12 @@ RSpec.describe RakeOptions::HelpGenerator do
|
|
75
69
|
end
|
76
70
|
|
77
71
|
describe "#format_option" do
|
78
|
-
let(:generator) { described_class.new(
|
72
|
+
let(:generator) { described_class.new([]) }
|
79
73
|
|
80
|
-
it "formats option with key and
|
81
|
-
formatted = generator.send(:format_option, "my-option",
|
82
|
-
expect(formatted).to include("--my-option
|
83
|
-
expect(formatted).to include("
|
74
|
+
it "formats option with key and type" do
|
75
|
+
formatted = generator.send(:format_option, "my-option", :string)
|
76
|
+
expect(formatted).to include("--my-option")
|
77
|
+
expect(formatted).to include("string")
|
84
78
|
end
|
85
79
|
end
|
86
80
|
end
|
@@ -41,17 +41,17 @@ RSpec.describe RakeOptions::TemplateEngine do
|
|
41
41
|
let(:parsed_template) { described_class.parse_template("--with-mysql-lib $path") }
|
42
42
|
|
43
43
|
it "extracts value from matching input" do
|
44
|
-
input = ["--with-mysql-lib
|
44
|
+
input = ["--with-mysql-lib=/usr/local/mysql/lib"]
|
45
45
|
result = described_class.extract_values(input, parsed_template)
|
46
46
|
|
47
47
|
expect(result).to eq({ "path" => "/usr/local/mysql/lib" })
|
48
48
|
end
|
49
49
|
|
50
50
|
it "extracts quoted value with spaces" do
|
51
|
-
input = [
|
51
|
+
input = ['--with-mysql-lib="path with spaces"']
|
52
52
|
result = described_class.extract_values(input, parsed_template)
|
53
53
|
|
54
|
-
expect(result["path"]).to
|
54
|
+
expect(result["path"]).to eq("path with spaces")
|
55
55
|
end
|
56
56
|
|
57
57
|
it "returns nil for non-matching input" do
|
@@ -66,7 +66,7 @@ RSpec.describe RakeOptions::TemplateEngine do
|
|
66
66
|
let(:parsed_template) { described_class.parse_template("--config $file --env $environment") }
|
67
67
|
|
68
68
|
it "extracts multiple values from matching input" do
|
69
|
-
input = ["--config
|
69
|
+
input = ["--config=database.yml", "--env=production"]
|
70
70
|
result = described_class.extract_values(input, parsed_template)
|
71
71
|
|
72
72
|
expect(result["file"]).to eq("database.yml")
|
@@ -98,7 +98,7 @@ RSpec.describe RakeOptions::TemplateEngine do
|
|
98
98
|
pattern = described_class.send(:build_pattern, "--with-mysql-lib $path", variables)
|
99
99
|
|
100
100
|
expect(pattern).to be_a(Regexp)
|
101
|
-
expect("--with-mysql-lib
|
101
|
+
expect("--with-mysql-lib=/usr/local/lib").to match(pattern)
|
102
102
|
end
|
103
103
|
|
104
104
|
it "creates pattern for multiple variables" do
|
@@ -106,7 +106,7 @@ RSpec.describe RakeOptions::TemplateEngine do
|
|
106
106
|
pattern = described_class.send(:build_pattern, "--config $file --env $env", variables)
|
107
107
|
|
108
108
|
expect(pattern).to be_a(Regexp)
|
109
|
-
expect("--config
|
109
|
+
expect("--config=db.yml --env=prod").to match(pattern)
|
110
110
|
end
|
111
111
|
end
|
112
112
|
end
|
data/spec/rake_options_spec.rb
CHANGED
@@ -4,23 +4,20 @@ require "spec_helper"
|
|
4
4
|
|
5
5
|
RSpec.describe RakeOptions do
|
6
6
|
let(:config) do
|
7
|
-
|
8
|
-
"with-mysql-lib" => "--with-mysql-lib $path",
|
9
|
-
"enable-feature" => "--enable-feature $name"
|
10
|
-
}
|
7
|
+
[["with-mysql-lib", :string], ["enable-feature", :string]]
|
11
8
|
end
|
12
9
|
|
13
10
|
describe ".command_line_args" do
|
14
11
|
context "with CLI notation" do
|
15
12
|
it "parses CLI-style arguments" do
|
16
|
-
stub_const("ARGV", ["--with-mysql-lib
|
13
|
+
stub_const("ARGV", ["--with-mysql-lib=/usr/local/lib"])
|
17
14
|
result = described_class.command_line_args(config, notation: :cli)
|
18
15
|
|
19
16
|
expect(result["with-mysql-lib"]).to eq("/usr/local/lib")
|
20
17
|
end
|
21
18
|
|
22
19
|
it "supports symbol key access" do
|
23
|
-
stub_const("ARGV", ["--with-mysql-lib
|
20
|
+
stub_const("ARGV", ["--with-mysql-lib=/usr/local/lib"])
|
24
21
|
result = described_class.command_line_args(config, notation: :cli)
|
25
22
|
|
26
23
|
expect(result[:with_mysql_lib]).to eq("/usr/local/lib")
|
@@ -38,7 +35,7 @@ RSpec.describe RakeOptions do
|
|
38
35
|
|
39
36
|
context "with default notation" do
|
40
37
|
it "defaults to CLI notation" do
|
41
|
-
stub_const("ARGV", ["--with-mysql-lib
|
38
|
+
stub_const("ARGV", ["--with-mysql-lib=/usr/local/lib"])
|
42
39
|
result = described_class.command_line_args(config)
|
43
40
|
|
44
41
|
expect(result["with-mysql-lib"]).to eq("/usr/local/lib")
|
@@ -57,7 +54,7 @@ RSpec.describe RakeOptions do
|
|
57
54
|
|
58
55
|
context "return value" do
|
59
56
|
it "returns HashWithIndifferentAccess" do
|
60
|
-
stub_const("ARGV", ["--with-mysql-lib
|
57
|
+
stub_const("ARGV", ["--with-mysql-lib=/usr/local/lib"])
|
61
58
|
result = described_class.command_line_args(config)
|
62
59
|
|
63
60
|
expect(result).to be_a(RakeOptions::HashWithIndifferentAccess)
|
@@ -66,6 +63,10 @@ RSpec.describe RakeOptions do
|
|
66
63
|
end
|
67
64
|
|
68
65
|
describe ".initialize_readme" do
|
66
|
+
let(:simple_config) do
|
67
|
+
[["option", :string]]
|
68
|
+
end
|
69
|
+
|
69
70
|
it "stores readme content" do
|
70
71
|
readme = "Custom help text"
|
71
72
|
described_class.initialize_readme(readme)
|
@@ -78,7 +79,7 @@ RSpec.describe RakeOptions do
|
|
78
79
|
described_class.initialize_readme(readme)
|
79
80
|
stub_const("ARGV", ["--help"])
|
80
81
|
|
81
|
-
expect { described_class.command_line_args(
|
82
|
+
expect { described_class.command_line_args(simple_config) }
|
82
83
|
.to output(/My Custom Help/).to_stdout
|
83
84
|
.and raise_error(SystemExit)
|
84
85
|
end
|