dry-cli 1.2.0 → 1.4.0
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/CHANGELOG.md +113 -83
- data/LICENSE +1 -1
- data/README.md +8 -13
- data/dry-cli.gemspec +11 -11
- data/lib/dry/cli/banner.rb +3 -3
- data/lib/dry/cli/command.rb +45 -2
- data/lib/dry/cli/command_registry.rb +2 -4
- data/lib/dry/cli/errors.rb +4 -0
- data/lib/dry/cli/inline.rb +1 -1
- data/lib/dry/cli/option.rb +12 -0
- data/lib/dry/cli/parser.rb +19 -12
- data/lib/dry/cli/registry.rb +10 -1
- data/lib/dry/cli/usage.rb +2 -2
- data/lib/dry/cli/version.rb +1 -1
- data/lib/dry/cli.rb +11 -4
- metadata +21 -54
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 92920db180b09c97eece82f48b921162625b30cd41e5ac5c1f86fb623012a939
|
|
4
|
+
data.tar.gz: 3dc7e165cc9164546106cd52311f5db44b7e620a0acb2eaceb1a572bbfde1ee8
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: '092186ca495d29592e2f24b1cbbecf981f1b3fb50065d61d0250055dce0fb2f419674daeb99d5771539721583417715b639f2c896c1135fa56fa7b420430fcdb'
|
|
7
|
+
data.tar.gz: 77e603998b0a56a3d19ee97c939ad00333b7262568c29d97463b39c3f442b60e5f85d3484fc7dd713e4fd96076a24d55ef8f37ffde0cfad164dd0b1fafaade6d
|
data/CHANGELOG.md
CHANGED
|
@@ -1,37 +1,102 @@
|
|
|
1
|
-
|
|
1
|
+
# Changelog
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
4
|
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
|
+
and this project adheres to [Break Versioning](https://www.taoensso.com/break-versioning).
|
|
7
|
+
|
|
8
|
+
## [Unreleased]
|
|
5
9
|
|
|
6
10
|
### Added
|
|
7
11
|
|
|
8
|
-
|
|
9
|
-
|
|
12
|
+
### Changed
|
|
13
|
+
|
|
14
|
+
### Deprecated
|
|
10
15
|
|
|
16
|
+
### Removed
|
|
11
17
|
|
|
12
|
-
|
|
18
|
+
### Fixed
|
|
19
|
+
|
|
20
|
+
### Security
|
|
13
21
|
|
|
14
|
-
|
|
22
|
+
[Unreleased]: https://github.com/dry-rb/dry-cli/compare/v1.4.0...main
|
|
15
23
|
|
|
24
|
+
## [1.4.0] - 2026-01-09
|
|
16
25
|
|
|
17
26
|
### Added
|
|
18
27
|
|
|
19
|
-
-
|
|
28
|
+
- Provide the CLI’s `out` and `err` streams to command instances (unless `@out` and `@err` ivars already exist in the command). (@aaronmallen in #150)
|
|
29
|
+
|
|
30
|
+
### Changed
|
|
31
|
+
|
|
32
|
+
- Require Ruby 3.2 or later. (@timriley)
|
|
33
|
+
|
|
34
|
+
### Fixed
|
|
35
|
+
|
|
36
|
+
- Pass a commands keyword arguments to any related callbacks. (@gustavothecoder in #136)
|
|
37
|
+
- Avoid duplicated option names in `--help` output when a subclass re-defines an option. (@gustavothecoder in #143)
|
|
38
|
+
- Properly raise an error when an invalid value is passed to an option (previously this was working for arguments only, not options). (@gustavothecoder in #142)
|
|
39
|
+
|
|
40
|
+
[1.4.0]: https://github.com/dry-rb/dry-cli/compare/v1.3.0...v1.4.0
|
|
41
|
+
|
|
42
|
+
## [1.3.0] - 2025-07-29
|
|
43
|
+
|
|
44
|
+
### Added
|
|
45
|
+
|
|
46
|
+
- Support unlimited nesting when registering commands via `register` with blocks. (@aaronmallen in #149)
|
|
20
47
|
|
|
48
|
+
You could previously do this only with fully qualified registrations:
|
|
21
49
|
|
|
22
|
-
|
|
50
|
+
```ruby
|
|
51
|
+
Commands.register "nested one", MyFirstNestedCommand
|
|
52
|
+
Commands.register "nested one two", MySecondNestedCommand
|
|
53
|
+
Commands.register "nested one two three", MyThirdNestedCommand
|
|
54
|
+
```
|
|
23
55
|
|
|
24
|
-
|
|
56
|
+
Now you can do the same via blocks:
|
|
25
57
|
|
|
58
|
+
```ruby
|
|
59
|
+
Commands.register "nested" do
|
|
60
|
+
register "one", MyFirstNestedCommand do
|
|
61
|
+
register "two", MySecondNestedCommand do
|
|
62
|
+
register "three", MyThirdNestedCommand
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
```
|
|
26
67
|
|
|
27
68
|
### Changed
|
|
28
69
|
|
|
29
|
-
-
|
|
70
|
+
- Set minimum Ruby version to 3.1. (@timriley)
|
|
71
|
+
|
|
72
|
+
[1.3.0]: https://github.com/dry-rb/dry-cli/compare/v1.2.0...v1.3.0
|
|
30
73
|
|
|
31
|
-
[
|
|
74
|
+
## [1.2.0] - 2024-10-15
|
|
32
75
|
|
|
33
|
-
|
|
76
|
+
### Added
|
|
34
77
|
|
|
78
|
+
- Added `:hidden` option to register commands that should not be shown in the help output. (@benoittgt in #137)
|
|
79
|
+
- Provide suggestions when there is a typo in a command name. (@benoittgt in #138)
|
|
80
|
+
|
|
81
|
+
[1.2.0]: https://github.com/dry-rb/dry-cli/compare/v1.1.0...v1.2.0
|
|
82
|
+
|
|
83
|
+
## [1.1.0] - 2024-07-14
|
|
84
|
+
|
|
85
|
+
### Added
|
|
86
|
+
|
|
87
|
+
- Added `:flag` option type. This acts like a `:boolean` that can only be set to true, so has no `--no-` prefix to disable it. (@Billiam in #117)
|
|
88
|
+
|
|
89
|
+
[1.1.0]: https://github.com/dry-rb/dry-cli/compare/v1.0.0...v1.1.0
|
|
90
|
+
|
|
91
|
+
## [1.0.0] - 2022-11-05
|
|
92
|
+
|
|
93
|
+
### Changed
|
|
94
|
+
|
|
95
|
+
- Version bumped to 1.0.0 (@solnic)
|
|
96
|
+
|
|
97
|
+
[1.0.0]: https://github.com/dry-rb/dry-cli/compare/v0.7.0...v1.0.0
|
|
98
|
+
|
|
99
|
+
## [0.7.0] - 2020-05-08
|
|
35
100
|
|
|
36
101
|
### Added
|
|
37
102
|
|
|
@@ -55,10 +120,9 @@
|
|
|
55
120
|
- Remove concurrent-ruby as runtime dependency (@jodosha)
|
|
56
121
|
- [Internal] Banner and Parses refactoring (@IvanShamatov)
|
|
57
122
|
|
|
58
|
-
[
|
|
59
|
-
|
|
60
|
-
## 0.6.0 2020-03-06
|
|
123
|
+
[0.7.0]: https://github.com/dry-rb/dry-cli/compare/v0.6.0...v0.7.0
|
|
61
124
|
|
|
125
|
+
## [0.6.0] - 2020-03-06
|
|
62
126
|
|
|
63
127
|
### Added
|
|
64
128
|
|
|
@@ -72,11 +136,9 @@
|
|
|
72
136
|
- [John Ledbetter & Luca Guidi] Fix ruby 2.7 warnings (@jodosha)
|
|
73
137
|
- Fix banner, when option is a type of Array (@IvanShamatov)
|
|
74
138
|
|
|
139
|
+
[0.6.0]: https://github.com/dry-rb/dry-cli/compare/v0.5.1...v0.6.0
|
|
75
140
|
|
|
76
|
-
[
|
|
77
|
-
|
|
78
|
-
## 0.5.1 2020-01-23
|
|
79
|
-
|
|
141
|
+
## [0.5.1] - 2020-01-23
|
|
80
142
|
|
|
81
143
|
### Added
|
|
82
144
|
|
|
@@ -90,48 +152,38 @@
|
|
|
90
152
|
|
|
91
153
|
- Added missing 'set' require (@solnic)
|
|
92
154
|
|
|
155
|
+
[0.5.1]: https://github.com/dry-rb/dry-cli/compare/v0.5.0...v0.5.1
|
|
93
156
|
|
|
94
|
-
[
|
|
95
|
-
|
|
96
|
-
## 0.5.0 2019-12-21
|
|
97
|
-
|
|
157
|
+
## [0.5.0] - 2019-12-21
|
|
98
158
|
|
|
99
159
|
### Added
|
|
100
160
|
|
|
101
161
|
- [Internal] removed runtime and development dependency against `hanami-utils` (@jodosha, @IvanShamatov, @solnic)
|
|
102
162
|
|
|
163
|
+
[0.5.0]: https://github.com/dry-rb/dry-cli/compare/v0.4.0...v0.5.0
|
|
103
164
|
|
|
104
|
-
[
|
|
105
|
-
|
|
106
|
-
## 0.4.0 2019-12-10
|
|
107
|
-
|
|
165
|
+
## [0.4.0] - 2019-12-10
|
|
108
166
|
|
|
109
167
|
### Added
|
|
110
168
|
|
|
111
169
|
- `hanami-cli` => `dry-cli` (@jodosha, @IvanShamatov, @solnic)
|
|
112
170
|
|
|
171
|
+
[0.4.0]: https://github.com/dry-rb/dry-cli/compare/v0.3.1...v0.4.0
|
|
113
172
|
|
|
114
|
-
[
|
|
115
|
-
|
|
116
|
-
## 0.3.1 2019-01-18
|
|
117
|
-
|
|
173
|
+
## [0.3.1] - 2019-01-18
|
|
118
174
|
|
|
119
175
|
### Added
|
|
120
176
|
|
|
121
177
|
- Official support for Ruby: MRI 2.6 (@jodosha)
|
|
122
178
|
- Support `bundler` 2.0+ (@jodosha)
|
|
123
179
|
|
|
180
|
+
[0.3.1]: https://github.com/dry-rb/dry-cli/compare/v0.3.0...v0.3.1
|
|
124
181
|
|
|
125
|
-
[
|
|
126
|
-
|
|
127
|
-
## 0.3.0 2018-10-24
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
[Compare v0.3.0.beta1...v0.3.0](https://github.com/dry-rb/dry-cli/compare/v0.3.0.beta1...v0.3.0)
|
|
182
|
+
## [0.3.0] - 2018-10-24
|
|
132
183
|
|
|
133
|
-
|
|
184
|
+
[0.3.0]: https://github.com/dry-rb/dry-cli/compare/v0.3.0.beta1...v0.3.0
|
|
134
185
|
|
|
186
|
+
## [0.3.0.beta1] - 2018-08-08
|
|
135
187
|
|
|
136
188
|
### Added
|
|
137
189
|
|
|
@@ -144,29 +196,21 @@
|
|
|
144
196
|
|
|
145
197
|
- Print informative message when unknown or wrong option is passed (`"test" was called with arguments "--framework=unknown"`) (@davydovanton)
|
|
146
198
|
|
|
199
|
+
[0.3.0.beta1]: https://github.com/dry-rb/dry-cli/compare/v0.2.0...v0.3.0.beta1
|
|
147
200
|
|
|
148
|
-
[
|
|
149
|
-
|
|
150
|
-
## 0.2.0 2018-04-11
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
[Compare v0.2.0.rc2...v0.2.0](https://github.com/dry-rb/dry-cli/compare/v0.2.0.rc2...v0.2.0)
|
|
201
|
+
## [0.2.0] - 2018-04-11
|
|
155
202
|
|
|
156
|
-
|
|
203
|
+
[0.2.0]: https://github.com/dry-rb/dry-cli/compare/v0.2.0.rc2...v0.2.0
|
|
157
204
|
|
|
205
|
+
## [0.2.0.rc2] - 2018-04-06
|
|
158
206
|
|
|
207
|
+
[0.2.0.rc2]: https://github.com/dry-rb/dry-cli/compare/v0.2.0.rc1...v0.2.0.rc2
|
|
159
208
|
|
|
160
|
-
[
|
|
209
|
+
## [0.2.0.rc1] - 2018-03-30
|
|
161
210
|
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
[Compare v0.2.0.beta2...v0.2.0.rc1](https://github.com/dry-rb/dry-cli/compare/v0.2.0.beta2...v0.2.0.rc1)
|
|
167
|
-
|
|
168
|
-
## 0.2.0.beta2 2018-03-23
|
|
211
|
+
[0.2.0.rc1]: https://github.com/dry-rb/dry-cli/compare/v0.2.0.beta2...v0.2.0.rc1
|
|
169
212
|
|
|
213
|
+
## [0.2.0.beta2] - 2018-03-23
|
|
170
214
|
|
|
171
215
|
### Added
|
|
172
216
|
|
|
@@ -176,21 +220,17 @@
|
|
|
176
220
|
|
|
177
221
|
- Ensure callbacks' context of execution (aka `self`) to be the command that is being executed (@jodosha, @davydovanton)
|
|
178
222
|
|
|
223
|
+
[0.2.0.beta2]: https://github.com/dry-rb/dry-cli/compare/v0.2.0.beta1...v0.2.0.beta2
|
|
179
224
|
|
|
180
|
-
[
|
|
181
|
-
|
|
182
|
-
## 0.2.0.beta1 2018-02-28
|
|
183
|
-
|
|
225
|
+
## [0.2.0.beta1] - 2018-02-28
|
|
184
226
|
|
|
185
227
|
### Added
|
|
186
228
|
|
|
187
229
|
- Register `before`/`after` callbacks for commands (@davydovanton)
|
|
188
230
|
|
|
231
|
+
[0.2.0.beta1]: https://github.com/dry-rb/dry-cli/compare/v0.1.1...v0.2.0.beta1
|
|
189
232
|
|
|
190
|
-
[
|
|
191
|
-
|
|
192
|
-
## 0.1.1 2018-02-27
|
|
193
|
-
|
|
233
|
+
## [0.1.1] - 2018-02-27
|
|
194
234
|
|
|
195
235
|
### Added
|
|
196
236
|
|
|
@@ -201,39 +241,29 @@
|
|
|
201
241
|
- Ensure default values for arguments to be sent to commands (@AlfonsoUceda)
|
|
202
242
|
- Ensure to fail when a missing required argument isn't provider, but an option is provided instead (@AlfonsoUceda)
|
|
203
243
|
|
|
244
|
+
[0.1.1]: https://github.com/dry-rb/dry-cli/compare/v0.1.0...v0.1.1
|
|
204
245
|
|
|
205
|
-
[
|
|
206
|
-
|
|
207
|
-
## 0.1.0 2017-10-25
|
|
246
|
+
## [0.1.0] - 2017-10-25
|
|
208
247
|
|
|
248
|
+
[0.1.0]: https://github.com/dry-rb/dry-cli/compare/v0.1.0.rc1...v0.1.0
|
|
209
249
|
|
|
250
|
+
## [0.1.0.rc1] - 2017-10-16
|
|
210
251
|
|
|
211
|
-
[
|
|
252
|
+
[0.1.0.rc1]: https://github.com/dry-rb/dry-cli/compare/v0.1.0.beta3...v0.1.0.rc1
|
|
212
253
|
|
|
213
|
-
## 0.1.0.
|
|
254
|
+
## [0.1.0.beta3] - 2017-10-04
|
|
214
255
|
|
|
256
|
+
[0.1.0.beta3]: https://github.com/dry-rb/dry-cli/compare/v0.1.0.beta2...v0.1.0.beta3
|
|
215
257
|
|
|
216
|
-
|
|
217
|
-
[Compare v0.1.0.beta3...v0.1.0.rc1](https://github.com/dry-rb/dry-cli/compare/v0.1.0.beta3...v0.1.0.rc1)
|
|
218
|
-
|
|
219
|
-
## 0.1.0.beta3 2017-10-04
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
[Compare v0.1.0.beta2...v0.1.0.beta3](https://github.com/dry-rb/dry-cli/compare/v0.1.0.beta2...v0.1.0.beta3)
|
|
224
|
-
|
|
225
|
-
## 0.1.0.beta2 2017-10-03
|
|
226
|
-
|
|
258
|
+
## [0.1.0.beta2] - 2017-10-03
|
|
227
259
|
|
|
228
260
|
### Added
|
|
229
261
|
|
|
230
262
|
- Allow default value for arguments (@AlfonsoUceda)
|
|
231
263
|
|
|
264
|
+
[0.1.0.beta2]: https://github.com/dry-rb/dry-cli/compare/v0.1.0.beta1...v0.1.0.beta2
|
|
232
265
|
|
|
233
|
-
[
|
|
234
|
-
|
|
235
|
-
## 0.1.0.beta1 2017-08-11
|
|
236
|
-
|
|
266
|
+
## [0.1.0.beta1] - 2017-08-11
|
|
237
267
|
|
|
238
268
|
### Added
|
|
239
269
|
|
data/LICENSE
CHANGED
data/README.md
CHANGED
|
@@ -1,22 +1,17 @@
|
|
|
1
|
-
<!---
|
|
2
|
-
|
|
1
|
+
<!--- This file is synced from hanakai-rb/repo-sync -->
|
|
2
|
+
|
|
3
|
+
[rubygem]: https://rubygems.org/gems/dry-cli
|
|
3
4
|
[actions]: https://github.com/dry-rb/dry-cli/actions
|
|
4
5
|
|
|
5
|
-
# dry-cli [][
|
|
6
|
+
# dry-cli [][rubygem] [][actions]
|
|
6
7
|
|
|
7
8
|
## Links
|
|
8
9
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
## Supported Ruby versions
|
|
14
|
-
|
|
15
|
-
This library officially supports the following Ruby versions:
|
|
16
|
-
|
|
17
|
-
* MRI `>= 2.4.0`
|
|
18
|
-
* jruby `>= 9.4` (not tested on CI)
|
|
10
|
+
- [User documentation](https://dry-rb.org/gems/dry-cli)
|
|
11
|
+
- [API documentation](http://rubydoc.info/gems/dry-cli)
|
|
12
|
+
- [Forum](https://discourse.dry-rb.org)
|
|
19
13
|
|
|
20
14
|
## License
|
|
21
15
|
|
|
22
16
|
See `LICENSE` file.
|
|
17
|
+
|
data/dry-cli.gemspec
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
#
|
|
3
|
+
# This file is synced from hanakai-rb/repo-sync. To update it, edit repo-sync.yml.
|
|
4
4
|
|
|
5
5
|
lib = File.expand_path("lib", __dir__)
|
|
6
6
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
@@ -8,8 +8,8 @@ require "dry/cli/version"
|
|
|
8
8
|
|
|
9
9
|
Gem::Specification.new do |spec|
|
|
10
10
|
spec.name = "dry-cli"
|
|
11
|
-
spec.authors = ["
|
|
12
|
-
spec.email = ["
|
|
11
|
+
spec.authors = ["Hanakai team"]
|
|
12
|
+
spec.email = ["info@hanakai.org"]
|
|
13
13
|
spec.license = "MIT"
|
|
14
14
|
spec.version = Dry::CLI::VERSION.dup
|
|
15
15
|
|
|
@@ -21,18 +21,18 @@ Gem::Specification.new do |spec|
|
|
|
21
21
|
spec.executables = []
|
|
22
22
|
spec.require_paths = ["lib"]
|
|
23
23
|
|
|
24
|
+
spec.extra_rdoc_files = ["README.md", "CHANGELOG.md", "LICENSE"]
|
|
25
|
+
|
|
24
26
|
spec.metadata["allowed_push_host"] = "https://rubygems.org"
|
|
25
27
|
spec.metadata["changelog_uri"] = "https://github.com/dry-rb/dry-cli/blob/main/CHANGELOG.md"
|
|
26
28
|
spec.metadata["source_code_uri"] = "https://github.com/dry-rb/dry-cli"
|
|
27
29
|
spec.metadata["bug_tracker_uri"] = "https://github.com/dry-rb/dry-cli/issues"
|
|
30
|
+
spec.metadata["funding_uri"] = "https://github.com/sponsors/hanami"
|
|
28
31
|
|
|
29
|
-
spec.required_ruby_version = ">= 2
|
|
30
|
-
|
|
31
|
-
# to update dependencies edit project.yml
|
|
32
|
+
spec.required_ruby_version = ">= 3.2"
|
|
32
33
|
|
|
33
|
-
spec.add_development_dependency "bundler"
|
|
34
|
-
spec.add_development_dependency "rake"
|
|
35
|
-
spec.add_development_dependency "rspec"
|
|
36
|
-
spec.add_development_dependency "rubocop", "~> 0.82"
|
|
37
|
-
spec.add_development_dependency "simplecov", "~> 0.17.1"
|
|
34
|
+
spec.add_development_dependency "bundler"
|
|
35
|
+
spec.add_development_dependency "rake"
|
|
36
|
+
spec.add_development_dependency "rspec"
|
|
38
37
|
end
|
|
38
|
+
|
data/lib/dry/cli/banner.rb
CHANGED
|
@@ -86,8 +86,8 @@ module Dry
|
|
|
86
86
|
required_arguments = command.required_arguments
|
|
87
87
|
optional_arguments = command.optional_arguments
|
|
88
88
|
|
|
89
|
-
required = required_arguments.map { |arg| arg.name.upcase }.join(" ") if required_arguments.any?
|
|
90
|
-
optional = optional_arguments.map { |arg| "[#{arg.name.upcase}]" }.join(" ") if optional_arguments.any?
|
|
89
|
+
required = required_arguments.map { |arg| arg.name.upcase }.join(" ") if required_arguments.any?
|
|
90
|
+
optional = optional_arguments.map { |arg| "[#{arg.name.upcase}]" }.join(" ") if optional_arguments.any?
|
|
91
91
|
result = [required, optional].compact
|
|
92
92
|
|
|
93
93
|
" #{result.join(" ")}" unless result.empty?
|
|
@@ -97,7 +97,7 @@ module Dry
|
|
|
97
97
|
# @api private
|
|
98
98
|
def self.extended_command_arguments(command)
|
|
99
99
|
command.arguments.map do |argument|
|
|
100
|
-
" #{argument.name.to_s.upcase.ljust(32)} # #{"REQUIRED " if argument.required?}#{argument.desc}"
|
|
100
|
+
" #{argument.name.to_s.upcase.ljust(32)} # #{"REQUIRED " if argument.required?}#{argument.desc}"
|
|
101
101
|
end.join("\n")
|
|
102
102
|
end
|
|
103
103
|
|
data/lib/dry/cli/command.rb
CHANGED
|
@@ -195,7 +195,12 @@ module Dry
|
|
|
195
195
|
# # Options:
|
|
196
196
|
# # --help, -h # Print this help
|
|
197
197
|
def self.argument(name, options = {})
|
|
198
|
-
|
|
198
|
+
new_arg = Argument.new(name, options)
|
|
199
|
+
|
|
200
|
+
duplicate_index = @arguments.find_index { _1.name == new_arg.name }
|
|
201
|
+
@arguments.delete_at(duplicate_index) unless duplicate_index.nil?
|
|
202
|
+
|
|
203
|
+
@arguments << new_arg
|
|
199
204
|
end
|
|
200
205
|
|
|
201
206
|
# Command line option (aka optional argument)
|
|
@@ -309,7 +314,12 @@ module Dry
|
|
|
309
314
|
# # Options:
|
|
310
315
|
# # --port=VALUE, -p VALUE
|
|
311
316
|
def self.option(name, options = {})
|
|
312
|
-
|
|
317
|
+
new_op = Option.new(name, options)
|
|
318
|
+
|
|
319
|
+
duplicate_index = @options.find_index { _1.name == new_op.name }
|
|
320
|
+
@options.delete_at(duplicate_index) unless duplicate_index.nil?
|
|
321
|
+
|
|
322
|
+
@options << new_op
|
|
313
323
|
end
|
|
314
324
|
|
|
315
325
|
# @since 0.1.0
|
|
@@ -379,6 +389,39 @@ module Dry
|
|
|
379
389
|
optional_arguments
|
|
380
390
|
subcommands
|
|
381
391
|
] => "self.class"
|
|
392
|
+
|
|
393
|
+
protected
|
|
394
|
+
|
|
395
|
+
# The error output used to print error messaging
|
|
396
|
+
#
|
|
397
|
+
# @example
|
|
398
|
+
# class MyCommand
|
|
399
|
+
# def call
|
|
400
|
+
# out.puts "Hello World!"
|
|
401
|
+
# exit(0)
|
|
402
|
+
# rescue StandardError => e
|
|
403
|
+
# err.puts "Uh oh: #{e.message}"
|
|
404
|
+
# exit(1)
|
|
405
|
+
# end
|
|
406
|
+
# end
|
|
407
|
+
#
|
|
408
|
+
# @since unreleased
|
|
409
|
+
# @return [IO]
|
|
410
|
+
attr_reader :err
|
|
411
|
+
|
|
412
|
+
# The standard output object used to print messaging
|
|
413
|
+
#
|
|
414
|
+
# @example
|
|
415
|
+
# class MyCommand
|
|
416
|
+
# def call
|
|
417
|
+
# out.puts "Hello World!"
|
|
418
|
+
# exit(0)
|
|
419
|
+
# end
|
|
420
|
+
# end
|
|
421
|
+
#
|
|
422
|
+
# @since unreleased
|
|
423
|
+
# @return [IO]
|
|
424
|
+
attr_reader :out
|
|
382
425
|
end
|
|
383
426
|
end
|
|
384
427
|
end
|
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require "set"
|
|
4
|
-
|
|
5
3
|
module Dry
|
|
6
4
|
class CLI
|
|
7
5
|
# Command registry
|
|
@@ -255,9 +253,9 @@ module Dry
|
|
|
255
253
|
|
|
256
254
|
# @since 0.4.0
|
|
257
255
|
# @api private
|
|
258
|
-
def run(context,
|
|
256
|
+
def run(context, **args)
|
|
259
257
|
chain.each do |callback|
|
|
260
|
-
context.instance_exec(
|
|
258
|
+
context.instance_exec(**args, &callback)
|
|
261
259
|
end
|
|
262
260
|
end
|
|
263
261
|
end
|
data/lib/dry/cli/errors.rb
CHANGED
data/lib/dry/cli/inline.rb
CHANGED
data/lib/dry/cli/option.rb
CHANGED
|
@@ -121,6 +121,18 @@ module Dry
|
|
|
121
121
|
.map { |name| name.size == 1 ? "-#{name}" : "--#{name}" }
|
|
122
122
|
.map { |name| boolean? || flag? ? name : "#{name} VALUE" }
|
|
123
123
|
end
|
|
124
|
+
|
|
125
|
+
# @api private
|
|
126
|
+
def valid_value?(value)
|
|
127
|
+
available_values = values
|
|
128
|
+
return true if available_values.nil?
|
|
129
|
+
|
|
130
|
+
if array?
|
|
131
|
+
(value - available_values).empty?
|
|
132
|
+
else
|
|
133
|
+
available_values.map(&:to_s).include?(value.to_s)
|
|
134
|
+
end
|
|
135
|
+
end
|
|
124
136
|
end
|
|
125
137
|
|
|
126
138
|
# Command line argument
|
data/lib/dry/cli/parser.rb
CHANGED
|
@@ -31,25 +31,25 @@ module Dry
|
|
|
31
31
|
|
|
32
32
|
parsed_options = command.default_params.merge(parsed_options)
|
|
33
33
|
parse_required_params(command, arguments, prog_name, parsed_options)
|
|
34
|
-
rescue ::OptionParser::ParseError
|
|
35
|
-
Result.failure("ERROR: \"#{prog_name}\" was called with arguments \"#{original_arguments.join(" ")}\"")
|
|
34
|
+
rescue ::OptionParser::ParseError, ValueError
|
|
35
|
+
Result.failure("ERROR: \"#{prog_name}\" was called with arguments \"#{original_arguments.join(" ")}\"")
|
|
36
36
|
end
|
|
37
37
|
|
|
38
38
|
# @since 0.1.0
|
|
39
39
|
# @api private
|
|
40
40
|
#
|
|
41
|
-
# rubocop:disable Metrics/AbcSize, Metrics/PerceivedComplexity
|
|
41
|
+
# rubocop:disable Metrics/AbcSize, Metrics/PerceivedComplexity, Layout/LineLength
|
|
42
42
|
def self.parse_required_params(command, arguments, prog_name, parsed_options)
|
|
43
|
-
parsed_params
|
|
44
|
-
parsed_required_params = match_arguments(command.required_arguments, arguments)
|
|
45
|
-
all_required_params_satisfied = command.required_arguments.all? { |param| !parsed_required_params[param.name].nil? }
|
|
43
|
+
parsed_params = match_arguments(command.arguments, arguments, parsed_options)
|
|
44
|
+
parsed_required_params = match_arguments(command.required_arguments, arguments, parsed_options)
|
|
45
|
+
all_required_params_satisfied = command.required_arguments.all? { |param| !parsed_required_params[param.name].nil? }
|
|
46
46
|
|
|
47
47
|
unused_arguments = arguments.drop(command.required_arguments.length)
|
|
48
48
|
|
|
49
49
|
unless all_required_params_satisfied
|
|
50
50
|
parsed_required_params_values = parsed_required_params.values.compact
|
|
51
51
|
|
|
52
|
-
usage = "\nUsage: \"#{prog_name} #{command.required_arguments.map(&:description_name).join(" ")}"
|
|
52
|
+
usage = "\nUsage: \"#{prog_name} #{command.required_arguments.map(&:description_name).join(" ")}"
|
|
53
53
|
|
|
54
54
|
usage += " | #{prog_name} SUBCOMMAND" if command.subcommands.any?
|
|
55
55
|
|
|
@@ -58,7 +58,7 @@ module Dry
|
|
|
58
58
|
if parsed_required_params_values.empty?
|
|
59
59
|
return Result.failure("ERROR: \"#{prog_name}\" was called with no arguments#{usage}")
|
|
60
60
|
else
|
|
61
|
-
return Result.failure("ERROR: \"#{prog_name}\" was called with arguments #{parsed_required_params_values}#{usage}")
|
|
61
|
+
return Result.failure("ERROR: \"#{prog_name}\" was called with arguments #{parsed_required_params_values}#{usage}")
|
|
62
62
|
end
|
|
63
63
|
end
|
|
64
64
|
|
|
@@ -67,17 +67,24 @@ module Dry
|
|
|
67
67
|
parsed_options = parsed_options.merge(args: unused_arguments) if unused_arguments.any?
|
|
68
68
|
Result.success(parsed_options)
|
|
69
69
|
end
|
|
70
|
-
# rubocop:enable Metrics/AbcSize, Metrics/PerceivedComplexity
|
|
70
|
+
# rubocop:enable Metrics/AbcSize, Metrics/PerceivedComplexity, Layout/LineLength
|
|
71
71
|
|
|
72
|
-
def self.match_arguments(command_arguments, arguments)
|
|
72
|
+
def self.match_arguments(command_arguments, arguments, default_values)
|
|
73
73
|
result = {}
|
|
74
74
|
|
|
75
|
+
arg = nil
|
|
75
76
|
command_arguments.each_with_index do |cmd_arg, index|
|
|
76
77
|
if cmd_arg.array?
|
|
77
|
-
|
|
78
|
+
arg = arguments[index..] || default_values[cmd_arg.name]
|
|
79
|
+
raise ValueError unless cmd_arg.valid_value?(arg)
|
|
80
|
+
|
|
81
|
+
result[cmd_arg.name] = arg
|
|
78
82
|
break
|
|
79
83
|
else
|
|
80
|
-
|
|
84
|
+
arg = arguments.at(index) || default_values[cmd_arg.name]
|
|
85
|
+
raise ValueError unless cmd_arg.valid_value?(arg)
|
|
86
|
+
|
|
87
|
+
result[cmd_arg.name] = arg
|
|
81
88
|
end
|
|
82
89
|
end
|
|
83
90
|
|
data/lib/dry/cli/registry.rb
CHANGED
|
@@ -318,9 +318,18 @@ module Dry
|
|
|
318
318
|
# @since 0.1.0
|
|
319
319
|
#
|
|
320
320
|
# @see Dry::CLI::Registry#register
|
|
321
|
-
def register(name, command, aliases: [], hidden: false)
|
|
321
|
+
def register(name, command = nil, aliases: [], hidden: false, &block)
|
|
322
322
|
command_name = "#{prefix} #{name}"
|
|
323
323
|
registry.set(command_name, command, aliases, hidden)
|
|
324
|
+
|
|
325
|
+
if block_given?
|
|
326
|
+
prefix = self.class.new(registry, command_name, aliases, hidden)
|
|
327
|
+
if block.arity.zero?
|
|
328
|
+
prefix.instance_eval(&block)
|
|
329
|
+
else
|
|
330
|
+
yield(prefix)
|
|
331
|
+
end
|
|
332
|
+
end
|
|
324
333
|
end
|
|
325
334
|
|
|
326
335
|
private
|
data/lib/dry/cli/usage.rb
CHANGED
|
@@ -57,8 +57,8 @@ module Dry
|
|
|
57
57
|
required_arguments = command.required_arguments
|
|
58
58
|
optional_arguments = command.optional_arguments
|
|
59
59
|
|
|
60
|
-
required = required_arguments.map { |arg| arg.name.upcase }.join(" ") if required_arguments.any?
|
|
61
|
-
optional = optional_arguments.map { |arg| "[#{arg.name.upcase}]" }.join(" ") if optional_arguments.any?
|
|
60
|
+
required = required_arguments.map { |arg| arg.name.upcase }.join(" ") if required_arguments.any?
|
|
61
|
+
optional = optional_arguments.map { |arg| "[#{arg.name.upcase}]" }.join(" ") if optional_arguments.any?
|
|
62
62
|
result = [required, optional].compact
|
|
63
63
|
|
|
64
64
|
" #{result.join(" ")}" unless result.empty?
|
data/lib/dry/cli/version.rb
CHANGED
data/lib/dry/cli.rb
CHANGED
|
@@ -64,8 +64,8 @@ module Dry
|
|
|
64
64
|
def call(arguments: ARGV, out: $stdout, err: $stderr)
|
|
65
65
|
@out, @err = out, err
|
|
66
66
|
kommand ? perform_command(arguments) : perform_registry(arguments)
|
|
67
|
-
rescue SignalException =>
|
|
68
|
-
signal_exception(
|
|
67
|
+
rescue SignalException => exception
|
|
68
|
+
signal_exception(exception)
|
|
69
69
|
rescue Errno::EPIPE
|
|
70
70
|
# no op
|
|
71
71
|
end
|
|
@@ -97,6 +97,10 @@ module Dry
|
|
|
97
97
|
# @api private
|
|
98
98
|
def perform_command(arguments)
|
|
99
99
|
command, args = parse(kommand, arguments, [])
|
|
100
|
+
|
|
101
|
+
command.instance_variable_set(:@err, err) unless command.instance_variable_defined?(:@err)
|
|
102
|
+
command.instance_variable_set(:@out, out) unless command.instance_variable_defined?(:@out)
|
|
103
|
+
|
|
100
104
|
command.call(**args)
|
|
101
105
|
end
|
|
102
106
|
|
|
@@ -113,9 +117,12 @@ module Dry
|
|
|
113
117
|
|
|
114
118
|
command, args = parse(result.command, result.arguments, result.names)
|
|
115
119
|
|
|
116
|
-
|
|
120
|
+
command.instance_variable_set(:@err, err) unless command.instance_variable_defined?(:@err)
|
|
121
|
+
command.instance_variable_set(:@out, out) unless command.instance_variable_defined?(:@out)
|
|
122
|
+
|
|
123
|
+
result.before_callbacks.run(command, **args)
|
|
117
124
|
command.call(**args)
|
|
118
|
-
result.after_callbacks.run(command, args)
|
|
125
|
+
result.after_callbacks.run(command, **args)
|
|
119
126
|
end
|
|
120
127
|
|
|
121
128
|
# Parse arguments for a command.
|
metadata
CHANGED
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: dry-cli
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.
|
|
4
|
+
version: 1.4.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
|
-
-
|
|
8
|
-
autorequire:
|
|
7
|
+
- Hanakai team
|
|
9
8
|
bindir: bin
|
|
10
9
|
cert_chain: []
|
|
11
|
-
date:
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
12
11
|
dependencies:
|
|
13
12
|
- !ruby/object:Gem::Dependency
|
|
14
13
|
name: bundler
|
|
@@ -16,82 +15,51 @@ dependencies:
|
|
|
16
15
|
requirements:
|
|
17
16
|
- - ">="
|
|
18
17
|
- !ruby/object:Gem::Version
|
|
19
|
-
version: '
|
|
20
|
-
- - "<"
|
|
21
|
-
- !ruby/object:Gem::Version
|
|
22
|
-
version: '3'
|
|
18
|
+
version: '0'
|
|
23
19
|
type: :development
|
|
24
20
|
prerelease: false
|
|
25
21
|
version_requirements: !ruby/object:Gem::Requirement
|
|
26
22
|
requirements:
|
|
27
23
|
- - ">="
|
|
28
24
|
- !ruby/object:Gem::Version
|
|
29
|
-
version: '
|
|
30
|
-
- - "<"
|
|
31
|
-
- !ruby/object:Gem::Version
|
|
32
|
-
version: '3'
|
|
25
|
+
version: '0'
|
|
33
26
|
- !ruby/object:Gem::Dependency
|
|
34
27
|
name: rake
|
|
35
28
|
requirement: !ruby/object:Gem::Requirement
|
|
36
29
|
requirements:
|
|
37
|
-
- - "
|
|
30
|
+
- - ">="
|
|
38
31
|
- !ruby/object:Gem::Version
|
|
39
|
-
version: '
|
|
32
|
+
version: '0'
|
|
40
33
|
type: :development
|
|
41
34
|
prerelease: false
|
|
42
35
|
version_requirements: !ruby/object:Gem::Requirement
|
|
43
36
|
requirements:
|
|
44
|
-
- - "
|
|
37
|
+
- - ">="
|
|
45
38
|
- !ruby/object:Gem::Version
|
|
46
|
-
version: '
|
|
39
|
+
version: '0'
|
|
47
40
|
- !ruby/object:Gem::Dependency
|
|
48
41
|
name: rspec
|
|
49
42
|
requirement: !ruby/object:Gem::Requirement
|
|
50
43
|
requirements:
|
|
51
|
-
- - "
|
|
52
|
-
- !ruby/object:Gem::Version
|
|
53
|
-
version: '3.7'
|
|
54
|
-
type: :development
|
|
55
|
-
prerelease: false
|
|
56
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
57
|
-
requirements:
|
|
58
|
-
- - "~>"
|
|
59
|
-
- !ruby/object:Gem::Version
|
|
60
|
-
version: '3.7'
|
|
61
|
-
- !ruby/object:Gem::Dependency
|
|
62
|
-
name: rubocop
|
|
63
|
-
requirement: !ruby/object:Gem::Requirement
|
|
64
|
-
requirements:
|
|
65
|
-
- - "~>"
|
|
66
|
-
- !ruby/object:Gem::Version
|
|
67
|
-
version: '0.82'
|
|
68
|
-
type: :development
|
|
69
|
-
prerelease: false
|
|
70
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
71
|
-
requirements:
|
|
72
|
-
- - "~>"
|
|
73
|
-
- !ruby/object:Gem::Version
|
|
74
|
-
version: '0.82'
|
|
75
|
-
- !ruby/object:Gem::Dependency
|
|
76
|
-
name: simplecov
|
|
77
|
-
requirement: !ruby/object:Gem::Requirement
|
|
78
|
-
requirements:
|
|
79
|
-
- - "~>"
|
|
44
|
+
- - ">="
|
|
80
45
|
- !ruby/object:Gem::Version
|
|
81
|
-
version: 0
|
|
46
|
+
version: '0'
|
|
82
47
|
type: :development
|
|
83
48
|
prerelease: false
|
|
84
49
|
version_requirements: !ruby/object:Gem::Requirement
|
|
85
50
|
requirements:
|
|
86
|
-
- - "
|
|
51
|
+
- - ">="
|
|
87
52
|
- !ruby/object:Gem::Version
|
|
88
|
-
version: 0
|
|
53
|
+
version: '0'
|
|
89
54
|
description: Common framework to build command line interfaces with Ruby
|
|
90
55
|
email:
|
|
91
|
-
-
|
|
56
|
+
- info@hanakai.org
|
|
92
57
|
executables: []
|
|
93
58
|
extensions: []
|
|
94
|
-
extra_rdoc_files:
|
|
59
|
+
extra_rdoc_files:
|
|
60
|
+
- CHANGELOG.md
|
|
61
|
+
- LICENSE
|
|
62
|
+
- README.md
|
|
95
63
|
files:
|
|
96
64
|
- CHANGELOG.md
|
|
97
65
|
- LICENSE
|
|
@@ -119,7 +87,7 @@ metadata:
|
|
|
119
87
|
changelog_uri: https://github.com/dry-rb/dry-cli/blob/main/CHANGELOG.md
|
|
120
88
|
source_code_uri: https://github.com/dry-rb/dry-cli
|
|
121
89
|
bug_tracker_uri: https://github.com/dry-rb/dry-cli/issues
|
|
122
|
-
|
|
90
|
+
funding_uri: https://github.com/sponsors/hanami
|
|
123
91
|
rdoc_options: []
|
|
124
92
|
require_paths:
|
|
125
93
|
- lib
|
|
@@ -127,15 +95,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
127
95
|
requirements:
|
|
128
96
|
- - ">="
|
|
129
97
|
- !ruby/object:Gem::Version
|
|
130
|
-
version: 2
|
|
98
|
+
version: '3.2'
|
|
131
99
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
132
100
|
requirements:
|
|
133
101
|
- - ">="
|
|
134
102
|
- !ruby/object:Gem::Version
|
|
135
103
|
version: '0'
|
|
136
104
|
requirements: []
|
|
137
|
-
rubygems_version: 3.
|
|
138
|
-
signing_key:
|
|
105
|
+
rubygems_version: 3.6.9
|
|
139
106
|
specification_version: 4
|
|
140
107
|
summary: Common framework to build command line interfaces with Ruby
|
|
141
108
|
test_files: []
|