gitlab-styles 12.0.1 → 13.0.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: 5301968fa7603c90e9ed917011c49e4a3124a7c442963e778fcc1f4862c7cf03
4
- data.tar.gz: 4b7676b2fcdb2bed6f3be9c8b0505ba04afa5ec008e95b6c980da5ef3a795032
3
+ metadata.gz: 7c8f4c0e301ccd103fbf7b527b4fc81563742555650b5e660ff4dcb18bad7de5
4
+ data.tar.gz: 7eb4ec96135389f35d7a5b5787c9ab1963b4bf670b64417cc1d31000a67f13f0
5
5
  SHA512:
6
- metadata.gz: bcb7c63e4e3cacd1638d87b2406483d763ecad6dbdb218a3da292f8be56112ca64d0d1596ac108143981d502834f6672e4c9128981edc8b6bd05566c924289f7
7
- data.tar.gz: e08bb7c660e85a30ffc64d669363e6b420219745231a5ea7e5524e657ae72c4f6b1fcb00c9d01d31c9bb846c5d8be57db22d8640dff67ae554f76db2092375ae
6
+ metadata.gz: a16a93bb989ef4057c9018f4cc8ba0916f31401546c50210d6d97f16445be17b0438a6f07d42d00e7fa1dcad711fb9c6e89aa86f19e08f7af6a3a0979ef47b35
7
+ data.tar.gz: 8304c777e6c7bac4a57a7583ba580367261483bcef4a4fcb97d81cc7086c76e5b1c8065df78466af537fe4bb2f9a85b4fded2e4841f49aae7a00f5c833fa338b
data/.gitlab-ci.yml CHANGED
@@ -18,12 +18,14 @@ default:
18
18
  .base-ruby-job:
19
19
  image: "ruby:${RUBY_VERSION}"
20
20
  before_script:
21
+ - bundle_version=$(grep -A 1 "BUNDLED WITH" Gemfile.lock | grep -oE '[[:digit:].]+')
22
+ - gem install bundler --version "$bundle_version" --no-document # Bundler is not installed with the image
21
23
  - bundle --version
22
24
  - bundle config set --local deployment 'true'
23
25
  - bundle install -j $(nproc)
24
26
  parallel:
25
27
  matrix:
26
- - RUBY_VERSION: ['3.0', '3.1', '3.2']
28
+ - RUBY_VERSION: ['3.1', '3.2', '3.3']
27
29
 
28
30
  styles:
29
31
  extends: .base-ruby-job
@@ -35,8 +37,8 @@ specs:
35
37
  extends: .base-ruby-job
36
38
  stage: test
37
39
  script:
38
- # Disable simplecov for all Ruby version other than 3.0
39
- - if [[ "$RUBY_VERSION" != "3.0" ]]; then export SIMPLECOV=0; fi
40
+ # Disable simplecov for all Ruby version other than the target Ruby version.
41
+ - if [[ "$RUBY_VERSION" != "3.1" ]]; then export SIMPLECOV=0; fi
40
42
  - bundle exec rspec
41
43
  artifacts:
42
44
  name: coverage
data/.rubocop.yml CHANGED
@@ -1,13 +1,21 @@
1
1
  inherit_from:
2
- - rubocop-default.yml
2
+ - rubocop-all.yml
3
+ - rubocop-minimal.yml
4
+ - rubocop-internal-affairs.yml
3
5
  - .rubocop_todo.yml
4
6
 
5
7
  require:
6
8
  - rubocop/cop/internal_affairs
7
9
  - rubocop-rake
8
10
 
11
+ inherit_mode:
12
+ merge:
13
+ - Exclude
14
+
9
15
  AllCops:
10
16
  NewCops: disable # https://gitlab.com/gitlab-org/ruby/gems/gitlab-styles/-/issues/40
17
+ Exclude:
18
+ - 'playground/**/*'
11
19
 
12
20
  Gemspec/DevelopmentDependencies:
13
21
  EnforcedStyle: gemspec
@@ -24,3 +32,22 @@ InternalAffairs/DeprecateCopHelper:
24
32
  # but realistically this is OK here.
25
33
  InternalAffairs/UndefinedConfig:
26
34
  Enabled: false
35
+
36
+ # Disable Rails-specific cops auto-enabled as part of `gitlab-styles`.
37
+ CodeReuse/ActiveRecord:
38
+ Enabled: false
39
+
40
+ Cop/ActiveRecordDependent:
41
+ Enabled: false
42
+
43
+ Cop/ActiveRecordSerialize:
44
+ Enabled: false
45
+
46
+ Cop/PolymorphicAssociations:
47
+ Enabled: false
48
+
49
+ Cop/RedirectWithStatus:
50
+ Enabled: false
51
+
52
+ Cop/InBatches:
53
+ Enabled: false
data/.rubocop_todo.yml CHANGED
@@ -1,17 +1,33 @@
1
1
  # This configuration was generated by
2
2
  # `rubocop --auto-gen-config`
3
- # on 2024-01-24 13:27:15 UTC using RuboCop version 1.57.2.
3
+ # on 2024-09-06 09:55:51 UTC using RuboCop version 1.64.0.
4
4
  # The point is for the user to remove these configuration records
5
5
  # one by one as the offenses are removed from the code base.
6
6
  # Note that changes in the inspected code, or installation of new
7
7
  # versions of RuboCop, may require this file to be generated again.
8
8
 
9
+ # Offense count: 11
10
+ # This cop supports safe autocorrection (--autocorrect).
11
+ InternalAffairs/CopDescriptionWithExample:
12
+ Exclude:
13
+ - 'lib/rubocop/cop/fips/md5.rb'
14
+ - 'lib/rubocop/cop/fips/open_ssl.rb'
15
+ - 'lib/rubocop/cop/fips/sha1.rb'
16
+ - 'lib/rubocop/cop/gem_fetcher.rb'
17
+ - 'lib/rubocop/cop/gitlab_security/deep_munge.rb'
18
+ - 'lib/rubocop/cop/in_batches.rb'
19
+ - 'lib/rubocop/cop/internal_affairs/deprecate_cop_helper.rb'
20
+ - 'lib/rubocop/cop/line_break_around_conditional_block.rb'
21
+ - 'lib/rubocop/cop/migration/update_large_table.rb'
22
+ - 'lib/rubocop/cop/performance/rubyzip.rb'
23
+ - 'lib/rubocop/cop/polymorphic_associations.rb'
24
+
9
25
  # Offense count: 1
