argvise 0.0.2 → 0.0.4

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: 8558fd9dd7cf152d33787d2c15c101a18e28d3064e2ecfe54c77d4d488e16119
4
- data.tar.gz: 1ef9387ef135826ee91e6409b1c585ba92ee7411487a1fc6dec25a47e7268718
3
+ metadata.gz: d63847d3264553ea75e063063330aff39cb7638bb22d4a227664dfef0f55203b
4
+ data.tar.gz: 44335dc0284501d472b81c9427b939000ade17971d0657727b81cc97a4ad631d
5
5
  SHA512:
6
- metadata.gz: d39ff4e6428417cd801f08f077a9f92b742d85bb91a2fd15cfed5bead4b432d4a999a592f93f7339334ec11b5ec4ec5d88fc719a126afc4341cf28424a2d94c0
7
- data.tar.gz: cec50ddc41188e914a4967ff97fe914e84ad620f7033823d322d25284d9f7933cf9e1f7f2186f06dfc57f3c92221d0e54828a9739c7681a3eba8f119f792062e
6
+ metadata.gz: 331dac661ca76f65e605c027be9217b213a97340530c4d4ebe2871979197f37fef9bb6f0ccfe92034faeeb1b879df1db2a180e932dfb992e6b0ae0b4720a690a
7
+ data.tar.gz: c00671dfccfba16990b7aff2db61612cbde3ca3b478a6e4b0369181ad6a58aabff3fa28257174bb701fa028b5e6267d227c13b78b85dfc043e8b81309d40de03
data/.rubocop.yml ADDED
@@ -0,0 +1,2 @@
1
+ AllCops:
2
+ TargetRubyVersion: 3.1
data/argvise.gemspec ADDED
@@ -0,0 +1,47 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'lib/argvise/version'
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = 'argvise'
7
+ # spec.version = '0.0.1'
8
+ spec.version = Argvise::VERSION
9
+ spec.authors = ['2moe']
10
+ spec.email = ['m@tmoe.me']
11
+
12
+ spec.summary = 'Turns a hash into CLI arguments'
13
+ spec.description = 'Provides flexible command-line argument generation with support for complex data structures'
14
+ spec.license = 'Apache-2.0'
15
+ # spec.extra_rdoc_files = ['docs/rdoc/Readme.rdoc']
16
+ spec.required_ruby_version = '>= 3.1.0'
17
+ # spec.metadata['allowed_push_host'] = "TODO: Set to your gem server 'https://example.com'"
18
+
19
+ spec.homepage = 'https://github.com/2moe/argvise-gem'
20
+ spec.metadata['homepage_uri'] = spec.homepage
21
+ # spec.metadata['source_code_uri'] = spec.homepage
22
+ # spec.metadata['changelog_uri'] = "TODO: Put your gem's CHANGELOG.md URL here."
23
+
24
+ # Specify which files should be added to the gem when it is released.
25
+ # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
26
+ # gemspec = File.basename(__FILE__)
27
+ spec.files = IO.popen(%w[git ls-files -z], chdir: __dir__, err: IO::NULL) do |ls|
28
+ ls.readlines("\x0", chomp: true).reject do |f|
29
+ # (f == gemspec) ||
30
+ f.start_with?(
31
+ # bin/ test/ Gemfile Rakefile assets docs/Readme-zh-
32
+ *%w[
33
+ spec/ features/ .git .github appveyor
34
+ ]
35
+ )
36
+ end
37
+ end
38
+ # spec.bindir = 'exe'
39
+ # spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
40
+ spec.require_paths = ['lib']
41
+
42
+ # Uncomment to register a new dependency of your gem
43
+ # spec.add_dependency "example-gem", "~> 1.0"
44
+
45
+ # For more information and examples about making a new gem, check out our
46
+ # guide at: https://bundler.io/guides/creating_gem.html
47
+ end
data/bin/build.rb ADDED
@@ -0,0 +1,19 @@
1
+ #!/usr/bin/env ruby
2
+ # typed: ignore
3
+ # frozen_string_literal: true
4
+
5
+ require 'pathname'
6
+
7
+ Pathname(__dir__ || File.dirname(__FILE__))
8
+ .parent
9
+ .then { Dir.chdir(it) }
10
+
11
+ proj = 'argvise'
12
+
13
+ system <<~CMD
14
+ gem uninstall #{proj}
15
+ gem build #{proj}
16
+ gem install #{proj}
17
+ CMD
18
+
19
+ # gem push argvise-*.gem
data/bin/console.rb ADDED
@@ -0,0 +1,63 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ # lib_path = File.expand_path('../lib', __dir__)
5
+ # exec "irb -I #{lib_path} -r argvise"
6
+
7
+ require 'irb'
8
+ require_relative '../lib/argvise'
9
+
10
+ puts "Argvise: #{Argvise::VERSION}"
11
+
12
+ def puts_division_line
13
+ puts
14
+ puts '-' * 80
15
+ end
16
+
17
+ raw_cmd = {
18
+ compiler: nil,
19
+ build: nil,
20
+ pack_type: 'tar+zstd',
21
+ push: true,
22
+ v: true,
23
+ f: 'p2',
24
+ tag: ['v0.0.1', 'beta'],
25
+ platform: 'wasi/wasm',
26
+ label: {
27
+ maintainer: 'user',
28
+ description: 'Demo'
29
+ },
30
+ "/path/to/dir": nil
31
+ }
32
+
33
+ puts 'GNU-style + kebab_case_flags(false)'
34
+ raw_cmd
35
+ .then(&Argvise.new_proc)
36
+ .with_bsd_style(false)
37
+ .with_kebab_case_flags(false)
38
+ .build
39
+ .display
40
+
41
+ puts_division_line
42
+ # -----------
43
+
44
+ puts 'GNU-style + kebab_case_flags(true)'
45
+ raw_cmd
46
+ .then(&hash_to_argv)
47
+ .display
48
+
49
+ puts_division_line
50
+ # -----------
51
+
52
+ puts 'BSD-style + kebab_case_flags(true)'
53
+ raw_cmd
54
+ .then(&Argvise.new_proc)
55
+ .with_bsd_style
56
+ .with_kebab_case_flags
57
+ .build
58
+ .display
59
+
60
+ puts_division_line
61
+ # -----------
62
+
63
+ IRB.start
data/docs/Readme.md CHANGED
@@ -6,36 +6,146 @@ A Ruby gem for converting hash structures into command-line argument arrays.
6
6
 
