slop 4.9.3 → 4.10.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/.github/workflows/ci.yml +2 -2
- data/CHANGELOG.md +12 -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 +24 -2
- data/lib/slop.rb +1 -1
- data/slop.gemspec +0 -1
- data/test/error_test.rb +15 -0
- data/test/types_test.rb +29 -4
- metadata +3 -11
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: fcc0ed29ee91f506402b198ce02623ee1040f8031c327a657377aa80bbf5376e
|
|
4
|
+
data.tar.gz: fcd35281ea96cca322645275cb51ea3b828a340941d31a862c2f84c711d2c3fa
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 793194abed9bad4d6c1c764685453078130caee0ad65065b94aac4759320391f4b45bc367311391afd2af55dcabc1b513ad82003a42dc85b6b8621559815e03d
|
|
7
|
+
data.tar.gz: 4954ca723cc9f0550938ba5e95cd7bf50f0586501da1ae957f035181fcbbbfdbdf2a053f0c7849c236a84bc156abc1d96b5046eee55b79d65f4b46d4517f626a
|
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
|
@@ -1,6 +1,18 @@
|
|
|
1
1
|
Changelog
|
|
2
2
|
=========
|
|
3
3
|
|
|
4
|
+
v4.10.1 (2023-02-26)
|
|
5
|
+
--------------------
|
|
6
|
+
|
|
7
|
+
Bug fixes
|
|
8
|
+
* Fix boolean flags from being invalid when followed by arguments #279
|
|
9
|
+
|
|
10
|
+
v4.10.0 (2023-02-15)
|
|
11
|
+
--------------------
|
|
12
|
+
|
|
13
|
+
Features:
|
|
14
|
+
* Add support for optional type validation [#278](https://github.com/leejarvis/slop/pull/278) (Victor Gama)
|
|
15
|
+
|
|
4
16
|
v4.9.3 (2022-09-30)
|
|
5
17
|
-------------------
|
|
6
18
|
|
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,18 @@ 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
|
+
# If we don't want to validate the type, then we don't care if the value
|
|
30
|
+
# is valid or not. Otherwise we would prevent boolean flags followed by
|
|
31
|
+
# arguments from being parsed correctly.
|
|
32
|
+
return true unless config[:validate_type]
|
|
33
|
+
|
|
34
|
+
return true if value.is_a?(String) && value.start_with?("--")
|
|
35
|
+
value.nil? || VALID_VALUES.include?(value)
|
|
36
|
+
end
|
|
25
37
|
|
|
26
38
|
def call(value)
|
|
27
39
|
self.explicit_value = value
|
|
@@ -52,8 +64,14 @@ module Slop
|
|
|
52
64
|
|
|
53
65
|
# Cast the option argument to an Integer.
|
|
54
66
|
class IntegerOption < Option
|
|
67
|
+
INT_STRING_REGEXP = /\A[+-]?\d+\z/.freeze
|
|
68
|
+
|
|
69
|
+
def valid?(value)
|
|
70
|
+
value =~ INT_STRING_REGEXP
|
|
71
|
+
end
|
|
72
|
+
|
|
55
73
|
def call(value)
|
|
56
|
-
value
|
|
74
|
+
value.to_i
|
|
57
75
|
end
|
|
58
76
|
end
|
|
59
77
|
IntOption = IntegerOption
|
|
@@ -62,8 +80,12 @@ module Slop
|
|
|
62
80
|
class FloatOption < Option
|
|
63
81
|
FLOAT_STRING_REGEXP = /\A[+-]?(?:0|[1-9]\d*)(?:\.\d*)?(?:[eE][+-]?\d+)?\z/.freeze
|
|
64
82
|
|
|
83
|
+
def valid?(value)
|
|
84
|
+
value =~ FLOAT_STRING_REGEXP
|
|
85
|
+
end
|
|
86
|
+
|
|
65
87
|
def call(value)
|
|
66
|
-
value
|
|
88
|
+
value.to_f
|
|
67
89
|
end
|
|
68
90
|
end
|
|
69
91
|
|
data/lib/slop.rb
CHANGED
data/slop.gemspec
CHANGED
|
@@ -10,7 +10,6 @@ Gem::Specification.new do |s|
|
|
|
10
10
|
s.email = 'ljjarvis@gmail.com'
|
|
11
11
|
s.homepage = 'http://github.com/leejarvis/slop'
|
|
12
12
|
s.files = `git ls-files`.split("\n")
|
|
13
|
-
s.test_files = `git ls-files -- test/*`.split("\n")
|
|
14
13
|
s.license = 'MIT'
|
|
15
14
|
|
|
16
15
|
s.required_ruby_version = '>= 2.0.0'
|
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,26 @@ 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
|
|
69
|
+
|
|
70
|
+
# Like above but without validate_type
|
|
71
|
+
it "returns true if used and ignores the value" do
|
|
72
|
+
@result.parser.parse %w(--quiet foo)
|
|
73
|
+
|
|
74
|
+
assert_equal true, @result[:quiet]
|
|
75
|
+
end
|
|
63
76
|
end
|
|
64
77
|
|
|
65
78
|
describe Slop::IntegerOption do
|
|
66
79
|
before do
|
|
67
80
|
@options = Slop::Options.new
|
|
68
81
|
@age = @options.integer "--age"
|
|
69
|
-
@minus = @options.integer "--minus"
|
|
82
|
+
@minus = @options.integer "--minus", validate_type: true
|
|
70
83
|
@plus = @options.integer "--plus"
|
|
71
84
|
@result = @options.parse %w(--age 20 --minus -10 --plus +30)
|
|
72
85
|
end
|
|
@@ -81,6 +94,12 @@ describe Slop::IntegerOption do
|
|
|
81
94
|
@result.parser.parse %w(--age hello)
|
|
82
95
|
assert_nil @result[:age]
|
|
83
96
|
end
|
|
97
|
+
|
|
98
|
+
it "raises with invalid types" do
|
|
99
|
+
assert_raises(Slop::InvalidOptionValue) do
|
|
100
|
+
@result.parser.parse %w(--minus foo)
|
|
101
|
+
end
|
|
102
|
+
end
|
|
84
103
|
end
|
|
85
104
|
|
|
86
105
|
describe Slop::FloatOption do
|
|
@@ -88,7 +107,7 @@ describe Slop::FloatOption do
|
|
|
88
107
|
@options = Slop::Options.new
|
|
89
108
|
@apr = @options.float "--apr"
|
|
90
109
|
@apr_value = 2.9
|
|
91
|
-
@minus = @options.float "--minus"
|
|
110
|
+
@minus = @options.float "--minus", validate_type: true
|
|
92
111
|
@plus = @options.float "--plus"
|
|
93
112
|
@scientific_notation = @options.float "--scientific-notation"
|
|
94
113
|
@scientific_notation_value = 4e21
|
|
@@ -125,6 +144,12 @@ describe Slop::FloatOption do
|
|
|
125
144
|
@result.parser.parse %w(--apr hello)
|
|
126
145
|
assert_nil @result[:apr]
|
|
127
146
|
end
|
|
147
|
+
|
|
148
|
+
it "raises with invalid types" do
|
|
149
|
+
assert_raises(Slop::InvalidOptionValue) do
|
|
150
|
+
@result.parser.parse %w(--minus foo)
|
|
151
|
+
end
|
|
152
|
+
end
|
|
128
153
|
end
|
|
129
154
|
|
|
130
155
|
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.1
|
|
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-26 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: rake
|
|
@@ -90,12 +90,4 @@ rubygems_version: 3.3.7
|
|
|
90
90
|
signing_key:
|
|
91
91
|
specification_version: 4
|
|
92
92
|
summary: Simple Lightweight Option Parsing
|
|
93
|
-
test_files:
|
|
94
|
-
- test/error_test.rb
|
|
95
|
-
- test/option_test.rb
|
|
96
|
-
- test/options_test.rb
|
|
97
|
-
- test/parser_test.rb
|
|
98
|
-
- test/result_test.rb
|
|
99
|
-
- test/slop_test.rb
|
|
100
|
-
- test/test_helper.rb
|
|
101
|
-
- test/types_test.rb
|
|
93
|
+
test_files: []
|