10
26
  InternalAffairs/InheritDeprecatedCopClass:
11
27
  Exclude:
12
28
  - 'lib/rubocop/cop/gitlab_security/json_serialization.rb'
13
29
 
14
- # Offense count: 11
30
+ # Offense count: 10
15
31
  InternalAffairs/MissingCopDepartment:
16
32
  Exclude:
17
33
  - 'lib/rubocop/cop/active_record_dependent.rb'
@@ -24,4 +40,3 @@ InternalAffairs/MissingCopDepartment:
24
40
  - 'lib/rubocop/cop/line_break_around_conditional_block.rb'
25
41
  - 'lib/rubocop/cop/polymorphic_associations.rb'
26
42
  - 'lib/rubocop/cop/redirect_with_status.rb'
27
- - 'lib/rubocop/cop/without_reactive_cache.rb'
data/Gemfile.lock CHANGED
@@ -1,13 +1,15 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- gitlab-styles (12.0.1)
5
- rubocop (~> 1.62.1)
6
- rubocop-factory_bot (~> 2.25.1)
7
- rubocop-graphql (~> 1.5.0)
8
- rubocop-performance (~> 1.20.2)
9
- rubocop-rails (~> 2.24.0)
10
- rubocop-rspec (~> 2.27.1)
4
+ gitlab-styles (13.0.0)
5
+ rubocop (~> 1.66.0)
6
+ rubocop-capybara (~> 2.21.0)
7
+ rubocop-factory_bot (~> 2.26.1)
8
+ rubocop-graphql (~> 1.5.4)
9
+ rubocop-performance (~> 1.21.1)
10
+ rubocop-rails (~> 2.26.0)
11
+ rubocop-rspec (~> 3.0.4)
12
+ rubocop-rspec_rails (~> 2.30.0)
11
13
 
12
14
  GEM
13
15
  remote: https://rubygems.org/
@@ -92,7 +94,7 @@ GEM
92
94
  multi_xml (>= 0.5.2)
93
95
  i18n (1.13.0)
94
96
  concurrent-ruby (~> 1.0)
95
- json (2.7.1)
97
+ json (2.7.2)
96
98
  kramdown (2.4.0)
97
99
  rexml
98
100
  kramdown-parser-gfm (1.1.0)
@@ -111,7 +113,7 @@ GEM
111
113
  sawyer (~> 0.9)
112
114
  open4 (1.3.4)
113
115
  parallel (1.24.0)
114
- parser (3.3.0.5)
116
+ parser (3.3.1.0)
115
117
  ast (~> 2.4.1)
116
118
  racc
117
119
  proc_to_ast (0.1.0)
@@ -125,13 +127,14 @@ GEM
125
127
  byebug (~> 11.0)
126
128
  pry (>= 0.13, < 0.15)
127
129
  public_suffix (5.0.3)
128
- racc (1.7.3)
130
+ racc (1.8.0)
129
131
  rack (3.0.7)
130
132
  rainbow (3.1.1)
131
133
  rake (13.0.6)
132
134
  rchardet (1.8.0)
133
- regexp_parser (2.8.3)
134
- rexml (3.2.6)
135
+ regexp_parser (2.9.2)
136
+ rexml (3.2.8)
137
+ strscan (>= 3.0.9)
135
138
  rspec (3.12.0)
136
139
  rspec-core (~> 3.12.0)
137
140
  rspec-expectations (~> 3.12.0)
@@ -153,39 +156,39 @@ GEM
153
156
  binding_of_caller
154
157
  rspec-parameterized-core (< 2)
155
158
  rspec-support (3.12.0)
156
- rubocop (1.62.1)
159
+ rubocop (1.66.0)
157
160
  json (~> 2.3)
158
161
  language_server-protocol (>= 3.17.0)
159
162
  parallel (~> 1.10)
160
163
  parser (>= 3.3.0.2)
161
164
  rainbow (>= 2.2.2, < 4.0)
162
- regexp_parser (>= 1.8, < 3.0)
163
- rexml (>= 3.2.5, < 4.0)
164
- rubocop-ast (>= 1.31.1, < 2.0)
165
+ regexp_parser (>= 2.4, < 3.0)
166
+ rubocop-ast (>= 1.32.1, < 2.0)
165
167
  ruby-progressbar (~> 1.7)
166
168
  unicode-display_width (>= 2.4.0, < 3.0)
167
- rubocop-ast (1.31.2)
168
- parser (>= 3.3.0.4)
169
- rubocop-capybara (2.20.0)
170
- rubocop (~> 1.41)
171
- rubocop-factory_bot (2.25.1)
169
+ rubocop-ast (1.32.1)
170
+ parser (>= 3.3.1.0)
171
+ rubocop-capybara (2.21.0)
172
172
  rubocop (~> 1.41)
173
- rubocop-graphql (1.5.0)
174
- rubocop (>= 0.90, < 2)
175
- rubocop-performance (1.20.2)
173
+ rubocop-factory_bot (2.26.1)
174
+ rubocop (~> 1.61)
175
+ rubocop-graphql (1.5.4)
176
+ rubocop (>= 1.50, < 2)
177
+ rubocop-performance (1.21.1)
176
178
  rubocop (>= 1.48.1, < 2.0)
177
- rubocop-ast (>= 1.30.0, < 2.0)
178
- rubocop-rails (2.24.0)
179
+ rubocop-ast (>= 1.31.1, < 2.0)
180
+ rubocop-rails (2.26.0)
179
181
  activesupport (>= 4.2.0)