7
7
  > **Note:** This is *not* a command-line parser — quite the opposite. Argvise helps you **build** CLI commands programmatically.
8
8
 
9
+ ## Quick Start
10
+
11
+ ```ruby
12
+ # IRB
13
+ system "gem install argvise"
14
+ ```
15
+
16
+ ```ruby
17
+ # RUBY
18
+ require 'argvise'
19
+
20
+ { cargo: nil, build: nil, v: true, target: "wasm32-wasip2" }
21
+ .then(&hash_to_argv)
22
+
23
+ #=> ["cargo", "build", "-v", "--target", "wasm32-wasip2"]
24
+ ```
25
+
26
+ `raw_cmd_hash.then(&hash_to_argv)` is equivalent to:
27
+
28
+ ```ruby
29
+ { cargo: nil, build: nil, v: true, target: "wasm32-wasip2" }
30
+ .then(&Argvise.new_proc)
31
+ .with_bsd_style(false) #=> GNU style
32
+ .with_kebab_case_flags(true) #=> replace "--cli_flag" with "--cli-flag"
33
+ .build
34
+ ```
35
+
9
36
  ## Installation
10
37
 
11
38
  Add this line to your application's Gemfile:
12
39
 
13
40
  ```ruby
41
+ # Gemfile
42
+ #
14
43
  gem 'argvise'
15
44
  ```
16
45
 
17
46
  And then execute:
18
47
 
19
- ```bash
48
+ ```sh
49
+ # SHELL
50
+ #
20
51
  bundler install
21
52
  ```
22
53
 
23
54
  Or install it directly:
24
55
 
25
- ```bash
56
+ ```sh
57
+ # SHELL
58
+ #
26
59
  gem install argvise
27
60
  ```
28
61
 
