leftovers 0.4.1 → 0.5.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (44) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +29 -0
  3. data/README.md +30 -0
  4. data/docs/Configuration.md +46 -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 +14 -0
  18. data/lib/leftovers/cli.rb +13 -4
  19. data/lib/leftovers/collector.rb +2 -1
  20. data/lib/leftovers/config.rb +8 -0
  21. data/lib/leftovers/config_validator/schema_hash.rb +50 -5
  22. data/lib/leftovers/definition.rb +4 -4
  23. data/lib/leftovers/erb.rb +2 -2
  24. data/lib/leftovers/file.rb +2 -3
  25. data/lib/leftovers/matcher_builders/node.rb +2 -0
  26. data/lib/leftovers/matcher_builders/node_has_argument.rb +11 -7
  27. data/lib/leftovers/matcher_builders/node_has_keyword_argument.rb +14 -10
  28. data/lib/leftovers/matcher_builders/node_has_positional_argument.rb +17 -13
  29. data/lib/leftovers/matcher_builders/node_has_receiver.rb +15 -0
  30. data/lib/leftovers/matcher_builders/node_type.rb +7 -6
  31. data/lib/leftovers/matcher_builders/node_value.rb +50 -0
  32. data/lib/leftovers/matcher_builders.rb +3 -2
  33. data/lib/leftovers/matchers/node_has_any_positional_argument_with_value.rb +4 -1
  34. data/lib/leftovers/matchers/node_has_positional_argument.rb +0 -4
  35. data/lib/leftovers/matchers/node_has_receiver.rb +20 -0
  36. data/lib/leftovers/matchers/predicate.rb +19 -0
  37. data/lib/leftovers/matchers.rb +2 -0
  38. data/lib/leftovers/merged_config.rb +24 -1
  39. data/lib/leftovers/reporter.rb +56 -4
  40. data/lib/leftovers/todo_reporter.rb +127 -0
  41. data/lib/leftovers/version.rb +1 -1
  42. data/lib/leftovers.rb +93 -96
  43. metadata +31 -4
  44. data/lib/leftovers/matcher_builders/argument_node_value.rb +0 -21
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA256:
3
- metadata.gz: a3fb0707b239e6e7581c2997969483c72b3ff272895173828fc3434c08de165a
4
- data.tar.gz: aadfba4e9fc93b110599c8e2bd66f723efbce39cabf4deda036d904358cfa131
2
+ SHA1:
3
+ metadata.gz: 03a9797868cc444642bc0d475de4bd067a344891
4
+ data.tar.gz: fa5961bbcbb420c1a4a1159215e5df64da163b71
5
5
  SHA512:
6
- metadata.gz: 129fe2d42ec0f47d9f76105c1d53f0209133864d77688db231cb9fbc3c5ad3e6ea3ea8bdd95b1902b480b8a7e78709f2c197b261e1132ae0ce3cddc618e39899
7
- data.tar.gz: 1d01550bdf1762344c2744d21f01c1590b928a751439714e5ad364211b2a914aec486415f1d5769113b1d3bf23023319c3d68bf72b733367dc7851fdc9e4ffb9
6
+ metadata.gz: 5c6d93694df1819e9f464b184b64ebb4ce53fe8b73558c59e286d21fae4d349bed14e89c57c4f6f7c38a7c8ec51669cd6ab909d09f6ec7384f197725846c5092
7
+ data.tar.gz: 2955b7635cf34fccbaa06e3555ec0210a2a9fc00afa116c7a9e412d703c22a6ad3e563021ace19fec7cd96d13ec5d3222515355f0794a39206deab64ac1297bb
data/CHANGELOG.md CHANGED
@@ -1,3 +1,32 @@
1
+ # v0.5.1
2
+ - fixed a bug with the erb parsing where it was incorrectly compiling comments:
3
+ ```
4
+ <% # Comment %>
5
+ <% if query? %>
6
+ <%= content %>
7
+ <% end %>
8
+ ```
9
+
10
+ # v0.5.0
11
+ - `has_receiver:` will match the receiver for methods and the namespace for constants.
12
+ - `has_value_type:` is now `has_value: type:`
13
+ - `has_value:` can be nested with `at:` and `has_value:`.
14
+ - `has_argument:` can be given `at:` with `'*'` or `'**'` which matches all positional arguments or keyword arguments respectively
15
+ - the rails.yml config has been broken up into e.g. activerecord, actionpack, etc
16
+ - `haml_paths:` and `erb_paths:` are now configurable.
17
+ - `type:` can match on `'Array'`, `'Hash'`, and `'Proc'` literals.
18
+ - rails.yml config determines which `scope` is which by its shape rather than its path: (ActiveRecord#scope has a proc as the second parameter)
19
+ - `--write--todo` now correctly handles grouped definitions (like activemodel attributes)
20
+
21
+ # v0.4.4
22
+ - don't hard-wrap the --write-todo instructions it looks weird
23
+
24
+ # v0.4.3
25
+ - add --write-todo so you can add this to your project without
26
+ immediately fixing everything.
27
+
28
+ # v0.4.2
29
+ - Make sorbet happy with this as a dependency
1
30
  # v0.4.1
2
31
  - add `test_only:` to mark methods/constants/assignments as test_only in the config rather than just with magic comments
3
32
 
data/README.md CHANGED
@@ -56,8 +56,38 @@ lib/hello_world.rb:18:6 another_tested_unused_method def another_tested_unused_m
56
56
  Not directly called at all:
57
57
  lib/hello_world.rb:6:6 generated_method= attr_accessor :generated_method
58
58
  lib/hello_world.rb:6:6 generated_method attr_accessor :generated_method
59
+
60
+ how to resolve: https://github.com/robotdana/leftovers/tree/main/Readme.md#how_to_resolve
59
61
  ```
60
62
 
63
+ if there is an overwhelming number of results, try using [`--write-todo`](#write-todo)
64
+
65
+ ## How to resolve
66
+
67
+ When running `leftovers` you'll be given a list of method, constant, and variable definitions it thinks are unused. Now what?
68
+
69
+ they were unintentionally left when removing their calls:
70
+ - remove their definitions. (they're still there in your git etc history if you want them back)
71
+
72
+ they are called dynamically:
73
+ - define how they're called dynamically in the [.leftovers.yml](#configuration-file); or
74
+ - mark the calls with [`# leftovers:call my_unused_method`](#leftovers-call); or
75
+ - mark the definition with [`# leftovers:keep`](#leftovers-keep)
76
+
77
+ they're defined intentionally to only be used by tests:
78
+ - add [`# leftovers:test_only`](#leftovers-test-only)
79
+
80
+ they're from a file that shouldn't be checked by leftovers:
81
+ - add the paths to the [`exclude_paths:`](https://github.com/robotdana/leftovers/tree/main/docs/Configuration.md#exclude_paths) list in the [.leftovers.yml](#configuration-file) file
82
+
83
+ if there are too many to address when first adding leftovers to your project, try running [`leftovers --write-todo`](#write-todo),
84
+
85
+ ### --write-todo
86
+
87
+ running `leftovers --write-todo` will generate a supplemental configuration file allowing all the currently detected uncalled definitions, which will be read on subsequent runs of `leftovers` without alerting any of the items mentioned in it.
88
+
89
+ commit this file so you/your team can gradually address these items while still having leftovers alert you to any newly unused items.
90
+
61
91
  ## Magic comments
62
92
 
63
93
  ### `# leftovers:keep`
@@ -6,6 +6,8 @@ Its presence is optional and all of these settings are optional.
6
6
  - [`include_paths:`](#include_paths)
7
7
  - [`exclude_paths:`](#exclude_paths)
8
8
  - [`test_paths:`](#test_paths)
9
+ - [`haml_paths:`](#haml_paths)
10
+ - [`erb_paths:`](#erb_paths)
9
11
  - [`requires:`](#requires)
10
12
  - [`gems:`](#gems)
11
13
  - [`keep:`](#keep)
@@ -47,7 +49,7 @@ exclude_paths:
47
49
 
48
50
  Arrays are not necessary for single values
49
51
 
50
- ## `requires:` # TODO
52
+ ## `requires:`
51
53
  _alias `require`_
52
54
 
53
55
  List filenames/paths that you want to include
@@ -78,6 +80,30 @@ test_paths:
78
80
 
79
81
  Arrays are not necessary for single values
80
82
 
83
+ ## `haml_paths:`
84
+
85
+ list filenames/paths of test directories that are in the haml format
86
+ Defined using the [.gitignore pattern format](https://git-scm.com/docs/gitignore#_pattern_format)
87
+
88
+ ```yml
89
+ haml_paths:
90
+ - '*.haml'
91
+ ```
92
+
93
+ Arrays are not necessary for single values. `*.haml` is recognized by default
94
+
95
+ ## `erb_paths:`
96
+
97
+ list filenames/paths of test directories that are in the erb format
98
+ Defined using the [.gitignore pattern format](https://git-scm.com/docs/gitignore#_pattern_format)
99
+
100
+ ```yml
101
+ erb_paths:
102
+ - '*.erb'
103
+ ```
104
+
105
+ Arrays are not necessary for single values. `*.erb` is recognized by default
106
+
81
107
  ## `gems:`
82
108
  _alias `gem:`_
83
109
 
@@ -105,6 +131,7 @@ Each entry can be a string (an exact match for a method, constant, or variable n
105
131
  - [`matches:`](#matches) (can't be used in the same entry as `has_prefix:` or `has_suffix:`)
106
132
  - [`paths:`](#paths)
107
133
  - [`has_arguments:`](#has_arguments)
134
+ - [`has_receiver:`](#has_receiver)
108
135
  - [`unless`](#unless)
109
136
 
110
137
  Arrays are not necessary for single values
@@ -161,6 +188,7 @@ Each entry must have at least one of the following properties to restrict which
161
188
  - [`matches:`](#matches)
162
189
  - [`paths:`](#paths)
163
190
  - [`has_arguments:`](#has_arguments)
191
+ - [`has_receiver:`](#has_receiver)
164
192
  - [`unless`](#unless)
165
193
 
166
194
  And must have one or both of
@@ -323,8 +351,7 @@ and when used in:
323
351
 
324
352
  It can have any of these properties:
325
353
  - [`at:`](#at)
326
- - [`has_value:`](#has_value)
327
- - [`has_value_type:`](#has_value_type)
354
+ - [`has_value:`](#has_value_has_receiver)
328
355
 
329
356
  Arrays are not necessary for single values and if the rule contains only `at:` it can be omitted, and the values moved up a level
330
357
 
@@ -340,8 +367,7 @@ The method call/constant variable/assignment will be considered matching if it h
340
367
 
341
368
  It can have any of these properties:
342
369
  - [`at:`](#at)
343
- - [`has_value:`](#has_value) # TODO
344
- - [`has_value_type:`](#has_value_type) # TODO
370
+ - [`has_value:`](#has_value_has_receiver)
345
371
 
346
372
  Arrays are not necessary for single values and if the rule contains only `at:` it can be omitted, and the values moved up a level
347
373
 
@@ -383,9 +409,9 @@ Each entry can be any of:
383
409
 
384
410
  Arrays are not necessary for single values
385
411
 
386
- ## `has_value:`
412
+ ## `has_value:`, `has_receiver:`
387
413
 
388
- filter [`arguments:`](#arguments), [`has_arguments:`](#has_arguments), and [`keywords:`](#keywords), by the argument/assigned value
414
+ filter [`arguments:`](#arguments), [`has_arguments:`](#has_arguments), and [`keywords:`](#keywords), by the argument/assigned/receiver value
389
415
 
390
416
  Each entry can be one of
391
417
  - `true`, `false`, `nil`, or an Integer. matches the literal value
@@ -394,16 +420,25 @@ Each entry can be one of
394
420
  - [`has_prefix:`](#has_prefix)
395
421
  - [`has_suffix:`](#has_suffix)
396
422
  - [`matches:`](#matches) (this can't be used in the same entry as `has_prefix:` or `has_suffix:`)
423
+ - or have at least one of the following properties to match within an array or hash:
424
+ - [`at`](#at)
425
+ - [`has_value`](#has_value_has_receiver)
426
+ - or have the following property to match the value type
427
+ - [`type`](#type)
428
+ - or have the following property to match the receiver
429
+ - [`has_receiver`](#has_value_has_receiver)
397
430
 
398
- ## `has_value_type:`
431
+ ## `type:`
399
432
 
400
- Filter [`arguments:`](#arguments), [`has_arguments:`](#has_arguments), and [`keywords:`](#keywords), by the argument/assigned value
433
+ Filter [`has_value`](#has_value_has_receiver), by the argument/assigned value type
401
434
 
402
435
  Each entry can be one of
403
436
  - `'String'`
404
437
  - `'Symbol'`
405
438
  - `'Integer'`
406
439
  - `'Float'`
440
+ - `'Array'`
441
+ - `'Hash'`
407
442
 
408
443
  Arrays are not necessary for single values
409
444
 
@@ -613,9 +648,9 @@ Can be used in the [`transforms:`](#transforms) list (or anywhere `transforms:`
613
648
  if used in a hash `true` can be used as a placeholder value
614
649
 
615
650
  the incoming value will be transformed using the [active_support String core extensions](https://edgeguides.rubyonrails.org/active_support_core_extensions.html#inflections)
616
- and if using [gems:](#gems) with `active_support` or `rails` then your `config/initializers/inflections.rb` will be loaded. if you have inflections in another file, then supply that to [`requires:`](#requires).
651
+ and if using [gems:](#gems) with `activesupport` or `rails` then your `config/initializers/inflections.rb` will be loaded. if you have inflections in another file, then supply that to [`requires:`](#requires).
617
652
 
618
- If the `active_support` gem is not available this will raise an error.
653
+ If the `activesupport` gem is not available this will raise an error.
619
654
 
620
655
  ## `unless:`
621
656
 
data/leftovers.gemspec CHANGED
@@ -42,6 +42,7 @@ Gem::Specification.new do |spec|
42
42
  spec.add_development_dependency 'rubocop-rspec', '~> 1.44.1'
43
43
  spec.add_development_dependency 'simplecov', '>= 0.18.5'
44
44
  spec.add_development_dependency 'simplecov-console'
45
+ spec.add_development_dependency 'timecop'
45
46
  spec.add_development_dependency 'tty_string', '>= 0.2.1'
46
47
 
47
48
  spec.add_development_dependency 'spellr', '>= 0.8.1'
@@ -0,0 +1,4 @@
1
+ # THIS IS INCOMPLETE (you can help by expanding it)
2
+ # rails is _really complicated_ and has a lot of magic which calls methods for you.
3
+ # some is currently impossible to handle (with_options).
4
+ # Some is just corners of rails I haven't hit yet.
@@ -0,0 +1,22 @@
1
+ # THIS IS INCOMPLETE (you can help by expanding it)
2
+ # rails is _really complicated_ and has a lot of magic which calls methods for you.
3
+ # some is currently impossible to handle (with_options).
4
+ # Some is just corners of rails I haven't hit yet.
5
+ keep:
6
+ - has_suffix: Preview
7
+ path: '**/mailers/previews/**/*_preview.rb'
8
+ - delivering_email
9
+ - delivered_email
10
+
11
+ dynamic:
12
+ names:
13
+ - deliver_now
14
+ - deliver_later
15
+ calls:
16
+ value:
17
+ deliver
18
+ names:
19
+ - before_action
20
+ - after_action
21
+ - around_action
22
+ calls: ['*', if, unless]
@@ -0,0 +1,190 @@
1
+ # THIS IS INCOMPLETE (you can help by expanding it)
2
+ # rails is _really complicated_ and has a lot of magic which calls methods for you.
3
+ # some is currently impossible to handle (with_options).
4
+ # Some is just corners of rails I haven't hit yet.
5
+
6
+ include_paths:
7
+ - '*.rjs'
8
+ - '*.rhtml'
9
+
10
+ erb_paths:
11
+ - '*.rjs'
12
+ - '*.rhtml'
13
+
14
+ keep:
15
+ - ssl_configured? # ApplicationController
16
+ - default_url_options # called by url_for
17
+ - matches? # called by route constraints
18
+ - has_suffix: Helper
19
+ path: /app/helpers
20
+
21
+ dynamic:
22
+ - names:
23
+ - after_action
24
+ - append_after_action
25
+ - append_around_action
26
+ - append_before_action
27
+ - around_action
28
+ - before_action
29
+ - prepend_after_action
30
+ - prepend_around_action
31
+ - prepend_before_action
32
+ - skip_before_action
33
+ - skip_after_action
34
+ - skip_around_action
35
+ calls:
36
+ - arguments: ['*', if, unless]
37
+ - name: scope
38
+ unless:
39
+ has_argument:
40
+ at: 1
41
+ has_value:
42
+ type: Proc
43
+ calls:
44
+ argument: module # routes
45
+ camelize: true
46
+ split: '::'
47
+ - name: namespace
48
+ calls:
49
+ - argument: 0
50
+ camelize: true
51
+ split: '::'
52
+ - name:
53
+ - rescue_from
54
+ calls:
55
+ - argument: [1, with]
56
+ - name:
57
+ - match
58
+ - delete
59
+ - get
60
+ - patch
61
+ - post
62
+ - put
63
+ - root
64
+ calls:
65
+ - arguments: [0, action]
66
+ - argument: '**'
67
+ delete_before: '#'
68
+ - argument: '**'
69
+ delete_after: '#'
70
+ camelize: true
71
+ add_suffix: Controller
72
+ split: '::'
73
+ - name:
74
+ - resource
75
+ - resources
76
+ calls:
77
+ - argument: only
78
+ - argument: controller
79
+ camelize: true
80
+ add_suffix: Controller
81
+ split: '::'
82
+ - name:
83
+ - resource
84
+ - resources
85
+ unless:
86
+ has_argument:
87
+ - at: only
88
+ - at: except
89
+ has_value: index
90
+ - at: except
91
+ has_value:
92
+ at: '*'
93
+ has_value: index
94
+ calls:
95
+ - value: index
96
+ - name:
97
+ - resource
98
+ - resources
99
+ unless:
100
+ has_argument:
101
+ - at: only
102
+ - at: except
103
+ has_value: new
104
+ - at: except
105
+ has_value:
106
+ at: '*'
107
+ has_value: new
108
+ calls:
109
+ - value: new
110
+ - name:
111
+ - resource
112
+ - resources
113
+ unless:
114
+ has_argument:
115
+ - at: only
116
+ - at: except
117
+ has_value: create
118
+ - at: except
119
+ has_value:
120
+ at: '*'
121
+ has_value: create
122
+ calls:
123
+ - value: create
124
+ - name:
125
+ - resource
126
+ - resources
127
+ unless:
128
+ has_argument:
129
+ - at: only
130
+ - at: except
131
+ has_value: edit
132
+ - at: except
133
+ has_value:
134
+ at: '*'
135
+ has_value: edit
136
+ calls:
137
+ - value: edit
138
+ - name:
139
+ - resource
140
+ - resources
141
+ unless:
142
+ has_argument:
143
+ - at: only
144
+ - at: except
145
+ has_value: update
146
+ - at: except
147
+ has_value:
148
+ at: '*'
149
+ has_value: update
150
+ calls:
151
+ - value: update
152
+ - name:
153
+ - resource
154
+ - resources
155
+ unless:
156
+ has_argument:
157
+ - at: only
158
+ - at: except
159
+ has_value: destroy
160
+ - at: except
161
+ has_value:
162
+ at: '*'
163
+ has_value: destroy
164
+ calls:
165
+ - value: destroy
166
+ - name:
167
+ - resources
168
+ - controller
169
+ - namespace
170
+ calls:
171
+ - argument: 0
172
+ camelize: true
173
+ add_suffix: Controller
174
+ split: '::'
175
+ - name: resource
176
+ calls:
177
+ - argument: 0
178
+ camelize: true
179
+ pluralize: true
180
+ add_suffix: Controller
181
+ split: '::'
182
+ - name: permit
183
+ calls:
184
+ arguments: ['*', '**']
185
+ keywords: '**'
186
+ add_suffix: "="
187
+ recursive: true
188
+ - name: layout
189
+ calls:
190
+ argument: 0
@@ -0,0 +1,64 @@
1
+ # THIS IS INCOMPLETE (you can help by expanding it)
2
+ # rails is _really complicated_ and has a lot of magic which calls methods for you.
3
+ # some is currently impossible to handle (with_options).
4
+ # Some is just corners of rails I haven't hit yet.
5
+ keep:
6
+ - has_suffix: Helper
7
+ path: /app/helpers
8
+
9
+ dynamic:
10
+ - name:
11
+ - check_box
12
+ - date_select
13
+ - datetime_select
14
+ - file_field
15
+ - hidden_field
16
+ - label
17
+ - radio_button
18
+ - select
19
+ - time_select
20
+ - time_zone_select
21
+ - color_field
22
+ - date_field
23
+ - datetime_field
24
+ - datetime_local_field
25
+ - email_field
26
+ - month_field
27
+ - number_field
28
+ - password_field
29
+ - phone_field
30
+ - range_field
31
+ - search_field
32
+ - telephone_field
33
+ - text_area
34
+ - text_field
35
+ - time_field
36
+ - url_field
37
+ - week_field
38
+ calls:
39
+ - arguments: [0,1] # 0: with a receiver, 1: with no receiver
40
+ - arguments: [0,1]
41
+ add_suffix: '='
42
+ - name: fields_for
43
+ calls:
44
+ argument: 1
45
+ add_suffix: _attributes
46
+ - name: options_from_collection_for_select
47
+ calls:
48
+ - arguments: [1,2]
49
+ - name:
50
+ - collection_select
51
+ - collection_check_boxes
52
+ - collection_radio_buttons
53
+ calls:
54
+ - argument: 1
55
+ add_suffix: '='
56
+ - arguments: [3,4]
57
+ - name: grouped_collection_select
58
+ calls:
59
+ - argument: 1
60
+ add_suffix: '='
61
+ - arguments: [3,4,5,6]
62
+ - name: option_groups_from_collection_for_select
63
+ calls:
64
+ - arguments: [0,1,2,3]
@@ -0,0 +1,29 @@
1
+ # THIS IS INCOMPLETE (you can help by expanding it)
2
+ # rails is _really complicated_ and has a lot of magic which calls methods for you.
3
+ # some is currently impossible to handle (with_options).
4
+ # Some is just corners of rails I haven't hit yet.
5
+ keep:
6
+ - serialize?
7
+ - serialize
8
+ - deserialize
9
+ dynamic:
10
+ - name:
11
+ - perform_later
12
+ - perform
13
+ calls:
14
+ - value: perform
15
+ - names:
16
+ - before_enqueue
17
+ - around_enqueue
18
+ - after_enqueue
19
+ - before_perform
20
+ - around_perform
21
+ - after_perform
22
+ calls:
23
+ - arguments: 1
24
+ - arguments: [if, unless]
25
+ nested:
26
+ arguments: '*'
27
+ - name: rescue_from
28
+ calls:
29
+ - arguments: 1
@@ -0,0 +1,74 @@
1
+ # THIS IS INCOMPLETE (you can help by expanding it)
2
+ # rails is _really complicated_ and has a lot of magic which calls methods for you.
3
+ # some is currently impossible to handle (with_options).
4
+ # Some is just corners of rails I haven't hit yet.
5
+ keep:
6
+ - validate_each # ActiveModel::EachValidator
7
+
8
+ dynamic:
9
+ - names:
10
+ - after_initialize
11
+ - before_validation
12
+ - after_validation
13
+ calls:
14
+ - arguments: 0
15
+ - arguments: [if, unless]
16
+ nested:
17
+ arguments: '*'
18
+ - name:
19
+ - validates_associated
20
+ calls:
21
+ - arguments: ['*', if, unless]
22
+ - name: validates
23
+ calls:
24
+ - arguments:
25
+ - '*'
26
+ - within
27
+ - inclusion
28
+ - scope
29
+ - if
30
+ - unless
31
+ - arguments: inclusion
32
+ nested:
33
+ arguments: 'in'
34
+ - keywords:
35
+ unless: [if, unless]
36
+ camelize: true
37
+ add_suffix: Validator
38
+ split: '::'
39
+ - names:
40
+ - validate
41
+ - validate_associated
42
+ calls:
43
+ - arguments: ['*', if, unless]
44
+ - name:
45
+ - attribute
46
+ - alias_attribute
47
+ path: app/models/*
48
+ defines:
49
+ argument: 0
50
+ transforms:
51
+ - original
52
+ - add_suffix: '?'
53
+ - add_suffix: '='
54
+ - name: alias_attribute
55
+ calls:
56
+ - argument: 1
57
+ - argument: 1
58
+ add_suffix: '?'
59
+ - argument: 1
60
+ add_suffix: '='
61
+ - name: resource
62
+ calls:
63
+ - argument: 0
64
+ camelize: true
65
+ pluralize: true
66
+ add_suffix: Controller
67
+ split: '::'
68
+
69
+ - name:
70
+ - new
71
+ - assign_attributes
72
+ calls:
73
+ keyword: '**'
74
+ add_suffix: '='