order_cop 0.1.1 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: eec6b83744b3873a01b1e5bbc3babf32c5d7a0ba76608b0aeacdd91094263eb2
4
- data.tar.gz: 3c2a4a792e2670544a4cd327ee094aab10f8212a3017cb937464ee3e3cea0dec
3
+ metadata.gz: e9db33624c2eb202e4a077391905aff8c3d2719ba36743ef86c169a3ebb44eab
4
+ data.tar.gz: 499e5fa4966beccfcfe5f8dde8db48bff9f9d364bddcc2618b70240e25f76cca
5
5
  SHA512:
6
- metadata.gz: f3e2281df0bbbc4ed5e17a9b2fb671b91af40c016fde050a6bb23d2969feee877b62c720255f49de9544756472692fb9df4fa8d957ff97540821263a31693d4b
7
- data.tar.gz: 3247b3dc2bd877226cd03437acb5cac3bf66712d7a7bfdc5d17357a41460dcf5783e265667394c1df0055958be2c7a3bcfa18cc534127761eb20dedf59a308d3
6
+ metadata.gz: f883d3cd5e17aa8d612542585fe490bbcce29bfd239a039a738ebb22bcc55bf01ee07bcdd816ed650169cbc6b5c8ceeed5cb84530078c2571b8c7275bb502e66
7
+ data.tar.gz: 9b4a1e48a5de4e49068cb9223dbab2e224453e81a26577bc2b7877800d06a985f0012ae1cacc5800db5e8f7b58d83a0a44b33142f60f776afa503da64a4728fa
data/Gemfile CHANGED
@@ -12,4 +12,5 @@ gem "rspec", "~> 3.0"
12
12
  gem "standard", "~> 1.3"
13
13
 
14
14
  gem "rails", "~> 7.0.0"
15
+
15
16
  gem "sqlite3"
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- order_cop (0.1.0)
4
+ order_cop (0.2.0)
5
5
  binding_of_caller (~> 1.0)
6
6
  rails (~> 7.0)
7
7
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module OrderCop
4
- VERSION = "0.1.1"
4
+ VERSION = "0.2.0"
5
5
  end
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 detect_missing_order(method)
58
- return if OrderCop.disabled?
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::WHITELIST.include?(lmethod)
64
- return nil
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
- if OrderCop.rails_logger?
80
- Rails.logger.error order_cop_red("Missing order for #{method}")
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 order_cop_red(" #{line}") if line.include?(Rails.root.to_s)
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.1.1
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-16 00:00:00.000000000 Z
11
+ date: 2023-08-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails