debian-mirror-gitlab/rubocop/cop/migration/with_lock_retries_disallowed_method.rb

80 lines
2.3 KiB
Ruby
Raw Normal View History

2020-05-24 23:13:21 +05:30
# frozen_string_literal: true
require_relative '../../migration_helpers'
module RuboCop
module Cop
module Migration
class WithLockRetriesDisallowedMethod < RuboCop::Cop::Cop
include MigrationHelpers
ALLOWED_MIGRATION_METHODS = %i[
create_table
2020-07-28 23:09:34 +05:30
create_hash_partitions
2020-05-24 23:13:21 +05:30
drop_table
add_foreign_key
remove_foreign_key
add_column
remove_column
execute
change_column_default
2020-10-24 23:57:45 +05:30
change_column_null
2020-05-24 23:13:21 +05:30
remove_foreign_key_if_exists
remove_foreign_key_without_error
2021-04-17 20:07:23 +05:30
rename_index
2021-09-30 23:02:18 +05:30
rename_constraint
2020-05-24 23:13:21 +05:30
table_exists?
index_exists_by_name?
foreign_key_exists?
index_exists?
column_exists?
2021-04-29 21:17:54 +05:30
create_trigger_to_sync_tables
2020-05-24 23:13:21 +05:30
].sort.freeze
MSG = "The method is not allowed to be called within the `with_lock_retries` block, the only allowed methods are: #{ALLOWED_MIGRATION_METHODS.join(', ')}"
2021-01-03 14:25:43 +05:30
MSG_ONLY_ONE_FK_ALLOWED = "Avoid adding more than one foreign key within the `with_lock_retries`. See https://docs.gitlab.com/ee/development/migration_style_guide.html#examples"
2020-05-24 23:13:21 +05:30
def_node_matcher :send_node?, <<~PATTERN
2021-01-03 14:25:43 +05:30
send
PATTERN
def_node_matcher :add_foreign_key?, <<~PATTERN
(send nil? :add_foreign_key ...)
2020-05-24 23:13:21 +05:30
PATTERN
def on_block(node)
block_body = node.body
return unless in_migration?(node)
return unless block_body
return unless node.method_name == :with_lock_retries
if send_node?(block_body)
check_node(block_body)
else
block_body.children.each { |n| check_node(n) }
end
end
def check_node(node)
return unless send_node?(node)
name = node.children[1]
add_offense(node, location: :expression) unless ALLOWED_MIGRATION_METHODS.include?(name)
2021-01-03 14:25:43 +05:30
add_offense(node, location: :selector, message: MSG_ONLY_ONE_FK_ALLOWED) if multiple_fks?(node)
end
def multiple_fks?(node)
return unless add_foreign_key?(node)
count = node.parent.each_descendant(:send).count do |node|
add_foreign_key?(node)
end
count > 1
2020-05-24 23:13:21 +05:30
end
end
end
end
end