gitlab-styles 12.0.1 → 13.0.0

Sign up to get free protection for your applications and to get access to all the features.
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