29
- ## Usage
62
+ ## Conversion Rules
63
+
64
+ ### Common
65
+
66
+ | Hash Format | Result Example |
67
+ | ------------------------ | ---------------------------- |
68
+ | `{ key: nil }` | `["key"]` |
69
+ | `{ "-k2": nil }` | `["-k2"]` |
70
+ | `{ "--r_a-nd_om": nil }` | `["--r_a-nd_om"]` |
71
+ | `{ key: false }` | `[]` |
72
+ | `{ key: [] }` | `[]` |
73
+ | `{ k: true }` | `["-k"]` |
74
+ | `{ k: "value" }` | `["-k", "value"]` |
75
+ | `{ k: ["a", "b"] }` | `["-k", "a", "-k", "b"]` |
76
+ | `{ k: { a: 1, b: 2 } }` | `["-k", "a=1", "-k", "b=2"]` |
77
+
78
+
79
+ ### GNU Style
80
+
81
+ | Hash Format | Result Example |
82
+ | ------------------------- | ---------------------------------- |
83
+ | `{ key: true }` | `["--key"]` |
84
+ | `{ key: "value" }` | `["--key", "value"]` |
85
+ | `{ key: ["a", "b"] }` | `["--key", "a", "--key", "b"]` |
86
+ | `{ key: { a: 1, b: 2 } }` | `["--key", "a=1", "--key", "b=2"]` |
87
+
88
+ ---
89
+
90
+ #### `with_kebab_case_flags(true)`:
91
+
92
+ | Hash Format | Result Example |
93
+ | ----------------- | -------------- |
94
+ | `{ key_a: true }` | `["--key-a"]` |
95
+
96
+ ---
97
+
98
+ #### `with_kebab_case_flags(false)`:
99
+
100
+ | Hash Format | Result Example |
101
+ | ----------------- | -------------- |
102
+ | `{ key_b: true }` | `["--key_b"]` |
103
+
104
+
105
+ ### BSD Style
106
+
107
+ | Hash Format | Result Example |
108
+ | ------------------------- | -------------------------------- |
109
+ | `{ key: true }` | `["-key"]` |
110
+ | `{ key: "value" }` | `["-key", "value"]` |
111
+ | `{ key: ["a", "b"] }` | `["-key", "a", "-key", "b"]` |
112
+ | `{ key: { a: 1, b: 2 } }` | `["-key", "a=1", "-key", "b=2"]` |
30
113
 
31
- ### Basic Conversion
114
+ ---
115
+
116
+ #### `with_kebab_case_flags(true)`:
117
+
118
+ | Hash Format | Result Example |
119
+ | ----------------- | -------------- |
120
+ | `{ key_c: true }` | `["-key-c"]` |
121
+
122
+ ---
123
+
124
+ #### `with_kebab_case_flags(false)`:
125
+
126
+ | Hash Format | Result Example |
127
+ | ----------------- | -------------- |
128
+ | `{ key_d: true }` | `["-key_d"]` |
129
+
130
+
131
+ ### Notes
132
+
133
+ > When the value of a flag key is `nil`, the `kebab_case_flags` option has
134
+ > no effect — i.e., the key will not be transformed.
135
+ >
136
+ > For example, the input `{"a_b-c": nil}` will result in `["a_b-c"]`,
137
+ > and **not** be automatically transformed into `["a-b-c"]`.
138
+
139
+ ## Examples
140
+
141
+ ### Basic Conversion (GNU Style)
32
142
 
33
143
  ```ruby
34
144
  require 'argvise'
35
145
 
36
- options = {
146
+ raw_cmd_hash = {
37
147
  docker: nil, #=> docker
38
- build: nil,
148
+ build: nil,
39
149
  push: true, #=> --push
40
150
  tag: ["ghcr.io/[user]/repo:latest", "ghcr.io/[user]/repo:v0.0.1"], #=> --tag ghcr... --tag ghcr..0.0.1
41
151
  platform: "wasi/wasm", #=> --platform wasi/wasm
@@ -47,12 +157,12 @@ options = {
47
157
  path: nil,
48
158
  }
49
159
 
50
- Argvise.build(options)
160
+ Argvise.build(raw_cmd_hash)
51
161
  # => [
52
- # "docker", "build", "--push",
53
- # "--tag", "ghcr.io/[user]/repo:latest", "--tag", "ghcr.io/[user]/repo:v0.0.1",
54
- # "--platform", "wasi/wasm",
55
- # "--label", "maintainer=user", "--label", "description=A Docker build example",
162
+ # "docker", "build", "--push",
163
+ # "--tag", "ghcr.io/[user]/repo:latest", "--tag", "ghcr.io/[user]/repo:v0.0.1",
164
+ # "--platform", "wasi/wasm",
165
+ # "--label", "maintainer=user", "--label", "description=A Docker build example",
56
166
  # "--file", "wasi.dockerfile", "path"
57
167
  # ]
58
168
  ```
