is_this_used 0.1.12 → 0.1.13

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: 2b45e5ae45262a6793a2d31dbc938dc1ca7dce14c41badab9f098281010c0fd7
4
- data.tar.gz: 83027360fc9f6ea7eb6f5209bf76e26f812acc1a6f017d25ae8c102e8dc384d5
3
+ metadata.gz: cce63d34e732bc62aaae3b0c3b6ec1dd2624a778db4f634a1a2cc111345c62dd
4
+ data.tar.gz: 80dfa1ff9f4689b3468b237674061a7a5dfc452c6e89d52c031b3e0d9c101c9e
5
5
  SHA512:
6
- metadata.gz: 7a563b281bf91261a8796ee3cf96ca7b93856f40e97db803aff7139bf554cfbf9fb9965bee06afa7e8b27f1571d14067aa6f9fbce087cb070dabeaad7c143e37
7
- data.tar.gz: 0116de239d46752d0240b6b76aadc56c7962f3e64b7e19f39080e7fa1a11eee73d9f7bd8a61287eb53b71d24604706f303529e0b6bd1d3a0941cc2719221ab78
6
+ metadata.gz: ec65d766721e3b41c649f557418ea9d9e1b1ca03b99610c2c1394508d1798f002560943ef7a5aadb55dcd05519346d79977cd764f6d70be53e463886ce883288
7
+ data.tar.gz: 4feb1afae406fc3dbec90584d8ee54dee4a1a4893e32d1a79b29c569c6d5c26b1f4d9be78f9635b195ec31aa2a517919da88499dece5099fe1798734299ca5e8
data/README.md CHANGED
@@ -40,6 +40,8 @@ actually occur.
40
40
 
41
41
  ## Usage
42
42
 
43
+ ### `is_this_used?`
44
+
43
45
  is_this_used is pretty simple. Let's say you have a class (or module) like this...
44
46
 
45
47
  ```ruby
@@ -75,7 +77,7 @@ in the `potential_crufts` table that looks like this:
75
77
 
76
78
  | id | owner_name | method_name | method_type | invocations | deleted_at | created_at | updated_at |
77
79
  | --- | ------------ | --------------- | --------------- | ----------- | ---------- | ------------------- | ------------------- |
78
- | 1 | SomeOldClass | some_old_method | instance_method | 0 | null | 2022-01-21 14:07:48 | 2022-01-21 14:07:48 |
80
+ | 1 | SomeOldClass | some_old_method | instance_method | 0 | null | 2022-01-21 14:07:48 | 2022-01-21 14:07:48 |
79
81
 
80
82
  This is easily accessed using the `IsThisUsed::PotentialCruft` model class.
81
83
 
@@ -102,7 +104,7 @@ So, having annotated the method, you can check this table after a while. If you
102
104
  you have a reasonably good hint that the method may not actually be used. Of course, you should consider that there are
103
105
  some processes that are not run frequently at all, so this gem isn't a panacea. Think before you delete!
104
106
 
105
- ### Tracking Stacks
107
+ #### Tracking Stacks
106
108
 
107
109
  In the case that a method _is_ actually invoked, the `invocations` value is incremented and a record is created in
108
110
  the `potential_cruft_stacks` table for each unique invocation stacktrace. This can be used to determine which methods
@@ -148,7 +150,7 @@ The `label` and `base_label` fields come from Ruby's `Thread::Backtrace::Locatio
148
150
  difference is, as the docs simply say this about `base_label`: "Usually same as label, without decoration". 🤷 Anyhow,
149
151
  it's there if you need it.
150
152
 
151
- ### Tracking Arguments
153
+ #### Tracking Arguments
152
154
 
153
155
  In addition to tracking stacks, you can track details about arguments provided to tracked methods. For example, let's say you have the following method:
154
156
 
