command_mapper 0.1.1 → 0.2.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
|