Skip to content

Commit 0b93c25

Browse files
committed
Merge pull request rails#9621 from sakuro/migration-magic-comment-fix
Preserve magic comments and content encoding of copied migrations.
2 parents 3a210da + c3a26c5 commit 0b93c25

File tree

4 files changed

+48
-3
lines changed

4 files changed

+48
-3
lines changed

activerecord/CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
## Rails 4.0.0 (unreleased) ##
22

3+
* When copying migrations, preserve their magic comments and content encoding.
4+
5+
*OZAWA Sakuro*
6+
37
* Fix ActiveRecord `subclass_from_attrs` when `eager_load` is false.
48
It cannot find subclass because all classes are loaded automatically
59
when it needs.

activerecord/lib/active_record/migration.rb

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -634,8 +634,17 @@ def copy(destination, sources, options = {})
634634
source_migrations = ActiveRecord::Migrator.migrations(path)
635635

636636
source_migrations.each do |migration|
637-
source = File.read(migration.filename)
638-
source = "# This migration comes from #{scope} (originally #{migration.version})\n#{source}"
637+
source = File.binread(migration.filename)
638+
inserted_comment = "# This migration comes from #{scope} (originally #{migration.version})\n"
639+
if /\A#.*\b(?:en)?coding:\s*\S+/ =~ source
640+
# If we have a magic comment in the original migration,
641+
# insert our comment after the first newline(end of the magic comment line)
642+
# so the magic keep working.
643+
# Note that magic comments must be at the first line(except sh-bang).
644+
source[/\n/] = "\n#{inserted_comment}"
645+
else
646+
source = "#{inserted_comment}#{source}"
647+
end
639648

640649
if duplicate = destination_migrations.detect { |m| m.name == migration.name }
641650
if options[:on_skip] && duplicate.scope != scope.to_s
@@ -649,7 +658,7 @@ def copy(destination, sources, options = {})
649658
old_path, migration.filename = migration.filename, new_path
650659
last = migration
651660

652-
File.open(migration.filename, "w") { |f| f.write source }
661+
File.binwrite(migration.filename, source)
653662
copied << migration
654663
options[:on_copy].call(scope, migration, old_path) if options[:on_copy]
655664
destination_migrations << migration

activerecord/test/cases/migration_test.rb

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -738,6 +738,26 @@ def test_copying_migrations_with_timestamps_to_destination_with_timestamps_in_fu
738738
clear
739739
end
740740

741+
def test_copying_migrations_preserving_magic_comments
742+
ActiveRecord::Base.timestamped_migrations = false
743+
@migrations_path = MIGRATIONS_ROOT + "/valid"
744+
@existing_migrations = Dir[@migrations_path + "/*.rb"]
745+
746+
copied = ActiveRecord::Migration.copy(@migrations_path, {:bukkits => MIGRATIONS_ROOT + "/magic"})
747+
assert File.exists?(@migrations_path + "/4_currencies_have_symbols.bukkits.rb")
748+
assert_equal [@migrations_path + "/4_currencies_have_symbols.bukkits.rb"], copied.map(&:filename)
749+
750+
expected = "# coding: ISO-8859-15\n# This migration comes from bukkits (originally 1)"
751+
assert_equal expected, IO.readlines(@migrations_path + "/4_currencies_have_symbols.bukkits.rb")[0..1].join.chomp
752+
753+
files_count = Dir[@migrations_path + "/*.rb"].length
754+
copied = ActiveRecord::Migration.copy(@migrations_path, {:bukkits => MIGRATIONS_ROOT + "/magic"})
755+
assert_equal files_count, Dir[@migrations_path + "/*.rb"].length
756+
assert copied.empty?
757+
ensure
758+
clear
759+
end
760+
741761
def test_skipping_migrations
742762
@migrations_path = MIGRATIONS_ROOT + "/valid_with_timestamps"
743763
@existing_migrations = Dir[@migrations_path + "/*.rb"]
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# coding: ISO-8859-15
2+
3+
class CurrenciesHaveSymbols < ActiveRecord::Migration
4+
def self.up
5+
# We use ¤ for default currency symbol
6+
add_column "currencies", "symbol", :string, :default => "¤"
7+
end
8+
9+
def self.down
10+
remove_column "currencies", "symbol"
11+
end
12+
end

0 commit comments

Comments
 (0)