otwarchive-symphonyarchive/rubocop/cop/migration/large_table_schema_update.rb
2026-03-11 22:22:11 +00:00

61 lines
1.8 KiB
Ruby

# frozen_string_literal: true
module RuboCop
module Cop
module Migration
# Checks that migrations updating the schema of large tables,
# as defined in the configuration, do so safely. As of writing,
# this involves utilizing the `uses_departure!` helper.
#
# @example
# # good
# class ExampleMigration < ActiveRecord::Migration[6.1]
# uses_departure! if Rails.env.staging? || Rails.env.production?
#
# add_column :users, :new_field, :integer, nullable: true
# end
#
# @example
# # bad
# class ExampleMigration < ActiveRecord::Migration[6.1]
# add_column :users, :new_field, :integer, nullable: true
# end
class LargeTableSchemaUpdate < RuboCop::Cop::Base
MSG = "Use departure to change the schema of large table `%s`"
# @!method uses_departure?(node)
def_node_search :uses_departure?, <<~PATTERN
(send nil? :uses_departure!)
PATTERN
# @!method schema_changes(node)
def_node_search :schema_changes, <<~PATTERN
$(send nil? _ (sym $_) ...)
PATTERN
def on_class(node)
return unless in_migration?(node)
return if uses_departure?(node)
schema_changes(node).each do |change_node, table_name|
next unless large_tables.include?(table_name.to_s)
add_offense(change_node.loc.expression, message: format(MSG, table_name), severity: :warning)
end
end
private
def large_tables
cop_config["Tables"] || []
end
def in_migration?(node)
filename = node.location.expression.source_buffer.name
directory = File.dirname(filename)
directory.end_with?("db/migrate")
end
end
end
end
end