order_cop 0.1.1 → 0.2.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 +4 -4
- data/Gemfile +1 -0
- data/Gemfile.lock +1 -1
- data/lib/order_cop/version.rb +1 -1
- data/lib/order_cop.rb +61 -53
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: e9db33624c2eb202e4a077391905aff8c3d2719ba36743ef86c169a3ebb44eab
|
|
4
|
+
data.tar.gz: 499e5fa4966beccfcfe5f8dde8db48bff9f9d364bddcc2618b70240e25f76cca
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: f883d3cd5e17aa8d612542585fe490bbcce29bfd239a039a738ebb22bcc55bf01ee07bcdd816ed650169cbc6b5c8ceeed5cb84530078c2571b8c7275bb502e66
|
|
7
|
+
data.tar.gz: 9b4a1e48a5de4e49068cb9223dbab2e224453e81a26577bc2b7877800d06a985f0012ae1cacc5800db5e8f7b58d83a0a44b33142f60f776afa503da64a4728fa
|
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
data/lib/order_cop/version.rb
CHANGED
data/lib/order_cop.rb
CHANGED
|
@@ -11,6 +11,42 @@ require "zeitwerk"
|
|
|
11
11
|
loader = Zeitwerk::Loader.for_gem
|
|
12
12
|
loader.setup
|
|
13
13
|
module OrderCop
|
|
14
|
+
class OrderCopConfig
|
|
15
|
+
def initialize
|
|
16
|
+
@enabled = true
|
|
17
|
+
@raise = true
|
|
18
|
+
@debug = false
|
|
19
|
+
@rails_logger = false
|
|
20
|
+
@whitelist_methods = %i[sum any? none? inspect method_missing not load_target reindex attachment attachments attributes_table with_current_arbre_element]
|
|
21
|
+
end
|
|
22
|
+
attr_accessor :enabled, :raise, :debug, :rails_logger, :whitelist_methods
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def self.config(**options, &block)
|
|
26
|
+
@config ||= OrderCopConfig.new
|
|
27
|
+
options.each do |key, value|
|
|
28
|
+
@config.send("#{key}=", value)
|
|
29
|
+
end
|
|
30
|
+
yield @config if block
|
|
31
|
+
@config
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def self.disable(&block)
|
|
35
|
+
old_enabled = @config.enabled
|
|
36
|
+
@config.enabled = false
|
|
37
|
+
yield
|
|
38
|
+
ensure
|
|
39
|
+
@config.enabled = old_enabled
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def self.disabled?
|
|
43
|
+
!@config.enabled
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def self.enabled?
|
|
47
|
+
@config.enabled
|
|
48
|
+
end
|
|
49
|
+
|
|
14
50
|
module OrderCopMixin
|
|
15
51
|
# patch all methods which iterate over the collection and return several records
|
|
16
52
|
# we don't patch `first` and `last`, take or others because they return a single record)
|
|
@@ -54,15 +90,29 @@ module OrderCop
|
|
|
54
90
|
|
|
55
91
|
private
|
|
56
92
|
|
|
57
|
-
def
|
|
58
|
-
|
|
59
|
-
level = 1.upto(binding.frame_count).find do |i|
|
|
93
|
+
def stack_is_whitelisted?
|
|
94
|
+
1.upto(binding.frame_count).each do |i|
|
|
60
95
|
lbinding = binding.of_caller(i)
|
|
61
96
|
lmethod = lbinding.eval("__method__")
|
|
62
97
|
next if lmethod.nil?
|
|
63
|
-
if OrderCop
|
|
64
|
-
|
|
98
|
+
puts "lmethod: #{lmethod}" if OrderCop.config.debug
|
|
99
|
+
if OrderCop.config.whitelist_methods.include?(lmethod)
|
|
100
|
+
puts "#{lmethod} is whitelisted, ignoring" if OrderCop.config.debug
|
|
101
|
+
return true
|
|
65
102
|
end
|
|
103
|
+
end
|
|
104
|
+
false
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
def detect_missing_order(method)
|
|
108
|
+
return if OrderCop.disabled?
|
|
109
|
+
puts "missing order, detect if allowed" if OrderCop.config.debug
|
|
110
|
+
puts "stack size: #{binding.frame_count}" if OrderCop.config.debug
|
|
111
|
+
|
|
112
|
+
return if stack_is_whitelisted?
|
|
113
|
+
|
|
114
|
+
level = 1.upto(binding.frame_count).find do |i|
|
|
115
|
+
lbinding = binding.of_caller(i)
|
|
66
116
|
location = lbinding.source_location[0]
|
|
67
117
|
location.include?(Rails.root.to_s) && !location.include?(Rails.root.join("config").to_s)
|
|
68
118
|
end
|
|
@@ -76,42 +126,22 @@ module OrderCop
|
|
|
76
126
|
msg = "Missing Order for :#{method}"
|
|
77
127
|
end
|
|
78
128
|
|
|
79
|
-
|
|
80
|
-
|
|
129
|
+
red = ->(msg) { ActiveSupport::LogSubscriber.new.send(:color, msg, :red) }
|
|
130
|
+
|
|
131
|
+
if OrderCop.config.rails_logger
|
|
132
|
+
Rails.logger.error red.call(msg)
|
|
81
133
|
caller.each do |line|
|
|
82
|
-
Rails.logger.error
|
|
134
|
+
Rails.logger.error red.call(" #{line}") if line.include?(Rails.root.to_s)
|
|
83
135
|
end
|
|
84
136
|
end
|
|
85
|
-
if OrderCop.raise
|
|
137
|
+
if OrderCop.config.raise
|
|
86
138
|
raise OrderCop::Error.new(msg)
|
|
87
139
|
end
|
|
88
140
|
end
|
|
89
|
-
|
|
90
|
-
def order_cop_red(msg)
|
|
91
|
-
ActiveSupport::LogSubscriber.new.send(:color, msg, :red)
|
|
92
|
-
end
|
|
93
141
|
end
|
|
94
142
|
|
|
95
143
|
class Error < StandardError; end
|
|
96
144
|
|
|
97
|
-
WHITELIST = %i[sum any? none? inspect method_missing not load_target reindex attachment attachments attributes_table with_current_arbre_element].freeze
|
|
98
|
-
|
|
99
|
-
def self.disable(&block)
|
|
100
|
-
old_enabled = @enabled
|
|
101
|
-
@enabled = false
|
|
102
|
-
yield
|
|
103
|
-
ensure
|
|
104
|
-
@enabled = old_enabled
|
|
105
|
-
end
|
|
106
|
-
|
|
107
|
-
def self.disabled?
|
|
108
|
-
@enabled == false
|
|
109
|
-
end
|
|
110
|
-
|
|
111
|
-
def self.enabled?
|
|
112
|
-
@enabled != false
|
|
113
|
-
end
|
|
114
|
-
|
|
115
145
|
def self.patch_active_record(app)
|
|
116
146
|
ActiveRecord::Base.descendants.each do |model|
|
|
117
147
|
model.const_get(:ActiveRecord_Associations_CollectionProxy).class_eval do
|
|
@@ -126,27 +156,6 @@ module OrderCop
|
|
|
126
156
|
end
|
|
127
157
|
end
|
|
128
158
|
|
|
129
|
-
def self.rails_logger?
|
|
130
|
-
config.rails_logger
|
|
131
|
-
end
|
|
132
|
-
|
|
133
|
-
def self.raise?
|
|
134
|
-
config.raise
|
|
135
|
-
end
|
|
136
|
-
|
|
137
|
-
def self.config(**options)
|
|
138
|
-
@config ||= OpenStruct.new(rails_logger: false, raise: true, enabled: true)
|
|
139
|
-
options.each do |k, v|
|
|
140
|
-
@config[k] = v
|
|
141
|
-
end
|
|
142
|
-
@enabled = @config.enabled
|
|
143
|
-
@config
|
|
144
|
-
end
|
|
145
|
-
|
|
146
|
-
def self.setup(**options)
|
|
147
|
-
config(**options)
|
|
148
|
-
end
|
|
149
|
-
|
|
150
159
|
def self.apply(app = Rails.application)
|
|
151
160
|
patch_active_record(app) if enabled?
|
|
152
161
|
end
|
|
@@ -169,4 +178,3 @@ end
|
|
|
169
178
|
ActiveSupport::Reloader.to_prepare do
|
|
170
179
|
OrderCop.apply(Rails.application)
|
|
171
180
|
end
|
|
172
|
-
# OrderCop.setup(rails_logger: true) unless Rails.env.production?
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: order_cop
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.2.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Gauthier Monserand
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2023-08-
|
|
11
|
+
date: 2023-08-19 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: rails
|