rake_options 0.1.1 → 0.1.3

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f139479b6f1399fc8d375f81f8b0d55c0ee617f38a029754e9ae1a70099015bb
4
- data.tar.gz: 744d888d606e102fd3b2e442c89596ac347c8397c30004808ee4d7d6b8416464
3
+ metadata.gz: c23f2f501224d1849ee5255aafb6f023e12f6bacdeacdcd2a4909eb711e73adb
4
+ data.tar.gz: eaaa2f161b92704669317004e64dfee3267f4473095a561be9b8c71354d6362e
5
5
  SHA512:
6
- metadata.gz: 27a9ba60af3907fb6b346fe00f386e02ed976ec3055b330a68848e42a911183b493fdd51f4a1584df90545bdb569339b5899a2da4ffe0be94beaaba96b0a2713
7
- data.tar.gz: 9c3f3056b9abfc8ed41e40991751c95a04c6e56d6d3cb3f4f4c76071930d4d87d5535ad4d1f9c31921acac6d12d14ed1d9ccef6d161b8a94c97f7d78b0475c1d
6
+ metadata.gz: b507cb81d6ae6518115b35ce028779d7dbccbdebac5d328970ff2935269cf4d46041bc45927333d39efe897ede7646087873401095295635853e0d6e1a542560
7
+ data.tar.gz: 54a8901e28628730a2a15c8a2b53a06a89bdc0e1c621aa437dcef36890f4ee6f8c7cff07c32b3d299a6ce42360137661266426d1323995caa001fdd17052a67a
data/README.md CHANGED
@@ -31,21 +31,24 @@ require 'rake_options'
31
31
 
32
32
  desc "Build with custom options"
33
33
  task :build do
34
- config = {
35
- "with-mysql-lib" => "--with-mysql-lib $path",
36
- "enable-feature" => "--enable-feature $name"
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=/usr/local/mysql/lib --enable-feature=caching
51
+ rake build -- --with-mysql-lib=/usr/local/mysql/lib --enable-feature=caching --port=3000
49
52
  ```
50
53
 
51
54
  For values with spaces, use quotes:
@@ -53,39 +56,34 @@ For values with spaces, use quotes:
53
56
  rake build -- --with-mysql-lib="/path/with spaces/lib"
54
57
  ```
55
58
 
56
- ### Bracket-Style Arguments
59
+ ### Type Casting
60
+
61
+ RakeOptions automatically casts values to the specified type:
57
62
 
58
63
  ```ruby
59
- require 'rake_options'
64
+ config = [
65
+ ["port", :integer],
66
+ ["enabled", :boolean],
67
+ ["ratio", :float],
68
+ ["name", :string]
69
+ ]
60
70
 
61
- desc "Deploy with bracket notation"
62
- task :deploy do
63
- config = {
64
- "environment" => "[environment=$env]",
65
- "region" => "[region=$region]"
66
- }
67
-
68
- options = RakeOptions.command_line_args(config, notation: :bracket)
69
-
70
- puts "Deploying to #{options['environment']} in #{options['region']}"
71
- end
72
- ```
71
+ options = RakeOptions.command_line_args(config)
73
72
 
74
- Run with:
75
- ```bash
76
- rake deploy [environment=production] [region=us-west-2]
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)
77
78
  ```
78
79
 
79
- ### Multiple Variables in One Template
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)
80
85
 
81
- ```ruby
82
- config = {
83
- "database" => "--config $file --env $environment"
84
- }
85
86
 
86
- options = RakeOptions.command_line_args(config)
87
- # Extracts both file and environment from: --config=database.yml --env=production
88
- ```
89
87
 
90
88
  ### Automatic Help Documentation
91
89
 
@@ -96,18 +94,20 @@ readme_content = <<~HELP
96
94
  Build Task Help
97
95
 
98
96
  Available options:
