block_repeater 0.3.0 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9eb254f9b3cc31e89dcb02d9df2b8bbe427b96b642cb14e293d05ff3b2da1200
4
- data.tar.gz: a360aacd3781b60724ac47854eb897bfc1bbc749e246e76b6cf13f6f7ebb2f12
3
+ metadata.gz: f94ed1fef785fdbd5a8f8f6810406a6a610be84fd551886b3e8b4784b7f47402
4
+ data.tar.gz: 4bace96bec87f17aacbc235907af48e5dfd641f1ff2f0c4126b95dff79f04fd1
5
5
  SHA512:
6
- metadata.gz: 8699bfd292493fb33fb07241c38b871448c2c9cf76f28062d391eecf7804fbbf6455b1dbf2ed36ca4b8c795358f8691834fd0a825a1fe8b67d3d42f33aadec7c
7
- data.tar.gz: a9bac7eaf904093e1691e564ec230cab1c71bcdcb8d36a87958efacefd70f7e9bf5faa04e6e423ba513c32b6b1e45e39b84af7ecbbabdc8682f208f7af1211ec
6
+ metadata.gz: be8d84eacb5b9397e6c47757fb68a06bb4c039cf6632230b68e44abffbb22b6d040b45f5b238220f12d25969e028a80228479f4afb0ba2a9ddebc71bf0ccaa43
7
+ data.tar.gz: 61437b317664440b00db72f3b8cb3e20d4d3da18281b9c9e6a87252a29200c622036e3bd824b3d077063208b7d6ff07ca4683498bd442fae913a36ce63530afc
@@ -0,0 +1,52 @@
1
+ name: Ruby Gem
2
+
3
+ on:
4
+ push:
5
+ branches: [ "master" ]
6
+ pull_request:
7
+ branches: [ "master" ]
8
+
9
+ jobs:
10
+ test:
11
+ runs-on: ubuntu-latest
12
+ strategy:
13
+ matrix:
14
+ ruby-version: [ '3.0', '3.1' ]
15
+
16
+ steps:
17
+ - uses: actions/checkout@v2
18
+ - name: Set up Ruby
19
+ uses: ruby/setup-ruby@v1
20
+ with:
21
+ ruby-version: ${{ matrix.ruby-version }}
22
+ bundler-cache: true # runs 'bundle install' and caches installed gems automatically
23
+ - name: Rubocop
24
+ run: bundle exec rubocop
25
+ - name: Run tests
26
+ run: bundle exec rake
27
+
28
+ deploy:
29
+ needs: test
30
+ runs-on: ubuntu-latest
31
+ permissions:
32
+ packages: write
33
+ contents: read
34
+
35
+ steps:
36
+ - uses: actions/checkout@v2
37
+ - name: Set up Ruby 3.0.1
38
+ uses: ruby/setup-ruby@v1
39
+ with:
40
+ ruby-version: 3.0.1
41
+ bundler-cache: true
42
+
43
+ - name: Publish to RubyGems
44
+ run: |
45
+ mkdir -p $HOME/.gem
46
+ touch $HOME/.gem/credentials
47
+ chmod 0600 $HOME/.gem/credentials
48
+ printf -- "---\n:rubygems_api_key: ${GEM_HOST_API_KEY}\n" > $HOME/.gem/credentials
49
+ gem build *.gemspec
50
+ gem push *.gem
51
+ env:
52
+ GEM_HOST_API_KEY: "${{secrets.RUBYGEMS_AUTH_TOKEN}}"
data/.rubocop.yml ADDED
@@ -0,0 +1,25 @@
1
+ ---
2
+
3
+ AllCops:
4
+ TargetRubyVersion: 3.0
5
+
6
+ Style/MultilineBlockChain:
7
+ Enabled: false
8
+
9
+ Style/ClassVars:
10
+ Enabled: false
11
+
12
+ Metrics/AbcSize:
13
+ Enabled: false
14
+
15
+ Metrics/CyclomaticComplexity:
16
+ Enabled: false
17
+
18
+ Metrics/MethodLength:
19
+ Enabled: false
20
+
21
+ Metrics/PerceivedComplexity:
22
+ Enabled: false
23
+
24
+ Metrics/BlockLength:
25
+ Enabled: false
data/Gemfile CHANGED
@@ -6,4 +6,4 @@ source 'https://rubygems.org'
6
6
  gemspec
7
7
 
8
8
  gem 'rake', '~> 12.0'
9
- gem 'rspec', '~> 3.0'
9
+ gem 'rubocop', '~> 1.50.0'
data/Gemfile.lock CHANGED
@@ -1,19 +1,27 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- block_repeater (0.3.0)
4
+ block_repeater (1.0.0)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
8
8
  specs:
9
+ ast (2.4.2)
9
10
  bump (0.10.0)
10
11
  coderay (1.1.3)
11
12
  diff-lcs (1.4.4)
13
+ json (2.6.3)
12
14
  method_source (1.0.0)
15
+ parallel (1.23.0)
16
+ parser (3.2.2.1)
17
+ ast (~> 2.4.1)
13
18
  pry (0.14.1)
14
19
  coderay (~> 1.1)
15
20
  method_source (~> 1.0)
21
+ rainbow (3.1.1)
16
22
  rake (12.3.3)
23
+ regexp_parser (2.8.0)
24
+ rexml (3.2.5)
17
25
  rspec (3.10.0)
18
26
  rspec-core (~> 3.10.0)
19
27
  rspec-expectations (~> 3.10.0)
@@ -27,6 +35,20 @@ GEM
27
35
  diff-lcs (>= 1.2.0, < 2.0)
28
36
  rspec-support (~> 3.10.0)
29
37
  rspec-support (3.10.2)
38
+ rubocop (1.50.2)
39
+ json (~> 2.3)
40
+ parallel (~> 1.10)
41
+ parser (>= 3.2.0.0)
42
+ rainbow (>= 2.2.2, < 4.0)
43
+ regexp_parser (>= 1.8, < 3.0)
44
+ rexml (>= 3.2.5, < 4.0)
45
+ rubocop-ast (>= 1.28.0, < 2.0)
46
+ ruby-progressbar (~> 1.7)
47
+ unicode-display_width (>= 2.4.0, < 3.0)
48
+ rubocop-ast (1.28.1)
49
+ parser (>= 3.2.1.0)
50
+ ruby-progressbar (1.13.0)
51
+ unicode-display_width (2.4.2)
30
52
 
31
53
  PLATFORMS
32
54
  ruby
@@ -34,10 +56,11 @@ PLATFORMS
34
56
  DEPENDENCIES
