argvise 0.0.3 → 0.0.5
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 +215 -45
- data/lib/argvise/version.rb +2 -1
- data/lib/argvise.rb +1 -0
- data/lib/core.rb +198 -29
- data/rbi/lib/argvise.rbi +26 -3
- 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: cc2e3625fabe3294535d920c085b82f1c2718032de5f3921a7a9f74424c1ca5f
|
|
4
|
+
data.tar.gz: 2005628bc2fc53ea8937a310111b4217289051e3c634d5960287ed9e4db4dca0
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 1f78e1ea42b3d355ec65da36c69bbf31b7dfa7386c7483ed42c625ef15dc826f052e7009f040a47ef0f685a2f4d26de347edfeeba9c53c09cdb7941bc5b6915a
|
|
7
|
+
data.tar.gz: a9c6c99a0590f822f5dda6782a3a12c664008c8eff472c234f004e9b2fb69033e12dba58d8efd6c9bb77ec449cc97dab121cf875e80535f226f0ec29c3aea45c
|
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
|
@@ -2,40 +2,153 @@
|
|
|
2
2
|
|
|
3
3
|
[](https://rubygems.org/gems/argvise)
|
|
4
4
|
|
|
5
|
+
<!-- [](https://www.rubydoc.info/gems/argvise) -->
|
|
6
|
+
|
|
5
7
|
A Ruby gem for converting hash structures into command-line argument arrays.
|
|
6
8
|
|
|
7
9
|
> **Note:** This is *not* a command-line parser — quite the opposite. Argvise helps you **build** CLI commands programmatically.
|
|
8
10
|
|
|
11
|
+
## Quick Start
|
|
12
|
+
|
|
13
|
+
```ruby
|
|
14
|
+
# IRB
|
|
15
|
+
system "gem install argvise"
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
```ruby
|
|
19
|
+
# RUBY
|
|
20
|
+
require 'argvise'
|
|
21
|
+
|
|
22
|
+
{ cargo: nil, b: nil, r: true, target: "wasm32-wasip2" }
|
|
23
|
+
.then(&hash_to_argv)
|
|
24
|
+
|
|
25
|
+
#=> ["cargo", "b", "-r", "--target", "wasm32-wasip2"]
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
`raw_cmd_hash.then(&hash_to_argv)` is equivalent to:
|
|
29
|
+
|
|
30
|
+
```ruby
|
|
31
|
+
{ cargo: nil, b: nil, r: true, target: "wasm32-wasip2" }
|
|
32
|
+
.then(&Argvise.new_proc)
|
|
33
|
+
.with_bsd_style(false) #=> GNU style
|
|
34
|
+
.with_kebab_case_flags(true) #=> replace "--cli_flag" with "--cli-flag"
|
|
35
|
+
.build
|
|
36
|
+
```
|
|
37
|
+
|
|
9
38
|
## Installation
|
|
10
39
|
|
|
11
40
|
Add this line to your application's Gemfile:
|
|
12
41
|
|
|
13
42
|
```ruby
|
|
43
|
+
# Gemfile
|
|
44
|
+
#
|
|
14
45
|
gem 'argvise'
|
|
15
46
|
```
|
|
16
47
|
|
|
17
48
|
And then execute:
|
|
18
49
|
|
|
19
|
-
```
|
|
50
|
+
```sh
|
|
51
|
+
# SHELL
|
|
52
|
+
#
|
|
20
53
|
bundler install
|
|
21
54
|
```
|
|
22
55
|
|
|
23
56
|
Or install it directly:
|
|
24
57
|
|
|
25
|
-
```
|
|
58
|
+
```sh
|
|
59
|
+
# SHELL
|
|
60
|
+
#
|
|
26
61
|
gem install argvise
|
|
27
62
|
```
|
|
28
63
|
|
|
29
|
-
##
|
|
64
|
+
## Conversion Rules
|
|
65
|
+
|
|
66
|
+
### Common
|
|
67
|
+
|
|
68
|
+
| Hash Format | Result |
|
|
69
|
+
| ----------------------- | ---------------------------- |
|
|
70
|
+
| `{ "-k2": nil }` | `["-k2"]` |
|
|
71
|
+
| `{ "--r_a-w_": nil }` | `["--r_a-w_"]` |
|
|
72
|
+
| `{ key: nil }` | `["key"]` |
|
|
73
|
+
| `{ key: [] }` | `[]` |
|
|
74
|
+
| `{ key: {} }` | `[]` |
|
|
75
|
+
| `{ key: false }` | `[]` |
|
|
76
|
+
| `{ k: true }` | `["-k"]` |
|
|
77
|
+
| `{ k: "value" }` | `["-k", "value"]` |
|
|
78
|
+
| `{ k: ["a", "b"] }` | `["-k", "a", "-k", "b"]` |
|
|
79
|
+
| `{ k: { a: 1, b: 2 } }` | `["-k", "a=1", "-k", "b=2"]` |
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
### GNU Style
|
|
83
|
+
|
|
84
|
+
| Hash Format | Result |
|
|
85
|
+
| ------------------------- | ---------------------------------- |
|
|
86
|
+
| `{ key: true }` | `["--key"]` |
|
|
87
|
+
| `{ key: "value" }` | `["--key", "value"]` |
|
|
88
|
+
| `{ key: ["a", "b"] }` | `["--key", "a", "--key", "b"]` |
|
|
89
|
+
| `{ key: { a: 1, b: 2 } }` | `["--key", "a=1", "--key", "b=2"]` |
|
|
90
|
+
|
|
91
|
+
---
|
|
92
|
+
|
|
93
|
+
#### `with_kebab_case_flags(true)`:
|
|
94
|
+
|
|
95
|
+
| Hash Format | Result |
|
|
96
|
+
| ----------------- | ------------- |
|
|
97
|
+
| `{ key_a: true }` | `["--key-a"]` |
|
|
98
|
+
|
|
99
|
+
---
|
|
100
|
+
|
|
101
|
+
#### `with_kebab_case_flags(false)`:
|
|
102
|
+
|
|
103
|
+
| Hash Format | Result |
|
|
104
|
+
| ----------------- | ------------- |
|
|
105
|
+
| `{ key_b: true }` | `["--key_b"]` |
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
### BSD Style
|
|
30
109
|
|
|
31
|
-
|
|
110
|
+
| Hash Format | Result |
|
|
111
|
+
| ------------------------- | -------------------------------- |
|
|
112
|
+
| `{ key: true }` | `["-key"]` |
|
|
113
|
+
| `{ key: "value" }` | `["-key", "value"]` |
|
|
114
|
+
| `{ key: ["a", "b"] }` | `["-key", "a", "-key", "b"]` |
|
|
115
|
+
| `{ key: { a: 1, b: 2 } }` | `["-key", "a=1", "-key", "b=2"]` |
|
|
116
|
+
|
|
117
|
+
---
|
|
118
|
+
|
|
119
|
+
#### `with_kebab_case_flags(true)`:
|
|
120
|
+
|
|
121
|
+
| Hash Format | Result |
|
|
122
|
+
| ----------------- | ------------ |
|
|
123
|
+
| `{ key_c: true }` | `["-key-c"]` |
|
|
124
|
+
|
|
125
|
+
---
|
|
126
|
+
|
|
127
|
+
#### `with_kebab_case_flags(false)`:
|
|
128
|
+
|
|
129
|
+
| Hash Format | Result |
|
|
130
|
+
| ----------------- | ------------ |
|
|
131
|
+
| `{ key_d: true }` | `["-key_d"]` |
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
### Notes
|
|
135
|
+
|
|
136
|
+
> When the value of a flag key is `nil`, the `kebab_case_flags` option has
|
|
137
|
+
> no effect — i.e., the key will not be transformed.
|
|
138
|
+
>
|
|
139
|
+
> For example, the input `{"a_b-c": nil}` will result in `["a_b-c"]`,
|
|
140
|
+
> and **not** be automatically transformed into `["a-b-c"]`.
|
|
141
|
+
|
|
142
|
+
## Examples
|
|
143
|
+
|
|
144
|
+
### Basic Conversion (GNU Style)
|
|
32
145
|
|
|
33
146
|
```ruby
|
|
34
147
|
require 'argvise'
|
|
35
148
|
|
|
36
|
-
|
|
149
|
+
raw_cmd_hash = {
|
|
37
150
|
docker: nil, #=> docker
|
|
38
|
-
build: nil,
|
|
151
|
+
build: nil,
|
|
39
152
|
push: true, #=> --push
|
|
40
153
|
tag: ["ghcr.io/[user]/repo:latest", "ghcr.io/[user]/repo:v0.0.1"], #=> --tag ghcr... --tag ghcr..0.0.1
|
|
41
154
|
platform: "wasi/wasm", #=> --platform wasi/wasm
|
|
@@ -47,12 +160,12 @@ options = {
|
|
|
47
160
|
path: nil,
|
|
48
161
|
}
|
|
49
162
|
|
|
50
|
-
Argvise.build(
|
|
163
|
+
Argvise.build(raw_cmd_hash)
|
|
51
164
|
# => [
|
|
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",
|
|
165
|
+
# "docker", "build", "--push",
|
|
166
|
+
# "--tag", "ghcr.io/[user]/repo:latest", "--tag", "ghcr.io/[user]/repo:v0.0.1",
|
|
167
|
+
# "--platform", "wasi/wasm",
|
|
168
|
+
# "--label", "maintainer=user", "--label", "description=A Docker build example",
|
|
56
169
|
# "--file", "wasi.dockerfile", "path"
|
|
57
170
|
# ]
|
|
58
171
|
```
|
|
@@ -64,56 +177,113 @@ Argvise.build(options)
|
|
|
64
177
|
# => ["-v", "--dir", "/path/to/dir"]
|
|
65
178
|
```
|
|
66
179
|
|
|
67
|
-
|
|
180
|
+
### Configurable builder
|
|
68
181
|
|
|
69
|
-
|
|
182
|
+
> Required
|
|
183
|
+
> - argvise: >= v0.0.4
|
|
184
|
+
> - ruby: >= v3.1.0
|
|
70
185
|
|
|
71
186
|
```ruby
|
|
72
|
-
|
|
187
|
+
raw_cmd = {
|
|
188
|
+
compiler: nil,
|
|
189
|
+
build: nil,
|
|
190
|
+
pack_type: 'tar+zstd',
|
|
191
|
+
push: true,
|
|
192
|
+
v: true,
|
|
193
|
+
f: 'p2',
|
|
194
|
+
tag: ['v0.0.1', 'beta'],
|
|
195
|
+
platform: 'wasi/wasm',
|
|
196
|
+
label: {
|
|
197
|
+
maintainer: 'user',
|
|
198
|
+
description: 'Demo'
|
|
199
|
+
},
|
|
200
|
+
"/path/to/dir": nil
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
p '----------------'
|
|
204
|
+
p "GNU-style + kebab case flags=false"
|
|
205
|
+
raw_cmd
|
|
206
|
+
.then(&Argvise.new_proc)
|
|
207
|
+
.with_bsd_style(false)
|
|
208
|
+
.with_kebab_case_flags(false)
|
|
209
|
+
.build
|
|
210
|
+
.display
|
|
211
|
+
|
|
212
|
+
#=> ["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"]
|
|
213
|
+
|
|
214
|
+
p '----------------'
|
|
215
|
+
p 'GNU-style + kebab-case-flags=true'
|
|
216
|
+
raw_cmd
|
|
217
|
+
.then(&hash_to_argv)
|
|
218
|
+
.display
|
|
219
|
+
|
|
220
|
+
#=> ["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"]
|
|
221
|
+
|
|
222
|
+
p '----------------'
|
|
223
|
+
p 'BSD-style + kebab-case-flags=true'
|
|
224
|
+
raw_cmd
|
|
225
|
+
.then(&Argvise.new_proc)
|
|
226
|
+
.with_bsd_style
|
|
227
|
+
.with_kebab_case_flags
|
|
228
|
+
.build
|
|
229
|
+
.display
|
|
230
|
+
|
|
231
|
+
#=> ["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
232
|
```
|
|
74
233
|
|
|
75
|
-
|
|
234
|
+
## Data Type
|
|
76
235
|
|
|
77
|
-
|
|
78
|
-
{ silent: false }.then(&hash_to_argv) # => []
|
|
79
|
-
```
|
|
236
|
+
### Boolean
|
|
80
237
|
|
|
81
|
-
|
|
238
|
+
#### GNU style
|
|
82
239
|
|
|
83
|
-
|
|
84
|
-
{
|
|
85
|
-
|
|
86
|
-
```
|
|
240
|
+
- `{ verbose: true }` => "--verbose"
|
|
241
|
+
- `{ v: true }` => "-v"
|
|
242
|
+
- `{ v: false }` => no argument generated
|
|
87
243
|
|
|
88
|
-
|
|
244
|
+
#### BSD style
|
|
89
245
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
```
|
|
246
|
+
- `{ verbose: true }` => "-verbose"
|
|
247
|
+
- `{ v: true }` => "-v"
|
|
248
|
+
- `{ v: false }` => no argument generated
|
|
94
249
|
|
|
95
|
-
|
|
250
|
+
### String
|
|
96
251
|
|
|
97
|
-
|
|
252
|
+
#### GNU style
|
|
98
253
|
|
|
99
|
-
|
|
254
|
+
- `{ f: "a.txt" }` => `["-f", "a.txt"]`
|
|
255
|
+
- `{ file: "a.txt" }` => `["--file", "a.txt"]`
|
|
100
256
|
|
|
101
|
-
|
|
257
|
+
#### BSD style
|
|
102
258
|
|
|
103
|
-
- `
|
|
259
|
+
- `{ f: "a.txt" }` => `["-f", "a.txt"]`
|
|
260
|
+
- `{ file: "a.txt" }` => `["-file", "a.txt"]`
|
|
104
261
|
|
|
105
|
-
|
|
262
|
+
### Array
|
|
106
263
|
|
|
107
|
-
|
|
264
|
+
#### GNU style
|
|
108
265
|
|
|
109
|
-
|
|
266
|
+
- `{ t: ["a", "b"] }` => `["-t", "a", "-t", "b"]`
|
|
267
|
+
- `{ tag: %w[a b] }` => `["--tag", "a", "--tag", "b"]`
|
|
110
268
|
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
269
|
+
#### BSD style
|
|
270
|
+
|
|
271
|
+
- `{ t: ["a", "b"] }` => `["-t", "a", "-t", "b"]`
|
|
272
|
+
- `{ tag: %w[a b] }` => `["-tag", "a", "-tag", "b"]`
|
|
273
|
+
|
|
274
|
+
### Hash
|
|
275
|
+
|
|
276
|
+
#### GNU style
|
|
277
|
+
|
|
278
|
+
- `{ e: { profile: 'test', lang: 'C'} }` => `["-e", "profile=test", "-e", "lang=C"]`
|
|
279
|
+
- `{ env: { profile: 'test', lang: 'C'} }` => `["--env", "profile=test", "--env", "lang=C"]`
|
|
280
|
+
|
|
281
|
+
#### BSD style
|
|
282
|
+
|
|
283
|
+
- `{ e: { profile: 'test', lang: 'C'} }` => `["-e", "profile=test", "-e", "lang=C"]`
|
|
284
|
+
- `{ env: { profile: 'test', lang: 'C'} }` => `["-env", "profile=test", "-env", "lang=C"]`
|
|
285
|
+
|
|
286
|
+
## Nil => Raw
|
|
287
|
+
|
|
288
|
+
- `{ cargo: nil, b: nil}` => `["cargo", "b"]`
|
|
289
|
+
- `{ "-fv": nil}` => `["-fv"]`
|
data/lib/argvise/version.rb
CHANGED
data/lib/argvise.rb
CHANGED
data/lib/core.rb
CHANGED
|
@@ -1,32 +1,163 @@
|
|
|
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, b: nil, r: true, target: "wasm32-wasip2" }
|
|
11
|
+
# .then(&Argvise.new_proc)
|
|
12
|
+
# .with_bsd_style(false)
|
|
13
|
+
# .build
|
|
14
|
+
# .display
|
|
15
|
+
#
|
|
16
|
+
# #=> ["cargo", "b", "-r", "--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
|
+
# Returns a Proc that wraps `Argvise.new`, allowing functional-style chaining.
|
|
94
|
+
#
|
|
95
|
+
# Useful for transforming a hash of CLI arguments into a command array.
|
|
96
|
+
#
|
|
97
|
+
# == Example
|
|
98
|
+
#
|
|
99
|
+
# require 'argvise'
|
|
100
|
+
# { ruby: nil, r: "argvise", e: true, "puts Argvise::VERSION": nil }
|
|
101
|
+
# .then(&Argvise.new_proc)
|
|
102
|
+
# .build
|
|
103
|
+
# .then{system *_1}
|
|
104
|
+
#
|
|
105
|
+
# > See also: [self.new]
|
|
106
|
+
def new_proc
|
|
107
|
+
->(raw_cmd_hash) do
|
|
108
|
+
new(raw_cmd_hash)
|
|
109
|
+
end
|
|
110
|
+
end
|
|
111
|
+
# ----
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
# == Example
|
|
115
|
+
#
|
|
116
|
+
# require 'argvise'
|
|
117
|
+
# cmd = { ruby: nil, r: "argvise", verbose: true, e: true, "puts Argvise::VERSION": nil }
|
|
118
|
+
# opts = Argvise::DEFAULT_OPTS
|
|
119
|
+
# Argvise.new(cmd, opts:).build.then{system *_1}
|
|
18
120
|
#
|
|
19
|
-
#
|
|
20
|
-
#
|
|
121
|
+
# == opts
|
|
122
|
+
# [Hash]: { bsd_style: Boolean, kebab_case_flags: Boolean }
|
|
21
123
|
#
|
|
22
|
-
#
|
|
23
|
-
|
|
24
|
-
|
|
124
|
+
# - When `bsd_style` is set to `false`, the builder operates in **GNU-style mode**,
|
|
125
|
+
# which typically uses hyphenated flags.
|
|
126
|
+
#
|
|
127
|
+
# - If `kebab_case_flags` is set to `true`, any underscores (`_`) in flag names
|
|
128
|
+
# will be automatically converted to hyphens (`-`).
|
|
129
|
+
# - For example, a flag like `--enable_jit` will be transformed into `--enable-jit`.
|
|
130
|
+
#
|
|
131
|
+
# When the value of a flag key is `nil`, the `kebab_case_flags` option has no effect
|
|
132
|
+
# — i.e., the key will not be transformed.
|
|
133
|
+
#
|
|
134
|
+
# For example, the input `{"a_b-c": nil}` will result in `["a_b-c"]`,
|
|
135
|
+
# and **not** be automatically transformed into `["a-b-c"]`.
|
|
136
|
+
#
|
|
137
|
+
def initialize(
|
|
138
|
+
raw_cmd_hash,
|
|
139
|
+
opts: nil
|
|
140
|
+
)
|
|
141
|
+
opts = DEFAULT_OPTS.merge(opts || {})
|
|
142
|
+
|
|
143
|
+
@raw_cmd_hash = raw_cmd_hash
|
|
144
|
+
@bsd_style = opts[:bsd_style]
|
|
145
|
+
@kebab_case_flags = opts[:kebab_case_flags]
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
def with_bsd_style(value = true) # rubocop:disable Style/OptionalBooleanParameter
|
|
149
|
+
@bsd_style = value
|
|
150
|
+
self
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
def with_kebab_case_flags(value = true) # rubocop:disable Style/OptionalBooleanParameter
|
|
154
|
+
@kebab_case_flags = value
|
|
155
|
+
self
|
|
25
156
|
end
|
|
26
157
|
|
|
27
|
-
def build
|
|
28
|
-
#
|
|
29
|
-
|
|
158
|
+
def build
|
|
159
|
+
# @raw_cmd_hash.each_pair.flat_map { |k, v| process_pair(k.to_s, v) }
|
|
160
|
+
@raw_cmd_hash.each_with_object([]) do |(k, v), memo|
|
|
30
161
|
memo.concat(process_pair(k.to_s, v))
|
|
31
162
|
end
|
|
32
163
|
end
|
|
@@ -44,13 +175,42 @@ class Argvise
|
|
|
44
175
|
generate_args(flag, value)
|
|
45
176
|
end
|
|
46
177
|
|
|
47
|
-
# Builds the command-line flag prefix (automatically detects short or long
|
|
178
|
+
# Builds the command-line flag prefix (automatically detects short or long raw_cmd_hash)
|
|
179
|
+
#
|
|
180
|
+
# GNU Style:
|
|
181
|
+
# - short key, e.g., {v: true} => "-v"
|
|
182
|
+
# - long key, e.g., {verbose: true} => "--verbose"
|
|
183
|
+
#
|
|
184
|
+
# BSD Style:
|
|
185
|
+
# - short key, e.g., {verbose: true} => "-verbose"
|
|
186
|
+
# - no long key
|
|
187
|
+
#
|
|
188
|
+
# @kebab_case_flags==true:
|
|
189
|
+
# - "_" => "-"
|
|
190
|
+
# - e.g., {enable_jit: true} =>
|
|
191
|
+
# - BSD-style: "-enable-jit"
|
|
192
|
+
# - GNU-style: "--enable-jit"
|
|
48
193
|
#
|
|
49
|
-
#
|
|
50
|
-
#
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
194
|
+
# @kebab_case_flags==false:
|
|
195
|
+
# - e.g., {enable_jit: true} =>
|
|
196
|
+
# - BSD-style: "-enable_jit"
|
|
197
|
+
# - GNU-style: "--enable_jit"
|
|
198
|
+
def build_flag(key) # rubocop:disable Metrics/MethodLength
|
|
199
|
+
prefix =
|
|
200
|
+
if @bsd_style
|
|
201
|
+
'-'
|
|
202
|
+
else
|
|
203
|
+
key.length == 1 ? '-' : '--'
|
|
204
|
+
end
|
|
205
|
+
|
|
206
|
+
flag =
|
|
207
|
+
if @kebab_case_flags
|
|
208
|
+
key.tr('_', '-')
|
|
209
|
+
else
|
|
210
|
+
key
|
|
211
|
+
end
|
|
212
|
+
|
|
213
|
+
"#{prefix}#{flag}"
|
|
54
214
|
end
|
|
55
215
|
|
|
56
216
|
# Generates the corresponding argument array based on the value type
|
|
@@ -95,12 +255,21 @@ end
|
|
|
95
255
|
|
|
96
256
|
# A convenient lambda method: converts a hash into command-line arguments
|
|
97
257
|
#
|
|
98
|
-
# Example:
|
|
99
|
-
# { v: true, path: '/path/to/dir' }.then(&hash_to_argv)
|
|
258
|
+
# == Example:
|
|
259
|
+
# { v: true, path: '/path/to/dir' }.then(&hash_to_argv)
|
|
260
|
+
# #=> ["-v", "--path", "/path/to/dir"]
|
|
261
|
+
#
|
|
262
|
+
# == raw_cmd_hash.then(&hash_to_argv) is equivalent to:
|
|
263
|
+
#
|
|
264
|
+
# raw_cmd_hash
|
|
265
|
+
# .then(&Argvise.new_proc)
|
|
266
|
+
# .with_bsd_style(false)
|
|
267
|
+
# .with_kebab_case_flags(true)
|
|
268
|
+
# .build
|
|
100
269
|
#
|
|
101
|
-
# sig { returns(T.proc.params(
|
|
270
|
+
# sig { returns(T.proc.params(raw_cmd_hash: Hash).returns(T::Array[String])) }
|
|
102
271
|
def hash_to_argv
|
|
103
|
-
->(
|
|
104
|
-
Argvise.build(
|
|
272
|
+
->(raw_cmd_hash) do
|
|
273
|
+
Argvise.build(raw_cmd_hash)
|
|
105
274
|
end
|
|
106
275
|
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(
|
|
34
|
+
sig { returns(T.proc.params(raw_cmd_hash: T::Hash[T.any(Symbol, String), T.untyped]).returns(T::Array[String])) }
|
|
12
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.5
|
|
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: []
|