gitlab-styles 4.0.0 → 5.1.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/.editorconfig +18 -0
- data/.gitlab-ci.yml +4 -15
- data/.gitlab/merge_request_templates/Release.md +4 -4
- data/.rubocop.yml +3 -1
- data/Gemfile +3 -2
- data/README.md +1 -0
- data/gitlab-styles.gemspec +5 -4
- data/lib/gitlab/styles/rubocop.rb +5 -0
- data/lib/gitlab/styles/rubocop/cop/active_record_dependent.rb +1 -1
- data/lib/gitlab/styles/rubocop/cop/code_reuse/active_record.rb +131 -0
- data/lib/gitlab/styles/rubocop/cop/custom_error_class.rb +6 -3
- data/lib/gitlab/styles/rubocop/cop/gem_fetcher.rb +1 -1
- data/lib/gitlab/styles/rubocop/cop/line_break_after_guard_clauses.rb +1 -1
- data/lib/gitlab/styles/rubocop/cop/line_break_around_conditional_block.rb +132 -0
- data/lib/gitlab/styles/rubocop/cop/migration/update_large_table.rb +64 -0
- data/lib/gitlab/styles/rubocop/cop/polymorphic_associations.rb +1 -1
- data/lib/gitlab/styles/rubocop/cop/rspec/base.rb +18 -0
- data/lib/gitlab/styles/rubocop/cop/rspec/empty_line_after_let_block.rb +65 -0
- data/lib/gitlab/styles/rubocop/cop/rspec/empty_line_after_shared_example.rb +65 -0
- data/lib/gitlab/styles/rubocop/cop/rspec/have_link_parameters.rb +10 -5
- data/lib/gitlab/styles/rubocop/cop/rspec/single_line_hook.rb +3 -2
- data/lib/gitlab/styles/rubocop/cop/rspec/verbose_include_metadata.rb +10 -13
- data/lib/gitlab/styles/rubocop/model_helpers.rb +1 -1
- data/lib/gitlab/styles/rubocop/rspec/helpers.rb +17 -0
- data/lib/gitlab/styles/version.rb +1 -1
- data/rubocop-all.yml +1 -0
- data/rubocop-bundler.yml +1 -0
- data/rubocop-code_reuse.yml +24 -0
- data/rubocop-default.yml +2 -0
- data/rubocop-gemspec.yml +1 -0
- data/rubocop-layout.yml +6 -0
- data/rubocop-lint.yml +63 -5
- data/rubocop-metrics.yml +1 -0
- data/rubocop-migrations.yml +22 -0
- data/rubocop-naming.yml +1 -0
- data/rubocop-performance.yml +48 -0
- data/rubocop-rails.yml +79 -0
- data/rubocop-rspec.yml +14 -0
- data/rubocop-security.yml +1 -0
- data/rubocop-style.yml +90 -1
- metadata +26 -17
- data/.rubocop_todo.yml +0 -7
@@ -0,0 +1,64 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require_relative '../../migration_helpers'
|
3
|
+
|
4
|
+
module Gitlab
|
5
|
+
module Styles
|
6
|
+
module Rubocop
|
7
|
+
module Cop
|
8
|
+
module Migration
|
9
|
+
# This cop checks for methods that may lead to batch type issues on a table that's been
|
10
|
+
# explicitly denied because of its size.
|
11
|
+
#
|
12
|
+
# Even though though these methods perform functions to avoid
|
13
|
+
# downtime, using it with tables with millions of rows still causes a
|
14
|
+
# significant delay in the deploy process and is best avoided.
|
15
|
+
#
|
16
|
+
# See https://gitlab.com/gitlab-com/infrastructure/issues/1602 for more
|
17
|
+
# information.
|
18
|
+
class UpdateLargeTable < RuboCop::Cop::Cop
|
19
|
+
include MigrationHelpers
|
20
|
+
|
21
|
+
MSG = 'Using `%s` on the `%s` table will take a long time to ' \
|
22
|
+
'complete, and should be avoided unless absolutely ' \
|
23
|
+
'necessary'
|
24
|
+
|
25
|
+
def_node_matcher :batch_update?, <<~PATTERN
|
26
|
+
(send nil? ${#denied_method?}
|
27
|
+
(sym $...)
|
28
|
+
...)
|
29
|
+
PATTERN
|
30
|
+
|
31
|
+
def on_send(node)
|
32
|
+
return if denied_tables.empty? || denied_methods.empty?
|
33
|
+
return unless in_migration?(node)
|
34
|
+
|
35
|
+
matches = batch_update?(node)
|
36
|
+
return unless matches
|
37
|
+
|
38
|
+
update_method = matches.first
|
39
|
+
table = matches.last.to_a.first
|
40
|
+
|
41
|
+
return unless denied_tables.include?(table)
|
42
|
+
|
43
|
+
add_offense(node, message: format(MSG, update_method, table))
|
44
|
+
end
|
45
|
+
|
46
|
+
private
|
47
|
+
|
48
|
+
def denied_tables
|
49
|
+
cop_config['DeniedTables'] || []
|
50
|
+
end
|
51
|
+
|
52
|
+
def denied_method?(method_name)
|
53
|
+
denied_methods.include?(method_name)
|
54
|
+
end
|
55
|
+
|
56
|
+
def denied_methods
|
57
|
+
cop_config['DeniedMethods'] || []
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'rubocop-rspec'
|
4
|
+
require_relative '../../rspec/helpers'
|
5
|
+
|
6
|
+
module Gitlab
|
7
|
+
module Styles
|
8
|
+
module Rubocop
|
9
|
+
module Cop
|
10
|
+
module RSpec
|
11
|
+
class Base < RuboCop::Cop::RSpec::Base
|
12
|
+
include Rubocop::Rspec::Helpers
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'rubocop-rspec'
|
4
|
+
require_relative 'base'
|
5
|
+
|
6
|
+
module Gitlab
|
7
|
+
module Styles
|
8
|
+
module Rubocop
|
9
|
+
module Cop
|
10
|
+
module RSpec
|
11
|
+
# Checks if there is an empty line after let blocks.
|
12
|
+
#
|
13
|
+
# @example
|
14
|
+
# # bad
|
15
|
+
# RSpec.describe Foo do
|
16
|
+
# let(:something) { 'something' }
|
17
|
+
# let(:another_thing) do
|
18
|
+
# end
|
19
|
+
# let(:something_else) do
|
20
|
+
# end
|
21
|
+
# let(:last_thing) { 'last thing' }
|
22
|
+
# end
|
23
|
+
#
|
24
|
+
# # good
|
25
|
+
# RSpec.describe Foo do
|
26
|
+
# let(:something) { 'something' }
|
27
|
+
# let(:another_thing) do
|
28
|
+
# end
|
29
|
+
#
|
30
|
+
# let(:something_else) do
|
31
|
+
# end
|
32
|
+
#
|
33
|
+
# let(:last_thing) { 'last thing' }
|
34
|
+
# end
|
35
|
+
#
|
36
|
+
# # good - it's ok to have non-separated without do/end blocks
|
37
|
+
# RSpec.describe Foo do
|
38
|
+
# let(:something) { 'something' }
|
39
|
+
# let(:last_thing) { 'last thing' }
|
40
|
+
# end
|
41
|
+
#
|
42
|
+
class EmptyLineAfterLetBlock < Base
|
43
|
+
extend RuboCop::Cop::AutoCorrector
|
44
|
+
include RuboCop::RSpec::EmptyLineSeparation
|
45
|
+
|
46
|
+
MSG = 'Add an empty line after `%<let>s` block.'
|
47
|
+
|
48
|
+
def_node_matcher :lets, LET.block_pattern
|
49
|
+
|
50
|
+
def on_block(node)
|
51
|
+
lets(node) do
|
52
|
+
break if last_child?(node)
|
53
|
+
next if node.single_line?
|
54
|
+
|
55
|
+
missing_separating_line_offense(node) do |method|
|
56
|
+
format(MSG, let: method)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'rubocop-rspec'
|
4
|
+
require_relative 'base'
|
5
|
+
|
6
|
+
module Gitlab
|
7
|
+
module Styles
|
8
|
+
module Rubocop
|
9
|
+
module Cop
|
10
|
+
module RSpec
|
11
|
+
# Checks if there is an empty line after shared example blocks.
|
12
|
+
#
|
13
|
+
# @example
|
14
|
+
# # bad
|
15
|
+
# RSpec.describe Foo do
|
16
|
+
# it_behaves_like 'do this first'
|
17
|
+
# it_behaves_like 'does this' do
|
18
|
+
# end
|
19
|
+
# it_behaves_like 'does that' do
|
20
|
+
# end
|
21
|
+
# it_behaves_like 'do some more'
|
22
|
+
# end
|
23
|
+
#
|
24
|
+
# # good
|
25
|
+
# RSpec.describe Foo do
|
26
|
+
# it_behaves_like 'do this first'
|
27
|
+
# it_behaves_like 'does this' do
|
28
|
+
# end
|
29
|
+
#
|
30
|
+
# it_behaves_like 'does that' do
|
31
|
+
# end
|
32
|
+
#
|
33
|
+
# it_behaves_like 'do some more'
|
34
|
+
# end
|
35
|
+
#
|
36
|
+
# # fair - it's ok to have non-separated without blocks
|
37
|
+
# RSpec.describe Foo do
|
38
|
+
# it_behaves_like 'do this first'
|
39
|
+
# it_behaves_like 'does this'
|
40
|
+
# end
|
41
|
+
#
|
42
|
+
class EmptyLineAfterSharedExample < Base
|
43
|
+
extend RuboCop::Cop::AutoCorrector
|
44
|
+
include RuboCop::RSpec::EmptyLineSeparation
|
45
|
+
|
46
|
+
MSG = 'Add an empty line after `%<example>s` block.'
|
47
|
+
|
48
|
+
def_node_matcher :shared_examples,
|
49
|
+
(SharedGroups::ALL + Includes::ALL).block_pattern
|
50
|
+
|
51
|
+
def on_block(node)
|
52
|
+
shared_examples(node) do
|
53
|
+
break if last_child?(node)
|
54
|
+
|
55
|
+
missing_separating_line_offense(node) do |method|
|
56
|
+
format(MSG, example: method)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
@@ -1,6 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'rubocop-rspec'
|
4
|
+
require_relative 'base'
|
4
5
|
|
5
6
|
module Gitlab
|
6
7
|
module Styles
|
@@ -17,7 +18,9 @@ module Gitlab
|
|
17
18
|
# # good
|
18
19
|
# expect(page).to have_link('Link', href: 'https://example.com')
|
19
20
|
# expect(page).to have_link('Example')
|
20
|
-
class HaveLinkParameters <
|
21
|
+
class HaveLinkParameters < Base
|
22
|
+
extend RuboCop::Cop::AutoCorrector
|
23
|
+
|
21
24
|
MESSAGE = "The second argument to `have_link` should be a Hash."
|
22
25
|
|
23
26
|
def_node_matcher :unused_parameters?, <<~PATTERN
|
@@ -29,11 +32,13 @@ module Gitlab
|
|
29
32
|
def on_send(node)
|
30
33
|
return unless unused_parameters?(node)
|
31
34
|
|
32
|
-
location = node.arguments[1
|
33
|
-
|
34
|
-
|
35
|
+
location = node.arguments[1..]
|
36
|
+
.map(&:source_range)
|
37
|
+
.reduce(:join)
|
35
38
|
|
36
|
-
add_offense(
|
39
|
+
add_offense(location, message: MESSAGE) do |corrector|
|
40
|
+
corrector.insert_after(location.end, "\n")
|
41
|
+
end
|
37
42
|
end
|
38
43
|
end
|
39
44
|
end
|
@@ -1,6 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'rubocop-rspec'
|
4
|
+
require_relative 'base'
|
4
5
|
|
5
6
|
module Gitlab
|
6
7
|
module Styles
|
@@ -23,7 +24,7 @@ module Gitlab
|
|
23
24
|
# after(:each) do
|
24
25
|
# undo_something
|
25
26
|
# end
|
26
|
-
class SingleLineHook <
|
27
|
+
class SingleLineHook < Base
|
27
28
|
MESSAGE = "Don't use single-line hook blocks."
|
28
29
|
|
29
30
|
def_node_search :rspec_hook?, <<~PATTERN
|
@@ -34,7 +35,7 @@ module Gitlab
|
|
34
35
|
return unless node.single_line?
|
35
36
|
return unless rspec_hook?(node)
|
36
37
|
|
37
|
-
add_offense(node,
|
38
|
+
add_offense(node, message: MESSAGE)
|
38
39
|
end
|
39
40
|
end
|
40
41
|
end
|
@@ -1,6 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'rubocop-rspec'
|
4
|
+
require_relative 'base'
|
4
5
|
|
5
6
|
module Gitlab
|
6
7
|
module Styles
|
@@ -17,7 +18,9 @@ module Gitlab
|
|
17
18
|
# # good
|
18
19
|
# describe MyClass, :js do
|
19
20
|
# end
|
20
|
-
class VerboseIncludeMetadata <
|
21
|
+
class VerboseIncludeMetadata < Base
|
22
|
+
extend RuboCop::Cop::AutoCorrector
|
23
|
+
|
21
24
|
MSG = 'Use `%s` instead of `%s`.'
|
22
25
|
|
23
26
|
SELECTORS = %i[describe context feature example_group it specify example scenario its].freeze
|
@@ -37,25 +40,19 @@ module Gitlab
|
|
37
40
|
|
38
41
|
def on_send(node)
|
39
42
|
invalid_metadata_matches(node) do |match|
|
40
|
-
add_offense(node,
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
def autocorrect(node)
|
45
|
-
lambda do |corrector|
|
46
|
-
invalid_metadata_matches(node) do |match|
|
47
|
-
corrector.replace(match.loc.expression, good(match))
|
43
|
+
add_offense(node, message: format(MSG, good(match), bad(match))) do |corrector|
|
44
|
+
invalid_metadata_matches(node) do |match|
|
45
|
+
corrector.replace(match.loc.expression, good(match))
|
46
|
+
end
|
48
47
|
end
|
49
48
|
end
|
50
49
|
end
|
51
50
|
|
52
51
|
private
|
53
52
|
|
54
|
-
def invalid_metadata_matches(node)
|
53
|
+
def invalid_metadata_matches(node, &block)
|
55
54
|
include_metadata(node) do |matches|
|
56
|
-
matches.select(&method(:invalid_metadata?)).each
|
57
|
-
yield match
|
58
|
-
end
|
55
|
+
matches.select(&method(:invalid_metadata?)).each(&block)
|
59
56
|
end
|
60
57
|
end
|
61
58
|
|
@@ -7,7 +7,7 @@ module Gitlab
|
|
7
7
|
# Returns true if the given node originated from the models directory.
|
8
8
|
def in_model?(node)
|
9
9
|
path = node.location.expression.source_buffer.name
|
10
|
-
pwd =
|
10
|
+
pwd = Dir.pwd
|
11
11
|
models_path = File.join(pwd, 'app', 'models')
|
12
12
|
ee_models_path = File.join(pwd, 'ee', 'app', 'models')
|
13
13
|
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'rubocop-rspec'
|
4
|
+
|
5
|
+
module Gitlab
|
6
|
+
module Styles
|
7
|
+
module Rubocop
|
8
|
+
module Rspec
|
9
|
+
module Helpers
|
10
|
+
include RuboCop::RSpec::Language
|
11
|
+
|
12
|
+
LET = SelectorSet.new(%i[let_it_be]) + RuboCop::RSpec::Language::Helpers::ALL
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
data/rubocop-all.yml
CHANGED
data/rubocop-bundler.yml
CHANGED
@@ -0,0 +1,24 @@
|
|
1
|
+
# Denies the use of ActiveRecord methods outside of configured
|
2
|
+
# excluded directories
|
3
|
+
# Directories that allow the use of the denied methods.
|
4
|
+
# To start we provide a default configuration that matches
|
5
|
+
# a standard Rails app and enable.
|
6
|
+
# The default configuration can be overridden by
|
7
|
+
# providing your own Exclusion list as follows:
|
8
|
+
# CodeReuse/ActiveRecord:
|
9
|
+
# Enabled: true
|
10
|
+
# Exclude:
|
11
|
+
# - app/models/**/*.rb
|
12
|
+
# - config/**/*.rb
|
13
|
+
# - db/**/*.rb
|
14
|
+
# - lib/tasks/**/*.rb
|
15
|
+
# - spec/**/*.rb
|
16
|
+
# - lib/gitlab/**/*.rb
|
17
|
+
CodeReuse/ActiveRecord:
|
18
|
+
Enabled: true
|
19
|
+
Exclude:
|
20
|
+
- app/models/**/*.rb
|
21
|
+
- config/**/*.rb
|
22
|
+
- db/**/*.rb
|
23
|
+
- lib/tasks/**/*.rb
|
24
|
+
- spec/**/*.rb
|
data/rubocop-default.yml
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
---
|
1
2
|
require:
|
2
3
|
- rubocop-gitlab-security
|
3
4
|
- rubocop-performance
|
@@ -12,6 +13,7 @@ inherit_from:
|
|
12
13
|
- rubocop-layout.yml
|
13
14
|
- rubocop-lint.yml
|
14
15
|
- rubocop-metrics.yml
|
16
|
+
- rubocop-migrations.yml
|
15
17
|
- rubocop-naming.yml
|
16
18
|
- rubocop-performance.yml
|
17
19
|
- rubocop-rails.yml
|
data/rubocop-gemspec.yml
CHANGED
data/rubocop-layout.yml
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
---
|
1
2
|
# Check indentation of private/protected visibility modifiers.
|
2
3
|
Layout/AccessModifierIndentation:
|
3
4
|
Enabled: true
|
@@ -60,6 +61,11 @@ Layout/EmptyLines:
|
|
60
61
|
Layout/EmptyLinesAroundAccessModifier:
|
61
62
|
Enabled: true
|
62
63
|
|
64
|
+
# Checks for a newline after an attribute accessor or a group of them
|
65
|
+
# https://docs.rubocop.org/rubocop/0.89/cops_layout.html#layoutemptylinesaroundattributeaccessor
|
66
|
+
Layout/EmptyLinesAroundAttributeAccessor:
|
67
|
+
Enabled: true
|
68
|
+
|
63
69
|
# Keeps track of empty lines around block bodies.
|
64
70
|
Layout/EmptyLinesAroundBlockBody:
|
65
71
|
Enabled: true
|