180
182
  rack (>= 1.1)
181
- rubocop (>= 1.33.0, < 2.0)
183
+ rubocop (>= 1.52.0, < 2.0)
182
184
  rubocop-ast (>= 1.31.1, < 2.0)
183
185
  rubocop-rake (0.6.0)
184
186
  rubocop (~> 1.0)
185
- rubocop-rspec (2.27.1)
186
- rubocop (~> 1.40)
187
- rubocop-capybara (~> 2.17)
188
- rubocop-factory_bot (~> 2.22)
187
+ rubocop-rspec (3.0.4)
188
+ rubocop (~> 1.61)
189
+ rubocop-rspec_rails (2.30.0)
190
+ rubocop (~> 1.61)
191
+ rubocop-rspec (~> 3, >= 3.0.1)
189
192
  ruby-progressbar (1.13.0)
190
193
  ruby2_keywords (0.0.5)
191
194
  sawyer (0.9.2)
@@ -200,6 +203,7 @@ GEM
200
203
  simplecov (~> 0.19)
201
204
  simplecov-html (0.12.3)
202
205
  simplecov_json_formatter (0.1.4)
206
+ strscan (3.1.0)
203
207
  terminal-table (3.0.2)
204
208
  unicode-display_width (>= 1.1.1, < 3)
205
209
  test_file_finder (0.1.4)
data/README.md CHANGED
@@ -50,6 +50,7 @@ rules:
50
50
  - `rubocop-rspec.yml`
51
51
  - `rubocop-security.yml`
52
52
  - `rubocop-style.yml`
53
+ - `rubocop-tailwind.yml`
53
54
 
54
55
  Example:
55
56
 
@@ -5,7 +5,7 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
5
5
  require 'gitlab/styles/version'
6
6
 
7
7
  Gem::Specification.new do |spec|
8
- spec.required_ruby_version = '>= 3.0'
8
+ spec.required_ruby_version = '>= 3.1'
9
9
  spec.name = 'gitlab-styles'
10
10
  spec.version = Gitlab::Styles::VERSION
11
11
  spec.authors = ['GitLab']
@@ -22,12 +22,14 @@ Gem::Specification.new do |spec|
22
22
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
23
23
  spec.require_paths = ['lib']
24
24
 
25
- spec.add_dependency 'rubocop', '~> 1.62.1'
26
- spec.add_dependency 'rubocop-factory_bot', '~> 2.25.1'
27
- spec.add_dependency 'rubocop-graphql', '~> 1.5.0'
28
- spec.add_dependency 'rubocop-performance', '~> 1.20.2'
29
- spec.add_dependency 'rubocop-rails', '~> 2.24.0'
30
- spec.add_dependency 'rubocop-rspec', '~> 2.27.1'
25
+ spec.add_dependency 'rubocop', '~> 1.66.0'
26
+ spec.add_dependency 'rubocop-capybara', '~> 2.21.0'
27
+ spec.add_dependency 'rubocop-factory_bot', '~> 2.26.1'
28
+ spec.add_dependency 'rubocop-graphql', '~> 1.5.4'
29
+ spec.add_dependency 'rubocop-performance', '~> 1.21.1'
30
+ spec.add_dependency 'rubocop-rails', '~> 2.26.0'
31
+ spec.add_dependency 'rubocop-rspec', '~> 3.0.4'
32
+ spec.add_dependency 'rubocop-rspec_rails', '~> 2.30.0'
31
33
 
32
34
  spec.add_development_dependency 'bundler', '~> 2.1'
33
35
  spec.add_development_dependency 'gitlab-dangerfiles', '~> 4.6.0'
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Gitlab
4
4
  module Styles
5
- VERSION = '12.0.1'
5
+ VERSION = '13.0.0'
6
6
  end
7
7
  end
@@ -3,6 +3,12 @@
3
3
  module Rubocop
4
4
  module Cop
5
5
  # Cop that prevents the use of `dependent: ...` in ActiveRecord models.
6
+ # @example
7
+ # # bad
8
+ # belongs_to :foo, dependent: :destroy
9
+ #
10
+ # # good
11
+ # belongs_to :foo # With database foreign key with cascading deletes
6
12
  class ActiveRecordDependent < RuboCop::Cop::Base
7
13
  MSG = 'Do not use `dependent:` to remove associated data, ' \
8
14
  'use foreign keys with cascading deletes instead.'
@@ -3,6 +3,13 @@
3
3
  module Rubocop
4
4
  module Cop
5
5
  # Cop that prevents the use of `serialize` in ActiveRecord models.
6
+ #
7
+ # @example
8
+ # # bad
9
+ # serialize :preferences
10
+ #
11
+ # # good
12
+ # # Column for each individual preference
6
13
  class ActiveRecordSerialize < RuboCop::Cop::Base
7
14
  MSG = 'Do not store serialized data in the database, use separate columns and/or tables instead'
8
15
 
@@ -4,9 +4,24 @@ module Rubocop
4
4
  module Cop
5
5
  module CodeReuse
6
6
  # Cop that denies the use of ActiveRecord methods outside of models.
7
+ #
8
+ # @example
9
+ # # bad
10
+ # # In app/workers/some_worker.rb
11
+ # User.where(admin: true)
12
+ #
13
+ # # good
14
+ # # In app/workers/some_worker.rb
15
+ # User.admins
16
+ # # In app/models/user.rb
17
+ # scope :admins, -> { where(admin: true) }
18
+ #
19
+ # See also:
20
+ # - https://docs.gitlab.com/ee/development/reusing_abstractions.html
21
+ # - https://gitlab.com/gitlab-org/gitlab-foss/issues/49653
7
22
  class ActiveRecord < RuboCop::Cop::Base
8
23
  MSG = 'This method can only be used inside an ActiveRecord model: ' \
9
- 'https://gitlab.com/gitlab-org/gitlab-foss/issues/49653'
24
+ 'https://docs.gitlab.com/ee/development/reusing_abstractions.html'
10
25
 
