prosopite 1.4.2 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: '0509715095d0797998d5bd88ad33bf6390bbc68d5da7f34a10ada120bbcbe96d'
4
- data.tar.gz: 3e05d4ae63f68955c002853d5820bac19ab239b7d4987576bf1d7b9dd85f7d06
3
+ metadata.gz: 79f272a757baeae3f05f7721b7204130588532ac09fb28d163d09737512f8edd
4
+ data.tar.gz: d45ecc27ba09f2b55447eb82f9fc35773846cf44d924b710a83eaa5ada5260a0
5
5
  SHA512:
6
- metadata.gz: 63408215134ec404aba9cd4728ae2bdbb57b0924c08449a1cccc1f72d46cfdedec33685643b452eac0a23ff05abbb0fc74f96954b0ec874b94aef974f46d2ed0
7
- data.tar.gz: d1b9a6d908bf2b17bbe9710b446a0c7b3f66a1a5b0468aaabb37b085d152d609a973faec5ae529d859ecea8c297d93ff3128917344ae6ff0159fb4fc5041a10b
6
+ metadata.gz: 60cd8f6dc74fc8a51e7ada04ae53212c8965309ffbe67ad83f6e2537a289bb205a4e626e44fda4b14673aed407cf2bb706306ba0f47051d22da7a16c78f73fcb
7
+ data.tar.gz: 66c392a288ddbdf44bacc433740c9b6c2e7213c714e80c77992581460736300451a0f7add73196d81203a0533900424128754960ffbce6914d20c9e01cfdb8c5
@@ -4,7 +4,7 @@ jobs:
4
4
  test:
5
5
  strategy:
6
6
  matrix:
7
- ruby: [2.7, '3.0', 3.1, 3.2]
7
+ ruby: [3.2, 3.3, 3.4]
8
8
  runs-on: ubuntu-latest
9
9
  steps:
10
10
  - uses: actions/checkout@v3
data/Gemfile.lock CHANGED
@@ -1,87 +1,136 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- prosopite (1.4.2)
4
+ prosopite (2.1.0)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
8
8
  specs:
9
- actionpack (6.1.3)
10
- actionview (= 6.1.3)
11
- activesupport (= 6.1.3)
12
- rack (~> 2.0, >= 2.0.9)
9
+ actionpack (8.0.1)
10
+ actionview (= 8.0.1)
11
+ activesupport (= 8.0.1)
12
+ nokogiri (>= 1.8.5)
13
+ rack (>= 2.2.4)
14
+ rack-session (>= 1.0.1)
13
15
  rack-test (>= 0.6.3)
14
- rails-dom-testing (~> 2.0)
15
- rails-html-sanitizer (~> 1.0, >= 1.2.0)
16
- actionview (6.1.3)
17
- activesupport (= 6.1.3)
16
+ rails-dom-testing (~> 2.2)
17
+ rails-html-sanitizer (~> 1.6)
18
+ useragent (~> 0.16)
19
+ actionview (8.0.1)
20
+ activesupport (= 8.0.1)
18
21
  builder (~> 3.1)
19
- erubi (~> 1.4)
20
- rails-dom-testing (~> 2.0)
21
- rails-html-sanitizer (~> 1.1, >= 1.2.0)
22
- activemodel (6.1.3)
23
- activesupport (= 6.1.3)
24
- activerecord (6.1.3)
25
- activemodel (= 6.1.3)
26
- activesupport (= 6.1.3)
27
- activesupport (6.1.3)
28
- concurrent-ruby (~> 1.0, >= 1.0.2)
22
+ erubi (~> 1.11)
23
+ rails-dom-testing (~> 2.2)
24
+ rails-html-sanitizer (~> 1.6)
25
+ activemodel (8.0.1)
26
+ activesupport (= 8.0.1)
27
+ activerecord (8.0.1)
28
+ activemodel (= 8.0.1)
29
+ activesupport (= 8.0.1)
30
+ timeout (>= 0.4.0)
31
+ activesupport (8.0.1)
32
+ base64
33
+ benchmark (>= 0.3)
34
+ bigdecimal
35
+ concurrent-ruby (~> 1.0, >= 1.3.1)
36
+ connection_pool (>= 2.2.5)
37
+ drb
29
38
  i18n (>= 1.6, < 2)
39
+ logger (>= 1.4.2)
30
40
  minitest (>= 5.1)
31
- tzinfo (~> 2.0)
32
- zeitwerk (~> 2.3)
41
+ securerandom (>= 0.3)
42
+ tzinfo (~> 2.0, >= 2.0.5)
43
+ uri (>= 0.13.1)
33
44
  ansi (1.5.0)
45
+ base64 (0.2.0)
46
+ benchmark (0.4.0)
47
+ bigdecimal (3.1.9)
34
48
  builder (3.2.4)