@@ -60,60 +170,117 @@ Argvise.build(options)
60
170
  ### Lambda Shortcut
61
171
 
62
172
  ```ruby
63
- { v: true, dir: '/path/to/dir' }.then(&hash_to_args)
173
+ { v: true, dir: '/path/to/dir' }.then(&hash_to_argv)
64
174
  # => ["-v", "--dir", "/path/to/dir"]
65
175
  ```
66
176
 
67
- ## Supported Data Structures
177
+ ### Configurable builder
68
178
 
69
- ### 1. Simple Flags
179
+ > Required
180
+ > - argvise: >= v0.0.4
181
+ > - ruby: >= v3.1.0
70
182
 
71
183
  ```ruby
72
- { verbose: true }.then(&hash_to_args) # => ["--verbose"]
184
+ raw_cmd = {
185
+ compiler: nil,
186
+ build: nil,
187
+ pack_type: 'tar+zstd',
188
+ push: true,
189
+ v: true,
190
+ f: 'p2',
191
+ tag: ['v0.0.1', 'beta'],
192
+ platform: 'wasi/wasm',
193
+ label: {
194
+ maintainer: 'user',
195
+ description: 'Demo'
196
+ },
197
+ "/path/to/dir": nil
198
+ }
199
+
200
+ p '----------------'
201
+ p "GNU-style + kebab case flags=false"
202
+ raw_cmd
203
+ .then(&Argvise.new_proc)
204
+ .with_bsd_style(false)
205
+ .with_kebab_case_flags(false)
206
+ .build
207
+ .display
208
+
209
+ #=> ["compiler", "build", "--pack_type", "tar+zstd", "--push", "-v", "-f", "p2", "--tag", "v0.0.1", "--tag", "beta", "--platform", "wasi/wasm", "--label", "maintainer=user", "--label", "description=Demo", "/path/to/dir"]
210
+
211
+ p '----------------'
212
+ p 'GNU-style + kebab-case-flags=true'
213
+ raw_cmd
214
+ .then(&hash_to_argv)
215
+ .display
216
+
217
+ #=> ["compiler", "build", "--pack-type", "tar+zstd", "--push", "-v", "-f", "p2", "--tag", "v0.0.1", "--tag", "beta", "--platform", "wasi/wasm", "--label", "maintainer=user", "--label", "description=Demo", "/path/to/dir"]
218
+
219
+ p '----------------'
220
+ p 'BSD-style + kebab-case-flags=true'
221
+ raw_cmd
222
+ .then(&Argvise.new_proc)
223
+ .with_bsd_style
224
+ .with_kebab_case_flags
225
+ .build
226
+ .display
227
+
228
+ #=> ["compiler", "build", "-pack-type", "tar+zstd", "-push", "-v", "-f", "p2", "-tag", "v0.0.1", "-tag", "beta", "-platform", "wasi/wasm", "-label", "maintainer=user", "-label", "description=Demo", "/path/to/dir"]
73
229
  ```
74
230
 
75
- ### 2. Boolean Values
231
+ ## Data Type
76
232
 
77
- ```ruby
78
- { silent: false }.then(&hash_to_args) # => []
79
- ```
233
+ ### Boolean
80
234
 
81
- ### 3. Array Values
235
+ #### GNU style
82
236
 
83
- ```ruby
84
- { tag: %w[a b] }.then(&hash_to_args)
85
- # => ["--tag", "a", "--tag", "b"]
86
- ```
237
+ - `{ verbose: true }` => "--verbose"
238
+ - `{ v: true }` => "-v"
239
+ - `{ v: false }` => no argument generated
87
240
 
88
- ### 4. Hash Values
241
+ #### BSD style
89
242
 
90
- ```ruby
91
- { label: { env: 'test', k2: 'v2' } }.then(&hash_to_args)
92
- # => ["--label", "env=test", "--label", "k2=v2"]
93
- ```
243
+ - `{ verbose: true }` => "-verbose"
244
+ - `{ v: true }` => "-v"
245
+ - `{ v: false }` => no argument generated
94
246
 
95
- ## API Documentation
247
+ ### String
96
248
 
