slop 4.9.3 → 4.10.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/.github/workflows/ci.yml +2 -2
- data/CHANGELOG.md +5 -0
- data/README.md +30 -1
- data/lib/slop/error.rb +12 -0
- data/lib/slop/option.rb +19 -1
- data/lib/slop/options.rb +4 -0
- data/lib/slop/types.rb +19 -2
- data/lib/slop.rb +1 -1
- data/test/error_test.rb +15 -0
- data/test/types_test.rb +22 -4
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2d4b4855a341f5e05c71ec19242556039ea85f4d339560dec38c24beb8831691
|
4
|
+
data.tar.gz: 95fcb3512ee937216387467758a05992d72bbfad627fd79b939277a204c941ad
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c0ecc669117cf0c6336e3dfb1cf65c5019a0d638205a2497511121e102f7af7f48f175ded4c03d382257710da679970e4e405b84bee44a0613781d90b5bd4b63
|
7
|
+
data.tar.gz: 867c2ef751092ce4fafe9010f1b6ddb9ec7ee9adcdd2d020353129e7189b3ea8224f33ac368b773cca1298c297b159054775fb71074691e8ce9e20f780a58388
|
data/.github/workflows/ci.yml
CHANGED
@@ -22,10 +22,10 @@ jobs:
|
|
22
22
|
strategy:
|
23
23
|
fail-fast: false
|
24
24
|
matrix:
|
25
|
-
ruby: [ "2.0", "2.1", "2.2", "2.3", "2.4", "2.5", "2.6", "2.7", "3.0", "3.1", head, jruby, truffleruby ]
|
25
|
+
ruby: [ "2.0", "2.1", "2.2", "2.3", "2.4", "2.5", "2.6", "2.7", "3.0", "3.1", "3.2", head, jruby, truffleruby ]
|
26
26
|
name: Ruby ${{ matrix.ruby }}
|
27
27
|
steps:
|
28
|
-
- uses: actions/checkout@
|
28
|
+
- uses: actions/checkout@v3
|
29
29
|
- name: Set up Ruby
|
30
30
|
uses: ruby/setup-ruby@v1
|
31
31
|
with:
|
data/CHANGELOG.md
CHANGED
data/README.md
CHANGED
@@ -204,6 +204,8 @@ Slop will raise errors for the following:
|
|
204
204
|
* An option used without an argument when it expects one: `Slop::MissingArgument`
|
205
205
|
* An option used that Slop doesn't know about: `Slop::UnknownOption`
|
206
206
|
* An option marked as `required` when not provided: `Slop::MissingRequiredOption`
|
207
|
+
* An option marked as `validate_types`, with an argument that does not match its
|
208
|
+
type (i.e. `bla` for `integer`): `Slop::InvalidOptionValue`
|
207
209
|
|
208
210
|
These errors inherit from `Slop::Error`, so you can rescue them all.
|
209
211
|
Alternatively you can suppress these errors with the `suppress_errors` config
|
@@ -222,6 +224,33 @@ opts = Slop.parse do
|
|
222
224
|
end
|
223
225
|
```
|
224
226
|
|
227
|
+
Validating Types
|
228
|
+
----------------
|
229
|
+
|
230
|
+
By default, Slop does not validate whether an argument is a valid value for a
|
231
|
+
given option; instead, if the option has a default value, it will be used over
|
232
|
+
the invalid argument provided.
|
233
|
+
In order to have types (such as `integer` and `float`) validate and indicate
|
234
|
+
that the provided value is invalid, an extra option can be either provided to
|
235
|
+
the argument itself, or its option set:
|
236
|
+
|
237
|
+
```ruby
|
238
|
+
opts = Slop::Options.new
|
239
|
+
opts.int "-p", "--port", "a port", default: 80, validate_types: true
|
240
|
+
|
241
|
+
parser = Slop::Parser.new(opts)
|
242
|
+
result = parser.parse(["--port", "bla"])
|
243
|
+
# invalid value for -p, --port (Slop::InvalidOptionValue)
|
244
|
+
|
245
|
+
# Or to the option set...
|
246
|
+
opts = Slop::Options.new(validate_types: true)
|
247
|
+
opts.int "-p", "--port", "a port", default: 80
|
248
|
+
|
249
|
+
parser = Slop::Parser.new(opts)
|
250
|
+
result = parser.parse(["--port", "bla"])
|
251
|
+
# invalid value for -p, --port (Slop::InvalidOptionValue)
|
252
|
+
```
|
253
|
+
|
225
254
|
Printing help
|
226
255
|
-------------
|
227
256
|
|
@@ -279,4 +308,4 @@ end
|
|
279
308
|
Commands
|
280
309
|
--------
|
281
310
|
|
282
|
-
Slop
|
311
|
+
Slop no longer has built in support for git-style subcommands.
|
data/lib/slop/error.rb
CHANGED
@@ -38,4 +38,16 @@ module Slop
|
|
38
38
|
# Suppress with the `suppress_errors` config option.
|
39
39
|
class MissingRequiredOption < Error
|
40
40
|
end
|
41
|
+
|
42
|
+
# Raised when a given option is provided by the user and does not
|
43
|
+
# match the expected format for that type. This is only raised if
|
44
|
+
# validate_types is set to true.
|
45
|
+
class InvalidOptionValue < Error
|
46
|
+
attr_reader :flag
|
47
|
+
|
48
|
+
def initialize(msg, flag)
|
49
|
+
super(msg)
|
50
|
+
@flag = flag
|
51
|
+
end
|
52
|
+
end
|
41
53
|
end
|
data/lib/slop/option.rb
CHANGED
@@ -56,7 +56,11 @@ module Slop
|
|
56
56
|
raise Slop::MissingArgument.new("missing argument for #{flag}", flags)
|
57
57
|
end
|
58
58
|
else
|
59
|
-
|
59
|
+
if validate_type? && !valid?(value) && !suppress_errors?
|
60
|
+
raise Slop::InvalidOptionValue.new("invalid value for #{flag}", flags)
|
61
|
+
end
|
62
|
+
|
63
|
+
@value = valid?(value) && call(value)
|
60
64
|
end
|
61
65
|
|
62
66
|
block.call(@value) if block.respond_to?(:call)
|
@@ -107,6 +111,13 @@ module Slop
|
|
107
111
|
config[:required]
|
108
112
|
end
|
109
113
|
|
114
|
+
# Returns true if an exception should be raised when this option value can't
|
115
|
+
# be parsed into the desired type or does not conform to the expected type's
|
116
|
+
# format
|
117
|
+
def validate_type?
|
118
|
+
config[:validate_type] || config[:validate_types]
|
119
|
+
end
|
120
|
+
|
110
121
|
# Returns all flags joined by a comma. Used by the help string.
|
111
122
|
def flag
|
112
123
|
flags.join(", ")
|
@@ -119,6 +130,13 @@ module Slop
|
|
119
130
|
key.to_sym
|
120
131
|
end
|
121
132
|
|
133
|
+
# Override this if you want to provide a custom validator for a type. This
|
134
|
+
# method must return whether the provided value is valid for the current
|
135
|
+
# argument's type
|
136
|
+
def valid?(value)
|
137
|
+
true
|
138
|
+
end
|
139
|
+
|
122
140
|
# Returns true if this option should be displayed with dashes transformed into underscores.
|
123
141
|
def underscore_flags?
|
124
142
|
config[:underscore_flags]
|
data/lib/slop/options.rb
CHANGED
@@ -7,6 +7,7 @@ module Slop
|
|
7
7
|
type: "null",
|
8
8
|
banner: true,
|
9
9
|
underscore_flags: true,
|
10
|
+
validate_types: false,
|
10
11
|
}
|
11
12
|
|
12
13
|
# The Array of Option instances we've created.
|
@@ -24,6 +25,9 @@ module Slop
|
|
24
25
|
# The String banner prefixed to the help string.
|
25
26
|
attr_accessor :banner
|
26
27
|
|
28
|
+
# Whether we should validate types of values provided by the user
|
29
|
+
attr_accessor :validate_types
|
30
|
+
|
27
31
|
def initialize(**config, &block)
|
28
32
|
@options = []
|
29
33
|
@separators = []
|
data/lib/slop/types.rb
CHANGED
@@ -22,6 +22,13 @@ module Slop
|
|
22
22
|
attr_accessor :explicit_value
|
23
23
|
|
24
24
|
FALSE_VALUES = [false, 'false', 'no', 'off', '0'].freeze
|
25
|
+
TRUE_VALUES = [true, 'true', 'yes', 'on', '1'].freeze
|
26
|
+
VALID_VALUES = (FALSE_VALUES + TRUE_VALUES).freeze
|
27
|
+
|
28
|
+
def valid?(value)
|
29
|
+
return true if value.is_a?(String) && value.start_with?("--")
|
30
|
+
value.nil? || VALID_VALUES.include?(value)
|
31
|
+
end
|
25
32
|
|
26
33
|
def call(value)
|
27
34
|
self.explicit_value = value
|
@@ -52,8 +59,14 @@ module Slop
|
|
52
59
|
|
53
60
|
# Cast the option argument to an Integer.
|
54
61
|
class IntegerOption < Option
|
62
|
+
INT_STRING_REGEXP = /\A[+-]?\d+\z/.freeze
|
63
|
+
|
64
|
+
def valid?(value)
|
65
|
+
value =~ INT_STRING_REGEXP
|
66
|
+
end
|
67
|
+
|
55
68
|
def call(value)
|
56
|
-
value
|
69
|
+
value.to_i
|
57
70
|
end
|
58
71
|
end
|
59
72
|
IntOption = IntegerOption
|
@@ -62,8 +75,12 @@ module Slop
|
|
62
75
|
class FloatOption < Option
|
63
76
|
FLOAT_STRING_REGEXP = /\A[+-]?(?:0|[1-9]\d*)(?:\.\d*)?(?:[eE][+-]?\d+)?\z/.freeze
|
64
77
|
|
78
|
+
def valid?(value)
|
79
|
+
value =~ FLOAT_STRING_REGEXP
|
80
|
+
end
|
81
|
+
|
65
82
|
def call(value)
|
66
|
-
value
|
83
|
+
value.to_f
|
67
84
|
end
|
68
85
|
end
|
69
86
|
|
data/lib/slop.rb
CHANGED
data/test/error_test.rb
CHANGED
@@ -63,3 +63,18 @@ describe Slop::MissingRequiredOption do
|
|
63
63
|
opts.parse []
|
64
64
|
end
|
65
65
|
end
|
66
|
+
|
67
|
+
describe Slop::InvalidOptionValue do
|
68
|
+
it "raises when an option has an invalid value" do
|
69
|
+
opts = Slop::Options.new(validate_types: true)
|
70
|
+
opts.integer "-n", "--number", default: 10
|
71
|
+
assert_raises(Slop::InvalidOptionValue) { opts.parse %w(-n foo) }
|
72
|
+
end
|
73
|
+
|
74
|
+
it "does not raise when errors are suppressed" do
|
75
|
+
opts = Slop::Options.new(suppress_errors: true)
|
76
|
+
opts.integer "-n", "--number", default: 10, validate_type: true
|
77
|
+
r = opts.parse %w(-n foo)
|
78
|
+
assert_equal(10, r[:n])
|
79
|
+
end
|
80
|
+
end
|
data/test/types_test.rb
CHANGED
@@ -31,10 +31,10 @@ end
|
|
31
31
|
describe Slop::BoolOption do
|
32
32
|
before do
|
33
33
|
@options = Slop::Options.new
|
34
|
-
@verbose = @options.bool "--verbose"
|
34
|
+
@verbose = @options.bool "--verbose", validate_type: true
|
35
35
|
@quiet = @options.bool "--quiet"
|
36
36
|
@inversed = @options.bool "--inversed", default: true
|
37
|
-
@explicit = @options.bool "--explicit"
|
37
|
+
@explicit = @options.bool "--explicit", validate_type: true
|
38
38
|
@bloc = @options.bool("--bloc"){|val| (@bloc_val ||= []) << val}
|
39
39
|
@result = @options.parse %w(--verbose --no-inversed
|
40
40
|
--bloc --no-bloc
|
@@ -60,13 +60,19 @@ describe Slop::BoolOption do
|
|
60
60
|
it "returns false when explicitly false" do
|
61
61
|
assert_equal false, @result[:explicit]
|
62
62
|
end
|
63
|
+
|
64
|
+
it "raises with invalid types" do
|
65
|
+
assert_raises(Slop::InvalidOptionValue) do
|
66
|
+
@result.parser.parse %w(--verbose foo)
|
67
|
+
end
|
68
|
+
end
|
63
69
|
end
|
64
70
|
|
65
71
|
describe Slop::IntegerOption do
|
66
72
|
before do
|
67
73
|
@options = Slop::Options.new
|
68
74
|
@age = @options.integer "--age"
|
69
|
-
@minus = @options.integer "--minus"
|
75
|
+
@minus = @options.integer "--minus", validate_type: true
|
70
76
|
@plus = @options.integer "--plus"
|
71
77
|
@result = @options.parse %w(--age 20 --minus -10 --plus +30)
|
72
78
|
end
|
@@ -81,6 +87,12 @@ describe Slop::IntegerOption do
|
|
81
87
|
@result.parser.parse %w(--age hello)
|
82
88
|
assert_nil @result[:age]
|
83
89
|
end
|
90
|
+
|
91
|
+
it "raises with invalid types" do
|
92
|
+
assert_raises(Slop::InvalidOptionValue) do
|
93
|
+
@result.parser.parse %w(--minus foo)
|
94
|
+
end
|
95
|
+
end
|
84
96
|
end
|
85
97
|
|
86
98
|
describe Slop::FloatOption do
|
@@ -88,7 +100,7 @@ describe Slop::FloatOption do
|
|
88
100
|
@options = Slop::Options.new
|
89
101
|
@apr = @options.float "--apr"
|
90
102
|
@apr_value = 2.9
|
91
|
-
@minus = @options.float "--minus"
|
103
|
+
@minus = @options.float "--minus", validate_type: true
|
92
104
|
@plus = @options.float "--plus"
|
93
105
|
@scientific_notation = @options.float "--scientific-notation"
|
94
106
|
@scientific_notation_value = 4e21
|
@@ -125,6 +137,12 @@ describe Slop::FloatOption do
|
|
125
137
|
@result.parser.parse %w(--apr hello)
|
126
138
|
assert_nil @result[:apr]
|
127
139
|
end
|
140
|
+
|
141
|
+
it "raises with invalid types" do
|
142
|
+
assert_raises(Slop::InvalidOptionValue) do
|
143
|
+
@result.parser.parse %w(--minus foo)
|
144
|
+
end
|
145
|
+
end
|
128
146
|
end
|
129
147
|
|
130
148
|
describe Slop::ArrayOption do
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: slop
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 4.
|
4
|
+
version: 4.10.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Lee Jarvis
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2023-02-15 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|