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

Fix rake db:migrate:status with subdirectories

`db:migrate` supports subdirectories and have a test.

https://github.com/rails/rails/blob/v5.1.0.beta1/activerecord/test/cases/migrator_test.rb#L78-L85

But `db:migrate:status` doesn't work with subdirectories. It is due to
`Dir.foreach(path)` is not the same with `Dir["#{path}/**/[0-9]*_*.rb"]`.

I extracted `migration_files` and sharing it in the both to fix the
issue. And added tests for `db:migrate:status`.
This commit is contained in:
Ryuta Kamizono 2016-05-28 13:46:59 +09:00 committed by Andrew White
parent 0d73f9116c
commit 7b49c5e2f5
4 changed files with 75 additions and 24 deletions

View file

@ -1,3 +1,7 @@
* Fix `rake db:migrate:status` with subdirectories.
*Ryuta Kamizono*
* Don't share options between reference id and type columns
When using a polymorphic reference column in a migration, sharing options

View file

@ -1056,10 +1056,6 @@ module ActiveRecord
Array(@migrations_paths)
end
def match_to_migration_filename?(filename) # :nodoc:
Migration::MigrationFilenameRegexp.match?(File.basename(filename))
end
def parse_migration_filename(filename) # :nodoc:
File.basename(filename).scan(Migration::MigrationFilenameRegexp).first
end
@ -1067,9 +1063,7 @@ module ActiveRecord
def migrations(paths)
paths = Array(paths)
files = Dir[*paths.map { |p| "#{p}/**/[0-9]*_*.rb" }]
migrations = files.map do |file|
migrations = migration_files(paths).map do |file|
version, name, scope = parse_migration_filename(file)
raise IllegalMigrationNameError.new(file) unless version
version = version.to_i
@ -1081,6 +1075,30 @@ module ActiveRecord
migrations.sort_by(&:version)
end
def migrations_status(paths)
paths = Array(paths)
db_list = ActiveRecord::SchemaMigration.normalized_versions
file_list = migration_files(paths).map do |file|
version, name, scope = parse_migration_filename(file)
raise IllegalMigrationNameError.new(file) unless version
version = ActiveRecord::SchemaMigration.normalize_migration_number(version)
status = db_list.delete(version) ? "up" : "down"
[status, version, (name + scope).humanize]
end.compact
db_list.map! do |version|
["up", version, "********** NO FILE **********"]
end
(db_list + file_list).sort_by { |_, version, _| version }
end
def migration_files(paths)
Dir[*paths.flat_map { |path| "#{path}/**/[0-9]*_*.rb" }]
end
private
def move(direction, migrations_paths, steps)

View file

@ -110,28 +110,13 @@ db_namespace = namespace :db do
unless ActiveRecord::SchemaMigration.table_exists?
abort "Schema migrations table does not exist yet."
end
db_list = ActiveRecord::SchemaMigration.normalized_versions
file_list =
ActiveRecord::Tasks::DatabaseTasks.migrations_paths.flat_map do |path|
Dir.foreach(path).map do |file|
next unless ActiveRecord::Migrator.match_to_migration_filename?(file)
version, name, scope = ActiveRecord::Migrator.parse_migration_filename(file)
version = ActiveRecord::SchemaMigration.normalize_migration_number(version)
status = db_list.delete(version) ? "up" : "down"
[status, version, (name + scope).humanize]
end.compact
end
db_list.map! do |version|
["up", version, "********** NO FILE **********"]
end
# output
puts "\ndatabase: #{ActiveRecord::Base.connection_config[:database]}\n\n"
puts "#{'Status'.center(8)} #{'Migration ID'.ljust(14)} Migration Name"
puts "-" * 50
(db_list + file_list).sort_by { |_, version, _| version }.each do |status, version, name|
paths = ActiveRecord::Tasks::DatabaseTasks.migrations_paths
ActiveRecord::Migrator.migrations_status(paths).each do |status, version, name|
puts "#{status.center(8)} #{version.ljust(14)} #{name}"
end
puts

View file

@ -124,6 +124,50 @@ class MigratorTest < ActiveRecord::TestCase
assert_equal migration_list.last, migrations.first
end
def test_migrations_status
path = MIGRATIONS_ROOT + "/valid"
ActiveRecord::SchemaMigration.create(version: 2)
ActiveRecord::SchemaMigration.create(version: 10)
assert_equal [
["down", "001", "Valid people have last names"],
["up", "002", "We need reminders"],
["down", "003", "Innocent jointable"],
["up", "010", "********** NO FILE **********"],
], ActiveRecord::Migrator.migrations_status(path)
end
def test_migrations_status_in_subdirectories
path = MIGRATIONS_ROOT + "/valid_with_subdirectories"
ActiveRecord::SchemaMigration.create(version: 2)
ActiveRecord::SchemaMigration.create(version: 10)
assert_equal [
["down", "001", "Valid people have last names"],
["up", "002", "We need reminders"],
["down", "003", "Innocent jointable"],
["up", "010", "********** NO FILE **********"],
], ActiveRecord::Migrator.migrations_status(path)
end
def test_migrations_status_from_two_directories
paths = [MIGRATIONS_ROOT + "/valid_with_timestamps", MIGRATIONS_ROOT + "/to_copy_with_timestamps"]
ActiveRecord::SchemaMigration.create(version: "20100101010101")
ActiveRecord::SchemaMigration.create(version: "20160528010101")
assert_equal [
["down", "20090101010101", "People have hobbies"],
["down", "20090101010202", "People have descriptions"],
["up", "20100101010101", "Valid with timestamps people have last names"],
["down", "20100201010101", "Valid with timestamps we need reminders"],
["down", "20100301010101", "Valid with timestamps innocent jointable"],
["up", "20160528010101", "********** NO FILE **********"],
], ActiveRecord::Migrator.migrations_status(paths)
end
def test_migrator_interleaved_migrations
pass_one = [Sensor.new("One", 1)]