97
- ### `Argvise.build(options)`
249
+ #### GNU style
98
250
 
99
- Main method to convert hash to command-line arguments array
251
+ - `{ f: "a.txt" }` => `["-f", "a.txt"]`
252
+ - `{ file: "a.txt" }` => `["--file", "a.txt"]`
100
253
 
101
- **Parameters:**
254
+ #### BSD style
102
255
 
103
- - `options` (Hash) - The hash to be converted
256
+ - `{ f: "a.txt" }` => `["-f", "a.txt"]`
257
+ - `{ file: "a.txt" }` => `["-file", "a.txt"]`
104
258
 
105
- **Returns:**
259
+ ### Array
106
260
 
107
- - Array<String> generated command-line arguments
261
+ #### GNU style
108
262
 
109
- ### Conversion Rules
263
+ - `{ t: ["a", "b"] }` => `["-t", "a", "-t", "b"]`
264
+ - `{ tag: %w[a b] }` => `["--tag", "a", "--tag", "b"]`
110
265
 
111
- | Hash Format | Result Example |
112
- | ------------------------- | ---------------------------------- |
113
- | `{ key: nil }` | `["key"]` |
114
- | `{ key: false }` | `[]` |
115
- | `{ key: true }` | `["--key"]` |
116
- | `{ k: true }` | `["-k"]` |
117
- | `{ key: "value" }` | `["--key", "value"]` |
118
- | `{ key: ["a", "b"] }` | `["--key", "a", "--key", "b"]` |
119
- | `{ key: { a: 1, b: 2 } }` | `["--key", "a=1", "--key", "b=2"]` |
266
+ #### BSD style
267
+
268
+ - `{ t: ["a", "b"] }` => `["-t", "a", "-t", "b"]`
269
+ - `{ tag: %w[a b] }` => `["-tag", "a", "-tag", "b"]`
270
+
271
+ ### Hash
272
+
273
+ #### GNU style
274
+
275
+ - `{ e: { profile: 'test', lang: 'C'} }` => `["-e", "profile=test", "-e", "lang=C"]`
276
+ - `{ env: { profile: 'test', lang: 'C'} }` => `["--env", "profile=test", "--env", "lang=C"]`
277
+
278
+ #### BSD style
279
+
280
+ - `{ e: { profile: 'test', lang: 'C'} }` => `["-e", "profile=test", "-e", "lang=C"]`
281
+ - `{ env: { profile: 'test', lang: 'C'} }` => `["-env", "profile=test", "-env", "lang=C"]`
282
+
283
+ ## Nil => Raw
284
+
285
+ - `{ cargo: nil, b: nil}` => `["cargo", "b"]`
286
+ - `{ "-fv": nil}` => `["-fv"]`
@@ -1,5 +1,6 @@
1
+ # typed: strict
1
2
  # frozen_string_literal: true
2
3
 
3
4
  class Argvise
4
- VERSION = '0.0.2'
5
+ VERSION = '0.0.4'
5
6
  end
data/lib/argvise.rb CHANGED
@@ -1,3 +1,4 @@
1
+ # typed: strict
1
2
  # frozen_string_literal: true
2
3
 
3
4
  require_relative 'argvise/version'
data/lib/core.rb CHANGED
@@ -1,32 +1,149 @@
1
+ # rubocop:disable Style/Lambda, Lint/MissingCopEnableDirective
2
+ # typed: true
1
3
  # frozen_string_literal: true
2
4
 
3
- # rubocop:disable Style/Lambda, Lint/MissingCopEnableDirective
4
5
  # ------------------
5
6
  # Converts hash to command array
6
7
  #
