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.
Files changed (68) hide show
  1. checksums.yaml +4 -4
  2. data/.gitlab/changelog_config.yml +13 -0
  3. data/.gitlab/merge_request_templates/Release.md +9 -31
  4. data/.gitlab-ci.yml +3 -1
  5. data/Dangerfile +5 -0
  6. data/gitlab-styles.gemspec +1 -0
  7. data/lib/gitlab/styles/common/banned_constants.rb +28 -0
  8. data/lib/gitlab/styles/rubocop/model_helpers.rb +1 -1
  9. data/lib/gitlab/styles/rubocop.rb +2 -2
  10. data/lib/gitlab/styles/version.rb +1 -1
  11. data/lib/rubocop/cop/active_record_dependent.rb +32 -0
  12. data/lib/rubocop/cop/active_record_serialize.rb +20 -0
  13. data/lib/rubocop/cop/avoid_return_from_blocks.rb +77 -0
  14. data/lib/rubocop/cop/code_reuse/active_record.rb +80 -0
  15. data/lib/rubocop/cop/custom_error_class.rb +69 -0
  16. data/lib/rubocop/cop/fips/md5.rb +27 -0
  17. data/lib/rubocop/cop/fips/open_ssl.rb +31 -0
  18. data/lib/rubocop/cop/fips/sha1.rb +27 -0
  19. data/lib/rubocop/cop/gem_fetcher.rb +37 -0
  20. data/lib/rubocop/cop/in_batches.rb +18 -0
  21. data/lib/rubocop/cop/internal_affairs/deprecate_cop_helper.rb +39 -0
  22. data/lib/rubocop/cop/line_break_after_guard_clauses.rb +100 -0
  23. data/lib/rubocop/cop/line_break_around_conditional_block.rb +128 -0
  24. data/lib/rubocop/cop/migration/update_large_table.rb +60 -0
  25. data/lib/rubocop/cop/performance/rubyzip.rb +35 -0
  26. data/lib/rubocop/cop/polymorphic_associations.rb +25 -0
  27. data/lib/rubocop/cop/rails/include_url_helper.rb +27 -0
  28. data/lib/rubocop/cop/redirect_with_status.rb +46 -0
  29. data/lib/rubocop/cop/rspec/base.rb +14 -0
  30. data/lib/rubocop/cop/rspec/empty_line_after_final_let_it_be.rb +47 -0
  31. data/lib/rubocop/cop/rspec/empty_line_after_let_block.rb +61 -0
  32. data/lib/rubocop/cop/rspec/empty_line_after_shared_example.rb +61 -0
  33. data/lib/rubocop/cop/rspec/example_starting_character.rb +120 -0
  34. data/lib/rubocop/cop/rspec/have_link_parameters.rb +44 -0
  35. data/lib/rubocop/cop/rspec/single_line_hook.rb +41 -0
  36. data/lib/rubocop/cop/rspec/verbose_include_metadata.rb +71 -0
  37. data/lib/rubocop/cop/style/hash_transformation.rb +83 -0
  38. data/lib/rubocop/cop/style/open_struct_use.rb +39 -0
  39. data/lib/rubocop/cop/without_reactive_cache.rb +16 -0
  40. data/rubocop-default.yml +1 -0
  41. data/rubocop-fips.yml +15 -0
  42. data/rubocop-rspec.yml +3 -2
  43. metadata +49 -27
  44. data/lib/gitlab/styles/rubocop/cop/active_record_dependent.rb +0 -32
  45. data/lib/gitlab/styles/rubocop/cop/active_record_serialize.rb +0 -24
  46. data/lib/gitlab/styles/rubocop/cop/code_reuse/active_record.rb +0 -130
  47. data/lib/gitlab/styles/rubocop/cop/custom_error_class.rb +0 -73
  48. data/lib/gitlab/styles/rubocop/cop/gem_fetcher.rb +0 -41
  49. data/lib/gitlab/styles/rubocop/cop/in_batches.rb +0 -22
  50. data/lib/gitlab/styles/rubocop/cop/internal_affairs/deprecate_cop_helper.rb +0 -43
  51. data/lib/gitlab/styles/rubocop/cop/line_break_after_guard_clauses.rb +0 -104
  52. data/lib/gitlab/styles/rubocop/cop/line_break_around_conditional_block.rb +0 -132
  53. data/lib/gitlab/styles/rubocop/cop/migration/update_large_table.rb +0 -64
  54. data/lib/gitlab/styles/rubocop/cop/performance/rubyzip.rb +0 -39
  55. data/lib/gitlab/styles/rubocop/cop/polymorphic_associations.rb +0 -29
  56. data/lib/gitlab/styles/rubocop/cop/rails/include_url_helper.rb +0 -31
  57. data/lib/gitlab/styles/rubocop/cop/redirect_with_status.rb +0 -50
  58. data/lib/gitlab/styles/rubocop/cop/rspec/base.rb +0 -18
  59. data/lib/gitlab/styles/rubocop/cop/rspec/empty_line_after_final_let_it_be.rb +0 -51
  60. data/lib/gitlab/styles/rubocop/cop/rspec/empty_line_after_let_block.rb +0 -65
  61. data/lib/gitlab/styles/rubocop/cop/rspec/empty_line_after_shared_example.rb +0 -65
  62. data/lib/gitlab/styles/rubocop/cop/rspec/example_starting_character.rb +0 -124
  63. data/lib/gitlab/styles/rubocop/cop/rspec/have_link_parameters.rb +0 -48
  64. data/lib/gitlab/styles/rubocop/cop/rspec/single_line_hook.rb +0 -45
  65. data/lib/gitlab/styles/rubocop/cop/rspec/verbose_include_metadata.rb +0 -75
  66. data/lib/gitlab/styles/rubocop/cop/style/hash_transformation.rb +0 -87
  67. data/lib/gitlab/styles/rubocop/cop/style/open_struct_use.rb +0 -43
  68. 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