35
49
  coderay (1.1.3)
36
- concurrent-ruby (1.1.8)
50
+ concurrent-ruby (1.3.5)
51
+ connection_pool (2.5.0)
37
52
  crass (1.0.6)
53
+ date (3.4.1)
54
+ drb (2.2.1)
38
55
  erubi (1.12.0)
39
- factory_bot (6.1.0)
40
- activesupport (>= 5.0.0)
56
+ factory_bot (6.5.1)
57
+ activesupport (>= 6.1.0)
41
58
  i18n (1.8.9)
42
59
  concurrent-ruby (~> 1.0)
43
- loofah (2.19.1)
60
+ io-console (0.8.0)
61
+ irb (1.15.1)
62
+ pp (>= 0.6.0)
63
+ rdoc (>= 4.0.0)
64
+ reline (>= 0.4.2)
65
+ logger (1.6.6)
66
+ loofah (2.24.0)
44
67
  crass (~> 1.0.2)
45
- nokogiri (>= 1.5.9)
68
+ nokogiri (>= 1.12.0)
46
69
  method_source (1.0.0)
47
- mini_portile2 (2.8.1)
48
- minitest (5.14.3)
70
+ mini_portile2 (2.8.8)
71
+ minitest (5.25.4)
49
72
  minitest-reporters (1.5.0)
50
73
  ansi
51
74
  builder
52
75
  minitest (>= 5.0)
53
76
  ruby-progressbar
54
- nokogiri (1.14.1)
55
- mini_portile2 (~> 2.8.0)
77
+ nokogiri (1.18.3)
78
+ mini_portile2 (~> 2.8.2)
56
79
  racc (~> 1.4)
57
- nokogiri (1.14.1-x86_64-linux)
80
+ nokogiri (1.18.3-x86_64-linux-gnu)
58
81
  racc (~> 1.4)
59
82
  pg_query (1.3.0)
83
+ pp (0.6.2)
84
+ prettyprint
85
+ prettyprint (0.2.0)
60
86
  pry (0.14.0)
61
87
  coderay (~> 1.1)
62
88
  method_source (~> 1.0)
63
- racc (1.6.2)
64
- rack (2.2.6.2)
89
+ psych (5.2.3)
90
+ date
91
+ stringio
92
+ racc (1.8.1)
93
+ rack (3.1.10)
94
+ rack-session (2.1.0)
95
+ base64 (>= 0.1.0)
96
+ rack (>= 3.0.0)
65
97
  rack-test (2.0.2)
66
98
  rack (>= 1.3)
67
- rails-dom-testing (2.0.3)
68
- activesupport (>= 4.2.0)
99
+ rackup (2.2.1)
100
+ rack (>= 3)
101
+ rails-dom-testing (2.2.0)
102
+ activesupport (>= 5.0.0)
103
+ minitest
69
104
  nokogiri (>= 1.6)
70
- rails-html-sanitizer (1.5.0)
71
- loofah (~> 2.19, >= 2.19.1)
72
- railties (6.1.3)
73
- actionpack (= 6.1.3)
74
- activesupport (= 6.1.3)
75
- method_source
76
- rake (>= 0.8.7)
77
- thor (~> 1.0)
105
+ rails-html-sanitizer (1.6.2)
106
+ loofah (~> 2.21)
107
+ nokogiri (>= 1.15.7, != 1.16.7, != 1.16.6, != 1.16.5, != 1.16.4, != 1.16.3, != 1.16.2, != 1.16.1, != 1.16.0.rc1, != 1.16.0)
108
+ railties (8.0.1)
109
+ actionpack (= 8.0.1)
110
+ activesupport (= 8.0.1)
111
+ irb (~> 1.13)
112
+ rackup (>= 1.0.0)
113
+ rake (>= 12.2)
114
+ thor (~> 1.0, >= 1.2.2)
115
+ zeitwerk (~> 2.6)
78
116
  rake (13.0.6)
117
+ rdoc (6.12.0)
118
+ psych (>= 4.0.0)
119
+ reline (0.6.0)
120
+ io-console (~> 0.5)
79
121
  ruby-progressbar (1.11.0)
80
- sqlite3 (1.4.2)
81
- thor (1.2.1)
82
- tzinfo (2.0.4)
122
+ securerandom (0.4.1)
123
+ sqlite3 (2.5.0)
124
+ mini_portile2 (~> 2.8.0)
125
+ sqlite3 (2.5.0-x86_64-linux-gnu)
126
+ stringio (3.1.4)
127
+ thor (1.3.2)
128
+ timeout (0.4.3)
129
+ tzinfo (2.0.6)
83
130
  concurrent-ruby (~> 1.0)
