From 0c8fe729ff1d4e67bbd211209c691f2816ab6f02 Mon Sep 17 00:00:00 2001 From: Tim Geoghegan Date: Tue, 13 Jun 2023 11:21:09 -0700 Subject: [PATCH] Traverse symlinks when resolving migrations (#2445) * Traverse symlinks when resolving migrations When enumerating the source directory seeking migration files, `sqlx` ignores entries that aren't files. This was previously reported as #614 and fixed in #985 but apparently regressed somewhere along the way. This commit reintroduces the fix from #985 to the current implementation: use `std::fs::metadata` instead of `std::fs::DirEntry::metadata`. The former is documented to traverse symlinks; the latter does not. * add migrations_symlink test --- sqlx-core/src/migrate/source.rs | 3 ++- tests/migrate/macro.rs | 3 +++ tests/migrate/migrations_symlink | 1 + 3 files changed, 6 insertions(+), 1 deletion(-) create mode 120000 tests/migrate/migrations_symlink diff --git a/sqlx-core/src/migrate/source.rs b/sqlx-core/src/migrate/source.rs index 609f4fde..10a18b36 100644 --- a/sqlx-core/src/migrate/source.rs +++ b/sqlx-core/src/migrate/source.rs @@ -24,7 +24,8 @@ impl<'s> MigrationSource<'s> for &'s Path { let mut migrations = Vec::new(); while let Some(entry) = s.next().await? { - if !entry.metadata.is_file() { + // std::fs::metadata traverses symlinks + if !std::fs::metadata(&entry.path)?.is_file() { // not a file; ignore continue; } diff --git a/tests/migrate/macro.rs b/tests/migrate/macro.rs index da7f9019..03cb578f 100644 --- a/tests/migrate/macro.rs +++ b/tests/migrate/macro.rs @@ -3,15 +3,18 @@ use std::path::Path; static EMBEDDED_SIMPLE: Migrator = sqlx::migrate!("tests/migrate/migrations_simple"); static EMBEDDED_REVERSIBLE: Migrator = sqlx::migrate!("tests/migrate/migrations_reversible"); +static EMBEDDED_SYMLINK: Migrator = sqlx::migrate!("tests/migrate/migrations_symlink"); #[sqlx_macros::test] async fn same_output() -> anyhow::Result<()> { let runtime_simple = Migrator::new(Path::new("tests/migrate/migrations_simple")).await?; let runtime_reversible = Migrator::new(Path::new("tests/migrate/migrations_reversible")).await?; + let runtime_symlink = Migrator::new(Path::new("tests/migrate/migrations_symlink")).await?; assert_same(&EMBEDDED_SIMPLE, &runtime_simple); assert_same(&EMBEDDED_REVERSIBLE, &runtime_reversible); + assert_same(&EMBEDDED_SYMLINK, &runtime_symlink); Ok(()) } diff --git a/tests/migrate/migrations_symlink b/tests/migrate/migrations_symlink new file mode 120000 index 00000000..433d9439 --- /dev/null +++ b/tests/migrate/migrations_symlink @@ -0,0 +1 @@ +migrations_simple \ No newline at end of file