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 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