99
- --with-mysql-lib PATH Specify MySQL library path
100
- --enable-feature NAME Enable a specific feature
97
+ --with-mysql-lib=PATH Specify MySQL library path (string)
98
+ --enable-feature=NAME Enable a specific feature (string)
99
+ --port=NUMBER Port number (integer)
101
100
  HELP
102
101
 
103
102
  RakeOptions.initialize_readme(readme_content)
104
103
 
105
104
  desc "Build with help support"
106
105
  task :build do
107
- config = {
108
- "with-mysql-lib" => "--with-mysql-lib $path",
109
- "enable-feature" => "--enable-feature $name"
110
- }
106
+ config = [
107
+ ["with-mysql-lib", :string],
108
+ ["enable-feature", :string],
109
+ ["port", :integer]
110
+ ]
111
111
 
112
112
  options = RakeOptions.command_line_args(config)
113
113
  # Your build logic here
@@ -133,37 +133,40 @@ options[:with_mysql_lib]
133
133
 
134
134
  ## Configuration Format
135
135
 
136
- The configuration hash maps symbolic names to template patterns:
136
+ The configuration is a simple array of tuples:
137
137
 
138
138
  ```ruby
139
- {
140
- "key-name" => "template pattern with $variables"
141
- }
139
+ [
140
+ ["flag-name", :type],
141
+ ["another-flag", :type]
142
+ ]
142
143
  ```
143
144
 
144
- - **Key**: The name you'll use to access the parsed value
145
- - **Value**: A template string that defines how to extract the argument
146
- - **Variables**: Prefixed with `$` to indicate where values should be extracted
145
+ - **flag-name**: The CLI flag name (will become `--flag-name`)
146
+ - **type**: The data type (`:string`, `:integer`, `:float`, `:boolean`)
147
147
 
148
- ### Template Examples
148
+ ### Examples
149
149
 
150
150
  ```ruby
151
- # Single variable
152
- "mysql-path" => "--with-mysql-lib $path"
151
+ # String values
152
+ ["mysql-path", :string]
153
+
154
+ # Integer values
155
+ ["port", :integer]
153
156
 
154
- # Multiple variables
155
- "database" => "--config $file --env $environment"
157
+ # Boolean flags
158
+ ["enabled", :boolean]
156
159
 
157
- # Bracket notation
158
- "region" => "[region=$value]"
160
+ # Float values
161
+ ["ratio", :float]
159
162
  ```
160
163
 
161
- ## Notation Styles
164
+ ## Usage Format
162
165
 
163
- ### CLI Notation (default)
166
+ RakeOptions uses standard CLI flag format:
164
167
 
165
168
  ```ruby
166
- options = RakeOptions.command_line_args(config, notation: :cli)
169
+ options = RakeOptions.command_line_args(config)
167
170
  ```
168
171
 
169
172
  Supports:
@@ -171,17 +174,6 @@ Supports:
171
174
  - `--flag="value with spaces"`
172
175
  - Multiple flags in one command
173
176
 
174
- ### Bracket Notation
175
-
176
- ```ruby
177
- options = RakeOptions.command_line_args(config, notation: :bracket)
178
- ```
179
-
180
- Supports:
181
- - `[key=value]`
182
- - `[key="value with spaces"]`
183
- - Multiple bracket arguments
184
-
185
177
  ## Error Handling
186
178
 
187
179
  RakeOptions provides clear error messages:
@@ -236,17 +228,17 @@ rake task -- --help
236
228
  rake task -- --path="/path/with spaces"
237
229
  ```
238
230
 
239
- ### Template not matching
231
+ ### Flag name mismatch
240
232
 
241
- **Problem**: Template variables aren't extracting values.
233
+ **Problem**: Arguments aren't being recognized.
242
234
 
243
- **Solution**: Ensure your template matches the command line format exactly:
235
+ **Solution**: Ensure the flag name in ARGV matches the config:
244
236
  ```ruby
245
- # Template
246
- "option" => "--option $value"
237
+ # Config
238
+ ["my-option", :string]
247
239
 
248
- # Command line must match (note the = sign)
249
- rake task -- --option=myvalue
240
+ # Command line must match exactly
241
+ rake task -- --my-option=myvalue
250
242
  ```
251
243
 
252
244
  ## 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, template_str|
13
- @parsed_templates[key] = TemplateEngine.parse_template(template_str)
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, _template_str|
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
- # For single variable templates, store the value directly
29
- if extracted.size == 1
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, template|
35
- help_text += format_option(key, template)
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 template [String] Template string
54
+ # @param type [Symbol] Value type
44
55
  # @return [String] Formatted option line
45
- def format_option(key, template)
46
- " #{template.ljust(40)} (#{key})\n"
56
+ def format_option(key, type)
57
+ " --#{key}=VALUE".ljust(42) + "(#{type})\n"
47
58
  end
48
59
  end
49
60
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module RakeOptions
4
- VERSION = "0.1.1"
4
+ VERSION = "0.1.3"
5
5
  end
data/lib/rake_options.rb CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  require_relative "rake_options/version"
4
4
  require_relative "rake_options/errors"
5
- require_relative "rake_options/argument_parser"
5
+ require_relative "rake_options/cli_parser"
6
6
  require_relative "rake_options/help_generator"
7
7
  require_relative "rake_options/hash_with_indifferent_access"
8
8
 
@@ -11,18 +11,17 @@ module RakeOptions
11
11
  attr_accessor :readme_content
12
12
 
13
13
  # Parse command line arguments based on configuration
14
- # @param config [Hash] Argument configuration mapping
15
- # @param notation [Symbol] Notation style (:cli or :bracket)
14
+ # @param config [Array] Argument configuration as array of [name, type] tuples
16
15
  # @return [HashWithIndifferentAccess] Parsed arguments with indifferent access
17
- def command_line_args(config, notation: :cli)
16
+ def command_line_args(config)
18
17
  # Check for --help flag
19
18
  if ARGV.include?("--help")
20
19
  help_generator = HelpGenerator.new(config, readme_content)
21
20
  help_generator.display_and_exit
22
21
  end
23
22
 
24
- # Parse arguments
25
- parser = ArgumentParser.new(config, notation)
23
+ # Parse arguments using CLI parser
24
+ parser = CLIParser.new(config)
26
25
  result = parser.parse
27
26
 
28
27
  # Wrap in HashWithIndifferentAccess
@@ -5,27 +5,27 @@ 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" => "--with-mysql-lib $path",
10
- "enable-feature" => "--enable-feature $name",
11
- "port" => "--port $number"
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
16
  stub_const("ARGV", ["--with-mysql-lib=/usr/local/lib", "--enable-feature=caching", "--port=3000"])
17
17
 
18
- result = RakeOptions.command_line_args(config, notation: :cli)
18
+ result = RakeOptions.command_line_args(config)
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("3000")
22
+ expect(result["port"]).to eq(3000)
23
23
  end
24
24
 
25
25
  it "handles partial arguments gracefully" do
26
26
  stub_const("ARGV", ["--with-mysql-lib=/usr/local/lib"])
27
27
 
28
- result = RakeOptions.command_line_args(config, notation: :cli)
28
+ result = RakeOptions.command_line_args(config)
29
29
 
30
30
  expect(result["with-mysql-lib"]).to eq("/usr/local/lib")
31
31
  expect(result["enable-feature"]).to be_nil
@@ -35,7 +35,7 @@ RSpec.describe "RakeOptions Integration Tests" do
35
35
  it "supports quoted values with spaces" do
36
36
  stub_const("ARGV", ['--with-mysql-lib="/path/with spaces/lib"'])
37
37
 
38
- result = RakeOptions.command_line_args(config, notation: :cli)
38
+ result = RakeOptions.command_line_args(config)
39
39
 
40
40
  expect(result["with-mysql-lib"]).to eq("/path/with spaces/lib")
41
41
  end
@@ -43,50 +43,13 @@ RSpec.describe "RakeOptions Integration Tests" do
43
43
  it "allows symbol key access" do
44
44
  stub_const("ARGV", ["--with-mysql-lib=/usr/local/lib"])
45
45
 
46
- result = RakeOptions.command_line_args(config, notation: :cli)
46
+ result = RakeOptions.command_line_args(config)
47
47
 
48
48
  expect(result[:with_mysql_lib]).to eq("/usr/local/lib")
49
49
  expect(result["with-mysql-lib"]).to eq("/usr/local/lib")
50
50
  end
51
51
  end
52
52
 
53
- describe "Full bracket parsing workflow" do
54
- let(:config) do
55
- {
56
- "environment" => "[environment=$env]",
57
- "region" => "[region=$reg]",
58
- "instance-type" => "[instance-type=$type]"
59
- }
60
- end
61
-
62
- it "parses multiple bracket arguments" do
63
- stub_const("ARGV", ["[environment=production]", "[region=us-west-2]", "[instance-type=t2.micro]"])
64
-
65
- result = RakeOptions.command_line_args(config, notation: :bracket)
66
-
67
- expect(result["environment"]).to eq("production")
68
- expect(result["region"]).to eq("us-west-2")
69
- expect(result["instance-type"]).to eq("t2.micro")
70
- end
71
-
72
- it "handles quoted bracket values" do
73
- stub_const("ARGV", ['[environment="staging environment"]'])
74
-
75
- result = RakeOptions.command_line_args(config, notation: :bracket)
76
-
77
- expect(result["environment"]).to eq("staging environment")
78
- end
79
-
80
- it "supports symbol key access with dashes/underscores" do
81
- stub_const("ARGV", ["[instance-type=t2.micro]"])
82
-
83
- result = RakeOptions.command_line_args(config, notation: :bracket)
84
-
85
- expect(result[:instance_type]).to eq("t2.micro")
86
- expect(result["instance-type"]).to eq("t2.micro")
87
- end
88
- end
89
-
90
53
  describe "Help display integration" do
91
54
  let(:config) do
92
55
  {
@@ -134,27 +97,25 @@ RSpec.describe "RakeOptions Integration Tests" do
134
97
 
135
98
  describe "Mixed scenarios" do
136
99
  let(:config) do
137
- {
138
- "database" => "--config $file --env $environment",
139
- "verbose" => "--verbose $level"
140
- }
100
+ [
101
+ ["database", :string],
102
+ ["verbose", :string]
103
+ ]
141
104
  end
142
105
 
143
- it "handles templates with multiple variables" do
144
- stub_const("ARGV", ["--config=database.yml", "--env=production", "--verbose=debug"])
106
+ it "handles multiple arguments" do
107
+ stub_const("ARGV", ["--database=mydb", "--verbose=debug"])
145
108
 
146
- result = RakeOptions.command_line_args(config, notation: :cli)
109
+ result = RakeOptions.command_line_args(config)
147
110
 
148
- expect(result["database"]).to be_a(Hash)
149
- expect(result["database"]["file"]).to eq("database.yml")
150
- expect(result["database"]["environment"]).to eq("production")
111
+ expect(result["database"]).to eq("mydb")
151
112
  expect(result["verbose"]).to eq("debug")
152
113
  end
153
114
 
154
115
  it "handles empty ARGV" do
155
116
  stub_const("ARGV", [])
156
117
 
157
- result = RakeOptions.command_line_args(config, notation: :cli)
118
+ result = RakeOptions.command_line_args(config)
158
119
 
159
120
  expect(result["database"]).to be_nil
160
121
  expect(result["verbose"]).to be_nil
@@ -163,48 +124,28 @@ RSpec.describe "RakeOptions Integration Tests" do
163
124
  it "ignores unrecognized arguments" do
164
125
  stub_const("ARGV", ["--unknown-flag=value", "--verbose=info"])
165
126
 
166
- result = RakeOptions.command_line_args(config, notation: :cli)
127
+ result = RakeOptions.command_line_args(config)
167
128
 
168
129
  expect(result["verbose"]).to eq("info")
169
130
  expect(result["database"]).to be_nil
170
131
  end
171
132
  end
172
133
 
173
- describe "Error scenarios" do
174
- let(:config) do
175
- {
176
- "option" => "--option $value"
177
- }
178
- end
179
-
180
- it "raises InvalidNotationError for unsupported notation" do
181
- stub_const("ARGV", ["--option=value"])
182
-
183
- expect { RakeOptions.command_line_args(config, notation: :invalid) }
184
- .to raise_error(RakeOptions::InvalidNotationError, /Invalid notation/)
185
- end
186
134
 
187
- it "provides clear error message with supported notations" do
188
- stub_const("ARGV", ["--option=value"])
189
-
190
- expect { RakeOptions.command_line_args(config, notation: :xml) }
191
- .to raise_error(RakeOptions::InvalidNotationError, /:cli, :bracket/)
192
- end
193
- end
194
135
 
195
136
  describe "Real-world usage scenarios" do
196
137
  context "deployment task" do
197
138
  let(:deploy_config) do
198
- {
199
- "environment" => "--env $environment",
200
- "region" => "--region $region",
201
- "version" => "--version $ver",
202
- "dry-run" => "--dry-run $flag"
203
- }
139
+ [
140
+ ["environment", :string],
141
+ ["region", :string],
142
+ ["version", :string],
143
+ ["dry-run", :boolean]
144
+ ]
204
145
  end
205
146
 
206
147
  it "handles typical deployment command" do
207
- stub_const("ARGV", ["--env=production", "--region=us-east-1", "--version=v1.2.3"])
148
+ stub_const("ARGV", ["--environment=production", "--region=us-east-1", "--version=v1.2.3"])
208
149
 
209
150
  result = RakeOptions.command_line_args(deploy_config)
210
151
 
@@ -217,17 +158,17 @@ RSpec.describe "RakeOptions Integration Tests" do
217
158
 
218
159
  context "build task" do
219
160
  let(:build_config) do
220
- {
221
- "with-mysql" => "--with-mysql-lib $path",
222
- "with-ssl" => "--with-ssl-lib $path",
223
- "prefix" => "--prefix $path"
224
- }
161
+ [
162
+ ["with-mysql", :string],
163
+ ["with-ssl", :string],
164
+ ["prefix", :string]
165
+ ]
225
166
  end
226
167
 
227
168
  it "handles build configuration" do
228
169
  stub_const("ARGV", [
229
- "--with-mysql-lib=/usr/local/mysql/lib",
230
- "--with-ssl-lib=/usr/local/ssl/lib",
170
+ "--with-mysql=/usr/local/mysql/lib",
171
+ "--with-ssl=/usr/local/ssl/lib",
231
172
  "--prefix=/opt/myapp"
232
173
  ])
233
174
 
@@ -7,9 +7,7 @@ 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
 
@@ -30,10 +28,7 @@ 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
 
@@ -56,9 +51,7 @@ 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
 
@@ -72,9 +65,7 @@ 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
 
@@ -87,21 +78,34 @@ RSpec.describe RakeOptions::CLIParser do
87
78
  end
88
79
  end
89
80
 
90
- context "with multiple variables in template" do
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 "extracts multiple variables" do
99
- argv = ["--config=database.yml", "--env=production"]
87
+ it "casts integer values" do
88
+ argv = ["--port=3000"]
100
89
  result = parser.parse(argv)
101
90
 
102
- expect(result["database"]).to be_a(Hash)
103
- expect(result["database"]["file"]).to eq("database.yml")
104
- expect(result["database"]["environment"]).to eq("production")
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 template" do
81
- formatted = generator.send(:format_option, "my-option", "--my-option $value")
82
- expect(formatted).to include("--my-option $value")
83
- expect(formatted).to include("my-option")
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
@@ -4,44 +4,31 @@ 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
- context "with CLI notation" do
11
+ context "parsing arguments" do
15
12
  it "parses CLI-style arguments" do
16
13
  stub_const("ARGV", ["--with-mysql-lib=/usr/local/lib"])
17
- result = described_class.command_line_args(config, notation: :cli)
14
+ result = described_class.command_line_args(config)
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
20
  stub_const("ARGV", ["--with-mysql-lib=/usr/local/lib"])
24
- result = described_class.command_line_args(config, notation: :cli)
21
+ result = described_class.command_line_args(config)
25
22
 
26
23
  expect(result[:with_mysql_lib]).to eq("/usr/local/lib")
27
24
  end
28
- end
29
25
 
30
- context "with bracket notation" do
31
- it "parses bracket-style arguments" do
32
- stub_const("ARGV", ["[with-mysql-lib=/usr/local/lib]"])
33
- result = described_class.command_line_args(config, notation: :bracket)
34
-
35
- expect(result["with-mysql-lib"]).to eq("/usr/local/lib")
36
- end
37
- end
38
-
39
- context "with default notation" do
40
- it "defaults to CLI notation" do
41
- stub_const("ARGV", ["--with-mysql-lib=/usr/local/lib"])
26
+ it "parses multiple arguments" do
27
+ stub_const("ARGV", ["--with-mysql-lib=/usr/local/lib", "--enable-feature=caching"])
42
28
  result = described_class.command_line_args(config)
43
29
 
44
30
  expect(result["with-mysql-lib"]).to eq("/usr/local/lib")
31
+ expect(result["enable-feature"]).to eq("caching")
45
32
  end
46
33
  end
47
34
 
@@ -66,6 +53,10 @@ RSpec.describe RakeOptions do
66
53
  end
67
54
 
68
55
  describe ".initialize_readme" do
56
+ let(:simple_config) do
57
+ [["option", :string]]
58
+ end
59
+
69
60
  it "stores readme content" do
70
61
  readme = "Custom help text"
71
62
  described_class.initialize_readme(readme)
@@ -78,7 +69,7 @@ RSpec.describe RakeOptions do
78
69
  described_class.initialize_readme(readme)
79
70
  stub_const("ARGV", ["--help"])
80
71
 
81
- expect { described_class.command_line_args(config) }
72
+ expect { described_class.command_line_args(simple_config) }
82
73
  .to output(/My Custom Help/).to_stdout
83
74
  .and raise_error(SystemExit)
84
75
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rake_options
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.1.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Randy Villanueva
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2025-10-15 00:00:00.000000000 Z
11
+ date: 2025-10-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake
@@ -51,8 +51,6 @@ files:
51
51
  - README.md
52
52
  - Rakefile
53
53
  - lib/rake_options.rb
54
- - lib/rake_options/argument_parser.rb
55
- - lib/rake_options/bracket_parser.rb
56
54
  - lib/rake_options/cli_parser.rb
57
55
  - lib/rake_options/errors.rb
58
56
  - lib/rake_options/hash_with_indifferent_access.rb
@@ -60,8 +58,6 @@ files:
60
58
  - lib/rake_options/template_engine.rb
61
59
  - lib/rake_options/version.rb
62
60
  - spec/integration/rake_options_integration_spec.rb
63
- - spec/rake_options/argument_parser_spec.rb
64
- - spec/rake_options/bracket_parser_spec.rb
65
61
  - spec/rake_options/cli_parser_spec.rb
66
62
  - spec/rake_options/help_generator_spec.rb
67
63
  - spec/rake_options/template_engine_spec.rb
@@ -1,46 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative "cli_parser"
4
- require_relative "bracket_parser"
5
- require_relative "errors"
6
-
7
- module RakeOptions
8
- class ArgumentParser
9
- VALID_NOTATIONS = [:cli, :bracket].freeze
10
-
11
- def initialize(config, notation)
12
- @config = config
13
- @notation = notation
14
- validate_notation
15
- end
16
-
17
- # Parse ARGV and return structured options
18
- # @return [Hash] Parsed options
19
- def parse
20
- parser = select_parser
21
- parser.parse
22
- end
23
-
24
- private
25
-
26
- # Select appropriate parser based on notation
27
- # @return [CLIParser, BracketParser] Parser instance
28
- def select_parser
29
- case @notation
30
- when :cli
31
- CLIParser.new(@config)
32
- when :bracket
33
- BracketParser.new(@config)
34
- end
35
- end
36
-
37
- # Validate notation parameter
38
- # @raise [InvalidNotationError] if notation is invalid
39
- def validate_notation
40
- return if VALID_NOTATIONS.include?(@notation)
41
-
42
- raise InvalidNotationError,
43
- "Invalid notation ':#{@notation}'. Supported notations: #{VALID_NOTATIONS.map { |n| ":#{n}" }.join(', ')}"
44
- end
45
- end
46
- end
@@ -1,64 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module RakeOptions
4
- class BracketParser
5
- def initialize(config)
6
- @config = config
7
- end
8
-
9
- # Parse bracket-style arguments from ARGV
10
- # @param argv [Array] Command line arguments (defaults to ARGV)
11
- # @return [Hash] Parsed values
12
- def parse(argv = ARGV)
13
- result = {}
14
-
15
- # Extract all bracket arguments from argv
16
- bracket_args = extract_bracket_args(argv)
17
-
18
- # Match bracket args to config keys
19
- @config.each do |key, _template|
20
- # Look for matching bracket key
21
- if bracket_args.key?(key)
22
- result[key] = bracket_args[key]
23
- else
24
- result[key] = nil
25
- end
26
- end
27
-
28
- result
29
- end
30
-
31
- private
32
-
33
- # Find all [key=value] patterns in argv
34
- # @param argv [Array] Command line arguments
35
- # @return [Hash] Extracted key-value pairs
36
- def extract_bracket_args(argv)
37
- result = {}
38
-
39
- argv.each do |arg|
40
- # Match [key=value] or [key="value"]
41
- match = arg.match(/^\[([^=]+)=(.+)\]$/)
42
- next unless match
43
-
44
- key = match[1]
45
- value = parse_bracket_value(match[2])
46
- result[key] = value
47
- end
48
-
49
- result
50
- end
51
-
52
- # Handle quoted and unquoted values in brackets
53
- # @param value [String] Value from bracket
54
- # @return [String] Parsed value
55
- def parse_bracket_value(value)
56
- # Remove surrounding quotes if present
57
- if value.start_with?('"') && value.end_with?('"')
58
- value[1..-2]
59
- else
60
- value
61
- end
62
- end
63
- end
64
- end
@@ -1,71 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "spec_helper"
4
- require "rake_options/argument_parser"
5
-
6
- RSpec.describe RakeOptions::ArgumentParser do
7
- let(:config) do
8
- {
9
- "option1" => "--option1 $value"
10
- }
11
- end
12
-
13
- describe "#initialize" do
14
- context "with valid notation" do
15
- it "accepts :cli notation" do
16
- expect { described_class.new(config, :cli) }.not_to raise_error
17
- end
18
-
19
- it "accepts :bracket notation" do
20
- expect { described_class.new(config, :bracket) }.not_to raise_error
21
- end
22
- end
23
-
24
- context "with invalid notation" do
25
- it "raises InvalidNotationError" do
26
- expect { described_class.new(config, :invalid) }.to raise_error(RakeOptions::InvalidNotationError)
27
- end
28
-
29
- it "provides helpful error message" do
30
- expect { described_class.new(config, :invalid) }.to raise_error(
31
- RakeOptions::InvalidNotationError,
32
- /Invalid notation ':invalid'. Supported notations: :cli, :bracket/
33
- )
34
- end
35
- end
36
- end
37
-
38
- describe "#parse" do
39
- context "with CLI notation" do
40
- let(:parser) { described_class.new(config, :cli) }
41
-
42
- it "uses CLIParser" do
43
- expect(RakeOptions::CLIParser).to receive(:new).with(config).and_call_original
44
- parser.parse
45
- end
46
- end
47
-
48
- context "with bracket notation" do
49
- let(:parser) { described_class.new(config, :bracket) }
50
-
51
- it "uses BracketParser" do
52
- expect(RakeOptions::BracketParser).to receive(:new).with(config).and_call_original
53
- parser.parse
54
- end
55
- end
56
- end
57
-
58
- describe "#select_parser" do
59
- it "returns CLIParser for :cli notation" do
60
- parser = described_class.new(config, :cli)
61
- selected = parser.send(:select_parser)
62
- expect(selected).to be_a(RakeOptions::CLIParser)
63
- end
64
-
65
- it "returns BracketParser for :bracket notation" do
66
- parser = described_class.new(config, :bracket)
67
- selected = parser.send(:select_parser)
68
- expect(selected).to be_a(RakeOptions::BracketParser)
69
- end
70
- end
71
- end
@@ -1,86 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "spec_helper"
4
- require "rake_options/bracket_parser"
5
-
6
- RSpec.describe RakeOptions::BracketParser do
7
- describe "#parse" do
8
- context "with simple key=value" do
9
- let(:config) do
10
- {
11
- "environment" => "[environment=$env]",
12
- "region" => "[region=$region]"
13
- }
14
- end
15
- let(:parser) { described_class.new(config) }
16
-
17
- it "parses [key=value] format" do
18
- argv = ["[environment=production]", "[region=us-west-2]"]
19
- result = parser.parse(argv)
20
-
21
- expect(result["environment"]).to eq("production")
22
- expect(result["region"]).to eq("us-west-2")
23
- end
24
-
25
- it "returns nil for missing arguments" do
26
- argv = ["[environment=production]"]
27
- result = parser.parse(argv)
28
-
29
- expect(result["environment"]).to eq("production")
30
- expect(result["region"]).to be_nil
31
- end
32
- end
33
-
34
- context "with quoted values" do
35
- let(:config) do
36
- {
37
- "message" => "[message=$text]"
38
- }
39
- end
40
- let(:parser) { described_class.new(config) }
41
-
42
- it "parses [key=\"value with spaces\"] format" do
43
- argv = ['[message="Hello World"]']
44
- result = parser.parse(argv)
45
-
46
- expect(result["message"]).to eq("Hello World")
47
- end
48
- end
49
-
50
- context "with multiple bracket arguments" do
51
- let(:config) do
52
- {
53
- "env" => "[env=$environment]",
54
- "region" => "[region=$reg]",
55
- "instance" => "[instance=$type]"
56
- }
57
- end
58
- let(:parser) { described_class.new(config) }
59
-
60
- it "parses multiple bracket arguments" do
61
- argv = ["[env=prod]", "[region=us-east-1]", "[instance=t2.micro]"]
62
- result = parser.parse(argv)
63
-
64
- expect(result["env"]).to eq("prod")
65
- expect(result["region"]).to eq("us-east-1")
66
- expect(result["instance"]).to eq("t2.micro")
67
- end
68
- end
69
-
70
- context "with malformed brackets" do
71
- let(:config) do
72
- {
73
- "valid" => "[valid=$val]"
74
- }
75
- end
76
- let(:parser) { described_class.new(config) }
77
-
78
- it "ignores malformed bracket arguments" do
79
- argv = ["[valid=test]", "invalid=value", "[missing-bracket"]
80
- result = parser.parse(argv)
81
-
82
- expect(result["valid"]).to eq("test")
83
- end
84
- end
85
- end
86
- end