Commit 722a6c53 authored by Robert Speicher's avatar Robert Speicher

Merge branch 'migration-cops' into 'master'

Added RuboCop cops for checking DB migrations

See merge request !4906
parents 293cf090 c740445a
require: rubocop-rspec
require:
- rubocop-rspec
- ./rubocop/rubocop
AllCops:
TargetRubyVersion: 2.1
......
module RuboCop
module Cop
module Migration
# Cop that checks if indexes are added in a concurrent manner.
class AddIndex < RuboCop::Cop::Cop
include MigrationHelpers
MSG = 'add_index requires downtime, use add_concurrent_index instead'
def on_def(node)
return unless in_migration?(node)
new_tables = []
node.each_descendant(:send) do |send_node|
first_arg = first_argument(send_node)
# The first argument of "create_table" / "add_index" is the table
# name.
new_tables << first_arg if create_table?(send_node)
next if method_name(send_node) != :add_index
# Using "add_index" is fine for newly created tables as there's no
# data in these tables yet.
next if new_tables.include?(first_arg)
add_offense(send_node, :selector)
end
end
def create_table?(node)
method_name(node) == :create_table
end
def method_name(node)
node.children[1]
end
def first_argument(node)
node.children[2] ? node.children[0] : nil
end
end
end
end
end
module RuboCop
module Cop
module Migration
# Cop that checks if columns are added in a way that doesn't require
# downtime.
class ColumnWithDefault < RuboCop::Cop::Cop
include MigrationHelpers
WHITELISTED_TABLES = [:application_settings]
MSG = 'add_column with a default value requires downtime, ' \
'use add_column_with_default instead'
def on_send(node)
return unless in_migration?(node)
name = node.children[1]
return unless name == :add_column
# Ignore whitelisted tables.
return if table_whitelisted?(node.children[2])
opts = node.children.last
return unless opts && opts.type == :hash
opts.each_node(:pair) do |pair|
if hash_key_type(pair) == :sym && hash_key_name(pair) == :default
add_offense(node, :selector)
end
end
end
def table_whitelisted?(symbol)
symbol && symbol.type == :sym &&
WHITELISTED_TABLES.include?(symbol.children[0])
end
def hash_key_type(pair)
pair.children[0].type
end
def hash_key_name(pair)
pair.children[0].children[0]
end
end
end
end
end
module RuboCop
# Module containing helper methods for writing migration cops.
module MigrationHelpers
# Returns true if the given node originated from the db/migrate directory.
def in_migration?(node)
File.dirname(node.location.expression.source_buffer.name).
end_with?('db/migrate')
end
end
end
require_relative 'migration_helpers'
require_relative 'cop/migration/add_index'
require_relative 'cop/migration/column_with_default'
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment