sevencop 0.4.1 → 0.6.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ef38866fd82173f9e717566ed4ddacaa43571eda5760cc72b37ec615256e32cc
4
- data.tar.gz: cf4aa55ea75a1eeebfae8a1d4ac311e83611a54b365911d4bf8d244fafbc587d
3
+ metadata.gz: 58fe0254e47cc59376f53d38640a163d0ba80dfba6f3f41998350b1b049010fd
4
+ data.tar.gz: 969301c9b0ef1af7ab3170c63fd72f5f8d6b095de2c84f2818917a003afe59cb
5
5
  SHA512:
6
- metadata.gz: 744673cf9ae424e870f5a7526a61c19f3b124597e83554c81967544cfdf617992bc2d46c464347cef5f654a5aca1654486511abb85afb0c3123719b6214411f6
7
- data.tar.gz: 81873ee0905b64eb4aa51cf7d0f93e62a87d2fd616a8c18756fe8d1ac68f023e0e8c0d5b6a2e77847bdf482edee2036956afc15248975292c10f1965488009d5
6
+ metadata.gz: be7586aef6236eab74b74494893ed7af665f01c4879ea36f63d6695250170174175859c439e7a6dd39775095b1ae210fa80a8d4e2e4f8a3c177e6ccc060c9c81
7
+ data.tar.gz: 7003edbafb17736c0e0bdfaaf65c1e1340fb45b684b31b1d573d6977f19e8c192700fb8bb4b57d0003f32753d2438110b6de937da42832a06641118c6e2b0c08
data/CHANGELOG.md CHANGED
@@ -2,6 +2,36 @@
2
2
 
3
3
  ## Unreleased
4
4
 
5
+ ## 0.6.0 - 2022-07-04
6
+
7
+ ### Added
8
+
9
+ - Add `Sevencop/HashLiteralOrder` cop.
10
+
11
+ ### Removed
12
+
13
+ - Remove unnecessary method names check on `Sevencop/OrderField`.
14
+
15
+ ## 0.5.1 - 2022-06-28
16
+
17
+ ### Fixed
18
+
19
+ - Fix `Sevencop/BelongsToOptional` scope bug.
20
+
21
+ ## 0.5.0 - 2022-06-27
22
+
23
+ ### Added
24
+
25
+ - Add `Sevencop/BelongsToOptional` cop.
26
+
27
+ ### Changed
28
+
29
+ - Make `Sevencop/RedundantExistenceCheck` cop disabled by default.
30
+
31
+ ### Removed
32
+
33
+ - Remove rubocop version dependency.
34
+
5
35
  ## 0.4.1 - 2022-06-23
6
36
 
7
37
  ### Fixed
data/Gemfile.lock CHANGED
@@ -1,8 +1,8 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- sevencop (0.4.1)
5
- rubocop (>= 1.27)
4
+ sevencop (0.6.0)
5
+ rubocop
6
6
 
7
7
  GEM
8
8
  remote: https://rubygems.org/
@@ -53,4 +53,4 @@ DEPENDENCIES
53
53
  sevencop!
54
54
 
55
55
  BUNDLED WITH
56
- 2.3.6
56
+ 2.3.16
data/README.md CHANGED
@@ -35,6 +35,48 @@ require:
35
35
 
36
36
  ## Cops
37
37
 
38
+ All cops are `Enabled: false` by default.
39
+
40
+ ### Sevencop/BelongsToOptional
41
+
42
+ Force `belongs_to` with `optional: true` option.
43
+
44
+ ```ruby
45
+ # bad
46
+ belongs_to :group
47
+
48
+ # good
49
+ belongs_to :group, optional: true
50
+
51
+ # good
52
+ belongs_to :group, optional: false
53
+
54
+ # good
55
+ belongs_to :group, options
56
+ ```
57
+
58
+ This is useful for migration of `config.active_record.belongs_to_required_by_default`.
59
+
60
+ ### Sevencop/HashLiteralOrder
61
+
62
+ Sort Hash literal by key.
63
+
64
+ ```ruby
65
+ # bad
66
+ {
67
+ b: 1,
68
+ a: 1,
69
+ c: 1
70
+ }
71
+
72
+ # good
73
+ {
74
+ a: 1,
75
+ b: 1,
76
+ c: 1
77
+ }
78
+ ```
79
+
38
80
  ### Sevencop/OrderField