7
- # Example
8
- # {cargo: nil, build: nil, v: true, target: "wasm32-wasip2"}.then { Argvise.build _1 }
9
- # # Output => ["cargo", "build", "-v", "--target", "wasm32-wasip2"]
8
+ # == Example
9
+ #
10
+ # { cargo: nil, build: nil, v: true, target: "wasm32-wasip2" }
11
+ # .then(&Argvise.new_proc)
12
+ # .with_bsd_style(false)
13
+ # .build
14
+ # .display
15
+ #
16
+ # #=> ["cargo", "build", "-v", "--target", "wasm32-wasip2"]
17
+ #
18
+ # == Conversion Rules:
19
+ #
20
+ # === GNU Style:
21
+ # - Boolean values:
22
+ # - `{ verbose: true }` => "--verbose"
23
+ # - `{ v: true }` => "-v"
24
+ # - `{ v: false }` => no argument generated
25
+ # - String values:
26
+ # - `{ f: "a.txt" }` => ["-f", "a.txt"]
27
+ # - `{ file: "a.txt" }` => ["--file", "a.txt"]
28
+ # - Array values:
29
+ # - `{ t: ["a", "b"] }` => `["-t", "a", "-t", "b"]`
30
+ # - `{ tag: %w[a b] }` => `["--tag", "a", "--tag", "b"]`
31
+ # - Hash values:
32
+ # - `{ L: { env: 'test' } }` => `["-L", "env=test"]`
33
+ # - `{ label: { env: 'test' } }` => `["--label", "env=test"]`
34
+ #
35
+ # === BSD Style:
36
+ # - Boolean values:
37
+ # - `{ verbose: true }` => "-verbose"
38
+ # - `{ v: true }` => "-v"
39
+ # - `{ v: false }` => no argument generated
40
+ # - String values:
41
+ # - `{ f: "a.txt" }` => ["-f", "a.txt"]
42
+ # - `{ file: "a.txt" }` => ["-file", "a.txt"]
43
+ # - Array values:
44
+ # - `{ t: ["a", "b"] }` => `["-t", "a", "-t", "b"]`
45
+ # - `{ tag: %w[a b] }` => `["-tag", "a", "-tag", "b"]`
46
+ # - Hash values:
47
+ # - `{ L: { env: 'test' } }` => `["-L", "env=test"]`
48
+ # - `{ label: { env: 'test' } }` => `["-label", "env=test"]`
49
+ #
50
+ # === Common:
51
+ # - Raw values:
52
+ # - `{ cargo: nil, b: nil}` => `["cargo", "b"]`
53
+ # - `{ "-fv": nil}` => `["-fv"]`
10
54
  #
11
- # Supported data structures:
12
- # - Simple flags: `{ verbose: true }` => "--verbose"
13
- # - Boolean values: `{ v: false }` => no argument generated
14
- # - Array values: `{ tag: %w[a b] }` => `["--tag", "a", "--tag", "b"]`
15
- # - Hash values: `{ label: { env: 'test' } }` => `["--label", "env=test"]`
55
+ # === About kebab_case_flags:
56
+ # - `with_kebab_case_flags(true)`:
57
+ # - `{enable_jit: true}` =>
58
+ # - GNU-style: `["--enable-jit"]`
59
+ # - BSD-style: `["-enable-jit"]`
60
+ # - `with_kebab_case_flags(false)`:
61
+ # - `{enable_jit: true}` =>
62
+ # - GNU-style: `["--enable_jit"]`
63
+ # - BSD-style: `["-enable_jit"]`
16
64
  class Argvise
17
- # Converts a hash into a command-line argument array
65
+ attr_accessor :bsd_style, :kebab_case_flags
66
+
67
+ # v0.0.3 default options
68
+ DEFAULT_OPTS = { bsd_style: false, kebab_case_flags: true }.freeze
69
+
70
+ class << self
71
+ # Converts a hash into a command-line argument array
72
+ #
73
+ # == Example
74
+ # require 'argvise'
75
+ # cmd = { ruby: nil, r: "argvise", verbose: true, e: true, "puts Argvise::VERSION": nil }
76
+ # opts = { bsd_style: false }
77
+ # Argvise.build(cmd, opts:)
78
+ #
79
+ # == Params
80
+ # - raw_cmd_hash [Hash] The hash to be converted (i.e., raw input data)
81
+ # - opts [Hash] See also: [self.new]
82
+ #
83
+ # == Returns
84
+ # [Array<String>] The generated array of command-line arguments
85
+ def build(
86
+ raw_cmd_hash,
87
+ opts: nil
88
+ )
89
+ opts ||= DEFAULT_OPTS
90
+ new(raw_cmd_hash, opts:).build
91
+ end
92
+
93
+ def new_proc
94
+ ->(raw_cmd_hash) do
95
+ new(raw_cmd_hash)
96
+ end
97
+ end
98
+ # ----
99
+ end
100
+
101
+ # == Example
102
+ # require 'argvise'
103
+ # cmd = { ruby: nil, r: "argvise", verbose: true, e: true, "puts Argvise::VERSION": nil }
104
+ # opts = Argvise::DEFAULT_OPTS
105
+ # Argvise.new(cmd, opts:)
18
106
  #
