bulletmark_repairer 0.1.5 → 0.1.7
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +9 -0
- data/lib/bulletmark_repairer/controller_corrector.rb +26 -4
- data/lib/bulletmark_repairer/markers.rb +2 -2
- data/lib/bulletmark_repairer/monkey_patches/action_view/base.rb +14 -0
- data/lib/bulletmark_repairer/monkey_patches/active_record/query_method.rb +3 -3
- data/lib/bulletmark_repairer/rack.rb +10 -6
- data/lib/bulletmark_repairer/railtie.rb +4 -0
- data/lib/bulletmark_repairer/retry_corrector.rb +26 -4
- data/lib/bulletmark_repairer/thread.rb +58 -0
- data/lib/bulletmark_repairer/version.rb +1 -1
- data/lib/bulletmark_repairer.rb +1 -0
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 39af4a769d591a28ab628d174b6224984bf3f87460e2ee4d782a5a16a3c04d87
|
4
|
+
data.tar.gz: 2b163d905540357085ef7d9436abc189d4cde357f95a5e7650b538b195bb95bc
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c5a8331d8787887ff29e736d353978d6d86000d14713df1576f131c9a661aaf166421aa963bd4752a5d3d55f2ee642fdbfeac3e551defe126450cd6d4c5d1aa3
|
7
|
+
data.tar.gz: 9d9a6aa80d778ec59b86d4eea3123e732ab146b01dfaf46ef78a7d66ebb0e1923558a903eef36afd895fb97404b4650585ad7ee3b5cbc34e16b947d790952f7b
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,12 @@
|
|
1
|
+
## [0.1.7] - 2023-11-21
|
2
|
+
|
3
|
+
- Validate detected instance_variable is an ActiveRecord::Relation [ed650ae](https://github.com/makicamel/bulletmark_repairer/commit/ed650ae41b4389774cb1135031f077e953d2c5db) [86497bd](https://github.com/makicamel/bulletmark_repairer/commit/86497bd3cbb6daf1672cd18210e5842d0ecc084f)
|
4
|
+
- Add includes after methods returning AR on autocorrect [767e5e1](https://github.com/makicamel/bulletmark_repairer/commit/767e5e1389f84daa6efce4463a4979a100c16640)
|
5
|
+
|
6
|
+
## [0.1.6] - 2023-11-09
|
7
|
+
|
8
|
+
Fix a bug when N+1 is caused not in the request (e.g. Sidekiq) [51f051e](https://github.com/makicamel/bulletmark_repairer/commit/51f051e608b84b7da96ac879a324ed438c14eeeb)
|
9
|
+
|
1
10
|
## [0.1.5] - 2023-10-27
|
2
11
|
|
3
12
|
Be able to patch for nested associations require `includes` though child associations are already included [d1b7445](https://github.com/makicamel/bulletmark_repairer/commit/d1b7445556c20bc037beb6a013ac70531426a7ea)
|
@@ -33,6 +33,14 @@ class ControllerCorrector < Parser::TreeRewriter
|
|
33
33
|
@patched ||= false
|
34
34
|
end
|
35
35
|
|
36
|
+
def includes_token
|
37
|
+
@includes_token ||= ".includes(#{associations})"
|
38
|
+
end
|
39
|
+
|
40
|
+
def inserted?(parent_node)
|
41
|
+
parent_node.location.expression.source.include?(includes_token)
|
42
|
+
end
|
43
|
+
|
36
44
|
def target_nodes
|
37
45
|
@target_nodes ||= {}
|
38
46
|
end
|
@@ -47,10 +55,8 @@ class ControllerCorrector < Parser::TreeRewriter
|
|
47
55
|
|
48
56
|
type, identifier = node.to_sexp_array.take(2)
|
49
57
|
if type == :ivasgn && identifier == instance_variable_name
|
50
|
-
|
51
|
-
|
52
|
-
insert_after node.children.last.location.expression, inserted
|
53
|
-
@patched = true
|
58
|
+
node.children.each do |child_node|
|
59
|
+
execute_insert_includes(node: child_node, parent_node: node)
|
54
60
|
end
|
55
61
|
else
|
56
62
|
node
|
@@ -67,6 +73,22 @@ class ControllerCorrector < Parser::TreeRewriter
|
|
67
73
|
end
|
68
74
|
end
|
69
75
|
|
76
|
+
def execute_insert_includes(node:, parent_node:)
|
77
|
+
return unless node.respond_to?(:children)
|
78
|
+
return if patched?
|
79
|
+
|
80
|
+
node.children.each do |child_node|
|
81
|
+
if child_node.is_a?(Symbol)
|
82
|
+
if BulletmarkRepairer::Thread.correctable_method?(child_node) && !inserted?(parent_node)
|
83
|
+
insert_after node.location.expression, includes_token
|
84
|
+
@patched = true
|
85
|
+
end
|
86
|
+
else
|
87
|
+
execute_insert_includes(node: child_node, parent_node: node)
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
70
92
|
def action
|
71
93
|
:__EMBEDDED_ACTION__
|
72
94
|
end
|
@@ -82,7 +82,6 @@ module BulletmarkRepairer
|
|
82
82
|
end
|
83
83
|
view_file, view_yield_index = @stacktraces[view_file_index].scan(%r{\A(/[./\w]+):(\d+):in `[\w]+'\z}).flatten
|
84
84
|
view_yield_index = view_yield_index.to_i
|
85
|
-
# TODO: Compile views
|
86
85
|
File.open(view_file) do |f|
|
87
86
|
lines = f.readlines
|
88
87
|
loop do
|
@@ -90,7 +89,8 @@ module BulletmarkRepairer
|
|
90
89
|
|
91
90
|
view_yield_index -= 1
|
92
91
|
line = lines[view_yield_index]
|
93
|
-
|
92
|
+
token = line&.scan(/\b?(@[\w]+)\b?/)&.flatten&.last
|
93
|
+
@instance_variable_name = token if BulletmarkRepairer::Thread.instance_variable_name?(token)
|
94
94
|
end
|
95
95
|
end
|
96
96
|
@index = @instance_variable_name ? "#{view_file}:#{view_yield_index}" : nil
|
@@ -0,0 +1,14 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module BulletmarkRepairer
|
4
|
+
module ActionView
|
5
|
+
module Base
|
6
|
+
def initialize(*args)
|
7
|
+
super(*args)
|
8
|
+
@_assigns.each do |ivname, value|
|
9
|
+
BulletmarkRepairer::Thread.memorize_instance_variable_name(name: ivname, value: value)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -4,17 +4,17 @@ module BulletmarkRepairer
|
|
4
4
|
module ActiveRecord
|
5
5
|
module QueryMethod
|
6
6
|
def includes(*args)
|
7
|
-
Thread.
|
7
|
+
BulletmarkRepairer::Thread.memorize_associations(name: model.name, method_type: :includes, args: args)
|
8
8
|
super(args)
|
9
9
|
end
|
10
10
|
|
11
11
|
def eager_load(*args)
|
12
|
-
Thread.
|
12
|
+
BulletmarkRepairer::Thread.memorize_associations(name: model.name, method_type: :eager_load, args: args)
|
13
13
|
super(args)
|
14
14
|
end
|
15
15
|
|
16
16
|
def preload(*args)
|
17
|
-
Thread.
|
17
|
+
BulletmarkRepairer::Thread.memorize_associations(name: model.name, method_type: :preload, args: args)
|
18
18
|
super(args)
|
19
19
|
end
|
20
20
|
end
|
@@ -7,24 +7,28 @@ module BulletmarkRepairer
|
|
7
7
|
end
|
8
8
|
|
9
9
|
def call(env)
|
10
|
-
|
11
|
-
|
10
|
+
trace_point = TracePoint.trace(:return) do |tp|
|
11
|
+
BulletmarkRepairer::Thread.memorize_methods(
|
12
|
+
method_name: tp.method_id,
|
13
|
+
value: tp.return_value
|
14
|
+
)
|
12
15
|
end
|
13
16
|
@app.call(env)
|
14
17
|
ensure
|
18
|
+
trace_point.disable
|
15
19
|
begin
|
16
|
-
if Thread.current[:bullet_notification_collector].notifications_present?
|
20
|
+
if ::Thread.current[:bullet_notification_collector].notifications_present?
|
17
21
|
BulletmarkRepairer::Patcher.execute(
|
18
|
-
notifications: Thread.current[:bullet_notification_collector],
|
22
|
+
notifications: ::Thread.current[:bullet_notification_collector],
|
19
23
|
controller: env['action_dispatch.request.parameters']['controller'],
|
20
24
|
action: env['action_dispatch.request.parameters']['action'],
|
21
|
-
loaded_associations: Thread.current
|
25
|
+
loaded_associations: BulletmarkRepairer::Thread.current(:loaded_associations)
|
22
26
|
)
|
23
27
|
end
|
24
28
|
rescue StandardError => e
|
25
29
|
raise e if BulletmarkRepairer.config.debug?
|
26
30
|
end
|
27
|
-
Thread.
|
31
|
+
BulletmarkRepairer::Thread.clear
|
28
32
|
end
|
29
33
|
end
|
30
34
|
end
|
@@ -14,5 +14,9 @@ module BulletmarkRepairer
|
|
14
14
|
require 'bulletmark_repairer/monkey_patches/active_record/query_method'
|
15
15
|
::ActiveRecord::Relation.prepend(BulletmarkRepairer::ActiveRecord::QueryMethod)
|
16
16
|
end
|
17
|
+
ActiveSupport.on_load(:action_view) do
|
18
|
+
require 'bulletmark_repairer/monkey_patches/action_view/base'
|
19
|
+
::ActionView::Base.prepend(BulletmarkRepairer::ActionView::Base)
|
20
|
+
end
|
17
21
|
end
|
18
22
|
end
|
@@ -13,6 +13,14 @@ class RetryCorrector < Parser::TreeRewriter
|
|
13
13
|
@patched ||= false
|
14
14
|
end
|
15
15
|
|
16
|
+
def includes_token
|
17
|
+
@includes_token ||= ".includes(#{associations})"
|
18
|
+
end
|
19
|
+
|
20
|
+
def inserted?(parent_node)
|
21
|
+
parent_node.location.expression.source.include?(includes_token)
|
22
|
+
end
|
23
|
+
|
16
24
|
def insert_includes(node:)
|
17
25
|
return if patched?
|
18
26
|
return if !node.respond_to?(:children) || node.children.empty?
|
@@ -21,11 +29,25 @@ class RetryCorrector < Parser::TreeRewriter
|
|
21
29
|
if node.type == :begin
|
22
30
|
node.children.each { |child_node| insert_includes(node: child_node) }
|
23
31
|
else
|
24
|
-
|
25
|
-
|
32
|
+
node.children.each do |child_node|
|
33
|
+
execute_insert_includes(node: child_node, parent_node: node)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def execute_insert_includes(node:, parent_node:)
|
39
|
+
return unless node.respond_to?(:children)
|
40
|
+
return if patched?
|
26
41
|
|
27
|
-
|
28
|
-
|
42
|
+
node.children.each do |child_node|
|
43
|
+
if child_node.is_a?(Symbol)
|
44
|
+
if BulletmarkRepairer::Thread.correctable_method?(child_node) && !inserted?(parent_node)
|
45
|
+
insert_after node.location.expression, includes_token
|
46
|
+
@patched = true
|
47
|
+
end
|
48
|
+
else
|
49
|
+
execute_insert_includes(node: child_node, parent_node: node)
|
50
|
+
end
|
29
51
|
end
|
30
52
|
end
|
31
53
|
|
@@ -0,0 +1,58 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'rails'
|
4
|
+
|
5
|
+
module BulletmarkRepairer
|
6
|
+
class Thread
|
7
|
+
class << self
|
8
|
+
def current(key)
|
9
|
+
touch(key)
|
10
|
+
end
|
11
|
+
|
12
|
+
def memorize_associations(name:, method_type:, args:)
|
13
|
+
current(:loaded_associations)[name][method_type].add(args)
|
14
|
+
end
|
15
|
+
|
16
|
+
def memorize_instance_variable_name(name:, value:)
|
17
|
+
return unless value.is_a?(::ActiveRecord::Relation)
|
18
|
+
|
19
|
+
current(:loaded_instance_variables).add("@#{name}")
|
20
|
+
end
|
21
|
+
|
22
|
+
def instance_variable_name?(name)
|
23
|
+
current(:loaded_instance_variables).include?(name)
|
24
|
+
end
|
25
|
+
|
26
|
+
# TODO: Memorize methods with class
|
27
|
+
def memorize_methods(method_name:, value:)
|
28
|
+
return unless value.is_a?(::ActiveRecord::Associations::CollectionProxy) || value.is_a?(::ActiveRecord::Relation)
|
29
|
+
|
30
|
+
current(:loaded_methods).add(method_name)
|
31
|
+
end
|
32
|
+
|
33
|
+
def correctable_method?(method_name)
|
34
|
+
current(:loaded_methods).include?(method_name)
|
35
|
+
end
|
36
|
+
|
37
|
+
def clear
|
38
|
+
::Thread.current[:bulletmark_repairer] = nil
|
39
|
+
end
|
40
|
+
|
41
|
+
private
|
42
|
+
|
43
|
+
def touch(key)
|
44
|
+
::Thread.current[:bulletmark_repairer] ||= {}
|
45
|
+
case key
|
46
|
+
when :loaded_associations
|
47
|
+
::Thread.current[:bulletmark_repairer][:loaded_associations] ||= Hash.new do |hash, key|
|
48
|
+
hash[key] = { includes: Set.new, eager_load: Set.new, preload: Set.new }
|
49
|
+
end
|
50
|
+
when :loaded_instance_variables
|
51
|
+
::Thread.current[:bulletmark_repairer][:loaded_instance_variables] ||= Set.new
|
52
|
+
when :loaded_methods
|
53
|
+
::Thread.current[:bulletmark_repairer][:loaded_methods] ||= Set.new
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
data/lib/bulletmark_repairer.rb
CHANGED
@@ -9,6 +9,7 @@ require 'bulletmark_repairer/corrector_builder'
|
|
9
9
|
require 'bulletmark_repairer/loaded_associations'
|
10
10
|
require 'bulletmark_repairer/markers'
|
11
11
|
require 'bulletmark_repairer/patcher'
|
12
|
+
require 'bulletmark_repairer/thread'
|
12
13
|
|
13
14
|
module BulletmarkRepairer
|
14
15
|
class Error < StandardError; end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: bulletmark_repairer
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.7
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- makicamel
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-
|
11
|
+
date: 2023-11-21 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|
@@ -90,11 +90,13 @@ files:
|
|
90
90
|
- lib/bulletmark_repairer/corrector_builder.rb
|
91
91
|
- lib/bulletmark_repairer/loaded_associations.rb
|
92
92
|
- lib/bulletmark_repairer/markers.rb
|
93
|
+
- lib/bulletmark_repairer/monkey_patches/action_view/base.rb
|
93
94
|
- lib/bulletmark_repairer/monkey_patches/active_record/query_method.rb
|
94
95
|
- lib/bulletmark_repairer/patcher.rb
|
95
96
|
- lib/bulletmark_repairer/rack.rb
|
96
97
|
- lib/bulletmark_repairer/railtie.rb
|
97
98
|
- lib/bulletmark_repairer/retry_corrector.rb
|
99
|
+
- lib/bulletmark_repairer/thread.rb
|
98
100
|
- lib/bulletmark_repairer/version.rb
|
99
101
|
- sig/bulletmark_repairer.rbs
|
100
102
|
homepage: https://github.com/makicamel/bulletmark_repairer
|