35
57
  block_repeater!
36
58
  bump (~> 0.6)
37
- bundler (~> 2.1.4)
59
+ bundler (~> 2.4.0)
38
60
  pry
39
61
  rake (~> 12.0)
40
- rspec (~> 3.0)
62
+ rspec (~> 3.8)
63
+ rubocop (~> 1.50.0)
41
64
 
42
65
  BUNDLED WITH
43
- 2.1.4
66
+ 2.4.10
data/README.md CHANGED
@@ -33,10 +33,10 @@ Repeater = BlockRepeater::Repeater
33
33
  This is the preferred way to use the repeater. It requires two blocks, the one to be executed and the one which sets the exit condition. As these are ordinary ruby blocks they can be defined using either `{ }` or `do end` syntax.
34
34
 
35
35
  ```ruby
36
- repeater{ call_database_method }.until{ |result| result.count.positive? }
36
+ repeat { call_database_method }.until{ |result| result.count.positive? }
37
37
  ```
38
38
  ```ruby
39
- repeater do
39
+ repeat do
40
40
  call_database_method
41
41
  end.until do |result|
42
42
  result.count.positive?
@@ -47,13 +47,53 @@ The repeater also takes two parameters:
47
47
  - `delay:` is how long in seconds the repeater will wait between attempts (defaults to 0.2 seconds)
48
48
  - `times:` is how many attempts the repeater will make before giving up (defaults to 25)
49
49
  ```ruby
50
- repeater(delay: 0.5, times: 10){ call_database_method }.until{ |result| result.count.positive? }
50
+ repeat (delay: 0.5, times: 10){ call_database_method }.until{ |result| result.count.positive? }
51
51
  ```
52
52
 
53
- ### RSpec functionality
54
- An RSpec expectation can be used in the block for the `until` method. The expectation will be attempted each try, but the exception will only be raised if it has still failed once the number or attempts has been reached.
53
+ ### Exception Handling
54
+ Using the `catch` method you can define how the repeater should respond to specific exception types. To do this you need to provide a list of exceptions to catch, a block of code which will be performed, and an option for how to trigger than block of code.
55
+
56
+ **IMPORTANT: Any `catch` blocks must be declared _before_ the `until` block**
57
+
58
+ The following code has custom behaviour for a variety of error types, stopping if it get's an IOError but otherwise continuing without halting the repeater:
55
59
  ```ruby
56
- repeater do
60
+ repeat do
61
+ call_database_method
62
+ end.catch(exceptions: IOError, behaviour: :stop) do |e|
63
+ puts "Error in IO operations: #{e}"
64
+ end.catch(behaviour: :continue) do |e|
65
+ puts "Error thrown: #{e}"
66
+ end.until do |result|
67
+ result.count.positive?
68
+ end
69
+ ```
70
+ `exceptions` can take either a single exception type or an array. If not provided it will default to `StandardError`.
71
+
72
+ There are three supported behaviours:
73
+ - `:continue` executes the provided block but doesn't stop the repeater
74
+ - `:stop` executes the provided block and then stops the repeater
75
+ - `:defer` only executes the provided block if the exception is still occurring on the final attempt. This is the default option.
76
+
77
+ If no block is provided it will default to attempting to raise the exception.
78
+
79
+ ### Default Exception Handling Behaviour
80
+ You can also define default exception handling behaviour which all repeaters in a project will use. A `catch` block on a repeater will override default behaviour for the same exception type. In this following example all repeaters will automatically catch `IOErrors` and raise them if they're still occurring once the repeater has completed its attempts.
81
+
82
+ ```ruby
83
+ BlockRepeater::Repeater.default_catch(exceptions: [IOError], behaviour: :defer) do |e|
84
+ puts 'An IOError occurred'
85
+ e.raise
86
+ end
87
+ ```
88
+ A common use-case for default exception handling is if using a gem such as RSpec, where you may want to handle failed expectations in a uniform manner. To do so you need define the default behaviour first, in a place such as a `env.rb` file or similar:
89
+ ```ruby
90
+ BlockRepeater::Repeater.default_catch(exceptions: [RSpec::Expectations::ExpectationNotMetError], behaviour: :defer) do |e|
91
+ e.raise
92
+ end
93
+ ```
94
+ Then an RSpec expectation can be used in the block for the `until` method. The expectation will be attempted each try, but the exception will only be raised if it has still failed once the number or attempts has been reached.
95
+ ```ruby
96
+ repeat do
57
97
  call_database_method
58
98
  end.until do |result|
59
99
  expect(result.count).to be_positive, raise 'No result returned from databased'
@@ -64,16 +104,16 @@ Very simple conditions can be utilised without using a block. This expects eithe
64
104
  The required format is `until_<method name>` or `until_<method name>_becomes_<method name>`.
65
105
 
66
106
  ```ruby
67
- repeat{ a_method_which_returns_a_number }.until_positive?
107
+ repeat { a_method_which_returns_a_number }.until_positive?
68
108
  #Attempts to call the :positive? method on the result of the method call
69
109
 
70
- repeat{ a_method_which_returns_an_array }.until_count_becomes_positive?
110
+ repeat { a_method_which_returns_an_array }.until_count_becomes_positive?
71
111
  #Attempts to call :count on the result of the method call, then :positive? on that result
72
- ````
73
- This supports two consecutive method calls, anything more complex should be written out in full in the standard manner.
112
+ ```
113
+ This supports up to two consecutive method calls, anything more complex should be written out in full in the standard manner.
74
114
 
75
115
  ### Direct class usage
