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 +4 -4
- data/.rubocop.yml +2 -0
- data/argvise.gemspec +47 -0
- data/bin/build.rb +19 -0
- data/bin/console.rb +63 -0
- data/docs/Readme.md +213 -46
- data/lib/argvise/version.rb +2 -1
- data/lib/argvise.rb +1 -0
- data/lib/core.rb +185 -30
- data/rbi/lib/argvise.rbi +27 -4
- metadata +7 -3
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: d63847d3264553ea75e063063330aff39cb7638bb22d4a227664dfef0f55203b
|
|
4
|
+
data.tar.gz: 44335dc0284501d472b81c9427b939000ade17971d0657727b81cc97a4ad631d
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 331dac661ca76f65e605c027be9217b213a97340530c4d4ebe2871979197f37fef9bb6f0ccfe92034faeeb1b879df1db2a180e932dfb992e6b0ae0b4720a690a
|
|
7
|
+
data.tar.gz: c00671dfccfba16990b7aff2db61612cbde3ca3b478a6e4b0369181ad6a58aabff3fa28257174bb701fa028b5e6267d227c13b78b85dfc043e8b81309d40de03
|
data/.rubocop.yml
ADDED
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
|
-
```
|
|
48
|
+
```sh
|
|
49
|
+
# SHELL
|
|
50
|
+
#
|
|
20
51
|
bundler install
|
|
21
52
|
```
|
|
22
53
|
|
|
23
54
|
Or install it directly:
|
|
24
55
|
|
|
25
|
-
```
|
|
56
|
+
```sh
|
|
57
|
+
# SHELL
|
|
58
|
+
#
|
|
26
59
|
gem install argvise
|
|
27
60
|
```
|
|
28
61
|
|
|
29
|
-
##
|
|
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
|
-
|
|
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
|
-
|
|
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(
|
|
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(&
|
|
173
|
+
{ v: true, dir: '/path/to/dir' }.then(&hash_to_argv)
|
|
64
174
|
# => ["-v", "--dir", "/path/to/dir"]
|
|
65
175
|
```
|
|
66
176
|
|
|
67
|
-
|
|
177
|
+
### Configurable builder
|
|
68
178
|
|
|
69
|
-
|
|
179
|
+
> Required
|
|
180
|
+
> - argvise: >= v0.0.4
|
|
181
|
+
> - ruby: >= v3.1.0
|
|
70
182
|
|
|
71
183
|
```ruby
|
|
72
|
-
|
|
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
|
-
|
|
231
|
+
## Data Type
|
|
76
232
|
|
|
77
|
-
|
|
78
|
-
{ silent: false }.then(&hash_to_args) # => []
|
|
79
|
-
```
|
|
233
|
+
### Boolean
|
|
80
234
|
|
|
81
|
-
|
|
235
|
+
#### GNU style
|
|
82
236
|
|
|
83
|
-
|
|
84
|
-
{
|
|
85
|
-
|
|
86
|
-
```
|
|
237
|
+
- `{ verbose: true }` => "--verbose"
|
|
238
|
+
- `{ v: true }` => "-v"
|
|
239
|
+
- `{ v: false }` => no argument generated
|
|
87
240
|
|
|
88
|
-
|
|
241
|
+
#### BSD style
|
|
89
242
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
```
|
|
243
|
+
- `{ verbose: true }` => "-verbose"
|
|
244
|
+
- `{ v: true }` => "-v"
|
|
245
|
+
- `{ v: false }` => no argument generated
|
|
94
246
|
|
|
95
|
-
|
|
247
|
+
### String
|
|
96
248
|
|
|
97
|
-
|
|
249
|
+
#### GNU style
|
|
98
250
|
|
|
99
|
-
|
|
251
|
+
- `{ f: "a.txt" }` => `["-f", "a.txt"]`
|
|
252
|
+
- `{ file: "a.txt" }` => `["--file", "a.txt"]`
|
|
100
253
|
|
|
101
|
-
|
|
254
|
+
#### BSD style
|
|
102
255
|
|
|
103
|
-
- `
|
|
256
|
+
- `{ f: "a.txt" }` => `["-f", "a.txt"]`
|
|
257
|
+
- `{ file: "a.txt" }` => `["-file", "a.txt"]`
|
|
104
258
|
|
|
105
|
-
|
|
259
|
+
### Array
|
|
106
260
|
|
|
107
|
-
|
|
261
|
+
#### GNU style
|
|
108
262
|
|
|
109
|
-
|
|
263
|
+
- `{ t: ["a", "b"] }` => `["-t", "a", "-t", "b"]`
|
|
264
|
+
- `{ tag: %w[a b] }` => `["--tag", "a", "--tag", "b"]`
|
|
110
265
|
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
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"]`
|
data/lib/argvise/version.rb
CHANGED
data/lib/argvise.rb
CHANGED
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
|
-
#
|
|
9
|
-
#
|
|
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
|
-
#
|
|
12
|
-
#
|
|
13
|
-
#
|
|
14
|
-
# -
|
|
15
|
-
# -
|
|
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
|
-
|
|
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
|
-
#
|
|
20
|
-
#
|
|
107
|
+
# == opts
|
|
108
|
+
# [Hash]: { bsd_style: Boolean, kebab_case_flags: Boolean }
|
|
21
109
|
#
|
|
22
|
-
#
|
|
23
|
-
|
|
24
|
-
|
|
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
|
|
28
|
-
#
|
|
29
|
-
|
|
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
|
|
164
|
+
# Builds the command-line flag prefix (automatically detects short or long raw_cmd_hash)
|
|
48
165
|
#
|
|
49
|
-
#
|
|
50
|
-
#
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
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(&
|
|
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(
|
|
102
|
-
def
|
|
103
|
-
->(
|
|
104
|
-
Argvise.build(
|
|
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
|
|
7
|
-
|
|
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(
|
|
12
|
-
def
|
|
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.
|
|
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.
|
|
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.
|
|
49
|
+
rubygems_version: 3.7.2
|
|
46
50
|
specification_version: 4
|
|
47
51
|
summary: Turns a hash into CLI arguments
|
|
48
52
|
test_files: []
|