11
26
  # Various methods from ActiveRecord::Querying that are denied. We
12
27
  # exclude some generic ones such as `any?` and `first`, as these may
@@ -19,7 +19,7 @@ module Rubocop
19
19
  @message_template = MESSAGE_TEMPLATE
20
20
  @replacements = REPLACEMENTS
21
21
  @autocorrect = false
22
- super(config, options)
22
+ super
23
23
  end
24
24
  end
25
25
  end
@@ -23,7 +23,7 @@ module Rubocop
23
23
  @message_template = MESSAGE_TEMPLATE
24
24
  @replacements = REPLACEMENTS
25
25
  @autocorrect = true
26
- super(config, options)
26
+ super
27
27
  end
28
28
  end
29
29
  end
@@ -19,7 +19,7 @@ module Rubocop
19
19
  @message_template = MESSAGE_TEMPLATE
20
20
  @replacements = REPLACEMENTS
21
21
  @autocorrect = false
22
- super(config, options)
22
+ super
23
23
  end
24
24
  end
25
25
  end
@@ -0,0 +1,98 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rubocop/cop/internal_affairs/cop_description'
4
+ require 'rubocop/cop/mixin/documentation_comment'
5
+
6
+ module Rubocop
7
+ module Cop
8
+ module InternalAffairs
9
+ # Enforces the cop description to start with a word such as verb, and to include good and bad examples
10
+ #
11
+ # @example
12
+ # # bad
13
+ # # This cop checks ....
14
+ # # @example
15
+ # # # bad
16
+ # # !array.empty?
17
+ # #
18
+ # # # good
19
+ # # array.any?
20
+ # class SomeCop < Base
21
+ # ....
22
+ # end
23
+ #
24
+ # # bad
25
+ # # Checks ...
26
+ # class SomeCop < Base
27
+ # ...
28
+ # end
29
+ #
30
+ # # good
31
+ # # Checks ...
32
+ # #
33
+ # # @example
34
+ # # # bad
35
+ # # !array.empty?
36
+ # #
37
+ # # # good
38
+ # # array.any?
39
+ # #
40
+ # class SomeCop < Base
41
+ # ...
42
+ # end
43
+ class CopDescriptionWithExample < RuboCop::Cop::InternalAffairs::CopDescription
44
+ include RuboCop::Cop::DocumentationComment
45
+ extend RuboCop::Cop::AutoCorrector
46
+
47
+ MSG_MISSING_EXAMPLES = 'Description should include good and bad examples'
48
+ MSG_MISSING_DESCRIPTION = 'Must include a description'
49
+
50
+ def on_class(node)
51
+ super
52
+
53
+ module_node = node.parent
54
+
55
+ return unless module_node && node.parent_class
56
+
57
+ return if description_includes_example?(node)
58
+
59
+ description_beginning = first_comment_line(module_node)
60
+
61
+ if description_beginning.nil?
62
+ register_offense_for_missing_description(node)
63
+ else
64
+ register_offense_for_missing_examples(module_node, description_beginning)
65
+ end
66
+ end
67
+
68
+ private
69
+
70
+ def register_offense_for_missing_description(node)
71
+ add_offense(node, message: MSG_MISSING_DESCRIPTION)
72
+ end
73
+
74
+ def register_offense_for_missing_examples(module_node, description_beginning)
75
+ range = range(module_node, description_beginning)
76
+ add_offense(range, message: MSG_MISSING_EXAMPLES)
77
+ end
78
+
79
+ def description_includes_example?(node)
80
+ lines = preceding_lines(node)
81
+ index_of_example = lines.index { |line| line.text.match?(/# @example( |$)/) }
82
+ return false unless index_of_example
83
+
84
+ lines_after_example = lines[index_of_example + 1..]
85
+
86
+ lines_after_example.any? { |line| line.text.downcase.match?(/# # good( |$)/) } &&
87
+ lines_after_example.any? { |line| line.text.downcase.match?(/# # bad( |$)/) }
88
+ end
89
+ end
90
+ end
91
+ end
92
+ end
93
+
94
+ # Don't match files programmatically and use `Include` directives instead.
95
+ # See https://github.com/rubocop/rubocop/pull/13209#issuecomment-2337963170
96
+ class RuboCop::Cop::InternalAffairs::CopDescription
97
+ remove_method :relevant_file? if instance_method(:relevant_file?)
98
+ end
@@ -3,6 +3,31 @@
3
3
  module Rubocop
4
4
  module Cop
5
5
  module Rails
6
+ # Avoid including `ActionView::Helpers::UrlHelper`.
7
+ # It adds/overrides ~40 methods while usually only one is needed.
8
+ # Instead, use the `Gitlab::Routing.url_helpers`/`Application.routes.url_helpers`(outside of gitlab)
9
+ # and `ActionController::Base.helpers.link_to`.
10
+ #
11
+ # @example
12
+ # # bad
13
+ # class Foo
14
+ # include ActionView::Helpers::UrlHelper # <-- includes 40 new methods !
15
+ #
16
+ # def link_to_something
17
+ # link_to(...)
18
+ # end
19
+ # end
20
+ #
21
+ # # good
22
+ # class Foo
23
+ # def link_to_something
24
+ # url = Gitlab::Routing.url_helpers.project_blob_path(...)
25
+ # ActionController::Base.helpers.link_to(url, "Link text")
26
+ # end
27
+ # end
28
+ #
29
+ # See also
30
+ # - https://gitlab.com/gitlab-org/gitlab/-/issues/340567.
6
31
  class IncludeUrlHelper < RuboCop::Cop::Base
7
32
  MSG = <<~MSG
8
33
  Avoid including `ActionView::Helpers::UrlHelper`.
@@ -5,7 +5,7 @@ require 'rubocop-rspec'
5
5
  module Rubocop
6
6
  module Cop
7
7
  module RSpec
8
- class Base < RuboCop::Cop::RSpec::Base
8
+ class Base < RuboCop::Cop::RSpec::Base # rubocop:disable InternalAffairs/CopDescriptionWithExample -- Base class
9
9
  end
10
10
  end
11
11
  end
@@ -0,0 +1,46 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module Style
6
+ # Flags use of strftime('%Y-%m-%d') for formatting dates
7
+ # the preferred method is using .iso8601
8
+ #
9
+ # @example
10
+ # # bad
11
+ # DateTime.now.strftime('%Y-%m-%d')
12
+ # Time.now.strftime("%Y-%m-%d")
13
+ # Date.today.strftime("%Y-%m-%d")
14
+ #
15
+ # # good
16
+ # DateTime.now.to_date.iso8601
17
+ # Time.now.to_date.iso8601
18
+ # Date.today.iso8601
19
+ #
20
+ # See also:
21
+ # - https://gitlab.com/gitlab-org/gitlab/-/issues/410638
22
+ class Iso8601Date < RuboCop::Cop::Base
23
+ extend RuboCop::Cop::AutoCorrector
24
+ include RangeHelp
25
+
26
+ MSG = 'Use `iso8601` instead of `strftime("%Y-%m-%d")`.'
27
+ RESTRICT_ON_SEND = [:strftime].freeze
28
+
29
+ # @!method strftime_iso8601?(node)
30
+ def_node_matcher :strftime_iso8601?, <<~PATTERN
31
+ (send $(...) :strftime (str "%Y-%m-%d"))
32
+ PATTERN
33
+
34
+ def on_send(node)
35
+ return unless strftime_iso8601?(node)
36
+
37
+ range = range_between(node.loc.selector.begin_pos, node.loc.end.end_pos)
38
+
39
+ add_offense(range) do |corrector|
40
+ corrector.replace(range, 'to_date.iso8601')
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
@@ -6,6 +6,15 @@ module Rubocop
6
6
  # Flags uses of OpenStruct, as it is now officially discouraged
7
7
  # to be used for performance, version compatibility, and potential security issues.
8
8
  #
9
+ # @example
10
+ # # bad
11
+ # class SubClass < OpenStruct
12
+ # end
13
+ #
14
+ # # good
15
+ # class SubClass
16
+ # end
17
+ #
9
18
  # See also:
10
19
  # - https://rubyreferences.github.io/rubychanges/3.0.html#standard-library
11
20
  # - https://docs.ruby-lang.org/en/3.0.0/OpenStruct.html#class-OpenStruct-label-Caveats
@@ -0,0 +1,40 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Rubocop
4
+ module Cop
5
+ module Tailwind
6
+ # This prevents utility class names from being built dynamically using string interpolation.
7
+ # Tailwind needs to be able to parse fully qualified names to include the necessary utils in
8
+ # the bundle.
9
+ # @example
10
+ # # bad
11
+ # bgColor = "gl-bg-#{palette}-#{variant}"
12
+ # cssClasses = "gl-#{display} gl-border"
13
+ # width = "gl-w-1/#{denominator}"
14
+ #
15
+ # # good
16
+ # bgColor = "gl-bg-red-800"
17
+ # cssClasses = "gl-flex gl-border"
18
+ # width = "gl-w-1/2"
19
+ class StringInterpolation < RuboCop::Cop::Base
20
+ TAILWIND_CSS_CLASS = %r{(^|\s)gl-[a-z0-9\-/]*$}
21
+ MSG = 'String interpolations in CSS utility class names are forbidden. See https://gitlab.com/gitlab-org/ruby/gems/gitlab-styles/-/issues/73.'
22
+
23
+ # @!method interpolated_tailwind_class?(node)
24
+ def_node_matcher :interpolated_tailwind_class?, <<~PATTERN
25
+ (dstr
26
+ (str /#{TAILWIND_CSS_CLASS}/)
27
+ (begin ...)
28
+ ...
29
+ )
30
+ PATTERN
31
+
32
+ def on_dstr(node)
33
+ return unless interpolated_tailwind_class?(node)
34
+
35
+ add_offense(node)
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
data/rubocop-all.yml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  AllCops:
3
3
  # The oldest supported Ruby version.
4
- TargetRubyVersion: 3.0
4
+ TargetRubyVersion: 3.1
5
5
  # Cop names are not displayed in offense messages by default. Change behavior
6
6
  # by overriding DisplayCopNames, or by giving the -D/--display-cop-names
7
7
  # option.
data/rubocop-capybara.yml CHANGED
@@ -1,5 +1,6 @@
1
1
  ---
2
2
  require:
3
+ - rubocop-capybara
3
4
  - ./lib/gitlab/styles/rubocop
4
5
 
5
6
  # Checks if there is a more specific finder offered by Capybara.
data/rubocop-default.yml CHANGED
@@ -4,9 +4,12 @@ require:
4
4
 
5
5
  inherit_from:
6
6
  - rubocop-all.yml
7
- - rubocop-minimal.yml
8
7
  - rubocop-capybara.yml
8
+ - rubocop-code_reuse.yml
9
+ - rubocop-factory_bot.yml
9
10
  - rubocop-graphql.yml
10
11
  - rubocop-internal-affairs.yml
11
12
  - rubocop-migrations.yml
13
+ - rubocop-minimal.yml
12
14
  - rubocop-rails.yml
15
+ - rubocop-tailwind.yml
@@ -1,5 +1,6 @@
1
1
  ---
2
2
  require:
3
+ - rubocop-factory_bot
3
4
  - ./lib/gitlab/styles/rubocop
4
5
 
5
6
  # Check for create_list FactoryBot declarations higher than MaxAmount
data/rubocop-gemspec.yml CHANGED
@@ -1,4 +1,8 @@
1
1
  ---
2
+ # Prefer add_dependency over add_runtime_dependency as the latter is considered soft-deprecated.
3
+ Gemspec/AddRuntimeDependency:
4
+ Enabled: true
5
+
2
6
  # Checks that deprecated attributes are not set in a gemspec file. Removing
3
7
  # deprecated attributes allows the user to receive smaller packed gems.
4
8
  Gemspec/DeprecatedAttributeAssignment:
@@ -9,3 +9,12 @@ InternalAffairs/DeprecateCopHelper:
9
9
  InternalAffairs/MissingCopDepartment:
10
10
  Include:
11
11
  - 'lib/rubocop/cop/**/*.rb'
12
+
13
+ # Superseded by InternalAffairs/CopDescriptionWithExample
14
+ InternalAffairs/CopDescription:
15
+ Enabled: false
16
+
17
+ InternalAffairs/CopDescriptionWithExample:
18
+ Enabled: true
19
+ Include:
20
+ - 'lib/rubocop/cop/**/*.rb'
data/rubocop-lint.yml CHANGED
@@ -381,6 +381,11 @@ Lint/UselessElseWithoutRescue:
381
381
  Lint/UselessMethodDefinition: # (new in 0.90)
382
382
  Enabled: true
383
383
 
384
+ # Certain numeric operations have no impact, being: Adding or subtracting 0, multiplying
385
+ # or dividing by 1 or raising to the power of 1. These are probably leftover from debugging, or are mistakes.
386
+ Lint/UselessNumericOperation:
387
+ Enabled: true
388
+
384
389
  # Checks for useless setter call to a local variable.
385
390
  Lint/UselessSetterCall:
386
391
  Enabled: true
data/rubocop-naming.yml CHANGED
@@ -50,7 +50,8 @@ Naming/MethodParameterName:
50
50
  # NameWhitelist: is_a?
51
51
  Naming/PredicateName:
52
52
  Enabled: true
53
- ForbiddenPrefixes: is_
53
+ ForbiddenPrefixes:
54
+ - is_
54
55
  Exclude:
55
56
  - 'spec/**/*'
56
57
  - 'features/**/*'
data/rubocop-rails.yml CHANGED
@@ -63,7 +63,8 @@ Rails/Blank:
63
63
  # Checks the correct usage of date aware methods, such as `Date.today`,
64
64
  # `Date.current`, etc.
65
65
  Rails/Date:
66
- Enabled: false
66
+ Enabled: true
67
+ EnforcedStyle: flexible
67
68
 
68
69
  # Prefer delegate method for delegations.
69
70
  # Disabled per https://gitlab.com/gitlab-org/gitlab-ce/issues/35869
@@ -74,6 +75,11 @@ Rails/Delegate:
74
75
  Rails/DynamicFindBy:
75
76
  Enabled: false
76
77
 
78
+ # Defining enums with keyword arguments syntax is deprecated and will be removed in
79
+ # Rails 8.0. Positional arguments should be used instead
80
+ Rails/EnumSyntax:
81
+ Enabled: true
82
+
77
83
  # This cop enforces that 'exit' calls are not used within a rails app.
78
84
  Rails/Exit:
79
85
  Enabled: true
@@ -199,7 +205,8 @@ Rails/SquishedSQLHeredocs:
199
205
 
200
206
  # This cop checks for the use of Time methods without zone.
201
207
  Rails/TimeZone:
202
- Enabled: false
208
+ Enabled: true
209
+ EnforcedStyle: flexible
203
210
 
204
211
  # Checks for the use of exit statements (namely return, break and throw) in
205
212
  # transactions. This is due to the eventual unexpected behavior when using
@@ -225,6 +232,11 @@ Rails/WhereExists:
225
232
  Rails/WhereNot:
226
233
  Enabled: true
227
234
 
235
+ # Identifies places where manually constructed SQL in where can be replaced with ranges.
236
+ # https://docs.rubocop.org/rubocop-rails/cops_rails.html#railswhererange
237
+ Rails/WhereRange:
238
+ Enabled: true
239
+
228
240
  # Bans the use of `include ActionView::Helpers::UrlHelper`.
229
241
  Rails/IncludeUrlHelper:
230
242
  Enabled: true
data/rubocop-rspec.yml CHANGED
@@ -1,6 +1,7 @@
1
1
  ---
2
2
  require:
3
3
  - rubocop-rspec
4
+ - rubocop-rspec_rails
4
5
  - ./lib/gitlab/styles/rubocop
5
6
 
6
7
  # Check that instances are not being stubbed globally.
@@ -38,6 +39,18 @@ RSpec/DescribedClass:
38
39
  Enabled: true
39
40
  SkipBlocks: true
40
41
 
42
+ # Enforces custom RSpec dialects.
43
+ # Migrated config from RSpec/Capybara/FeatureMethods
44
+ RSpec/Dialect:
45
+ Enabled: true
46
+ PreferredMethods:
47
+ background: :before
48
+ scenario: :it
49
+ xscenario: :xit
50
+ given: :let
51
+ given!: :let!
52
+ feature: :describe
53
+
41
54
  # Checks if an example group does not include any tests.
42
55
  RSpec/EmptyExampleGroup:
43
56
  Enabled: true
@@ -78,12 +91,6 @@ RSpec/ExpectChange:
78
91
  RSpec/ExpectOutput:
79
92
  Enabled: true
80
93
 
81
- # Checks the file and folder naming of the spec file.
82
- # Will be replaced with RSpec/SpecFilePathFormat and RSpec/SpecFilePathSuffix.
83
- RSpec/FilePath:
84
- Enabled: true
85
- IgnoreMethods: true
86
-
87
94
  # Checks if there are focused specs.
88
95
  RSpec/Focus:
89
96
  Enabled: true
@@ -103,6 +110,10 @@ RSpec/ImplicitExpect:
103
110
  Enabled: true
104
111
  EnforcedStyle: is_expected
105
112
 
113
+ # Do not set up test data using indexes (e.g., item_1, item_2).
114
+ RSpec/IndexedLet:
115
+ Enabled: false
116
+
106
117
  # Checks for the usage of instance variables.
107
118
  # https://docs.gitlab.com/ee/development/testing_guide/best_practices.html#subject-and-let-variables
108
119
  RSpec/InstanceVariable:
@@ -116,6 +127,11 @@ RSpec/LeadingSubject:
116
127
  RSpec/LetSetup:
117
128
  Enabled: false
118
129
 
130
+ # Checks where match_array is used.
131
+ # see: https://gitlab.com/gitlab-org/ruby/gems/gitlab-styles/-/merge_requests/225
132
+ RSpec/MatchArray:
133
+ Enabled: false
134
+
119
135
  # Check that chains of messages are not being stubbed.
120
136
  RSpec/MessageChain:
121
137
  Enabled: false
@@ -160,16 +176,19 @@ RSpec/SingleLineHook:
160
176
  - 'spec/factories/*'
161
177
  - 'spec/requests/api/v3/*'
162
178
 
179
+ # Sort RSpec metadata alphabetically.
180
+ # see: https://gitlab.com/gitlab-org/ruby/gems/gitlab-styles/-/merge_requests/232#note_2089653748
181
+ RSpec/SortMetadata:
182
+ Enabled: false
183
+
163
184
  # Checks the file and folder naming of the spec file.
164
- # Will replace RSpec/FilePath.
165
185
  RSpec/SpecFilePathFormat:
166
- Enabled: false
186
+ Enabled: true
167
187
  IgnoreMethods: true
168
188
 
169
189
  # Checks the file and folder naming of the spec file.
170
- # Will replace RSpec/FilePath.
171
190
  RSpec/SpecFilePathSuffix:
172
- Enabled: false
191
+ Enabled: true
173
192
 
174
193
  # Checks that message expectations do not have a configured response.
175
194
  # https://docs.rubocop.org/rubocop-rspec/1.44/cops_rspec.html#rspecstubbedmock
data/rubocop-style.yml CHANGED
@@ -182,8 +182,11 @@ Style/HashLikeCase:
182
182
 
183
183
  # Prefer Ruby 1.9 hash syntax `{ a: 1, b: 2 }`
184
184
  # over 1.8 syntax `{ :a => 1, :b => 2 }`.
185
+ # Short-hand Hash syntax does not work prior 3.1.
186
+ # See https://gitlab.com/gitlab-org/gitlab/-/issues/435940#note_1703307479
185
187
  Style/HashSyntax:
186
188
  Enabled: true
189
+ EnforcedShorthandSyntax: never
187
190
 
188
191
  # looks for uses of _.each_with_object({}) {...}, _.map {...}.to_h, and Hash[_.map {...}]
189
192
  # that are actually just transforming the keys of a hash, and tries to use a simpler & faster
@@ -222,6 +225,10 @@ Style/InfiniteLoop:
222
225
  Style/InverseMethods:
223
226
  Enabled: false
224
227
 
228
+ # Use iso8601 date format via specific function instead of strftime
229
+ Style/Iso8601Date:
230
+ Enabled: true
231
+
225
232
  Style/KeywordParametersOrder: # (new in 0.90)
226
233
  Enabled: true
227
234
 
@@ -238,6 +245,10 @@ Style/OptionalBooleanParameter:
238
245
  Style/Strip:
239
246
  Enabled: true
240
247
 
248
+ # Checks for usages of each with <<, push, or append which can be replaced by map.
249
+ Style/MapIntoArray:
250
+ Enabled: true
251
+
241
252
  # Checks if the method definitions have or don't have parentheses.
242
253
  Style/MethodDefParentheses:
243
254
  Enabled: true
@@ -360,6 +371,12 @@ Style/RedundantFetchBlock:
360
371
  Style/RedundantFileExtensionInRequire:
361
372
  Enabled: true
362
373
 
374
+ # Before Ruby 3.0, interpolated strings followed the frozen string literal magic comment which sometimes made it
375
+ # necessary to explicitly unfreeze them. Ruby 3.0 changed interpolated strings to always be unfrozen which makes
376
+ # unfreezing them redundant.
377
+ Style/RedundantInterpolationUnfreeze:
378
+ Enabled: true
379
+
363
380
  # Checks for parentheses that seem not to serve any purpose.
364
381
  Style/RedundantParentheses:
365
382
  Enabled: true
@@ -389,6 +406,10 @@ Style/RedundantSortBy:
389
406
  Style/Semicolon:
390
407
  Enabled: true
391
408
 
409
+ # Detects the use of the public_send method with a literal method name argument.
410
+ Style/SendWithLiteralMethodName:
411
+ Enabled: true
412
+
392
413
  # Sometimes using dig method ends up with just a single argument. In such cases, dig should be replaced with [].
393
414
  # https://docs.rubocop.org/rubocop/0.89/cops_style.html#stylesingleargumentdig
394
415
  Style/SingleArgumentDig:
@@ -427,6 +448,11 @@ Style/StringMethods:
427
448
  intern: to_sym
428
449
  Enabled: true
429
450
 
451
+ # Checks for redundant argument forwarding when calling super with arguments identical to
452
+ # the method definition.
453
+ Style/SuperArguments:
454
+ Enabled: true
455
+
430
456
  # Use %i or %I for arrays of symbols.
431
457
  Style/SymbolArray:
432
458
  Enabled: false
@@ -0,0 +1,7 @@
1
+ ---
2
+ require:
3
+ - ./lib/gitlab/styles/rubocop
4
+
5
+ # Prevent string interpolation when building Tailwind CSS utils names
6
+ Tailwind/StringInterpolation:
7
+ Enabled: false
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: gitlab-styles
3
3
  version: !ruby/object:Gem::Version
4
- version: 12.0.1
4
+ version: 13.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - GitLab
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2024-05-13 00:00:00.000000000 Z
11
+ date: 2024-10-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rubocop
@@ -16,84 +16,112 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: 1.62.1
19
+ version: 1.66.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.62.1
26
+ version: 1.66.0
27
+ - !ruby/object:Gem::Dependency
28
+ name: rubocop-capybara
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: 2.21.0
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: 2.21.0
27
41
  - !ruby/object:Gem::Dependency
28
42
  name: rubocop-factory_bot
29
43
  requirement: !ruby/object:Gem::Requirement
30
44
  requirements:
31
45
  - - "~>"
32
46
  - !ruby/object:Gem::Version
33
- version: 2.25.1
47
+ version: 2.26.1
34
48
  type: :runtime
35
49
  prerelease: false
36
50
  version_requirements: !ruby/object:Gem::Requirement
37
51
  requirements:
38
52
  - - "~>"
39
53
  - !ruby/object:Gem::Version
40
- version: 2.25.1
54
+ version: 2.26.1
41
55
  - !ruby/object:Gem::Dependency
42
56
  name: rubocop-graphql
43
57
  requirement: !ruby/object:Gem::Requirement
44
58
  requirements:
45
59
  - - "~>"
46
60
  - !ruby/object:Gem::Version
47
- version: 1.5.0
61
+ version: 1.5.4
48
62
  type: :runtime
49
63
  prerelease: false
50
64
  version_requirements: !ruby/object:Gem::Requirement
51
65
  requirements:
52
66
  - - "~>"
53
67
  - !ruby/object:Gem::Version
54
- version: 1.5.0
68
+ version: 1.5.4
55
69
  - !ruby/object:Gem::Dependency
56
70
  name: rubocop-performance
57
71
  requirement: !ruby/object:Gem::Requirement
58
72
  requirements:
59
73
  - - "~>"
60
74
  - !ruby/object:Gem::Version
61
- version: 1.20.2
75
+ version: 1.21.1
62
76
  type: :runtime
63
77
  prerelease: false
64
78
  version_requirements: !ruby/object:Gem::Requirement
65
79
  requirements:
66
80
  - - "~>"
67
81
  - !ruby/object:Gem::Version
68
- version: 1.20.2
82
+ version: 1.21.1
69
83
  - !ruby/object:Gem::Dependency
70
84
  name: rubocop-rails
71
85
  requirement: !ruby/object:Gem::Requirement
72
86
  requirements:
73
87
  - - "~>"
74
88
  - !ruby/object:Gem::Version
75
- version: 2.24.0
89
+ version: 2.26.0
76
90
  type: :runtime
77
91
  prerelease: false
78
92
  version_requirements: !ruby/object:Gem::Requirement
79
93
  requirements:
80
94
  - - "~>"
81
95
  - !ruby/object:Gem::Version
82
- version: 2.24.0
96
+ version: 2.26.0
83
97
  - !ruby/object:Gem::Dependency
84
98
  name: rubocop-rspec
85
99
  requirement: !ruby/object:Gem::Requirement
86
100
  requirements:
87
101
  - - "~>"
88
102
  - !ruby/object:Gem::Version
89
- version: 2.27.1
103
+ version: 3.0.4
104
+ type: :runtime
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: 3.0.4
111
+ - !ruby/object:Gem::Dependency
112
+ name: rubocop-rspec_rails
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - "~>"
116
+ - !ruby/object:Gem::Version
117
+ version: 2.30.0
90
118
  type: :runtime
91
119
  prerelease: false
92
120
  version_requirements: !ruby/object:Gem::Requirement
93
121
  requirements:
94
122
  - - "~>"
95
123
  - !ruby/object:Gem::Version
96
- version: 2.27.1
124
+ version: 2.30.0
97
125
  - !ruby/object:Gem::Dependency
98
126
  name: bundler
99
127
  requirement: !ruby/object:Gem::Requirement
@@ -313,6 +341,7 @@ files:
313
341
  - lib/rubocop/cop/gitlab_security/sql_injection.rb
314
342
  - lib/rubocop/cop/gitlab_security/system_command_injection.rb
315
343
  - lib/rubocop/cop/in_batches.rb
344
+ - lib/rubocop/cop/internal_affairs/cop_description_with_example.rb
316
345
  - lib/rubocop/cop/internal_affairs/deprecate_cop_helper.rb
317
346
  - lib/rubocop/cop/internal_affairs/missing_cop_department.rb
318
347
  - lib/rubocop/cop/internal_affairs/use_restrict_on_send.rb
@@ -334,8 +363,9 @@ files:
334
363
  - lib/rubocop/cop/rspec/useless_dynamic_definition.rb
335
364
  - lib/rubocop/cop/rspec/verbose_include_metadata.rb
336
365
  - lib/rubocop/cop/style/hash_transformation.rb
366
+ - lib/rubocop/cop/style/iso8601_date.rb
337
367
  - lib/rubocop/cop/style/open_struct_use.rb
338
- - lib/rubocop/cop/without_reactive_cache.rb
368
+ - lib/rubocop/cop/tailwind/string_interpolation.rb
339
369
  - rubocop-all.yml
340
370
  - rubocop-bundler.yml
341
371
  - rubocop-capybara.yml
@@ -357,6 +387,7 @@ files:
357
387
  - rubocop-rspec.yml
358
388
  - rubocop-security.yml
359
389
  - rubocop-style.yml
390
+ - rubocop-tailwind.yml
360
391
  homepage: https://gitlab.com/gitlab-org/ruby/gems/gitlab-styles
361
392
  licenses:
362
393
  - MIT
@@ -369,7 +400,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
369
400
  requirements:
370
401
  - - ">="
371
402
  - !ruby/object:Gem::Version
372
- version: '3.0'
403
+ version: '3.1'
373
404
  required_rubygems_version: !ruby/object:Gem::Requirement
374
405
  requirements:
375
406
  - - ">="
@@ -1,16 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Rubocop
4
- module Cop
5
- # Cop that prevents the use of `without_reactive_cache`
6
- class WithoutReactiveCache < RuboCop::Cop::Base
7
- MSG = 'without_reactive_cache is for debugging purposes only. Please use with_reactive_cache.'
8
-
9
- RESTRICT_ON_SEND = %i[without_reactive_cache].freeze
10
-
11
- def on_send(node)
12
- add_offense(node.loc.selector)
13
- end
14
- end
15
- end
16
- end