isolator 0.6.2 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 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