1
0
Fork 0
mirror of https://github.com/rails/rails.git synced 2022-11-09 12:12:34 -05:00

Ignore origin comment when checking for duplicates on Migration.copy

49ebe51 fixed copying migrations, but existing migrations would still
trigger warnings. The proper way to compare migrations is to ignore
origin lines - if migration is identical it means that we can
silently skip it, regardless where it comes from.
This commit is contained in:
Piotr Sarnacki 2011-12-09 01:49:08 +01:00
parent 652db2fc3e
commit 62d556424a
3 changed files with 58 additions and 5 deletions

View file

@ -461,11 +461,13 @@ module ActiveRecord
source_migrations = ActiveRecord::Migrator.migrations(path) source_migrations = ActiveRecord::Migrator.migrations(path)
source_migrations.each do |migration| source_migrations.each do |migration|
source = File.read(migration.filename).chomp source = File.read(migration.filename)
source = "# This migration comes from #{name} (originally #{migration.version})\n#{source}" source = "# This migration comes from #{name} (originally #{migration.version})\n#{source}"
if duplicate = destination_migrations.detect { |m| m.name == migration.name } if duplicate = destination_migrations.detect { |m| m.name == migration.name }
options[:on_skip].call(name, migration) if File.read(duplicate.filename).chomp != source && options[:on_skip] if options[:on_skip] && !migrations_identical?(File.read(duplicate.filename), source)
options[:on_skip].call(name, migration)
end
next next
end end
@ -491,6 +493,22 @@ module ActiveRecord
"%.3d" % number "%.3d" % number
end end
end end
def migrations_identical?(a, b)
# Due to a bug some of the migrations copied may not have origin comment,
# so we need to ignore it.
remove_origin_comment(a.chomp) == remove_origin_comment(b.chomp)
end
private :migrations_identical?
def remove_origin_comment(migration_source)
if migration_source =~ /^# This migration comes from/
migration_source = migration_source.to_a[1..-1].join
end
migration_source
end
private :remove_origin_comment
end end
# MigrationProxy is used to defer loading of the actual migration classes # MigrationProxy is used to defer loading of the actual migration classes

View file

@ -2203,15 +2203,16 @@ if ActiveRecord::Base.connection.supports_migrations?
@existing_migrations = Dir[@migrations_path + "/*.rb"] @existing_migrations = Dir[@migrations_path + "/*.rb"]
sources = ActiveSupport::OrderedHash.new sources = ActiveSupport::OrderedHash.new
sources[:bukkits] = sources[:omg] = MIGRATIONS_ROOT + "/to_copy_with_timestamps" sources[:bukkits] = MIGRATIONS_ROOT + "/to_copy_with_timestamps"
sources[:omg] = MIGRATIONS_ROOT + "/to_copy_with_name_collision"
skipped = [] skipped = []
on_skip = Proc.new { |name, migration| skipped << "#{name} #{migration.name}" } on_skip = Proc.new { |name, migration| skipped << "#{name} #{migration.name}" }
copied = ActiveRecord::Migration.copy(@migrations_path, sources, :on_skip => on_skip) copied = ActiveRecord::Migration.copy(@migrations_path, sources, :on_skip => on_skip)
assert_equal 2, copied.length assert_equal 2, copied.length
assert_equal 2, skipped.length assert_equal 1, skipped.length
assert_equal ["bukkits PeopleHaveHobbies", "bukkits PeopleHaveDescriptions"], skipped assert_equal ["omg PeopleHaveHobbies"], skipped
ensure ensure
clear clear
end end
@ -2234,6 +2235,31 @@ if ActiveRecord::Base.connection.supports_migrations?
clear clear
end end
def test_skip_ignores_origin_comment
ActiveRecord::Base.timestamped_migrations = false
@migrations_path = MIGRATIONS_ROOT + "/valid"
@existing_migrations = Dir[@migrations_path + "/*.rb"]
sources = ActiveSupport::OrderedHash.new
sources[:bukkits] = MIGRATIONS_ROOT + "/to_copy"
skipped = []
on_skip = Proc.new { |name, migration| skipped << "#{name} #{migration.name}" }
copied = ActiveRecord::Migration.copy(@migrations_path, sources, :on_skip => on_skip)
# remove origin comment
migration = @migrations_path + "/4_people_have_hobbies.rb"
migration_source = File.read(migration).to_a[1..-1].join
File.open(migration, "w") { |f| f.write migration_source }
ActiveRecord::Migration.copy(@migrations_path, sources, :on_skip => on_skip)
assert_equal 2, copied.length
assert_equal 0, skipped.length
ensure
clear
end
def test_copying_migrations_to_non_existing_directory def test_copying_migrations_to_non_existing_directory
@migrations_path = MIGRATIONS_ROOT + "/non_existing" @migrations_path = MIGRATIONS_ROOT + "/non_existing"
@existing_migrations = [] @existing_migrations = []

View file

@ -0,0 +1,9 @@
class PeopleHaveLastNames < ActiveRecord::Migration
def self.up
add_column "people", "hobbies", :string
end
def self.down
remove_column "people", "hobbies"
end
end