betterlint 1.29.0 → 1.31.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 +4 -4
- data/README.md +68 -0
- data/config/default.yml +16 -1
- data/lib/betterlint/version.rb +1 -1
- data/lib/rubocop/cop/betterment/no_down_migrations.rb +48 -0
- data/lib/rubocop/cop/betterment/no_send.rb +25 -0
- data/lib/rubocop/cop/betterment.rb +2 -0
- metadata +9 -7
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: df6ab37fcacbca2232240ecc261718b03ce8cae9d9ec6860d01b1fe5aafa15de
|
|
4
|
+
data.tar.gz: 3c1aace8b60b77b649f621b5923f3defddb33d18922aff23211225cea7461af5
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 0405efeb7e9268e65ab0440399f375e482338b7008a9ffa4690cbdc0640d8f0d1e5ea5382ddf2f203f54beb517f76387386f104b0f2a20519615e9c34f3bd6fd
|
|
7
|
+
data.tar.gz: 668fba99358e61376714517009c13e3e335e74c5576541941293c56018a851dca599edb0333160d99c27a31b192ec730149dac7cdf53045dbbac2cc24f643fba
|
data/README.md
CHANGED
|
@@ -19,6 +19,10 @@ plugins:
|
|
|
19
19
|
- betterlint
|
|
20
20
|
```
|
|
21
21
|
|
|
22
|
+
## Upgrading to 1.30
|
|
23
|
+
|
|
24
|
+
Migration files are included in normal lint runs. Set `AllCops/MigratedSchemaVersion` to the last existing migration version to [skip historical files](#bettermentnodownmigrations).
|
|
25
|
+
|
|
22
26
|
## Dependencies
|
|
23
27
|
|
|
24
28
|
This gem depends on the following other gems:
|
|
@@ -235,6 +239,49 @@ Betterment/UnsafeJob:
|
|
|
235
239
|
|
|
236
240
|
It may make sense to consult your application's values for `Rails.application.config.filter_parameters`; if the application is filtering specific parameters from being logged, it might be a good idea to prevent these values from being stored in plaintext in a database as well.
|
|
237
241
|
|
|
242
|
+
### Betterment/NoDownMigrations
|
|
243
|
+
|
|
244
|
+
This cop enforces [the rule against down migrations](https://the-book.betterment.io/rules/ruby/#do-not-write-down-migrations)
|
|
245
|
+
by flagging `down` methods and `direction.down` calls in migration `reversible` blocks.
|
|
246
|
+
It allows `change` and standalone `up` methods and does not autocorrect.
|
|
247
|
+
|
|
248
|
+
**Bad**
|
|
249
|
+
|
|
250
|
+
```ruby
|
|
251
|
+
class AddNickname < ActiveRecord::Migration[8.0]
|
|
252
|
+
def up
|
|
253
|
+
add_column :users, :nickname, :string
|
|
254
|
+
end
|
|
255
|
+
|
|
256
|
+
def down
|
|
257
|
+
remove_column :users, :nickname
|
|
258
|
+
end
|
|
259
|
+
end
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
**Good**
|
|
263
|
+
|
|
264
|
+
```ruby
|
|
265
|
+
class AddNickname < ActiveRecord::Migration[8.0]
|
|
266
|
+
def change
|
|
267
|
+
add_column :users, :nickname, :string
|
|
268
|
+
end
|
|
269
|
+
end
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
The cop is disabled by default. Enable it for migrations newer than a chosen version:
|
|
273
|
+
|
|
274
|
+
```yaml
|
|
275
|
+
AllCops:
|
|
276
|
+
MigratedSchemaVersion: '20261030120000'
|
|
277
|
+
|
|
278
|
+
Betterment/NoDownMigrations:
|
|
279
|
+
Enabled: true
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
Set `MigratedSchemaVersion` under this cop to ignore additional migrations.
|
|
283
|
+
Leave `Rails/ReversibleMigrationMethodDefinition` disabled: it requires `up` and `down`.
|
|
284
|
+
|
|
238
285
|
### Betterment/NonStandardActions
|
|
239
286
|
|
|
240
287
|
This cop looks at Rails route files and flags routes that go to non-standard controller actions.
|
|
@@ -423,3 +470,24 @@ end
|
|
|
423
470
|
```
|
|
424
471
|
|
|
425
472
|
This cop is disabled by default, because it reports many offenses in applications with older specs. To use it, enable it in your `.rubocop.yml`. By default it examines all files in `spec/`, except for the `features`, `requests`, `routing`, `system`, and `views` directories, where integration style tests that don't test one class and method are common. Examples in shared example groups are also ignored.
|
|
473
|
+
|
|
474
|
+
### Betterment/NoSend
|
|
475
|
+
|
|
476
|
+
This cop flags calls to `send`, `public_send`, and `__send__`. Dynamic dispatch hides the call from Sorbet and code search, and `send` also reaches private methods. Call the method directly instead.
|
|
477
|
+
|
|
478
|
+
#### BAD:
|
|
479
|
+
|
|
480
|
+
```ruby
|
|
481
|
+
record.public_send(:name)
|
|
482
|
+
record.send(attribute_name)
|
|
483
|
+
job.send(:plaid_item)
|
|
484
|
+
```
|
|
485
|
+
|
|
486
|
+
#### GOOD:
|
|
487
|
+
|
|
488
|
+
```ruby
|
|
489
|
+
record.name
|
|
490
|
+
record.attributes.fetch(attribute_name)
|
|
491
|
+
```
|
|
492
|
+
|
|
493
|
+
This cop ignores files in `spec/`, and calls to `send` with no arguments, which are usually a different method named `send`.
|
data/config/default.yml
CHANGED
|
@@ -20,7 +20,7 @@ AllCops:
|
|
|
20
20
|
- Gemfile
|
|
21
21
|
- bin/**/*
|
|
22
22
|
- build/**/*
|
|
23
|
-
- db
|
|
23
|
+
- db/*schema.rb
|
|
24
24
|
- frontend/**/*
|
|
25
25
|
- node_modules/**/*
|
|
26
26
|
- tmp/**/*
|
|
@@ -62,6 +62,21 @@ Betterment/InternalsProtection:
|
|
|
62
62
|
StyleGuide: '#bettermentinternalsprotection'
|
|
63
63
|
Enabled: false
|
|
64
64
|
|
|
65
|
+
Betterment/NoDownMigrations:
|
|
66
|
+
Description: Disallows explicit rollback code in database migrations.
|
|
67
|
+
Enabled: false
|
|
68
|
+
MigratedSchemaVersion:
|
|
69
|
+
StyleGuide: '#bettermentnodownmigrations'
|
|
70
|
+
Include:
|
|
71
|
+
- db/migrate/**/*.rb
|
|
72
|
+
|
|
73
|
+
Betterment/NoSend:
|
|
74
|
+
Description: Detects dynamic method calls through send, public_send and __send__.
|
|
75
|
+
StyleGuide: '#bettermentnosend'
|
|
76
|
+
Enabled: true
|
|
77
|
+
Exclude:
|
|
78
|
+
- spec/**/*
|
|
79
|
+
|
|
65
80
|
Betterment/NonNamespacedClass:
|
|
66
81
|
Description: Detects classes that are not namespaced under a module or constant
|
|
67
82
|
StyleGuide: '#bettermentnonamespacedclass'
|
data/lib/betterlint/version.rb
CHANGED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'rubocop/cop/mixin/migrations_helper'
|
|
4
|
+
|
|
5
|
+
module RuboCop
|
|
6
|
+
module Cop
|
|
7
|
+
module Betterment
|
|
8
|
+
class NoDownMigrations < Base
|
|
9
|
+
include MigrationsHelper
|
|
10
|
+
|
|
11
|
+
MSG = 'Do not write explicit rollback code. Correct deployed migrations with a new forward migration.'
|
|
12
|
+
RESTRICT_ON_SEND = %i(down).freeze
|
|
13
|
+
|
|
14
|
+
def on_def(node)
|
|
15
|
+
add_offense(node.loc.name) if node.method?(:down) && migration_to_check?(node)
|
|
16
|
+
end
|
|
17
|
+
alias on_defs on_def
|
|
18
|
+
|
|
19
|
+
def on_send(node)
|
|
20
|
+
if migration_to_check?(node) && reversible_direction?(node.receiver)
|
|
21
|
+
add_offense(node.loc.selector)
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
alias on_csend on_send
|
|
25
|
+
|
|
26
|
+
private
|
|
27
|
+
|
|
28
|
+
def migration_to_check?(node)
|
|
29
|
+
return false unless migration_class?(node.each_ancestor(:class).first)
|
|
30
|
+
|
|
31
|
+
cutoff = cop_config.fetch('MigratedSchemaVersion')
|
|
32
|
+
version = File.basename(processed_source.file_path)[/\A\d+(?=_)/]
|
|
33
|
+
!cutoff || !version || version.to_i > Integer(cutoff)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def reversible_direction?(receiver)
|
|
37
|
+
return false unless receiver&.lvar_type?
|
|
38
|
+
|
|
39
|
+
binding = receiver.each_ancestor(:any_block).find do |block|
|
|
40
|
+
block.argument_list.any? { |argument| argument.name == receiver.children.first }
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
binding&.method?(:reversible) && (binding.receiver.nil? || binding.receiver.self_type?)
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module RuboCop
|
|
4
|
+
module Cop
|
|
5
|
+
module Betterment
|
|
6
|
+
class NoSend < Base
|
|
7
|
+
MSG = <<~TEXT
|
|
8
|
+
Call the method directly instead of using `%<method>s`; dynamic dispatch is invisible to Sorbet and code search.
|
|
9
|
+
|
|
10
|
+
See here for more information on this cop:
|
|
11
|
+
https://github.com/Betterment/betterlint/blob/main/README.md#bettermentnosend
|
|
12
|
+
TEXT
|
|
13
|
+
|
|
14
|
+
RESTRICT_ON_SEND = %i(send public_send __send__).freeze
|
|
15
|
+
|
|
16
|
+
def on_send(node)
|
|
17
|
+
return unless node.arguments?
|
|
18
|
+
|
|
19
|
+
add_offense(node.loc.selector, message: format(MSG, method: node.method_name))
|
|
20
|
+
end
|
|
21
|
+
alias on_csend on_send
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
@@ -12,6 +12,8 @@ require 'rubocop/cop/betterment/hardcoded_id'
|
|
|
12
12
|
require 'rubocop/cop/betterment/implicit_redirect_type'
|
|
13
13
|
require 'rubocop/cop/betterment/internals_protection'
|
|
14
14
|
require 'rubocop/cop/betterment/memoization_with_arguments'
|
|
15
|
+
require 'rubocop/cop/betterment/no_down_migrations'
|
|
16
|
+
require 'rubocop/cop/betterment/no_send'
|
|
15
17
|
require 'rubocop/cop/betterment/non_namespaced_class'
|
|
16
18
|
require 'rubocop/cop/betterment/non_standard_actions'
|
|
17
19
|
require 'rubocop/cop/betterment/non_standard_controller'
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: betterlint
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.
|
|
4
|
+
version: 1.31.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Development
|
|
@@ -105,14 +105,14 @@ dependencies:
|
|
|
105
105
|
requirements:
|
|
106
106
|
- - "~>"
|
|
107
107
|
- !ruby/object:Gem::Version
|
|
108
|
-
version: '2.
|
|
108
|
+
version: '2.36'
|
|
109
109
|
type: :runtime
|
|
110
110
|
prerelease: false
|
|
111
111
|
version_requirements: !ruby/object:Gem::Requirement
|
|
112
112
|
requirements:
|
|
113
113
|
- - "~>"
|
|
114
114
|
- !ruby/object:Gem::Version
|
|
115
|
-
version: '2.
|
|
115
|
+
version: '2.36'
|
|
116
116
|
- !ruby/object:Gem::Dependency
|
|
117
117
|
name: rubocop-rake
|
|
118
118
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -179,6 +179,8 @@ files:
|
|
|
179
179
|
- lib/rubocop/cop/betterment/implicit_redirect_type.rb
|
|
180
180
|
- lib/rubocop/cop/betterment/internals_protection.rb
|
|
181
181
|
- lib/rubocop/cop/betterment/memoization_with_arguments.rb
|
|
182
|
+
- lib/rubocop/cop/betterment/no_down_migrations.rb
|
|
183
|
+
- lib/rubocop/cop/betterment/no_send.rb
|
|
182
184
|
- lib/rubocop/cop/betterment/non_namespaced_class.rb
|
|
183
185
|
- lib/rubocop/cop/betterment/non_standard_actions.rb
|
|
184
186
|
- lib/rubocop/cop/betterment/non_standard_controller.rb
|
|
@@ -203,10 +205,10 @@ licenses:
|
|
|
203
205
|
- MIT
|
|
204
206
|
metadata:
|
|
205
207
|
homepage_uri: https://github.com/Betterment/betterlint
|
|
206
|
-
source_code_uri: https://github.com/Betterment/betterlint/tree/v1.
|
|
207
|
-
changelog_uri: https://github.com/Betterment/betterlint/blob/v1.
|
|
208
|
+
source_code_uri: https://github.com/Betterment/betterlint/tree/v1.31.0
|
|
209
|
+
changelog_uri: https://github.com/Betterment/betterlint/blob/v1.31.0/CHANGELOG.md
|
|
208
210
|
bug_tracker_uri: https://github.com/Betterment/betterlint/issues
|
|
209
|
-
documentation_uri: https://www.rubydoc.info/gems/betterlint/1.
|
|
211
|
+
documentation_uri: https://www.rubydoc.info/gems/betterlint/1.31.0
|
|
210
212
|
rubygems_mfa_required: 'true'
|
|
211
213
|
default_lint_roller_plugin: Betterlint::Plugin
|
|
212
214
|
rdoc_options: []
|
|
@@ -223,7 +225,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
223
225
|
- !ruby/object:Gem::Version
|
|
224
226
|
version: '0'
|
|
225
227
|
requirements: []
|
|
226
|
-
rubygems_version: 4.0.
|
|
228
|
+
rubygems_version: 4.0.24
|
|
227
229
|
specification_version: 4
|
|
228
230
|
summary: Betterment rubocop configuration
|
|
229
231
|
test_files: []
|