From cd9e4a2b67cdea258e1daa2d9d830b7643bc19bb Mon Sep 17 00:00:00 2001 From: nsfisis Date: Fri, 7 Aug 2026 20:51:59 +0900 Subject: fix(autoload-generator): survive listeners that re-enter dump() AutoloadGenerator::dump dispatches PRE_AUTOLOAD_DUMP / POST_AUTOLOAD_DUMP, and EventDispatcher::make_autoloader answers those by walking back into the Composer graph -- the local repository, the installation manager, and the generator itself. Installer::run held mutable borrows of all three across the dump call, so any plugin subscribing to either event panicked with "RefCell already borrowed" before its listener ran. dump() and build_package_map() now take the local repository, the installation manager and the locker as shared handles instead of &mut dyn, and the borrow is taken where it is used. The generator itself is re-entered, not just borrowed twice: PHP listeners reach it through Composer::getAutoloadGenerator() and call setDevMode() while dump() is running, and make_autoloader asks the same object for a package map. That is not expressible behind &mut self, so the mutable state moves into Cell/RefCell fields and the whole AutoloadGeneratorInterface takes &self. Co-Authored-By: Claude Opus 5 (1M context) --- crates/shirabe/src/autoload/autoload_generator.rs | 156 +++++++++++---------- .../shirabe/src/command/dump_autoload_command.rs | 32 ++--- crates/shirabe/src/command/reinstall_command.rs | 18 +-- crates/shirabe/src/console/application.rs | 2 +- .../src/event_dispatcher/event_dispatcher.rs | 4 +- crates/shirabe/src/installer.rs | 19 ++- .../tests/autoload/autoload_generator_test.rs | 67 ++++++--- .../event_dispatcher/event_dispatcher_test.rs | 27 ++-- crates/shirabe/tests/installer_test.rs | 30 ++-- 9 files changed, 187 insertions(+), 168 deletions(-) (limited to 'crates/shirabe') diff --git a/crates/shirabe/src/autoload/autoload_generator.rs b/crates/shirabe/src/autoload/autoload_generator.rs index 06225c08..aacbfc0f 100644 --- a/crates/shirabe/src/autoload/autoload_generator.rs +++ b/crates/shirabe/src/autoload/autoload_generator.rs @@ -14,7 +14,6 @@ use crate::json::JsonFile; use crate::package::LockerInterface; use crate::package::PackageInterfaceHandle; use crate::package::RootPackageInterfaceHandle; -use crate::repository::InstalledRepositoryInterface; use crate::script::ScriptEvents; use crate::util::Filesystem; use crate::util::PackageSorter; @@ -37,13 +36,16 @@ use shirabe_semver::constraint::Bound; pub struct AutoloadGenerator { event_dispatcher: std::rc::Rc>, io: std::rc::Rc>, - dev_mode: Option, - class_map_authoritative: bool, - apcu: bool, - apcu_prefix: Option, - dry_run: bool, - run_scripts: bool, - platform_requirement_filter: std::rc::Rc, + // `dump()` dispatches script events whose listeners reach back here through + // `Composer::getAutoloadGenerator()` and mutate this instance mid-dump. + dev_mode: std::cell::Cell>, + class_map_authoritative: std::cell::Cell, + apcu: std::cell::Cell, + apcu_prefix: std::cell::RefCell>, + dry_run: std::cell::Cell, + run_scripts: std::cell::Cell, + platform_requirement_filter: + std::cell::RefCell>, } impl AutoloadGenerator { @@ -57,71 +59,73 @@ impl AutoloadGenerator { Self { event_dispatcher, io, - dev_mode: None, - class_map_authoritative: false, - apcu: false, - apcu_prefix: None, - dry_run: false, - run_scripts: false, - platform_requirement_filter: PlatformRequirementFilterFactory::ignore_nothing(), + dev_mode: std::cell::Cell::new(None), + class_map_authoritative: std::cell::Cell::new(false), + apcu: std::cell::Cell::new(false), + apcu_prefix: std::cell::RefCell::new(None), + dry_run: std::cell::Cell::new(false), + run_scripts: std::cell::Cell::new(false), + platform_requirement_filter: std::cell::RefCell::new( + PlatformRequirementFilterFactory::ignore_nothing(), + ), } } - pub fn set_dev_mode(&mut self, dev_mode: bool) { - self.dev_mode = Some(dev_mode); + pub fn set_dev_mode(&self, dev_mode: bool) { + self.dev_mode.set(Some(dev_mode)); } /// Whether generated autoloader considers the class map authoritative. - pub fn set_class_map_authoritative(&mut self, class_map_authoritative: bool) { - self.class_map_authoritative = class_map_authoritative; + pub fn set_class_map_authoritative(&self, class_map_authoritative: bool) { + self.class_map_authoritative.set(class_map_authoritative); } /// Whether generated autoloader considers APCu caching. - pub fn set_apcu(&mut self, apcu: bool, apcu_prefix: Option) { - self.apcu = apcu; - self.apcu_prefix = apcu_prefix; + pub fn set_apcu(&self, apcu: bool, apcu_prefix: Option) { + self.apcu.set(apcu); + *self.apcu_prefix.borrow_mut() = apcu_prefix; } /// Whether to run scripts or not - pub fn set_run_scripts(&mut self, run_scripts: bool) { - self.run_scripts = run_scripts; + pub fn set_run_scripts(&self, run_scripts: bool) { + self.run_scripts.set(run_scripts); } /// Whether to run in drymode or not - pub fn set_dry_run(&mut self, dry_run: bool) { - self.dry_run = dry_run; + pub fn set_dry_run(&self, dry_run: bool) { + self.dry_run.set(dry_run); } pub fn set_platform_requirement_filter( - &mut self, + &self, platform_requirement_filter: std::rc::Rc, ) { - self.platform_requirement_filter = platform_requirement_filter; + *self.platform_requirement_filter.borrow_mut() = platform_requirement_filter; } #[allow(clippy::too_many_arguments, reason = "to keep PHP signature")] pub fn dump( - &mut self, + &self, config: &Config, - local_repo: &mut dyn InstalledRepositoryInterface, + local_repo: crate::repository::RepositoryInterfaceHandle, root_package: RootPackageInterfaceHandle, - installation_manager: &mut dyn InstallationManagerInterface, + installation_manager: std::rc::Rc>, target_dir: &str, scan_psr_packages: bool, suffix: Option, - locker: Option<&mut dyn LockerInterface>, + locker: Option>>, strict_ambiguous: bool, ) -> anyhow::Result { let mut scan_psr_packages = scan_psr_packages; - if self.class_map_authoritative { + if self.class_map_authoritative.get() { // Force scanPsrPackages when classmap is authoritative scan_psr_packages = true; } // auto-set devMode based on whether dev dependencies are installed or not - if self.dev_mode.is_none() { + if self.dev_mode.get().is_none() { // we assume no-dev mode if no vendor dir is present or it is too old to contain dev information - self.dev_mode = Some(false); + self.dev_mode.set(Some(false)); let installed_json = JsonFile::new( format!( @@ -136,12 +140,12 @@ impl AutoloadGenerator { if let Some(arr) = installed_json_data.as_array() && let Some(dev) = arr.get("dev") { - self.dev_mode = dev.as_bool(); + self.dev_mode.set(dev.as_bool()); } } } - if self.run_scripts { + if self.run_scripts.get() { // set COMPOSER_DEV_MODE in case not set yet so it is available in the dump-autoload event listeners if shirabe_php_shim::PHP_SERVER .lock() @@ -151,7 +155,7 @@ impl AutoloadGenerator { { Platform::put_env( "COMPOSER_DEV_MODE", - if self.dev_mode.unwrap_or(false) { + if self.dev_mode.get().unwrap_or(false) { "1" } else { "0" @@ -163,7 +167,7 @@ impl AutoloadGenerator { additional_args.insert("optimize".to_string(), PhpMixed::Bool(scan_psr_packages)); self.event_dispatcher.borrow_mut().dispatch_script( ScriptEvents::PRE_AUTOLOAD_DUMP, - self.dev_mode.unwrap_or(false), + self.dev_mode.get().unwrap_or(false), vec![], additional_args, )?; @@ -249,7 +253,7 @@ return array( local_repo.get_canonical_packages()?, )?; let dev_package_names = local_repo.get_dev_package_names(); - let filtered_dev_packages: PhpMixed = if self.dev_mode.unwrap_or(false) { + let filtered_dev_packages: PhpMixed = if self.dev_mode.get().unwrap_or(false) { // if dev mode is enabled, then we do not filter any dev packages out so disable this entirely PhpMixed::Bool(false) } else { @@ -566,8 +570,10 @@ return array( if suffix.is_none() { suffix = Some(if let Some(l) = locker { - if l.is_locked() { - l.get_lock_data()? + let is_locked = l.borrow_mut().is_locked(); + if is_locked { + l.borrow_mut() + .get_lock_data()? .get("content-hash") .and_then(|v| v.as_string()) .unwrap_or("") @@ -582,7 +588,7 @@ return array( } let suffix = suffix.unwrap_or_default(); - if self.dry_run { + if self.dry_run.get() { return Ok(class_map); } @@ -642,6 +648,7 @@ return array( let mut check_platform = config.get("platform-check").as_bool() != Some(false) && self .platform_requirement_filter + .borrow() .as_any() .downcast_ref::() .is_none(); @@ -701,12 +708,12 @@ return array( &format!("{}/LICENSE", target_dir), )?; - if self.run_scripts { + if self.run_scripts.get() { let mut additional_args: IndexMap = IndexMap::new(); additional_args.insert("optimize".to_string(), PhpMixed::Bool(scan_psr_packages)); self.event_dispatcher.borrow_mut().dispatch_script( ScriptEvents::POST_AUTOLOAD_DUMP, - self.dev_mode.unwrap_or(false), + self.dev_mode.get().unwrap_or(false), vec![], additional_args, )?; @@ -774,7 +781,7 @@ return array( pub fn build_package_map( &self, - installation_manager: &mut dyn InstallationManagerInterface, + installation_manager: std::rc::Rc>, root_package: RootPackageInterfaceHandle, packages: Vec, ) -> anyhow::Result)>> { @@ -788,7 +795,9 @@ return array( continue; } self.validate_package(package.clone())?; - let install_path = installation_manager.get_install_path(package.clone()); + let install_path = installation_manager + .borrow() + .get_install_path(package.clone()); package_map.push((package, install_path)); } @@ -1181,6 +1190,7 @@ return array( for (_k, link) in &package.get_requires() { if self .platform_requirement_filter + .borrow() .is_ignored(link.get_target()) { continue; @@ -1509,13 +1519,13 @@ class ComposerAutoloaderInit{} suffix )); - if self.class_map_authoritative { + if self.class_map_authoritative.get() { file.push_str(" $loader->setClassMapAuthoritative(true);\n"); } - if self.apcu { + if self.apcu.get() { let apcu_prefix = var_export( - &PhpMixed::String(if let Some(ref prefix) = self.apcu_prefix { + &PhpMixed::String(if let Some(ref prefix) = *self.apcu_prefix.borrow() { prefix.clone() } else { bin2hex(&random_bytes(10)) @@ -1839,7 +1849,7 @@ class ComposerStaticInit{} let mut autoload = package.get_autoload(); let is_root = package.ptr_eq(&root_package.clone().into()); - if self.dev_mode.unwrap_or(false) && is_root { + if self.dev_mode.get().unwrap_or(false) && is_root { let merged = array_merge_recursive(vec![ PhpMixed::Array(autoload.into_iter().collect()), PhpMixed::Array(root_package.get_dev_autoload().into_iter().collect()), @@ -2131,31 +2141,31 @@ class ComposerStaticInit{} // may swap in a replacement. The interface captures the methods reached through Composer's accessor // and through the `Rc>` references fed from it. pub trait AutoloadGeneratorInterface: std::fmt::Debug { - fn set_dev_mode(&mut self, dev_mode: bool); - fn set_class_map_authoritative(&mut self, class_map_authoritative: bool); - fn set_apcu(&mut self, apcu: bool, apcu_prefix: Option); - fn set_run_scripts(&mut self, run_scripts: bool); - fn set_dry_run(&mut self, dry_run: bool); + fn set_dev_mode(&self, dev_mode: bool); + fn set_class_map_authoritative(&self, class_map_authoritative: bool); + fn set_apcu(&self, apcu: bool, apcu_prefix: Option); + fn set_run_scripts(&self, run_scripts: bool); + fn set_dry_run(&self, dry_run: bool); fn set_platform_requirement_filter( - &mut self, + &self, platform_requirement_filter: std::rc::Rc, ); #[allow(clippy::too_many_arguments, reason = "to keep PHP signature")] fn dump( - &mut self, + &self, config: &Config, - local_repo: &mut dyn InstalledRepositoryInterface, + local_repo: crate::repository::RepositoryInterfaceHandle, root_package: RootPackageInterfaceHandle, - installation_manager: &mut dyn InstallationManagerInterface, + installation_manager: std::rc::Rc>, target_dir: &str, scan_psr_packages: bool, suffix: Option, - locker: Option<&mut dyn LockerInterface>, + locker: Option>>, strict_ambiguous: bool, ) -> anyhow::Result; fn build_package_map( &self, - installation_manager: &mut dyn InstallationManagerInterface, + installation_manager: std::rc::Rc>, root_package: RootPackageInterfaceHandle, packages: Vec, ) -> anyhow::Result)>>; @@ -2173,28 +2183,28 @@ pub trait AutoloadGeneratorInterface: std::fmt::Debug { } impl AutoloadGeneratorInterface for AutoloadGenerator { - fn set_dev_mode(&mut self, dev_mode: bool) { + fn set_dev_mode(&self, dev_mode: bool) { self.set_dev_mode(dev_mode); } - fn set_class_map_authoritative(&mut self, class_map_authoritative: bool) { + fn set_class_map_authoritative(&self, class_map_authoritative: bool) { self.set_class_map_authoritative(class_map_authoritative); } - fn set_apcu(&mut self, apcu: bool, apcu_prefix: Option) { + fn set_apcu(&self, apcu: bool, apcu_prefix: Option) { self.set_apcu(apcu, apcu_prefix); } - fn set_run_scripts(&mut self, run_scripts: bool) { + fn set_run_scripts(&self, run_scripts: bool) { self.set_run_scripts(run_scripts); } - fn set_dry_run(&mut self, dry_run: bool) { + fn set_dry_run(&self, dry_run: bool) { self.set_dry_run(dry_run); } fn set_platform_requirement_filter( - &mut self, + &self, platform_requirement_filter: std::rc::Rc, ) { self.set_platform_requirement_filter(platform_requirement_filter); @@ -2202,15 +2212,15 @@ impl AutoloadGeneratorInterface for AutoloadGenerator { #[allow(clippy::too_many_arguments, reason = "to keep PHP signature")] fn dump( - &mut self, + &self, config: &Config, - local_repo: &mut dyn InstalledRepositoryInterface, + local_repo: crate::repository::RepositoryInterfaceHandle, root_package: RootPackageInterfaceHandle, - installation_manager: &mut dyn InstallationManagerInterface, + installation_manager: std::rc::Rc>, target_dir: &str, scan_psr_packages: bool, suffix: Option, - locker: Option<&mut dyn LockerInterface>, + locker: Option>>, strict_ambiguous: bool, ) -> anyhow::Result { self.dump( @@ -2228,7 +2238,7 @@ impl AutoloadGeneratorInterface for AutoloadGenerator { fn build_package_map( &self, - installation_manager: &mut dyn InstallationManagerInterface, + installation_manager: std::rc::Rc>, root_package: RootPackageInterfaceHandle, packages: Vec, ) -> anyhow::Result)>> { diff --git a/crates/shirabe/src/command/dump_autoload_command.rs b/crates/shirabe/src/command/dump_autoload_command.rs index 59295e23..8aad0705 100644 --- a/crates/shirabe/src/command/dump_autoload_command.rs +++ b/crates/shirabe/src/command/dump_autoload_command.rs @@ -188,10 +188,7 @@ impl Command for DumpAutoloadCommand { .as_bool() .unwrap_or(false) { - composer - .get_autoload_generator() - .borrow_mut() - .set_dry_run(true); + composer.get_autoload_generator().borrow().set_dry_run(true); } if input .borrow() @@ -201,7 +198,7 @@ impl Command for DumpAutoloadCommand { { composer .get_autoload_generator() - .borrow_mut() + .borrow() .set_dev_mode(false); } if input.borrow().get_option("dev")?.as_bool().unwrap_or(false) { @@ -221,24 +218,24 @@ impl Command for DumpAutoloadCommand { } composer .get_autoload_generator() - .borrow_mut() + .borrow() .set_dev_mode(true); } composer .get_autoload_generator() - .borrow_mut() + .borrow() .set_class_map_authoritative(authoritative); composer .get_autoload_generator() - .borrow_mut() + .borrow() .set_run_scripts(true); composer .get_autoload_generator() - .borrow_mut() + .borrow() .set_apcu(apcu, apcu_prefix); composer .get_autoload_generator() - .borrow_mut() + .borrow() .set_platform_requirement_filter(platform_requirement_filter); let strict_ambiguous = input .borrow() @@ -256,22 +253,15 @@ impl Command for DumpAutoloadCommand { let autoload_generator = composer.get_autoload_generator(); let config_ref = config.borrow(); - let mut local_repo_ref = local_repo_handle.borrow_mut(); - let local_repo = local_repo_ref - .as_installed_repository_interface_mut() - .expect("local repository must be an InstalledRepositoryInterface"); - let mut installation_manager_ref = installation_manager.borrow_mut(); - let mut locker_ref = locker.borrow_mut(); - - let class_map = autoload_generator.borrow_mut().dump( + let class_map = autoload_generator.borrow().dump( &config_ref, - local_repo, + local_repo_handle, package, - &mut *installation_manager_ref, + installation_manager, "composer", optimize, None, - Some(&mut *locker_ref), + Some(locker), strict_ambiguous, )?; let number_of_classes = class_map.map.len(); diff --git a/crates/shirabe/src/command/reinstall_command.rs b/crates/shirabe/src/command/reinstall_command.rs index 05543870..b16b6c92 100644 --- a/crates/shirabe/src/command/reinstall_command.rs +++ b/crates/shirabe/src/command/reinstall_command.rs @@ -307,27 +307,23 @@ impl Command for ReinstallCommand { let autoload_generator = composer.get_autoload_generator(); autoload_generator - .borrow_mut() + .borrow() .set_class_map_authoritative(authoritative); - autoload_generator.borrow_mut().set_apcu(apcu, apcu_prefix); + autoload_generator.borrow().set_apcu(apcu, apcu_prefix); autoload_generator - .borrow_mut() + .borrow() .set_platform_requirement_filter(self.get_platform_requirement_filter(input)?); let locker = composer.get_locker(); - let mut local_repo_ref = local_repo.borrow_mut(); - let repo = local_repo_ref - .as_installed_repository_interface_mut() - .expect("local repository must be an InstalledRepositoryInterface"); - autoload_generator.borrow_mut().dump( + autoload_generator.borrow().dump( &config.borrow(), - repo, + local_repo.clone(), package.clone(), - &mut *installation_manager.borrow_mut(), + installation_manager.clone(), "composer", optimize, None, - Some(&mut *locker.borrow_mut()), + Some(locker.clone()), false, )?; } diff --git a/crates/shirabe/src/console/application.rs b/crates/shirabe/src/console/application.rs index 3ba6a324..36151563 100644 --- a/crates/shirabe/src/console/application.rs +++ b/crates/shirabe/src/console/application.rs @@ -2417,7 +2417,7 @@ impl ApplicationHandle { let installation_manager = composer.get_installation_manager(); let package_map = generator.build_package_map( - &mut *installation_manager.borrow_mut(), + installation_manager.clone(), root_package.clone(), vec![], )?; diff --git a/crates/shirabe/src/event_dispatcher/event_dispatcher.rs b/crates/shirabe/src/event_dispatcher/event_dispatcher.rs index 5043610b..1480188a 100644 --- a/crates/shirabe/src/event_dispatcher/event_dispatcher.rs +++ b/crates/shirabe/src/event_dispatcher/event_dispatcher.rs @@ -1541,7 +1541,7 @@ try {{ .map(|e| e.is_dev_mode()) }); if let Some(dev_mode) = dev_mode { - generator.borrow_mut().set_dev_mode(dev_mode); + generator.borrow().set_dev_mode(dev_mode); if dev_mode { hash_input.push_str("/dev"); } @@ -1556,7 +1556,7 @@ try {{ let installation_manager = composer.borrow().get_installation_manager(); let package_map = generator.borrow().build_package_map( - &mut *installation_manager.borrow_mut(), + installation_manager.clone(), package.clone(), packages, )?; diff --git a/crates/shirabe/src/installer.rs b/crates/shirabe/src/installer.rs index 091fb35f..9028af88 100644 --- a/crates/shirabe/src/installer.rs +++ b/crates/shirabe/src/installer.rs @@ -392,30 +392,27 @@ impl Installer { } self.autoload_generator - .borrow_mut() + .borrow() .set_class_map_authoritative(self.class_map_authoritative); self.autoload_generator - .borrow_mut() + .borrow() .set_apcu(self.apcu_autoloader, self.apcu_autoloader_prefix.clone()); self.autoload_generator - .borrow_mut() + .borrow() .set_run_scripts(self.run_scripts); self.autoload_generator - .borrow_mut() + .borrow() .set_platform_requirement_filter(self.platform_requirement_filter.clone()); let local_repo_handle = self.repository_manager.borrow().get_local_repository(); - let mut local_repo_ref = local_repo_handle.borrow_mut(); - self.autoload_generator.borrow_mut().dump( + self.autoload_generator.borrow().dump( &self.config.borrow(), - local_repo_ref - .as_installed_repository_interface_mut() - .unwrap(), + local_repo_handle, self.package.clone(), - &mut *self.installation_manager.borrow_mut(), + self.installation_manager.clone(), "composer", self.optimize_autoloader, None, - Some(&mut *self.locker.borrow_mut()), + Some(self.locker.clone()), false, )?; } diff --git a/crates/shirabe/tests/autoload/autoload_generator_test.rs b/crates/shirabe/tests/autoload/autoload_generator_test.rs index 92baadcd..97fabf16 100644 --- a/crates/shirabe/tests/autoload/autoload_generator_test.rs +++ b/crates/shirabe/tests/autoload/autoload_generator_test.rs @@ -14,9 +14,7 @@ use shirabe::package::handle::{ AliasPackageHandle, CompletePackageHandle, PackageHandle, RootPackageHandle, }; use shirabe::package::{Link, PackageInterfaceHandle, RootPackageInterfaceHandle}; -use shirabe::repository::{ - InstalledArrayRepository, InstalledRepositoryInterfaceHandle, WritableRepositoryInterface, -}; +use shirabe::repository::{InstalledArrayRepository, InstalledRepositoryInterfaceHandle}; use shirabe::script::ScriptEvents; use shirabe::util::http_downloader::HttpDownloader; use shirabe::util::r#loop::Loop; @@ -127,10 +125,10 @@ struct SetUp { prev_cwd: std::path::PathBuf, working_dir: String, vendor_dir: String, - repository: InstalledArrayRepository, + repository: shirabe::repository::RepositoryInterfaceHandle, /// ref: `$this->configValueMap['use-include-path']`, which testUseGlobalIncludePath mutates. use_include_path: bool, - im: InstallationManager, + im: std::rc::Rc>, io: std::rc::Rc>, generator: AutoloadGenerator, event_dispatcher: std::rc::Rc>, @@ -181,9 +179,15 @@ fn set_up() -> SetUp { )); let dispatcher_io: std::rc::Rc> = io.clone(); - let im = make_installation_manager(&vendor_dir, dispatcher_io.clone()); + let im: std::rc::Rc> = + std::rc::Rc::new(std::cell::RefCell::new(make_installation_manager( + &vendor_dir, + dispatcher_io.clone(), + ))); - let repository = InstalledArrayRepository::new().unwrap(); + let repository = shirabe::repository::RepositoryInterfaceHandle::new( + InstalledArrayRepository::new().unwrap(), + ); // EventDispatcher constructor is disabled in PHP and dispatch is never called when run-scripts // is off (the default), so a real dispatcher over an empty Composer is a faithful no-op stand-in. @@ -237,7 +241,12 @@ impl SetUp { fn set_canonical_packages(&mut self, packages: Vec) { for p in packages { - self.repository.add_package(p).unwrap(); + self.repository + .borrow_mut() + .as_writable_repository_interface_mut() + .expect("the test repository is writable") + .add_package(p) + .unwrap(); } } } @@ -357,9 +366,9 @@ fn dump( } = s; generator.dump( &config, - repository, + repository.clone(), package, - im, + im.clone(), "composer", scan_psr_packages, Some(suffix.to_string()), @@ -497,9 +506,10 @@ fn test_vendor_dir_same_as_working_dir() { let mut s = set_up(); s.vendor_dir = s.working_dir.clone(); // Re-register the install-path stub so getInstallPath uses the new vendor dir. - s.im.add_installer(std::rc::Rc::new(InstallPathStubInstaller { - vendor_dir: s.vendor_dir.clone(), - })); + s.im.borrow() + .add_installer(std::rc::Rc::new(InstallPathStubInstaller { + vendor_dir: s.vendor_dir.clone(), + })); let package = new_root_pkg("root/a"); package.set_autoload(autoload(vec![ @@ -557,9 +567,10 @@ fn test_root_package_autoloading_alternative_vendor_dir() { ])); s.vendor_dir = format!("{}/subdir", s.vendor_dir); - s.im.add_installer(std::rc::Rc::new(InstallPathStubInstaller { - vendor_dir: s.vendor_dir.clone(), - })); + s.im.borrow() + .add_installer(std::rc::Rc::new(InstallPathStubInstaller { + vendor_dir: s.vendor_dir.clone(), + })); s.ensure_dir(&format!("{}/composer", s.vendor_dir)); s.ensure_dir(&format!("{}/src", s.working_dir)); @@ -1851,7 +1862,9 @@ fn test_files_autoload_generation_remove_extra_entities_from_autoload_files() { &format!("{}/include_paths.php", composer_out), ); - s.repository = InstalledArrayRepository::new().unwrap(); + s.repository = shirabe::repository::RepositoryInterfaceHandle::new( + InstalledArrayRepository::new().unwrap(), + ); s.set_canonical_packages(not_autoload_packages()); dump( &mut s, @@ -1883,7 +1896,9 @@ fn test_files_autoload_generation_remove_extra_entities_from_autoload_files() { &format!("{}/include_paths.php", composer_out), ); - s.repository = InstalledArrayRepository::new().unwrap(); + s.repository = shirabe::repository::RepositoryInterfaceHandle::new( + InstalledArrayRepository::new().unwrap(), + ); s.set_canonical_packages(not_autoload_packages()); dump(&mut s, not_autoload_package.into(), false, "FilesAutoload").unwrap(); assert_file_content_equals( @@ -2015,7 +2030,11 @@ fn test_vendor_dir_excluded_from_working_dir() { s.set_canonical_packages(vec![vendor_package.into()]); - let mut im = make_installation_manager(&vendor_dir, s.io.clone()); + let im: std::rc::Rc> = + std::rc::Rc::new(std::cell::RefCell::new(make_installation_manager( + &vendor_dir, + s.io.clone(), + ))); s.ensure_dir(&format!("{}/src/Foo", working_dir)); s.ensure_dir(&format!("{}/classmap", working_dir)); @@ -2049,9 +2068,9 @@ fn test_vendor_dir_excluded_from_working_dir() { s.generator .dump( &config, - &mut s.repository, + s.repository.clone(), package.into(), - &mut im, + im, "composer", true, Some("_13".to_string()), @@ -2241,7 +2260,11 @@ fn test_autoload_rules_in_package_that_does_not_exist_on_disk() { )])); let map = s .generator - .build_package_map(&mut s.im, package.clone().into(), vec![dep.clone().into()]) + .build_package_map( + s.im.clone(), + package.clone().into(), + vec![dep.clone().into()], + ) .unwrap(); let parsed = s .generator diff --git a/crates/shirabe/tests/event_dispatcher/event_dispatcher_test.rs b/crates/shirabe/tests/event_dispatcher/event_dispatcher_test.rs index d97c14f0..af8a33db 100644 --- a/crates/shirabe/tests/event_dispatcher/event_dispatcher_test.rs +++ b/crates/shirabe/tests/event_dispatcher/event_dispatcher_test.rs @@ -19,8 +19,7 @@ use shirabe::package::{ LockerInterface, PackageInterfaceHandle, RootPackageHandle, RootPackageInterfaceHandle, }; use shirabe::repository::{ - InstalledArrayRepository, InstalledRepositoryInterface, RepositoryInterfaceHandle, - RepositoryManagerInterface, + InstalledArrayRepository, RepositoryInterfaceHandle, RepositoryManagerInterface, }; use shirabe::script::Event as ScriptEvent; use shirabe::script::ScriptEvents; @@ -405,30 +404,30 @@ mockall::mock! { #[derive(Debug)] pub AutoloadGenerator {} impl AutoloadGeneratorInterface for AutoloadGenerator { - fn set_dev_mode(&mut self, dev_mode: bool); - fn set_class_map_authoritative(&mut self, class_map_authoritative: bool); - fn set_apcu(&mut self, apcu: bool, apcu_prefix: Option); - fn set_run_scripts(&mut self, run_scripts: bool); - fn set_dry_run(&mut self, dry_run: bool); + fn set_dev_mode(&self, dev_mode: bool); + fn set_class_map_authoritative(&self, class_map_authoritative: bool); + fn set_apcu(&self, apcu: bool, apcu_prefix: Option); + fn set_run_scripts(&self, run_scripts: bool); + fn set_dry_run(&self, dry_run: bool); fn set_platform_requirement_filter( - &mut self, + &self, platform_requirement_filter: std::rc::Rc, ); - fn dump<'a>( - &mut self, + fn dump( + &self, config: &Config, - local_repo: &mut dyn InstalledRepositoryInterface, + local_repo: shirabe::repository::RepositoryInterfaceHandle, root_package: RootPackageInterfaceHandle, - installation_manager: &mut dyn InstallationManagerInterface, + installation_manager: std::rc::Rc>, target_dir: &str, scan_psr_packages: bool, suffix: Option, - locker: Option<&'a mut dyn LockerInterface>, + locker: Option>>, strict_ambiguous: bool, ) -> anyhow::Result; fn build_package_map( &self, - installation_manager: &mut dyn InstallationManagerInterface, + installation_manager: std::rc::Rc>, root_package: RootPackageInterfaceHandle, packages: Vec, ) -> anyhow::Result)>>; diff --git a/crates/shirabe/tests/installer_test.rs b/crates/shirabe/tests/installer_test.rs index f5e84558..90dca3ca 100644 --- a/crates/shirabe/tests/installer_test.rs +++ b/crates/shirabe/tests/installer_test.rs @@ -34,8 +34,8 @@ use shirabe::package::{ RootPackageInterfaceHandle, }; use shirabe::repository::{ - ArrayRepository, InstalledArrayRepository, InstalledRepositoryInterface, - RepositoryInterfaceHandle, RepositoryManager, RepositoryManagerInterface, + ArrayRepository, InstalledArrayRepository, RepositoryInterfaceHandle, RepositoryManager, + RepositoryManagerInterface, }; use shirabe::util::http_downloader::HttpDownloader; use shirabe::util::r#loop::Loop; @@ -206,34 +206,38 @@ impl EventDispatcherInterface for StubEventDispatcher { struct StubAutoloadGenerator; impl AutoloadGeneratorInterface for StubAutoloadGenerator { - fn set_dev_mode(&mut self, _dev_mode: bool) {} - fn set_class_map_authoritative(&mut self, _class_map_authoritative: bool) {} - fn set_apcu(&mut self, _apcu: bool, _apcu_prefix: Option) {} - fn set_run_scripts(&mut self, _run_scripts: bool) {} - fn set_dry_run(&mut self, _dry_run: bool) {} + fn set_dev_mode(&self, _dev_mode: bool) {} + fn set_class_map_authoritative(&self, _class_map_authoritative: bool) {} + fn set_apcu(&self, _apcu: bool, _apcu_prefix: Option) {} + fn set_run_scripts(&self, _run_scripts: bool) {} + fn set_dry_run(&self, _dry_run: bool) {} fn set_platform_requirement_filter( - &mut self, + &self, _platform_requirement_filter: std::rc::Rc, ) { } #[allow(clippy::too_many_arguments)] fn dump( - &mut self, + &self, _config: &Config, - _local_repo: &mut dyn InstalledRepositoryInterface, + _local_repo: shirabe::repository::RepositoryInterfaceHandle, _root_package: RootPackageInterfaceHandle, - _installation_manager: &mut dyn shirabe::installer::InstallationManagerInterface, + _installation_manager: std::rc::Rc< + std::cell::RefCell, + >, _target_dir: &str, _scan_psr_packages: bool, _suffix: Option, - _locker: Option<&mut dyn LockerInterface>, + _locker: Option>>, _strict_ambiguous: bool, ) -> anyhow::Result { Ok(ClassMap::new()) } fn build_package_map( &self, - _installation_manager: &mut dyn shirabe::installer::InstallationManagerInterface, + _installation_manager: std::rc::Rc< + std::cell::RefCell, + >, _root_package: RootPackageInterfaceHandle, _packages: Vec, ) -> anyhow::Result)>> { -- cgit v1.3.1