is_this_used 0.1.11 → 0.1.14
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +8 -3
- data/gemfiles/rails_5.2.gemfile.lock +1 -1
- data/gemfiles/rails_6.0.gemfile.lock +1 -1
- data/gemfiles/rails_6.1.gemfile.lock +1 -1
- data/lib/generators/is_this_used/templates/create_potential_cruft_arguments.rb.erb +4 -0
- data/lib/generators/is_this_used/templates/create_potential_cruft_stacks.rb.erb +4 -0
- data/lib/generators/is_this_used/templates/create_potential_crufts.rb.erb +4 -1
- data/lib/is_this_used/cruft_tracker.rb +106 -34
- data/lib/is_this_used/util/log_suppressor.rb +1 -0
- data/lib/is_this_used/version.rb +1 -1
- metadata +5 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9ee3077f21a391a8be63d34431215b2a230b03155cd50ae99466079f796ef7de
|
4
|
+
data.tar.gz: 8df3bc2329e894929843ecc61481cccd8b357ca09fa11cc63f917ade6af7dcb0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1417d2134db8d73a852036164e7b71cef3ac3cdb4888162abe111734bf28a5e20b1eb13d4206ac5ccd302fa1b680b25a09a15e201075147ceb5727320095e9d8
|
7
|
+
data.tar.gz: ca93f1e66d50095f4e21d7a968c6769a05122259259dcdcac4c8295093ac987e1f736698217f9cb032789b31a5000e620473a296d2773d8a439f92a011f0059b
|
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
|
-
|
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
|
-
|
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
|
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
|
-
|
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
|
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
|
-
|
66
|
+
arguments_hash: arguments_hash
|
59
67
|
)
|
60
|
-
potential_cruft_argument ||=
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
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
|
-
|
85
|
-
|
86
|
-
|
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,19 +126,34 @@ 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
|
-
rescue ActiveRecord::StatementInvalid
|
132
|
+
rescue ActiveRecord::StatementInvalid => e
|
111
133
|
raise unless e.cause.present? && e.cause.instance_of?(Mysql2::Error)
|
112
134
|
|
113
135
|
Rails.logger.warn(
|
114
136
|
'There was an error recording potential cruft. Does the potential_crufts table exist? Have migrations been run?'
|
115
137
|
)
|
138
|
+
rescue NoMethodError
|
139
|
+
Rails.logger.warn(
|
140
|
+
'There was an error recording potential cruft. Have migrations been run?'
|
141
|
+
)
|
116
142
|
rescue Mysql2::Error::ConnectionError, ActiveRecord::ConnectionNotEstablished
|
117
143
|
Rails.logger.warn(
|
118
144
|
'There was an error recording potential cruft due to being unable to connect to the database. This may be a non-issue in cases where the database is intentionally not available.'
|
119
145
|
)
|
120
146
|
end
|
121
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
|
+
|
122
157
|
def target_method(method_name, method_type)
|
123
158
|
case method_type
|
124
159
|
when INSTANCE_METHOD
|
@@ -129,12 +164,8 @@ module IsThisUsed
|
|
129
164
|
end
|
130
165
|
|
131
166
|
def determine_method_type(method_name)
|
132
|
-
is_instance_method =
|
133
|
-
|
134
|
-
method_name
|
135
|
-
)
|
136
|
-
is_class_method =
|
137
|
-
(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)
|
138
169
|
|
139
170
|
if is_instance_method && is_class_method
|
140
171
|
raise AmbiguousMethodType.new(self.name, method_name)
|
@@ -146,6 +177,47 @@ module IsThisUsed
|
|
146
177
|
raise NoSuchMethod.new(self.name, method_name)
|
147
178
|
end
|
148
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
|
149
221
|
end
|
150
222
|
end
|
151
223
|
|
data/lib/is_this_used/version.rb
CHANGED
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.
|
4
|
+
version: 0.1.14
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Doug Hughes
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-
|
11
|
+
date: 2022-04-18 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|
@@ -253,7 +253,7 @@ homepage: https://github.com/dhughes/is_this_used
|
|
253
253
|
licenses:
|
254
254
|
- MIT
|
255
255
|
metadata: {}
|
256
|
-
post_install_message:
|
256
|
+
post_install_message:
|
257
257
|
rdoc_options: []
|
258
258
|
require_paths:
|
259
259
|
- lib
|
@@ -269,7 +269,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
269
269
|
version: '0'
|
270
270
|
requirements: []
|
271
271
|
rubygems_version: 3.0.3.1
|
272
|
-
signing_key:
|
272
|
+
signing_key:
|
273
273
|
specification_version: 4
|
274
274
|
summary: Provides a system to track method usage somewhat unobtrusively.
|
275
275
|
test_files: []
|