sevencop 0.5.1 → 0.7.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/.rubocop.yml +0 -7
- data/CHANGELOG.md +22 -0
- data/Gemfile.lock +13 -11
- data/README.md +42 -0
- data/config/default.yml +19 -3
- data/lib/rubocop/cop/sevencop/hash_literal_order.rb +110 -0
- data/lib/rubocop/cop/sevencop/order_field.rb +1 -3
- data/lib/rubocop/cop/sevencop/uniqueness_validator_explicit_case_sensitivity.rb +1 -1
- data/lib/rubocop/cop/sevencop/where_not.rb +45 -0
- data/lib/sevencop/version.rb +1 -1
- data/lib/sevencop.rb +2 -0
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 435ef77ac8fd3b1e598c538068a02cf91bce3e1d3143bd1e48b45ed80b9a8cd1
|
4
|
+
data.tar.gz: 8bc5d65cde82f92a7f6457041cd49a1448af80d1915841a44a4fc2c22b7b0877
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f53c512de8a6c32b2c4a409dc274dc22149c3ef15b680c8223e58a74bcac0015ccb3dd2d2e397fbb410bdf6f949e9f3d1de645c8332204a88dce7ab6ca5194da
|
7
|
+
data.tar.gz: 2fd6cc8caf282c894b41744ae7df09d54017ce02d82ac3ab4925c85cde00a1aa0b8fd0ebc0fac5ec70f25dd8ab5fbfa79160102456a2a58ffafd3da1ffb92689
|
data/.rubocop.yml
CHANGED
data/CHANGELOG.md
CHANGED
@@ -2,6 +2,28 @@
|
|
2
2
|
|
3
3
|
## Unreleased
|
4
4
|
|
5
|
+
## 0.7.0 - 2022-07-15
|
6
|
+
|
7
|
+
### Added
|
8
|
+
|
9
|
+
- Add `Sevencop/WhereNot` cop.
|
10
|
+
|
11
|
+
## 0.6.1 - 2022-07-04
|
12
|
+
|
13
|
+
### Fixed
|
14
|
+
|
15
|
+
- Fix `Sevencop/HashLiteralOrder` on surrounding-space-less Hash.
|
16
|
+
|
17
|
+
## 0.6.0 - 2022-07-04
|
18
|
+
|
19
|
+
### Added
|
20
|
+
|
21
|
+
- Add `Sevencop/HashLiteralOrder` cop.
|
22
|
+
|
23
|
+
### Removed
|
24
|
+
|
25
|
+
- Remove unnecessary method names check on `Sevencop/OrderField`.
|
26
|
+
|
5
27
|
## 0.5.1 - 2022-06-28
|
6
28
|
|
7
29
|
### Fixed
|
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
sevencop (0.
|
4
|
+
sevencop (0.7.0)
|
5
5
|
rubocop
|
6
6
|
|
7
7
|
GEM
|
@@ -9,12 +9,13 @@ GEM
|
|
9
9
|
specs:
|
10
10
|
ast (2.4.2)
|
11
11
|
diff-lcs (1.5.0)
|
12
|
-
|
13
|
-
|
12
|
+
json (2.6.2)
|
13
|
+
parallel (1.22.1)
|
14
|
+
parser (3.1.2.0)
|
14
15
|
ast (~> 2.4.1)
|
15
16
|
rainbow (3.1.1)
|
16
17
|
rake (13.0.6)
|
17
|
-
regexp_parser (2.
|
18
|
+
regexp_parser (2.5.0)
|
18
19
|
rexml (3.2.5)
|
19
20
|
rspec (3.11.0)
|
20
21
|
rspec-core (~> 3.11.0)
|
@@ -25,23 +26,24 @@ GEM
|
|
25
26
|
rspec-expectations (3.11.0)
|
26
27
|
diff-lcs (>= 1.2.0, < 2.0)
|
27
28
|
rspec-support (~> 3.11.0)
|
28
|
-
rspec-mocks (3.11.
|
29
|
+
rspec-mocks (3.11.1)
|
29
30
|
diff-lcs (>= 1.2.0, < 2.0)
|
30
31
|
rspec-support (~> 3.11.0)
|
31
32
|
rspec-support (3.11.0)
|
32
|
-
rubocop (1.
|
33
|
+
rubocop (1.31.2)
|
34
|
+
json (~> 2.3)
|
33
35
|
parallel (~> 1.10)
|
34
36
|
parser (>= 3.1.0.0)
|
35
37
|
rainbow (>= 2.2.2, < 4.0)
|
36
38
|
regexp_parser (>= 1.8, < 3.0)
|
37
|
-
rexml
|
38
|
-
rubocop-ast (>= 1.
|
39
|
+
rexml (>= 3.2.5, < 4.0)
|
40
|
+
rubocop-ast (>= 1.18.0, < 2.0)
|
39
41
|
ruby-progressbar (~> 1.7)
|
40
42
|
unicode-display_width (>= 1.4.0, < 3.0)
|
41
|
-
rubocop-ast (1.
|
43
|
+
rubocop-ast (1.19.1)
|
42
44
|
parser (>= 3.1.1.0)
|
43
45
|
ruby-progressbar (1.11.0)
|
44
|
-
unicode-display_width (2.
|
46
|
+
unicode-display_width (2.2.0)
|
45
47
|
|
46
48
|
PLATFORMS
|
47
49
|
x86_64-linux
|
@@ -53,4 +55,4 @@ DEPENDENCIES
|
|
53
55
|
sevencop!
|
54
56
|
|
55
57
|
BUNDLED WITH
|
56
|
-
2.3.
|
58
|
+
2.3.17
|
data/README.md
CHANGED
@@ -27,12 +27,22 @@ gem install sevencop
|
|
27
27
|
|
28
28
|
## Usage
|
29
29
|
|
30
|
+
Require sevencop from your .rubocop.yml:
|
31
|
+
|
30
32
|
```yaml
|
31
33
|
# .rubocop.yml
|
32
34
|
require:
|
33
35
|
- sevencop
|
34
36
|
```
|
35
37
|
|
38
|
+
then enable the cops you want to use:
|
39
|
+
|
40
|
+
```yaml
|
41
|
+
# .rubocop.yml
|
42
|
+
Sevencop/BelongsToOptional:
|
43
|
+
Enabled: true
|
44
|
+
```
|
45
|
+
|
36
46
|
## Cops
|
37
47
|
|
38
48
|
All cops are `Enabled: false` by default.
|
@@ -57,6 +67,26 @@ belongs_to :group, options
|
|
57
67
|
|
58
68
|
This is useful for migration of `config.active_record.belongs_to_required_by_default`.
|
59
69
|
|
70
|
+
### Sevencop/HashLiteralOrder
|
71
|
+
|
72
|
+
Sort Hash literal entries by key.
|
73
|
+
|
74
|
+
```ruby
|
75
|
+
# bad
|
76
|
+
{
|
77
|
+
b: 1,
|
78
|
+
a: 1,
|
79
|
+
c: 1
|
80
|
+
}
|
81
|
+
|
82
|
+
# good
|
83
|
+
{
|
84
|
+
a: 1,
|
85
|
+
b: 1,
|
86
|
+
c: 1
|
87
|
+
}
|
88
|
+
```
|
89
|
+
|
60
90
|
### Sevencop/OrderField
|
61
91
|
|
62
92
|
Identifies a String including "field" is passed to `order` or `reorder`.
|
@@ -115,3 +145,15 @@ validates :name, uniqueness: { allow_nil: true, scope: :user_id, case_sensitive:
|
|
115
145
|
```
|
116
146
|
|
117
147
|
Useful to keep the same behavior between Rails 6.0 and 6.1 where case insensitive collation is used in MySQL.
|
148
|
+
|
149
|
+
### Sevencop/WhereNot
|
150
|
+
|
151
|
+
Identifies passing multi-elements Hash literal to `where.not`.
|
152
|
+
|
153
|
+
```ruby
|
154
|
+
# bad
|
155
|
+
where.not(key1: value1, key2: value2)
|
156
|
+
|
157
|
+
# good
|
158
|
+
where.not(key1: value1).where.not(key2: value2)
|
159
|
+
```
|
data/config/default.yml
CHANGED
@@ -5,20 +5,36 @@ Sevencop/BelongsToOptional:
|
|
5
5
|
Safe: false
|
6
6
|
VersionAdded: '0.5'
|
7
7
|
|
8
|
+
Sevencop/HashLiteralOrder:
|
9
|
+
Description: |
|
10
|
+
Sort Hash literal entries by key.
|
11
|
+
Enabled: false
|
12
|
+
VersionAdded: '0.6'
|
13
|
+
|
8
14
|
Sevencop/OrderField:
|
9
|
-
Description:
|
15
|
+
Description: |
|
16
|
+
Wrap safe SQL String by `Arel.sql`.
|
10
17
|
Enabled: false
|
11
18
|
Safe: false
|
12
19
|
VersionAdded: '0.4'
|
13
20
|
|
14
21
|
Sevencop/RedundantExistenceCheck:
|
15
|
-
Description:
|
22
|
+
Description: |
|
23
|
+
Avoid redundant existent check before file operation.
|
16
24
|
Enabled: false
|
17
25
|
Safe: false
|
18
26
|
VersionAdded: '0.1'
|
19
27
|
|
20
28
|
Sevencop/UniquenessValidatorExplicitCaseSensitivity:
|
21
|
-
Description:
|
29
|
+
Description: |
|
30
|
+
Specify :case_sensitivity option on use of UniquenessValidator.
|
22
31
|
Enabled: false
|
23
32
|
Safe: false
|
24
33
|
VersionAdded: '0.3'
|
34
|
+
|
35
|
+
Sevencop/WhereNot:
|
36
|
+
Description: |
|
37
|
+
Identifies passing multi-elements Hash literal to `where.not`.
|
38
|
+
Enabled: false
|
39
|
+
Safe: false
|
40
|
+
VersionAdded: '0.7'
|
@@ -0,0 +1,110 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module Sevencop
|
6
|
+
# Sort Hash literal entries by key.
|
7
|
+
#
|
8
|
+
# @example
|
9
|
+
#
|
10
|
+
# # bad
|
11
|
+
# {
|
12
|
+
# b: 1,
|
13
|
+
# a: 1,
|
14
|
+
# c: 1
|
15
|
+
# }
|
16
|
+
#
|
17
|
+
# # good
|
18
|
+
# {
|
19
|
+
# a: 1,
|
20
|
+
# b: 1,
|
21
|
+
# c: 1
|
22
|
+
# }
|
23
|
+
#
|
24
|
+
class HashLiteralOrder < Base
|
25
|
+
extend AutoCorrector
|
26
|
+
|
27
|
+
MSG = 'Sort Hash literal entries by key.'
|
28
|
+
|
29
|
+
def_node_matcher :hash_literal?, <<~PATTERN
|
30
|
+
(hash
|
31
|
+
(pair
|
32
|
+
{sym | str}
|
33
|
+
_
|
34
|
+
)+
|
35
|
+
)
|
36
|
+
PATTERN
|
37
|
+
|
38
|
+
# @param [RuboCop::AST::HashNode] node
|
39
|
+
def on_hash(node)
|
40
|
+
return unless hash_literal?(node)
|
41
|
+
|
42
|
+
return if sorted?(node)
|
43
|
+
|
44
|
+
add_offense(node) do |corrector|
|
45
|
+
corrector.replace(
|
46
|
+
node,
|
47
|
+
autocorrect(node)
|
48
|
+
)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
private
|
53
|
+
|
54
|
+
# @param [RuboCop::AST::HashNode] node
|
55
|
+
# @return [String]
|
56
|
+
def autocorrect(node)
|
57
|
+
[
|
58
|
+
'{',
|
59
|
+
whitespace_leading(node),
|
60
|
+
sort(node.pairs).map(&:source).join(",#{whitespace_between(node)}"),
|
61
|
+
whitespace_trailing(node),
|
62
|
+
'}'
|
63
|
+
].join
|
64
|
+
end
|
65
|
+
|
66
|
+
# @param [Array<RuboCop::AST::PairNode>] pairs
|
67
|
+
# @return [Array<RuboCop::AST::PairNode>]
|
68
|
+
def sort(pairs)
|
69
|
+
pairs.sort_by do |pair|
|
70
|
+
pair.key.value
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
# @param [RuboCop::AST::HashNode] node
|
75
|
+
# @return [Boolean]
|
76
|
+
def sorted?(node)
|
77
|
+
node.pairs.map(&:source) == sort(node.pairs).map(&:source)
|
78
|
+
end
|
79
|
+
|
80
|
+
# @param [RuboCop::AST::HashNode] node
|
81
|
+
# @return [String]
|
82
|
+
# { a: 1, b: 1 }
|
83
|
+
# ^^^
|
84
|
+
def whitespace_between(node)
|
85
|
+
if node.pairs.length >= 2
|
86
|
+
node.source[node.pairs[0].location.expression.end_pos + 1...node.pairs[1].location.expression.begin_pos]
|
87
|
+
else
|
88
|
+
' '
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
# @param [RuboCop::AST::HashNode] node
|
93
|
+
# @return [String]
|
94
|
+
# { a: 1, b: 1 }
|
95
|
+
# ^^
|
96
|
+
def whitespace_trailing(node)
|
97
|
+
node.source[node.pairs[-1].location.expression.end_pos...node.location.end.begin_pos]
|
98
|
+
end
|
99
|
+
|
100
|
+
# @param [RuboCop::AST::HashNode] node
|
101
|
+
# @return [String]
|
102
|
+
# { a: 1, b: 1 }
|
103
|
+
# ^^^^
|
104
|
+
def whitespace_leading(node)
|
105
|
+
node.source[node.location.begin.end_pos...node.pairs[0].location.expression.begin_pos]
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
@@ -32,11 +32,9 @@ module RuboCop
|
|
32
32
|
reorder
|
33
33
|
].freeze
|
34
34
|
|
35
|
-
ORDER_METHOD_NAMES = RESTRICT_ON_SEND.to_set.freeze
|
36
|
-
|
37
35
|
def_node_matcher :order_with_field?, <<~PATTERN
|
38
36
|
(send
|
39
|
-
_
|
37
|
+
_ _
|
40
38
|
{
|
41
39
|
(str /field\(.+\)/) |
|
42
40
|
(dstr <(str /field\(.+\)/) ...>)
|
@@ -4,7 +4,7 @@ module RuboCop
|
|
4
4
|
module Cop
|
5
5
|
module Sevencop
|
6
6
|
# Identifies use of UniquenessValidator without :case_sensitive option.
|
7
|
-
#
|
7
|
+
# Useful to keep the same behavior between Rails 6.0 and 6.1 where case insensitive collation is used in MySQL.
|
8
8
|
#
|
9
9
|
# @safety
|
10
10
|
# This cop is unsafe because it can register a false positive.
|
@@ -0,0 +1,45 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module Sevencop
|
6
|
+
# Identifies passing multi-elements Hash literal to `where.not`.
|
7
|
+
#
|
8
|
+
# @example
|
9
|
+
#
|
10
|
+
# # bad
|
11
|
+
# where.not(key1: value1, key2: value2)
|
12
|
+
#
|
13
|
+
# # good
|
14
|
+
# where.not(key1: value1).where.not(key2: value2)
|
15
|
+
#
|
16
|
+
class WhereNot < Base
|
17
|
+
extend AutoCorrector
|
18
|
+
|
19
|
+
MSG = 'Use `where.not(key1: value1).where.not(key2: value2)` style.'
|
20
|
+
|
21
|
+
def_node_matcher :where_not_with_multiple_elements_hash?, <<~PATTERN
|
22
|
+
(send
|
23
|
+
(send _ :where) :not
|
24
|
+
({ hash | kwargs }
|
25
|
+
(pair _ _)
|
26
|
+
(pair _ _)+))
|
27
|
+
PATTERN
|
28
|
+
|
29
|
+
def on_send(node)
|
30
|
+
return unless where_not_with_multiple_elements_hash?(node)
|
31
|
+
|
32
|
+
add_offense(node) do |corrector|
|
33
|
+
pairs = node.children[2].children
|
34
|
+
last_end_pos = pairs[0].location.expression.end_pos
|
35
|
+
pairs[1..].each do |pair|
|
36
|
+
corrector.remove(pair.location.expression.with(begin_pos: last_end_pos))
|
37
|
+
last_end_pos = pair.location.expression.end_pos
|
38
|
+
corrector.insert_after(node.location.expression, ".where.not(#{pair.source})")
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
data/lib/sevencop/version.rb
CHANGED
data/lib/sevencop.rb
CHANGED
@@ -7,9 +7,11 @@ require_relative 'sevencop/inject'
|
|
7
7
|
require_relative 'sevencop/version'
|
8
8
|
|
9
9
|
require_relative 'rubocop/cop/sevencop/belongs_to_optional'
|
10
|
+
require_relative 'rubocop/cop/sevencop/hash_literal_order'
|
10
11
|
require_relative 'rubocop/cop/sevencop/order_field'
|
11
12
|
require_relative 'rubocop/cop/sevencop/redundant_existence_check'
|
12
13
|
require_relative 'rubocop/cop/sevencop/uniqueness_validator_explicit_case_sensitivity'
|
14
|
+
require_relative 'rubocop/cop/sevencop/where_not'
|
13
15
|
|
14
16
|
module Sevencop
|
15
17
|
PROJECT_ROOT = ::Pathname.new(__dir__).parent.expand_path.freeze
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sevencop
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.7.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ryo Nakamura
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-
|
11
|
+
date: 2022-07-15 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rubocop
|
@@ -42,9 +42,11 @@ files:
|
|
42
42
|
- Rakefile
|
43
43
|
- config/default.yml
|
44
44
|
- lib/rubocop/cop/sevencop/belongs_to_optional.rb
|
45
|
+
- lib/rubocop/cop/sevencop/hash_literal_order.rb
|
45
46
|
- lib/rubocop/cop/sevencop/order_field.rb
|
46
47
|
- lib/rubocop/cop/sevencop/redundant_existence_check.rb
|
47
48
|
- lib/rubocop/cop/sevencop/uniqueness_validator_explicit_case_sensitivity.rb
|
49
|
+
- lib/rubocop/cop/sevencop/where_not.rb
|
48
50
|
- lib/sevencop.rb
|
49
51
|
- lib/sevencop/inject.rb
|
50
52
|
- lib/sevencop/version.rb
|