chain_options 0.1.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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 5632f3b6617e959a1329ae0bba7f1c4c3f24b8678e326a60e2507c07aad97efe
4
+ data.tar.gz: 1d814bcc04f29d57d614faea7738e38df7ecdc1917016b084c30dd61b57d6d17
5
+ SHA512:
6
+ metadata.gz: 5f3d50a324399a2a9709c4fbd2308678ba39c882c47460cc5541ef3c5265b21b4c9254c33c5f79368d6b937133274fc7eb5695cea42950a6dfa24957fd2bd38e
7
+ data.tar.gz: 02d5fc98eb5832186a75618e8b4721a15eb13282942ad12485bde7e7ee0dcc0595d3cf4a94345bd94e3d36bf26c7310758326c808a3eeb907c8e930030c1ae24
data/.gitignore ADDED
@@ -0,0 +1,11 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /_yardoc/
4
+ /coverage/
5
+ /doc/
6
+ /pkg/
7
+ /spec/reports/
8
+ /tmp/
9
+
10
+ # rspec failure tracking
11
+ .rspec_status
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --format documentation
2
+ --color
3
+ --require spec_helper
data/.rubocop.yml ADDED
@@ -0,0 +1,138 @@
1
+ AllCops:
2
+ TargetRubyVersion: 2.3
3
+ Exclude:
4
+ - tmp/**/*
5
+
6
+ #---------------------------------------------
7
+ # Layout
8
+ #---------------------------------------------
9
+
10
+ # Hashes do not need padding
11
+ Layout/SpaceInsideHashLiteralBraces:
12
+ Enabled: false
13
+
14
+ # Allow 2 space indentation for when inside a case
15
+ Layout/CaseIndentation:
16
+ Enabled: false
17
+
18
+ # Allow empty lines in classes
19
+ Layout/EmptyLinesAroundClassBody:
20
+ Enabled: false
21
+
22
+ # Allow multiple spaces before first argument
23
+ Layout/SpaceBeforeFirstArg:
24
+ Enabled: false
25
+
26
+ # Allow extra spacing, e.g. to align components
27
+ Layout/ExtraSpacing:
28
+ Enabled: false
29
+
30
+ # Usually good, but in some cases not possible
31
+ Layout/AlignHash:
32
+ Enabled: false
33
+
34
+ # Allow an empty line after do / before end
35
+ Layout/EmptyLinesAroundBlockBody:
36
+ Enabled: false
37
+
38
+ # Again, generally a good idea, but it has problems with multiline operations in
39
+ # combination with assignments
40
+ Layout/MultilineOperationIndentation:
41
+ Enabled: false
42
+
43
+ # See the corresponding other cops
44
+ Layout/EmptyLinesAroundModuleBody:
45
+ Enabled: false
46
+
47
+ Layout/SpaceInLambdaLiteral:
48
+ Enabled: false
49
+
50
+ #---------------------------------------------
51
+ # Metrics
52
+ #---------------------------------------------
53
+
54
+ # Allow bigger classes
55
+ Metrics/ClassLength:
56
+ Enabled: false
57
+
58
+ Metrics/LineLength:
59
+ Max: 120
60
+
61
+ # To make it possible to copy or click on URIs in the code, we allow lines
62
+ # containing a URI to be longer than Max.
63
+ AllowHeredoc: true
64
+ AllowURI: true
65
+
66
+ Metrics/BlockLength:
67
+ Max: 75
68
+ Exclude:
69
+ - spec/**/*.rb
70
+ - lib/chain_options/test_integration/rspec.rb
71
+
72
+ # Allow longer methods
73
+ Metrics/MethodLength:
74
+ Enabled: false
75
+
76
+ # Allow bigger modules
77
+ Metrics/ModuleLength:
78
+ Enabled: false
79
+
80
+ Metrics/ParameterLists:
81
+ Exclude:
82
+ - lib/chain_options/option_set.rb
83
+
84
+ #---------------------------------------------
85
+ # Naming
86
+ #---------------------------------------------
87
+
88
+ Naming/HeredocDelimiterNaming:
89
+ Enabled: false
90
+
91
+ #---------------------------------------------
92
+ # Style
93
+ #---------------------------------------------
94
+
95
+ # Allow fail() for initial exception, raise() for re-raise
96
+ # It seems that the cop decision was mainly based on "more people use raise than fail"...
97
+ Style/SignalException:
98
+ Enabled: false
99
+
100
+ # Allow assigning multiple variables in one line.
101
+ # This should not be overused, but comes in handy when assigning initializer values to instance variables
102
+ Style/ParallelAssignment:
103
+ Enabled: false
104
+
105
+ # Depending on the situation, it might make more sense to use
106
+ # [:symbol1, :symbol2] over %i[symbol1 symbol2], e.g. for multiline aligning reasons.
107
+ Style/SymbolArray:
108
+ Enabled: false
109
+
110
+ # Not all modules have to have top level comments
111
+ Style/Documentation:
112
+ Enabled: false
113
+
114
+ # Allow class variable usage
115
+ Style/ClassVars:
116
+ Enabled: false
117
+
118
+ # Allow block comments
119
+ Style/BlockComments:
120
+ Enabled: false
121
+
122
+ # Allow the use of !! (conversion of nil/object to true/false)
123
+ Style/DoubleNegation:
124
+ Enabled: false
125
+
126
+ # Allow unless/if blocks even for one-liners
127
+ Style/IfUnlessModifier:
128
+ Enabled: false
129
+
130
+ Style/GuardClause:
131
+ Enabled: false
132
+
133
+ Style/AccessModifierDeclarations:
134
+ Enabled: false
135
+
136
+ Style/MethodMissingSuper:
137
+ Exclude:
138
+ - lib/chain_options/util.rb
data/.travis.yml ADDED
@@ -0,0 +1,21 @@
1
+ language: ruby
2
+ sudo: false
3
+ cache: bundler
4
+
5
+ rvm:
6
+ - 2.3.0
7
+ - 2.3.3
8
+ - 2.4.0
9
+ - 2.4.4
10
+ - 2.5.0
11
+ - 2.5.3
12
+
13
+ before_install: gem install bundler
14
+
15
+ before_script:
16
+ - curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./cc-test-reporter
17
+ - chmod +x ./cc-test-reporter
18
+ - ./cc-test-reporter before-build
19
+
20
+ after_script:
21
+ - ./cc-test-reporter after-build --exit-code $TRAVIS_TEST_RESULT
data/Gemfile ADDED
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ source 'https://rubygems.org'
4
+
5
+ git_source(:github) { |repo_name| "https://github.com/#{repo_name}" }
6
+
7
+ # Specify your gem's dependencies in chain_options.gemspec
8
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,72 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ chain_options (0.1.0)
5
+
6
+ GEM
7
+ remote: https://rubygems.org/
8
+ specs:
9
+ ast (2.4.0)
10
+ byebug (10.0.2)
11
+ coderay (1.1.2)
12
+ diff-lcs (1.3)
13
+ docile (1.3.1)
14
+ jaro_winkler (1.5.1)
15
+ json (2.1.0)
16
+ method_source (0.9.2)
17
+ parallel (1.12.1)
18
+ parser (2.5.3.0)
19
+ ast (~> 2.4.0)
20
+ powerpack (0.1.2)
21
+ pry (0.12.2)
22
+ coderay (~> 1.1.0)
23
+ method_source (~> 0.9.0)
24
+ pry-byebug (3.6.0)
25
+ byebug (~> 10.0)
26
+ pry (~> 0.10)
27
+ rainbow (3.0.0)
28
+ rake (10.5.0)
29
+ rspec (3.8.0)
30
+ rspec-core (~> 3.8.0)
31
+ rspec-expectations (~> 3.8.0)
32
+ rspec-mocks (~> 3.8.0)
33
+ rspec-core (3.8.0)
34
+ rspec-support (~> 3.8.0)
35
+ rspec-expectations (3.8.2)
36
+ diff-lcs (>= 1.2.0, < 2.0)
37
+ rspec-support (~> 3.8.0)
38
+ rspec-mocks (3.8.0)
39
+ diff-lcs (>= 1.2.0, < 2.0)
40
+ rspec-support (~> 3.8.0)
41
+ rspec-support (3.8.0)
42
+ rubocop (0.60.0)
43
+ jaro_winkler (~> 1.5.1)
44
+ parallel (~> 1.10)
45
+ parser (>= 2.5, != 2.5.1.1)
46
+ powerpack (~> 0.1)
47
+ rainbow (>= 2.2.2, < 4.0)
48
+ ruby-progressbar (~> 1.7)
49
+ unicode-display_width (~> 1.4.0)
50
+ ruby-progressbar (1.10.0)
51
+ simplecov (0.16.1)
52
+ docile (~> 1.1)
53
+ json (>= 1.8, < 3)
54
+ simplecov-html (~> 0.10.0)
55
+ simplecov-html (0.10.2)
56
+ unicode-display_width (1.4.0)
57
+
58
+ PLATFORMS
59
+ ruby
60
+
61
+ DEPENDENCIES
62
+ bundler (~> 1.16)
63
+ chain_options!
64
+ pry (~> 0.12)
65
+ pry-byebug (~> 3.6)
66
+ rake (~> 10.0)
67
+ rspec (~> 3.8)
68
+ rubocop (~> 0.60)
69
+ simplecov (~> 0.16)
70
+
71
+ BUNDLED WITH
72
+ 1.17.1
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2018 Stefan Exner
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,319 @@
1
+ [![Build Status](https://travis-ci.org/lokalportal/chain_options.svg?branch=master)](https://travis-ci.org/lokalportal/chain_options)
2
+ [![Maintainability](https://api.codeclimate.com/v1/badges/aa9c3e9eb2a02095c587/maintainability)](https://codeclimate.com/github/lokalportal/chain_options/maintainability)
3
+ [![Test Coverage](https://api.codeclimate.com/v1/badges/aa9c3e9eb2a02095c587/test_coverage)](https://codeclimate.com/github/lokalportal/chain_options/test_coverage)
4
+
5
+ # ChainOptions
6
+
7
+ ChainOptions is a small gem which allows you to add non-destructive chainable options to
8
+ your classes. It is useful to incrementally build instances without overriding the previous
9
+ one and provides an easy-to-understand DSL to set options either through
10
+ method-chaining or in a block.
11
+
12
+ An example:
13
+
14
+ ```ruby
15
+ class MyItemFeed
16
+ include ChainOptions::Integration
17
+
18
+ chain_option :page,
19
+ default: 1,
20
+ invalid: :default,
21
+ validate: ->(value) { value.to_i.positive? }
22
+
23
+ chain_option :per_page,
24
+ default: 30,
25
+ validate: ->(value) { value.to_i.positive? },
26
+ invalid: :default
27
+ end
28
+
29
+ feed = MyItemFeed.new.build_options do
30
+ set :page, params[:page]
31
+ set :per_page, params[:per_page]
32
+ end
33
+
34
+ # or
35
+
36
+ feed = MyItemFeed.new.page(params[:page]).per_page(params[:per_page])
37
+ ```
38
+
39
+ ## Installation
40
+
41
+ Add this line to your application's Gemfile:
42
+
43
+ ```ruby
44
+ gem 'chain_options'
45
+ ```
46
+
47
+ And then execute:
48
+
49
+ $ bundle
50
+
51
+ Or install it yourself as:
52
+
53
+ $ gem install chain_options
54
+
55
+ ## Usage
56
+
57
+ To use ChainOptions in one of your classes, simply include its integration module:
58
+
59
+ ```ruby
60
+ include ChainOptions::Integration
61
+ ```
62
+
63
+ Afterwards, you're ready to define the options available to instances of your class.
64
+
65
+ ### Basic Options
66
+
67
+ The easiest way to define an option is to call `chain_option` with just the option name:
68
+
69
+ ```ruby
70
+ class MyClass
71
+ chain_option :my_option
72
+ end
73
+ ```
74
+
75
+ This will generate the method `#my_option` which is accessible by instances of your class.
76
+ When it's called with an argument, it will return a new instance of your class with
77
+ the option set to this value, when being called without an argument, it will return the current value.
78
+
79
+ ```ruby
80
+ my_class = MyClass.new #=> Instance 1 of MyClass
81
+ my_class.my_option('my value') #=> Instance 2 of MyClass
82
+ my_class.my_option #=> 'my value'
83
+ ```
84
+
85
+ Please note that instance variables are currently not carried over to the new
86
+ instances built when setting a new option.
87
+ This decision was made to ensure no cached values could be used any more
88
+ after changing an option value:
89
+
90
+ ```ruby
91
+ class Feed
92
+ chain_option :page
93
+ chain_option :per_page
94
+
95
+ def entries
96
+ @entries ||= MyModel.page(page).per(per_page)
97
+ end
98
+ end
99
+ ```
100
+
101
+ Setting `page` to a different value after `#entries` was called once would not
102
+ lead to another page being loaded, the return value would stay the same.
103
+
104
+ This behaviour might be changed in the future, but would only make the gem more complex
105
+ for now.
106
+
107
+ Array may be passed in as multiple arguments or an Array object, so the following calls are equivalent:
108
+
109
+ ```ruby
110
+ my_object.my_value(1, 2, 3)
111
+ my_option.my_value([1, 2, 3])
112
+ ```
113
+
114
+ ### Advanced Options
115
+
116
+ #### Filters
117
+
118
+ It is possible to apply filters to option values. As soon as a filter Proc is defined,
119
+ it is assumed that the option value will be an Array.
120
+
121
+ ```ruby
122
+ chain_option :my_even_numbers,
123
+ filter: -> (number) { number.even? }
124
+
125
+ my_object.my_even_numbers(1, 2, 3, 4, 5) #=> [2, 4]
126
+ ```
127
+
128
+ **Note**: As soon as `:filter` is defined, the value will be treated as Array, even if only a single
129
+ element is passed in:
130
+
131
+ ```ruby
132
+ my_object.my_even_numbers(2) #=> [2]
133
+ ```
134
+
135
+ #### Value Validations
136
+
137
+ It is possible to define validations on the setting value. These are executed whenever a new
138
+ value is set and will either cause an Exception or the option going back to the default value:
139
+
140
+ ```ruby
141
+ chain_option :per_page,
142
+ validate: -> (value) { value.to_i.positive? },
143
+ invalid: :raise
144
+ ```
145
+
146
+ The above example ensures that a value set for the `per_page` option has to be positive.
147
+ Otherwise, an `ArgumentError` is raised.
148
+
149
+ ```ruby
150
+ chain_option :per_page,
151
+ default: 1
152
+ validate: -> (value) { value.to_i.positive? },
153
+ invalid: :default
154
+
155
+ my_object.per_page(-1).per_page #=> 1
156
+ ```
157
+
158
+ **Note**: If filters are set up as well, your validation proc will always receive an Array, never a single element.
159
+
160
+ #### Value Transformations
161
+
162
+ It is possible to perform automatic transformations (or type casts) on an option value,
163
+ pretty similar to what ActiveRecord does when e.g. a numeric value is assigned to a string attribute.
164
+
165
+ As options don't have a type, you have to define the transformation yourself:
166
+
167
+ ```ruby
168
+ chain_option :my_strings,
169
+ transform: -> (element) { element.to_s }
170
+
171
+ chain_option :my_strings,
172
+ transform: :to_s
173
+ ```
174
+
175
+ The above calls are equivalent. If a symbol is given, the value (resp. each element of it in case of
176
+ an Array) is expected to respond to a method with the same name.
177
+
178
+ If the value is an array, the `transform` Proc will receive each item individually.
179
+
180
+ #### Default Values
181
+
182
+ It is possible to specify a default value for each option using the `:default` keyword argument.
183
+ The default value is returned in the following cases:
184
+
185
+ * No custom value was set for the option yet
186
+ * The value set for the option is invalid and the option is set to use the default value instead (see below)
187
+
188
+ The default value may either be a Proc which is executed on demand or any kind of Ruby object.
189
+
190
+ ```ruby
191
+ chain_option :per_page,
192
+ default: -> { SomeStore.get_default_per_page }
193
+ ```
194
+
195
+ #### Incremental Values
196
+
197
+ Options can be set to increment their value through multiple setter calls:
198
+
199
+ ```ruby
200
+ chain_option :favourite_books, incremental: true
201
+
202
+ user.favourite_books('Lord of the Rings').favourite_books('The Hobbit')
203
+ #=> [['Lord of the Rings'], ['The Hobbit]]
204
+ ```
205
+
206
+ As the values should still be separateable, the elements which were added in each
207
+ setter call are wrapped in another array instead of just appending them to the collection.
208
+ Otherwise, it wouldn't be possible to determine that the following value was caused by two sets:
209
+
210
+ ```ruby
211
+ user.favourite_books('Momo', 'Neverending Story').favourite_books('Lord of the Rings', 'The Hobbit')
212
+ #=> [["Momo", "Neverending Story"], ["Lord of the Rings", "The Hobbit"]]
213
+ ```
214
+
215
+ #### Blocks as option values
216
+
217
+ If your option accepts blocks as values, setting this to `true` allows you to use the block syntax
218
+ to set a new option value instead of having to pass in a lambda function or Proc object:
219
+
220
+ ```ruby
221
+ chain_option :my_proc, allow_block: true
222
+
223
+ my_object = my_object.my_proc do
224
+ # ...
225
+ end
226
+
227
+ my_object.my_proc #=> <#Proc...>
228
+ ```
229
+
230
+ ## Option Testing
231
+
232
+ ChainOptions comes with basic RSpec integration by providing custom matchers.
233
+
234
+ To use them, simply require the corresponding module and include it in your specs:
235
+
236
+ ```ruby
237
+ require 'chain_options/test_integration/rspec'
238
+
239
+ subject { MyClass.new }
240
+
241
+ describe 'my_option' do
242
+ include ChainOptions::TestIntegration::Rspec
243
+
244
+ it { is_expected.to have_chain_option(:my_option) }
245
+ end
246
+ ```
247
+
248
+ Every matcher call starts with `have_chain_option` which ensures the the given
249
+ object actually has access to a chain option with the given name.
250
+
251
+ ### Value Acceptance
252
+
253
+ To test for values which should raise an exception when being set as a chain option value,
254
+ continue the matcher as follows:
255
+
256
+ ```ruby
257
+ it { is_expected.to have_chain_option(:my_option).which_takes(42).and_raises_an_exception }
258
+ ```
259
+
260
+ This matcher can only fail if the option is set to `invalid: :raise`.
261
+
262
+ ### Value Filters / Transformations
263
+
264
+ To test whether the option is actually set to the correct value after passing an object to it,
265
+ continue the matcher as follows:
266
+
267
+ ```ruby
268
+ it { is_expected.to have_chain_option(:my_option).which_takes(42).and_sets_it_as_value }
269
+ ```
270
+
271
+ If you expect the option to perform a filtering and/or transformation, you can also
272
+ specify the actual value you expect to be set:
273
+
274
+ ```ruby
275
+ it { is_expected.to have_chain_option(:my_option).which_takes(42).and_sets("42").as_value }
276
+ ```
277
+
278
+ ### Default Value
279
+
280
+ To test whether the option has a certain default value, continue the matcher as follows:
281
+
282
+ ```ruby
283
+ it { is_expected.to have_chain_option(:my_option).with_the_default_value(21) }
284
+ ```
285
+
286
+ ### Basic Testing
287
+
288
+ If you can't or don't want to use the custom matchers, you could define your own helper
289
+ methods to keep your option tests readable:
290
+
291
+ ```ruby
292
+ def expect_to_eql(name, value, expected)
293
+ expect(subject.send(name, value).send(name)).to eql expected
294
+ end
295
+
296
+ def expect_to_raise(name, value)
297
+ expect { subject.send(name, value) }.to raise_error(ArgumentError, /not valid/),
298
+ "`#{value.inspect}` should not be a valid value for option `#{name}`"
299
+ end
300
+
301
+ it { expect_to_eql :my_option, 42, '42' }
302
+ it { expect_to_raise :my_option, Object.new }
303
+ ```
304
+
305
+ ## Contributing
306
+
307
+ Bug reports and pull requests are welcome on GitHub at https://github.com/lokalportal/chain_options.
308
+ For pull request, please follow [git-flow](https://danielkummer.github.io/git-flow-cheatsheet/) naming conventions.
309
+
310
+ This project is intended to be a safe, welcoming space for collaboration,
311
+ and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
312
+
313
+ ## License
314
+
315
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
316
+
317
+ ## Code of Conduct
318
+
319
+ Everyone interacting in the ChainOptions project’s codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/[USERNAME]/chain_options/blob/master/CODE_OF_CONDUCT.md).
data/Rakefile ADDED
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'bundler/gem_tasks'
4
+ require 'rspec/core/rake_task'
5
+
6
+ RSpec::Core::RakeTask.new(:spec)
7
+
8
+ task default: :spec
data/bin/console ADDED
@@ -0,0 +1,15 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require 'bundler/setup'
5
+ require 'chain_options'
6
+
7
+ # You can add fixtures and/or initialization code here to make experimenting
8
+ # with your gem easier. You can also use a different console, if you like.
9
+
10
+ # (If you use this, don't forget to add pry to your Gemfile!)
11
+ # require "pry"
12
+ # Pry.start
13
+
14
+ require 'irb'
15
+ IRB.start(__FILE__)
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ lib = File.expand_path('lib', __dir__)
4
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
5
+ require 'chain_options/version'
6
+
7
+ Gem::Specification.new do |spec|
8
+ spec.name = 'chain_options'
9
+ spec.version = ChainOptions::VERSION
10
+ spec.authors = ['Stefan Exner']
11
+ spec.email = ['stex@sterex.de']
12
+
13
+ spec.summary = 'DSL to add non(destructive).option(methods).to(objects)'
14
+ spec.homepage = 'https://github.com/lokalportal/chain_options'
15
+ spec.license = 'MIT'
16
+ spec.files = `git ls-files -z`.split("\x0").reject do |f|
17
+ f.match(%r{^(test|spec|features)/})
18
+ end
19
+ spec.bindir = 'exe'
20
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
21
+ spec.require_paths = ['lib']
22
+
23
+ spec.required_ruby_version = ['>= 2.3', '< 3']
24
+
25
+ spec.add_development_dependency 'bundler', '~> 1.16'
26
+ spec.add_development_dependency 'pry', '~> 0.12'
27
+ spec.add_development_dependency 'pry-byebug', '~> 3.6'
28
+ spec.add_development_dependency 'rake', '~> 10.0'
29
+ spec.add_development_dependency 'rspec', '~> 3.8'
30
+ spec.add_development_dependency 'rubocop', '~> 0.60'
31
+ spec.add_development_dependency 'simplecov', '~> 0.16'
32
+ end