isolator 0.6.2 → 0.7.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: 36b44d69162aa2c6450298b45b30c824e129448be00ff92ffb0835da654cdf15
4
- data.tar.gz: f5179d3d98ef52b3dd2c52c022da6e61cd1ea9472619d8350545756014ad9c3f
3
+ metadata.gz: 00d85d8a62a5a34bd39ef9295e1e8ad9c13599fc17648bbda7a5012f9a89ddfa
4
+ data.tar.gz: cf7a441154f63bc40258b4a78e57e3d3f46158b915167c1631d717530571dcd2
5
5
  SHA512:
6
- metadata.gz: b0194b763fac7ed01c229bac83985770c0ac9ba6da6448706a4bfa70d6f578b044b1d280cdb78e1fa7eebab6961979ddd937d914486f96cac067368f586b5f04
7
- data.tar.gz: c9015bf6498684d09188a535fae608e02939a0cec7eb63f5ada0e705881d56f72f0971c55674e4e6a7448d6da3a933d54e8ed4a1c50fa5a9a906b0f09e36a381
6
+ metadata.gz: a088b0f2e24c8afd8a2ec3fd65df4ef5e2d550f55c8376132955db8f870f68a28f021b8079024b413ef2692a474136f3d7da56c098a89d2e3b3aa52deb0ce334
7
+ data.tar.gz: d3667e26d54697e09eaefd7cdee7e9c5586e307c371ce41215d8eca88dc514c652079088bba2af3aeb654b9bfbdad3a3ab6080c5f20b47867291cf4734f16cda
@@ -2,6 +2,21 @@
2
2
 
3
3
  ## master
4
4
 
5
+ ## 0.7.0 (2020-09-25)
6
+
7
+ - Add debug mode. ([@palkan][])
8
+
9
+ Use `ISOLATOR_DEBUG=true` to turn on debug mode, which prints some useful information: when a transaction is tracked,
10
+ thresholds are changed, etc.
11
+
12
+ - Track transactions for different connections independently. ([@mquan][], [@palkan][])
13
+
14
+ This, for example, makes Isolator compatible with Rails multi-database apps.
15
+
16
+ - Allow custom ignorer usage. ([@iiwo][])
17
+
18
+ - `Isolator.load_ignore_config` is deprecated in favor of `Isolator::Ignorer.prepare`. ([@iiwo][])
19
+
5
20
  ## 0.6.2 (2020-03-20)
6
21
 
7
22
  - Make Sniffer version requirement open-ended. ([@palkan][])
@@ -76,3 +91,5 @@
76
91
  [@Envek]: https://github.com/Envek
77
92
  [@DmitryTsepelev]: https://github.com/DmitryTsepelev
78
93
  [@shivanshgaur]: https://github.com/shivanshgaur
