diff --git a/Cargo.lock b/Cargo.lock index 3473f4dc6..75a848fc9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -125,7 +125,7 @@ dependencies = [ "same-file 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "tempdir 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", "thread_local 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", - "walkdir 2.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "walkdir 2.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -331,7 +331,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "walkdir" -version = "2.1.3" +version = "2.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "same-file 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -401,7 +401,7 @@ dependencies = [ "checksum unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "382810877fe448991dfc7f0dd6e3ae5d58088fd0ea5e35189655f84e6814fa56" "checksum utf8-ranges 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "662fab6525a98beff2921d7f61a39e7d59e0b425ebc7d0d9e66d316e55124122" "checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" -"checksum walkdir 2.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "b167e9a4420d8dddb260e70c90a4a375a1e5691f21f70e715553da87b6c2503a" +"checksum walkdir 2.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "63636bd0eb3d00ccb8b9036381b526efac53caf112b7783b730ab3f8e44da369" "checksum winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "04e3bd221fcbe8a271359c04f21a76db7d0c6028862d1bb5512d85e1e2eb5bb3" "checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" "checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" diff --git a/ignore/src/walk.rs b/ignore/src/walk.rs index 6a260f854..c185a2887 100644 --- a/ignore/src/walk.rs +++ b/ignore/src/walk.rs @@ -249,6 +249,14 @@ struct DirEntryRaw { /// The underlying inode number (Unix only). #[cfg(unix)] ino: u64, + /// The underlying metadata (Windows only). We store this on Windows + /// because this comes for free while reading a directory. + /// + /// We use this to determine whether an entry is a directory or not, which + /// works around a bug in Rust's standard library: + /// https://github.com/rust-lang/rust/issues/46484 + #[cfg(windows)] + metadata: fs::Metadata, } impl fmt::Debug for DirEntryRaw { @@ -274,6 +282,20 @@ impl DirEntryRaw { } fn metadata(&self) -> Result { + self.metadata_internal() + } + + #[cfg(windows)] + fn metadata_internal(&self) -> Result { + if self.follow_link { + fs::metadata(&self.path) + } else { + Ok(self.metadata.clone()) + }.map_err(|err| Error::Io(io::Error::from(err)).with_path(&self.path)) + } + + #[cfg(not(windows))] + fn metadata_internal(&self) -> Result { if self.follow_link { fs::metadata(&self.path) } else { @@ -309,21 +331,29 @@ impl DirEntryRaw { err: Box::new(err), } })?; - Ok(DirEntryRaw::from_entry_os(depth, ent, ty)) + DirEntryRaw::from_entry_os(depth, ent, ty) } - #[cfg(not(unix))] + #[cfg(windows)] fn from_entry_os( depth: usize, ent: &fs::DirEntry, ty: fs::FileType, - ) -> DirEntryRaw { - DirEntryRaw { + ) -> Result { + let md = ent.metadata().map_err(|err| { + let err = Error::Io(io::Error::from(err)).with_path(ent.path()); + Error::WithDepth { + depth: depth, + err: Box::new(err), + } + })?; + Ok(DirEntryRaw { path: ent.path(), ty: ty, follow_link: false, depth: depth, - } + metadata: md, + }) } #[cfg(unix)] @@ -331,16 +361,16 @@ impl DirEntryRaw { depth: usize, ent: &fs::DirEntry, ty: fs::FileType, - ) -> DirEntryRaw { + ) -> Result { use std::os::unix::fs::DirEntryExt; - DirEntryRaw { + Ok(DirEntryRaw { path: ent.path(), ty: ty, follow_link: false, depth: depth, ino: ent.ino(), - } + }) } #[cfg(not(unix))] @@ -353,6 +383,7 @@ impl DirEntryRaw { ty: md.file_type(), follow_link: true, depth: depth, + metadata: md, }) }