@@ -196,8 +198,11 @@ The above would result in the following records in `potential_cruft_arguments` (
196
198
  | 1619ec6af47253461e87ebf1923a8a83 | ["color", "locality"] | 1 |
197
199
  | 88c8205498de97d4ef06b249006bb68b | ["status"] | 1 |
198
200
 
201
+ ### `is_any_of_this_stuff_used?`
199
202
 
203
+ Let's say you have a class and you're wondering what, if anything, in that class is used. You probably don't want to tag every single method in that class with `is_this_used?`. Instead, you can add `is_any_of_this_stuff_used?` as the last line in that class. When the class is loaded, is_this_used will identify all of the instance and class methods defined directly on the object itself and track each one of those, just as if you'd tagged them individually with `is_this_used?`.
200
204
 
205
+ The `is_any_of_this_stuff_used?` method does not accept any arguments and cannot be used to track arguments. However, you can use both `is_this_used?` and `is_any_of_this_stuff_used?` at the same time. If you want to track everything in a class, but track arguments for a specific method, simply tag that method with `is_this_used?` and specify the `track_arguments` argument. Be sure to place `is_any_of_this_stuff_used?` as the last line within the class. Now that one method will have its arguments tracked while the others will simply be tracked normally.
201
206
 
202
207
  ## Models
203
208
 
@@ -7,6 +7,10 @@ class CreatePotentialCruftArguments < ActiveRecord::Migration<%= migration_versi
7
7
  t.json :arguments, null: false
8
8
  t.integer :occurrences, null: false, index: true, default: 0
9
9
  t.timestamps
10
+
11
+ t.index %i[potential_cruft_id arguments_hash],
12
+ unique: true,
13
+ name: 'index_pca_on_potential_cruft_id_and_arguments_hash'
10
14
  end
11
15
  end
12
16
  end
@@ -7,6 +7,10 @@ class CreatePotentialCruftStacks < ActiveRecord::Migration<%= migration_version
7
7
  t.json :stack, null: false
8
8
  t.integer :occurrences, null: false, index: true, default: 0
9
9
  t.timestamps
10
+
11
+ t.index %i[potential_cruft_id stack_hash],
12
+ unique: true,
13
+ name: 'index_pcs_on_potential_cruft_id_and_stack_hash'
10
14
  end
11
15
  end
12
16
  end
@@ -11,7 +11,10 @@ class CreatePotentialCrufts < ActiveRecord::Migration<%= migration_version %>
11
11
 
12
12
  t.index :owner_name
13
13
  t.index :method_name
14
- t.index %i(owner_name method_name)
14
+ t.index %i[owner_name method_name]
15
+ t.index %i[owner_name method_name method_type],
16
+ unique: true,
17
+ name: 'index_pc_on_owner_name_and_method_name_and_method_type'
15
18
  end
16
19
  end
17
20
  end
@@ -21,18 +21,26 @@ module IsThisUsed
21
21
 
22
22
  potential_cruft_stack =
23
23
  PotentialCruftStack.find_by(
24
- potential_cruft: potential_cruft, stack_hash: stack_hash
24
+ stack_hash: stack_hash
25
25
  )
26
- potential_cruft_stack ||=
27
- PotentialCruftStack.new(
28
- potential_cruft: potential_cruft,
29
- stack_hash: stack_hash,
30
- stack: stack
31
- )
32
-
33
- potential_cruft_stack.occurrences += 1
34
26
 
35
- potential_cruft_stack.save
27
+ potential_cruft_stack ||= begin
28
+ PotentialCruftStack.create(
29
+ potential_cruft: potential_cruft,
30
+ stack_hash: stack_hash,
31
+ stack: stack
32
+ )
33
+ rescue ActiveRecord::RecordNotUnique
34
+ PotentialCruftStack.find_by(
35
+ stack_hash: stack_hash
36
+ )
37
+ end
38
+
39
+ potential_cruft_stack.with_lock do
40
+ potential_cruft_stack.reload
41
+ potential_cruft_stack.occurrences += 1
42
+ potential_cruft_stack.save!
43
+ end
36
44
  end
37
45
 
38
46
  def self.filtered_stack
@@ -55,18 +63,24 @@ module IsThisUsed
55
63
 
56
64
  potential_cruft_argument =
57
65
  PotentialCruftArgument.find_by(
58
- potential_cruft: potential_cruft, arguments_hash: arguments_hash
59
- )
60
- potential_cruft_argument ||=
61
- PotentialCruftArgument.new(
62
- potential_cruft: potential_cruft,
63
- arguments_hash: arguments_hash,
64
- arguments: arguments
66
+ arguments_hash: arguments_hash
65
67
  )
66
-
67
- potential_cruft_argument.occurrences += 1
68
-
69
- potential_cruft_argument.save
68
+ potential_cruft_argument ||= begin
69
+ PotentialCruftArgument.create(
70
+ potential_cruft: potential_cruft,
71
+ arguments_hash: arguments_hash,
72
+ arguments: arguments
73
+ )
74
+ rescue ActiveRecord::RecordNotUnique
75
+ PotentialCruftArgument.find_by(
76
+ arguments_hash: arguments_hash
77
+ )
78
+ end
79
+
80
+ potential_cruft_argument.with_lock do
81
+ potential_cruft_argument.occurrences += 1
82
+ potential_cruft_argument.save!
83
+ end
70
84
  end
71
85
  end
72
86
 
@@ -75,17 +89,23 @@ module IsThisUsed
75
89
  end
76
90
 
77
91
  module ClassMethods
92
+ def potentially_crufty_methods_being_tracked
93
+ @potentially_crufty_methods_being_tracked ||= []
94
+ end
95
+
78
96
  def is_this_used?(method_name, method_type: nil, track_arguments: false)
79
97
  IsThisUsed::Util::LogSuppressor.suppress_logging do
80
98
  method_type ||= determine_method_type(method_name)
99
+
100
+ tracked_method_identifier = "#{method_name}/#{method_type}"
101
+ return if potentially_crufty_methods_being_tracked.include?(tracked_method_identifier)
102
+
81
103
  target_method = target_method(method_name, method_type)
82
104
 
83
- potential_cruft =
84
- PotentialCruft.find_or_create_by(
85
- owner_name: self.name,
86
- method_name: method_name,
87
- method_type: method_type
88
- )
105
+ potential_cruft = create_or_find_potential_cruft(
106
+ method_name: method_name,
107
+ method_type: method_type
108
+ )
89
109
 
90
110
  potential_cruft.update(deleted_at: nil) if potential_cruft.deleted_at.present?
91
111
 
@@ -106,6 +126,8 @@ module IsThisUsed
106
126
  target_method.call(*args)
107
127
  end
108
128
  end
129
+
130
+ potentially_crufty_methods_being_tracked << tracked_method_identifier
109
131
  end
110
132
  rescue ActiveRecord::StatementInvalid => e
111
133
  raise unless e.cause.present? && e.cause.instance_of?(Mysql2::Error)
@@ -123,6 +145,15 @@ module IsThisUsed
123
145
  )
