command_mapper 0.1.1 → 0.2.1
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/.document +3 -0
- data/.github/workflows/ruby.yml +2 -1
- data/ChangeLog.md +32 -0
- data/Gemfile +2 -0
- data/LICENSE.txt +1 -1
- data/README.md +41 -8
- data/examples/grep.rb +62 -0
- data/lib/command_mapper/arg.rb +5 -0
- data/lib/command_mapper/argument.rb +6 -0
- data/lib/command_mapper/command.rb +209 -56
- data/lib/command_mapper/option.rb +50 -13
- data/lib/command_mapper/option_value.rb +22 -0
- data/lib/command_mapper/types/enum.rb +8 -0
- data/lib/command_mapper/types/hex.rb +16 -2
- data/lib/command_mapper/types/input_dir.rb +2 -0
- data/lib/command_mapper/types/input_file.rb +2 -0
- data/lib/command_mapper/types/input_path.rb +2 -0
- data/lib/command_mapper/types/key_value.rb +10 -0
- data/lib/command_mapper/types/key_value_list.rb +2 -0
- data/lib/command_mapper/types/list.rb +10 -0
- data/lib/command_mapper/types/map.rb +12 -1
- data/lib/command_mapper/types/num.rb +28 -1
- data/lib/command_mapper/types/str.rb +10 -1
- data/lib/command_mapper/types/type.rb +4 -0
- data/lib/command_mapper/version.rb +1 -1
- data/spec/commnad_spec.rb +345 -74
- data/spec/option_spec.rb +252 -1
- data/spec/option_value_spec.rb +28 -0
- data/spec/types/hex_spec.rb +59 -1
- data/spec/types/map_spec.rb +2 -2
- data/spec/types/num_spec.rb +93 -3
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: abc51ed8c1f7edf0484053eb62854a56b13dce9d5e3ea7b3373799c4b7a1d4fb
|
4
|
+
data.tar.gz: 0e7945e79e57cb99a4448b4eafef1237e9cc5e06d4523e13efd68b2767106a2f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ea9449f43ab086e941cc011dffd778cea4d356a2a9171aef5496e9a4593f62ca3ba68356d455cc510046ee926970c290c065b76bf445ba843a317f60c0fbbd31
|
7
|
+
data.tar.gz: 5979c264d481d50be2fed8ca17a19cb59b4c522303ff4d5cdf14164195b9b27fd6589ebe5b8e0b06276494f5298c6898fb297a97a606ca10d5fb916dbe1d568d
|
data/.document
ADDED
data/.github/workflows/ruby.yml
CHANGED
data/ChangeLog.md
CHANGED
@@ -1,3 +1,35 @@
|
|
1
|
+
### 0.2.1 / 2022-04-22
|
2
|
+
|
3
|
+
* Properly validate in {CommandMapper::OptionValue#validate} when an option,
|
4
|
+
who's value is not required, is given `true`.
|
5
|
+
* Omit `nil` arguments from {CommandMapper::Command#command_argv} if the
|
6
|
+
argument is not required.
|
7
|
+
* Improve validation error message for {CommandMapper::Types::Num} when
|
8
|
+
initialized with a `range:` value.
|
9
|
+
* Improve validation error message for {CommandMapper::Types::Map} and
|
10
|
+
{CommandMapper::Types::Enum}.
|
11
|
+
|
12
|
+
### 0.2.0 / 2022-04-18
|
13
|
+
|
14
|
+
* Added {CommandMapper::Command.spawn} and
|
15
|
+
{CommandMapper::Command#spawn_command}.
|
16
|
+
* Added checks to {CommandMapper::Command.option},
|
17
|
+
{CommandMapper::Command.argument}, and {CommandMapper::Command.subcommand} to
|
18
|
+
avoid overwriting an existing option/argument/subcommand with the same name.
|
19
|
+
* Added the `value_in_flag:` keyword argument to
|
20
|
+
{CommandMapper::Command.option} which indicates an option's value
|
21
|
+
should be appended to the flag (ex: `-Fvalue`).
|
22
|
+
* Added the `range:` keyword argument to {CommandMapper::Types::Num#initialize}
|
23
|
+
for specifying the acceptable range of numbers.
|
24
|
+
* Allow options with `equals: true` (aka `--opt=...`) or `value_in_flag: true`
|
25
|
+
(aka `-Fvalue`) to accept values that start with a `-` character.
|
26
|
+
|
27
|
+
### 0.1.2 / 2021-11-29
|
28
|
+
|
29
|
+
* Fixed a bug where {CommandMapper::Command.command_name} was not checking the
|
30
|
+
superclass for the {CommandMapper::Command.command_name command_name}, if no
|
31
|
+
`command "..."` was defined in the subclass.
|
32
|
+
|
1
33
|
### 0.1.1 / 2021-11-29
|
2
34
|
|
3
35
|
* Fixed a bug where {CommandMapper::Types::Num}, {CommandMapper::Types::Hex},
|
data/Gemfile
CHANGED
data/LICENSE.txt
CHANGED
data/README.md
CHANGED
@@ -21,9 +21,9 @@ allow safely and securely executing commands.
|
|
21
21
|
* [Str][CommandMapper::Types::Str]: string values
|
22
22
|
* [Num][CommandMapper::Types::Num]: numeric values
|
23
23
|
* [Hex][CommandMapper::Types::Hex]: hexadecimal values
|
24
|
-
* [Map][CommandMapper::Types::Map]: maps
|
25
|
-
`
|
26
|
-
|
24
|
+
* [Map][CommandMapper::Types::Map]: maps Ruby values to other String values.
|
25
|
+
* `Map::YesNo`: maps `true`/`false` to `yes`/`no`.
|
26
|
+
* `Map::EnabledDisabled`: Maps `true`/`false` to `enabled`/`disabled`.
|
27
27
|
* [Enum][CommandMapper::Types::Enum]: maps a finite set of Symbols to a
|
28
28
|
finite set of Strings (aka `--opt={foo|bar|baz}` values).
|
29
29
|
* [List][CommandMapper::Types::List]: comma-separated list
|
@@ -43,7 +43,10 @@ allow safely and securely executing commands.
|
|
43
43
|
* Allows running commands with additional environment variables.
|
44
44
|
* Allows overriding the command name or path to the command.
|
45
45
|
* Allows running commands via `sudo`.
|
46
|
-
* Prevents command injection and option injection.
|
46
|
+
* Prevents [command injection] and [option injection].
|
47
|
+
|
48
|
+
[command injection]: https://owasp.org/www-community/attacks/Command_Injection
|
49
|
+
[option injection]: https://staaldraad.github.io/post/2019-11-24-argument-injection/
|
47
50
|
|
48
51
|
[CommandMapper::Types::Str]: https://rubydoc.info/gems/command_mapper/CommandMapper/Types/Str
|
49
52
|
[CommandMapper::Types::Num]: https://rubydoc.info/gems/command_mapper/CommandMapper/Types/Num
|
@@ -73,7 +76,7 @@ class Grep < CommandMapper::Command
|
|
73
76
|
option "--basic-regexp"
|
74
77
|
option "--perl-regexp"
|
75
78
|
option "--regexp", equals: true, value: true
|
76
|
-
option "--file", equals: true, value: true
|
79
|
+
option "--file", name: :patterns_file, equals: true, value: true
|
77
80
|
option "--ignore-case"
|
78
81
|
option "--no-ignore-case"
|
79
82
|
option "--word-regexp"
|
@@ -142,6 +145,18 @@ Defines an option with a required value:
|
|
142
145
|
option "--output", value: {required: true}
|
143
146
|
```
|
144
147
|
|
148
|
+
Defines an option that uses an equals sign (ex: `--output=value`):
|
149
|
+
|
150
|
+
```ruby
|
151
|
+
option "--output", equals: true, value: {required: true}
|
152
|
+
```
|
153
|
+
|
154
|
+
Defines an option where the value is embedded into the flag (ex: `-Ivalue`):
|
155
|
+
|
156
|
+
```ruby
|
157
|
+
option "-I", value: {required: true}, value_in_flag: true
|
158
|
+
```
|
159
|
+
|
145
160
|
Defines an option that can be specified multiple times:
|
146
161
|
|
147
162
|
```ruby
|
@@ -154,6 +169,12 @@ Defines an option that accepts a numeric value:
|
|
154
169
|
option "--count", value: {type: Num.new}
|
155
170
|
```
|
156
171
|
|
172
|
+
Define an option that only accepts a range of acceptable values:
|
173
|
+
|
174
|
+
```ruby
|
175
|
+
option "--count", value: {type: Num.new(range: 1..100)}
|
176
|
+
```
|
177
|
+
|
157
178
|
Defines an option that accepts a comma-separated list:
|
158
179
|
|
159
180
|
```ruby
|
@@ -293,6 +314,18 @@ Grep.run do |grep|
|
|
293
314
|
end
|
294
315
|
```
|
295
316
|
|
317
|
+
Overriding the command name:
|
318
|
+
|
319
|
+
```ruby
|
320
|
+
Grep.run(..., command_name: 'grep2')
|
321
|
+
```
|
322
|
+
|
323
|
+
Specifying the direct path to the command:
|
324
|
+
|
325
|
+
```ruby
|
326
|
+
Grep.run(..., command_path: '/path/to/grep')
|
327
|
+
```
|
328
|
+
|
296
329
|
### Capturing output
|
297
330
|
|
298
331
|
```ruby
|
@@ -368,18 +401,18 @@ $ gem install command_mapper
|
|
368
401
|
### Gemfile
|
369
402
|
|
370
403
|
```ruby
|
371
|
-
gem 'command_mapper', '~> 0.
|
404
|
+
gem 'command_mapper', '~> 0.2'
|
372
405
|
```
|
373
406
|
|
374
407
|
### gemspec
|
375
408
|
|
376
409
|
```ruby
|
377
|
-
gemspec.add_dependency 'command_mapper', '~> 0.
|
410
|
+
gemspec.add_dependency 'command_mapper', '~> 0.2'
|
378
411
|
```
|
379
412
|
|
380
413
|
## License
|
381
414
|
|
382
|
-
Copyright (c) 2021 Hal Brodigan
|
415
|
+
Copyright (c) 2021-2022 Hal Brodigan
|
383
416
|
|
384
417
|
See {file:LICENSE.txt} for license information.
|
385
418
|
|
data/examples/grep.rb
ADDED
@@ -0,0 +1,62 @@
|
|
1
|
+
require 'command_mapper/command'
|
2
|
+
|
3
|
+
#
|
4
|
+
# Represents the `grep` command
|
5
|
+
#
|
6
|
+
class Grep < CommandMapper::Command
|
7
|
+
|
8
|
+
command "grep" do
|
9
|
+
option "--extended-regexp"
|
10
|
+
option "--fixed-strings"
|
11
|
+
option "--basic-regexp"
|
12
|
+
option "--perl-regexp"
|
13
|
+
option "--regexp", equals: true, value: true
|
14
|
+
option "--file", name: :patterns_file, equals: true, value: true
|
15
|
+
option "--ignore-case"
|
16
|
+
option "--no-ignore-case"
|
17
|
+
option "--word-regexp"
|
18
|
+
option "--line-regexp"
|
19
|
+
option "--null-data"
|
20
|
+
option "--no-messages"
|
21
|
+
option "--invert-match"
|
22
|
+
option "--version"
|
23
|
+
option "--help"
|
24
|
+
option "--max-count", equals: true, value: {type: Num.new}
|
25
|
+
option "--byte-offset"
|
26
|
+
option "--line-number"
|
27
|
+
option "--line-buffered"
|
28
|
+
option "--with-filename"
|
29
|
+
option "--no-filename"
|
30
|
+
option "--label", equals: true, value: true
|
31
|
+
option "--only-matching"
|
32
|
+
option "--quiet"
|
33
|
+
option "--binary-files", equals: true, value: true
|
34
|
+
option "--text"
|
35
|
+
option "-I", name: :binary
|
36
|
+
option "--directories", equals: true, value: true
|
37
|
+
option "--devices", equals: true, value: true
|
38
|
+
option "--recursive"
|
39
|
+
option "--dereference-recursive"
|
40
|
+
option "--include", equals: true, value: true
|
41
|
+
option "--exclude", equals: true, value: true
|
42
|
+
option "--exclude-from", equals: true, value: true
|
43
|
+
option "--exclude-dir", equals: true, value: true
|
44
|
+
option "--files-without-match", value: true
|
45
|
+
option "--files-with-matches"
|
46
|
+
option "--count"
|
47
|
+
option "--initial-tab"
|
48
|
+
option "--null"
|
49
|
+
option "--before-context", equals: true, value: {type: Num.new}
|
50
|
+
option "--after-context", equals: true, value: {type: Num.new}
|
51
|
+
option "--context", equals: true, value: {type: Num.new}
|
52
|
+
option "--group-separator", equals: true, value: true
|
53
|
+
option "--no-group-separator"
|
54
|
+
option "--color", equals: :optional, value: {required: false}
|
55
|
+
option "--colour", equals: :optional, value: {required: false}
|
56
|
+
option "--binary"
|
57
|
+
|
58
|
+
argument :patterns
|
59
|
+
argument :file, required: false, repeats: true
|
60
|
+
end
|
61
|
+
|
62
|
+
end
|
data/lib/command_mapper/arg.rb
CHANGED
@@ -6,6 +6,7 @@ module CommandMapper
|
|
6
6
|
# The base class for both {Option options} and {Argument arguments}.
|
7
7
|
#
|
8
8
|
class Arg
|
9
|
+
|
9
10
|
# The argument's arg's type.
|
10
11
|
#
|
11
12
|
# @return [Types::Type, nil]
|
@@ -23,6 +24,8 @@ module CommandMapper
|
|
23
24
|
# @raise [ArgumentError]
|
24
25
|
# The `type` keyword argument was given a `nil` value.
|
25
26
|
#
|
27
|
+
# @api private
|
28
|
+
#
|
26
29
|
def initialize(required: true, type: Types::Str.new)
|
27
30
|
@required = required
|
28
31
|
|
@@ -61,6 +64,8 @@ module CommandMapper
|
|
61
64
|
# Returns true if the value is valid, or `false` and a validation error
|
62
65
|
# message if the value is not compatible.
|
63
66
|
#
|
67
|
+
# @api semipublic
|
68
|
+
#
|
64
69
|
def validate(value)
|
65
70
|
if value.nil?
|
66
71
|
if required?
|
@@ -30,6 +30,8 @@ module CommandMapper
|
|
30
30
|
# @raise [ArgumentError]
|
31
31
|
# The given `type:` must not be `false` or `nil`.
|
32
32
|
#
|
33
|
+
# @api private
|
34
|
+
#
|
33
35
|
def initialize(name, required: true, type: Types::Str.new, repeats: false)
|
34
36
|
super(required: required, type: type)
|
35
37
|
|
@@ -56,6 +58,8 @@ module CommandMapper
|
|
56
58
|
# Returns true if the value is valid, or `false` and a validation error
|
57
59
|
# message if the value is not compatible.
|
58
60
|
#
|
61
|
+
# @api semipublic
|
62
|
+
#
|
59
63
|
def validate(value)
|
60
64
|
if repeats?
|
61
65
|
values = case value
|
@@ -101,6 +105,8 @@ module CommandMapper
|
|
101
105
|
# @raise [ArgumentError]
|
102
106
|
# The given value was incompatible with the argument.
|
103
107
|
#
|
108
|
+
# @api semipublic
|
109
|
+
#
|
104
110
|
def argv(argv=[],value)
|
105
111
|
valid, message = validate(value)
|
106
112
|
|