diff options
Diffstat (limited to 'crates/shirabe/src/repository/composer_repository.rs')
| -rw-r--r-- | crates/shirabe/src/repository/composer_repository.rs | 139 |
1 files changed, 67 insertions, 72 deletions
diff --git a/crates/shirabe/src/repository/composer_repository.rs b/crates/shirabe/src/repository/composer_repository.rs index 9752bc0..5c16f8e 100644 --- a/crates/shirabe/src/repository/composer_repository.rs +++ b/crates/shirabe/src/repository/composer_repository.rs @@ -7,7 +7,7 @@ use shirabe_php_shim::{ Countable, InvalidArgumentException, JSON_UNESCAPED_SLASHES, JSON_UNESCAPED_UNICODE, LogicException, PHP_EOL, PhpMixed, RuntimeException, UnexpectedValueException, extension_loaded, hash, http_build_query, in_array, json_decode, parse_url_all, realpath, - spl_object_hash, strtolower, strtr, urlencode, var_export, + strtolower, strtr, urlencode, var_export, }; use shirabe_semver::compiling_matcher::CompilingMatcher; @@ -22,7 +22,9 @@ use crate::downloader::TransportException; use crate::event_dispatcher::EventDispatcher; use crate::io::IOInterface; use crate::json::JsonFile; +use crate::package::BasePackageHandle; use crate::package::PackageInterface; +use crate::package::PackageInterfaceHandle; use crate::package::base_package::{self, BasePackage}; use crate::package::loader::ArrayLoader; use crate::package::version::StabilityFilter; @@ -119,15 +121,15 @@ pub struct ComposerRepository { #[derive(Debug)] pub enum FindPackageReturn { - Package(Box<dyn BasePackage>), - Packages(Vec<Box<dyn BasePackage>>), + Package(BasePackageHandle), + Packages(Vec<BasePackageHandle>), None, } #[derive(Debug)] pub struct LoadAsyncPackagesResult { pub names_found: IndexMap<String, bool>, - pub packages: IndexMap<String, Box<dyn BasePackage>>, + pub packages: IndexMap<String, BasePackageHandle>, } impl ConfigurableRepositoryInterface for ComposerRepository { @@ -322,7 +324,7 @@ impl ComposerRepository { &mut self, name: String, constraint: PhpMixed, - ) -> anyhow::Result<Option<Box<dyn BasePackage>>> { + ) -> anyhow::Result<Option<BasePackageHandle>> { // this call initializes loadRootServerFile which is needed for the rest below to work let has_providers = self.has_providers()?; @@ -343,7 +345,7 @@ impl ComposerRepository { .map_or(false, |m| m.contains_key(&name)) { let packages = self.what_provides(&name, None, None, IndexMap::new())?; - let packages_vec: Vec<Box<dyn BasePackage>> = packages.into_values().collect(); + let packages_vec: Vec<BasePackageHandle> = packages.into_values().collect(); return Ok( match self.filter_packages(packages_vec, Some(&constraint), true) { FindPackageReturn::Package(p) => Some(p), @@ -372,7 +374,7 @@ impl ComposerRepository { if name == provider_name { let packages = self.what_provides(&provider_name, None, None, IndexMap::new())?; - let packages_vec: Vec<Box<dyn BasePackage>> = packages.into_values().collect(); + let packages_vec: Vec<BasePackageHandle> = packages.into_values().collect(); return Ok( match self.filter_packages(packages_vec, Some(&constraint), true) { FindPackageReturn::Package(p) => Some(p), @@ -396,7 +398,7 @@ impl ComposerRepository { &mut self, name: String, constraint: Option<PhpMixed>, - ) -> anyhow::Result<Vec<Box<dyn BasePackage>>> { + ) -> anyhow::Result<Vec<BasePackageHandle>> { // this call initializes loadRootServerFile which is needed for the rest below to work let has_providers = self.has_providers()?; @@ -415,7 +417,7 @@ impl ComposerRepository { .map_or(false, |m| m.contains_key(&name)) { let packages = self.what_provides(&name, None, None, IndexMap::new())?; - let packages_vec: Vec<Box<dyn BasePackage>> = packages.into_values().collect(); + let packages_vec: Vec<BasePackageHandle> = packages.into_values().collect(); return Ok( match self.filter_packages(packages_vec, constraint.as_ref(), false) { FindPackageReturn::Packages(v) => v, @@ -440,7 +442,7 @@ impl ComposerRepository { if name == provider_name { let packages = self.what_provides(&provider_name, None, None, IndexMap::new())?; - let packages_vec: Vec<Box<dyn BasePackage>> = packages.into_values().collect(); + let packages_vec: Vec<BasePackageHandle> = packages.into_values().collect(); return Ok( match self.filter_packages(packages_vec, constraint.as_ref(), false) { FindPackageReturn::Packages(v) => v, @@ -461,7 +463,7 @@ impl ComposerRepository { fn filter_packages( &self, - packages: Vec<Box<dyn BasePackage>>, + packages: Vec<BasePackageHandle>, constraint: Option<&AnyConstraint>, return_first_match: bool, ) -> FindPackageReturn { @@ -477,7 +479,7 @@ impl ComposerRepository { } let constraint = constraint.unwrap(); - let mut filtered_packages: Vec<Box<dyn BasePackage>> = Vec::new(); + let mut filtered_packages: Vec<BasePackageHandle> = Vec::new(); for package in packages.into_iter() { let pkg_constraint = @@ -499,7 +501,7 @@ impl ComposerRepository { FindPackageReturn::Packages(filtered_packages) } - pub fn get_packages(&mut self) -> anyhow::Result<Vec<Box<dyn BasePackage>>> { + pub fn get_packages(&mut self) -> anyhow::Result<Vec<BasePackageHandle>> { let has_providers = self.has_providers()?; if self.lazy_providers_url.is_some() { @@ -712,7 +714,7 @@ impl ComposerRepository { mut package_name_map: IndexMap<String, Option<AnyConstraint>>, acceptable_stabilities: IndexMap<String, i64>, stability_flags: IndexMap<String, i64>, - already_loaded: IndexMap<String, IndexMap<String, Box<dyn PackageInterface>>>, + already_loaded: IndexMap<String, IndexMap<String, PackageInterfaceHandle>>, ) -> anyhow::Result<LoadPackagesResult> { // this call initializes loadRootServerFile which is needed for the rest below to work let has_providers = self.has_providers()?; @@ -724,22 +726,16 @@ impl ComposerRepository { stability_flags, already_loaded, ); - // TODO(phase-b): repository_interface::LoadPackagesResult uses Vec<Box<dyn BasePackage>> - // for `packages`; this fn returns IndexMap. Reconciliation needs structural changes. - let _ = inner_result; - return Ok(LoadPackagesResult { - names_found: Vec::new(), - packages: IndexMap::new(), - }); + return Ok(inner_result); } - let mut packages: IndexMap<String, Box<dyn BasePackage>> = IndexMap::new(); + let mut packages: IndexMap<String, BasePackageHandle> = IndexMap::new(); let mut names_found: IndexMap<String, bool> = IndexMap::new(); if has_providers || self.has_partial_packages()? { let names: Vec<String> = package_name_map.keys().cloned().collect(); for name in names { - let mut matches: IndexMap<String, Box<dyn BasePackage>> = IndexMap::new(); + let mut matches: IndexMap<String, BasePackageHandle> = IndexMap::new(); // if a repo has no providers but only partial packages and the partial packages are missing // then we don't want to call whatProvides as it would try to load from the providers and fail @@ -752,12 +748,11 @@ impl ComposerRepository { continue; } - // TODO(phase-b): Box<dyn PackageInterface> is not Clone; share via Rc let candidates = self.what_provides( &name, Some(&acceptable_stabilities), Some(&stability_flags), - todo!("clone of already_loaded requires sharing Box<dyn PackageInterface>"), + already_loaded.clone(), )?; let constraint = package_name_map .get(&name) @@ -783,13 +778,13 @@ impl ComposerRepository { } }; if matches_constraint { - let hash_c = spl_object_hash(&**candidate); - matches.insert(hash_c, dyn_clone_box(&**candidate)); - if let Some(alias) = candidate.as_alias_package() { + let hash_c = candidate.ptr_id().to_string(); + matches.insert(hash_c, candidate.clone()); + if let Some(alias) = candidate.as_alias() { let aliased = alias.get_alias_of(); - let aliased_hash = spl_object_hash(aliased); + let aliased_hash = aliased.ptr_id().to_string(); if !matches.contains_key(&aliased_hash) { - matches.insert(aliased_hash, dyn_clone_box(aliased)); + matches.insert(aliased_hash, aliased.into()); } } } @@ -797,12 +792,12 @@ impl ComposerRepository { // add aliases of matched packages even if they did not match the constraint for (_uid, candidate) in candidates.iter() { - if let Some(alias) = candidate.as_alias_package() { + if let Some(alias) = candidate.as_alias() { let aliased = alias.get_alias_of(); - let aliased_hash = spl_object_hash(aliased); + let aliased_hash = aliased.ptr_id().to_string(); if matches.contains_key(&aliased_hash) { - let hash_c = spl_object_hash(&**candidate); - matches.insert(hash_c, dyn_clone_box(&**candidate)); + let hash_c = candidate.ptr_id().to_string(); + matches.insert(hash_c, candidate.clone()); } } } @@ -1412,8 +1407,8 @@ impl ComposerRepository { name: &str, acceptable_stabilities: Option<&IndexMap<String, i64>>, stability_flags: Option<&IndexMap<String, i64>>, - already_loaded: IndexMap<String, IndexMap<String, Box<dyn PackageInterface>>>, - ) -> anyhow::Result<IndexMap<String, Box<dyn BasePackage>>> { + already_loaded: IndexMap<String, IndexMap<String, PackageInterfaceHandle>>, + ) -> anyhow::Result<IndexMap<String, BasePackageHandle>> { let mut packages_source: Option<String> = None; let packages: IndexMap<String, PhpMixed>; let loading_partial_package: bool; @@ -1635,7 +1630,7 @@ impl ComposerRepository { loading_partial_package = true; } - let mut result: IndexMap<String, Box<dyn BasePackage>> = IndexMap::new(); + let mut result: IndexMap<String, BasePackageHandle> = IndexMap::new(); let mut versions_to_load: IndexMap<String, IndexMap<String, PhpMixed>> = IndexMap::new(); let packages_inner = packages .get("packages") @@ -1749,15 +1744,13 @@ impl ComposerRepository { let loaded_packages = self.create_packages_flat(versions_to_load_vec, packages_source)?; let uids: Vec<String> = versions_to_load.keys().cloned().collect(); - for (index, mut package) in loaded_packages.into_iter().enumerate() { - package.set_repository_self(); + for (index, package) in loaded_packages.into_iter().enumerate() { + // TODO(phase-c): wire the repository back-reference onto the shared package handle. let uid = &uids[index]; - if let Some(alias) = package.as_alias_package_mut() { - let aliased = alias.get_alias_of_mut(); - aliased.set_repository_self(); - - result.insert(uid.clone(), dyn_clone_box(aliased)); + if let Some(alias) = package.as_alias() { + let aliased = alias.get_alias_of(); + result.insert(uid.clone(), aliased.into()); result.insert(format!("{}-alias", uid), package); } else { result.insert(uid.clone(), package); @@ -1784,10 +1777,11 @@ impl ComposerRepository { } /// Adds a new package to the repository - pub fn add_package(&mut self, mut package: Box<dyn BasePackage>) { - // configurePackageTransportOptions(*package); - self.configure_package_transport_options(&mut *package); - self.inner.add_package(package); + pub fn add_package(&mut self, package: BasePackageHandle) { + self.configure_package_transport_options( + package.as_rc().borrow_mut().as_package_interface_mut(), + ); + self.inner.add_package(package.into()); } /// @param packageNames array of package name => ConstraintInterface|null - if a constraint is provided, only packages matching it will be loaded @@ -1796,11 +1790,11 @@ impl ComposerRepository { mut package_names: IndexMap<String, Option<AnyConstraint>>, acceptable_stabilities: Option<&IndexMap<String, i64>>, stability_flags: Option<&IndexMap<String, i64>>, - already_loaded: IndexMap<String, IndexMap<String, Box<dyn PackageInterface>>>, + already_loaded: IndexMap<String, IndexMap<String, PackageInterfaceHandle>>, ) -> anyhow::Result<LoadAsyncPackagesResult> { self.load_root_server_file(None)?; - let mut packages: IndexMap<String, Box<dyn BasePackage>> = IndexMap::new(); + let mut packages: IndexMap<String, BasePackageHandle> = IndexMap::new(); let mut names_found: IndexMap<String, bool> = IndexMap::new(); if self.lazy_providers_url.is_none() { @@ -1980,17 +1974,16 @@ impl ComposerRepository { } } - let loaded_packages: Vec<Box<dyn BasePackage>> = + let loaded_packages: Vec<BasePackageHandle> = ComposerRepository::create_packages_static(versions_to_load, packages_source)?; - for mut package in loaded_packages.into_iter() { - package.set_repository_self(); - let hash_c = spl_object_hash(&*package); - if let Some(alias) = package.as_alias_package_mut() { - let aliased_hash = spl_object_hash(alias.get_alias_of()); + for package in loaded_packages.into_iter() { + // TODO(phase-c): wire the repository back-reference onto the shared package handle. + let hash_c = package.ptr_id().to_string(); + if let Some(alias) = package.as_alias() { + let aliased = alias.get_alias_of(); + let aliased_hash = aliased.ptr_id().to_string(); if !packages.contains_key(&aliased_hash) { - alias.get_alias_of_mut().set_repository_self(); - let aliased_clone = dyn_clone_box(alias.get_alias_of()); - packages.insert(aliased_hash, aliased_clone); + packages.insert(aliased_hash, aliased.into()); } } packages.insert(hash_c, package); @@ -2716,13 +2709,13 @@ impl ComposerRepository { &mut self, packages: Vec<IndexMap<String, PhpMixed>>, source: Option<String>, - ) -> anyhow::Result<Vec<Box<dyn BasePackage>>> { + ) -> anyhow::Result<Vec<BasePackageHandle>> { if packages.is_empty() { return Ok(vec![]); } let mut packages = packages; - let result = (|| -> anyhow::Result<Vec<Box<dyn BasePackage>>> { + let result = (|| -> anyhow::Result<Vec<BasePackageHandle>> { for data in packages.iter_mut() { if !data.contains_key("notification-url") { data.insert( @@ -2737,11 +2730,11 @@ impl ComposerRepository { let package_instances = self.loader.load_packages(packages.clone())?; - let mut results: Vec<Box<dyn BasePackage>> = Vec::new(); - for mut package in package_instances.into_iter() { + let mut results: Vec<BasePackageHandle> = Vec::new(); + for package in package_instances.into_iter() { if let Some(src_type) = package.get_source_type() { if let Some(mirrors) = - self.source_mirrors.as_ref().and_then(|m| m.get(src_type)) + self.source_mirrors.as_ref().and_then(|m| m.get(&src_type)) { let converted: Vec<IndexMap<String, PhpMixed>> = mirrors .iter() @@ -2767,8 +2760,10 @@ impl ComposerRepository { .collect(); package.set_dist_mirrors(Some(converted)); } - self.configure_package_transport_options(&mut *package); - results.push(package); + self.configure_package_transport_options( + package.as_rc().borrow_mut().as_package_interface_mut(), + ); + results.push(package.into()); } Ok(results) })(); @@ -2794,12 +2789,16 @@ impl ComposerRepository { fn create_packages_static( packages: Vec<IndexMap<String, PhpMixed>>, _source: Option<String>, - ) -> anyhow::Result<Vec<Box<dyn BasePackage>>> { + ) -> anyhow::Result<Vec<BasePackageHandle>> { if packages.is_empty() { return Ok(vec![]); } let loader = ArrayLoader::new(Some(VersionParser::new()), true); - Ok(loader.load_packages(packages)?) + Ok(loader + .load_packages(packages)? + .into_iter() + .map(|p| p.into()) + .collect()) } fn fetch_file( @@ -3485,7 +3484,3 @@ fn clone_root_data(rd: &RootData) -> RootData { RootData::Data(d) => RootData::Data(d.clone()), } } - -fn dyn_clone_box(_pkg: &dyn BasePackage) -> Box<dyn BasePackage> { - todo!() -} |