124
146
  end
125
147
 
148
+ def is_any_of_this_stuff_used?
149
+ own_instance_methods.each do |instance_method|
150
+ is_this_used?(instance_method, method_type: INSTANCE_METHOD)
151
+ end
152
+ own_class_methods.each do |class_method|
153
+ is_this_used?(class_method, method_type: CLASS_METHOD)
154
+ end
155
+ end
156
+
126
157
  def target_method(method_name, method_type)
127
158
  case method_type
128
159
  when INSTANCE_METHOD
@@ -133,12 +164,8 @@ module IsThisUsed
133
164
  end
134
165
 
135
166
  def determine_method_type(method_name)
136
- is_instance_method =
137
- (self.instance_methods + self.private_instance_methods).include?(
138
- method_name
139
- )
140
- is_class_method =
141
- (self.methods + self.private_methods).include?(method_name)
167
+ is_instance_method = all_instance_methods(self).include?(method_name)
168
+ is_class_method = all_class_methods(self).include?(method_name)
142
169
 
143
170
  if is_instance_method && is_class_method
144
171
  raise AmbiguousMethodType.new(self.name, method_name)
@@ -150,6 +177,47 @@ module IsThisUsed
150
177
  raise NoSuchMethod.new(self.name, method_name)
151
178
  end
152
179
  end
180
+
181
+ def all_instance_methods(object)
182
+ object.instance_methods + object.private_instance_methods
183
+ end
184
+
185
+ def all_class_methods(object)
186
+ object.methods + object.private_methods
187
+ end
188
+
189
+ def own_instance_methods
190
+ ancestors_instance_methods =
191
+ (self.ancestors - [self])
192
+ .map {|ancestor| all_instance_methods(ancestor)}
193
+ .flatten
194
+ .uniq
195
+
196
+ all_instance_methods(self) - ancestors_instance_methods
197
+ end
198
+
199
+ def own_class_methods
200
+ ancestors_class_methods =
201
+ (self.ancestors - [self])
202
+ .map {|ancestor| all_class_methods(ancestor)}
203
+ .flatten
204
+ .uniq
205
+
206
+ all_class_methods(self) -
207
+ all_instance_methods(IsThisUsed::CruftTracker::ClassMethods) -
208
+ ancestors_class_methods
209
+ end
210
+
211
+ def create_or_find_potential_cruft(method_name:, method_type:)
212
+ PotentialCruft.find_or_create_by(owner_name: self.name,
213
+ method_name: method_name,
214
+ method_type: method_type)
215
+
216
+ rescue ActiveRecord::RecordNotUnique
217
+ PotentialCruft.find_by(owner_name: self.name,
218
+ method_name: method_name,
219
+ method_type: method_type)
220
+ end
153
221
  end
154
222
  end
155
223
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module IsThisUsed
4
- VERSION = '0.1.12'
4
+ VERSION = '0.1.13'
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: is_this_used
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.12
4
+ version: 0.1.13
5
5
  platform: ruby
6
6
  authors:
7
7
  - Doug Hughes
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2022-03-10 00:00:00.000000000 Z
11
+ date: 2022-03-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord