slop 4.9.2 → 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 +11 -0
- data/README.md +34 -3
- 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 +22 -3
- data/lib/slop.rb +1 -1
- data/test/error_test.rb +15 -0
- data/test/types_test.rb +28 -4
- metadata +3 -3
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
|
@@ -1,6 +1,17 @@
|
|
|
1
1
|
Changelog
|
|
2
2
|
=========
|
|
3
3
|
|
|
4
|
+
v4.10.0 (2023-02-15)
|
|
5
|
+
|
|
6
|
+
Features:
|
|
7
|
+
* Add support for optional type validation [#278](https://github.com/leejarvis/slop/pull/278) (Victor Gama)
|
|
8
|
+
|
|
9
|
+
v4.9.3 (2022-09-30)
|
|
10
|
+
-------------------
|
|
11
|
+
|
|
12
|
+
Bug fixes:
|
|
13
|
+
* Fix explicitly false boolean options and allow for additional false arguments [#276](https://github.com/leejarvis/slop/pull/276) (Eugene Otto)
|
|
14
|
+
|
|
4
15
|
v4.9.2 (2022-03-26)
|
|
5
16
|
-------------------
|
|
6
17
|
|
data/README.md
CHANGED
|
@@ -22,17 +22,19 @@ opts = Slop.parse do |o|
|
|
|
22
22
|
o.bool '-v', '--verbose', 'enable verbose mode'
|
|
23
23
|
o.bool '-q', '--quiet', 'suppress output (quiet mode)'
|
|
24
24
|
o.bool '-c', '--check-ssl-certificate', 'check SSL certificate for host'
|
|
25
|
+
o.bool '-k', '--use-keychain', 'store passphrase in OS keychain'
|
|
25
26
|
o.on '--version', 'print the version' do
|
|
26
27
|
puts Slop::VERSION
|
|
27
28
|
exit
|
|
28
29
|
end
|
|
29
30
|
end
|
|
30
31
|
|
|
31
|
-
ARGV #=> -v --login alice --host 192.168.0.1 -m post --check-ssl-certificate
|
|
32
|
+
ARGV #=> -v --login alice --host 192.168.0.1 -m post --check-ssl-certificate --use-keychain false
|
|
32
33
|
|
|
33
34
|
opts[:host] #=> 192.168.0.1
|
|
34
35
|
opts[:login] #=> alice
|
|
35
36
|
opts[:method] #=> :post
|
|
37
|
+
opts[:use_keychain] #=> false
|
|
36
38
|
opts.verbose? #=> true
|
|
37
39
|
opts.quiet? #=> false
|
|
38
40
|
opts.check_ssl_certificate? #=> true
|
|
@@ -53,7 +55,7 @@ Built in Option types are as follows:
|
|
|
53
55
|
|
|
54
56
|
```ruby
|
|
55
57
|
o.string #=> Slop::StringOption, expects an argument
|
|
56
|
-
o.bool #=> Slop::BoolOption,
|
|
58
|
+
o.bool #=> Slop::BoolOption, argument optional, aliased to BooleanOption
|
|
57
59
|
o.integer #=> Slop::IntegerOption, expects an argument, aliased to IntOption
|
|
58
60
|
o.float #=> Slop::FloatOption, expects an argument
|
|
59
61
|
o.array #=> Slop::ArrayOption, expects an argument
|
|
@@ -202,6 +204,8 @@ Slop will raise errors for the following:
|
|
|
202
204
|
* An option used without an argument when it expects one: `Slop::MissingArgument`
|
|
203
205
|
* An option used that Slop doesn't know about: `Slop::UnknownOption`
|
|
204
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`
|
|
205
209
|
|
|
206
210
|
These errors inherit from `Slop::Error`, so you can rescue them all.
|
|
207
211
|
Alternatively you can suppress these errors with the `suppress_errors` config
|
|
@@ -220,6 +224,33 @@ opts = Slop.parse do
|
|
|
220
224
|
end
|
|
221
225
|
```
|
|
222
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
|
+
|
|
223
254
|
Printing help
|
|
224
255
|
-------------
|
|
225
256
|
|
|
@@ -277,4 +308,4 @@ end
|
|
|
277
308
|
Commands
|
|
278
309
|
--------
|
|
279
310
|
|
|
280
|
-
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
|
@@ -21,6 +21,15 @@ module Slop
|
|
|
21
21
|
class BoolOption < Option
|
|
22
22
|
attr_accessor :explicit_value
|
|
23
23
|
|
|
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
|
|
32
|
+
|
|
24
33
|
def call(value)
|
|
25
34
|
self.explicit_value = value
|
|
26
35
|
!force_false?
|
|
@@ -35,7 +44,7 @@ module Slop
|
|
|
35
44
|
end
|
|
36
45
|
|
|
37
46
|
def force_false?
|
|
38
|
-
explicit_value
|
|
47
|
+
FALSE_VALUES.include?(explicit_value)
|
|
39
48
|
end
|
|
40
49
|
|
|
41
50
|
def default_value
|
|
@@ -50,8 +59,14 @@ module Slop
|
|
|
50
59
|
|
|
51
60
|
# Cast the option argument to an Integer.
|
|
52
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
|
+
|
|
53
68
|
def call(value)
|
|
54
|
-
value
|
|
69
|
+
value.to_i
|
|
55
70
|
end
|
|
56
71
|
end
|
|
57
72
|
IntOption = IntegerOption
|
|
@@ -60,8 +75,12 @@ module Slop
|
|
|
60
75
|
class FloatOption < Option
|
|
61
76
|
FLOAT_STRING_REGEXP = /\A[+-]?(?:0|[1-9]\d*)(?:\.\d*)?(?:[eE][+-]?\d+)?\z/.freeze
|
|
62
77
|
|
|
78
|
+
def valid?(value)
|
|
79
|
+
value =~ FLOAT_STRING_REGEXP
|
|
80
|
+
end
|
|
81
|
+
|
|
63
82
|
def call(value)
|
|
64
|
-
value
|
|
83
|
+
value.to_f
|
|
65
84
|
end
|
|
66
85
|
end
|
|
67
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,12 +31,14 @@ 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", validate_type: true
|
|
37
38
|
@bloc = @options.bool("--bloc"){|val| (@bloc_val ||= []) << val}
|
|
38
39
|
@result = @options.parse %w(--verbose --no-inversed
|
|
39
|
-
--bloc --no-bloc
|
|
40
|
+
--bloc --no-bloc
|
|
41
|
+
--explicit=false)
|
|
40
42
|
end
|
|
41
43
|
|
|
42
44
|
it "returns true if used" do
|
|
@@ -54,13 +56,23 @@ describe Slop::BoolOption do
|
|
|
54
56
|
it "will invert the value passed to &block via --no- prefix" do
|
|
55
57
|
assert_equal [true, false], @bloc_val
|
|
56
58
|
end
|
|
59
|
+
|
|
60
|
+
it "returns false when explicitly false" do
|
|
61
|
+
assert_equal false, @result[:explicit]
|
|
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
|
|
57
69
|
end
|
|
58
70
|
|
|
59
71
|
describe Slop::IntegerOption do
|
|
60
72
|
before do
|
|
61
73
|
@options = Slop::Options.new
|
|
62
74
|
@age = @options.integer "--age"
|
|
63
|
-
@minus = @options.integer "--minus"
|
|
75
|
+
@minus = @options.integer "--minus", validate_type: true
|
|
64
76
|
@plus = @options.integer "--plus"
|
|
65
77
|
@result = @options.parse %w(--age 20 --minus -10 --plus +30)
|
|
66
78
|
end
|
|
@@ -75,6 +87,12 @@ describe Slop::IntegerOption do
|
|
|
75
87
|
@result.parser.parse %w(--age hello)
|
|
76
88
|
assert_nil @result[:age]
|
|
77
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
|
|
78
96
|
end
|
|
79
97
|
|
|
80
98
|
describe Slop::FloatOption do
|
|
@@ -82,7 +100,7 @@ describe Slop::FloatOption do
|
|
|
82
100
|
@options = Slop::Options.new
|
|
83
101
|
@apr = @options.float "--apr"
|
|
84
102
|
@apr_value = 2.9
|
|
85
|
-
@minus = @options.float "--minus"
|
|
103
|
+
@minus = @options.float "--minus", validate_type: true
|
|
86
104
|
@plus = @options.float "--plus"
|
|
87
105
|
@scientific_notation = @options.float "--scientific-notation"
|
|
88
106
|
@scientific_notation_value = 4e21
|
|
@@ -119,6 +137,12 @@ describe Slop::FloatOption do
|
|
|
119
137
|
@result.parser.parse %w(--apr hello)
|
|
120
138
|
assert_nil @result[:apr]
|
|
121
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
|
|
122
146
|
end
|
|
123
147
|
|
|
124
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
|
|
@@ -86,7 +86,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
86
86
|
- !ruby/object:Gem::Version
|
|
87
87
|
version: '0'
|
|
88
88
|
requirements: []
|
|
89
|
-
rubygems_version: 3.
|
|
89
|
+
rubygems_version: 3.3.7
|
|
90
90
|
signing_key:
|
|
91
91
|
specification_version: 4
|
|
92
92
|
summary: Simple Lightweight Option Parsing
|