39
81
 
40
82
  Identifies a String including "field" is passed to `order` or `reorder`.
@@ -53,8 +95,6 @@ reorder('field(id, ?)', a)
53
95
  reorder(Arel.sql('field(id, ?)'), a)
54
96
  ```
55
97
 
56
- `Enabled: false` by default.
57
-
58
98
  ### Sevencop/RedundantExistenceCheck
59
99
 
60
100
  Identifies redundant existent check before file operation.
@@ -95,5 +135,3 @@ validates :name, uniqueness: { allow_nil: true, scope: :user_id, case_sensitive:
95
135
  ```
96
136
 
97
137
  Useful to keep the same behavior between Rails 6.0 and 6.1 where case insensitive collation is used in MySQL.
98
-
99
- `Enabled: false` by default.
data/config/default.yml CHANGED
@@ -1,17 +1,33 @@
1
+ Sevencop/BelongsToOptional:
2
+ Description: |
3
+ Force `belongs_to` with `optional: true` option.
4
+ Enabled: false
5
+ Safe: false
6
+ VersionAdded: '0.5'
7
+
8
+ Sevencop/HashLiteralOrder:
9
+ Description: |
10
+ Sort Hash literal entries by key.
11
+ Enabled: false
12
+ VersionAdded: '0.6'
13
+
1
14
  Sevencop/OrderField:
2
- Description: Wrap safe SQL String by `Arel.sql`.
15
+ Description: |
16
+ Wrap safe SQL String by `Arel.sql`.
3
17
  Enabled: false
4
18
  Safe: false
5
19
  VersionAdded: '0.4'
6
20
 
7
21
  Sevencop/RedundantExistenceCheck:
8
- Description: Avoid redundant existent check before file operation.
9
- Enabled: true
22
+ Description: |
23
+ Avoid redundant existent check before file operation.
24
+ Enabled: false
10
25
  Safe: false
11
26
  VersionAdded: '0.1'
12
27
 
13
28
  Sevencop/UniquenessValidatorExplicitCaseSensitivity:
14
- Description: Specify :case_sensitivity option on use of UniquenessValidator.
29
+ Description: |
30
+ Specify :case_sensitivity option on use of UniquenessValidator.
15
31
  Enabled: false
16
32
  Safe: false
17
33
  VersionAdded: '0.3'
