From e068a9d644fde6659a88accd55b3f1d0d9d7cf46 Mon Sep 17 00:00:00 2001 From: nsfisis Date: Sat, 23 May 2026 03:07:15 +0900 Subject: refactor(promise): rewrite promise bodies to async/await Mechanically convert promise-returning function bodies to async/await: resolve() returns the value directly, forwarding calls get .await, and simple .then chains become await sequences. Also collapse the installer double-Option (Result>> -> Result>). Hard spots that depend on the Loop::wait / job-machine boundary (accept/reject orchestration, closures capturing &mut self, batch waits) are left intact and marked with TODO(phase-c-promise) for manual porting. The crate does not compile yet; traits still need #[async_trait]. Co-Authored-By: Claude Opus 4.7 --- .../shirabe/src/installer/installation_manager.rs | 32 +++++---- crates/shirabe/src/installer/library_installer.rs | 75 +++++++++------------- .../shirabe/src/installer/metapackage_installer.rs | 24 ++----- crates/shirabe/src/installer/noop_installer.rs | 24 ++----- crates/shirabe/src/installer/plugin_installer.rs | 48 +++++--------- crates/shirabe/src/installer/project_installer.rs | 15 ++--- 6 files changed, 82 insertions(+), 136 deletions(-) (limited to 'crates/shirabe/src/installer') diff --git a/crates/shirabe/src/installer/installation_manager.rs b/crates/shirabe/src/installer/installation_manager.rs index 114f1fc..ae0470a 100644 --- a/crates/shirabe/src/installer/installation_manager.rs +++ b/crates/shirabe/src/installer/installation_manager.rs @@ -285,6 +285,8 @@ impl InstallationManager { download_only: bool, all_operations: Vec>, ) -> Result<()> { + // TODO(phase-c-promise): Loop::wait-driven batch orchestration (download/cleanup promises); + // rewrite to await collected futures once the async Loop boundary lands. let mut promises: Vec> = vec![]; for (index, operation) in &operations { @@ -401,6 +403,8 @@ impl InstallationManager { run_scripts: bool, all_operations: &[Box], ) -> Result<()> { + // TODO(phase-c-promise): Loop::wait-driven batch orchestration (prepare/install promises); + // rewrite to await collected futures once the async Loop boundary lands. let mut promises: Vec> = vec![]; let mut post_exec_callbacks: Vec> = vec![]; @@ -513,6 +517,7 @@ impl InstallationManager { /// @param array> $promises fn wait_on_promises(&mut self, promises: Vec>) { + // TODO(phase-c-promise): thin wrapper over Loop::wait (the async boundary owned separately). let mut progress: Option<()> = None; // TODO(phase-b): self.io instanceof ConsoleIO downcast let io_is_console = false; @@ -541,7 +546,7 @@ impl InstallationManager { /// @phpstan-return PromiseInterface|null pub async fn download(&mut self, package: &dyn PackageInterface) -> Option { let installer = self.get_installer(package.get_type()).ok()?; - let promise = installer.cleanup("install", package, None).ok()?; + let promise = installer.cleanup("install", package, None).await.ok()?; promise } @@ -556,7 +561,7 @@ impl InstallationManager { ) -> Option { let package = operation.get_package(); let installer = self.get_installer(package.get_type()).ok()?; - let promise = installer.install(repo, package).ok()?; + let promise = installer.install(repo, package).await.ok()?; self.mark_for_notification(package); promise @@ -578,24 +583,19 @@ impl InstallationManager { let promise = if initial_type == target_type { let installer = self.get_installer(initial_type).ok()?; - let promise = installer.update(repo, initial, target).ok()?; + let promise = installer.update(repo, initial, target).await.ok()?; self.mark_for_notification(target); promise } else { - let promise = self + // PHP: uninstall initial, then install target via the target-type installer. + let _ = self .get_installer(initial_type) .ok()? .uninstall(repo, initial) + .await .ok()?; - let promise = match promise { - Some(p) => p, - None => promise::resolve(None), - }; - - let target_type = target_type.to_string(); - // TODO(phase-b): promise.then(closure capturing self/installer) - let _ = target_type; - Some(promise) + let installer = self.get_installer(target_type).ok()?; + installer.install(repo, target).await.ok()? }; promise @@ -612,7 +612,7 @@ impl InstallationManager { let package = operation.get_package(); let installer = self.get_installer(package.get_type()).ok()?; - installer.uninstall(repo, package).ok()? + installer.uninstall(repo, package).await.ok()? } /// Executes markAliasInstalled operation. @@ -653,6 +653,8 @@ impl InstallationManager { } pub fn notify_installs(&mut self, _io: &dyn IOInterface) { + // TODO(phase-c-promise): collects http_downloader.add() promises and drives them via Loop::wait; + // rewrite to await the collected futures once the async Loop boundary lands. let mut promises: Vec> = vec![]; let result: Result<()> = (|| -> Result<()> { @@ -802,6 +804,8 @@ impl InstallationManager { &mut self, cleanup_promises: &IndexMap Option>>>, ) { + // TODO(phase-c-promise): runs cleanup closures and drives them via Loop::wait; + // rewrite once the async Loop boundary and async cleanup closures land. let mut promises: Vec> = vec![]; self.loop_.borrow().abort_jobs(); diff --git a/crates/shirabe/src/installer/library_installer.rs b/crates/shirabe/src/installer/library_installer.rs index a9a77e9..0629de5 100644 --- a/crates/shirabe/src/installer/library_installer.rs +++ b/crates/shirabe/src/installer/library_installer.rs @@ -137,11 +137,10 @@ impl LibraryInstaller { ) -> Result> { let download_path = self.get_install_path(package).unwrap(); - Ok(Some( - self.get_download_manager() - .borrow() - .install(package, &download_path)?, - )) + self.get_download_manager() + .borrow() + .install(package, &download_path) + .await } /// @return PromiseInterface|null @@ -159,19 +158,9 @@ impl LibraryInstaller { if strpos(&initial_download_path, &target_download_path) == Some(0) || strpos(&target_download_path, &initial_download_path) == Some(0) { - let promise = self.remove_code(initial)?; - let promise = match promise { - Some(p) => p, - None => shirabe_external_packages::react::promise::resolve(None), - }; - - // TODO(phase-b): promise.then expects Option) -> Option>> - // arguments. Translating the original PHP closure (which captures &self and target) - // requires restructuring; tracked separately. - let _ = promise; - return Ok(Some(todo!( - "promise.then(...) chain to install_code(target)" - ))); + // PHP: return $this->removeCode($initial)->then(fn () => $this->installCode($target)); + let _ = self.remove_code(initial).await?; + return self.install_code(target).await; } self.filesystem @@ -179,11 +168,10 @@ impl LibraryInstaller { .rename(&initial_download_path, &target_download_path); } - Ok(Some(self.get_download_manager().borrow().update( - initial, - target, - &target_download_path, - )?)) + self.get_download_manager() + .borrow() + .update(initial, target, &target_download_path) + .await } /// @return PromiseInterface|null @@ -194,11 +182,10 @@ impl LibraryInstaller { ) -> Result> { let download_path = self.get_package_base_path(package); - Ok(Some( - self.get_download_manager() - .borrow() - .remove(package, &download_path)?, - )) + self.get_download_manager() + .borrow() + .remove(package, &download_path) + .await } pub(crate) fn initialize_vendor_dir(&mut self) { @@ -275,11 +262,10 @@ impl InstallerInterface for LibraryInstaller { // self.initialize_vendor_dir(); let download_path = self.get_install_path(package).unwrap(); - Ok(Some(self.get_download_manager().borrow().download( - package, - &download_path, - prev_package, - )?)) + self.get_download_manager() + .borrow() + .download(package, &download_path, prev_package) + .await } async fn prepare( @@ -292,12 +278,10 @@ impl InstallerInterface for LibraryInstaller { // self.initialize_vendor_dir(); let download_path = self.get_install_path(package).unwrap(); - Ok(Some(self.get_download_manager().borrow().prepare( - r#type, - package, - &download_path, - prev_package, - )?)) + self.get_download_manager() + .borrow() + .prepare(r#type, package, &download_path, prev_package) + .await } async fn cleanup( @@ -310,12 +294,10 @@ impl InstallerInterface for LibraryInstaller { // self.initialize_vendor_dir(); let download_path = self.get_install_path(package).unwrap(); - Ok(Some(self.get_download_manager().borrow().cleanup( - r#type, - package, - &download_path, - prev_package, - )?)) + self.get_download_manager() + .borrow() + .cleanup(r#type, package, &download_path, prev_package) + .await } async fn install( @@ -332,6 +314,7 @@ impl InstallerInterface for LibraryInstaller { self.binary_installer.remove_binaries(package); } + // TODO(phase-c-promise): rewrite install_code().then(installBinaries + repo.addPackage) as an await sequence. let promise = self.install_code(package)?; let promise = match promise { Some(p) => p, @@ -365,6 +348,7 @@ impl InstallerInterface for LibraryInstaller { // self.initialize_vendor_dir(); self.binary_installer.remove_binaries(initial); + // TODO(phase-c-promise): rewrite update_code().then(installBinaries + repo updates) as an await sequence. let promise = self.update_code(initial, target)?; let promise = match promise { Some(p) => p, @@ -393,6 +377,7 @@ impl InstallerInterface for LibraryInstaller { .into()); } + // TODO(phase-c-promise): rewrite remove_code().then(remove_binaries/remove_package/rmdir) as an await sequence. let promise = self.remove_code(package)?; let promise = match promise { Some(p) => p, diff --git a/crates/shirabe/src/installer/metapackage_installer.rs b/crates/shirabe/src/installer/metapackage_installer.rs index f6d6133..23d92f2 100644 --- a/crates/shirabe/src/installer/metapackage_installer.rs +++ b/crates/shirabe/src/installer/metapackage_installer.rs @@ -40,9 +40,7 @@ impl InstallerInterface for MetapackageInstaller { _package: &dyn PackageInterface, _prev_package: Option<&dyn PackageInterface>, ) -> Result> { - Ok(Some(shirabe_external_packages::react::promise::resolve( - None, - ))) + Ok(None) } async fn prepare( @@ -51,9 +49,7 @@ impl InstallerInterface for MetapackageInstaller { _package: &dyn PackageInterface, _prev_package: Option<&dyn PackageInterface>, ) -> Result> { - Ok(Some(shirabe_external_packages::react::promise::resolve( - None, - ))) + Ok(None) } async fn cleanup( @@ -62,9 +58,7 @@ impl InstallerInterface for MetapackageInstaller { _package: &dyn PackageInterface, _prev_package: Option<&dyn PackageInterface>, ) -> Result> { - Ok(Some(shirabe_external_packages::react::promise::resolve( - None, - ))) + Ok(None) } async fn install( @@ -80,9 +74,7 @@ impl InstallerInterface for MetapackageInstaller { repo.add_package(package.clone_package_box()); - Ok(Some(shirabe_external_packages::react::promise::resolve( - None, - ))) + Ok(None) } async fn update( @@ -108,9 +100,7 @@ impl InstallerInterface for MetapackageInstaller { repo.remove_package(initial); repo.add_package(target.clone_package_box()); - Ok(Some(shirabe_external_packages::react::promise::resolve( - None, - ))) + Ok(None) } async fn uninstall( @@ -134,9 +124,7 @@ impl InstallerInterface for MetapackageInstaller { repo.remove_package(package); - Ok(Some(shirabe_external_packages::react::promise::resolve( - None, - ))) + Ok(None) } fn get_install_path(&self, _package: &dyn PackageInterface) -> Option { diff --git a/crates/shirabe/src/installer/noop_installer.rs b/crates/shirabe/src/installer/noop_installer.rs index 263caca..68e4ef8 100644 --- a/crates/shirabe/src/installer/noop_installer.rs +++ b/crates/shirabe/src/installer/noop_installer.rs @@ -26,9 +26,7 @@ impl InstallerInterface for NoopInstaller { _package: &dyn PackageInterface, _prev_package: Option<&dyn PackageInterface>, ) -> anyhow::Result> { - Ok(Some(shirabe_external_packages::react::promise::resolve( - None, - ))) + Ok(None) } async fn prepare( @@ -37,9 +35,7 @@ impl InstallerInterface for NoopInstaller { _package: &dyn PackageInterface, _prev_package: Option<&dyn PackageInterface>, ) -> anyhow::Result> { - Ok(Some(shirabe_external_packages::react::promise::resolve( - None, - ))) + Ok(None) } async fn cleanup( @@ -48,9 +44,7 @@ impl InstallerInterface for NoopInstaller { _package: &dyn PackageInterface, _prev_package: Option<&dyn PackageInterface>, ) -> anyhow::Result> { - Ok(Some(shirabe_external_packages::react::promise::resolve( - None, - ))) + Ok(None) } async fn install( @@ -62,9 +56,7 @@ impl InstallerInterface for NoopInstaller { repo.add_package(package.clone_package_box()); } - Ok(Some(shirabe_external_packages::react::promise::resolve( - None, - ))) + Ok(None) } async fn update( @@ -86,9 +78,7 @@ impl InstallerInterface for NoopInstaller { repo.add_package(target.clone_package_box()); } - Ok(Some(shirabe_external_packages::react::promise::resolve( - None, - ))) + Ok(None) } async fn uninstall( @@ -105,9 +95,7 @@ impl InstallerInterface for NoopInstaller { } repo.remove_package(package); - Ok(Some(shirabe_external_packages::react::promise::resolve( - None, - ))) + Ok(None) } fn get_install_path(&self, package: &dyn PackageInterface) -> Option { diff --git a/crates/shirabe/src/installer/plugin_installer.rs b/crates/shirabe/src/installer/plugin_installer.rs index fd1fc99..4f9918e 100644 --- a/crates/shirabe/src/installer/plugin_installer.rs +++ b/crates/shirabe/src/installer/plugin_installer.rs @@ -96,7 +96,7 @@ impl InstallerInterface for PluginInstaller { let _ = plugin_optional; } - self.inner.prepare(r#type, package, prev_package) + self.inner.prepare(r#type, package, prev_package).await } async fn download( @@ -116,7 +116,7 @@ impl InstallerInterface for PluginInstaller { }.into()); } - self.inner.download(package, prev_package) + self.inner.download(package, prev_package).await } async fn install( @@ -124,22 +124,13 @@ impl InstallerInterface for PluginInstaller { repo: &mut dyn InstalledRepositoryInterface, package: &dyn PackageInterface, ) -> Result> { - let promise = self.inner.install(repo, package)?; - let promise = match promise { - Some(p) => p, - None => shirabe_external_packages::react::promise::resolve(None), - }; + self.inner.install(repo, package).await?; // TODO(plugin): register package in plugin manager after install, rollback on failure - Ok(Some(promise.then( - Some(Box::new(move |_v| -> Option { - Platform::workaround_filesystem_issues(); - // self.get_plugin_manager().register_package(package, true)?; - // On error: self.rollback_install(e, repo, package)?; - None - })), - None, - ))) + Platform::workaround_filesystem_issues(); + // self.get_plugin_manager().register_package(package, true)?; + // On error: self.rollback_install(e, repo, package)?; + Ok(None) } async fn update( @@ -148,23 +139,14 @@ impl InstallerInterface for PluginInstaller { initial: &dyn PackageInterface, target: &dyn PackageInterface, ) -> Result> { - let promise = self.inner.update(repo, initial, target)?; - let promise = match promise { - Some(p) => p, - None => shirabe_external_packages::react::promise::resolve(None), - }; + self.inner.update(repo, initial, target).await?; // TODO(plugin): deactivate initial and register target in plugin manager after update, rollback on failure - Ok(Some(promise.then( - Some(Box::new(move |_v| -> Option { - Platform::workaround_filesystem_issues(); - // self.get_plugin_manager().deactivate_package(initial); - // self.get_plugin_manager().register_package(target, true)?; - // On error: self.rollback_install(e, repo, target)?; - None - })), - None, - ))) + Platform::workaround_filesystem_issues(); + // self.get_plugin_manager().deactivate_package(initial); + // self.get_plugin_manager().register_package(target, true)?; + // On error: self.rollback_install(e, repo, target)?; + Ok(None) } async fn uninstall( @@ -177,7 +159,7 @@ impl InstallerInterface for PluginInstaller { .borrow_mut() .uninstall_package(package); - self.inner.uninstall(repo, package) + self.inner.uninstall(repo, package).await } async fn cleanup( @@ -186,7 +168,7 @@ impl InstallerInterface for PluginInstaller { package: &dyn PackageInterface, prev_package: Option<&dyn PackageInterface>, ) -> Result> { - self.inner.cleanup(r#type, package, prev_package) + self.inner.cleanup(r#type, package, prev_package).await } fn get_install_path(&self, package: &dyn PackageInterface) -> Option { diff --git a/crates/shirabe/src/installer/project_installer.rs b/crates/shirabe/src/installer/project_installer.rs index 1c50a16..034a07a 100644 --- a/crates/shirabe/src/installer/project_installer.rs +++ b/crates/shirabe/src/installer/project_installer.rs @@ -64,7 +64,7 @@ impl InstallerInterface for ProjectInstaller { self.download_manager .borrow() .download(package, install_path, prev_package) - .map(Some) + .await } async fn prepare( @@ -76,7 +76,7 @@ impl InstallerInterface for ProjectInstaller { self.download_manager .borrow() .prepare(r#type, package, &self.install_path, prev_package) - .map(Some) + .await } async fn cleanup( @@ -88,7 +88,7 @@ impl InstallerInterface for ProjectInstaller { self.download_manager .borrow() .cleanup(r#type, package, &self.install_path, prev_package) - .map(Some) + .await } async fn install( @@ -96,11 +96,10 @@ impl InstallerInterface for ProjectInstaller { _repo: &mut dyn InstalledRepositoryInterface, package: &dyn PackageInterface, ) -> anyhow::Result> { - Ok(Some( - self.download_manager - .borrow() - .install(package, &self.install_path)?, - )) + self.download_manager + .borrow() + .install(package, &self.install_path) + .await } async fn update( -- cgit v1.3.1