aboutsummaryrefslogtreecommitdiffhomepage
path: root/crates/shirabe/src/util/filesystem.rs
diff options
context:
space:
mode:
authornsfisis <nsfisis@gmail.com>2026-06-06 19:31:45 +0900
committernsfisis <nsfisis@gmail.com>2026-06-06 19:31:45 +0900
commitd9090c4c52fa29ee1569aedf8be858bf78001d7b (patch)
treecd78e31a6853fb51da4473242552d98add45443d /crates/shirabe/src/util/filesystem.rs
parent57e9f6a1c6cf47d222343f2469ecbb91c569f9e1 (diff)
downloadphp-shirabe-d9090c4c52fa29ee1569aedf8be858bf78001d7b.tar.gz
php-shirabe-d9090c4c52fa29ee1569aedf8be858bf78001d7b.tar.zst
php-shirabe-d9090c4c52fa29ee1569aedf8be858bf78001d7b.zip
feat(filesystem): model iterator failure to restore removal retry
RecursiveDirectoryIterator construction can throw UnexpectedValueException; the shim now returns a Result so remove_directory_php can re-create the iterator once after clearstatcache()/usleep, mirroring Composer's retry for the spurious failures in composer/composer#4009. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Diffstat (limited to 'crates/shirabe/src/util/filesystem.rs')
-rw-r--r--crates/shirabe/src/util/filesystem.rs34
1 files changed, 24 insertions, 10 deletions
diff --git a/crates/shirabe/src/util/filesystem.rs b/crates/shirabe/src/util/filesystem.rs
index c7f3583..da9369e 100644
--- a/crates/shirabe/src/util/filesystem.rs
+++ b/crates/shirabe/src/util/filesystem.rs
@@ -219,11 +219,25 @@ impl Filesystem {
return Ok(r);
}
- // PHP: $it = new RecursiveDirectoryIterator($directory, RecursiveDirectoryIterator::SKIP_DOTS);
- // TODO(phase-b): PHP throws UnexpectedValueException on iterator creation failure;
- // shim signature does not yet model this. Skipping the retry/clearstatcache branch.
- let it =
- shirabe_php_shim::recursive_directory_iterator(directory, shirabe_php_shim::SKIP_DOTS);
+ let it = match shirabe_php_shim::recursive_directory_iterator(
+ directory,
+ shirabe_php_shim::SKIP_DOTS,
+ ) {
+ Ok(it) => it,
+ Err(_e) => {
+ // re-try once after clearing the stat cache if it failed as it
+ // sometimes fails without apparent reason, see https://github.com/composer/composer/issues/4009
+ clearstatcache();
+ usleep(100000);
+ if !is_dir(directory) {
+ return Ok(true);
+ }
+ shirabe_php_shim::recursive_directory_iterator(
+ directory,
+ shirabe_php_shim::SKIP_DOTS,
+ )?
+ }
+ };
let ri = shirabe_php_shim::recursive_iterator_iterator(it, shirabe_php_shim::CHILD_FIRST);
for file in &ri {
@@ -420,7 +434,7 @@ impl Filesystem {
}
let it =
- shirabe_php_shim::recursive_directory_iterator(source, shirabe_php_shim::SKIP_DOTS);
+ shirabe_php_shim::recursive_directory_iterator(source, shirabe_php_shim::SKIP_DOTS)?;
let ri = shirabe_php_shim::recursive_iterator_iterator(it, shirabe_php_shim::SELF_FIRST);
self.ensure_directory_exists(&target)?;
@@ -660,7 +674,7 @@ impl Filesystem {
.into());
}
if is_dir(path) {
- return Ok(self.directory_size(path));
+ return self.directory_size(path);
}
Ok(filesize(path).unwrap_or(0))
@@ -801,9 +815,9 @@ impl Filesystem {
false
}
- pub(crate) fn directory_size(&self, directory: &str) -> i64 {
+ pub(crate) fn directory_size(&self, directory: &str) -> anyhow::Result<i64> {
let it =
- shirabe_php_shim::recursive_directory_iterator(directory, shirabe_php_shim::SKIP_DOTS);
+ shirabe_php_shim::recursive_directory_iterator(directory, shirabe_php_shim::SKIP_DOTS)?;
let ri = shirabe_php_shim::recursive_iterator_iterator(it, shirabe_php_shim::CHILD_FIRST);
let mut size: i64 = 0;
@@ -813,7 +827,7 @@ impl Filesystem {
}
}
- size
+ Ok(size)
}
pub(crate) fn get_process(&mut self) -> std::cell::RefMut<'_, ProcessExecutor> {