bullet 5.9.0 → 6.1.1
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 +5 -5
- data/.travis.yml +22 -1
- data/CHANGELOG.md +27 -0
- data/Gemfile.rails-4.0 +1 -1
- data/Gemfile.rails-4.1 +1 -1
- data/Gemfile.rails-4.2 +1 -1
- data/Gemfile.rails-5.0 +1 -1
- data/Gemfile.rails-5.1 +1 -1
- data/Gemfile.rails-5.2 +1 -1
- data/Gemfile.rails-6.0 +15 -0
- data/Gemfile.rails-6.1 +15 -0
- data/README.md +31 -10
- data/lib/bullet.rb +50 -26
- data/lib/bullet/active_job.rb +13 -0
- data/lib/bullet/active_record4.rb +9 -32
- data/lib/bullet/active_record41.rb +7 -27
- data/lib/bullet/active_record42.rb +8 -24
- data/lib/bullet/active_record5.rb +188 -179
- data/lib/bullet/active_record52.rb +176 -168
- data/lib/bullet/active_record60.rb +267 -0
- data/lib/bullet/active_record61.rb +267 -0
- data/lib/bullet/bullet_xhr.js +63 -0
- data/lib/bullet/dependency.rb +50 -36
- data/lib/bullet/detector/association.rb +26 -20
- data/lib/bullet/detector/base.rb +1 -2
- data/lib/bullet/detector/counter_cache.rb +13 -9
- data/lib/bullet/detector/n_plus_one_query.rb +22 -12
- data/lib/bullet/detector/unused_eager_loading.rb +6 -3
- data/lib/bullet/ext/object.rb +4 -2
- data/lib/bullet/mongoid4x.rb +2 -6
- data/lib/bullet/mongoid5x.rb +2 -6
- data/lib/bullet/mongoid6x.rb +2 -6
- data/lib/bullet/mongoid7x.rb +2 -6
- data/lib/bullet/notification/base.rb +14 -18
- data/lib/bullet/notification/n_plus_one_query.rb +2 -4
- data/lib/bullet/notification/unused_eager_loading.rb +2 -4
- data/lib/bullet/rack.rb +50 -25
- data/lib/bullet/stack_trace_filter.rb +6 -12
- data/lib/bullet/version.rb +1 -1
- data/lib/generators/bullet/install_generator.rb +23 -23
- data/perf/benchmark.rb +8 -14
- data/spec/bullet/detector/counter_cache_spec.rb +6 -6
- data/spec/bullet/detector/n_plus_one_query_spec.rb +7 -3
- data/spec/bullet/detector/unused_eager_loading_spec.rb +19 -6
- data/spec/bullet/ext/object_spec.rb +9 -4
- data/spec/bullet/notification/base_spec.rb +1 -3
- data/spec/bullet/notification/n_plus_one_query_spec.rb +16 -3
- data/spec/bullet/notification/unused_eager_loading_spec.rb +5 -1
- data/spec/bullet/rack_spec.rb +86 -6
- data/spec/bullet/registry/association_spec.rb +2 -2
- data/spec/bullet/registry/base_spec.rb +1 -1
- data/spec/bullet_spec.rb +11 -30
- data/spec/integration/active_record/association_spec.rb +44 -136
- data/spec/integration/counter_cache_spec.rb +11 -31
- data/spec/integration/mongoid/association_spec.rb +18 -32
- data/spec/models/folder.rb +1 -2
- data/spec/models/group.rb +1 -2
- data/spec/models/page.rb +1 -2
- data/spec/models/writer.rb +1 -2
- data/spec/spec_helper.rb +6 -10
- data/spec/support/bullet_ext.rb +8 -9
- data/spec/support/mongo_seed.rb +2 -16
- data/test.sh +1 -0
- metadata +12 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 6d02240600f13580ed16200edd5c39563bec1cb49a46ccbc82c57cff73a46e2f
|
4
|
+
data.tar.gz: 0f40a4a1fe6157dabec88cb0ecc817168eda794aa1177c41ede1df351695d76a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1d3d3ce81767ce81091ddd7412dd8f341190ffac085477cde3ea04fa1ed696661f84be64d9c1fb6e6a0de276788e56f18aaada213df712cb51e6efb0a577ec37
|
7
|
+
data.tar.gz: a3633af514a31e0ad6ff317a98616ed2c6c3ce070109288b8514c80277d4098359ed25a60bd5bcc4cd0ebf469f156751fa707f8d410f010bfcb8828e206e08a3
|
data/.travis.yml
CHANGED
@@ -1,12 +1,33 @@
|
|
1
|
-
sudo: false
|
2
1
|
language: ruby
|
3
2
|
rvm:
|
4
3
|
- 2.3.0
|
4
|
+
- 2.6.0
|
5
5
|
gemfile:
|
6
|
+
- Gemfile.rails-6.0
|
7
|
+
- Gemfile.rails-5.2
|
6
8
|
- Gemfile.rails-5.1
|
7
9
|
- Gemfile.rails-5.0
|
8
10
|
- Gemfile.rails-4.2
|
9
11
|
- Gemfile.rails-4.1
|
10
12
|
- Gemfile.rails-4.0
|
13
|
+
matrix:
|
14
|
+
exclude:
|
15
|
+
- rvm: 2.3.0
|
16
|
+
gemfile: Gemfile.rails-6.0
|
17
|
+
- rvm: 2.6.0
|
18
|
+
gemfile: Gemfile.rails-5.2
|
19
|
+
- rvm: 2.6.0
|
20
|
+
gemfile: Gemfile.rails-5.1
|
21
|
+
- rvm: 2.6.0
|
22
|
+
gemfile: Gemfile.rails-5.0
|
23
|
+
- rvm: 2.6.0
|
24
|
+
gemfile: Gemfile.rails-4.2
|
25
|
+
- rvm: 2.6.0
|
26
|
+
gemfile: Gemfile.rails-4.1
|
27
|
+
- rvm: 2.6.0
|
28
|
+
gemfile: Gemfile.rails-4.0
|
11
29
|
env:
|
12
30
|
- DB=sqlite
|
31
|
+
before_install:
|
32
|
+
- "find /home/travis/.rvm/rubies -wholename '*default/bundler-*.gemspec' -delete"
|
33
|
+
- gem install bundler -v '< 2'
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,32 @@
|
|
1
1
|
## Next Release
|
2
2
|
|
3
|
+
## 6.1.1 (12/12/2020)
|
4
|
+
|
5
|
+
* Add support Rails 6.1
|
6
|
+
* Make whitelist thread safe
|
7
|
+
|
8
|
+
## 6.1.0 (12/28/2019)
|
9
|
+
|
10
|
+
* Add skip_html_injection flag
|
11
|
+
* Remove writer hack in active_record6
|
12
|
+
* Use modern includes syntax in warnings
|
13
|
+
* Fix warning: The last argument is used as the keyword parameter
|
14
|
+
|
15
|
+
## 6.0.2 (08/20/2019)
|
16
|
+
|
17
|
+
* Fully support Rails 6.0
|
18
|
+
|
19
|
+
## 6.0.1 (06/26/2019)
|
20
|
+
|
21
|
+
* Add Bullet::ActiveJob
|
22
|
+
* Prevent "Maximum call stack exceeded" errors when used with Turbolinks
|
23
|
+
|
24
|
+
## 6.0.0 (04/25/2019)
|
25
|
+
|
26
|
+
* Add XHR support to Bullet
|
27
|
+
* Support Rails 6.0
|
28
|
+
* Handle case where ID is manually set on unpersisted record
|
29
|
+
|
3
30
|
## 5.9.0 (11/11/2018)
|
4
31
|
|
5
32
|
* Require Ruby 2.3+
|
data/Gemfile.rails-4.0
CHANGED
@@ -3,7 +3,7 @@ source "https://rubygems.org"
|
|
3
3
|
gemspec
|
4
4
|
|
5
5
|
gem 'rails', '~> 4.0.0'
|
6
|
-
gem 'sqlite3', platforms: [:ruby]
|
6
|
+
gem 'sqlite3', '~> 1.3.6', platforms: [:ruby]
|
7
7
|
gem 'activerecord-jdbcsqlite3-adapter', platforms: [:jruby]
|
8
8
|
gem 'activerecord-import'
|
9
9
|
gem 'tins', '~> 1.6.0', platforms: [:ruby_19]
|
data/Gemfile.rails-4.1
CHANGED
data/Gemfile.rails-4.2
CHANGED
data/Gemfile.rails-5.0
CHANGED
data/Gemfile.rails-5.1
CHANGED
data/Gemfile.rails-5.2
CHANGED
data/Gemfile.rails-6.0
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
source "https://rubygems.org"
|
2
|
+
|
3
|
+
gemspec
|
4
|
+
|
5
|
+
gem 'rails', '~> 6.0.0'
|
6
|
+
gem 'sqlite3'
|
7
|
+
gem 'activerecord-jdbcsqlite3-adapter', platforms: [:jruby]
|
8
|
+
gem 'activerecord-import'
|
9
|
+
|
10
|
+
gem "rspec"
|
11
|
+
|
12
|
+
platforms :rbx do
|
13
|
+
gem 'rubysl', '~> 2.0'
|
14
|
+
gem 'rubinius-developer_tools'
|
15
|
+
end
|
data/Gemfile.rails-6.1
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
source "https://rubygems.org"
|
2
|
+
|
3
|
+
gemspec
|
4
|
+
|
5
|
+
gem 'rails', '~> 6.1.0'
|
6
|
+
gem 'sqlite3'
|
7
|
+
gem 'activerecord-jdbcsqlite3-adapter', platforms: [:jruby]
|
8
|
+
gem 'activerecord-import'
|
9
|
+
|
10
|
+
gem "rspec"
|
11
|
+
|
12
|
+
platforms :rbx do
|
13
|
+
gem 'rubysl', '~> 2.0'
|
14
|
+
gem 'rubinius-developer_tools'
|
15
|
+
end
|
data/README.md
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# Bullet
|
2
2
|
|
3
|
-
[](http://badge.fury.io/rb/bullet)
|
4
|
+
[](http://travis-ci.org/flyerhzm/bullet)
|
5
5
|
[](https://awesomecode.io/repos/flyerhzm/bullet)
|
6
6
|
[](http://coderwall.com/flyerhzm)
|
7
7
|
|
@@ -37,6 +37,13 @@ or add it into a Gemfile (Bundler):
|
|
37
37
|
gem 'bullet', group: 'development'
|
38
38
|
```
|
39
39
|
|
40
|
+
enable the Bullet gem with generate command
|
41
|
+
|
42
|
+
```ruby
|
43
|
+
bundle exec rails g bullet:install
|
44
|
+
```
|
45
|
+
The generate command will auto generate the default configuration and may ask to include in the test environment as well. See below for custom configuration.
|
46
|
+
|
40
47
|
**Note**: make sure `bullet` gem is added after activerecord (rails) and
|
41
48
|
mongoid.
|
42
49
|
|
@@ -63,6 +70,7 @@ config.after_initialize do
|
|
63
70
|
Bullet.airbrake = true
|
64
71
|
Bullet.rollbar = true
|
65
72
|
Bullet.add_footer = true
|
73
|
+
Bullet.skip_html_injection = false
|
66
74
|
Bullet.stacktrace_includes = [ 'your_gem', 'your_middleware' ]
|
67
75
|
Bullet.stacktrace_excludes = [ 'their_gem', 'their_middleware', ['my_file.rb', 'my_method'], ['my_file.rb', 16..20] ]
|
68
76
|
Bullet.slack = { webhook_url: 'http://some.slack.url', channel: '#default', username: 'notifier' }
|
@@ -85,6 +93,7 @@ The code above will enable all of the Bullet notification systems:
|
|
85
93
|
* `Bullet.rollbar`: add notifications to rollbar
|
86
94
|
* `Bullet.sentry`: add notifications to sentry
|
87
95
|
* `Bullet.add_footer`: adds the details in the bottom left corner of the page. Double click the footer or use close button to hide footer.
|
96
|
+
* `Bullet.skip_html_injection`: prevents Bullet from injecting XHR into the returned HTML. This must be false for receiving alerts or console logging.
|
88
97
|
* `Bullet.stacktrace_includes`: include paths with any of these substrings in the stack trace, even if they are not in your main app
|
89
98
|
* `Bullet.stacktrace_excludes`: ignore paths with any of these substrings in the stack trace, even if they are not in your main app.
|
90
99
|
Each item can be a string (match substring), a regex, or an array where the first item is a path to match, and the second
|
@@ -125,7 +134,7 @@ do like
|
|
125
134
|
|
126
135
|
```ruby
|
127
136
|
class ApplicationController < ActionController::Base
|
128
|
-
around_action :skip_bullet
|
137
|
+
around_action :skip_bullet, if: -> { defined?(Bullet) }
|
129
138
|
|
130
139
|
def skip_bullet
|
131
140
|
previous_value = Bullet.enable?
|
@@ -181,15 +190,27 @@ If you find Bullet does not work for you, *please disable your browser's cache*.
|
|
181
190
|
|
182
191
|
## Advanced
|
183
192
|
|
184
|
-
###
|
193
|
+
### Work with ActiveJob
|
185
194
|
|
186
|
-
|
195
|
+
Include `Bullet::ActiveJob` in your `ApplicationJob`.
|
187
196
|
|
188
197
|
```ruby
|
189
|
-
|
190
|
-
|
198
|
+
class ApplicationJob < ActiveJob::Base
|
199
|
+
include Bullet::ActiveJob if Rails.env.development?
|
200
|
+
end
|
201
|
+
```
|
202
|
+
|
203
|
+
### Work with other background job solution
|
204
|
+
|
205
|
+
Use the Bullet.profile method.
|
191
206
|
|
192
|
-
|
207
|
+
```ruby
|
208
|
+
class ApplicationJob < ActiveJob::Base
|
209
|
+
around_perform do |_job, block|
|
210
|
+
Bullet.profile do
|
211
|
+
block.call
|
212
|
+
end
|
213
|
+
end
|
193
214
|
end
|
194
215
|
```
|
195
216
|
|
@@ -221,7 +242,7 @@ end
|
|
221
242
|
Then wrap each test in Bullet api.
|
222
243
|
|
223
244
|
```ruby
|
224
|
-
# spec/
|
245
|
+
# spec/rails_helper.rb
|
225
246
|
if Bullet.enable?
|
226
247
|
config.before(:each) do
|
227
248
|
Bullet.start_request
|
@@ -458,4 +479,4 @@ Meanwhile, there's a line appended to `log/bullet.log`
|
|
458
479
|
Post => [:comments]
|
459
480
|
```
|
460
481
|
|
461
|
-
Copyright (c) 2009 -
|
482
|
+
Copyright (c) 2009 - 2019 Richard Huang (flyerhzm@gmail.com), released under the MIT license
|
data/lib/bullet.rb
CHANGED
@@ -14,6 +14,7 @@ module Bullet
|
|
14
14
|
autoload :ActiveRecord, "bullet/#{active_record_version}" if active_record?
|
15
15
|
autoload :Mongoid, "bullet/#{mongoid_version}" if mongoid?
|
16
16
|
autoload :Rack, 'bullet/rack'
|
17
|
+
autoload :ActiveJob, 'bullet/active_job'
|
17
18
|
autoload :Notification, 'bullet/notification'
|
18
19
|
autoload :Detector, 'bullet/detector'
|
19
20
|
autoload :Registry, 'bullet/registry'
|
@@ -22,7 +23,7 @@ module Bullet
|
|
22
23
|
BULLET_DEBUG = 'BULLET_DEBUG'
|
23
24
|
TRUE = 'true'
|
24
25
|
|
25
|
-
if defined?
|
26
|
+
if defined?(Rails::Railtie)
|
26
27
|
class BulletRailtie < Rails::Railtie
|
27
28
|
initializer 'bullet.configure_rails_initialization' do |app|
|
28
29
|
app.middleware.use Bullet::Rack
|
@@ -31,28 +32,35 @@ module Bullet
|
|
31
32
|
end
|
32
33
|
|
33
34
|
class << self
|
34
|
-
attr_writer :n_plus_one_query_enable,
|
35
|
-
|
36
|
-
|
35
|
+
attr_writer :n_plus_one_query_enable,
|
36
|
+
:unused_eager_loading_enable,
|
37
|
+
:counter_cache_enable,
|
38
|
+
:stacktrace_includes,
|
39
|
+
:stacktrace_excludes,
|
40
|
+
:skip_html_injection
|
41
|
+
attr_accessor :add_footer, :orm_patches_applied
|
37
42
|
|
38
43
|
available_notifiers = UniformNotifier::AVAILABLE_NOTIFIERS.map { |notifier| "#{notifier}=" }
|
39
|
-
|
40
|
-
delegate(*available_notifiers)
|
44
|
+
available_notifiers_options = { to: UniformNotifier }
|
45
|
+
delegate(*available_notifiers, **available_notifiers_options)
|
41
46
|
|
42
47
|
def raise=(should_raise)
|
43
48
|
UniformNotifier.raise = (should_raise ? Notification::UnoptimizedQueryError : false)
|
44
49
|
end
|
45
50
|
|
46
|
-
DETECTORS = [
|
47
|
-
|
48
|
-
|
51
|
+
DETECTORS = [
|
52
|
+
Bullet::Detector::NPlusOneQuery,
|
53
|
+
Bullet::Detector::UnusedEagerLoading,
|
54
|
+
Bullet::Detector::CounterCache
|
55
|
+
].freeze
|
49
56
|
|
50
57
|
def enable=(enable)
|
51
58
|
@enable = @n_plus_one_query_enable = @unused_eager_loading_enable = @counter_cache_enable = enable
|
59
|
+
|
52
60
|
if enable?
|
53
61
|
reset_whitelist
|
54
|
-
unless
|
55
|
-
self.
|
62
|
+
unless orm_patches_applied
|
63
|
+
self.orm_patches_applied = true
|
56
64
|
Bullet::Mongoid.enable if mongoid?
|
57
65
|
Bullet::ActiveRecord.enable if active_record?
|
58
66
|
end
|
@@ -63,6 +71,10 @@ module Bullet
|
|
63
71
|
!!@enable
|
64
72
|
end
|
65
73
|
|
74
|
+
def app_root
|
75
|
+
(defined?(::Rails.root) ? Rails.root.to_s : Dir.pwd).to_s
|
76
|
+
end
|
77
|
+
|
66
78
|
def n_plus_one_query_enable?
|
67
79
|
enable? && !!@n_plus_one_query_enable
|
68
80
|
end
|
@@ -85,35 +97,34 @@ module Bullet
|
|
85
97
|
|
86
98
|
def add_whitelist(options)
|
87
99
|
reset_whitelist
|
88
|
-
|
89
|
-
|
100
|
+
Thread.current[:whitelist][options[:type]][options[:class_name]] ||= []
|
101
|
+
Thread.current[:whitelist][options[:type]][options[:class_name]] << options[:association].to_sym
|
90
102
|
end
|
91
103
|
|
92
104
|
def delete_whitelist(options)
|
93
105
|
reset_whitelist
|
94
|
-
|
95
|
-
|
96
|
-
|
106
|
+
Thread.current[:whitelist][options[:type]][options[:class_name]] ||= []
|
107
|
+
Thread.current[:whitelist][options[:type]][options[:class_name]].delete(options[:association].to_sym)
|
108
|
+
Thread.current[:whitelist][options[:type]].delete_if { |_key, val| val.empty? }
|
97
109
|
end
|
98
110
|
|
99
111
|
def get_whitelist_associations(type, class_name)
|
100
|
-
Array(
|
112
|
+
Array(Thread.current[:whitelist][type][class_name])
|
101
113
|
end
|
102
114
|
|
103
115
|
def reset_whitelist
|
104
|
-
|
116
|
+
Thread.current[:whitelist] ||= { n_plus_one_query: {}, unused_eager_loading: {}, counter_cache: {} }
|
105
117
|
end
|
106
118
|
|
107
119
|
def clear_whitelist
|
108
|
-
|
120
|
+
Thread.current[:whitelist] = nil
|
109
121
|
end
|
110
122
|
|
111
123
|
def bullet_logger=(active)
|
112
124
|
if active
|
113
125
|
require 'fileutils'
|
114
|
-
|
115
|
-
|
116
|
-
bullet_log_file = File.open("#{root_path}/log/bullet.log", 'a+')
|
126
|
+
FileUtils.mkdir_p(app_root + '/log')
|
127
|
+
bullet_log_file = File.open("#{app_root}/log/bullet.log", 'a+')
|
117
128
|
bullet_log_file.sync = true
|
118
129
|
UniformNotifier.customized_logger = bullet_log_file
|
119
130
|
end
|
@@ -170,9 +181,7 @@ module Bullet
|
|
170
181
|
|
171
182
|
def gather_inline_notifications
|
172
183
|
responses = []
|
173
|
-
for_each_active_notifier_with_notification
|
174
|
-
responses << notification.notify_inline
|
175
|
-
end
|
184
|
+
for_each_active_notifier_with_notification { |notification| responses << notification.notify_inline }
|
176
185
|
responses.join("\n")
|
177
186
|
end
|
178
187
|
|
@@ -185,9 +194,15 @@ module Bullet
|
|
185
194
|
end
|
186
195
|
|
187
196
|
def footer_info
|
197
|
+
info = []
|
198
|
+
notification_collector.collection.each { |notification| info << notification.short_notice }
|
199
|
+
info
|
200
|
+
end
|
201
|
+
|
202
|
+
def text_notifications
|
188
203
|
info = []
|
189
204
|
notification_collector.collection.each do |notification|
|
190
|
-
info << notification.
|
205
|
+
info << notification.notification_data.values.compact.join("\n")
|
191
206
|
end
|
192
207
|
info
|
193
208
|
end
|
@@ -202,6 +217,7 @@ module Bullet
|
|
202
217
|
|
203
218
|
def profile
|
204
219
|
return_value = nil
|
220
|
+
|
205
221
|
if Bullet.enable?
|
206
222
|
begin
|
207
223
|
Bullet.start_request
|
@@ -219,6 +235,14 @@ module Bullet
|
|
219
235
|
return_value
|
220
236
|
end
|
221
237
|
|
238
|
+
def console_enabled?
|
239
|
+
UniformNotifier.active_notifiers.include?(UniformNotifier::JavascriptConsole)
|
240
|
+
end
|
241
|
+
|
242
|
+
def inject_into_page?
|
243
|
+
!@skip_html_injection && (console_enabled? || add_footer)
|
244
|
+
end
|
245
|
+
|
222
246
|
private
|
223
247
|
|
224
248
|
def for_each_active_notifier_with_notification
|