84
- zeitwerk (2.4.2)
131
+ uri (1.0.2)
132
+ useragent (0.16.11)
133
+ zeitwerk (2.7.2)
85
134
 
86
135
  PLATFORMS
87
136
  ruby
@@ -100,4 +149,4 @@ DEPENDENCIES
100
149
  sqlite3
101
150
 
102
151
  BUNDLED WITH
103
- 2.2.10
152
+ 2.6.5
data/README.md CHANGED
@@ -116,37 +116,17 @@ Or install it yourself as:
116
116
  The preferred type of notifications can be configured with:
117
117
 
118
118
  * `Prosopite.min_n_queries`: Minimum number of N queries to report per N+1 case. Defaults to 2.
119
- * `Prosopite.raise = true`: Raise warnings as exceptions
120
- * `Prosopite.rails_logger = true`: Send warnings to the Rails log
121
- * `Prosopite.prosopite_logger = true`: Send warnings to `log/prosopite.log`
122
- * `Prosopite.stderr_logger = true`: Send warnings to STDERR
119
+ * `Prosopite.raise = true`: Raise warnings as exceptions. Defaults to `false`.
120
+ * `Prosopite.start_raise`: Raises warnings as exceptions from when this is called. Overrides `Proposite.raise`.
121
+ * `Propsoite.stop_raise`: Disables raising warnings as exceptions if previously enabled with `Proposite.start_raise`.
122
+ * `Prosopite.local_raise?`: Returns `true` if `Prosopite.start_raise` has been called previously.
123
+ * `Prosopite.rails_logger = true`: Send warnings to the Rails log. Defaults to `false`.
124
+ * `Prosopite.prosopite_logger = true`: Send warnings to `log/prosopite.log`. Defaults to `false`.
125
+ * `Prosopite.stderr_logger = true`: Send warnings to STDERR. Defaults to `false`.
123
126
  * `Prosopite.backtrace_cleaner = my_custom_backtrace_cleaner`: use a different [ActiveSupport::BacktraceCleaner](https://api.rubyonrails.org/classes/ActiveSupport/BacktraceCleaner.html). Defaults to `Rails.backtrace_cleaner`.
124
- * `Prosopite.custom_logger = my_custom_logger`:
127
+ * `Prosopite.custom_logger = my_custom_logger`: Set a custom logger. See the following section for the details. Defaults to `false`.
125
128
  * `Prosopite.enabled = true`: Enables or disables the gem. Defaults to `true`.
126
129
 
127
- ### Custom Logging Configuration
128
-
129
- You can supply a custom logger with the `Prosopite.custom_logger` setting.
130
-
131
- This is useful for circumstances where you don't want your logs to be
132
- highlighted with red, or you want logs sent to a custom location.
133
-
134
- One common scenario is that you may be generating json logs and sending them to
135
- Datadog, ELK stack, or similar, and don't want to have to remove the default red
136
- escaping data from messages sent to the Rails logger, or want to tag them
137
- differently with your own custom logger.
138
-
139
- ```ruby
140
- # Turns off logging with red highlights, but still sends them to the Rails logger
141
- Prosopite.custom_logger = Rails.logger
142
- ```
143
-
144
- ```ruby
145
- # Use a completely custom logging instance
146
- Prosopite.custom_logger = MyLoggerClass.new
147
-
148
- ```
149
-
150
130
  ## Development Environment Usage
151
131
 
152
132
  Prosopite auto-detection can be enabled on all controllers:
@@ -174,7 +154,7 @@ config.after_initialize do
174
154
  Prosopite.rails_logger = true
175
155
  end
176
156
  ```
177
-
157
+ ```
178
158
  ## Test Environment Usage
179
159
 
180
160
  Tests with N+1 queries can be configured to fail with:
@@ -315,6 +295,77 @@ Pauses can be ignored with `Prosopite.ignore_pauses = true` in case you want to
315
295
  An example of when you might use this is if you are [testing Active Jobs inline](https://guides.rubyonrails.org/testing.html#testing-jobs),
316
296
  and don't want to run Prosopite on background job code, just foreground app code. In that case you could write an [Active Job callback](https://edgeguides.rubyonrails.org/active_job_basics.html#callbacks) that pauses the scan while the job is running.
317
297
 
298
+ ## Local Raise
299
+
300
+ In some cases you may want to configure prosopite to not raise by default and only raise in certain scenarios.
301
+ In this example we scan on all controllers but also provide an API to only raise on specific actions.
302
+
303
+ ```ruby
304
+ Proposite.raise = false
305
+ ```
306
+
307
+ ```ruby
308
+ # app/controllers/application_controller.rb
309
+ class ApplicationController < ActionController::Base
310
+ def raise_on_n_plus_ones!(**options)
311
+ return if Rails.env.production?
312
+
313
+ prepend_around_action(:_raise_on_n_plus_ones, **options)
314
+ end
315
+
316
+ unless Rails.env.production?
317
+ around_action :n_plus_one_detection
318
+
319
+ def n_plus_one_detection
320
+ ...
321
+ end
322
+
323
+ def _raise_on_n_plus_ones
324
+ Proposite.start_raise
325
+ yield
326
+ ensure
327
+ Prosopite.stop_raise
328
+ end
329
+ end
330
+ end
331
+ ```
332
+ ```ruby
333
+ # app/controllers/books_controller.rb
334
+ class BooksController < ApplicationController
335
+ raise_on_n_plus_ones!(only: [:index])
336
+
337
+ def index
338
+ @books = Book.all.map(&:author) # This will raise N+1 errors
339
+ end
340
+
341
+ def show
342
+ @book = Book.find(params[:id])
343
+ @book.reviews.map(&:author) # This will not raise N+1 errors
344
+ end
345
+ end
346
+
347
+ ## Custom Logging Configuration
348
+
349
+ You can supply a custom logger with the `Prosopite.custom_logger` setting.
350
+
351
+ This is useful for circumstances where you don't want your logs to be
352
+ highlighted with red, or you want logs sent to a custom location.
353
+
354
+ One common scenario is that you may be generating json logs and sending them to
355
+ Datadog, ELK stack, or similar, and don't want to have to remove the default red
356
+ escaping data from messages sent to the Rails logger, or want to tag them
357
+ differently with your own custom logger.
358
+
359
+ ```ruby
360
+ # Turns off logging with red highlights, but still sends them to the Rails logger
361
+ Prosopite.custom_logger = Rails.logger
362
+ ```
363
+
364
+ ```ruby
365
+ # Use a completely custom logging instance
366
+ Prosopite.custom_logger = MyLoggerClass.new
367
+ ```
368
+
318
369
  ## Contributing
319
370
 
320
371
  Bug reports and pull requests are welcome on GitHub at https://github.com/charkost/prosopite.
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Prosopite
4
- VERSION = "1.4.2"
4
+ VERSION = "2.1.0"
5
5
  end
data/lib/prosopite.rb CHANGED
@@ -113,6 +113,22 @@ module Prosopite
113
113
  tc[:prosopite_query_caller] = nil
114
114
  end
115
115
 
116
+ def start_raise
117
+ tc[:prosopite_local_raise] = true
118
+ end
119
+
120
+ def stop_raise
121
+ tc[:prosopite_local_raise] = false
122
+ end
123
+
124
+ def local_raise?
125
+ tc[:prosopite_local_raise] == true
126
+ end
127
+
128
+ def raise?
129
+ local_raise? || !!@raise
130
+ end
131
+
116
132
  def create_notifications
117
133
  tc[:prosopite_notifications] = {}
118
134
 
@@ -144,7 +160,12 @@ module Prosopite
144
160
  end
145
161
 
146
162
  def fingerprint(query)
147
- db_adapter = ActiveRecord::Base.connection.adapter_name.downcase
163
+ conn = if ActiveRecord::Base.respond_to?(:lease_connection)
164
+ ActiveRecord::Base.lease_connection
165
+ else
166
+ ActiveRecord::Base.connection
167
+ end
168
+ db_adapter = conn.adapter_name.downcase
148
169
  if db_adapter.include?('mysql') || db_adapter.include?('trilogy')
149
170
  mysql_fingerprint(query)
150
171
  else
@@ -212,9 +233,8 @@ module Prosopite
212
233
  @rails_logger ||= false
213
234
  @stderr_logger ||= false
214
235
  @prosopite_logger ||= false
215
- @raise ||= false
216
236
 
217
- notifications_str = ''
237
+ notifications_str = String.new('')
218
238
 
219
239
  tc[:prosopite_notifications].each do |queries, kaller|
220
240
  notifications_str << "N+1 queries detected:\n"
@@ -241,7 +261,7 @@ module Prosopite
241
261
  end
242
262
  end
243
263
 
244
- raise NPlusOneQueriesError.new(notifications_str) if @raise
264
+ raise NPlusOneQueriesError.new(notifications_str) if raise?
245
265
  end
246
266
 
247
267
  def red(str)
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: prosopite
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.4.2
4
+ version: 2.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mpampis Kostas
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-12-14 00:00:00.000000000 Z
11
+ date: 2025-03-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: pry
@@ -148,7 +148,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
148
148
  - !ruby/object:Gem::Version
149
149
  version: '0'
150
150
  requirements: []
151
- rubygems_version: 3.4.6
151
+ rubygems_version: 3.5.3
152
152
  signing_key:
153
153
  specification_version: 4
154
154
  summary: N+1 auto-detection for Rails with zero false positives / false negatives