gitlab-styles 6.6.0 → 8.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 +4 -4
- data/.gitlab/changelog_config.yml +13 -0
- data/.gitlab/merge_request_templates/Release.md +9 -31
- data/.gitlab-ci.yml +3 -1
- data/Dangerfile +5 -0
- data/gitlab-styles.gemspec +1 -0
- data/lib/gitlab/styles/common/banned_constants.rb +28 -0
- data/lib/gitlab/styles/rubocop/model_helpers.rb +1 -1
- data/lib/gitlab/styles/rubocop.rb +2 -2
- data/lib/gitlab/styles/version.rb +1 -1
- data/lib/rubocop/cop/active_record_dependent.rb +32 -0
- data/lib/rubocop/cop/active_record_serialize.rb +20 -0
- data/lib/rubocop/cop/avoid_return_from_blocks.rb +77 -0
- data/lib/rubocop/cop/code_reuse/active_record.rb +80 -0
- data/lib/rubocop/cop/custom_error_class.rb +69 -0
- data/lib/rubocop/cop/fips/md5.rb +27 -0
- data/lib/rubocop/cop/fips/open_ssl.rb +31 -0
- data/lib/rubocop/cop/fips/sha1.rb +27 -0
- data/lib/rubocop/cop/gem_fetcher.rb +37 -0
- data/lib/rubocop/cop/in_batches.rb +18 -0
- data/lib/rubocop/cop/internal_affairs/deprecate_cop_helper.rb +39 -0
- data/lib/rubocop/cop/line_break_after_guard_clauses.rb +100 -0
- data/lib/rubocop/cop/line_break_around_conditional_block.rb +128 -0
- data/lib/rubocop/cop/migration/update_large_table.rb +60 -0
- data/lib/rubocop/cop/performance/rubyzip.rb +35 -0
- data/lib/rubocop/cop/polymorphic_associations.rb +25 -0
- data/lib/rubocop/cop/rails/include_url_helper.rb +27 -0
- data/lib/rubocop/cop/redirect_with_status.rb +46 -0
- data/lib/rubocop/cop/rspec/base.rb +14 -0
- data/lib/rubocop/cop/rspec/empty_line_after_final_let_it_be.rb +47 -0
- data/lib/rubocop/cop/rspec/empty_line_after_let_block.rb +61 -0
- data/lib/rubocop/cop/rspec/empty_line_after_shared_example.rb +61 -0
- data/lib/rubocop/cop/rspec/example_starting_character.rb +120 -0
- data/lib/rubocop/cop/rspec/have_link_parameters.rb +44 -0
- data/lib/rubocop/cop/rspec/single_line_hook.rb +41 -0
- data/lib/rubocop/cop/rspec/verbose_include_metadata.rb +71 -0
- data/lib/rubocop/cop/style/hash_transformation.rb +83 -0
- data/lib/rubocop/cop/style/open_struct_use.rb +39 -0
- data/lib/rubocop/cop/without_reactive_cache.rb +16 -0
- data/rubocop-default.yml +1 -0
- data/rubocop-fips.yml +15 -0
- data/rubocop-rspec.yml +3 -2
- metadata +49 -27
- data/lib/gitlab/styles/rubocop/cop/active_record_dependent.rb +0 -32
- data/lib/gitlab/styles/rubocop/cop/active_record_serialize.rb +0 -24
- data/lib/gitlab/styles/rubocop/cop/code_reuse/active_record.rb +0 -130
- data/lib/gitlab/styles/rubocop/cop/custom_error_class.rb +0 -73
- data/lib/gitlab/styles/rubocop/cop/gem_fetcher.rb +0 -41
- data/lib/gitlab/styles/rubocop/cop/in_batches.rb +0 -22
- data/lib/gitlab/styles/rubocop/cop/internal_affairs/deprecate_cop_helper.rb +0 -43
- data/lib/gitlab/styles/rubocop/cop/line_break_after_guard_clauses.rb +0 -104
- data/lib/gitlab/styles/rubocop/cop/line_break_around_conditional_block.rb +0 -132
- data/lib/gitlab/styles/rubocop/cop/migration/update_large_table.rb +0 -64
- data/lib/gitlab/styles/rubocop/cop/performance/rubyzip.rb +0 -39
- data/lib/gitlab/styles/rubocop/cop/polymorphic_associations.rb +0 -29
- data/lib/gitlab/styles/rubocop/cop/rails/include_url_helper.rb +0 -31
- data/lib/gitlab/styles/rubocop/cop/redirect_with_status.rb +0 -50
- data/lib/gitlab/styles/rubocop/cop/rspec/base.rb +0 -18
- data/lib/gitlab/styles/rubocop/cop/rspec/empty_line_after_final_let_it_be.rb +0 -51
- data/lib/gitlab/styles/rubocop/cop/rspec/empty_line_after_let_block.rb +0 -65
- data/lib/gitlab/styles/rubocop/cop/rspec/empty_line_after_shared_example.rb +0 -65
- data/lib/gitlab/styles/rubocop/cop/rspec/example_starting_character.rb +0 -124
- data/lib/gitlab/styles/rubocop/cop/rspec/have_link_parameters.rb +0 -48
- data/lib/gitlab/styles/rubocop/cop/rspec/single_line_hook.rb +0 -45
- data/lib/gitlab/styles/rubocop/cop/rspec/verbose_include_metadata.rb +0 -75
- data/lib/gitlab/styles/rubocop/cop/style/hash_transformation.rb +0 -87
- data/lib/gitlab/styles/rubocop/cop/style/open_struct_use.rb +0 -43
- data/lib/gitlab/styles/rubocop/cop/without_reactive_cache.rb +0 -20
@@ -1,130 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Gitlab
|
4
|
-
module Styles
|
5
|
-
module Rubocop
|
6
|
-
module Cop
|
7
|
-
module CodeReuse
|
8
|
-
# Cop that denies the use of ActiveRecord methods outside of models.
|
9
|
-
class ActiveRecord < RuboCop::Cop::Cop
|
10
|
-
MSG = 'This method can only be used inside an ActiveRecord model: ' \
|
11
|
-
'https://gitlab.com/gitlab-org/gitlab-foss/issues/49653'
|
12
|
-
|
13
|
-
# Various methods from ActiveRecord::Querying that are denied. We
|
14
|
-
# exclude some generic ones such as `any?` and `first`, as these may
|
15
|
-
# lead to too many false positives, since `Array` also supports these
|
16
|
-
# methods.
|
17
|
-
#
|
18
|
-
# The keys of this Hash are the denied method names. The values are
|
19
|
-
# booleans that indicate if the method should only be denied if any
|
20
|
-
# arguments are provided.
|
21
|
-
NOT_ALLOWED = {
|
22
|
-
average: true,
|
23
|
-
calculate: true,
|
24
|
-
count_by_sql: true,
|
25
|
-
create_with: true,
|
26
|
-
distinct: false,
|
27
|
-
eager_load: true,
|
28
|
-
exists?: true,
|
29
|
-
find_by: true,
|
30
|
-
find_by!: true,
|
31
|
-
find_by_sql: true,
|
32
|
-
find_each: true,
|
33
|
-
find_in_batches: true,
|
34
|
-
find_or_create_by: true,
|
35
|
-
find_or_create_by!: true,
|
36
|
-
find_or_initialize_by: true,
|
37
|
-
first!: false,
|
38
|
-
first_or_create: true,
|
39
|
-
first_or_create!: true,
|
40
|
-
first_or_initialize: true,
|
41
|
-
from: true,
|
42
|
-
group: true,
|
43
|
-
having: true,
|
44
|
-
ids: false,
|
45
|
-
includes: true,
|
46
|
-
joins: true,
|
47
|
-
lock: false,
|
48
|
-
many?: false,
|
49
|
-
offset: true,
|
50
|
-
order: true,
|
51
|
-
pluck: true,
|
52
|
-
preload: true,
|
53
|
-
readonly: false,
|
54
|
-
references: true,
|
55
|
-
reorder: true,
|
56
|
-
rewhere: true,
|
57
|
-
take: false,
|
58
|
-
take!: false,
|
59
|
-
unscope: false,
|
60
|
-
where: false,
|
61
|
-
with: true
|
62
|
-
}.freeze
|
63
|
-
|
64
|
-
def on_send(node)
|
65
|
-
receiver = node.children[0]
|
66
|
-
send_name = node.children[1]
|
67
|
-
first_arg = node.children[2]
|
68
|
-
|
69
|
-
return unless receiver && NOT_ALLOWED.key?(send_name)
|
70
|
-
|
71
|
-
# If the rule requires an argument to be given, but none are
|
72
|
-
# provided, we won't register an offense. This prevents us from
|
73
|
-
# adding offenses for `project.group`, while still covering
|
74
|
-
# `Project.group(:name)`.
|
75
|
-
return if NOT_ALLOWED[send_name] && !first_arg
|
76
|
-
|
77
|
-
add_offense(node, location: :selector)
|
78
|
-
end
|
79
|
-
|
80
|
-
# We can not auto correct code like this, as it requires manual
|
81
|
-
# refactoring. Instead, we'll just allow the surrounding scope.
|
82
|
-
#
|
83
|
-
# Despite this method's presence, you should not use it. This method
|
84
|
-
# exists to make it possible to allow large chunks of offenses we
|
85
|
-
# can't fix in the short term. If you are writing new code, follow the
|
86
|
-
# code reuse guidelines, instead of allowing any new offenses.
|
87
|
-
def autocorrect(node)
|
88
|
-
scope = surrounding_scope_of(node)
|
89
|
-
indent = indentation_of(scope)
|
90
|
-
|
91
|
-
lambda do |corrector|
|
92
|
-
# This prevents us from inserting the same enable/disable comment
|
93
|
-
# for a method or block that has multiple offenses.
|
94
|
-
next if allowed_scopes.include?(scope)
|
95
|
-
|
96
|
-
corrector.insert_before(
|
97
|
-
scope.source_range,
|
98
|
-
"# rubocop: disable #{cop_name}\n#{indent}"
|
99
|
-
)
|
100
|
-
|
101
|
-
corrector.insert_after(
|
102
|
-
scope.source_range,
|
103
|
-
"\n#{indent}# rubocop: enable #{cop_name}"
|
104
|
-
)
|
105
|
-
|
106
|
-
allowed_scopes << scope
|
107
|
-
end
|
108
|
-
end
|
109
|
-
|
110
|
-
def indentation_of(node)
|
111
|
-
' ' * node.loc.expression.source_line[/\A */].length
|
112
|
-
end
|
113
|
-
|
114
|
-
def surrounding_scope_of(node)
|
115
|
-
%i[def defs block begin].each do |type|
|
116
|
-
if (found = node.each_ancestor(type).first)
|
117
|
-
return found
|
118
|
-
end
|
119
|
-
end
|
120
|
-
end
|
121
|
-
|
122
|
-
def allowed_scopes
|
123
|
-
@allowed_scopes ||= Set.new
|
124
|
-
end
|
125
|
-
end
|
126
|
-
end
|
127
|
-
end
|
128
|
-
end
|
129
|
-
end
|
130
|
-
end
|
@@ -1,73 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Gitlab
|
4
|
-
module Styles
|
5
|
-
module Rubocop
|
6
|
-
module Cop
|
7
|
-
# This cop makes sure that custom error classes, when empty, are declared
|
8
|
-
# with Class.new.
|
9
|
-
#
|
10
|
-
# @example
|
11
|
-
# # bad
|
12
|
-
# class FooError < StandardError
|
13
|
-
# end
|
14
|
-
#
|
15
|
-
# # okish
|
16
|
-
# class FooError < StandardError; end
|
17
|
-
#
|
18
|
-
# # good
|
19
|
-
# FooError = Class.new(StandardError)
|
20
|
-
class CustomErrorClass < RuboCop::Cop::Cop
|
21
|
-
MSG = 'Use `Class.new(SuperClass)` to define an empty custom error class.'
|
22
|
-
|
23
|
-
def on_class(node)
|
24
|
-
parent = node.parent_class
|
25
|
-
body = node.body
|
26
|
-
|
27
|
-
return if body
|
28
|
-
|
29
|
-
parent_klass = class_name_from_node(parent)
|
30
|
-
|
31
|
-
return unless parent_klass&.to_s&.end_with?('Error')
|
32
|
-
|
33
|
-
add_offense(node)
|
34
|
-
end
|
35
|
-
|
36
|
-
def autocorrect(node)
|
37
|
-
klass = node.identifier
|
38
|
-
parent = node.parent_class
|
39
|
-
|
40
|
-
replacement = "#{class_name_from_node(klass)} = Class.new(#{class_name_from_node(parent)})"
|
41
|
-
|
42
|
-
lambda do |corrector|
|
43
|
-
corrector.replace(node.source_range, replacement)
|
44
|
-
end
|
45
|
-
end
|
46
|
-
|
47
|
-
private
|
48
|
-
|
49
|
-
# The nested constant `Foo::Bar::Baz` looks like:
|
50
|
-
#
|
51
|
-
# s(:const,
|
52
|
-
# s(:const,
|
53
|
-
# s(:const, nil, :Foo), :Bar), :Baz)
|
54
|
-
#
|
55
|
-
# So recurse through that to get the name as written in the source.
|
56
|
-
#
|
57
|
-
def class_name_from_node(node, suffix = nil)
|
58
|
-
return unless node&.type == :const
|
59
|
-
|
60
|
-
name = node.children[1].to_s
|
61
|
-
name = "#{name}::#{suffix}" if suffix
|
62
|
-
|
63
|
-
if node.children[0]
|
64
|
-
class_name_from_node(node.children[0], name)
|
65
|
-
else
|
66
|
-
name
|
67
|
-
end
|
68
|
-
end
|
69
|
-
end
|
70
|
-
end
|
71
|
-
end
|
72
|
-
end
|
73
|
-
end
|
@@ -1,41 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Gitlab
|
4
|
-
module Styles
|
5
|
-
module Rubocop
|
6
|
-
module Cop
|
7
|
-
# This cop prevents usage of the `git` and `github` arguments to `gem` in a
|
8
|
-
# `Gemfile` in order to avoid additional points of failure beyond
|
9
|
-
# rubygems.org.
|
10
|
-
class GemFetcher < RuboCop::Cop::Cop
|
11
|
-
MSG = 'Do not use gems from git repositories, only use gems from RubyGems.'
|
12
|
-
|
13
|
-
GIT_KEYS = [:git, :github].freeze
|
14
|
-
|
15
|
-
def on_send(node)
|
16
|
-
return unless gemfile?(node)
|
17
|
-
|
18
|
-
func_name = node.children[1]
|
19
|
-
return unless func_name == :gem
|
20
|
-
|
21
|
-
node.children.last.each_node(:pair) do |pair|
|
22
|
-
key_name = pair.children[0].children[0].to_sym
|
23
|
-
add_offense(node, location: pair.source_range) if GIT_KEYS.include?(key_name)
|
24
|
-
end
|
25
|
-
end
|
26
|
-
|
27
|
-
private
|
28
|
-
|
29
|
-
def gemfile?(node)
|
30
|
-
node
|
31
|
-
.location
|
32
|
-
.expression
|
33
|
-
.source_buffer
|
34
|
-
.name
|
35
|
-
.end_with?("Gemfile")
|
36
|
-
end
|
37
|
-
end
|
38
|
-
end
|
39
|
-
end
|
40
|
-
end
|
41
|
-
end
|
@@ -1,22 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require_relative '../model_helpers'
|
4
|
-
|
5
|
-
module Gitlab
|
6
|
-
module Styles
|
7
|
-
module Rubocop
|
8
|
-
module Cop
|
9
|
-
# Cop that prevents the use of `in_batches`
|
10
|
-
class InBatches < RuboCop::Cop::Cop
|
11
|
-
MSG = 'Do not use `in_batches`, use `each_batch` from the EachBatch module instead'
|
12
|
-
|
13
|
-
def on_send(node)
|
14
|
-
return unless node.children[1] == :in_batches
|
15
|
-
|
16
|
-
add_offense(node, location: :selector)
|
17
|
-
end
|
18
|
-
end
|
19
|
-
end
|
20
|
-
end
|
21
|
-
end
|
22
|
-
end
|
@@ -1,43 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Gitlab
|
4
|
-
module Styles
|
5
|
-
module Rubocop
|
6
|
-
module Cop
|
7
|
-
module InternalAffairs
|
8
|
-
# Cop that denies the use of CopHelper.
|
9
|
-
class DeprecateCopHelper < RuboCop::Cop::Cop
|
10
|
-
MSG = 'Do not use `CopHelper` or methods from it, use improved patterns described in https://www.rubydoc.info/gems/rubocop/RuboCop/RSpec/ExpectOffense'
|
11
|
-
|
12
|
-
def_node_matcher :cop_helper, <<~PATTERN
|
13
|
-
(send nil? ${:include :extend :prepend}
|
14
|
-
(const _ {:CopHelper}))
|
15
|
-
PATTERN
|
16
|
-
|
17
|
-
def_node_search :cop_helper_method, <<~PATTERN
|
18
|
-
(send nil? {:inspect_source :inspect_source_file :parse_source :autocorrect_source_file :autocorrect_source :_investigate} ...)
|
19
|
-
PATTERN
|
20
|
-
|
21
|
-
def_node_search :cop_helper_method_on_instance, <<~PATTERN
|
22
|
-
(send (send nil? _) {:messages :highlights :offenses} ...)
|
23
|
-
PATTERN
|
24
|
-
|
25
|
-
def on_send(node)
|
26
|
-
cop_helper(node) do
|
27
|
-
add_offense(node)
|
28
|
-
end
|
29
|
-
|
30
|
-
cop_helper_method(node) do
|
31
|
-
add_offense(node)
|
32
|
-
end
|
33
|
-
|
34
|
-
cop_helper_method_on_instance(node) do
|
35
|
-
add_offense(node)
|
36
|
-
end
|
37
|
-
end
|
38
|
-
end
|
39
|
-
end
|
40
|
-
end
|
41
|
-
end
|
42
|
-
end
|
43
|
-
end
|
@@ -1,104 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Gitlab
|
4
|
-
module Styles
|
5
|
-
module Rubocop
|
6
|
-
module Cop
|
7
|
-
# Ensures a line break after guard clauses.
|
8
|
-
#
|
9
|
-
# @example
|
10
|
-
# # bad
|
11
|
-
# return unless condition
|
12
|
-
# do_stuff
|
13
|
-
#
|
14
|
-
# # good
|
15
|
-
# return unless condition
|
16
|
-
#
|
17
|
-
# do_stuff
|
18
|
-
#
|
19
|
-
# # bad
|
20
|
-
# raise if condition
|
21
|
-
# do_stuff
|
22
|
-
#
|
23
|
-
# # good
|
24
|
-
# raise if condition
|
25
|
-
#
|
26
|
-
# do_stuff
|
27
|
-
#
|
28
|
-
# Multiple guard clauses are allowed without
|
29
|
-
# line break.
|
30
|
-
#
|
31
|
-
# # good
|
32
|
-
# return unless condition_a
|
33
|
-
# return unless condition_b
|
34
|
-
#
|
35
|
-
# do_stuff
|
36
|
-
#
|
37
|
-
# Guard clauses in case statement are allowed without
|
38
|
-
# line break.
|
39
|
-
#
|
40
|
-
# # good
|
41
|
-
# case model
|
42
|
-
# when condition_a
|
43
|
-
# return true unless condition_b
|
44
|
-
# when
|
45
|
-
# ...
|
46
|
-
# end
|
47
|
-
#
|
48
|
-
# Guard clauses before end are allowed without
|
49
|
-
# line break.
|
50
|
-
#
|
51
|
-
# # good
|
52
|
-
# if condition_a
|
53
|
-
# do_something
|
54
|
-
# else
|
55
|
-
# do_something_else
|
56
|
-
# return unless condition
|
57
|
-
# end
|
58
|
-
#
|
59
|
-
# do_something_more
|
60
|
-
class LineBreakAfterGuardClauses < RuboCop::Cop::Cop
|
61
|
-
MSG = 'Add a line break after guard clauses'
|
62
|
-
|
63
|
-
def_node_matcher :guard_clause_node?, <<-PATTERN
|
64
|
-
[{(send nil? {:raise :fail :throw} ...) return break next} single_line?]
|
65
|
-
PATTERN
|
66
|
-
|
67
|
-
def on_if(node)
|
68
|
-
return unless node.single_line?
|
69
|
-
return unless guard_clause?(node)
|
70
|
-
return if next_line(node).blank? || clause_last_line?(next_line(node)) || guard_clause?(next_sibling(node))
|
71
|
-
|
72
|
-
add_offense(node)
|
73
|
-
end
|
74
|
-
|
75
|
-
def autocorrect(node)
|
76
|
-
lambda do |corrector|
|
77
|
-
corrector.insert_after(node.loc.expression, "\n")
|
78
|
-
end
|
79
|
-
end
|
80
|
-
|
81
|
-
private
|
82
|
-
|
83
|
-
def guard_clause?(node)
|
84
|
-
return false unless node.if_type?
|
85
|
-
|
86
|
-
guard_clause_node?(node.if_branch)
|
87
|
-
end
|
88
|
-
|
89
|
-
def next_sibling(node)
|
90
|
-
node.parent.children[node.sibling_index + 1]
|
91
|
-
end
|
92
|
-
|
93
|
-
def next_line(node)
|
94
|
-
processed_source[node.loc.line]
|
95
|
-
end
|
96
|
-
|
97
|
-
def clause_last_line?(line)
|
98
|
-
line =~ /^\s*(?:end|elsif|else|when|rescue|ensure)/
|
99
|
-
end
|
100
|
-
end
|
101
|
-
end
|
102
|
-
end
|
103
|
-
end
|
104
|
-
end
|
@@ -1,132 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Gitlab
|
4
|
-
module Styles
|
5
|
-
module Rubocop
|
6
|
-
module Cop
|
7
|
-
# Ensures a line break around conditional blocks.
|
8
|
-
#
|
9
|
-
# @example
|
10
|
-
# # bad
|
11
|
-
# do_something
|
12
|
-
# if condition
|
13
|
-
# do_extra_stuff
|
14
|
-
# end
|
15
|
-
# do_something_more
|
16
|
-
#
|
17
|
-
# # good
|
18
|
-
# do_something
|
19
|
-
#
|
20
|
-
# if condition
|
21
|
-
# do_extra_stuff
|
22
|
-
# end
|
23
|
-
#
|
24
|
-
# do_something_more
|
25
|
-
#
|
26
|
-
# # bad
|
27
|
-
# do_something
|
28
|
-
# unless condition
|
29
|
-
# do_extra_stuff
|
30
|
-
# end
|
31
|
-
#
|
32
|
-
# do_something_more
|
33
|
-
#
|
34
|
-
# # good
|
35
|
-
# def a_method
|
36
|
-
# if condition
|
37
|
-
# do_something
|
38
|
-
# end
|
39
|
-
# end
|
40
|
-
#
|
41
|
-
# # good
|
42
|
-
# on_block do
|
43
|
-
# if condition
|
44
|
-
# do_something
|
45
|
-
# end
|
46
|
-
# end
|
47
|
-
class LineBreakAroundConditionalBlock < RuboCop::Cop::Cop
|
48
|
-
include RuboCop::Cop::RangeHelp
|
49
|
-
|
50
|
-
MSG = 'Add a line break around conditional blocks'
|
51
|
-
|
52
|
-
def on_if(node)
|
53
|
-
# This cop causes errors in haml files, so let's skip those
|
54
|
-
return if in_haml?(node)
|
55
|
-
return if node.single_line?
|
56
|
-
return unless node.if? || node.unless?
|
57
|
-
|
58
|
-
add_offense(node) unless previous_line_valid?(node)
|
59
|
-
add_offense(node) unless last_line_valid?(node)
|
60
|
-
end
|
61
|
-
|
62
|
-
def autocorrect(node)
|
63
|
-
lambda do |corrector|
|
64
|
-
line = range_by_whole_lines(node.source_range)
|
65
|
-
|
66
|
-
corrector.insert_before(line, "\n") unless previous_line_valid?(node)
|
67
|
-
corrector.insert_after(line, "\n") unless last_line_valid?(node)
|
68
|
-
end
|
69
|
-
end
|
70
|
-
|
71
|
-
private
|
72
|
-
|
73
|
-
def previous_line_valid?(node)
|
74
|
-
previous_line(node).empty? ||
|
75
|
-
start_clause_line?(previous_line(node)) ||
|
76
|
-
block_start?(previous_line(node)) ||
|
77
|
-
begin_line?(previous_line(node)) ||
|
78
|
-
assignment_line?(previous_line(node)) ||
|
79
|
-
rescue_line?(previous_line(node))
|
80
|
-
end
|
81
|
-
|
82
|
-
def last_line_valid?(node)
|
83
|
-
last_line(node).empty? ||
|
84
|
-
end_line?(last_line(node)) ||
|
85
|
-
end_clause_line?(last_line(node))
|
86
|
-
end
|
87
|
-
|
88
|
-
def previous_line(node)
|
89
|
-
processed_source[node.loc.line - 2]
|
90
|
-
end
|
91
|
-
|
92
|
-
def last_line(node)
|
93
|
-
processed_source[node.loc.last_line]
|
94
|
-
end
|
95
|
-
|
96
|
-
def start_clause_line?(line)
|
97
|
-
line =~ /^\s*(def|=end|#|module|class|if|unless|else|elsif|ensure|when)/
|
98
|
-
end
|
99
|
-
|
100
|
-
def end_clause_line?(line)
|
101
|
-
line =~ /^\s*(#|rescue|else|elsif|when)/
|
102
|
-
end
|
103
|
-
|
104
|
-
def begin_line?(line)
|
105
|
-
# an assignment followed by a begin or ust a begin
|
106
|
-
line =~ /^\s*(@?(\w|\|+|=|\[|\]|\s)+begin|begin)/
|
107
|
-
end
|
108
|
-
|
109
|
-
def assignment_line?(line)
|
110
|
-
line =~ /^\s*.*=/
|
111
|
-
end
|
112
|
-
|
113
|
-
def rescue_line?(line)
|
114
|
-
line =~ /^\s*rescue/
|
115
|
-
end
|
116
|
-
|
117
|
-
def block_start?(line)
|
118
|
-
line.match(/ (do|{)( \|.*?\|)?\s?(#.+)?\z/)
|
119
|
-
end
|
120
|
-
|
121
|
-
def end_line?(line)
|
122
|
-
line =~ /^\s*(end|})/
|
123
|
-
end
|
124
|
-
|
125
|
-
def in_haml?(node)
|
126
|
-
node.location.expression.source_buffer.name.end_with?('.haml.rb')
|
127
|
-
end
|
128
|
-
end
|
129
|
-
end
|
130
|
-
end
|
131
|
-
end
|
132
|
-
end
|
@@ -1,64 +0,0 @@
|
|
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
|
@@ -1,39 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Gitlab
|
4
|
-
module Styles
|
5
|
-
module Rubocop
|
6
|
-
module Cop
|
7
|
-
module Performance
|
8
|
-
# This cop flags inefficient uses of rubyzip's Zip::File, since when instantiated
|
9
|
-
# it reads the file's Central Directory into memory entirely. For zips with many
|
10
|
-
# files and directories, this can be very expensive even when the archive's size
|
11
|
-
# in bytes is small.
|
12
|
-
#
|
13
|
-
# See also:
|
14
|
-
# - https://github.com/rubyzip/rubyzip/issues/506
|
15
|
-
# - https://github.com/rubyzip/rubyzip#notes-on-zipinputstream
|
16
|
-
class Rubyzip < RuboCop::Cop::Cop
|
17
|
-
MSG = 'Be careful when opening or iterating zip files via Zip::File. ' \
|
18
|
-
'Zip archives may contain many entries, and their file index is ' \
|
19
|
-
'read into memory upon construction, which can lead to ' \
|
20
|
-
'high memory use and poor performance. ' \
|
21
|
-
'Consider iterating archive entries via Zip::InputStream instead.'
|
22
|
-
|
23
|
-
def_node_matcher :reads_central_directory?, <<-PATTERN
|
24
|
-
(send
|
25
|
-
(const
|
26
|
-
(const {nil? (cbase)} :Zip) :File) {:new :open :foreach} ...)
|
27
|
-
PATTERN
|
28
|
-
|
29
|
-
def on_send(node)
|
30
|
-
return unless reads_central_directory?(node)
|
31
|
-
|
32
|
-
add_offense(node)
|
33
|
-
end
|
34
|
-
end
|
35
|
-
end
|
36
|
-
end
|
37
|
-
end
|
38
|
-
end
|
39
|
-
end
|
@@ -1,29 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require_relative '../model_helpers'
|
4
|
-
|
5
|
-
module Gitlab
|
6
|
-
module Styles
|
7
|
-
module Rubocop
|
8
|
-
module Cop
|
9
|
-
# Cop that prevents the use of polymorphic associations
|
10
|
-
class PolymorphicAssociations < RuboCop::Cop::Cop
|
11
|
-
include ModelHelpers
|
12
|
-
|
13
|
-
MSG = 'Do not use polymorphic associations, use separate tables instead'
|
14
|
-
|
15
|
-
def on_send(node)
|
16
|
-
return unless in_model?(node)
|
17
|
-
return unless node.children[1] == :belongs_to
|
18
|
-
|
19
|
-
node.children.last.each_node(:pair) do |pair|
|
20
|
-
key_name = pair.children[0].children[0]
|
21
|
-
|
22
|
-
add_offense(pair) if key_name == :polymorphic
|
23
|
-
end
|
24
|
-
end
|
25
|
-
end
|
26
|
-
end
|
27
|
-
end
|
28
|
-
end
|
29
|
-
end
|