leftovers 0.4.0 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (48) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +22 -0
  3. data/README.md +37 -4
  4. data/docs/Configuration.md +75 -11
  5. data/leftovers.gemspec +1 -0
  6. data/lib/config/actioncable.yml +4 -0
  7. data/lib/config/actionmailer.yml +22 -0
  8. data/lib/config/actionpack.yml +190 -0
  9. data/lib/config/actionview.yml +64 -0
  10. data/lib/config/activejob.yml +29 -0
  11. data/lib/config/activemodel.yml +74 -0
  12. data/lib/config/activerecord.yml +179 -0
  13. data/lib/config/activesupport.yml +98 -0
  14. data/lib/config/haml.yml +2 -0
  15. data/lib/config/rails.yml +11 -450
  16. data/lib/config/ruby.yml +6 -0
  17. data/lib/leftovers/ast/node.rb +18 -4
  18. data/lib/leftovers/cli.rb +13 -4
  19. data/lib/leftovers/collector.rb +2 -1
  20. data/lib/leftovers/config.rb +12 -0
  21. data/lib/leftovers/config_validator/schema_hash.rb +57 -11
  22. data/lib/leftovers/definition.rb +6 -6
  23. data/lib/leftovers/definition_node.rb +36 -0
  24. data/lib/leftovers/definition_set.rb +15 -8
  25. data/lib/leftovers/file.rb +2 -3
  26. data/lib/leftovers/file_collector.rb +10 -5
  27. data/lib/leftovers/matcher_builders/node.rb +2 -0
  28. data/lib/leftovers/matcher_builders/node_has_argument.rb +11 -7
  29. data/lib/leftovers/matcher_builders/node_has_keyword_argument.rb +14 -10
  30. data/lib/leftovers/matcher_builders/node_has_positional_argument.rb +17 -13
  31. data/lib/leftovers/matcher_builders/node_has_receiver.rb +15 -0
  32. data/lib/leftovers/matcher_builders/node_type.rb +7 -6
  33. data/lib/leftovers/matcher_builders/node_value.rb +42 -0
  34. data/lib/leftovers/matcher_builders.rb +3 -2
  35. data/lib/leftovers/matchers/node_has_any_positional_argument_with_value.rb +4 -1
  36. data/lib/leftovers/matchers/node_has_positional_argument.rb +0 -4
  37. data/lib/leftovers/matchers/node_has_receiver.rb +20 -0
  38. data/lib/leftovers/matchers/predicate.rb +19 -0
  39. data/lib/leftovers/matchers.rb +2 -0
  40. data/lib/leftovers/merged_config.rb +28 -1
  41. data/lib/leftovers/reporter.rb +56 -4
  42. data/lib/leftovers/todo_reporter.rb +127 -0
  43. data/lib/leftovers/value_processors/each_for_definition_set.rb +2 -6
  44. data/lib/leftovers/value_processors/return_definition.rb +5 -3
  45. data/lib/leftovers/version.rb +1 -1
  46. data/lib/leftovers.rb +94 -96
  47. metadata +31 -5
  48. data/lib/leftovers/matcher_builders/argument_node_value.rb +0 -21