19
- # @param options [Hash] The hash to be converted
20
- # @return [Array<String>] The generated array of command-line arguments
107
+ # == opts
108
+ # [Hash]: { bsd_style: Boolean, kebab_case_flags: Boolean }
21
109
  #
22
- # sig { params(options: Hash).returns(T::Array[String]) }
23
- def self.build(options)
24
- new.build(options)
110
+ # - When `bsd_style` is set to `false`, the builder operates in **GNU-style mode**,
111
+ # which typically uses hyphenated flags.
112
+ #
113
+ # - If `kebab_case_flags` is set to `true`, any underscores (`_`) in flag names
114
+ # will be automatically converted to hyphens (`-`).
115
+ # - For example, a flag like `--enable_jit` will be transformed into `--enable-jit`.
116
+ #
117
+ # > When the value of a flag key is `nil`, the `kebab_case_flags` option has
118
+ # > no effect — i.e., the key will not be transformed.
119
+ # >
120
+ # > For example, the input `{"a_b-c": nil}` will result in `["a_b-c"]`,
121
+ # > and **not** be automatically transformed into `["a-b-c"]`.
122
+ #
123
+ def initialize(
124
+ raw_cmd_hash,
125
+ opts: nil
126
+ )
127
+ opts = DEFAULT_OPTS.merge(opts || {})
128
+
129
+ @raw_cmd_hash = raw_cmd_hash
130
+ @bsd_style = opts[:bsd_style]
131
+ @kebab_case_flags = opts[:kebab_case_flags]
132
+ end
133
+
134
+ def with_bsd_style(value = true) # rubocop:disable Style/OptionalBooleanParameter
135
+ @bsd_style = value
136
+ self
137
+ end
138
+
139
+ def with_kebab_case_flags(value = true) # rubocop:disable Style/OptionalBooleanParameter
140
+ @kebab_case_flags = value
141
+ self
25
142
  end
26
143
 
27
- def build(options)
28
- # options.each_pair.flat_map { |k, v| process_pair(k.to_s, v) }
29
- options.each_with_object([]) do |(k, v), memo|
144
+ def build
145
+ # @raw_cmd_hash.each_pair.flat_map { |k, v| process_pair(k.to_s, v) }
146
+ @raw_cmd_hash.each_with_object([]) do |(k, v), memo|
30
147
  memo.concat(process_pair(k.to_s, v))
31
148
  end
32
149
  end
@@ -44,13 +161,42 @@ class Argvise
44
161
  generate_args(flag, value)
45
162
  end
46
163
 
47
- # Builds the command-line flag prefix (automatically detects short or long options)
164
+ # Builds the command-line flag prefix (automatically detects short or long raw_cmd_hash)
48
165
  #
49
- # short key, e.g., {v: true} => "-v"
50
- # long key, e.g., {verbose: true} => "--verbose"
51
- def build_flag(key)
52
- prefix = key.length == 1 ? '-' : '--'
53
- "#{prefix}#{key.tr('_', '-')}"
166
+ # GNU Style:
167
+ # - short key, e.g., {v: true} => "-v"
168
+ # - long key, e.g., {verbose: true} => "--verbose"
169
+ #
170
+ # BSD Style:
171
+ # - short key, e.g., {verbose: true} => "-verbose"
172
+ # - no long key
173
+ #
174
+ # @kebab_case_flags==true:
175
+ # - "_" => "-"
176
+ # - e.g., {enable_jit: true} =>
177
+ # - BSD-style: "-enable-jit"
178
+ # - GNU-style: "--enable-jit"
179
+ #
180
+ # @kebab_case_flags==false:
181
+ # - e.g., {enable_jit: true} =>
182
+ # - BSD-style: "-enable_jit"
183
+ # - GNU-style: "--enable_jit"
184
+ def build_flag(key) # rubocop:disable Metrics/MethodLength
185
+ prefix =
186
+ if @bsd_style
187
+ '-'
188
+ else
189
+ key.length == 1 ? '-' : '--'
190
+ end
191
+
192
+ flag =
193
+ if @kebab_case_flags
194
+ key.tr('_', '-')
195
+ else
196
+ key
197
+ end
198
+
199
+ "#{prefix}#{flag}"
54
200
  end
55
201
 
56
202
  # Generates the corresponding argument array based on the value type
@@ -95,12 +241,21 @@ end
95
241
 
96
242
  # A convenient lambda method: converts a hash into command-line arguments
97
243
  #
98
- # Example:
99
- # { v: true, path: '/path/to/dir' }.then(&hash_to_args) # => ["-v", "--path", "/path/to/dir"]
244
+ # == Example:
245
+ # { v: true, path: '/path/to/dir' }.then(&hash_to_argv)
246
+ # #=> ["-v", "--path", "/path/to/dir"]
247
+ #
248
+ # == raw_cmd_hash.then(&hash_to_argv) is equivalent to:
249
+ #
250
+ # raw_cmd_hash
251
+ # .then(&Argvise.new_proc)
252
+ # .with_bsd_style(false)
253
+ # .with_kebab_case_flags(true)
254
+ # .build
100
255
  #
101
- # sig { returns(T.proc.params(options: Hash).returns(T::Array[String])) }
102
- def hash_to_args
103
- ->(options) do
104
- Argvise.build(options)
256
+ # sig { returns(T.proc.params(raw_cmd_hash: Hash).returns(T::Array[String])) }
257
+ def hash_to_argv
258
+ ->(raw_cmd_hash) do
259
+ Argvise.build(raw_cmd_hash)
105
260
  end
106
261
  end
data/rbi/lib/argvise.rbi CHANGED
@@ -1,12 +1,35 @@
1
+ # rubocop:disable Style/Documentation, Lint/MissingCopEnableDirective
1
2
  # typed: true
2
3
  # frozen_string_literal: true
3
4
 
4
5
  class Argvise
5
6
  class << self
6
- sig { params(options: Hash).returns(T::Array[String]) }
7
- def build(options); end
7
+ sig do
8
+ params(
9
+ raw_cmd_hash: Hash,
10
+ opts: T.nilable(T::Hash[Symbol, T::Boolean])
11
+ ).returns(T::Array[String])
12
+ end
13
+ def build(raw_cmd_hash, opts: nil); end
8
14
  end
15
+
16
+ sig do
17
+ params(
18
+ raw_cmd_hash: Hash,
19
+ opts: T.nilable(T::Hash[Symbol, T::Boolean])
20
+ ).void
21
+ end
22
+ def initialize(raw_cmd_hash, opts: nil); end
23
+
24
+ sig { params(value: T::Boolean).returns(self) }
25
+ def with_bsd_style(value = true); end # rubocop:disable Style/OptionalBooleanParameter
26
+
27
+ sig { params(value: T::Boolean).returns(self) }
28
+ def with_kebab_case_flags(value = true); end # rubocop:disable Style/OptionalBooleanParameter
29
+
30
+ sig { returns(T::Array[String]) }
31
+ def build; end
9
32
  end
10
33
 
11
- sig { returns(T.proc.params(options: Hash).returns(T::Array[String])) }
12
- def hash_to_args; end
34
+ sig { returns(T.proc.params(raw_cmd_hash: T::Hash[T.any(Symbol, String), T.untyped]).returns(T::Array[String])) }
35
+ def hash_to_argv; end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: argvise
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.0.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - 2moe
@@ -17,7 +17,11 @@ executables: []
17
17
  extensions: []
18
18
  extra_rdoc_files: []
19
19
  files:
20
+ - ".rubocop.yml"
20
21
  - License
22
+ - argvise.gemspec
23
+ - bin/build.rb
24
+ - bin/console.rb
21
25
  - docs/Readme.md
22
26
  - lib/argvise.rb
23
27
  - lib/argvise/version.rb
@@ -35,14 +39,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
35
39
  requirements:
36
40
  - - ">="
37
41
  - !ruby/object:Gem::Version
38
- version: 3.0.0
42
+ version: 3.1.0
39
43
  required_rubygems_version: !ruby/object:Gem::Requirement
40
44
  requirements:
41
45
  - - ">="
42
46
  - !ruby/object:Gem::Version
43
47
  version: '0'
44
48
  requirements: []
45
- rubygems_version: 3.6.9
49
+ rubygems_version: 3.7.2
46
50
  specification_version: 4
47
51
  summary: Turns a hash into CLI arguments
48
52
  test_files: []