76
- It's also possible to directly access the Repeater class which has been left available as to not break existing functionality. It's not recommended to combine this with the non predefined condition method pattern described above.
116
+ It's also possible to directly access the Repeater class which has been left available as to provide backwards compatibility with older implementations of BlockRepeater. It's not recommended to combine this with the non predefined condition method pattern described above.
77
117
  ```ruby
78
118
  Repeater = BlockRepeater::Repeater
79
119
 
data/bin/console CHANGED
@@ -2,7 +2,7 @@
2
2
  # frozen_string_literal: true
3
3
 
4
4
  require 'bundler/setup'
5
- require 'repeater'
5
+ require 'block_repeater'
6
6
 
7
7
  # You can add fixtures and/or initialization code here to make experimenting
8
8
  # with your gem easier. You can also use a different console, if you like.
@@ -6,16 +6,16 @@ Gem::Specification.new do |spec|
6
6
  spec.name = 'block_repeater'
7
7
  spec.version = BlockRepeater::VERSION
8
8
  spec.authors = ['William Bray']
9
- spec.email = ['william.bray@dvla.gov.uk']
9
+ spec.email = ['wbray11@hotmail.com']
10
10
 
11
11
  spec.summary = 'Conditionally repeat a block of code'
12
12
  spec.description = 'Attempt a piece of code a set number of times or until a condition is met'
13
13
  spec.homepage = 'https://github.com/dvla/block-repeater'
14
- spec.required_ruby_version = Gem::Requirement.new('>= 2.3.0')
15
- spec.license = 'MIT'
14
+ spec.required_ruby_version = Gem::Requirement.new('>= 3.0.0')
15
+ spec.license = 'MIT'
16
16
 
17
- spec.metadata["homepage_uri"] = spec.homepage
18
- spec.metadata["source_code_uri"] = "https://github.com/dvla/block-repeater"
17
+ spec.metadata['homepage_uri'] = spec.homepage
18
+ spec.metadata['source_code_uri'] = 'https://github.com/dvla/block-repeater'
19
19
 
20
20
  # Specify which files should be added to the gem when it is released.
21
21
  # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
@@ -27,8 +27,9 @@ Gem::Specification.new do |spec|
27
27
  spec.require_paths = ['lib']
28
28
 
29
29
  spec.add_development_dependency 'bump', '~> 0.6'
30
- spec.add_development_dependency 'bundler', '~> 2.1.4'
30
+ spec.add_development_dependency 'bundler', '~> 2.4.0'
31
31
  spec.add_development_dependency 'pry'
32
32
  spec.add_development_dependency 'rake', '~> 10.0'
33
33
  spec.add_development_dependency 'rspec', '~> 3.8'
34
+ spec.add_development_dependency 'rubocop'
34
35
  end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ ##
4
+ # Store an execute behaviour in response to an exception being raised
5
+ class ExceptionResponse
6
+ attr_accessor :types, :response, :behaviour, :actual
7
+
8
+ BEHAVIOURS = %i[continue stop defer].freeze
9
+
10
+ def initialize(types: [], behaviour: :defer, &block)
11
+ raise "Exception handling behaviour '#{behaviour}' not recognised" unless BEHAVIOURS.include? behaviour
12
+ raise 'No exception types provided' if [*types].count.zero?
13
+
14
+ @types = [*types]
15
+ @behaviour = behaviour
16
+ @response = block || default_proc
17
+ end
18
+
19
+ def execute(exception = nil)
20
+ @response.call(exception || @actual)
21
+ end
22
+
23
+ private
24
+
25
+ def default_proc
26
+ proc { |e| raise e }
27
+ end
28
+ end
@@ -3,16 +3,13 @@
3
3
  module BlockRepeater
4
4
  ##
5
5
  # A nicer way to access the Repeater without setting up the class manually
6
- #
7
6
  module Repeatable
8
-
9
7
  ##
10
8
  # Create an instance of the Repeater class
11
9
  #
12
10
  # @param **kwargs - Capture all the keyword arguments, pass them into the Repeater
13
- # Specifically pass through times: and delay: as others will be ignored
11
+ # Specifically pass through :times and :delay as others will be ignored
14
12
  # @param &block - The block of code to be repeated
15
- #
16
13
  def repeat(**kwargs, &block)
17
14
  Repeater.new(manual_repeat: false, **kwargs, &block)
18
15
  end
@@ -1,25 +1,28 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'block_repeater/repeater_methods'
4
+ require 'block_repeater/exception_response'
4
5
 
5
6
  ##
6
- # A class which repeatedly executes a block of code until a given condition is met or a timeout is reached
7
- #
7
+ # A way to repeatedly execute a block of code until a given condition is met or a timeout is reached
8
8
  module BlockRepeater
9
+ ##
10
+ # The class which governs when to stop repeating based on condition or timeout
9
11
  class Repeater
10
12
  include RepeaterMethods
11
-
13
+ @@default_exceptions = []
12
14
 
13
15
  ##
14
16
  # Prepare the Repeater to take the initial block to be repeated
15
17
  #
16
- # @param manual_repeat - Determines whether the repeat method needs to called manually, used by the Repeatable module
18
+ # @param manual_repeat - Determines whether the repeat method is called manually, used by the Repeatable module
17
19
  # @param **kwargs - Capture other arguments in the situation where repeat isn't being called manually
18
20
  # @param &block - The block of code to be repeated
19
21
  def initialize(manual_repeat: true, **kwargs, &block)
20
22
  @manual_repeat = manual_repeat
21
23
  @repeater_arguments = kwargs
22
24
  @repeat_block = block
25
+ @anticipated_exceptions = []
23
26
  end
24
27
 
25
28
  ##
@@ -29,26 +32,67 @@ module BlockRepeater
29
32
  # @param delay - The amount of time to wait between each attempt
30
33
  # @param **_ - Capture any extra keyword arguments and discard them
31
34
  # @return The result of calling the main block the final time
32
- def repeat(times: 25, delay: 0.2)
33
- result, @condition_met, exception = nil
35
+ def repeat(times: 25, delay: 0.2, **_)
36
+ result, @condition_met, deferred_exception = nil
37
+ anticipated_exception_types = @anticipated_exceptions.map(&:types).flatten
38
+ default_exception_types = @@default_exceptions.map(&:types).flatten
39
+ exception_types = anticipated_exception_types + default_exception_types
40
+
34
41
  times.times do
35
- result = @repeat_block.call
36
42
  begin
43
+ result = @repeat_block.call
37
44
  @condition_met = @condition_block.call(result) if @condition_block
38
- exception = nil
39
- rescue RSpec::Expectations::ExpectationNotMetError => e
40
- exception = e
45
+ deferred_exception = nil
46
+ rescue *exception_types => e
47
+ exceptions = if anticipated_exception_types.any? do |ex|
48
+ e.class <= ex
49
+ end
50
+ @anticipated_exceptions
51
+ else
52
+ @@default_exceptions
53
+ end
54
+ matched_response = exceptions.detect { |expected| expected.types.any? { |ex| e.class <= ex } }
55
+ if matched_response.behaviour == :defer
56
+ deferred_exception = matched_response
57
+ deferred_exception.actual = e
58
+ else
59
+ matched_response.execute(e)
60
+ end
61
+
62
+ break if matched_response.behaviour == :stop
41
63
  end
64
+
42
65
  break if @condition_met
43
66
 
44
67
  sleep delay
45
68
  end
46
69
 
47
- raise exception if exception
70
+ deferred_exception&.execute
48
71
 
49
72
  result
50
73
  end
51
74
 
75
+ ##
76
+ # Determine how to respond to exceptions raised while repeating, must be called _before_ #until
77
+ #
78
+ # @param &block - Code to execute when an exception is encountered
79
+ # @param exceptions - Which exceptions are being handled by this block, defaults to StandardError
80
+ # @param behaviour - After encountering the exception how should the repeater behave:
81
+ # :stop - cease repeating, execute the given block
82
+ # :continue - execute the given block but keep repeating
83
+ # :defer - execute the block only if the exception still occurs after all repeat attempts
84
+ def catch(exceptions: [StandardError], behaviour: :defer, &block)
85
+ @anticipated_exceptions << ExceptionResponse.new(types: exceptions, behaviour: behaviour, &block)
86
+ self
87
+ end
88
+
89
+ ##
90
+ # Same as #catch but defines default behaviours shared by all BlockRepeater instances
91
+ # except that there is no default exception type, it must be defined
92
+ def self.default_catch(exceptions: [], behaviour: :defer, &block)
93
+ @@default_exceptions << ExceptionResponse.new(types: exceptions, behaviour: behaviour, &block)
94
+ end
95
+
52
96
  ##
53
97
  # Set the block which determines if the main block should stop being executed
54
98
  #
@@ -60,7 +104,7 @@ module BlockRepeater
60
104
  if @manual_repeat
61
105
  self
62
106
  else
63
- repeat **@repeater_arguments
107
+ repeat(**@repeater_arguments)
64
108
  end
65
109
  end
66
110
  end
@@ -4,7 +4,7 @@
4
4
  # Additional methods for the Repeater class
5
5
  #
6
6
  module RepeaterMethods
7
- UNTIL_METHOD_REGEX = /until_((.*)_becomes_(.*)|(.*))/.freeze
7
+ UNTIL_METHOD_REGEX = /until_((.*)_becomes_(.*)|(.*))/
8
8
 
9
9
  ##
10
10
  # If a method in the correct format is provided it will be converted into the conditional block for the Repeater class
@@ -27,17 +27,21 @@ module RepeaterMethods
27
27
  second_match = Regexp.last_match(2)
28
28
  third_match = Regexp.last_match(3)
29
29
 
30
- if second_match && third_match
31
- final_result = self.until do |result|
32
- call_output = call_if_method_responsive(result, second_match)
33
- call_if_method_responsive(call_output, third_match) if @unresponsive_errors.empty?
34
- end
35
- else
36
- final_result = self.until do |result|
37
- call_if_method_responsive(result, first_match)
38
- end
30
+ final_result = if second_match && third_match
31
+ self.until do |result|
32
+ call_output = call_if_method_responsive(result, second_match)
33
+ call_if_method_responsive(call_output, third_match) if @unresponsive_errors.empty?
34
+ end
35
+ else
36
+ self.until do |result|
37
+ call_if_method_responsive(result, first_match)
38
+ end
39
+ end
40
+ unless @unresponsive_errors.empty?
41
+ raise MethodUnresponsiveError,
42
+ "Methods were not compatible: #{@unresponsive_errors.uniq.join(', ')}"
39
43
  end
40
- raise MethodUnresponsiveError, "Methods were not compatible: #{@unresponsive_errors.uniq.join(', ')}" unless @unresponsive_errors.empty?
44
+
41
45
  final_result
42
46
  else
43
47
  super
@@ -57,6 +61,8 @@ module RepeaterMethods
57
61
  end
58
62
  end
59
63
 
64
+ ##
65
+ # Custom exception for when the repeater response does not respond to a given method
60
66
  class MethodUnresponsiveError < StandardError
61
67
  def initialize(msg = 'Value in repeater did not respond to given method')
62
68
  super
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module BlockRepeater
4
- VERSION = '0.3.0'
4
+ VERSION = '1.0.0'
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: block_repeater
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - William Bray
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-11-01 00:00:00.000000000 Z
11
+ date: 2023-05-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bump
@@ -30,14 +30,14 @@ dependencies:
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: 2.1.4
33
+ version: 2.4.0
34
34
  type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: 2.1.4
40
+ version: 2.4.0
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: pry
43
43
  requirement: !ruby/object:Gem::Requirement
@@ -80,24 +80,32 @@ dependencies:
80
80
  - - "~>"
81
81
  - !ruby/object:Gem::Version
82
82
  version: '3.8'
83
+ - !ruby/object:Gem::Dependency
84
+ name: rubocop
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
83
97
  description: Attempt a piece of code a set number of times or until a condition is
84
98
  met
85
99
  email:
86
- - william.bray@dvla.gov.uk
100
+ - wbray11@hotmail.com
87
101
  executables: []
88
102
  extensions: []
89
103
  extra_rdoc_files: []
90
104
  files:
91
- - ".drone.yml"
105
+ - ".github/workflows/gem-push.yml"
92
106
  - ".gitignore"
93
- - ".idea/.rakeTasks"
94
- - ".idea/inspectionProfiles/Project_Default.xml"
95
- - ".idea/misc.xml"
96
- - ".idea/modules.xml"
97
- - ".idea/repeater.iml"
98
- - ".idea/vcs.xml"
99
- - ".idea/workspace.xml"
100
107
  - ".rspec"
108
+ - ".rubocop.yml"
101
109
  - ".travis.yml"
102
110
  - Gemfile
103
111
  - Gemfile.lock
@@ -107,6 +115,7 @@ files:
107
115
  - bin/setup
108
116
  - block_repeater.gemspec
109
117
  - lib/block_repeater.rb
118
+ - lib/block_repeater/exception_response.rb
110
119
  - lib/block_repeater/repeatable.rb
111
120
  - lib/block_repeater/repeater.rb
112
121
  - lib/block_repeater/repeater_methods.rb
@@ -125,14 +134,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
125
134
  requirements:
126
135
  - - ">="
127
136
  - !ruby/object:Gem::Version
128
- version: 2.3.0
137
+ version: 3.0.0
129
138
  required_rubygems_version: !ruby/object:Gem::Requirement
130
139
  requirements:
131
140
  - - ">="
132
141
  - !ruby/object:Gem::Version
133
142
  version: '0'
134
143
  requirements: []
135
- rubygems_version: 3.1.4
144
+ rubygems_version: 3.4.10
136
145
  signing_key:
137
146
  specification_version: 4
138
147
  summary: Conditionally repeat a block of code
data/.drone.yml DELETED
@@ -1,32 +0,0 @@
1
- ---
2
- kind: pipeline
3
- name: default
4
-
5
- platform:
6
- os: linux
7
- arch: amd64
8
-
9
- steps:
10
- - name: unit tests
11
- pull: if-not-exists
12
- image: ecr.tooling.dvla.gov.uk/base-images/qe-ruby:2.7.0-1
13
- commands:
14
- - bundle --jobs 5 --quiet
15
- - bundle exec rspec
16
- when:
17
- event:
18
- - push
19
-
20
- - name: build and deploy
21
- pull: if-not-exists
22
- image: ecr.tooling.dvla.gov.uk/base-images/qe-ruby:2.7.0-1
23
- commands:
24
- - apk add --update git unzip alpine-sdk jq --no-cache
25
- - gem install bundler
26
- - gem install nexus
27
- - bundle --jobs 5 --quiet
28
- - gem build block_repeater.gemspec
29
- - gem nexus --url https://nexus.tooling.dvla.gov.uk/repository/gem-private/ block_repeater*gem
30
- when:
31
- branch:
32
- - master
data/.idea/.rakeTasks DELETED
@@ -1,7 +0,0 @@
1
- <?xml version="1.0" encoding="UTF-8"?>
2
- <Settings><!--This file was automatically generated by Ruby plugin.
3
- You are allowed to:
4
- 1. Remove rake task
5
- 2. Add existing rake tasks
6
- To add existing rake tasks automatically delete this file and reload the project.
7
- --><RakeGroup description="" fullCmd="" taksId="rake"><RakeTask description="Build block_repeater-0.1.0.gem into the pkg directory" fullCmd="build" taksId="build" /><RakeTask description="Remove any temporary products" fullCmd="clean" taksId="clean" /><RakeTask description="Remove any generated files" fullCmd="clobber" taksId="clobber" /><RakeTask description="Build and install block_repeater-0.1.0.gem into system gems" fullCmd="install" taksId="install" /><RakeGroup description="" fullCmd="" taksId="install"><RakeTask description="Build and install block_repeater-0.1.0.gem into system gems without network access" fullCmd="install:local" taksId="local" /></RakeGroup><RakeTask description="Create tag v0.1.0 and build and push block_repeater-0.1.0.gem to https://nexus-internal.iep.dvla.gov.uk/nexus/content/groups/gems" fullCmd="release[remote]" taksId="release[remote]" /><RakeTask description="Run RSpec code examples" fullCmd="spec" taksId="spec" /><RakeTask description="" fullCmd="default" taksId="default" /><RakeTask description="" fullCmd="release" taksId="release" /><RakeGroup description="" fullCmd="" taksId="release"><RakeTask description="" fullCmd="release:guard_clean" taksId="guard_clean" /><RakeTask description="" fullCmd="release:rubygem_push" taksId="rubygem_push" /><RakeTask description="" fullCmd="release:source_control_push" taksId="source_control_push" /></RakeGroup></RakeGroup></Settings>
@@ -1,6 +0,0 @@
1
- <component name="InspectionProjectProfileManager">
2
- <profile version="1.0">
3
- <option name="myName" value="Project Default" />
4
- <inspection_tool class="Rubocop" enabled="false" level="WARNING" enabled_by_default="false" />
5
- </profile>
6
- </component>
data/.idea/misc.xml DELETED
@@ -1,7 +0,0 @@
1
- <?xml version="1.0" encoding="UTF-8"?>
2
- <project version="4">
3
- <component name="JavaScriptSettings">
4
- <option name="languageLevel" value="ES6" />
5
- </component>
6
- <component name="ProjectRootManager" version="2" project-jdk-name="ruby-2.3.7-p456" project-jdk-type="RUBY_SDK" />
7
- </project>
data/.idea/modules.xml DELETED
@@ -1,8 +0,0 @@
1
- <?xml version="1.0" encoding="UTF-8"?>
2
- <project version="4">
3
- <component name="ProjectModuleManager">
4
- <modules>
5
- <module fileurl="file://$PROJECT_DIR$/.idea/repeater.iml" filepath="$PROJECT_DIR$/.idea/repeater.iml" />
6
- </modules>
7
- </component>
8
- </project>
data/.idea/repeater.iml DELETED
@@ -1,23 +0,0 @@
1
- <?xml version="1.0" encoding="UTF-8"?>
2
- <module type="RUBY_MODULE" version="4">
3
- <component name="ModuleRunConfigurationManager">
4
- <shared />
5
- </component>
6
- <component name="NewModuleRootManager">
7
- <content url="file://$MODULE_DIR$" />
8
- <orderEntry type="jdk" jdkName="RVM: ruby-2.7.2" jdkType="RUBY_SDK" />
9
- <orderEntry type="sourceFolder" forTests="false" />
10
- <orderEntry type="library" scope="PROVIDED" name="bump (v0.10.0, RVM: ruby-2.7.2) [gem]" level="application" />
11
- <orderEntry type="library" scope="PROVIDED" name="bundler (v2.1.4, RVM: ruby-2.7.2) [gem]" level="application" />
12
- <orderEntry type="library" scope="PROVIDED" name="coderay (v1.1.3, RVM: ruby-2.7.2) [gem]" level="application" />
13
- <orderEntry type="library" scope="PROVIDED" name="diff-lcs (v1.4.4, RVM: ruby-2.7.2) [gem]" level="application" />
14
- <orderEntry type="library" scope="PROVIDED" name="method_source (v1.0.0, RVM: ruby-2.7.2) [gem]" level="application" />
15
- <orderEntry type="library" scope="PROVIDED" name="pry (v0.14.1, RVM: ruby-2.7.2) [gem]" level="application" />
16
- <orderEntry type="library" scope="PROVIDED" name="rake (v12.3.3, RVM: ruby-2.7.2) [gem]" level="application" />
17
- <orderEntry type="library" scope="PROVIDED" name="rspec (v3.10.0, RVM: ruby-2.7.2) [gem]" level="application" />
18
- <orderEntry type="library" scope="PROVIDED" name="rspec-core (v3.10.1, RVM: ruby-2.7.2) [gem]" level="application" />
19
- <orderEntry type="library" scope="PROVIDED" name="rspec-expectations (v3.10.1, RVM: ruby-2.7.2) [gem]" level="application" />
20
- <orderEntry type="library" scope="PROVIDED" name="rspec-mocks (v3.10.2, RVM: ruby-2.7.2) [gem]" level="application" />
21
- <orderEntry type="library" scope="PROVIDED" name="rspec-support (v3.10.2, RVM: ruby-2.7.2) [gem]" level="application" />
22
- </component>
23
- </module>
data/.idea/vcs.xml DELETED
@@ -1,6 +0,0 @@
1
- <?xml version="1.0" encoding="UTF-8"?>
2
- <project version="4">
3
- <component name="VcsDirectoryMappings">
4
- <mapping directory="$PROJECT_DIR$" vcs="Git" />
5
- </component>
6
- </project>
data/.idea/workspace.xml DELETED
@@ -1,368 +0,0 @@
1
- <?xml version="1.0" encoding="UTF-8"?>
2
- <project version="4">
3
- <component name="ChangeListManager">
4
- <list default="true" id="b98fee1d-e3fb-4a5d-b159-c1c7714c792f" name="Default Changelist" comment="">
5
- <change beforePath="$PROJECT_DIR$/.idea/.rakeTasks" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/.rakeTasks" afterDir="false" />
6
- <change beforePath="$PROJECT_DIR$/.idea/repeater.iml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/repeater.iml" afterDir="false" />
7
- <change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
8
- <change beforePath="$PROJECT_DIR$/lib/block_repeater/repeatable.rb" beforeDir="false" afterPath="$PROJECT_DIR$/lib/block_repeater/repeatable.rb" afterDir="false" />
9
- </list>
10
- <option name="EXCLUDED_CONVERTED_TO_IGNORED" value="true" />
11
- <option name="SHOW_DIALOG" value="false" />
12
- <option name="HIGHLIGHT_CONFLICTS" value="true" />
13
- <option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
14
- <option name="LAST_RESOLUTION" value="IGNORE" />
15
- </component>
16
- <component name="FileEditorManager">
17
- <leaf SIDE_TABS_SIZE_LIMIT_KEY="300">
18
- <file pinned="false" current-in-tab="true">
19
- <entry file="file://$PROJECT_DIR$/block_repeater.gemspec">
20
- <provider selected="true" editor-type-id="text-editor">
21
- <state relative-caret-position="555">
22
- <caret line="37" column="51" selection-start-line="37" selection-start-column="51" selection-end-line="37" selection-end-column="51" />
23
- </state>
24
- </provider>
25
- </entry>
26
- </file>
27
- <file pinned="false" current-in-tab="false">
28
- <entry file="file://$PROJECT_DIR$/lib/block_repeater.rb">
29
- <provider selected="true" editor-type-id="text-editor">
30
- <state>
31
- <caret column="29" selection-start-column="29" selection-end-column="29" />
32
- </state>
33
- </provider>
34
- </entry>
35
- </file>
36
- <file pinned="false" current-in-tab="false">
37
- <entry file="file://$PROJECT_DIR$/lib/block_repeater/repeater.rb">
38
- <provider selected="true" editor-type-id="text-editor">
39
- <state relative-caret-position="668">
40
- <caret line="49" selection-start-line="49" selection-end-line="49" />
41
- </state>
42
- </provider>
43
- </entry>
44
- </file>
45
- <file pinned="false" current-in-tab="false">
46
- <entry file="file://$PROJECT_DIR$/lib/block_repeater/repeatable.rb">
47
- <provider selected="true" editor-type-id="text-editor">
48
- <state relative-caret-position="405">
49
- <caret line="27" selection-start-line="27" selection-end-line="27" />
50
- </state>
51
- </provider>
52
- </entry>
53
- </file>
54
- <file pinned="false" current-in-tab="false">
55
- <entry file="file://$PROJECT_DIR$/.drone.yml">
56
- <provider selected="true" editor-type-id="text-editor">
57
- <state relative-caret-position="345">
58
- <caret line="23" column="59" selection-start-line="23" selection-start-column="59" selection-end-line="23" selection-end-column="59" />
59
- </state>
60
- </provider>
61
- </entry>
62
- </file>
63
- <file pinned="false" current-in-tab="false">
64
- <entry file="file://$PROJECT_DIR$/lib/block_repeater/repeater_methods.rb">
65
- <provider selected="true" editor-type-id="text-editor">
66
- <state relative-caret-position="-5">
67
- <caret line="8" column="4" selection-start-line="8" selection-start-column="4" selection-end-line="8" selection-end-column="4" />
68
- </state>
69
- </provider>
70
- </entry>
71
- </file>
72
- <file pinned="false" current-in-tab="false">
73
- <entry file="file://$PROJECT_DIR$/spec/spec_helper.rb">
74
- <provider selected="true" editor-type-id="text-editor" />
75
- </entry>
76
- </file>
77
- <file pinned="false" current-in-tab="false">
78
- <entry file="file://$PROJECT_DIR$/spec/block_repeater/repeatable_spec.rb">
79
- <provider selected="true" editor-type-id="text-editor">
80
- <state relative-caret-position="615">
81
- <caret line="41" column="7" selection-start-line="41" selection-start-column="7" selection-end-line="41" selection-end-column="7" />
82
- </state>
83
- </provider>
84
- </entry>
85
- </file>
86
- <file pinned="false" current-in-tab="false">
87
- <entry file="file://$PROJECT_DIR$/spec/block_repeater/repeater_spec.rb">
88
- <provider selected="true" editor-type-id="text-editor">
89
- <state>
90
- <caret column="41" selection-start-column="41" selection-end-column="41" />
91
- </state>
92
- </provider>
93
- </entry>
94
- </file>
95
- <file pinned="false" current-in-tab="false">
96
- <entry file="file://$PROJECT_DIR$/README.md">
97
- <provider selected="true" editor-type-id="split-provider[text-editor;markdown-preview-editor]">
98
- <state split_layout="SPLIT">
99
- <first_editor relative-caret-position="863">
100
- <caret line="79" selection-start-line="79" selection-end-line="79" />
101
- </first_editor>
102
- <second_editor />
103
- </state>
104
- </provider>
105
- </entry>
106
- </file>
107
- </leaf>
108
- </component>
109
- <component name="Git.Settings">
110
- <option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$" />
111
- </component>
112
- <component name="IdeDocumentHistory">
113
- <option name="CHANGED_PATHS">
114
- <list>
115
- <option value="$APPLICATION_CONFIG_DIR$/scratches/scratch_1.rb" />
116
- <option value="$PROJECT_DIR$/lib/repeater/repeater_methods.rb" />
117
- <option value="$PROJECT_DIR$/lib/repeater.rb" />
118
- <option value="$PROJECT_DIR$/lib/repeater/repeater.rb" />
119
- <option value="$PROJECT_DIR$/lib/repeater/repeatable.rb" />
120
- <option value="$PROJECT_DIR$/lib/block_repeater/repeater.rb" />
121
- <option value="$PROJECT_DIR$/spec/block_repeater_spec.rb" />
122
- <option value="$PROJECT_DIR$/repeater.gemspec" />
123
- <option value="$PROJECT_DIR$/lib/block_repeater/version.rb" />
124
- <option value="$PROJECT_DIR$/Gemfile.lock" />
125
- <option value="$PROJECT_DIR$/Gemfile" />
126
- <option value="$PROJECT_DIR$/README.md" />
127
- <option value="$PROJECT_DIR$/lib/block_repeater/repeater.rb" />
128
- <option value="$PROJECT_DIR$/spec/block_repeater/repeater_methods_spec.rb" />
129
- <option value="$PROJECT_DIR$/lib/block_repeater.rb" />
130
- <option value="$PROJECT_DIR$/lib/block_repeater.rb" />
131
- <option value="$PROJECT_DIR$/lib/block_repeater/repeater_methods.rb" />
132
- <option value="$PROJECT_DIR$/spec/block_repeater/repeatable_spec.rb" />
133
- <option value="$PROJECT_DIR$/lib/block_repeater/repeatable.rb" />
134
- <option value="$PROJECT_DIR$/.drone.yml" />
135
- <option value="$PROJECT_DIR$/block_repeater.gemspec" />
136
- </list>
137
- </option>
138
- </component>
139
- <component name="ProjectFrameBounds" fullScreen="true">
140
- <option name="x" value="-1920" />
141
- <option name="width" value="1920" />
142
- <option name="height" value="1080" />
143
- </component>
144
- <component name="ProjectLevelVcsManager" settingsEditedManually="true" />
145
- <component name="ProjectView">
146
- <navigator proportions="" version="1">
147
- <foldersAlwaysOnTop value="true" />
148
- </navigator>
149
- <panes>
150
- <pane id="ProjectPane">
151
- <subPane>
152
- <expand>
153
- <path>
154
- <item name="block_repeater" type="b2602c69:ProjectViewProjectNode" />
155
- <item name="block_repeater" type="462c0819:PsiDirectoryNode" />
156
- </path>
157
- <path>
158
- <item name="block_repeater" type="b2602c69:ProjectViewProjectNode" />
159
- <item name="block_repeater" type="462c0819:PsiDirectoryNode" />
160
- <item name="spec" type="462c0819:PsiDirectoryNode" />
161
- </path>
162
- <path>
163
- <item name="block_repeater" type="b2602c69:ProjectViewProjectNode" />
164
- <item name="block_repeater" type="462c0819:PsiDirectoryNode" />
165
- <item name="spec" type="462c0819:PsiDirectoryNode" />
166
- <item name="block_repeater" type="462c0819:PsiDirectoryNode" />
167
- </path>
168
- </expand>
169
- <select />
170
- </subPane>
171
- </pane>
172
- <pane id="Scope" />
173
- </panes>
174
- </component>
175
- <component name="PropertiesComponent">
176
- <property name="SHARE_PROJECT_CONFIGURATION_FILES" value="true" />
177
- <property name="WebServerToolWindowFactoryState" value="false" />
178
- <property name="com.intellij.ide.scratch.LRUPopupBuilder$1/New Scratch File" value="ruby" />
179
- <property name="last_opened_file_path" value="$PROJECT_DIR$" />
180
- <property name="nodejs_interpreter_path.stuck_in_default_project" value="undefined stuck path" />
181
- <property name="nodejs_npm_path_reset_for_default_project" value="true" />
182
- </component>
183
- <component name="RunDashboard">
184
- <option name="ruleStates">
185
- <list>
186
- <RuleState>
187
- <option name="name" value="ConfigurationTypeDashboardGroupingRule" />
188
- </RuleState>
189
- <RuleState>
190
- <option name="name" value="StatusDashboardGroupingRule" />
191
- </RuleState>
192
- </list>
193
- </option>
194
- </component>
195
- <component name="SpringUtil" SPRING_PRE_LOADER_OPTION="true" />
196
- <component name="TaskManager">
197
- <task active="true" id="Default" summary="Default task">
198
- <changelist id="b98fee1d-e3fb-4a5d-b159-c1c7714c792f" name="Default Changelist" comment="" />
199
- <created>1626098360263</created>
200
- <option name="number" value="Default" />
201
- <option name="presentableId" value="Default" />
202
- <updated>1626098360263</updated>
203
- <workItem from="1626098361348" duration="13047000" />
204
- <workItem from="1626264453454" duration="3322000" />
205
- <workItem from="1626418917271" duration="950000" />
206
- <workItem from="1626764476711" duration="18455000" />
207
- <workItem from="1628769996055" duration="4210000" />
208
- <workItem from="1629964050435" duration="1745000" />
209
- <workItem from="1630485234370" duration="10691000" />
210
- </task>
211
- <servers />
212
- </component>
213
- <component name="TimeTrackingManager">
214
- <option name="totallyTimeSpent" value="52420000" />
215
- </component>
216
- <component name="ToolWindowManager">
217
- <frame x="-1920" y="0" width="1920" height="1080" extended-state="0" />
218
- <editor active="true" />
219
- <layout>
220
- <window_info active="true" content_ui="combo" id="Project" order="0" visible="true" weight="0.14057508" />
221
- <window_info id="Structure" order="1" side_tool="true" weight="0.25" />
222
- <window_info id="Favorites" order="2" side_tool="true" />
223
- <window_info anchor="bottom" id="Message" order="0" />
224
- <window_info anchor="bottom" id="Find" order="1" />
225
- <window_info anchor="bottom" id="Run" order="2" />
226
- <window_info anchor="bottom" id="Debug" order="3" weight="0.4" />
227
- <window_info anchor="bottom" id="Cvs" order="4" weight="0.25" />
228
- <window_info anchor="bottom" id="Inspection" order="5" weight="0.4" />
229
- <window_info anchor="bottom" id="TODO" order="6" />
230
- <window_info anchor="bottom" id="Docker" order="7" show_stripe_button="false" />
231
- <window_info anchor="bottom" id="Database Changes" order="8" />
232
- <window_info anchor="bottom" id="Version Control" order="9" />
233
- <window_info anchor="bottom" id="Terminal" order="10" />
234
- <window_info anchor="bottom" id="Event Log" order="11" side_tool="true" />
235
- <window_info active="true" anchor="bottom" id="Messages" order="12" visible="true" weight="0.3291536" />
236
- <window_info anchor="right" id="Commander" internal_type="SLIDING" order="0" type="SLIDING" weight="0.4" />
237
- <window_info anchor="right" id="Ant Build" order="1" weight="0.25" />
238
- <window_info anchor="right" content_ui="combo" id="Hierarchy" order="2" weight="0.25" />
239
- <window_info anchor="right" id="Database" order="3" />
240
- </layout>
241
- </component>
242
- <component name="TypeScriptGeneratedFilesManager">
243
- <option name="version" value="1" />
244
- </component>
245
- <component name="editorHistoryManager">
246
- <entry file="file://$PROJECT_DIR$/bin/console">
247
- <provider selected="true" editor-type-id="text-editor">
248
- <state relative-caret-position="180">
249
- <caret line="12" column="13" lean-forward="true" selection-start-line="12" selection-start-column="13" selection-end-line="12" selection-end-column="13" />
250
- </state>
251
- </provider>
252
- </entry>
253
- <entry file="file://$PROJECT_DIR$/Rakefile">
254
- <provider selected="true" editor-type-id="text-editor" />
255
- </entry>
256
- <entry file="file://$PROJECT_DIR$/Gemfile">
257
- <provider selected="true" editor-type-id="text-editor">
258
- <state relative-caret-position="105">
259
- <caret line="7" selection-start-line="7" selection-end-line="7" />
260
- </state>
261
- </provider>
262
- </entry>
263
- <entry file="file://$PROJECT_DIR$/lib/block_repeater/version.rb">
264
- <provider selected="true" editor-type-id="text-editor">
265
- <state relative-caret-position="45">
266
- <caret line="3" lean-forward="true" selection-start-line="3" selection-end-line="3" />
267
- </state>
268
- </provider>
269
- </entry>
270
- <entry file="file://$PROJECT_DIR$/Gemfile.lock">
271
- <provider selected="true" editor-type-id="text-editor">
272
- <state relative-caret-position="585">
273
- <caret line="39" column="8" selection-start-line="39" selection-start-column="8" selection-end-line="39" selection-end-column="8" />
274
- </state>
275
- </provider>
276
- </entry>
277
- <entry file="file://$APPLICATION_CONFIG_DIR$/scratches/scratch_1.rb">
278
- <provider selected="true" editor-type-id="text-editor">
279
- <state relative-caret-position="375">
280
- <caret line="25" column="36" selection-start-line="25" selection-start-column="36" selection-end-line="25" selection-end-column="36" />
281
- </state>
282
- </provider>
283
- </entry>
284
- <entry file="file://$PROJECT_DIR$/README.md">
285
- <provider selected="true" editor-type-id="split-provider[text-editor;markdown-preview-editor]">
286
- <state split_layout="SPLIT">
287
- <first_editor relative-caret-position="863">
288
- <caret line="79" selection-start-line="79" selection-end-line="79" />
289
- </first_editor>
290
- <second_editor />
291
- </state>
292
- </provider>
293
- </entry>
294
- <entry file="file://$PROJECT_DIR$/spec/block_repeater/repeater_spec.rb">
295
- <provider selected="true" editor-type-id="text-editor">
296
- <state>
297
- <caret column="41" selection-start-column="41" selection-end-column="41" />
298
- </state>
299
- </provider>
300
- </entry>
301
- <entry file="file://$PROJECT_DIR$/spec/block_repeater/repeater_methods_spec.rb">
302
- <provider selected="true" editor-type-id="text-editor">
303
- <state>
304
- <caret column="33" lean-forward="true" selection-start-column="33" selection-end-column="33" />
305
- </state>
306
- </provider>
307
- </entry>
308
- <entry file="file://$PROJECT_DIR$/spec/block_repeater/repeatable_spec.rb">
309
- <provider selected="true" editor-type-id="text-editor">
310
- <state relative-caret-position="615">
311
- <caret line="41" column="7" selection-start-line="41" selection-start-column="7" selection-end-line="41" selection-end-column="7" />
312
- </state>
313
- </provider>
314
- </entry>
315
- <entry file="file://$PROJECT_DIR$/spec/block_repeater_spec.rb">
316
- <provider selected="true" editor-type-id="text-editor">
317
- <state relative-caret-position="105">
318
- <caret line="7" lean-forward="true" selection-start-line="7" selection-end-line="7" />
319
- </state>
320
- </provider>
321
- </entry>
322
- <entry file="file://$PROJECT_DIR$/spec/spec_helper.rb">
323
- <provider selected="true" editor-type-id="text-editor" />
324
- </entry>
325
- <entry file="file://$PROJECT_DIR$/lib/block_repeater/repeater_methods.rb">
326
- <provider selected="true" editor-type-id="text-editor">
327
- <state relative-caret-position="-5">
328
- <caret line="8" column="4" selection-start-line="8" selection-start-column="4" selection-end-line="8" selection-end-column="4" />
329
- </state>
330
- </provider>
331
- </entry>
332
- <entry file="file://$PROJECT_DIR$/lib/block_repeater/repeater.rb">
333
- <provider selected="true" editor-type-id="text-editor">
334
- <state relative-caret-position="668">
335
- <caret line="49" selection-start-line="49" selection-end-line="49" />
336
- </state>
337
- </provider>
338
- </entry>
339
- <entry file="file://$PROJECT_DIR$/lib/block_repeater.rb">
340
- <provider selected="true" editor-type-id="text-editor">
341
- <state>
342
- <caret column="29" selection-start-column="29" selection-end-column="29" />
343
- </state>
344
- </provider>
345
- </entry>
346
- <entry file="file://$PROJECT_DIR$/lib/block_repeater/repeatable.rb">
347
- <provider selected="true" editor-type-id="text-editor">
348
- <state relative-caret-position="405">
349
- <caret line="27" selection-start-line="27" selection-end-line="27" />
350
- </state>
351
- </provider>
352
- </entry>
353
- <entry file="file://$PROJECT_DIR$/.drone.yml">
354
- <provider selected="true" editor-type-id="text-editor">
355
- <state relative-caret-position="345">
356
- <caret line="23" column="59" selection-start-line="23" selection-start-column="59" selection-end-line="23" selection-end-column="59" />
357
- </state>
358
- </provider>
359
- </entry>
360
- <entry file="file://$PROJECT_DIR$/block_repeater.gemspec">
361
- <provider selected="true" editor-type-id="text-editor">
362
- <state relative-caret-position="555">
363
- <caret line="37" column="51" selection-start-line="37" selection-start-column="51" selection-end-line="37" selection-end-column="51" />
364
- </state>
365
- </provider>
366
- </entry>
367
- </component>
368
- </project>