data/lib/config/rails.yml CHANGED
@@ -1,457 +1,18 @@
1
-
2
- exclude_paths:
3
- - db/migrate/*
4
- include_paths:
5
- - '*.rjs'
6
- - '*.rhtml'
7
- requires:
8
- - 'active_support/core_ext/string'
9
- - 'active_support/inflections'
10
- - './config/initializers/inflections'
11
-
12
1
  # THIS IS INCOMPLETE (you can help by expanding it)
13
2
  # rails is _really complicated_ and has a lot of magic which calls methods for you.
14
3
  # some is currently impossible to handle (with_options).
15
4
  # Some is just corners of rails I haven't hit yet.
5
+ gems:
6
+ - actioncable
7
+ - actionmailer
8
+ - actionpack
9
+ - actionview
10
+ - activejob
11
+ - activemodel
12
+ - activerecord
13
+ - activesupport
14
+
16
15
  keep:
17
- - ClassMethods # ActiveSupport::Concern
18
- - process_action # ActiveSupport::LogSubscriber
19
- - validate_each # ActiveModel::EachValidator
20
- - format_message # ActiveSupport::Logger
21
- - ssl_configured? # ApplicationController
22
- - default_url_options # called by url_for
16
+ - default_url_options # called by url_for, unsure what gem does
23
17
  - APP_PATH
24
18
  - APP_ROOT
25
- - has_suffix: Helper
26
- path: /app/helpers
27
- - has_suffix: Preview
28
- path: '**/mailers/previews/**/*_preview.rb'
29
-
30
- dynamic:
31
- - names:
32
- - after_initialize
33
- - after_find
34
- - after_touch
35
- - before_validation
36
- - after_validation
37
- - before_save
38
- - around_save
39
- - after_save
40
- - before_create
41
- - around_create
42
- - after_create
43
- - before_update
44
- - around_update
45
- - after_update
46
- - before_destroy
47
- - around_destroy
48
- - after_destroy
49
- - after_commit
50
- - after_rollback
51
- - after_create_commit
52
- - after_update_commit
53
- - after_destroy_commit
54
- - after_save_commit
55
- calls:
56
- - arguments: 0
57
- - arguments: [if, unless]
58
- nested:
59
- arguments: '*'
60
- - name:
61
- - after_action
62
- - append_after_action
63
- - append_around_action
64
- - append_before_action
65
- - around_action
66
- - before_action
67
- - prepend_after_action
68
- - prepend_around_action
69
- - prepend_before_action
70
- - skip_before_action
71
- - skip_after_action
72
- - skip_around_action
73
- - validates_associated
74
- calls:
75
- - arguments: ['*', if, unless]
76
- - name: validates
77
- calls:
78
- - arguments:
79
- - '*'
80
- - within
81
- - inclusion
82
- - scope
83
- - if
84
- - unless
85
- - arguments: inclusion
86
- nested:
87
- arguments: 'in'
88
- - keywords:
89
- unless: [if, unless]
90
- camelize: true
91
- add_suffix: Validator
92
- split: '::'
93
- - names:
94
- - validate
95
- - validate_associated
96
- calls:
97
- - arguments: ['*', if, unless]
98
- - name:
99
- - check_box
100
- - date_select
101
- - datetime_select
102
- - file_field
103
- - hidden_field
104
- - label
105
- - radio_button
106
- - select
107
- - time_select
108
- - time_zone_select
109
- - color_field
110
- - date_field
111
- - datetime_field
112
- - datetime_local_field
113
- - email_field
114
- - month_field
115
- - number_field
116
- - password_field
117
- - phone_field
118
- - range_field
119
- - search_field
120
- - telephone_field
121
- - text_area
122
- - text_field
123
- - time_field
124
- - url_field
125
- - week_field
126
- calls:
127
- - arguments: [0,1] # 0: with a receiver, 1: with no receiver
128
- - arguments: [0,1]
129
- add_suffix: '='
130
- - name: fields_for
131
- calls:
132
- argument: 1
133
- add_suffix: _attributes
134
- - name: options_from_collection_for_select
135
- calls:
136
- - arguments: [1,2]
137
- - name:
138
- - collection_select
139
- - collection_check_boxes
140
- - collection_radio_buttons
141
- calls:
142
- - argument: 1
143
- add_suffix: '='
144
- - arguments: [3,4]
145
- - name: grouped_collection_select
146
- calls:
147
- - argument: 1
148
- add_suffix: '='
149
- - arguments: [3,4,5,6]
150
- - name: option_groups_from_collection_for_select
151
- calls:
152
- - arguments: [0,1,2,3]
153
- - name: scope
154
- path: /app/models
155
- defines:
156
- argument: 0 # ar
157
- - name: scope
158
- path: /config/routes*
159
- calls:
160
- argument: module # routes
161
- camelize: true
162
- split: '::'
163
- - name: namespace
164
- calls:
165
- - argument: 0
166
- camelize: true
167
- split: '::'
168
- - name:
169
- - attribute
170
- - alias_attribute
171
- path: app/models/*
172
- defines:
173
- argument: 0
174
- transforms:
175
- - original
176
- - add_suffix: '?'
177
- - add_suffix: '='
178
- - name: alias_attribute
179
- calls:
180
- - argument: 1
181
- - argument: 1
182
- add_suffix: '?'
183
- - argument: 1
184
- add_suffix: '='
185
- - name:
186
- - has_one
187
- - belongs_to
188
- unless:
189
- has_argument: class_name
190
- calls:
191
- argument: 0
192
- camelize: true
193
- split: '::'
194
-
195
- - name:
196
- - has_many
197
- - has_and_belongs_to_many
198
- unless:
199
- has_argument: class_name
200
- calls:
201
- - argument: 0
202
- camelize: true
203
- singularize: true
204
- split: '::'
205
- - name:
206
- - has_many
207
- - has_and_belongs_to_many
208
- defines:
209
- - argument: 0
210
- transforms:
211
- - original
212
- - add_suffix: '='
213
- - singularize: true
214
- add_suffix: _ids
215
- - singularize: true
216
- add_suffix: _ids=
217
- - name:
218
- - has_many
219
- - has_one
220
- - has_and_belongs_to_many
221
- calls:
222
- argument:
223
- - as
224
- - name:
225
- - has_one
226
- - has_many
227
- calls:
228
- - argument:
229
- - source_type
230
- - source
231
- - through
232
- - name:
233
- - has_one
234
- - belongs_to
235
- defines:
236
- - argument: 0
237
- transforms:
238
- - original
239
- - add_suffix: '='
240
- - add_prefix: build_
241
- - add_prefix: create_
242
- - add_prefix: create_
243
- add_suffix: '!'
244
- - add_prefix: reload
245
- - name: belongs_to
246
- unless:
247
- has_argument:
248
- at: optional
249
- has_value: true
250
- calls:
251
- argument: 0
252
-
253
- - name:
254
- - has_one
255
- - has_many
256
- - belongs_to
257
- - has_and_belongs_to_many
258
- calls:
259
- - argument: class_name
260
- split: '::'
261
- - argument: inverse_of
262
- - argument: touch
263
- add_suffix: '='
264
- - name:
265
- - has_one
266
- - has_many
267
- - belongs_to
268
- - has_and_belongs_to_many
269
- has_argument:
270
- at: [dependent, inverse_of, touch, validate]
271
- unless:
272
- has_value: false
273
- calls:
274
- argument: 0
275
-
276
- - name:
277
- - rescue_from
278
- calls:
279
- - argument: with
280
- - name:
281
- - match
282
- - delete
283
- - get
284
- - patch
285
- - post
286
- - put
287
- - root
288
- calls:
289
- - arguments: [0, action]
290
- - argument: '**'
291
- delete_before: '#'
292
- - argument: '**'
293
- delete_after: '#'
294
- camelize: true
295
- add_suffix: Controller
296
- split: '::'
297
- - name: delegate
298
- has_argument:
299
- at: prefix
300
- has_value: true
301
- defines:
302
- - argument: '*'
303
- add_prefix:
304
- argument: to
305
- add_suffix: '_'
306
- calls:
307
- - argument: to
308
- - argument: '*'
309
- - name: delegate
310
- has_argument:
311
- at: prefix
312
- has_value_type: [String, Symbol]
313
- defines:
314
- - argument: '*'
315
- add_prefix:
316
- argument: prefix
317
- add_suffix: '_'
318
- calls:
319
- - argument: to
320
- - argument: '*'
321
- - name: delegate
322
- unless:
323
- has_argument:
324
- - at: prefix
325
- has_value: true
326
- - at: prefix
327
- has_value_type: [String, Symbol]
328
- calls:
329
- - argument: to
330
- - name:
331
- - resource
332
- - resources
333
- calls:
334
- - argument: only
335
- - argument: controller
336
- camelize: true
337
- add_suffix: Controller
338
- split: '::'
339
- - name:
340
- - resources
341
- - controller
342
- - namespace
343
- calls:
344
- - argument: 0
345
- camelize: true
346
- add_suffix: Controller
347
- split: '::'
348
- - name: accepts_nested_attributes_for
349
- defines:
350
- argument: '*'
351
- transforms:
352
- - add_suffix: _attributes
353
- - add_suffix: _attributes=
354
- calls:
355
- argument: reject_if
356
- - name: resource
357
- calls:
358
- - argument: 0
359
- camelize: true
360
- pluralize: true
361
- add_suffix: Controller
362
- split: '::'
363
- - name:
364
- - new
365
- - create
366
- - create!
367
- - update
368
- - update!
369
- - assign_attributes
370
- calls:
371
- keyword: '**'
372
- add_suffix: '='
373
- - name: permit
374
- calls:
375
- arguments: ['*', '**']
376
- keywords: '**'
377
- add_suffix: "="
378
- recursive: true
379
- - name: layout
380
- calls:
381
- argument: 0
382
- - name:
383
- - includes
384
- - preload
385
- - eager_load
386
- - joins
387
- - left_joins
388
- - left_outer_joins
389
- calls:
390
- arguments: ['*', '**']
391
- keywords: '**'
392
- - name:
393
- - string
394
- - text
395
- - integer
396
- - bigint
397
- - float
398
- - decimal
399
- - numeric
400
- - datetime
401
- - time
402
- - date
403
- - binary
404
- - boolean
405
- path: /db/schema.rb
406
- calls:
407
- argument: 0
408
- transforms:
409
- - original
410
- - add_suffix: '='
411
- - add_suffix: '?'
412
- - name:
413
- - cattr_accessor
414
- - mattr_accessor
415
- defines:
416
- - argument: '*'
417
- - argument: '*'
418
- add_suffix: '='
419
- calls:
420
- - argument: '*'
421
- add_prefix: '@'
422
- - name:
423
- - cattr_reader
424
- - mattr_reader
425
- defines:
426
- - argument: '*'
427
- calls:
428
- - argument: '*'
429
- add_prefix: '@'
430
- - name:
431
- - cattr_writer
432
- - mattr_writer
433
- defines:
434
- - argument: '*'
435
- add_suffix: '='
436
-
437
- - name:
438
- - thread_cattr_accessor
439
- - thread_mattr_accessor
440
- defines:
441
- - argument: '*'
442
- - argument: '*'
443
- add_suffix: '='
444
- - name:
445
- - thread_cattr_reader
446
- - thread_mattr_reader
447
- defines:
448
- argument: '*'
449
- - name:
450
- - thread_cattr_writer
451
- - thread_mattr_writer
452
- defines:
453
- argument: '*'
454
- add_suffix: '='
455
- - name: delegate_missing_to
456
- calls:
457
- argument: 0
data/lib/config/ruby.yml CHANGED
@@ -14,6 +14,12 @@ test_paths:
14
14
  - /tests/
15
15
  - /test/
16
16
 
17
+ erb_paths:
18
+ - '*.erb'
19
+
20
+ haml_paths:
21
+ - '*.haml'
22
+
17
23
  keep:
18
24
  - initialize # called by new
19
25
  - inspect # called by repl, to_s
@@ -25,12 +25,12 @@ module Leftovers
25
25
  @memo[:path] ||= loc.expression.source_buffer.name.to_s
26
26
  end
27
27
 
28
- def test?
29
- @memo[:test]
28
+ def test_line?
29
+ @memo[:test_line]
30
30
  end
31
31
 
32
- def test=(value)
33
- @memo[:test] = value
32
+ def test_line=(value)
33
+ @memo[:test_line] = value
34
34
  end
35
35
 
36
36
  def keep_line=(value)
@@ -78,6 +78,13 @@ module Leftovers
78
78
  type == :str || type == :sym
79
79
  end
80
80
 
81
+ def proc?
82
+ return unless type == :block
83
+
84
+ name = first.name
85
+ name == :lambda || name == :proc
86
+ end
87
+
81
88
  def arguments
82
89
  @memo.fetch(:arguments) do
83
90
  @memo[:arguments] = case type
@@ -106,6 +113,13 @@ module Leftovers
106
113
  end
107
114
  end
108
115
 
116
+ def receiver
117
+ case type
118
+ when :const, :csend, :send
119
+ first
120
+ end
121
+ end
122
+
109
123
  def unwrap_freeze
110
124
  return self unless type == :send && name == :freeze
111
125
 
data/lib/leftovers/cli.rb CHANGED
@@ -28,20 +28,29 @@ module Leftovers
28
28
  Leftovers.progress = true
29
29
 
30
30
  opts.banner = 'Usage: leftovers [options]'
31
+
31
32
  opts.on('--[no-]parallel', 'Run in parallel or not, default --parallel') do |p|
32
33
  Leftovers.parallel = p
33
34
  end
35
+
34
36
  opts.on('--[no-]progress', 'Show progress counts or not, default --progress') do |p|
35
37
  Leftovers.progress = p
36
38
  end
37
- opts.on('-v', '--version', 'Returns the current version') do
38
- stdout.puts(Leftovers::VERSION)
39
- Leftovers.exit
40
- end
39
+
41
40
  opts.on('--dry-run', 'Output files that will be looked at') do
42
41
  Leftovers::FileList.new.each { |f| stdout.puts f.relative_path }
43
42
  Leftovers.exit
44
43
  end
44
+
45
+ opts.on('--write-todo', 'Outputs the unused items in a todo file to gradually fix') do
46
+ Leftovers.reporter = Leftovers::TodoReporter.new
47
+ end
48
+
49
+ opts.on('-v', '--version', 'Returns the current version') do
50
+ stdout.puts(Leftovers::VERSION)
51
+ Leftovers.exit
52
+ end
53
+
45
54
  opts.on('-h', '--help', 'Shows this message') do
46
55
  stdout.puts(opts.help)
47
56
  Leftovers.exit
@@ -18,6 +18,7 @@ module Leftovers
18
18
  end
19
19
 
20
20
  def collect
21
+ Leftovers.reporter.prepare
21
22
  collect_file_list(Leftovers::FileList.new)
22
23
  print_progress
23
24
  Leftovers.newline
@@ -46,7 +47,7 @@ module Leftovers
46
47
  )
47
48
  end
48
49
 
49
- def finish_file(_, _, result)
50
+ def finish_file(_item, _index, result)
50
51
  @count += 1
51
52
  @count_calls += result[:calls].length
52
53
  @count_definitions += result[:definitions].length
@@ -32,6 +32,14 @@ module Leftovers
32
32
  @test_paths ||= Array(yaml[:test_paths])
33
33
  end
34
34
 
35
+ def haml_paths
36
+ @haml_paths ||= Array(yaml[:haml_paths])
37
+ end
38
+
39
+ def erb_paths
40
+ @erb_paths ||= Array(yaml[:erb_paths])
41
+ end
42
+
35
43
  def dynamic
36
44
  @dynamic ||= ::Leftovers::ProcessorBuilders::Dynamic.build(yaml[:dynamic])
37
45
  end
@@ -40,6 +48,10 @@ module Leftovers
40
48
  @keep ||= ::Leftovers::MatcherBuilders::Node.build(yaml[:keep])
41
49
  end
42
50
 
51
+ def test_only
52
+ @test_only ||= ::Leftovers::MatcherBuilders::Node.build(yaml[:test_only])
53
+ end
54
+
43
55
  def requires
44
56
  @requires ||= Array(yaml[:requires])
45
57
  end