Skip to content

Commit 5865ad5

Browse files
arzezakvprigent
authored andcommitted
Make status command find migrations in subdirectories
Previously, `db:migrate:status:with_data` used `Dir.foreach` and `Dir.children`, which only scan the top-level migration directory. As a result, archived migrations placed in subdirectories (e.g., `db/migrate/archive/`) appeared as "*** NO SCHEMA FILE ***" even though they existed in the database. The fix switches to `Dir.glob` with a recursive `**/*.rb` pattern and then filters by matching file basenames against `/(\d{14})_(.+)\\.rb/`, enabling the command to find migrations in nested directories and correctly report their status. This ensures that migrations stored anywhere under the migration paths are recognized and displayed accurately in the status output. Before: ``` ~/Project (main) % bundle exec rake db:migrate:status | grep 20210323133030 up 20210323133030 Create resource ~/Project (main) % bundle exec rake db:migrate:status:with_data | grep 20210323133030 up 20210323133030 *** NO SCHEMA FILE ***``` ``` After: ``` ~/Project (main) % bundle exec rake db:migrate:status | grep 20210323133030 up 20210323133030 Create resource ~/Project (main|!|+) % bundle exec rake db:migrate:status:with_data | grep 20210323133030 up schema 20210323133030 Create resource ```
1 parent a59d19a commit 5865ad5

File tree

2 files changed

+56
-9
lines changed

2 files changed

+56
-9
lines changed

lib/data_migrate/tasks/data_migrate_tasks.rb

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -56,22 +56,24 @@ def status_with_schema
5656
file_list = []
5757

5858
migrations_paths.each do |path|
59-
Dir.foreach(File.join(Rails.root, path)) do |file|
59+
Dir.glob(File.join(Rails.root, path, "**", "*.rb")).each do |file_path|
6060
# only files matching "20091231235959_some_name.rb" pattern
61-
if match_data = /(\d{14})_(.+)\.rb/.match(file)
61+
if match_data = /(\d{14})_(.+)\.rb/.match(File.basename(file_path))
6262
status = db_list_data.delete(match_data[1]) ? 'up' : 'down'
6363
file_list << [status, match_data[1], match_data[2], 'data']
6464
end
6565
end
6666
end
6767

68-
DataMigrate::SchemaMigration.migrations_paths.map do |path|
69-
Dir.children(path) if Dir.exist?(path)
70-
end.flatten.compact.each do |file|
71-
# only files matching "20091231235959_some_name.rb" pattern
72-
if match_data = /(\d{14})_(.+)\.rb/.match(file)
73-
status = db_list_schema.delete(match_data[1]) ? 'up' : 'down'
74-
file_list << [status, match_data[1], match_data[2], 'schema']
68+
DataMigrate::SchemaMigration.migrations_paths.each do |path|
69+
next unless Dir.exist?(path)
70+
71+
Dir.glob("#{path}/**/*.rb").each do |file_path|
72+
# only files matching "20091231235959_some_name.rb" pattern
73+
if match_data = /(\d{14})_(.+)\.rb/.match(File.basename(file_path))
74+
status = db_list_schema.delete(match_data[1]) ? 'up' : 'down'
75+
file_list << [status, match_data[1], match_data[2], 'schema']
76+
end
7577
end
7678
end
7779

spec/data_migrate/tasks/data_migrate_tasks_spec.rb

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,5 +125,50 @@
125125
}.to output(match(/up data 20091231235959 Some name/)
126126
.and match(/down schema 20131111111111 Late migration/)).to_stdout
127127
end
128+
129+
context "with migrations in subdirectories" do
130+
let(:archive_dir) { "spec/db/data/archive" }
131+
let(:archived_schema_dir) { "spec/db/migrate/archived" }
132+
133+
before do
134+
FileUtils.mkdir_p(archive_dir)
135+
FileUtils.mkdir_p(archived_schema_dir)
136+
137+
File.write("#{archive_dir}/20101010101010_archived_data.rb", <<~RUBY)
138+
class ArchivedData < ActiveRecord::Migration[6.1]
139+
end
140+
RUBY
141+
142+
File.write("#{archived_schema_dir}/20121212121212_archived_schema.rb", <<~RUBY)
143+
class ArchivedSchema < ActiveRecord::Migration[6.1]
144+
end
145+
RUBY
146+
147+
ActiveRecord::Base.connection.execute(<<~SQL.squish)
148+
INSERT INTO data_migrations (version) VALUES ('20101010101010')
149+
SQL
150+
end
151+
152+
after do
153+
FileUtils.rm_rf(archive_dir)
154+
FileUtils.rm_rf(archived_schema_dir)
155+
end
156+
157+
it "should find and display data migrations in subdirectories" do
158+
expect {
159+
DataMigrate::Tasks::DataMigrateTasks.status
160+
}.to output(match(/up 20091231235959 Some name/)
161+
.and match(/up 20101010101010 Archived data/)).to_stdout
162+
end
163+
164+
it "should find and display schema migrations in subdirectories" do
165+
expect {
166+
DataMigrate::Tasks::DataMigrateTasks.status_with_schema
167+
}.to output(match(/up data 20091231235959 Some name/)
168+
.and match(/up data 20101010101010 Archived data/)
169+
.and match(/down schema 20121212121212 Archived schema/)
170+
.and match(/down schema 20131111111111 Late migration/)).to_stdout
171+
end
172+
end
128173
end
129174
end

0 commit comments

Comments
 (0)