@@ -0,0 +1,54 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module Sevencop
6
+ # Force `belongs_to` with `optional: true` option.
7
+ #
8
+ # @example
9
+ #
10
+ # # bad
11
+ # belongs_to :group
12
+ #
13
+ # # good
14
+ # belongs_to :group, optional: true
15
+ #
16
+ # # good
17
+ # belongs_to :group, optional: false
18
+ #
19
+ # # good (We cannot identify offenses in this case.)
20
+ # belongs_to :group, options
21
+ #
22
+ class BelongsToOptional < Base
23
+ extend AutoCorrector
24
+
25
+ MSG = 'Specify :optional option.'
26
+
27
+ RESTRICT_ON_SEND = %i[
28
+ belongs_to
29
+ ].freeze
30
+
31
+ def_node_matcher :without_options?, <<~PATTERN
32
+ (send _ _ _ (block ...)?)
33
+ PATTERN
34
+
35
+ def_node_matcher :with_hash_options?, <<~PATTERN
36
+ (send _ _ _ (block ...)? (hash ...))
37
+ PATTERN
38
+
39
+ def_node_matcher :with_optional?, <<~PATTERN
40
+ (send _ _ _ (block ...)? (hash <(pair (sym :optional) _) ...>))
41
+ PATTERN
42
+
43
+ # @param [RuboCop::AST::SendNode] node
44
+ def on_send(node)
45
+ return unless without_options?(node) || (with_hash_options?(node) && !with_optional?(node))
46
+
47
+ add_offense(node) do |corrector|
48
+ corrector.insert_after(node.arguments[-1], ', optional: true')
49
+ end
50
+ end
51
+ end
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,105 @@
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
+ whitespace = whitespace_leading(node)
58
+ [
59
+ '{',
60
+ whitespace,
61
+ sort(node.pairs).map(&:source).join(",#{whitespace}"),
62
+ whitespace_ending(node),
63
+ '}'
64
+ ].join
65
+ end
66
+
67
+ # @param [RuboCop::AST::HashNode] node
68
+ # @return [Boolean]
69
+ def multi_line?(node)
70
+ node.source.include?("\n")
71
+ end
72
+
73
+ # @param [Array<RuboCop::AST::PairNode>] pairs
74
+ # @return [Array<RuboCop::AST::PairNode>]
75
+ def sort(pairs)
76
+ pairs.sort_by do |pair|
77
+ pair.key.value
78
+ end
79
+ end
80
+
81
+ # @param [RuboCop::AST::HashNode] node
82
+ # @return [Boolean]
83
+ def sorted?(node)
84
+ node.pairs.map(&:source) == sort(node.pairs).map(&:source)
85
+ end
86
+
87
+ # @param [RuboCop::AST::HashNode] node
88
+ # @return [String]
89
+ # { a: 1, b: 1 }
90
+ # ^^
91
+ def whitespace_ending(node)
92
+ node.source[node.pairs[-1].location.expression.end_pos...node.location.end.begin_pos]
93
+ end
94
+
95
+ # @param [RuboCop::AST::HashNode] node
96
+ # @return [String]
97
+ # { a: 1, b: 1 }
98
+ # ^^^^
99
+ def whitespace_leading(node)
100
+ node.source[node.location.begin.end_pos...node.pairs[0].location.expression.begin_pos]
101
+ end
102
+ end
103
+ end
104
+ end
105
+ 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
- _ ORDER_METHOD_NAMES
37
+ _ _
40
38
  {
41
39
  (str /field\(.+\)/) |
42
40
  (dstr <(str /field\(.+\)/) ...>)
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Sevencop
4
- VERSION = '0.4.1'
4
+ VERSION = '0.6.0'
5
5
  end
data/lib/sevencop.rb CHANGED
@@ -6,6 +6,8 @@ require 'yaml'
6
6
  require_relative 'sevencop/inject'
7
7
  require_relative 'sevencop/version'
8
8
 
9
+ require_relative 'rubocop/cop/sevencop/belongs_to_optional'
10
+ require_relative 'rubocop/cop/sevencop/hash_literal_order'
9
11
  require_relative 'rubocop/cop/sevencop/order_field'
10
12
  require_relative 'rubocop/cop/sevencop/redundant_existence_check'
11
13
  require_relative 'rubocop/cop/sevencop/uniqueness_validator_explicit_case_sensitivity'
data/sevencop.gemspec CHANGED
@@ -29,5 +29,5 @@ Gem::Specification.new do |spec|
29
29
  spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
30
30
  spec.require_paths = ['lib']
31
31
 
32
- spec.add_runtime_dependency 'rubocop', '>= 1.27'
32
+ spec.add_runtime_dependency 'rubocop'
33
33
  end
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.1
4
+ version: 0.6.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-06-23 00:00:00.000000000 Z
11
+ date: 2022-07-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rubocop
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: '1.27'
19
+ version: '0'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
- version: '1.27'
26
+ version: '0'
27
27
  description:
28
28
  email:
29
29
  - r7kamura@gmail.com
@@ -41,6 +41,8 @@ files:
41
41
  - README.md
42
42
  - Rakefile
43
43
  - config/default.yml
44
+ - lib/rubocop/cop/sevencop/belongs_to_optional.rb
45
+ - lib/rubocop/cop/sevencop/hash_literal_order.rb
44
46
  - lib/rubocop/cop/sevencop/order_field.rb
45
47
  - lib/rubocop/cop/sevencop/redundant_existence_check.rb
46
48
  - lib/rubocop/cop/sevencop/uniqueness_validator_explicit_case_sensitivity.rb
@@ -71,7 +73,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
71
73
  - !ruby/object:Gem::Version
72
74
  version: '0'
73
75
  requirements: []
74
- rubygems_version: 3.2.32
76
+ rubygems_version: 3.3.7
75
77
  signing_key:
76
78
  specification_version: 4
77
79
  summary: Custom cops for RuboCop.