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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: db594ae38cd4d8b8d078d3b3854e5dce764f4763107caacc02b0b270c33098d8
4
- data.tar.gz: 6e1348ca3f3d642bff87411d33c78b2f3d1b654c11c079a228f327f82648cd5f
3
+ metadata.gz: 2d4b4855a341f5e05c71ec19242556039ea85f4d339560dec38c24beb8831691
4
+ data.tar.gz: 95fcb3512ee937216387467758a05992d72bbfad627fd79b939277a204c941ad
5
5
  SHA512:
6
- metadata.gz: b578d6d172adf2b9c88d482fe27798d97a821b83ef7ff4f8b6e8ed37d63cd7f7963b9634b9f734e80d744c0fc077f47bc2a08e00feed02af90452c6415383494
7
- data.tar.gz: 8fc6007694ba5df48585ac6561c1ec68cf50141d92cb6f080d50b6de700a0244aefd3d3d647f7ccee197c57cfcd3ad4721b2c88039ab6f9667cb47d4dc705620
6
+ metadata.gz: c0ecc669117cf0c6336e3dfb1cf65c5019a0d638205a2497511121e102f7af7f48f175ded4c03d382257710da679970e4e405b84bee44a0613781d90b5bd4b63
7
+ data.tar.gz: 867c2ef751092ce4fafe9010f1b6ddb9ec7ee9adcdd2d020353129e7189b3ea8224f33ac368b773cca1298c297b159054775fb71074691e8ce9e20f780a58388
@@ -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@v2
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, no argument, aliased to BooleanOption
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 not longer has built in support for git-style subcommands.
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
- @value = call(value)
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 == false
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 =~ /\A[+-]?\d+\z/ && value.to_i
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 =~ FLOAT_STRING_REGEXP && value.to_f
83
+ value.to_f
65
84
  end
66
85
  end
67
86
 
data/lib/slop.rb CHANGED
@@ -6,7 +6,7 @@ require 'slop/types'
6
6
  require 'slop/error'
7
7
 
8
8
  module Slop
9
- VERSION = '4.9.2'
9
+ VERSION = '4.10.0'
10
10
 
11
11
  # Parse an array of options (defaults to ARGV). Accepts an
12
12
  # optional hash of configuration options and block.
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.9.2
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: 2022-03-26 00:00:00.000000000 Z
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.2.32
89
+ rubygems_version: 3.3.7
90
90
  signing_key:
91
91
  specification_version: 4
92
92
  summary: Simple Lightweight Option Parsing