94
+ [@iiwo]: https://github.com/iiwo
95
+ [@mquan]: https://github.com/mquan
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  [![Cult Of Martians](http://cultofmartians.com/assets/badges/badge.svg)](http://cultofmartians.com/tasks/isolator.html)
2
2
  [![Gem Version](https://badge.fury.io/rb/isolator.svg)](https://badge.fury.io/rb/isolator)
3
- [![Build Status](https://travis-ci.org/palkan/isolator.svg?branch=master)](https://travis-ci.org/palkan/isolator)
3
+ ![Build](https://github.com/palkan/isolator/workflows/Build/badge.svg)
4
4
 
5
5
  # Isolator
6
6
 
@@ -79,6 +79,8 @@ However, there are some potential caveats:
79
79
 
80
80
  3) Isolator tries to detect the `test` environment and slightly change its behavior: first, it respect _transactional tests_; secondly, error raising is turned on by default (see [below](#configuration)).
81
81
 
82
+ 4) Experimental [multiple databases](https://guides.rubyonrails.org/active_record_multiple_databases.html) has been added in v0.7.0. Please, let us know if you encounter any issues.
83
+
82
84
  ### Configuration
83
85
 
84
86
  ```ruby
@@ -95,6 +97,10 @@ Isolator.configure do |config|
95
97
  # Customize backtrace filtering (provide a callable)
96
98
  # By default, just takes the top-5 lines
97
99
  config.backtrace_filter = ->(backtrace) { backtrace.take(5) }
100
+
101
+ # Define a custom ignorer class (must implement .prepare)
102
+ # uses a row number based list from the .isolator_todo.yml file
103
+ config.ignorer = Isolator::Ignorer
98
104
  end
99
105
  ```
100
106
 
@@ -167,7 +173,7 @@ All the exceptions raised in the listed lines will be ignored.
167
173
 
168
174
  ### Using with legacy Ruby codebases
169
175
 
170
- If you are not using Rails, you'll have to load ignores from file manually, using `Isolator#load_ignore_config`, for instance `Isolator.load_ignore_config("./config/.isolator_todo.yml")`
176
+ If you are not using Rails, you'll have to load ignores from file manually, using `Isolator::Ignorer.prepare(path:)`, for instance `Isolator::Ignorer.prepare(path: "./config/.isolator_todo.yml")`
171
177
 
172
178
  ## Custom Adapters
173
179
 
@@ -183,7 +189,7 @@ Suppose that you have a class `Danger` with a method `#explode`, which is not sa
183
189
  # the third one is a method name.
184
190
  Isolator.isolate :danger, Danger, :explode, options
185
191
 
186
- # NOTE: if you want to isolate a class method, use signleton_class instead
192
+ # NOTE: if you want to isolate a class method, use singleton_class instead
187
193
  Isolator.isolate :danger, Danger.singleton_class, :explode, options
188
194
  ```
189
195
 
@@ -210,10 +216,22 @@ Isolator.before_isolate do
210
216
  end
211
217
 
212
218
  Isolator.after_isolate do
213
- # right after the transaction has been committed/rollbacked
219
+ # right after the transaction has been committed/rolled back
214
220
  end
215
221
  ```
216
222
 
223
+ ## Troubleshooting
224
+
225
+ ### Verbose output
226
+
227
+ In most cases, turning on verbose output for Isolator helps to identify the issue. To do that, you can either specify `ISOLATOR_DEBUG=true` environment variable or set `Isolator.debug_enabled` manually.
228
+
229
+ ### Tests failing after upgrading to Rails 6.0.3 while using [Combustion](https://github.com/pat/combustion)
230
+
231
+ The reason is that Rails started using a [separate connection pool for advisory locks](https://github.com/rails/rails/pull/38235) since 6.0.3. Since Combustion usually applies migrations for every test run, this pool becomse visible to [test fixtures](https://github.com/rails/rails/blob/b738f1930f3c82f51741ef7241c1fee691d7deb2/activerecord/lib/active_record/test_fixtures.rb#L123-L127), which resulted in 2 transactional commits tracked by Isolator, which only expects one. That leads to false negatives.
232
+
233
+ To fix this disable migrations advisory locks by adding `advisory_locks: false` to your database configuration in `(spec|test)/internal/config/database.yml`.
234
+
217
235
  ## Contributing
218
236
 
219
237
  Bug reports and pull requests are welcome on GitHub at https://github.com/palkan/isolator.
@@ -17,7 +17,25 @@ require "isolator/ext/thread_fetch"
17
17
  module Isolator
18
18
  using Isolator::ThreadFetch
19
19
 
20
+ class ThreadStateProxy
21
+ attr_reader :prefix
22
+
23
+ def initilize(prefix = "isolator_")
24
+ @prefix = prefix
25
+ end
26
+
27
+ def [](key)
28
+ Thread.current[:"#{prefix}#{key}"]
29
+ end
30
+
31
+ def []=(key, value)
32
+ Thread.current[:"#{prefix}#{key}"] = value
33
+ end
34
+ end
35
+
20
36
  class << self
37
+ attr_accessor :default_threshold, :default_connection_id
38
+
21
39
  def config
22
40
  @config ||= Configuration.new
23
41
  end
@@ -31,11 +49,11 @@ module Isolator
31
49
  end
32
50
 
33
51
  def enable!
34
- Thread.current[:isolator_disabled] = false
52
+ state[:disabled] = false
35
53
  end
36
54
 
37
55
  def disable!
38
- Thread.current[:isolator_disabled] = true
56
+ state[:disabled] = true
39
57
  end
40
58
 
41
59
  # Accepts block and disable Isolator within
@@ -64,32 +82,77 @@ module Isolator
64
82
  res
65
83
  end
66
84
 
67
- def transactions_threshold
68
- Thread.current.fetch(:isolator_threshold, 1)
85
+ def transactions_threshold=(val)
86
+ set_connection_threshold(val)
87
+ end
88
+
89
+ def transactions_threshold(connection_id = default_connection_id.call)
90
+ connection_threshold(connection_id)
69
91
  end
70
92
 
71
- def transactions_threshold=(val)
72
- Thread.current[:isolator_threshold] = val
93
+ def current_transactions(connection_id = default_connection_id.call)
94
+ state[:transactions]&.[](connection_id) || 0
73
95
  end
74
96
 
75
- def incr_transactions!
76
- Thread.current[:isolator_transactions] =
77
- Thread.current.fetch(:isolator_transactions, 0) + 1
78
- start! if Thread.current.fetch(:isolator_transactions) == transactions_threshold
97
+ def set_connection_threshold(val, connection_id = default_connection_id.call)
98
+ state[:thresholds] ||= Hash.new { |h, k| h[k] = Isolator.default_threshold }
99
+ state[:thresholds][connection_id] = val
100
+
101
+ debug!("Threshold value was changed for connection #{connection_id}: #{val}")
79
102
  end
80
103
 
81
- def decr_transactions!
82
- Thread.current[:isolator_transactions] =
83
- Thread.current.fetch(:isolator_transactions) - 1
84
- finish! if Thread.current.fetch(:isolator_transactions) == (transactions_threshold - 1)
104
+ def incr_thresholds!
105
+ self.default_threshold += 1
106
+ return unless state[:thresholds]
107
+
108
+ state[:thresholds].transform_values!(&:succ)
109
+
110
+ debug!("Thresholds were incremented")
111
+ end
112
+
113
+ def decr_thresholds!
114
+ self.default_threshold -= 1
115
+ return unless state[:thresholds]
116
+
117
+ state[:thresholds].transform_values!(&:pred)
118
+
119
+ debug!("Thresholds were decremented")
120
+ end
121
+
122
+ def incr_transactions!(connection_id = default_connection_id.call)
123
+ state[:transactions] ||= Hash.new { |h, k| h[k] = 0 }
124
+ state[:transactions][connection_id] += 1
125
+
126
+ # Workaround to track threshold changes made before opening a connection
127
+ pending_threshold = state[:thresholds]&.delete(0)
128
+ if pending_threshold
129
+ state[:thresholds][connection_id] = pending_threshold
130
+ end
131
+
132
+ debug!("Transaction opened for connection #{connection_id} (total: #{state[:transactions][connection_id]}, threshold: #{state[:thresholds]&.fetch(connection_id, default_threshold)})")
133
+
134
+ start! if current_transactions(connection_id) == connection_threshold(connection_id)
135
+ end
136
+
137
+ def decr_transactions!(connection_id = default_connection_id.call)
138
+ state[:transactions][connection_id] -= 1
139
+
140
+ finish! if current_transactions(connection_id) == (connection_threshold(connection_id) - 1)
141
+
142
+ state[:transactions].delete(connection_id) if state[:transactions][connection_id].zero?
143
+
144
+ debug!("Transaction closed for connection #{connection_id} (total: #{state[:transactions][connection_id]}, threshold: #{state[:thresholds]&.[](connection_id) || default_threshold})")
85
145
  end
86
146
 
87
147
  def clear_transactions!
88
- Thread.current[:isolator_transactions] = 0
148
+ state[:transactions]&.clear
89
149
  end
90
150
 
91
151
  def within_transaction?
92
- Thread.current.fetch(:isolator_transactions, 0) >= transactions_threshold
152
+ state[:transactions]&.each do |connection_id, transaction_count|
153
+ return true if transaction_count >= connection_threshold(connection_id)
154
+ end
155
+ false
93
156
  end
94
157
 
95
158
  def enabled?
@@ -97,17 +160,61 @@ module Isolator
97
160
  end
98
161
 
99
162
  def disabled?
100
- Thread.current[:isolator_disabled] == true
163
+ state[:disabled] == true
101
164
  end
102
165
 
103
166
  def adapters
104
167
  @adapters ||= Isolator::SimpleHashie.new
105
168
  end
106
169
 
170
+ def load_ignore_config(path)
171
+ warn "[DEPRECATION] `load_ignore_config` is deprecated. Please use `Isolator::Ignorer.prepare` instead."
172
+ Isolator::Ignorer.prepare(path: path)
173
+ end
174
+
107
175
  include Isolator::Isolate
108
176
  include Isolator::Callbacks
109
- include Isolator::Ignorer
177
+
178
+ attr_accessor :debug_enabled, :backtrace_cleaner, :backtrace_length
179
+
180
+ private
181
+
182
+ attr_accessor :state
183
+
184
+ def connection_threshold(connection_id)
185
+ state[:thresholds]&.[](connection_id) || default_threshold
186
+ end
187
+
188
+ def debug!(msg)
189
+ return unless debug_enabled
190
+ msg = "[ISOLATOR DEBUG] #{msg}"
191
+
192
+ if backtrace_cleaner && backtrace_length.positive?
193
+ source = extract_source_location(caller)
194
+
195
+ msg = "#{msg}\n ↳ #{source.join("\n")}" unless source.empty?
196
+ end
197
+
198
+ $stdout.puts(colorize_debug(msg))
199
+ end
200
+
201
+ def extract_source_location(locations)
202
+ backtrace_cleaner.call(locations.lazy)
203
+ .take(backtrace_length).to_a
204
+ end
205
+
206
+ def colorize_debug(msg)
207
+ return msg unless $stdout.tty?
208
+
209
+ "\u001b[31;1m#{msg}\u001b[0m"
210
+ end
110
211
  end
212
+
213
+ self.state = ThreadStateProxy.new
214
+ self.default_threshold = 1
215
+ self.default_connection_id = -> { ActiveRecord::Base.connected? ? ActiveRecord::Base.connection.object_id : 0 }
216
+ self.debug_enabled = ENV["ISOLATOR_DEBUG"] == "true"
217
+ self.backtrace_length = ENV.fetch("ISOLATOR_BACKTRACE_LENGTH", 1).to_i
111
218
  end
112
219
 
113
220
  require "isolator/orm_adapters"
@@ -5,21 +5,27 @@ module Isolator
5
5
  #
6
6
  # - `raise_exceptions` - whether to raise an exception in case of offense;
7
7
  # defaults to true in test env and false otherwise.
8
- # NOTE: env is infered from RACK_ENV and RAILS_ENV.
8
+ # NOTE: env is inferred from RACK_ENV and RAILS_ENV.
9
9
  #
10
10
  # - `logger` - logger instance (nil by default)
11
11
  #
12
12
  # - `send_notifications` - whether to send notifications (through uniform_notifier);
13
- # defauls to false
13
+ # defaults to false
14
+ #
15
+ # - `backtrace_filter` - define a custom backtrace filtering (provide a callable)
16
+ #
17
+ # - `ignorer` - define a custom ignorer (must implement .prepare)
18
+ #
14
19
  class Configuration
15
20
  attr_accessor :raise_exceptions, :logger, :send_notifications,
16
- :backtrace_filter
21
+ :backtrace_filter, :ignorer
17
22
 
18
23
  def initialize
19
24
  @logger = nil
20
25
  @raise_exceptions = test_env?
21
26
  @send_notifications = false
22
27
  @backtrace_filter = ->(backtrace) { backtrace.take(5) }
28
+ @ignorer = Isolator::Ignorer
23
29
  end
24
30
 
25
31
  alias raise_exceptions? raise_exceptions
@@ -1,39 +1,59 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Isolator
4
- # Add .load_ignore_config function for ignoring patterns from file
5
- module Ignorer
6
- def load_ignore_config(path)
7
- return unless File.exist?(path)
4
+ # Handle ignoring isolator errors using a yml file
5
+ class Ignorer
6
+ TODO_PATH = ".isolator_todo.yml"
8
7
 
9
- todos = YAML.load_file(path)
8
+ class << self
9
+ def prepare(path: TODO_PATH, regex_string: "^.*(#ignores#):.*$")
10
+ return unless File.exist?(path)
10
11
 
11
- adapters.each do |id, adapter|
12
- ignored_paths = todos.fetch(id, [])
13
- configure_adapter(adapter, ignored_paths)
12
+ todos = YAML.load_file(path)
13
+
14
+ Isolator.adapters.each do |id, adapter|
15
+ ignored_paths = todos.fetch(id, [])
16
+ AdapterIgnore.new(adapter: adapter, ignored_paths: ignored_paths, regex_string: regex_string).prepare
17
+ end
14
18
  end
15
19
  end
16
20
 
17
21
  private
18
22
 
19
- def configure_adapter(adapter, ignored_paths)
20
- ignores = build_ignore_list(ignored_paths)
21
- return if ignores.blank?
23
+ class AdapterIgnore
24
+ def initialize(adapter:, ignored_paths:, regex_string:)
25
+ self.adapter = adapter
26
+ self.ignored_paths = ignored_paths
27
+ self.regex_string = regex_string
28
+ end
29
+
30
+ def prepare
31
+ return if ignores.blank?
22
32
 
23
- regex = Regexp.new("^.*(#{ignores.join("|")}):.*$")
24
- adapter.ignore_if { caller.any? { |row| regex =~ row } }
25
- end
33
+ adapter.ignore_if { caller.any? { |row| regex =~ row } }
34
+ end
26
35
 
27
- def build_ignore_list(ignored_paths)
28
- ignored_paths.each_with_object([]) do |path, result|
29
- ignored_files = Dir[path]
36
+ private
30
37
 
31
- if ignored_files.blank?
32
- result << path.to_s
33
- else
34
- result.concat(ignored_files)
38
+ attr_accessor :adapter, :ignored_paths, :regex_string
39
+
40
+ def ignores
41
+ return @ignores if defined? @ignores
42
+
43
+ @ignores = ignored_paths.each_with_object([]) do |path, result|
44
+ ignored_files = Dir[path]
45
+
46
+ if ignored_files.blank?
47
+ result << path.to_s
48
+ else
49
+ result.concat(ignored_files)
50
+ end
35
51
  end
36
52
  end
53
+
54
+ def regex
55
+ Regexp.new(regex_string.gsub("#ignores#", ignores.join("|")))
56
+ end
37
57
  end
38
58
  end
39
59
  end
@@ -9,8 +9,9 @@ module Isolator
9
9
 
10
10
  def self.subscribe!(event)
11
11
  ::ActiveSupport::Notifications.subscribe(event) do |_name, _start, _finish, _id, query|
12
- Isolator.incr_transactions! if START_PATTERN.match?(query[:sql])
13
- Isolator.decr_transactions! if FINISH_PATTERN.match?(query[:sql])
12
+ connection_id = query[:connection_id] || query[:connection]&.object_id || 0
13
+ Isolator.incr_transactions!(connection_id) if START_PATTERN.match?(query[:sql])
14
+ Isolator.decr_transactions!(connection_id) if FINISH_PATTERN.match?(query[:sql])
14
15
  end
15
16
  end
16
17
  end
@@ -2,12 +2,20 @@
2
2
 
3
3
  module Isolator
4
4
  class Railtie < ::Rails::Railtie # :nodoc:
5
+ initializer "isolator.backtrace_cleaner" do
6
+ ActiveSupport.on_load(:active_record) do
7
+ Isolator.backtrace_cleaner = lambda do |locations|
8
+ ::Rails.backtrace_cleaner.clean(locations)
9
+ end
10
+ end
11
+ end
12
+
5
13
  config.after_initialize do
6
14
  # Forec load adapters after application initialization
7
15
  # (when all deps are likely to be loaded).
8
16
  load File.join(__dir__, "adapters.rb")
9
17
 
10
- Isolator.load_ignore_config(Rails.root.join(".isolator_todo.yml"))
18
+ Isolator.config.ignorer&.prepare
11
19
 
12
20
  next unless Rails.env.test?
13
21
 
@@ -18,14 +26,12 @@ module Isolator
18
26
  super
19
27
  return unless run_in_transaction?
20
28
 
21
- open_count = ActiveRecord::Base.connection.open_transactions
22
- Isolator.transactions_threshold += open_count
29
+ Isolator.incr_thresholds!
23
30
  end
24
31
 
25
32
  def teardown_fixtures(*)
26
33
  if run_in_transaction?
27
- open_count = ActiveRecord::Base.connection.open_transactions
28
- Isolator.transactions_threshold -= open_count
34
+ Isolator.decr_thresholds!
29
35
  end
30
36
  super
31
37
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Isolator
4
- VERSION = "0.6.2"
4
+ VERSION = "0.7.0"
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: isolator
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.2
4
+ version: 0.7.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Vladimir Dementyev
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-03-20 00:00:00.000000000 Z
11
+ date: 2020-09-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: sniffer
@@ -70,14 +70,14 @@ dependencies:
70
70
  name: rspec-rails
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
- - - "~>"
73
+ - - ">="
74
74
  - !ruby/object:Gem::Version
75
75
  version: '3.0'
76
76
  type: :development
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
- - - "~>"
80
+ - - ">="
81
81
  - !ruby/object:Gem::Version
82
82
  version: '3.0'
83
83
  - !ruby/object:Gem::Dependency
@@ -95,77 +95,77 @@ dependencies:
95
95
  - !ruby/object:Gem::Version
96
96
  version: 5.10.0
97
97
  - !ruby/object:Gem::Dependency
98
- name: standard
98
+ name: sidekiq
99
99
  requirement: !ruby/object:Gem::Requirement
100
100
  requirements:
101
101
  - - "~>"
102
102
  - !ruby/object:Gem::Version
103
- version: 0.2.0
103
+ version: '5.0'
104
104
  type: :development
105
105
  prerelease: false
106
106
  version_requirements: !ruby/object:Gem::Requirement
107
107
  requirements:
108
108
  - - "~>"
109
109
  - !ruby/object:Gem::Version
110
- version: 0.2.0
110
+ version: '5.0'
111
111
  - !ruby/object:Gem::Dependency
112
- name: rubocop-md
112
+ name: webmock
113
113
  requirement: !ruby/object:Gem::Requirement
114
114
  requirements:
115
115
  - - "~>"
116
116
  - !ruby/object:Gem::Version
117
- version: '0.3'
117
+ version: '3.1'
118
118
  type: :development
119
119
  prerelease: false
120
120
  version_requirements: !ruby/object:Gem::Requirement
121
121
  requirements:
122
122
  - - "~>"
123
123
  - !ruby/object:Gem::Version
124
- version: '0.3'
124
+ version: '3.1'
125
125
  - !ruby/object:Gem::Dependency
126
- name: sidekiq
126
+ name: test_after_commit
127
127
  requirement: !ruby/object:Gem::Requirement
128
128
  requirements:
129
129
  - - "~>"
130
130
  - !ruby/object:Gem::Version
131
- version: '5.0'
131
+ version: '1.1'
132
132
  type: :development
133
133
  prerelease: false
134
134
  version_requirements: !ruby/object:Gem::Requirement
135
135
  requirements:
136
136
  - - "~>"
137
137
  - !ruby/object:Gem::Version
138
- version: '5.0'
138
+ version: '1.1'
139
139
  - !ruby/object:Gem::Dependency
140
- name: webmock
140
+ name: resque
141
141
  requirement: !ruby/object:Gem::Requirement
142
142
  requirements:
143
- - - "~>"
143
+ - - ">="
144
144
  - !ruby/object:Gem::Version
145
- version: '3.1'
145
+ version: '0'
146
146
  type: :development
147
147
  prerelease: false
148
148
  version_requirements: !ruby/object:Gem::Requirement
149
149
  requirements:
150
- - - "~>"
150
+ - - ">="
151
151
  - !ruby/object:Gem::Version
152
- version: '3.1'
152
+ version: '0'
153
153
  - !ruby/object:Gem::Dependency
154
- name: test_after_commit
154
+ name: fakeredis
155
155
  requirement: !ruby/object:Gem::Requirement
156
156
  requirements:
157
- - - "~>"
157
+ - - ">="
158
158
  - !ruby/object:Gem::Version
159
- version: '1.1'
159
+ version: '0'
160
160
  type: :development
161
161
  prerelease: false
162
162
  version_requirements: !ruby/object:Gem::Requirement
163
163
  requirements:
164
- - - "~>"
164
+ - - ">="
165
165
  - !ruby/object:Gem::Version
166
- version: '1.1'
166
+ version: '0'
167
167
  - !ruby/object:Gem::Dependency
168
- name: resque
168
+ name: resque-scheduler
169
169
  requirement: !ruby/object:Gem::Requirement
170
170
  requirements:
171
171
  - - ">="
@@ -179,7 +179,7 @@ dependencies:
179
179
  - !ruby/object:Gem::Version
180
180
  version: '0'
181
181
  - !ruby/object:Gem::Dependency
182
- name: fakeredis
182
+ name: sucker_punch
183
183
  requirement: !ruby/object:Gem::Requirement
184
184
  requirements:
185
185
  - - ">="
@@ -193,7 +193,7 @@ dependencies:
193
193
  - !ruby/object:Gem::Version
194
194
  version: '0'
195
195
  - !ruby/object:Gem::Dependency
196
- name: resque-scheduler
196
+ name: database_cleaner
197
197
  requirement: !ruby/object:Gem::Requirement
198
198
  requirements:
199
199
  - - ">="
@@ -207,7 +207,7 @@ dependencies:
207
207
  - !ruby/object:Gem::Version
208
208
  version: '0'
209
209
  - !ruby/object:Gem::Dependency
210
- name: sucker_punch
210
+ name: database_cleaner-active_record
211
211
  requirement: !ruby/object:Gem::Requirement
212
212
  requirements:
213
213
  - - ">="
@@ -221,7 +221,7 @@ dependencies:
221
221
  - !ruby/object:Gem::Version
222
222
  version: '0'
223
223
  - !ruby/object:Gem::Dependency
224
- name: database_cleaner
224
+ name: after_commit_everywhere
225
225
  requirement: !ruby/object:Gem::Requirement
226
226
  requirements:
227
227
  - - ">="
@@ -235,7 +235,7 @@ dependencies:
235
235
  - !ruby/object:Gem::Version
236
236
  version: '0'
237
237
  - !ruby/object:Gem::Dependency
238
- name: database_cleaner-active_record
238
+ name: uniform_notifier
239
239
  requirement: !ruby/object:Gem::Requirement
240
240
  requirements:
241
241
  - - ">="
@@ -255,21 +255,9 @@ executables: []
255
255
  extensions: []
256
256
  extra_rdoc_files: []
257
257
  files:
258
- - ".gitignore"
259
- - ".rubocop.yml"
260
- - ".travis.yml"
261
258
  - CHANGELOG.md
262
- - Gemfile
263
259
  - LICENSE.txt
264
260
  - README.md
265
- - Rakefile
266
- - bin/console
267
- - bin/setup
268
- - gemfiles/activerecord42.gemfile
269
- - gemfiles/jruby.gemfile
270
- - gemfiles/rails6.gemfile
271
- - gemfiles/railsmaster.gemfile
272
- - isolator.gemspec
273
261
  - lib/isolator.rb
274
262
  - lib/isolator/adapter_builder.rb
275
263
  - lib/isolator/adapters.rb
data/.gitignore DELETED
@@ -1,13 +0,0 @@
1
- /.bundle/
2
- /.yardoc
3
- /Gemfile.lock
4
- /_yardoc/
5
- /coverage/
6
- /doc/
7
- /pkg/
8
- /spec/reports/
9
- /tmp/
10
- *.gem
11
- gemfiles/*.lock
12
- Gemfile.local
13
- .rspec_status
@@ -1,51 +0,0 @@
1
- require:
2
- - standard/cop/semantic_blocks
3
- - rubocop-md
4
-
5
- inherit_gem:
6
- standard: config/base.yml
7
-
8
- AllCops:
9
- Exclude:
10
- - 'bin/*'
11
- - 'tmp/**/*'
12
- - 'Gemfile'
13
- - 'vendor/**/*'
14
- - 'gemfiles/**/*'
15
- - 'lib/generators/**/templates/**/*'
16
- DisplayCopNames: true
17
- TargetRubyVersion: 2.5
18
-
19
- Standard/SemanticBlocks:
20
- Enabled: false
21
-
22
- Style/FrozenStringLiteralComment:
23
- Enabled: true
24
-
25
- Style/TrailingCommaInArrayLiteral:
26
- EnforcedStyleForMultiline: no_comma
27
-
28
- Style/TrailingCommaInHashLiteral:
29
- EnforcedStyleForMultiline: no_comma
30
-
31
- Lint/Void:
32
- Exclude:
33
- - '**/*.md'
34
-
35
- # See https://github.com/rubocop-hq/rubocop/issues/4222
36
- Lint/AmbiguousBlockAssociation:
37
- Exclude:
38
- - 'spec/**/*'
39
- - '**/*.md'
40
-
41
- Lint/DuplicateMethods:
42
- Exclude:
43
- - '**/*.md'
44
-
45
- Naming/FileName:
46
- Exclude:
47
- - '**/*.md'
48
-
49
- Layout/InitialIndentation:
50
- Exclude:
51
- - 'CHANGELOG.md'
@@ -1,27 +0,0 @@
1
- sudo: false
2
- language: ruby
3
- cache: bundler
4
-
5
- notifications:
6
- email: false
7
-
8
- matrix:
9
- fast_finish: true
10
- include:
11
- - rvm: ruby-head
12
- gemfile: gemfiles/railsmaster.gemfile
13
- - rvm: jruby-9.2.10.0
14
- gemfile: gemfiles/jruby.gemfile
15
- - rvm: 2.7
16
- gemfile: Gemfile
17
- - rvm: 2.6
18
- gemfile: gemfiles/rails6.gemfile
19
- - rvm: 2.5
20
- gemfile: Gemfile
21
- - rvm: 2.5
22
- gemfile: gemfiles/activerecord42.gemfile
23
- allow_failures:
24
- - rvm: ruby-head
25
- gemfile: gemfiles/railsmaster.gemfile
26
- - rvm: jruby-9.2.10.0
27
- gemfile: gemfiles/jruby.gemfile
data/Gemfile DELETED
@@ -1,20 +0,0 @@
1
- source "https://rubygems.org"
2
-
3
- git_source(:github) { |repo_name| "https://github.com/#{repo_name}" }
4
-
5
- # Specify your gem's dependencies in isolator.gemspec
6
- gemspec
7
-
8
- gem "pry-byebug"
9
-
10
- gem "sqlite3", "~> 1.3.0"
11
-
12
- local_gemfile = File.join(__dir__, "Gemfile.local")
13
-
14
- if File.exist?(local_gemfile)
15
- eval(File.read(local_gemfile)) # rubocop:disable Security/Eval
16
- else
17
- gem "rails", "~> 5.0"
18
- end
19
-
20
- gem 'uniform_notifier', '~> 1.11'
data/Rakefile DELETED
@@ -1,10 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "bundler/gem_tasks"
4
- require "rspec/core/rake_task"
5
- require "rubocop/rake_task"
6
-
7
- RSpec::Core::RakeTask.new(:spec)
8
- RuboCop::RakeTask.new
9
-
10
- task default: [:rubocop, :spec]
@@ -1,7 +0,0 @@
1
- #!/usr/bin/env ruby
2
-
3
- require "bundler/setup"
4
- require "isolator"
5
-
6
- require "pry"
7
- Pry.start
data/bin/setup DELETED
@@ -1,8 +0,0 @@
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
@@ -1,7 +0,0 @@
1
- source "https://rubygems.org"
2
-
3
- gem "rails", "~> 4.2"
4
- gem "sqlite3", "~> 1.3.0"
5
- gem 'uniform_notifier', '~> 1.11'
6
-
7
- gemspec path: ".."
@@ -1,8 +0,0 @@
1
- source "https://rubygems.org"
2
-
3
- gem "activerecord-jdbcsqlite3-adapter", "~> 60.0"
4
- gem "jdbc-sqlite3"
5
- gem "rails", "~> 6.0.0"
6
- gem 'uniform_notifier', '~> 1.11'
7
-
8
- gemspec path: ".."
@@ -1,7 +0,0 @@
1
- source "https://rubygems.org"
2
-
3
- gem "rails", "6.0.0.beta3"
4
- gem "sqlite3", "~> 1.3"
5
- gem 'uniform_notifier', '~> 1.11'
6
-
7
- gemspec path: ".."
@@ -1,7 +0,0 @@
1
- source "https://rubygems.org"
2
-
3
- gem "rails", github: "rails/rails"
4
- gem "sqlite3"
5
- gem 'uniform_notifier', '~> 1.11'
6
-
7
- gemspec path: ".."
@@ -1,53 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- lib = File.expand_path("../lib", __FILE__)
4
- $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
5
- require "isolator/version"
6
-
7
- Gem::Specification.new do |spec|
8
- spec.name = "isolator"
9
- spec.version = Isolator::VERSION
10
- spec.authors = ["Vladimir Dementyev"]
11
- spec.email = ["dementiev.vm@gmail.com"]
12
-
13
- spec.summary = "Detect non-atomic interactions within DB transactions"
14
- spec.description = "Detect non-atomic interactions within DB transactions"
15
- spec.homepage = "https://github.com/palkan/isolator"
16
- spec.license = "MIT"
17
-
18
- spec.required_ruby_version = ">= 2.5.0"
19
-
20
- spec.files = `git ls-files -z`.split("\x0").reject do |f|
21
- f.match(%r{^(test|spec|features)/})
22
- end
23
-
24
- spec.metadata = {
25
- "bug_tracker_uri" => "http://github.com/palkan/isolator/issues",
26
- "changelog_uri" => "https://github.com/palkan/isolator/blob/master/CHANGELOG.md",
27
- "documentation_uri" => "http://github.com/palkan/isolator",
28
- "homepage_uri" => "http://github.com/palkan/isolator",
29
- "source_code_uri" => "http://github.com/palkan/isolator"
30
- }
31
-
32
- spec.require_paths = ["lib"]
33
-
34
- spec.add_runtime_dependency "sniffer", ">= 0.3.1"
35
-
36
- spec.add_development_dependency "bundler", ">= 1.16"
37
- spec.add_development_dependency "rake", "~> 13.0"
38
- spec.add_development_dependency "rspec", "~> 3.0"
39
- spec.add_development_dependency "rspec-rails", "~> 3.0"
40
- spec.add_development_dependency "minitest", "~> 5.10.0"
41
- spec.add_development_dependency "standard", "~> 0.2.0"
42
- spec.add_development_dependency "rubocop-md", "~> 0.3"
43
-
44
- spec.add_development_dependency "sidekiq", "~> 5.0"
45
- spec.add_development_dependency "webmock", "~> 3.1"
46
- spec.add_development_dependency "test_after_commit", "~> 1.1"
47
- spec.add_development_dependency "resque"
48
- spec.add_development_dependency "fakeredis"
49
- spec.add_development_dependency "resque-scheduler"
50
- spec.add_development_dependency "sucker_punch"
51
- spec.add_development_dependency "database_cleaner"
52
- spec.add_development_dependency "database_cleaner-active_record"
53
- end