diff options
Diffstat (limited to 'crates/shirabe/src')
93 files changed, 1045 insertions, 1222 deletions
diff --git a/crates/shirabe/src/advisory/auditor.rs b/crates/shirabe/src/advisory/auditor.rs index 8ac6d0c..535f6a7 100644 --- a/crates/shirabe/src/advisory/auditor.rs +++ b/crates/shirabe/src/advisory/auditor.rs @@ -16,7 +16,6 @@ use crate::io::ConsoleIO; use crate::io::IOInterface; use crate::json::JsonFile; use crate::package::CompletePackageInterfaceHandle; -use crate::package::PackageInterface; use crate::package::PackageInterfaceHandle; use crate::package::base_package; use crate::package::base_package::BasePackage; @@ -603,7 +602,7 @@ impl Auditor { io.write_error(&sprintf( "%s is abandoned. %s.", &[ - PhpMixed::String(self.get_package_name_with_link_for_complete(pkg)), + PhpMixed::String(self.get_package_name_with_link_for_complete(pkg.clone())), PhpMixed::String(replacement), ], )); @@ -643,7 +642,7 @@ impl Auditor { table.add_row(ConsoleIO::sanitize( PhpMixed::List(vec![ Box::new(PhpMixed::String( - self.get_package_name_with_link_for_complete(pkg), + self.get_package_name_with_link_for_complete(pkg.clone()), )), Box::new(PhpMixed::String(replacement)), ]), @@ -656,8 +655,8 @@ impl Auditor { Ok(()) } - fn get_package_name_with_link(&self, package: &dyn PackageInterface) -> String { - let package_url = PackageInfo::get_view_source_or_homepage_url(package); + fn get_package_name_with_link(&self, package: PackageInterfaceHandle) -> String { + let package_url = PackageInfo::get_view_source_or_homepage_url(package.clone()); if package_url.is_some() { format!( @@ -666,7 +665,7 @@ impl Auditor { package.get_pretty_name() ) } else { - package.get_pretty_name().to_string() + package.get_pretty_name() } } @@ -674,11 +673,9 @@ impl Auditor { // upcast to PackageInterface (e.g. via an as_package_interface() trait method) fn get_package_name_with_link_for_complete( &self, - package: &CompletePackageInterfaceHandle, + package: CompletePackageInterfaceHandle, ) -> String { - let _ = package; - // PackageInfo::get_view_source_or_homepage_url(package.as_rc().borrow().as_package_interface()) - String::new() + self.get_package_name_with_link(package.into()) } fn get_severity(&self, advisory: &SecurityAdvisory) -> String { diff --git a/crates/shirabe/src/autoload/autoload_generator.rs b/crates/shirabe/src/autoload/autoload_generator.rs index 59cf6ae..4d2e704 100644 --- a/crates/shirabe/src/autoload/autoload_generator.rs +++ b/crates/shirabe/src/autoload/autoload_generator.rs @@ -31,7 +31,7 @@ use crate::json::JsonFile; use crate::package::Locker; use crate::package::PackageInterface; use crate::package::PackageInterfaceHandle; -use crate::package::RootPackageInterface; +use crate::package::RootPackageInterfaceHandle; use crate::repository::InstalledRepositoryInterface; use crate::script::ScriptEvents; use crate::util::Filesystem; @@ -126,7 +126,7 @@ impl AutoloadGenerator { &mut self, config: &Config, local_repo: &dyn InstalledRepositoryInterface, - root_package: &dyn RootPackageInterface, + root_package: RootPackageInterfaceHandle, installation_manager: &mut InstallationManager, target_dir: &str, scan_psr_packages: bool, @@ -247,7 +247,7 @@ impl AutoloadGenerator { let dev_package_names = local_repo.get_dev_package_names(); let package_map = self.build_package_map( installation_manager, - root_package, + root_package.clone(), local_repo.get_canonical_packages(), )?; let filtered_dev_packages: PhpMixed = if self.dev_mode.unwrap_or(false) { @@ -271,7 +271,7 @@ impl AutoloadGenerator { .iter() .map(|(p, s)| (p.clone(), s.clone())) .collect(), - root_package, + root_package.clone(), filtered_dev_packages, ); @@ -742,15 +742,11 @@ impl AutoloadGenerator { pub fn build_package_map( &self, installation_manager: &mut InstallationManager, - root_package: &dyn RootPackageInterface, + root_package: RootPackageInterfaceHandle, packages: Vec<PackageInterfaceHandle>, ) -> anyhow::Result<Vec<(PackageInterfaceHandle, Option<String>)>> { // build package => install path map - // TODO(phase-c): the root package needs to be available here as a shared handle; - // a borrowed &dyn RootPackageInterface cannot be lifted into a PackageInterfaceHandle. - let _ = root_package; - let root_package_handle: PackageInterfaceHandle = - todo!("root package handle for build_package_map"); + let root_package_handle: PackageInterfaceHandle = root_package.into(); let mut package_map: Vec<(PackageInterfaceHandle, Option<String>)> = vec![(root_package_handle, Some(String::new()))]; @@ -758,9 +754,8 @@ impl AutoloadGenerator { if package.as_alias().is_some() { continue; } - self.validate_package(package.as_rc().borrow().as_package_interface())?; - let install_path = installation_manager - .get_install_path(package.as_rc().borrow().as_package_interface()); + self.validate_package(package.clone())?; + let install_path = installation_manager.get_install_path(package.clone()); package_map.push((package, install_path)); } @@ -768,7 +763,7 @@ impl AutoloadGenerator { } /// Throws InvalidArgumentException if the package has illegal settings. - pub(crate) fn validate_package(&self, package: &dyn PackageInterface) -> anyhow::Result<()> { + pub(crate) fn validate_package(&self, package: PackageInterfaceHandle) -> anyhow::Result<()> { let autoload = package.get_autoload(); if autoload .get("psr-4") @@ -802,7 +797,7 @@ impl AutoloadGenerator { pub fn parse_autoloads( &self, package_map: Vec<(PackageInterfaceHandle, Option<String>)>, - root_package: &dyn RootPackageInterface, + root_package: RootPackageInterfaceHandle, filtered_dev_packages: PhpMixed, ) -> IndexMap<String, PhpMixed> { let mut package_map = package_map; @@ -821,7 +816,7 @@ impl AutoloadGenerator { .filter(|item| !dev_list.contains(&item.0.get_name())) .collect() } else if filtered_dev_packages.as_bool() == Some(true) { - self.filter_package_map(package_map, root_package) + self.filter_package_map(package_map, root_package.clone()) } else { package_map }; @@ -829,15 +824,21 @@ impl AutoloadGenerator { sorted_package_map.push(root_package_map); // TODO(phase-b): psr-0/4/classmap should use reverse_sorted_map (root first) for correct precedence - let mut psr0 = self.parse_autoloads_type(&sorted_package_map, "psr-0", root_package); - let mut psr4 = self.parse_autoloads_type(&sorted_package_map, "psr-4", root_package); - let classmap = self.parse_autoloads_type(&sorted_package_map, "classmap", root_package); + let mut psr0 = + self.parse_autoloads_type(&sorted_package_map, "psr-0", root_package.clone()); + let mut psr4 = + self.parse_autoloads_type(&sorted_package_map, "psr-4", root_package.clone()); + let classmap = + self.parse_autoloads_type(&sorted_package_map, "classmap", root_package.clone()); // sorted (i.e. dependents first) for files to ensure that dependencies are loaded/available once a file is included - let files = self.parse_autoloads_type(&sorted_package_map, "files", root_package); + let files = self.parse_autoloads_type(&sorted_package_map, "files", root_package.clone()); // using sorted here but it does not really matter as all are excluded equally - let exclude = - self.parse_autoloads_type(&sorted_package_map, "exclude-from-classmap", root_package); + let exclude = self.parse_autoloads_type( + &sorted_package_map, + "exclude-from-classmap", + root_package.clone(), + ); psr0.sort_by(|k1, _, k2, _| k2.cmp(k1)); psr4.sort_by(|k1, _, k2, _| k2.cmp(k1)); @@ -1633,7 +1634,7 @@ impl AutoloadGenerator { &self, package_map: &Vec<(PackageInterfaceHandle, Option<String>)>, r#type: &str, - root_package: &dyn RootPackageInterface, + root_package: RootPackageInterfaceHandle, ) -> IndexMap<String, Box<PhpMixed>> { let mut autoloads: IndexMap<String, Box<PhpMixed>> = IndexMap::new(); let mut numeric_index: i64 = 0; @@ -1800,10 +1801,7 @@ impl AutoloadGenerator { if r#type == "files" { autoloads.insert( - self.get_file_identifier( - package.as_rc().borrow().as_package_interface(), - &path_str, - ), + self.get_file_identifier(package.clone(), &path_str), Box::new(PhpMixed::String(relative_path)), ); continue; @@ -1831,7 +1829,11 @@ impl AutoloadGenerator { autoloads } - pub(crate) fn get_file_identifier(&self, package: &dyn PackageInterface, path: &str) -> String { + pub(crate) fn get_file_identifier( + &self, + package: PackageInterfaceHandle, + path: &str, + ) -> String { // TODO composer v3 change this to sha1 or xxh3? Possibly not worth the potential breakage though hash("md5", &format!("{}:{}", package.get_name(), path)) } @@ -1840,7 +1842,7 @@ impl AutoloadGenerator { pub(crate) fn filter_package_map( &self, package_map: Vec<(PackageInterfaceHandle, Option<String>)>, - root_package: &dyn RootPackageInterface, + root_package: RootPackageInterfaceHandle, ) -> Vec<(PackageInterfaceHandle, Option<String>)> { let mut packages: IndexMap<String, PackageInterfaceHandle> = IndexMap::new(); let mut include: IndexMap<String, bool> = IndexMap::new(); @@ -1857,7 +1859,7 @@ impl AutoloadGenerator { // Recursive walk emulating PHP's by-reference closure capture. fn add( - package: &dyn PackageInterface, + package: PackageInterfaceHandle, packages: &IndexMap<String, PackageInterfaceHandle>, include: &mut IndexMap<String, bool>, replaced_by: &IndexMap<String, String>, @@ -1870,18 +1872,13 @@ impl AutoloadGenerator { if !include.contains_key(&target) { include.insert(target.clone(), true); if let Some(p) = packages.get(&target) { - add( - p.as_rc().borrow().as_package_interface(), - packages, - include, - replaced_by, - ); + add(p.clone(), packages, include, replaced_by); } } } } add( - RootPackageInterface::as_package_interface(root_package), + root_package.clone().into(), &packages, &mut include, &replaced_by, diff --git a/crates/shirabe/src/command/archive_command.rs b/crates/shirabe/src/command/archive_command.rs index 225b092..aab7b51 100644 --- a/crates/shirabe/src/command/archive_command.rs +++ b/crates/shirabe/src/command/archive_command.rs @@ -201,10 +201,9 @@ impl ArchiveCommand { None => return Ok(1), } } else { - let _rc = self.require_composer(None, None)?; - // TODO(phase-c): composer.get_package() returns &dyn RootPackageInterface, not a - // handle, so it cannot be shared as a CompletePackageInterfaceHandle yet. - todo!("share composer.get_package() as a CompletePackageInterfaceHandle") + let rc = self.require_composer(None, None)?; + let composer = crate::command::composer_full(&rc); + composer.get_package().clone().into() }; io.write_error(&format!( diff --git a/crates/shirabe/src/command/base_dependency_command.rs b/crates/shirabe/src/command/base_dependency_command.rs index f449629..7a5300a 100644 --- a/crates/shirabe/src/command/base_dependency_command.rs +++ b/crates/shirabe/src/command/base_dependency_command.rs @@ -337,9 +337,7 @@ pub trait BaseDependencyCommand: BaseCommand { } else { package.get_pretty_version().to_string() }; - let package_url = PackageInfo::get_view_source_or_homepage_url( - package.as_rc().borrow().as_package_interface(), - ); + let package_url = PackageInfo::get_view_source_or_homepage_url(package.clone()); let name_with_link = match &package_url { Some(url) => format!( "<href={}>{}</>", @@ -414,9 +412,7 @@ pub trait BaseDependencyCommand: BaseCommand { } else { package.get_pretty_version().to_string() }; - let package_url = PackageInfo::get_view_source_or_homepage_url( - package.as_rc().borrow().as_package_interface(), - ); + let package_url = PackageInfo::get_view_source_or_homepage_url(package.clone()); let name_with_link = match &package_url { Some(url) => format!( "<href={}>{}</>", diff --git a/crates/shirabe/src/command/bump_command.rs b/crates/shirabe/src/command/bump_command.rs index 3299f85..a1e5f35 100644 --- a/crates/shirabe/src/command/bump_command.rs +++ b/crates/shirabe/src/command/bump_command.rs @@ -255,10 +255,7 @@ impl BumpCommand { package = alias.get_alias_of().into(); } - let bumped = bumper.bump_requirement( - link.get_constraint(), - package.as_rc().borrow().as_package_interface(), - )?; + let bumped = bumper.bump_requirement(link.get_constraint(), package.clone())?; if bumped == current_constraint { continue; diff --git a/crates/shirabe/src/command/licenses_command.rs b/crates/shirabe/src/command/licenses_command.rs index 6c7ea73..add5b0b 100644 --- a/crates/shirabe/src/command/licenses_command.rs +++ b/crates/shirabe/src/command/licenses_command.rs @@ -114,11 +114,7 @@ impl LicensesCommand { if input.get_option("no-dev").as_bool().unwrap_or(false) { RepositoryUtils::filter_required_packages( &repo.get_packages(), - composer - .get_package() - .as_rc() - .borrow() - .as_package_interface(), + composer.get_package().clone().into(), false, vec![], ) @@ -160,9 +156,7 @@ impl LicensesCommand { PhpMixed::String("Licenses".to_string()), ]); for package in &packages { - let link = PackageInfo::get_view_source_or_homepage_url( - package.as_rc().borrow().as_package_interface(), - ); + let link = PackageInfo::get_view_source_or_homepage_url(package.clone()); let name = if let Some(link) = link { format!( "<href={}>{}</>", diff --git a/crates/shirabe/src/command/package_discovery_trait.rs b/crates/shirabe/src/command/package_discovery_trait.rs index e8a56a9..d0574c6 100644 --- a/crates/shirabe/src/command/package_discovery_trait.rs +++ b/crates/shirabe/src/command/package_discovery_trait.rs @@ -21,9 +21,7 @@ use crate::filter::platform_requirement_filter::IgnoreAllPlatformRequirementFilt use crate::filter::platform_requirement_filter::PlatformRequirementFilterFactory; use crate::io::IOInterface; use crate::io::IOInterfaceImmutable; -use crate::package::BasePackage; -use crate::package::CompletePackageInterface; -use crate::package::PackageInterface; +use crate::package::PackageInterfaceHandle; use crate::package::version::VersionParser; use crate::package::version::VersionSelector; use crate::repository::CompositeRepository; @@ -576,7 +574,7 @@ pub trait PackageDiscoveryTrait { &format!( "Package %s has requirements incompatible with your PHP version, PHP extensions and Composer version{}", self.get_platform_exception_details( - candidate.as_rc().borrow().as_package_interface(), + candidate.clone(), platform_repo, ), ), @@ -673,7 +671,7 @@ pub trait PackageDiscoveryTrait { &format!( "Could not find package %s in any version matching your PHP version, PHP extensions and Composer version{}%s", self.get_platform_exception_details( - candidate.as_rc().borrow().as_package_interface(), + candidate.clone(), platform_repo, ), ), @@ -781,9 +779,7 @@ pub trait PackageDiscoveryTrait { if fixed { package.get_pretty_version().to_string() } else { - version_selector.find_recommended_require_version( - package.as_rc().borrow().as_package_interface(), - )? + version_selector.find_recommended_require_version(package.clone())? }, )) } @@ -846,7 +842,7 @@ pub trait PackageDiscoveryTrait { fn get_platform_exception_details( &self, - candidate: &dyn PackageInterface, + candidate: PackageInterfaceHandle, platform_repo: Option<&PlatformRepository>, ) -> String { let mut details: Vec<String> = vec![]; diff --git a/crates/shirabe/src/command/require_command.rs b/crates/shirabe/src/command/require_command.rs index 66e1134..bf5f159 100644 --- a/crates/shirabe/src/command/require_command.rs +++ b/crates/shirabe/src/command/require_command.rs @@ -976,9 +976,7 @@ impl RequireCommand { } else { requirements.insert( package_name.clone(), - version_selector.find_recommended_require_version( - package.as_rc().borrow().as_package_interface(), - )?, + version_selector.find_recommended_require_version(package.clone())?, ); } self.get_io().write_error3( diff --git a/crates/shirabe/src/command/show_command.rs b/crates/shirabe/src/command/show_command.rs index f3c1b3d..b72a986 100644 --- a/crates/shirabe/src/command/show_command.rs +++ b/crates/shirabe/src/command/show_command.rs @@ -24,9 +24,10 @@ use crate::filter::platform_requirement_filter::PlatformRequirementFilterInterfa use crate::io::IOInterface; use crate::io::IOInterfaceImmutable; use crate::json::JsonFile; -use crate::package::CompletePackageInterface; +use crate::package::CompletePackageInterfaceHandle; use crate::package::Link; use crate::package::PackageInterface; +use crate::package::PackageInterfaceHandle; use crate::package::base_package; use crate::package::version::VersionParser; use crate::package::version::VersionSelector; @@ -397,7 +398,7 @@ impl ShowCommand { .get_packages(); let packages = RepositoryUtils::filter_required_packages( &local_packages, - root_pkg.as_rc().borrow().as_package_interface(), + root_pkg.clone().into(), false, Vec::new(), ); @@ -545,13 +546,8 @@ impl ShowCommand { let mut exit_code: i64 = 0; if input.get_option("tree").as_bool() == Some(true) { - let package_ref = package.as_rc().borrow(); - let array_tree = self.generate_package_tree( - package_ref.as_package_interface(), - &*installed_repo, - &*repos, - ); - drop(package_ref); + let array_tree = + self.generate_package_tree(package.clone().into(), &*installed_repo, &*repos); if format == "json" { let mut wrapper: IndexMap<String, PhpMixed> = IndexMap::new(); @@ -579,9 +575,8 @@ impl ShowCommand { let mut latest_package: Option<crate::package::PackageInterfaceHandle> = None; if input.get_option("latest").as_bool() == Some(true) { - let package_ref = package.as_rc().borrow(); latest_package = self.find_latest_package( - package_ref.as_package_interface(), + package.clone().into(), composer.as_ref().unwrap(), &platform_repo, input.get_option("major-only").as_bool().unwrap_or(false), @@ -626,25 +621,21 @@ impl ShowCommand { return Ok(exit_code); } - let package_ref = package.as_rc().borrow(); - let package_dyn = package_ref - .as_complete_package_interface() - .expect("single_package is a CompletePackageInterface"); - let latest_ref = latest_package.as_ref().map(|p| p.as_rc().borrow()); - let latest_dyn: Option<&dyn PackageInterface> = - latest_ref.as_ref().map(|r| r.as_package_interface()); if format == "json" { self.print_package_info_as_json( - package_dyn, + package.clone(), &versions_map, &*installed_repo, - latest_dyn, + latest_package, )?; } else { - self.print_package_info(package_dyn, &versions_map, &*installed_repo, latest_dyn)?; + self.print_package_info( + package.clone(), + &versions_map, + &*installed_repo, + latest_package, + )?; } - drop(latest_ref); - drop(package_ref); return Ok(exit_code); } @@ -670,9 +661,8 @@ impl ShowCommand { ), true, ) { - let package_ref = package.as_rc().borrow(); array_tree.push(self.generate_package_tree( - package_ref.as_package_interface(), + package.clone(), &*installed_repo, &*repos, )); @@ -844,9 +834,8 @@ impl ShowCommand { if let PackageOrName::Pkg(package) = package_or_name { if !Preg::is_match(&ignored_packages_regex, &package.get_pretty_name())? { - let package_ref = package.as_rc().borrow(); let latest = self.find_latest_package( - package_ref.as_package_interface(), + package.clone(), composer.as_ref().unwrap(), &platform_repo, show_major_only, @@ -854,7 +843,6 @@ impl ShowCommand { show_patch_only, &*platform_req_filter, )?; - drop(package_ref); if latest.is_none() { continue; } @@ -956,9 +944,7 @@ impl ShowCommand { ); package_view_data.insert( "source".to_string(), - match PackageInfo::get_view_source_url( - package.as_rc().borrow().as_package_interface(), - ) { + match PackageInfo::get_view_source_url(package.clone()) { Some(s) => PhpMixed::String(s), None => PhpMixed::Null, }, @@ -1007,14 +993,8 @@ impl ShowCommand { latest_version_str = latest_version_str.trim_start_matches('v').to_string(); } - let latest_ref = latest.as_rc().borrow(); - let package_ref = package.as_rc().borrow(); - let update_status = Self::get_update_status( - latest_ref.as_package_interface(), - package_ref.as_package_interface(), - ); - drop(package_ref); - drop(latest_ref); + let update_status = + Self::get_update_status(latest.clone(), package.clone()); latest_length = latest_length.max(latest_version_str.len()); package_view_data .insert("latest".to_string(), PhpMixed::String(latest_version_str)); @@ -1480,8 +1460,8 @@ impl ShowCommand { /// @return array|string|string[] pub(crate) fn get_version_style( &self, - latest_package: &dyn PackageInterface, - package: &dyn PackageInterface, + latest_package: PackageInterfaceHandle, + package: PackageInterfaceHandle, ) -> String { Self::update_status_to_version_style(&Self::get_update_status(latest_package, package)) .to_string() @@ -1539,9 +1519,7 @@ impl ShowCommand { } // select an exact match if it is in the installed repo and no specific version was required - if version.is_null() - && installed_repo.has_package(p.as_rc().borrow().as_package_interface()) - { + if version.is_null() && installed_repo.has_package(p.clone()) { matched_package = Some(p.clone()); } @@ -1575,14 +1553,18 @@ impl ShowCommand { /// Prints package info. pub(crate) fn print_package_info( &mut self, - package: &dyn CompletePackageInterface, + package: CompletePackageInterfaceHandle, versions: &IndexMap<String, String>, installed_repo: &InstalledRepository, - latest_package: Option<&dyn PackageInterface>, + latest_package: Option<PackageInterfaceHandle>, ) -> anyhow::Result<()> { - self.print_meta(package, versions, installed_repo, latest_package); - self.print_links(package, Link::TYPE_REQUIRE, None); - self.print_links(package, Link::TYPE_DEV_REQUIRE, Some("requires (dev)")); + self.print_meta(package.clone(), versions, installed_repo, latest_package); + self.print_links(package.clone(), Link::TYPE_REQUIRE, None); + self.print_links( + package.clone(), + Link::TYPE_DEV_REQUIRE, + Some("requires (dev)"), + ); if !package.get_suggests().is_empty() { self.get_io().write("\n<info>suggests</info>"); @@ -1592,8 +1574,8 @@ impl ShowCommand { } } - self.print_links(package, Link::TYPE_PROVIDE, None); - self.print_links(package, Link::TYPE_CONFLICT, None); + self.print_links(package.clone(), Link::TYPE_PROVIDE, None); + self.print_links(package.clone(), Link::TYPE_CONFLICT, None); self.print_links(package, Link::TYPE_REPLACE, None); Ok(()) } @@ -1601,13 +1583,13 @@ impl ShowCommand { /// Prints package metadata. pub(crate) fn print_meta( &mut self, - package: &dyn CompletePackageInterface, + package: CompletePackageInterfaceHandle, versions: &IndexMap<String, String>, installed_repo: &InstalledRepository, - latest_package: Option<&dyn PackageInterface>, + latest_package: Option<PackageInterfaceHandle>, ) { - let is_installed_package = !PlatformRepository::is_platform_package(package.get_name()) - && installed_repo.has_package(package.as_package_interface()); + let is_installed_package = !PlatformRepository::is_platform_package(&package.get_name()) + && installed_repo.has_package(package.clone().into()); self.get_io().write(&format!( "<info>name</info> : {}", @@ -1615,12 +1597,12 @@ impl ShowCommand { )); self.get_io().write(&format!( "<info>descrip.</info> : {}", - package.get_description().unwrap_or("") + package.get_description().unwrap_or_default() )); let keywords = package.get_keywords(); self.get_io() .write(&format!("<info>keywords</info> : {}", keywords.join(", "))); - self.print_versions(package, versions, installed_repo); + self.print_versions(package.clone(), versions, installed_repo); if is_installed_package { if let Some(rd) = package.get_release_date() { let rel = self.get_relative_time(&rd); @@ -1631,8 +1613,8 @@ impl ShowCommand { )); } } - let latest = if let Some(latest) = latest_package { - let style = self.get_version_style(latest, package.as_package_interface()); + let latest: PackageInterfaceHandle = if let Some(latest) = latest_package { + let style = self.get_version_style(latest.clone(), package.clone().into()); let released_time = match latest.get_release_date() { None => String::new(), Some(rd) => { @@ -1649,26 +1631,26 @@ impl ShowCommand { )); latest } else { - package.as_package_interface() + package.clone().into() }; self.get_io() .write(&format!("<info>type</info> : {}", package.get_type())); - self.print_licenses(package); + self.print_licenses(package.clone()); self.get_io().write(&format!( "<info>homepage</info> : {}", - package.get_homepage().unwrap_or("") + package.get_homepage().unwrap_or_default() )); self.get_io().write(&format!( "<info>source</info> : [{}] <comment>{}</comment> {}", - package.get_source_type().unwrap_or(""), - package.get_source_url().unwrap_or(""), - package.get_source_reference().unwrap_or("") + package.get_source_type().unwrap_or_default(), + package.get_source_url().unwrap_or_default(), + package.get_source_reference().unwrap_or_default() )); self.get_io().write(&format!( "<info>dist</info> : [{}] <comment>{}</comment> {}", - package.get_dist_type().unwrap_or(""), - package.get_dist_url().unwrap_or(""), - package.get_dist_reference().unwrap_or("") + package.get_dist_type().unwrap_or_default(), + package.get_dist_url().unwrap_or_default(), + package.get_dist_reference().unwrap_or_default() )); if is_installed_package { // TODO(phase-b): get_installation_manager wants &mut Composer; PHP shares by ref. @@ -1691,7 +1673,7 @@ impl ShowCommand { package.get_names(true).join(", ") )); - if let Some(c) = latest.as_complete_package_interface() { + if let Some(c) = latest.as_complete() { if c.is_abandoned() { let replacement = match c.get_replacement_package() { Some(rp) => format!(" The author suggests using the {} package instead.", rp), @@ -1759,7 +1741,7 @@ impl ShowCommand { /// Prints all available versions of this package and highlights the installed one if any. pub(crate) fn print_versions( &mut self, - package: &dyn CompletePackageInterface, + package: CompletePackageInterfaceHandle, versions: &IndexMap<String, String>, installed_repo: &InstalledRepository, ) { @@ -1767,7 +1749,7 @@ impl ShowCommand { versions_keys = Semver::rsort(versions_keys); // highlight installed version - let installed_packages = installed_repo.find_packages(package.get_name(), None); + let installed_packages = installed_repo.find_packages(&package.get_name(), None); if !installed_packages.is_empty() { for installed_package in installed_packages.iter() { let installed_version = installed_package.get_pretty_version(); @@ -1792,7 +1774,7 @@ impl ShowCommand { /// print link objects pub(crate) fn print_links( &mut self, - package: &dyn CompletePackageInterface, + package: CompletePackageInterfaceHandle, link_type: &str, title: Option<&str>, ) { @@ -1813,7 +1795,7 @@ impl ShowCommand { } /// Prints the licenses of a package with metadata - pub(crate) fn print_licenses(&mut self, package: &dyn CompletePackageInterface) { + pub(crate) fn print_licenses(&mut self, package: CompletePackageInterfaceHandle) { let spdx_licenses = SpdxLicenses::new(); let licenses = package.get_license(); @@ -1846,10 +1828,10 @@ impl ShowCommand { /// Prints package info in JSON format. pub(crate) fn print_package_info_as_json( &mut self, - package: &dyn CompletePackageInterface, + package: CompletePackageInterfaceHandle, versions: &IndexMap<String, String>, installed_repo: &InstalledRepository, - latest_package: Option<&dyn PackageInterface>, + latest_package: Option<PackageInterfaceHandle>, ) -> anyhow::Result<()> { let mut json: IndexMap<String, PhpMixed> = IndexMap::new(); json.insert( @@ -1858,7 +1840,7 @@ impl ShowCommand { ); json.insert( "description".to_string(), - PhpMixed::String(package.get_description().unwrap_or("").to_string()), + PhpMixed::String(package.get_description().unwrap_or_default()), ); let keywords: Vec<PhpMixed> = package .get_keywords() @@ -1876,7 +1858,7 @@ impl ShowCommand { json.insert( "homepage".to_string(), match package.get_homepage() { - Some(h) => PhpMixed::String(h.to_string()), + Some(h) => PhpMixed::String(h), None => PhpMixed::Null, }, ); @@ -1892,31 +1874,31 @@ impl ShowCommand { ); json = Self::append_versions(json, versions); - json = Self::append_licenses(json, package); + json = Self::append_licenses(json, package.clone()); - let latest = if let Some(latest) = latest_package { + let latest: PackageInterfaceHandle = if let Some(latest) = latest_package { json.insert( "latest".to_string(), PhpMixed::String(latest.get_pretty_version().to_string()), ); latest } else { - package.as_package_interface() + package.clone().into() }; if package.get_source_type().is_some() { let mut src: IndexMap<String, PhpMixed> = IndexMap::new(); src.insert( "type".to_string(), - PhpMixed::String(package.get_source_type().unwrap_or("").to_string()), + PhpMixed::String(package.get_source_type().unwrap_or_default()), ); src.insert( "url".to_string(), - PhpMixed::String(package.get_source_url().unwrap_or("").to_string()), + PhpMixed::String(package.get_source_url().unwrap_or_default()), ); src.insert( "reference".to_string(), - PhpMixed::String(package.get_source_reference().unwrap_or("").to_string()), + PhpMixed::String(package.get_source_reference().unwrap_or_default()), ); json.insert( "source".to_string(), @@ -1928,15 +1910,15 @@ impl ShowCommand { let mut dst: IndexMap<String, PhpMixed> = IndexMap::new(); dst.insert( "type".to_string(), - PhpMixed::String(package.get_dist_type().unwrap_or("").to_string()), + PhpMixed::String(package.get_dist_type().unwrap_or_default()), ); dst.insert( "url".to_string(), - PhpMixed::String(package.get_dist_url().unwrap_or("").to_string()), + PhpMixed::String(package.get_dist_url().unwrap_or_default()), ); dst.insert( "reference".to_string(), - PhpMixed::String(package.get_dist_reference().unwrap_or("").to_string()), + PhpMixed::String(package.get_dist_reference().unwrap_or_default()), ); json.insert( "dist".to_string(), @@ -1944,8 +1926,8 @@ impl ShowCommand { ); } - if !PlatformRepository::is_platform_package(package.get_name()) - && installed_repo.has_package(package.as_package_interface()) + if !PlatformRepository::is_platform_package(&package.get_name()) + && installed_repo.has_package(package.clone().into()) { // TODO(phase-b): get_installation_manager wants &mut Composer; PHP shares by ref. let _ = self.require_composer(None, None)?; @@ -1966,7 +1948,7 @@ impl ShowCommand { } } - if let Some(c) = latest.as_complete_package_interface() { + if let Some(c) = latest.as_complete() { if c.is_abandoned() { json.insert( "replacement".to_string(), @@ -2000,7 +1982,7 @@ impl ShowCommand { ); } - json = Self::append_autoload(json, package); + json = Self::append_autoload(json, package.clone()); if !package.get_include_paths().is_empty() { json.insert( @@ -2057,7 +2039,7 @@ impl ShowCommand { fn append_licenses( mut json: IndexMap<String, PhpMixed>, - package: &dyn CompletePackageInterface, + package: CompletePackageInterfaceHandle, ) -> IndexMap<String, PhpMixed> { let licenses = package.get_license(); if !licenses.is_empty() { @@ -2092,7 +2074,7 @@ impl ShowCommand { fn append_autoload( mut json: IndexMap<String, PhpMixed>, - package: &dyn CompletePackageInterface, + package: CompletePackageInterfaceHandle, ) -> IndexMap<String, PhpMixed> { let autoload_config = package.get_autoload(); if !autoload_config.is_empty() { @@ -2148,10 +2130,10 @@ impl ShowCommand { fn append_links( mut json: IndexMap<String, PhpMixed>, - package: &dyn CompletePackageInterface, + package: CompletePackageInterfaceHandle, ) -> IndexMap<String, PhpMixed> { for link_type in Link::types().iter() { - json = Self::append_link(json, package, link_type); + json = Self::append_link(json, package.clone(), link_type); } json @@ -2159,7 +2141,7 @@ impl ShowCommand { fn append_link( mut json: IndexMap<String, PhpMixed>, - package: &dyn CompletePackageInterface, + package: CompletePackageInterfaceHandle, link_type: &str, ) -> IndexMap<String, PhpMixed> { let links = package.get_links_for_type(link_type); @@ -2285,7 +2267,7 @@ impl ShowCommand { /// Generate the package tree pub(crate) fn generate_package_tree( &mut self, - package: &dyn PackageInterface, + package: PackageInterfaceHandle, installed_repo: &InstalledRepository, remote_repos: &dyn RepositoryInterface, ) -> IndexMap<String, PhpMixed> { @@ -2354,8 +2336,8 @@ impl ShowCommand { "description".to_string(), PhpMixed::String( package - .as_complete_package_interface() - .map(|c| c.get_description().unwrap_or("").to_string()) + .as_complete() + .map(|c| c.get_description().unwrap_or_default()) .unwrap_or_default(), ), ); @@ -2518,8 +2500,8 @@ impl ShowCommand { } fn get_update_status( - latest_package: &dyn PackageInterface, - package: &dyn PackageInterface, + latest_package: PackageInterfaceHandle, + package: PackageInterfaceHandle, ) -> String { if latest_package.get_full_pretty_version(true, 0) == package.get_full_pretty_version(true, 0) @@ -2532,7 +2514,7 @@ impl ShowCommand { constraint = format!("^{}", constraint); } if !latest_package.get_version().is_empty() - && Semver::satisfies(latest_package.get_version(), &constraint) + && Semver::satisfies(&latest_package.get_version(), &constraint) { // it needs an immediate semver-compliant upgrade return "semver-safe-update".to_string(); @@ -2559,7 +2541,7 @@ impl ShowCommand { /// Given a package, this finds the latest package matching it fn find_latest_package( &mut self, - package: &dyn PackageInterface, + package: PackageInterfaceHandle, composer: &PartialComposerHandle, platform_repo: &PlatformRepository, major_only: bool, @@ -2587,7 +2569,7 @@ impl ShowCommand { .get_minimum_stability() .to_string(); let flags = composer_ref.get_package().get_stability_flags(); - if let Some(flag_value) = flags.get(name) { + if let Some(flag_value) = flags.get(&name) { let key_map: IndexMap<String, String> = base_package::STABILITIES .iter() .map(|(k, v)| (k.to_string(), v.to_string())) @@ -2605,7 +2587,7 @@ impl ShowCommand { let mut target_version: Option<String> = None; if package.get_version().starts_with("dev-") { - target_version = Some(package.get_version().to_string()); + target_version = Some(package.get_version()); // dev-x branches are considered to be on the latest major version always, do not look up for a new commit as that is deemed a minor upgrade (albeit risky) if major_only { @@ -2618,7 +2600,7 @@ impl ShowCommand { if major_only && Preg::is_match3( r"{^(?P<zero_major>(?:0\.)+)?(?P<first_meaningful>\d+)\.}", - package.get_version(), + &package.get_version(), Some(&mut groups), )? { @@ -2644,7 +2626,7 @@ impl ShowCommand { } if patch_only { - let trimmed_version = Preg::replace(r"{(\.0)+$}D", "", package.get_version())?; + let trimmed_version = Preg::replace(r"{(\.0)+$}D", "", &package.get_version())?; let parts_needed = if trimmed_version.starts_with('0') { 4 } else { @@ -2658,26 +2640,26 @@ impl ShowCommand { } } - let show_warnings_box: Box<dyn Fn(&dyn PackageInterface) -> bool>; + let show_warnings_box: Box<dyn Fn(PackageInterfaceHandle) -> bool>; if self.get_io().is_verbose() { - show_warnings_box = Box::new(|_p: &dyn PackageInterface| -> bool { true }); + show_warnings_box = Box::new(|_p: PackageInterfaceHandle| -> bool { true }); } else { - let package_version = package.get_version().to_string(); - show_warnings_box = Box::new(move |candidate: &dyn PackageInterface| -> bool { + let package_version = package.get_version(); + show_warnings_box = Box::new(move |candidate: PackageInterfaceHandle| -> bool { if candidate.get_version().starts_with("dev-") || package_version.starts_with("dev-") { return false; } - version_compare(candidate.get_version(), &package_version, "<=") + version_compare(&candidate.get_version(), &package_version, "<=") }); } // TODO(phase-b): platform_req_filter needs to be Option<Box<dyn ...>>; current code holds &dyn. let _ = platform_req_filter; let _ = show_warnings_box; let mut candidate = version_selector.find_best_candidate( - name, + &name, target_version.as_deref(), &best_stability, None, diff --git a/crates/shirabe/src/command/status_command.rs b/crates/shirabe/src/command/status_command.rs index 182dec8..9f66adf 100644 --- a/crates/shirabe/src/command/status_command.rs +++ b/crates/shirabe/src/command/status_command.rs @@ -125,19 +125,18 @@ impl StatusCommand { let target_dir = composer .get_installation_manager() .borrow_mut() - .get_install_path(package.as_rc().borrow().as_package_interface()); + .get_install_path(package.clone()); let target_dir = match target_dir { Some(d) => d, None => continue, }; // TODO(phase-b): downloader borrow lifetime tied to dm.borrow() temporary; restructure later. let dm_borrow = dm.borrow(); - let downloader: &dyn crate::downloader::DownloaderInterface = match dm_borrow - .get_downloader_for_package(package.as_rc().borrow().as_package_interface())? - { - Some(d) => d, - None => continue, - }; + let downloader: &dyn crate::downloader::DownloaderInterface = + match dm_borrow.get_downloader_for_package(package.clone())? { + Some(d) => d, + None => continue, + }; // TODO(phase-b): isinstance checks using ChangeReportInterface/VcsCapableDownloaderInterface/DvcsDownloaderInterface if let Some(change_reporter) = downloader.as_change_report_interface() { @@ -148,20 +147,16 @@ impl StatusCommand { ); } - if let Some(changes) = change_reporter.get_local_changes( - package.as_rc().borrow().as_package_interface(), - &target_dir, - )? { + if let Some(changes) = + change_reporter.get_local_changes(package.clone(), &target_dir)? + { errors.insert(target_dir.clone(), changes); } } if let Some(vcs_downloader) = downloader.as_vcs_capable_downloader_interface() { if vcs_downloader - .get_vcs_reference( - package.as_rc().borrow().as_package_interface(), - target_dir.clone(), - ) + .get_vcs_reference(package.clone(), target_dir.clone()) .is_some() { let previous_ref = match package.get_installation_source().as_deref() { @@ -170,10 +165,8 @@ impl StatusCommand { _ => None, }; - let current_version = guesser.guess_version( - &dumper.dump(package.as_rc().borrow().as_package_interface()), - &target_dir, - )?; + let current_version = + guesser.guess_version(&dumper.dump(package.clone()), &target_dir)?; if let (Some(prev_ref), Some(cur_version)) = (&previous_ref, ¤t_version) { if cur_version.commit.as_deref() != Some(prev_ref.as_str()) @@ -207,10 +200,9 @@ impl StatusCommand { } if let Some(dvcs_downloader) = downloader.as_dvcs_downloader_interface() { - if let Some(unpushed) = dvcs_downloader.get_unpushed_changes( - package.as_rc().borrow().as_package_interface(), - target_dir.clone(), - ) { + if let Some(unpushed) = + dvcs_downloader.get_unpushed_changes(package.clone(), target_dir.clone()) + { unpushed_changes.insert(target_dir, unpushed); } } diff --git a/crates/shirabe/src/command/suggests_command.rs b/crates/shirabe/src/command/suggests_command.rs index b4693a2..aa1ae15 100644 --- a/crates/shirabe/src/command/suggests_command.rs +++ b/crates/shirabe/src/command/suggests_command.rs @@ -47,10 +47,8 @@ impl SuggestsCommand { let composer = self.require_composer(None, None)?; let mut composer = crate::command::composer_full_mut(&composer); - // TODO(phase-c): composer.get_package() returns &dyn RootPackageInterface, not a - // RootPackageInterfaceHandle, so it cannot be shared into RootPackageRepository::new yet. let root_package_handle: crate::package::RootPackageInterfaceHandle = - todo!("share composer.get_package() as a RootPackageInterfaceHandle"); + composer.get_package().clone(); let mut installed_repos: Vec<Box<dyn RepositoryInterface>> = vec![Box::new(RootPackageRepository::new(root_package_handle))]; @@ -97,16 +95,14 @@ impl SuggestsCommand { let filter = input.get_argument("packages"); let mut packages = RepositoryInterface::get_packages(&installed_repo); - // TODO(phase-c): composer.get_package() returns &dyn RootPackageInterface, not a handle, - // so it cannot be shared into the package list yet. let root_pkg_as_base: crate::package::BasePackageHandle = - todo!("share composer.get_package() as a BasePackageHandle"); + composer.get_package().clone().into(); packages.push(root_pkg_as_base); for package in &packages { if !empty(&filter) && !in_array(PhpMixed::String(package.get_name()), &filter, false) { continue; } - reporter.add_suggestions_from_package(package.as_rc().borrow().as_package_interface()); + reporter.add_suggestions_from_package(package.clone()); } let mut mode = SuggestedPackagesReporter::MODE_BY_PACKAGE; @@ -121,12 +117,9 @@ impl SuggestsCommand { mode = SuggestedPackagesReporter::MODE_LIST; } - let only_dependents_of: Option<&dyn crate::package::PackageInterface> = + let only_dependents_of: Option<crate::package::PackageInterfaceHandle> = if empty(&filter) && !input.get_option("all").as_bool().unwrap_or(false) { - // TODO(phase-b): composer.get_package() returns &dyn RootPackageInterface; need conversion to &dyn PackageInterface - Some(todo!( - "convert RootPackageInterface to &dyn PackageInterface" - )) + Some(composer.get_package().clone().into()) } else { None }; diff --git a/crates/shirabe/src/command/validate_command.rs b/crates/shirabe/src/command/validate_command.rs index cb8fa89..12eadd7 100644 --- a/crates/shirabe/src/command/validate_command.rs +++ b/crates/shirabe/src/command/validate_command.rs @@ -217,7 +217,7 @@ impl ValidateCommand { let path = composer .get_installation_manager() .borrow_mut() - .get_install_path(package.as_rc().borrow().as_package_interface()); + .get_install_path(package.clone()); let path = match path { Some(p) => p, None => continue, diff --git a/crates/shirabe/src/console/application.rs b/crates/shirabe/src/console/application.rs index 3a6b847..f27ed79 100644 --- a/crates/shirabe/src/console/application.rs +++ b/crates/shirabe/src/console/application.rs @@ -648,11 +648,7 @@ impl Application { ); let map = generator.parse_autoloads( package_map, - root_package - .as_rc() - .borrow() - .as_root_package_interface() - .unwrap(), + root_package.clone(), PhpMixed::Bool(false), ); diff --git a/crates/shirabe/src/dependency_resolver/default_policy.rs b/crates/shirabe/src/dependency_resolver/default_policy.rs index 0c6b2fc..541ec44 100644 --- a/crates/shirabe/src/dependency_resolver/default_policy.rs +++ b/crates/shirabe/src/dependency_resolver/default_policy.rs @@ -44,8 +44,8 @@ impl DefaultPolicy { pub fn compare_by_priority( &self, pool: &Pool, - a: &BasePackageHandle, - b: &BasePackageHandle, + a: BasePackageHandle, + b: BasePackageHandle, required_package: Option<String>, ignore_replace: bool, ) -> i64 { @@ -61,10 +61,10 @@ impl DefaultPolicy { } if !ignore_replace { - if self.replaces(a, b) { + if self.replaces(a.clone(), b.clone()) { return 1; } - if self.replaces(b, a) { + if self.replaces(b.clone(), a.clone()) { return -1; } @@ -125,10 +125,10 @@ impl DefaultPolicy { continue; } let package = pool.literal_to_package(literal); - if self.version_compare(&package, &best_package, operator) { + if self.version_compare(package.clone(), best_package.clone(), operator) { best_package = package; best_literals = vec![literal]; - } else if self.version_compare(&package, &best_package, "==") { + } else if self.version_compare(package.clone(), best_package.clone(), "==") { best_literals.push(literal); } } @@ -164,7 +164,7 @@ impl DefaultPolicy { selected } - pub(crate) fn replaces(&self, source: &BasePackageHandle, target: &BasePackageHandle) -> bool { + pub(crate) fn replaces(&self, source: BasePackageHandle, target: BasePackageHandle) -> bool { for link in source.get_replaces().values() { if link.get_target() == target.get_name().as_str() { return true; @@ -175,12 +175,7 @@ impl DefaultPolicy { } impl PolicyInterface for DefaultPolicy { - fn version_compare( - &self, - a: &BasePackageHandle, - b: &BasePackageHandle, - operator: &str, - ) -> bool { + fn version_compare(&self, a: BasePackageHandle, b: BasePackageHandle, operator: &str) -> bool { if self.prefer_stable { let stab_a = a.get_stability().to_string(); let stab_b = b.get_stability().to_string(); @@ -263,8 +258,8 @@ impl PolicyInterface for DefaultPolicy { } let result = self.compare_by_priority( pool, - &pool.literal_to_package(a), - &pool.literal_to_package(b), + pool.literal_to_package(a), + pool.literal_to_package(b), required_package.clone(), true, ); @@ -296,8 +291,8 @@ impl PolicyInterface for DefaultPolicy { } let result = self.compare_by_priority( pool, - &pool.literal_to_package(a), - &pool.literal_to_package(b), + pool.literal_to_package(a), + pool.literal_to_package(b), required_package.clone(), false, ); diff --git a/crates/shirabe/src/dependency_resolver/lock_transaction.rs b/crates/shirabe/src/dependency_resolver/lock_transaction.rs index 09d4571..dd3dd97 100644 --- a/crates/shirabe/src/dependency_resolver/lock_transaction.rs +++ b/crates/shirabe/src/dependency_resolver/lock_transaction.rs @@ -117,7 +117,7 @@ impl LockTransaction { } if update_mirrors && !self.present_map.contains_key(&package.ptr_id().to_string()) { - let updated = self.update_mirror_and_urls(package); + let updated = self.update_mirror_and_urls(package.clone()); packages.push(updated); } else { packages.push(package.clone()); @@ -127,7 +127,7 @@ impl LockTransaction { packages } - fn update_mirror_and_urls(&self, package: &PackageInterfaceHandle) -> PackageInterfaceHandle { + fn update_mirror_and_urls(&self, package: PackageInterfaceHandle) -> PackageInterfaceHandle { for present_package in self.present_map.values() { if package.get_name() != present_package.get_name() { continue; diff --git a/crates/shirabe/src/dependency_resolver/operation/install_operation.rs b/crates/shirabe/src/dependency_resolver/operation/install_operation.rs index 466c877..23be038 100644 --- a/crates/shirabe/src/dependency_resolver/operation/install_operation.rs +++ b/crates/shirabe/src/dependency_resolver/operation/install_operation.rs @@ -15,11 +15,11 @@ impl InstallOperation { Self { package } } - pub fn get_package(&self) -> &PackageInterfaceHandle { - &self.package + pub fn get_package(&self) -> PackageInterfaceHandle { + self.package.clone() } - pub fn format(package: &dyn PackageInterface, lock: bool) -> String { + pub fn format(package: PackageInterfaceHandle, lock: bool) -> String { format!( "{}<info>{}</info> (<comment>{}</comment>)", if lock { "Locking " } else { "Installing " }, @@ -44,7 +44,7 @@ impl OperationInterface for InstallOperation { } fn show(&self, lock: bool) -> String { - Self::format(self.package.as_rc().borrow().as_package_interface(), lock) + Self::format(self.package.clone(), lock) } fn to_string(&self) -> String { diff --git a/crates/shirabe/src/dependency_resolver/operation/mark_alias_installed_operation.rs b/crates/shirabe/src/dependency_resolver/operation/mark_alias_installed_operation.rs index 339f86c..a10186a 100644 --- a/crates/shirabe/src/dependency_resolver/operation/mark_alias_installed_operation.rs +++ b/crates/shirabe/src/dependency_resolver/operation/mark_alias_installed_operation.rs @@ -2,21 +2,21 @@ use crate::dependency_resolver::operation::OperationInterface; use crate::dependency_resolver::operation::SolverOperation; -use crate::package::AliasPackage; +use crate::package::AliasPackageHandle; use crate::package::PackageInterface; #[derive(Debug)] pub struct MarkAliasInstalledOperation { - pub(crate) package: AliasPackage, + pub(crate) package: AliasPackageHandle, } impl MarkAliasInstalledOperation { - pub fn new(package: AliasPackage) -> Self { + pub fn new(package: AliasPackageHandle) -> Self { Self { package } } - pub fn get_package(&self) -> &AliasPackage { - &self.package + pub fn get_package(&self) -> AliasPackageHandle { + self.package.clone() } } @@ -36,12 +36,9 @@ impl OperationInterface for MarkAliasInstalledOperation { fn show(&self, _lock: bool) -> String { format!( "Marking <info>{}</info> (<comment>{}</comment>) as installed, alias of <info>{}</info> (<comment>{}</comment>)", - PackageInterface::get_pretty_name(&self.package), - PackageInterface::get_full_pretty_version( - &self.package, - true, - <dyn PackageInterface>::DISPLAY_SOURCE_REF_IF_DEV, - ), + self.package.get_pretty_name(), + self.package + .get_full_pretty_version(true, <dyn PackageInterface>::DISPLAY_SOURCE_REF_IF_DEV), self.package.get_alias_of().get_pretty_name(), self.package .get_alias_of() diff --git a/crates/shirabe/src/dependency_resolver/operation/mark_alias_uninstalled_operation.rs b/crates/shirabe/src/dependency_resolver/operation/mark_alias_uninstalled_operation.rs index a5b7b7d..b9ad26e 100644 --- a/crates/shirabe/src/dependency_resolver/operation/mark_alias_uninstalled_operation.rs +++ b/crates/shirabe/src/dependency_resolver/operation/mark_alias_uninstalled_operation.rs @@ -2,21 +2,21 @@ use crate::dependency_resolver::operation::OperationInterface; use crate::dependency_resolver::operation::SolverOperation; -use crate::package::AliasPackage; +use crate::package::AliasPackageHandle; use crate::package::PackageInterface; #[derive(Debug)] pub struct MarkAliasUninstalledOperation { - pub(crate) package: AliasPackage, + pub(crate) package: AliasPackageHandle, } impl MarkAliasUninstalledOperation { - pub fn new(package: AliasPackage) -> Self { + pub fn new(package: AliasPackageHandle) -> Self { Self { package } } - pub fn get_package(&self) -> &AliasPackage { - &self.package + pub fn get_package(&self) -> AliasPackageHandle { + self.package.clone() } } @@ -36,12 +36,9 @@ impl OperationInterface for MarkAliasUninstalledOperation { fn show(&self, _lock: bool) -> String { format!( "Marking <info>{}</info> (<comment>{}</comment>) as uninstalled, alias of <info>{}</info> (<comment>{}</comment>)", - PackageInterface::get_pretty_name(&self.package), - PackageInterface::get_full_pretty_version( - &self.package, - true, - <dyn PackageInterface>::DISPLAY_SOURCE_REF_IF_DEV, - ), + self.package.get_pretty_name(), + self.package + .get_full_pretty_version(true, <dyn PackageInterface>::DISPLAY_SOURCE_REF_IF_DEV), self.package.get_alias_of().get_pretty_name(), self.package .get_alias_of() diff --git a/crates/shirabe/src/dependency_resolver/operation/operation_interface.rs b/crates/shirabe/src/dependency_resolver/operation/operation_interface.rs index a5b5e5f..3c24ff4 100644 --- a/crates/shirabe/src/dependency_resolver/operation/operation_interface.rs +++ b/crates/shirabe/src/dependency_resolver/operation/operation_interface.rs @@ -31,7 +31,7 @@ pub trait OperationInterface: std::fmt::Debug { /// PHP duck-typed accessor. Only InstallOperation/UninstallOperation/MarkAlias*Operation /// expose this; UpdateOperation has getInitialPackage()/getTargetPackage() instead. - fn get_package(&self) -> &dyn crate::package::PackageInterface { + fn get_package(&self) -> crate::package::PackageInterfaceHandle { todo!("get_package is not available on this operation type") } } diff --git a/crates/shirabe/src/dependency_resolver/operation/uninstall_operation.rs b/crates/shirabe/src/dependency_resolver/operation/uninstall_operation.rs index 2757146..3ff547c 100644 --- a/crates/shirabe/src/dependency_resolver/operation/uninstall_operation.rs +++ b/crates/shirabe/src/dependency_resolver/operation/uninstall_operation.rs @@ -15,11 +15,11 @@ impl UninstallOperation { Self { package } } - pub fn get_package(&self) -> &PackageInterfaceHandle { - &self.package + pub fn get_package(&self) -> PackageInterfaceHandle { + self.package.clone() } - pub fn format(package: &dyn PackageInterface, _lock: bool) -> String { + pub fn format(package: PackageInterfaceHandle, _lock: bool) -> String { format!( "Removing <info>{}</info> (<comment>{}</comment>)", package.get_pretty_name(), @@ -43,7 +43,7 @@ impl OperationInterface for UninstallOperation { } fn show(&self, lock: bool) -> String { - Self::format(self.package.as_rc().borrow().as_package_interface(), lock) + Self::format(self.package.clone(), lock) } fn to_string(&self) -> String { diff --git a/crates/shirabe/src/dependency_resolver/operation/update_operation.rs b/crates/shirabe/src/dependency_resolver/operation/update_operation.rs index 6881782..bc31256 100644 --- a/crates/shirabe/src/dependency_resolver/operation/update_operation.rs +++ b/crates/shirabe/src/dependency_resolver/operation/update_operation.rs @@ -20,17 +20,17 @@ impl UpdateOperation { } } - pub fn get_initial_package(&self) -> &PackageInterfaceHandle { - &self.initial_package + pub fn get_initial_package(&self) -> PackageInterfaceHandle { + self.initial_package.clone() } - pub fn get_target_package(&self) -> &PackageInterfaceHandle { - &self.target_package + pub fn get_target_package(&self) -> PackageInterfaceHandle { + self.target_package.clone() } pub fn format( - initial_package: &dyn PackageInterface, - target_package: &dyn PackageInterface, + initial_package: PackageInterfaceHandle, + target_package: PackageInterfaceHandle, lock: bool, ) -> String { let mut from_version = initial_package @@ -90,8 +90,8 @@ impl OperationInterface for UpdateOperation { fn show(&self, lock: bool) -> String { Self::format( - self.initial_package.as_rc().borrow().as_package_interface(), - self.target_package.as_rc().borrow().as_package_interface(), + self.initial_package.clone(), + self.target_package.clone(), lock, ) } diff --git a/crates/shirabe/src/dependency_resolver/policy_interface.rs b/crates/shirabe/src/dependency_resolver/policy_interface.rs index 002bfe9..0b37dc5 100644 --- a/crates/shirabe/src/dependency_resolver/policy_interface.rs +++ b/crates/shirabe/src/dependency_resolver/policy_interface.rs @@ -4,8 +4,7 @@ use crate::dependency_resolver::Pool; use crate::package::BasePackageHandle; pub trait PolicyInterface: std::fmt::Debug { - fn version_compare(&self, a: &BasePackageHandle, b: &BasePackageHandle, operator: &str) - -> bool; + fn version_compare(&self, a: BasePackageHandle, b: BasePackageHandle, operator: &str) -> bool; fn select_preferred_packages( &self, diff --git a/crates/shirabe/src/dependency_resolver/pool.rs b/crates/shirabe/src/dependency_resolver/pool.rs index 388f23f..ddb4df5 100644 --- a/crates/shirabe/src/dependency_resolver/pool.rs +++ b/crates/shirabe/src/dependency_resolver/pool.rs @@ -272,7 +272,7 @@ impl Pool { let mut matches: Vec<BasePackageHandle> = vec![]; for candidate in candidates { - if self.r#match(candidate, name, constraint) { + if self.r#match(candidate.clone(), name, constraint) { matches.push(candidate.clone()); } } @@ -313,7 +313,7 @@ impl Pool { /// @param string $name Name of the package to be matched pub fn r#match( &self, - candidate: &BasePackageHandle, + candidate: BasePackageHandle, name: &str, constraint: Option<&AnyConstraint>, ) -> bool { @@ -371,12 +371,12 @@ impl Pool { false } - pub fn is_unacceptable_fixed_or_locked_package(&self, package: &BasePackageHandle) -> bool { + pub fn is_unacceptable_fixed_or_locked_package(&self, package: BasePackageHandle) -> bool { // PHP: \in_array($package, $this->unacceptableFixedOrLockedPackages, true) // strict comparison checks reference identity for objects self.unacceptable_fixed_or_locked_packages .iter() - .any(|p| p.ptr_eq(package)) + .any(|p| p.ptr_eq(&package)) } /// @return BasePackage[] diff --git a/crates/shirabe/src/dependency_resolver/pool_builder.rs b/crates/shirabe/src/dependency_resolver/pool_builder.rs index 0efaac5..489b358 100644 --- a/crates/shirabe/src/dependency_resolver/pool_builder.rs +++ b/crates/shirabe/src/dependency_resolver/pool_builder.rs @@ -164,7 +164,7 @@ impl PoolBuilder { for locked_package in CanonicalPackagesTrait::get_packages(request.get_locked_repository().unwrap()) { - if !self.is_update_allowed(locked_package.as_rc().borrow().as_package_interface()) { + if !self.is_update_allowed(locked_package.clone()) { // Path repo packages are never loaded from lock, to force them to always remain in sync // unless symlinking is disabled in which case we probably should rather treat them like // regular packages. We mark them specially so they can be reloaded fully including update propagation @@ -221,7 +221,7 @@ impl PoolBuilder { &package.get_stability(), ) { - self.load_package(request, &repositories, &package, false)?; + self.load_package(request, &repositories, package.clone(), false)?; } else { self.unacceptable_fixed_or_locked_packages.push(package); } @@ -578,7 +578,7 @@ impl PoolBuilder { } let _ = (pkg_name, pkg_version); let propagate = !self.path_repo_unlocked.contains_key(&package.get_name()); - self.load_package(request, repositories, package, propagate)?; + self.load_package(request, repositories, package.clone(), propagate)?; } } @@ -612,7 +612,7 @@ impl PoolBuilder { &mut self, request: &mut Request, repositories: &Vec<Box<dyn RepositoryInterface>>, - package: &BasePackageHandle, + package: BasePackageHandle, propagate_update: bool, ) -> anyhow::Result<()> { let index = self.index_counter; @@ -805,10 +805,10 @@ impl PoolBuilder { } /// Checks whether the update allow list allows this package in the lock file to be updated - fn is_update_allowed(&self, package: &dyn PackageInterface) -> bool { + fn is_update_allowed(&self, package: PackageInterfaceHandle) -> bool { for pattern in &self.update_allow_list { let pattern_regexp = base_package::package_name_to_regexp(pattern); - if Preg::is_match3(&pattern_regexp, package.get_name(), None).unwrap_or(false) { + if Preg::is_match3(&pattern_regexp, &package.get_name(), None).unwrap_or(false) { return true; } } @@ -927,7 +927,7 @@ impl PoolBuilder { .map(|(i, p)| (*i, p.clone())) .collect(); for (index, package) in &entries { - self.remove_loaded_package(request, repositories, package, *index); + self.remove_loaded_package(request, repositories, package.clone(), *index); } } @@ -945,8 +945,13 @@ impl PoolBuilder { // PHP uses array_search with strict identity; map to pointer comparison. let index_opt = pkgs.iter().position(|p| p.ptr_eq(locked_package)); if let Some(index) = index_opt { - request.unlock_package(locked_package); - self.remove_loaded_package(request, repositories, locked_package, index as i64); + request.unlock_package(locked_package.clone()); + self.remove_loaded_package( + request, + repositories, + locked_package.clone(), + index as i64, + ); // make sure that any requirements for this package by other locked or fixed packages are now // also loaded, as they were previously ignored because the locked (now unlocked) package already @@ -1025,7 +1030,7 @@ impl PoolBuilder { &mut self, _request: &Request, repositories: &Vec<Box<dyn RepositoryInterface>>, - package: &BasePackageHandle, + package: BasePackageHandle, index: i64, ) { let repos_box: Vec<Box<dyn RepositoryInterface>> = diff --git a/crates/shirabe/src/dependency_resolver/pool_optimizer.rs b/crates/shirabe/src/dependency_resolver/pool_optimizer.rs index 8aa8324..18c8d01 100644 --- a/crates/shirabe/src/dependency_resolver/pool_optimizer.rs +++ b/crates/shirabe/src/dependency_resolver/pool_optimizer.rs @@ -162,18 +162,18 @@ impl PoolOptimizer { SimpleConstraint::OP_EQ, package.get_version().to_string(), ) { - self.mark_package_irremovable(package); + self.mark_package_irremovable(package.clone()); } } } - fn mark_package_irremovable(&mut self, package: &BasePackageHandle) { + fn mark_package_irremovable(&mut self, package: BasePackageHandle) { self.irremovable_packages.insert(package.id(), true); if let Some(alias_pkg) = package.as_alias() { // recursing here so aliasesPerPackage for the aliasOf can be checked // and all its aliases marked as irremovable as well let aliased: BasePackageHandle = alias_pkg.get_alias_of().into(); - self.mark_package_irremovable(&aliased); + self.mark_package_irremovable(aliased); } // PHP: foreach ($this->aliasesPerPackage[$package->id] as $aliasPackage) let alias_ids: Vec<i64> = self @@ -238,7 +238,7 @@ impl PoolOptimizer { self.mark_package_for_removal(package.id())?; - let dependency_hash = self.calculate_dependency_hash(package); + let dependency_hash = self.calculate_dependency_hash(package.clone()); for package_name in package.get_names(false) { if !self @@ -333,7 +333,7 @@ impl PoolOptimizer { // Only one package in this constraint group has the same requirements, we're not allowed to remove that package if 1 == packages.len() { self.keep_package( - &packages[0], + packages[0].clone(), &identical_definitions_per_package, &package_identical_definition_lookup, ); @@ -353,7 +353,7 @@ impl PoolOptimizer { .select_preferred_packages(pool, literals.clone(), None) { self.keep_package( - &pool.literal_to_package(preferred_literal), + pool.literal_to_package(preferred_literal), &identical_definitions_per_package, &package_identical_definition_lookup, ); @@ -365,7 +365,7 @@ impl PoolOptimizer { Ok(()) } - fn calculate_dependency_hash(&self, package: &BasePackageHandle) -> String { + fn calculate_dependency_hash(&self, package: BasePackageHandle) -> String { let mut hash = String::new(); let hash_relevant_links: Vec<(&str, Vec<crate::package::Link>)> = vec![ @@ -438,7 +438,7 @@ impl PoolOptimizer { /// @param array<int, array<string, array{groupHash: string, dependencyHash: string}>> $packageIdenticalDefinitionLookup fn keep_package( &mut self, - package: &BasePackageHandle, + package: BasePackageHandle, identical_definitions_per_package: &IndexMap< String, IndexMap<String, IndexMap<String, Vec<BasePackageHandle>>>, @@ -460,7 +460,7 @@ impl PoolOptimizer { // and all its aliases marked to be kept as well let aliased: BasePackageHandle = alias_pkg.get_alias_of().into(); self.keep_package( - &aliased, + aliased, identical_definitions_per_package, package_identical_definition_lookup, ); @@ -572,7 +572,9 @@ impl PoolOptimizer { continue; } // Do not remove locked packages - if request.is_fixed_package(&package) || request.is_locked_package(&package) { + if request.is_fixed_package(package.clone()) + || request.is_locked_package(package.clone()) + { continue; } diff --git a/crates/shirabe/src/dependency_resolver/problem.rs b/crates/shirabe/src/dependency_resolver/problem.rs index 509a0dc..58d47f1 100644 --- a/crates/shirabe/src/dependency_resolver/problem.rs +++ b/crates/shirabe/src/dependency_resolver/problem.rs @@ -156,9 +156,7 @@ impl Problem { // TODO(phase-b): reason_data is a Link. let source = rule.get_source_package(pool).unwrap(); let link_pretty = match rule.get_reason_data() { - rule::ReasonData::Link(link) => { - link.get_pretty_string(source.as_rc().borrow().as_package_interface()) - } + rule::ReasonData::Link(link) => link.get_pretty_string(source.clone()), _ => String::new(), }; format!("{}//{}", source.get_pretty_string(), link_pretty) @@ -558,9 +556,7 @@ impl Problem { for (_key, package) in request.get_locked_packages() { if package.get_name().as_str() == package_name { locked_package = Some(package.clone()); - // TODO(phase-c): wire Pool::is_unacceptable_fixed_or_locked_package(package) here; - // the locked package handle and the pool's identity check are now both handle-based. - if todo!("is_unacceptable_fixed_or_locked_package with a request package handle") { + if pool.is_unacceptable_fixed_or_locked_package(package.clone()) { return ( "- ".to_string(), format!( @@ -807,9 +803,9 @@ impl Problem { } if pool.is_security_removed_package_version(package_name, constraint) { - // TODO(phase-b): get_matching_security_advisories needs Vec<Box<dyn PackageInterface>> + // TODO(phase-b): get_matching_security_advisories needs Vec<PackageInterfaceHandle> // and SecurityAdvisory.inner.advisory_id is on the private inner field. - // Convert packages to PackageInterface boxes and adjust SecurityAdvisory accessor first. + // Convert packages to PackageInterfaceHandle and adjust SecurityAdvisory accessor first. let _ = repository_set; let advisories_list: Vec<String> = pool .get_security_advisory_identifiers_for_package_version(package_name, constraint) diff --git a/crates/shirabe/src/dependency_resolver/request.rs b/crates/shirabe/src/dependency_resolver/request.rs index 686373b..0621775 100644 --- a/crates/shirabe/src/dependency_resolver/request.rs +++ b/crates/shirabe/src/dependency_resolver/request.rs @@ -125,7 +125,7 @@ impl Request { self.fixed_locked_packages.insert(hash, package); } - pub fn unlock_package(&mut self, package: &BasePackageHandle) { + pub fn unlock_package(&mut self, package: BasePackageHandle) { self.locked_packages.remove(&package.ptr_id().to_string()); } @@ -161,7 +161,7 @@ impl Request { &self.fixed_packages } - pub fn is_fixed_package(&self, package: &BasePackageHandle) -> bool { + pub fn is_fixed_package(&self, package: BasePackageHandle) -> bool { self.fixed_packages .contains_key(&package.ptr_id().to_string()) } @@ -170,7 +170,7 @@ impl Request { &self.locked_packages } - pub fn is_locked_package(&self, package: &BasePackageHandle) -> bool { + pub fn is_locked_package(&self, package: BasePackageHandle) -> bool { let hash = package.ptr_id().to_string(); self.locked_packages.contains_key(&hash) || self.fixed_locked_packages.contains_key(&hash) } diff --git a/crates/shirabe/src/dependency_resolver/rule.rs b/crates/shirabe/src/dependency_resolver/rule.rs index afb0318..1681509 100644 --- a/crates/shirabe/src/dependency_resolver/rule.rs +++ b/crates/shirabe/src/dependency_resolver/rule.rs @@ -234,9 +234,9 @@ impl Rule { if let Some(_locked_repo) = locked_repo { let packages: Vec<BasePackageHandle> = todo!("locked_repo.get_packages()"); for package in packages { - let p: &BasePackageHandle = &package; + let p = package.clone(); if p.get_name() == link.get_target() { - if pool.is_unacceptable_fixed_or_locked_package(p) { + if pool.is_unacceptable_fixed_or_locked_package(p.clone()) { return true; } if !link.get_constraint().matches( @@ -250,8 +250,7 @@ impl Rule { return true; } // required package was locked but has been unlocked and still matches - if !request.is_locked_package(todo!("package as &dyn PackageInterface")) - { + if !request.is_locked_package(p) { return true; } break; @@ -275,9 +274,9 @@ impl Rule { if let Some(_locked_repo) = locked_repo { let packages: Vec<BasePackageHandle> = todo!("locked_repo.get_packages()"); for package in packages { - let p: &BasePackageHandle = &package; + let p = package.clone(); if p.get_name() == *package_name { - if pool.is_unacceptable_fixed_or_locked_package(p) { + if pool.is_unacceptable_fixed_or_locked_package(p.clone()) { return true; } if !constraint.matches( @@ -378,8 +377,7 @@ impl Rule { .collect(); if packages_non_alias.len() == 1 { let package = &packages_non_alias[0]; - // TODO(phase-b): request.is_locked_package signature - if request.is_locked_package(todo!("package as &dyn PackageInterface")) { + if request.is_locked_package(package.clone()) { return format!( "{} is locked to version {} and an update of this package was not requested.", package.get_pretty_name(), @@ -409,7 +407,7 @@ impl Rule { }; let package = self.deduplicate_default_branch_alias(package_in); - if request.is_locked_package(todo!("package as &dyn PackageInterface")) { + if request.is_locked_package(package.clone()) { return format!( "{} is locked to version {} and an update of this package was not requested.", package.get_pretty_name(), @@ -504,8 +502,7 @@ impl Rule { requires.push(pool.literal_to_package(*literal)); } - let text = - link.get_pretty_string(source_package.as_rc().borrow().as_package_interface()); + let text = link.get_pretty_string(source_package.clone()); if requires.len() > 0 { format!( "{} -> satisfiable by {}.", diff --git a/crates/shirabe/src/dependency_resolver/rule_set_generator.rs b/crates/shirabe/src/dependency_resolver/rule_set_generator.rs index 69f5c4a..fece1e4 100644 --- a/crates/shirabe/src/dependency_resolver/rule_set_generator.rs +++ b/crates/shirabe/src/dependency_resolver/rule_set_generator.rs @@ -50,7 +50,7 @@ impl RuleSetGenerator { /// one requirement of the package A. fn create_require_rule( &self, - package: &PackageInterfaceHandle, + package: PackageInterfaceHandle, providers: &[PackageInterfaceHandle], reason: i64, reason_data: PhpMixed, @@ -59,7 +59,7 @@ impl RuleSetGenerator { for provider in providers { // self fulfilling rule? - if provider.ptr_eq(package) { + if provider.ptr_eq(&package) { return None; } literals.push(provider.get_id()); @@ -92,13 +92,13 @@ impl RuleSetGenerator { /// and B the provider. fn create_rule2_literals( &self, - issuer: &PackageInterfaceHandle, - provider: &PackageInterfaceHandle, + issuer: PackageInterfaceHandle, + provider: PackageInterfaceHandle, reason: i64, reason_data: PhpMixed, ) -> Option<Rule2Literals> { // ignore self conflict - if issuer.ptr_eq(provider) { + if issuer.ptr_eq(&provider) { return None; } @@ -172,7 +172,7 @@ impl RuleSetGenerator { let alias_of: PackageInterfaceHandle = alias_pkg.get_alias_of().into(); work_queue.push_back(alias_of.clone()); let rule = self.create_require_rule( - &package, + package.clone(), &[alias_of.clone()], rule::RULE_PACKAGE_ALIAS, PhpMixed::Null, // reasonData: $package (BasePackage) @@ -181,7 +181,7 @@ impl RuleSetGenerator { // aliases must be installed with their main package, so create a rule the other way around as well let inverse_rule = self.create_require_rule( - &alias_of, + alias_of.clone(), &[package.clone()], rule::RULE_PACKAGE_INVERSE_ALIAS, PhpMixed::Null, // reasonData: $package->getAliasOf() (BasePackage) @@ -218,7 +218,7 @@ impl RuleSetGenerator { .collect(); let rule = self.create_require_rule( - &package, + package.clone(), &possible_requires, rule::RULE_PACKAGE_REQUIRES, PhpMixed::Null, // reasonData: $link (Link) @@ -274,8 +274,8 @@ impl RuleSetGenerator { let conflict_name_matches = conflict.get_name() == link.get_target(); if !conflict_is_alias || conflict_name_matches { let rule = self.create_rule2_literals( - package, - conflict, + package.clone(), + conflict.clone(), rule::RULE_PACKAGE_CONFLICT, PhpMixed::Null, // reasonData: $link (Link) ); diff --git a/crates/shirabe/src/dependency_resolver/security_advisory_pool_filter.rs b/crates/shirabe/src/dependency_resolver/security_advisory_pool_filter.rs index ba2cf09..785e758 100644 --- a/crates/shirabe/src/dependency_resolver/security_advisory_pool_filter.rs +++ b/crates/shirabe/src/dependency_resolver/security_advisory_pool_filter.rs @@ -5,7 +5,7 @@ use crate::advisory::Auditor; use crate::advisory::PartialSecurityAdvisory; use crate::dependency_resolver::Pool; use crate::dependency_resolver::Request; -use crate::package::PackageInterface; +use crate::package::BasePackageHandle; use crate::repository::RepositoryInterface; use indexmap::IndexMap; use shirabe_semver::constraint::AnyConstraint; @@ -51,7 +51,7 @@ impl SecurityAdvisoryPoolFilter { /// @return list<PartialSecurityAdvisory|SecurityAdvisory> fn get_matching_advisories( &self, - package: &dyn PackageInterface, + package: BasePackageHandle, advisory_map: &IndexMap<String, Vec<PartialSecurityAdvisory>>, ) -> Vec<PartialSecurityAdvisory> { if package.is_dev() { diff --git a/crates/shirabe/src/downloader/archive_downloader.rs b/crates/shirabe/src/downloader/archive_downloader.rs index ffa2ef4..f2ec719 100644 --- a/crates/shirabe/src/downloader/archive_downloader.rs +++ b/crates/shirabe/src/downloader/archive_downloader.rs @@ -13,7 +13,7 @@ use crate::downloader::DownloaderInterface; use crate::downloader::FileDownloader; use crate::io::IOInterface; use crate::io::IOInterfaceImmutable; -use crate::package::PackageInterface; +use crate::package::PackageInterfaceHandle; use crate::util::Filesystem; use crate::util::Platform; @@ -25,7 +25,7 @@ pub trait ArchiveDownloader { async fn extract( &self, - package: &dyn PackageInterface, + package: PackageInterfaceHandle, file: &str, path: &str, ) -> Result<Option<PhpMixed>>; @@ -33,11 +33,11 @@ pub trait ArchiveDownloader { async fn prepare( &mut self, r#type: &str, - package: &dyn PackageInterface, + package: PackageInterfaceHandle, path: &str, - prev_package: Option<&dyn PackageInterface>, + prev_package: Option<PackageInterfaceHandle>, ) -> Result<Option<PhpMixed>> { - self.cleanup_executed_mut().remove(package.get_name()); + self.cleanup_executed_mut().remove(&package.get_name()); self.inner_mut() .prepare(r#type, package, path, prev_package) .await @@ -46,12 +46,11 @@ pub trait ArchiveDownloader { async fn cleanup( &mut self, r#type: &str, - package: &dyn PackageInterface, + package: PackageInterfaceHandle, path: &str, - prev_package: Option<&dyn PackageInterface>, + prev_package: Option<PackageInterfaceHandle>, ) -> Result<Option<PhpMixed>> { - self.cleanup_executed_mut() - .insert(package.get_name().to_string(), true); + self.cleanup_executed_mut().insert(package.get_name(), true); self.inner_mut() .cleanup(r#type, package, path, prev_package) .await @@ -63,15 +62,15 @@ pub trait ArchiveDownloader { /// @throws \UnexpectedValueException async fn install( &mut self, - package: &dyn PackageInterface, + package: PackageInterfaceHandle, path: &str, output: bool, ) -> Result<Option<PhpMixed>> { if output { self.inner().io.write_error(&format!( " - {}{}", - InstallOperation::format(package, false), - self.get_install_operation_appendix(package, path) + InstallOperation::format(package.clone(), false), + self.get_install_operation_appendix(package.clone(), path) )); } @@ -113,22 +112,26 @@ pub trait ArchiveDownloader { } }; - self.inner_mut().add_cleanup_path(package, &temporary_dir); + self.inner_mut() + .add_cleanup_path(package.clone(), &temporary_dir); // avoid cleaning up $path if installing in "." for eg create-project as we can not // delete the directory we are currently in on windows if !is_dir(path) || realpath(path) != Some(Platform::get_cwd(false).unwrap_or_default()) { - self.inner_mut().add_cleanup_path(package, path); + self.inner_mut().add_cleanup_path(package.clone(), path); } self.inner_mut() .filesystem .borrow_mut() .ensure_directory_exists(&temporary_dir); - let file_name = self.inner().get_file_name(package, path); + let file_name = self.inner().get_file_name(package.clone(), path); - match self.extract(package, &file_name, &temporary_dir).await { + match self + .extract(package.clone(), &file_name, &temporary_dir) + .await + { Err(e) => { - install_cleanup(self.inner_mut(), package, path, &temporary_dir)?; + install_cleanup(self.inner_mut(), package.clone(), path, &temporary_dir)?; Err(e) } Ok(_) => { @@ -184,7 +187,7 @@ pub trait ArchiveDownloader { from = content_dir.first().unwrap().get_pathname(); } - rename_recursively(&self.inner().filesystem, package, &from, path)?; + rename_recursively(&self.inner().filesystem, package.clone(), &from, path)?; } self.inner() @@ -193,7 +196,7 @@ pub trait ArchiveDownloader { .remove_directory_async(&temporary_dir) .await?; self.inner_mut() - .remove_cleanup_path(package, &temporary_dir); + .remove_cleanup_path(package.clone(), &temporary_dir); self.inner_mut().remove_cleanup_path(package, path); Ok(None) @@ -202,19 +205,23 @@ pub trait ArchiveDownloader { } /// @inheritDoc - fn get_install_operation_appendix(&self, _package: &dyn PackageInterface, _path: &str) -> &str { + fn get_install_operation_appendix( + &self, + _package: PackageInterfaceHandle, + _path: &str, + ) -> &str { ": Extracting archive" } } fn install_cleanup( inner: &mut FileDownloader, - package: &dyn PackageInterface, + package: PackageInterfaceHandle, path: &str, temporary_dir: &str, ) -> Result<()> { // remove cache if the file was corrupted - inner.clear_last_cache_write(package); + inner.clear_last_cache_write(package.clone()); // clean up inner @@ -224,7 +231,7 @@ fn install_cleanup( if is_dir(path) && realpath(path) != Some(Platform::get_cwd(false).unwrap_or_default()) { inner.filesystem.borrow_mut().remove_directory(path)?; } - inner.remove_cleanup_path(package, temporary_dir); + inner.remove_cleanup_path(package.clone(), temporary_dir); let realpath = realpath(path); if let Some(realpath) = realpath { inner.remove_cleanup_path(package, &realpath); @@ -253,7 +260,7 @@ fn get_folder_content(dir: &str) -> Vec<SplFileInfo> { /// put the source into the target e.g. src/ => target/src/ (assuming target exists) instead of src/ => target/ fn rename_recursively( filesystem: &std::rc::Rc<std::cell::RefCell<Filesystem>>, - package: &dyn PackageInterface, + package: PackageInterfaceHandle, from: &str, to: &str, ) -> Result<()> { @@ -277,7 +284,7 @@ fn rename_recursively( } rename_recursively( filesystem, - package, + package.clone(), &file, &format!("{}/{}", to, basename(&file)), )?; diff --git a/crates/shirabe/src/downloader/change_report_interface.rs b/crates/shirabe/src/downloader/change_report_interface.rs index f5e686a..5e770f7 100644 --- a/crates/shirabe/src/downloader/change_report_interface.rs +++ b/crates/shirabe/src/downloader/change_report_interface.rs @@ -2,12 +2,12 @@ use anyhow::Result; -use crate::package::PackageInterface; +use crate::package::PackageInterfaceHandle; pub trait ChangeReportInterface { fn get_local_changes( &self, - package: &dyn PackageInterface, + package: PackageInterfaceHandle, path: &str, ) -> Result<Option<String>>; } diff --git a/crates/shirabe/src/downloader/download_manager.rs b/crates/shirabe/src/downloader/download_manager.rs index 83a03c4..33a555a 100644 --- a/crates/shirabe/src/downloader/download_manager.rs +++ b/crates/shirabe/src/downloader/download_manager.rs @@ -14,7 +14,7 @@ use crate::downloader::DownloaderInterface; use crate::exception::IrrecoverableDownloadException; use crate::io::IOInterface; use crate::io::IOInterfaceImmutable; -use crate::package::PackageInterface; +use crate::package::PackageInterfaceHandle; use crate::util::Filesystem; /// Downloaders manager. @@ -130,7 +130,7 @@ impl DownloadManager { /// wrong type pub fn get_downloader_for_package( &self, - package: &dyn PackageInterface, + package: PackageInterfaceHandle, ) -> Result<Option<&dyn DownloaderInterface>> { let installation_source = package.get_installation_source(); @@ -138,10 +138,10 @@ impl DownloadManager { return Ok(None); } - let downloader = if installation_source == Some("dist") { - self.get_downloader(package.get_dist_type().unwrap_or(""))? - } else if installation_source == Some("source") { - self.get_downloader(package.get_source_type().unwrap_or(""))? + let downloader = if installation_source.as_deref() == Some("dist") { + self.get_downloader(&package.get_dist_type().unwrap_or_default())? + } else if installation_source.as_deref() == Some("source") { + self.get_downloader(&package.get_source_type().unwrap_or_default())? } else { return Err(InvalidArgumentException { message: format!( @@ -153,14 +153,14 @@ impl DownloadManager { .into()); }; - if installation_source != Some(&downloader.get_installation_source()) { + if installation_source.as_deref() != Some(&downloader.get_installation_source()) { return Err(LogicException { message: sprintf( "Downloader \"%s\" is a %s type downloader and can not be used to download %s for package %s", &[ PhpMixed::String(shirabe_php_shim::get_class_obj(downloader)), PhpMixed::String(downloader.get_installation_source()), - PhpMixed::String(installation_source.unwrap_or("").to_string()), + PhpMixed::String(installation_source.clone().unwrap_or_default()), PhpMixed::String(package.to_string()), ], ), @@ -197,16 +197,16 @@ impl DownloadManager { /// @throws \RuntimeException pub async fn download( &self, - package: &dyn PackageInterface, + package: PackageInterfaceHandle, target_dir: &str, - prev_package: Option<&dyn PackageInterface>, + prev_package: Option<PackageInterfaceHandle>, ) -> Result<Option<PhpMixed>> { let target_dir = self.normalize_target_dir(target_dir); self.filesystem .borrow_mut() .ensure_directory_exists(&dirname(&target_dir)); - let mut sources = self.get_available_sources(package, prev_package)?; + let mut sources = self.get_available_sources(package.clone(), prev_package.clone())?; // PHP closure: uses recursive variable $download and captures $sources by reference // TODO(phase-b): recursive closure with mutable shared state needs Rc<RefCell<>> or similar @@ -231,7 +231,7 @@ impl DownloadManager { // TODO(phase-b): &mut on shared package — PHP mutates by reference todo!("package.set_installation_source(Some(source.clone()))"); - let downloader = match self.get_downloader_for_package(package)? { + let downloader = match self.get_downloader_for_package(package.clone())? { Some(d) => d, None => { return Ok(None); @@ -240,7 +240,7 @@ impl DownloadManager { // TODO(phase-b): use anyhow::Result<Result<T, E>> to model PHP try/catch let result = match downloader - .download3(package, &target_dir, prev_package) + .download3(package.clone(), &target_dir, prev_package.clone()) .await { Ok(r) => r, @@ -290,12 +290,12 @@ impl DownloadManager { pub async fn prepare( &self, r#type: &str, - package: &dyn PackageInterface, + package: PackageInterfaceHandle, target_dir: &str, - prev_package: Option<&dyn PackageInterface>, + prev_package: Option<PackageInterfaceHandle>, ) -> Result<Option<PhpMixed>> { let target_dir = self.normalize_target_dir(target_dir); - if let Some(downloader) = self.get_downloader_for_package(package)? { + if let Some(downloader) = self.get_downloader_for_package(package.clone())? { return downloader .prepare(r#type, package, &target_dir, prev_package) .await; @@ -314,11 +314,11 @@ impl DownloadManager { /// @throws \RuntimeException pub async fn install( &self, - package: &dyn PackageInterface, + package: PackageInterfaceHandle, target_dir: &str, ) -> Result<Option<PhpMixed>> { let target_dir = self.normalize_target_dir(target_dir); - if let Some(downloader) = self.get_downloader_for_package(package)? { + if let Some(downloader) = self.get_downloader_for_package(package.clone())? { return downloader.install2(package, &target_dir).await; } @@ -335,13 +335,13 @@ impl DownloadManager { /// @throws \InvalidArgumentException if initial package is not installed pub async fn update( &self, - initial: &dyn PackageInterface, - target: &dyn PackageInterface, + initial: PackageInterfaceHandle, + target: PackageInterfaceHandle, target_dir: &str, ) -> Result<Option<PhpMixed>> { let target_dir = self.normalize_target_dir(target_dir); - let downloader = self.get_downloader_for_package(target)?; - let initial_downloader = self.get_downloader_for_package(initial)?; + let downloader = self.get_downloader_for_package(target.clone())?; + let initial_downloader = self.get_downloader_for_package(initial.clone())?; // no downloaders present means update from metapackage to metapackage, nothing to do if initial_downloader.is_none() && downloader.is_none() { @@ -362,7 +362,7 @@ impl DownloadManager { // TODO(phase-b): use anyhow::Result<Result<T, E>> to model PHP try/catch match downloader .unwrap() - .update(initial, target, &target_dir) + .update(initial.clone(), target.clone(), &target_dir) .await { Ok(p) => return Ok(p), @@ -404,11 +404,11 @@ impl DownloadManager { /// @phpstan-return PromiseInterface<void|null> pub async fn remove( &self, - package: &dyn PackageInterface, + package: PackageInterfaceHandle, target_dir: &str, ) -> Result<Option<PhpMixed>> { let target_dir = self.normalize_target_dir(target_dir); - if let Some(downloader) = self.get_downloader_for_package(package)? { + if let Some(downloader) = self.get_downloader_for_package(package.clone())? { return downloader.remove2(package, &target_dir).await; } @@ -425,12 +425,12 @@ impl DownloadManager { pub async fn cleanup( &self, r#type: &str, - package: &dyn PackageInterface, + package: PackageInterfaceHandle, target_dir: &str, - prev_package: Option<&dyn PackageInterface>, + prev_package: Option<PackageInterfaceHandle>, ) -> Result<Option<PhpMixed>> { let target_dir = self.normalize_target_dir(target_dir); - if let Some(downloader) = self.get_downloader_for_package(package)? { + if let Some(downloader) = self.get_downloader_for_package(package.clone())? { return downloader .cleanup(r#type, package, &target_dir, prev_package) .await; @@ -444,14 +444,14 @@ impl DownloadManager { /// @param PackageInterface $package package instance pub(crate) fn resolve_package_install_preference( &self, - package: &dyn PackageInterface, + package: PackageInterfaceHandle, ) -> String { for (pattern, preference) in &self.package_preferences { let pattern_regex = format!( "{{^{}$}}i", str_replace("\\*", ".*", &preg_quote(pattern, None)), ); - if Preg::is_match(&pattern_regex, package.get_name()).unwrap_or(false) { + if Preg::is_match(&pattern_regex, &package.get_name()).unwrap_or(false) { if "dist" == preference || (!package.is_dev() && "auto" == preference) { return "dist".to_string(); } @@ -471,8 +471,8 @@ impl DownloadManager { /// @phpstan-return array<'dist'|'source'>&non-empty-array fn get_available_sources( &self, - package: &dyn PackageInterface, - prev_package: Option<&dyn PackageInterface>, + package: PackageInterfaceHandle, + prev_package: Option<PackageInterfaceHandle>, ) -> Result<Vec<String>> { let source_type = package.get_source_type(); let dist_type = package.get_dist_type(); @@ -498,7 +498,7 @@ impl DownloadManager { // if we are updating, we want to keep the same source as the previously installed package (if available in the new one) let prev_source = prev.get_installation_source(); if in_array( - PhpMixed::String(prev_source.unwrap_or("").to_string()), + PhpMixed::String(prev_source.clone().unwrap_or_default()), &PhpMixed::List( sources .iter() @@ -509,10 +509,10 @@ impl DownloadManager { ) // unless the previous package was stable dist (by default) and the new package is dev, then we allow the new default to take over && !(!prev.is_dev() - && prev.get_installation_source() == Some("dist") + && prev.get_installation_source().as_deref() == Some("dist") && package.is_dev()) { - let prev_source_owned = prev_source.unwrap_or("").to_string(); + let prev_source_owned = prev_source.unwrap_or_default(); usort(&mut sources, move |a: &String, b: &String| -> i64 { if *a == prev_source_owned { -1 } else { 1 } }); @@ -523,7 +523,8 @@ impl DownloadManager { // reverse sources in case dist is the preferred source for this package if !self.prefer_source - && (self.prefer_dist || "dist" == self.resolve_package_install_preference(package)) + && (self.prefer_dist + || "dist" == self.resolve_package_install_preference(package.clone())) { sources = array_reverse(&sources, false); } diff --git a/crates/shirabe/src/downloader/downloader_interface.rs b/crates/shirabe/src/downloader/downloader_interface.rs index 18026a4..986db28 100644 --- a/crates/shirabe/src/downloader/downloader_interface.rs +++ b/crates/shirabe/src/downloader/downloader_interface.rs @@ -1,6 +1,6 @@ //! ref: composer/src/Composer/Downloader/DownloaderInterface.php -use crate::package::PackageInterface; +use crate::package::PackageInterfaceHandle; use shirabe_php_shim::PhpMixed; #[async_trait::async_trait(?Send)] @@ -9,18 +9,18 @@ pub trait DownloaderInterface: std::fmt::Debug { async fn download( &self, - package: &dyn PackageInterface, + package: PackageInterfaceHandle, path: &str, - prev_package: Option<&dyn PackageInterface>, + prev_package: Option<PackageInterfaceHandle>, output: bool, ) -> anyhow::Result<Option<PhpMixed>>; /// Convenience for the PHP default `$output = true` overload. async fn download3( &self, - package: &dyn PackageInterface, + package: PackageInterfaceHandle, path: &str, - prev_package: Option<&dyn PackageInterface>, + prev_package: Option<PackageInterfaceHandle>, ) -> anyhow::Result<Option<PhpMixed>> { self.download(package, path, prev_package, true).await } @@ -28,14 +28,14 @@ pub trait DownloaderInterface: std::fmt::Debug { async fn prepare( &self, r#type: &str, - package: &dyn PackageInterface, + package: PackageInterfaceHandle, path: &str, - prev_package: Option<&dyn PackageInterface>, + prev_package: Option<PackageInterfaceHandle>, ) -> anyhow::Result<Option<PhpMixed>>; async fn install( &self, - package: &dyn PackageInterface, + package: PackageInterfaceHandle, path: &str, output: bool, ) -> anyhow::Result<Option<PhpMixed>>; @@ -43,7 +43,7 @@ pub trait DownloaderInterface: std::fmt::Debug { /// Convenience for the PHP default `$output = true` overload. async fn install2( &self, - package: &dyn PackageInterface, + package: PackageInterfaceHandle, path: &str, ) -> anyhow::Result<Option<PhpMixed>> { self.install(package, path, true).await @@ -51,14 +51,14 @@ pub trait DownloaderInterface: std::fmt::Debug { async fn update( &self, - initial: &dyn PackageInterface, - target: &dyn PackageInterface, + initial: PackageInterfaceHandle, + target: PackageInterfaceHandle, path: &str, ) -> anyhow::Result<Option<PhpMixed>>; async fn remove( &self, - package: &dyn PackageInterface, + package: PackageInterfaceHandle, path: &str, output: bool, ) -> anyhow::Result<Option<PhpMixed>>; @@ -66,7 +66,7 @@ pub trait DownloaderInterface: std::fmt::Debug { /// Convenience for the PHP default `$output = true` overload. async fn remove2( &self, - package: &dyn PackageInterface, + package: PackageInterfaceHandle, path: &str, ) -> anyhow::Result<Option<PhpMixed>> { self.remove(package, path, true).await @@ -75,9 +75,9 @@ pub trait DownloaderInterface: std::fmt::Debug { async fn cleanup( &self, r#type: &str, - package: &dyn PackageInterface, + package: PackageInterfaceHandle, path: &str, - prev_package: Option<&dyn PackageInterface>, + prev_package: Option<PackageInterfaceHandle>, ) -> anyhow::Result<Option<PhpMixed>>; /// TODO(phase-b): runtime downcast helpers for PHP `instanceof` checks. diff --git a/crates/shirabe/src/downloader/dvcs_downloader_interface.rs b/crates/shirabe/src/downloader/dvcs_downloader_interface.rs index 94c3e4f..4c8ebd3 100644 --- a/crates/shirabe/src/downloader/dvcs_downloader_interface.rs +++ b/crates/shirabe/src/downloader/dvcs_downloader_interface.rs @@ -1,7 +1,8 @@ //! ref: composer/src/Composer/Downloader/DvcsDownloaderInterface.php -use crate::package::PackageInterface; +use crate::package::PackageInterfaceHandle; pub trait DvcsDownloaderInterface { - fn get_unpushed_changes(&self, package: &dyn PackageInterface, path: String) -> Option<String>; + fn get_unpushed_changes(&self, package: PackageInterfaceHandle, path: String) + -> Option<String>; } diff --git a/crates/shirabe/src/downloader/file_downloader.rs b/crates/shirabe/src/downloader/file_downloader.rs index 4f2ee63..dadf8fb 100644 --- a/crates/shirabe/src/downloader/file_downloader.rs +++ b/crates/shirabe/src/downloader/file_downloader.rs @@ -28,7 +28,7 @@ use crate::io::IOInterface; use crate::io::IOInterfaceImmutable; use crate::io::IOInterfaceMutable; use crate::io::NullIO; -use crate::package::PackageInterface; +use crate::package::PackageInterfaceHandle; use crate::package::comparer::Comparer; use crate::plugin::PluginEvents; use crate::plugin::PostFileDownloadEvent; @@ -156,9 +156,9 @@ impl DownloaderInterface for FileDownloader { /// @inheritDoc async fn download( &self, - package: &dyn PackageInterface, + package: PackageInterfaceHandle, path: &str, - _prev_package: Option<&dyn PackageInterface>, + _prev_package: Option<PackageInterfaceHandle>, output: bool, ) -> Result<Option<PhpMixed>> { if package.get_dist_url().is_none() { @@ -169,14 +169,14 @@ impl DownloaderInterface for FileDownloader { .into()); } - let cache_key_generator = |package: &dyn PackageInterface, key: &str| -> String { + let cache_key_generator = |package: PackageInterfaceHandle, key: &str| -> String { let cache_key = hash("sha1", key); format!( "{}/{}.{}", package.get_name(), cache_key, - package.get_dist_type().unwrap_or("") + package.get_dist_type().unwrap_or_default() ) }; @@ -185,8 +185,8 @@ impl DownloaderInterface for FileDownloader { // @var array<array{base: non-empty-string, processed: non-empty-string, cacheKey: string}> $urls let mut urls: Vec<UrlEntry> = vec![]; for url in dist_urls { - let processed_url = self.process_url(package, &url)?; - let cache_key = cache_key_generator(package, &processed_url); + let processed_url = self.process_url(package.clone(), &url)?; + let cache_key = cache_key_generator(package.clone(), &processed_url); urls.push(UrlEntry { base: url, processed: processed_url, @@ -199,7 +199,7 @@ impl DownloaderInterface for FileDownloader { } debug_assert!(urls.len() > 0); - let file_name = self.get_file_name(package, path); + let file_name = self.get_file_name(package.clone(), path); self.filesystem.borrow_mut().ensure_directory_exists(path)?; let dir_of_file = shirabe_php_shim::dirname(&file_name); self.filesystem @@ -312,7 +312,7 @@ impl DownloaderInterface for FileDownloader { if file_exists(&file_name) { self.filesystem.borrow().unlink(&file_name)?; } - self.clear_last_cache_write(package); + self.clear_last_cache_write(package.clone()); if e.downcast_ref::<IrrecoverableDownloadException>().is_some() { return Err(e); @@ -429,9 +429,9 @@ impl DownloaderInterface for FileDownloader { async fn prepare( &self, _type: &str, - _package: &dyn PackageInterface, + _package: PackageInterfaceHandle, _path: &str, - _prev_package: Option<&dyn PackageInterface>, + _prev_package: Option<PackageInterfaceHandle>, ) -> Result<Option<PhpMixed>> { Ok(Some(PhpMixed::Null)) } @@ -440,11 +440,11 @@ impl DownloaderInterface for FileDownloader { async fn cleanup( &self, _type: &str, - package: &dyn PackageInterface, + package: PackageInterfaceHandle, path: &str, - _prev_package: Option<&dyn PackageInterface>, + _prev_package: Option<PackageInterfaceHandle>, ) -> Result<Option<PhpMixed>> { - let file_name = self.get_file_name(package, path); + let file_name = self.get_file_name(package.clone(), path); if file_exists(&file_name) { self.filesystem.borrow_mut().unlink(&file_name)?; } @@ -471,7 +471,7 @@ impl DownloaderInterface for FileDownloader { if let Some(paths) = self .additional_cleanup_paths - .get(package.get_name()) + .get(&package.get_name()) .cloned() { for path_to_clean in &paths { @@ -494,13 +494,15 @@ impl DownloaderInterface for FileDownloader { /// @inheritDoc async fn install( &self, - package: &dyn PackageInterface, + package: PackageInterfaceHandle, path: &str, output: bool, ) -> Result<Option<PhpMixed>> { if output { - self.io - .write_error(&format!(" - {}", InstallOperation::format(package, false))); + self.io.write_error(&format!( + " - {}", + InstallOperation::format(package.clone(), false) + )); } let vendor_dir = self @@ -526,11 +528,11 @@ impl DownloaderInterface for FileDownloader { } self.filesystem.borrow_mut().ensure_directory_exists(path)?; self.filesystem.borrow_mut().rename( - &self.get_file_name(package, path), + &self.get_file_name(package.clone(), path), &format!( "{}/{}", path, - self.get_dist_path(package, PATHINFO_BASENAME) + self.get_dist_path(package.clone(), PATHINFO_BASENAME) ), )?; @@ -554,14 +556,14 @@ impl DownloaderInterface for FileDownloader { /// @inheritDoc async fn update( &self, - initial: &dyn PackageInterface, - target: &dyn PackageInterface, + initial: PackageInterfaceHandle, + target: PackageInterfaceHandle, path: &str, ) -> Result<Option<PhpMixed>> { self.io.write_error(&format!( " - {}{}", - UpdateOperation::format(initial, target, false), - self.get_install_operation_appendix(target, path) + UpdateOperation::format(initial.clone(), target.clone(), false), + self.get_install_operation_appendix(target.clone(), path) )); // PHP: return $this->remove($initial, $path, false)->then(fn () => $this->install($target, $path, false)); @@ -572,7 +574,7 @@ impl DownloaderInterface for FileDownloader { /// @inheritDoc async fn remove( &self, - package: &dyn PackageInterface, + package: PackageInterfaceHandle, path: &str, output: bool, ) -> Result<Option<PhpMixed>> { @@ -604,7 +606,7 @@ impl ChangeReportInterface for FileDownloader { /// @throws \RuntimeException fn get_local_changes( &self, - package: &dyn PackageInterface, + package: PackageInterfaceHandle, path: &str, ) -> Result<Option<String>> { // TODO(phase-b): swap self.io to NullIO and restore — needs a take/swap helper @@ -626,14 +628,18 @@ impl ChangeReportInterface for FileDownloader { tokio::runtime::Runtime::new() .unwrap() .block_on(self.download( - package, + package.clone(), &format!("{}_compare", target_dir), None, false, ))?; tokio::runtime::Runtime::new() .unwrap() - .block_on(self.install(package, &format!("{}_compare", target_dir), false))?; + .block_on(self.install( + package.clone(), + &format!("{}_compare", target_dir), + false, + ))?; let mut comparer = Comparer::new(); comparer.set_source(format!("{}_compare", target_dir)); @@ -677,11 +683,11 @@ impl ChangeReportInterface for FileDownloader { impl FileDownloader { /// @param PATHINFO_EXTENSION|PATHINFO_BASENAME $component - fn get_dist_path(&self, package: &dyn PackageInterface, component: i64) -> String { + fn get_dist_path(&self, package: PackageInterfaceHandle, component: i64) -> String { pathinfo( PhpMixed::String( parse_url( - &strtr(package.get_dist_url().unwrap_or(""), "\\", "/"), + &strtr(&package.get_dist_url().unwrap_or_default(), "\\", "/"), PHP_URL_PATH, ) .as_string() @@ -695,24 +701,24 @@ impl FileDownloader { .to_string() } - pub(crate) fn clear_last_cache_write(&self, package: &dyn PackageInterface) { + pub(crate) fn clear_last_cache_write(&self, package: PackageInterfaceHandle) { let mut last_cache_writes = self.last_cache_writes.lock().unwrap(); - if self.cache.is_some() && last_cache_writes.contains_key(package.get_name()) { - let key = last_cache_writes.get(package.get_name()).unwrap().clone(); + if self.cache.is_some() && last_cache_writes.contains_key(&package.get_name()) { + let key = last_cache_writes.get(&package.get_name()).unwrap().clone(); self.cache.as_ref().unwrap().borrow_mut().remove(&key); - last_cache_writes.shift_remove(package.get_name()); + last_cache_writes.shift_remove(&package.get_name()); } } - pub(crate) fn add_cleanup_path(&mut self, package: &dyn PackageInterface, path: &str) { + pub(crate) fn add_cleanup_path(&mut self, package: PackageInterfaceHandle, path: &str) { self.additional_cleanup_paths - .entry(package.get_name().to_string()) + .entry(package.get_name()) .or_insert_with(Vec::new) .push(path.to_string()); } - pub(crate) fn remove_cleanup_path(&mut self, package: &dyn PackageInterface, path: &str) { - if let Some(paths) = self.additional_cleanup_paths.get_mut(package.get_name()) { + pub(crate) fn remove_cleanup_path(&mut self, package: PackageInterfaceHandle, path: &str) { + if let Some(paths) = self.additional_cleanup_paths.get_mut(&package.get_name()) { // PHP: array_search($path, ..., true) let idx = paths.iter().position(|p| p == path); if let Some(i) = idx { @@ -723,10 +729,10 @@ impl FileDownloader { } /// Gets file name for specific package - pub(crate) fn get_file_name(&self, package: &dyn PackageInterface, _path: &str) -> String { - let extension = self.get_dist_path(package, PATHINFO_EXTENSION); + pub(crate) fn get_file_name(&self, package: PackageInterfaceHandle, _path: &str) -> String { + let extension = self.get_dist_path(package.clone(), PATHINFO_EXTENSION); let extension = if extension.is_empty() { - package.get_dist_type().unwrap_or("").to_string() + package.get_dist_type().unwrap_or_default() } else { extension }; @@ -752,14 +758,14 @@ impl FileDownloader { /// Gets appendix message to add to the "- Upgrading x" string being output on update fn get_install_operation_appendix( &self, - _package: &dyn PackageInterface, + _package: PackageInterfaceHandle, _path: &str, ) -> String { String::new() } /// Process the download url - pub(crate) fn process_url(&self, package: &dyn PackageInterface, url: &str) -> Result<String> { + pub(crate) fn process_url(&self, package: PackageInterfaceHandle, url: &str) -> Result<String> { if !shirabe_php_shim::extension_loaded("openssl") && Some(0) == strpos(url, "https:") { return Err(RuntimeException { message: "You must enable the openssl extension to download files via https" @@ -774,7 +780,7 @@ impl FileDownloader { url = UrlUtil::update_dist_reference( &*self.config.borrow(), url, - package.get_dist_reference().unwrap(), + &package.get_dist_reference().unwrap(), ); } diff --git a/crates/shirabe/src/downloader/fossil_downloader.rs b/crates/shirabe/src/downloader/fossil_downloader.rs index 9f0277e..fae3bd4 100644 --- a/crates/shirabe/src/downloader/fossil_downloader.rs +++ b/crates/shirabe/src/downloader/fossil_downloader.rs @@ -5,7 +5,7 @@ use crate::downloader::DownloaderInterface; use crate::downloader::VcsDownloaderBase; use crate::io::IOInterface; use crate::io::IOInterfaceImmutable; -use crate::package::PackageInterface; +use crate::package::PackageInterfaceHandle; use crate::util::Filesystem; use crate::util::ProcessExecutor; use anyhow::Result; @@ -31,17 +31,17 @@ impl FossilDownloader { pub(crate) async fn do_download( &self, - _package: &dyn PackageInterface, + _package: PackageInterfaceHandle, _path: String, _url: String, - _prev_package: Option<&dyn PackageInterface>, + _prev_package: Option<PackageInterfaceHandle>, ) -> Result<Option<PhpMixed>> { Ok(None) } pub(crate) async fn do_install( &self, - package: &dyn PackageInterface, + package: PackageInterfaceHandle, path: String, url: String, ) -> Result<Option<PhpMixed>> { @@ -101,8 +101,8 @@ impl FossilDownloader { pub(crate) async fn do_update( &self, - _initial: &dyn PackageInterface, - target: &dyn PackageInterface, + _initial: PackageInterfaceHandle, + target: PackageInterfaceHandle, path: String, url: String, ) -> Result<Option<PhpMixed>> { @@ -153,7 +153,7 @@ impl FossilDownloader { pub fn get_local_changes( &self, - _package: &dyn PackageInterface, + _package: PackageInterfaceHandle, path: String, ) -> Option<String> { if !self.has_metadata_repository(&path) { @@ -259,9 +259,9 @@ impl DownloaderInterface for FossilDownloader { async fn download( &self, - _package: &dyn PackageInterface, + _package: PackageInterfaceHandle, _path: &str, - _prev_package: Option<&dyn PackageInterface>, + _prev_package: Option<PackageInterfaceHandle>, _output: bool, ) -> Result<Option<PhpMixed>> { todo!() @@ -270,16 +270,16 @@ impl DownloaderInterface for FossilDownloader { async fn prepare( &self, _type: &str, - _package: &dyn PackageInterface, + _package: PackageInterfaceHandle, _path: &str, - _prev_package: Option<&dyn PackageInterface>, + _prev_package: Option<PackageInterfaceHandle>, ) -> Result<Option<PhpMixed>> { todo!() } async fn install( &self, - _package: &dyn PackageInterface, + _package: PackageInterfaceHandle, _path: &str, _output: bool, ) -> Result<Option<PhpMixed>> { @@ -288,8 +288,8 @@ impl DownloaderInterface for FossilDownloader { async fn update( &self, - _initial: &dyn PackageInterface, - _target: &dyn PackageInterface, + _initial: PackageInterfaceHandle, + _target: PackageInterfaceHandle, _path: &str, ) -> Result<Option<PhpMixed>> { todo!() @@ -297,7 +297,7 @@ impl DownloaderInterface for FossilDownloader { async fn remove( &self, - _package: &dyn PackageInterface, + _package: PackageInterfaceHandle, _path: &str, _output: bool, ) -> Result<Option<PhpMixed>> { @@ -307,9 +307,9 @@ impl DownloaderInterface for FossilDownloader { async fn cleanup( &self, _type: &str, - _package: &dyn PackageInterface, + _package: PackageInterfaceHandle, _path: &str, - _prev_package: Option<&dyn PackageInterface>, + _prev_package: Option<PackageInterfaceHandle>, ) -> Result<Option<PhpMixed>> { todo!() } diff --git a/crates/shirabe/src/downloader/git_downloader.rs b/crates/shirabe/src/downloader/git_downloader.rs index b3e00a2..ed6f913 100644 --- a/crates/shirabe/src/downloader/git_downloader.rs +++ b/crates/shirabe/src/downloader/git_downloader.rs @@ -16,6 +16,7 @@ use crate::downloader::VcsDownloaderBase; use crate::io::IOInterface; use crate::io::IOInterfaceImmutable; use crate::package::PackageInterface; +use crate::package::PackageInterfaceHandle; use crate::util::Filesystem; use crate::util::Git as GitUtil; use crate::util::Platform; @@ -59,10 +60,10 @@ impl GitDownloader { pub(crate) async fn do_download( &mut self, - package: &dyn PackageInterface, + package: PackageInterfaceHandle, _path: &str, url: &str, - _prev_package: Option<&dyn PackageInterface>, + _prev_package: Option<PackageInterfaceHandle>, ) -> Result<Option<PhpMixed>> { // Do not create an extra local cache when repository is already local if Filesystem::is_local_path(url) { @@ -109,17 +110,18 @@ impl GitDownloader { io_interface::DEBUG, ); let r#ref = package.get_source_reference(); + let pretty_version = package.get_pretty_version(); if self.git_util.fetch_ref_or_sync_mirror( url, &cache_path, - r#ref.unwrap_or(""), - Some(package.get_pretty_version()), + r#ref.as_deref().unwrap_or(""), + Some(&pretty_version), )? && is_dir(&cache_path) { self.cached_packages .entry(package.get_id()) .or_insert_with(IndexMap::new) - .insert(r#ref.unwrap_or("").to_string(), true); + .insert(r#ref.as_deref().unwrap_or("").to_string(), true); } } else if git_version.is_none() { return Err(RuntimeException { @@ -134,7 +136,7 @@ impl GitDownloader { pub(crate) async fn do_install( &mut self, - package: &dyn PackageInterface, + package: PackageInterfaceHandle, path: &str, url: &str, ) -> Result<Option<PhpMixed>> { @@ -150,7 +152,7 @@ impl GitDownloader { .unwrap_or(""), Preg::replace(r"{[^a-z0-9.]}i", "-", &Url::sanitize(url.to_string()))?, ); - let r#ref = package.get_source_reference().unwrap_or("").to_string(); + let r#ref = package.get_source_reference().unwrap_or_default(); let msg; let commands: Vec<Vec<String>>; @@ -265,14 +267,15 @@ impl GitDownloader { .run_commands(commands, url, Some(&path), true, None)?; let source_url = package.get_source_url(); - if url != source_url.unwrap_or("") && source_url.is_some() { - self.update_origin_url(&path, source_url.unwrap()); + if Some(url) != source_url.as_deref() && source_url.is_some() { + self.update_origin_url(&path, source_url.as_deref().unwrap()); } else { self.set_push_url(&path, url); } + let pretty_version = package.get_pretty_version(); if let Some(new_ref) = - self.update_to_commit(package, &path, &r#ref, package.get_pretty_version())? + self.update_to_commit(package.clone(), &path, &r#ref, &pretty_version)? { if package.get_dist_reference() == package.get_source_reference() { // TODO(phase-b): set_dist_reference requires &mut PackageInterface @@ -287,8 +290,8 @@ impl GitDownloader { pub(crate) async fn do_update( &mut self, - _initial: &dyn PackageInterface, - target: &dyn PackageInterface, + _initial: PackageInterfaceHandle, + target: PackageInterfaceHandle, path: &str, url: &str, ) -> Result<Option<PhpMixed>> { @@ -315,7 +318,7 @@ impl GitDownloader { .unwrap_or(""), Preg::replace(r"{[^a-z0-9.]}i", "-", &Url::sanitize(url.to_string()))?, ); - let r#ref = target.get_source_reference().unwrap_or("").to_string(); + let r#ref = target.get_source_reference().unwrap_or_default(); let msg; let remote_url; @@ -395,8 +398,9 @@ impl GitDownloader { self.git_util .run_commands(vec![command], url, Some(&path), false, None)?; + let pretty_version = target.get_pretty_version(); if let Some(new_ref) = - self.update_to_commit(target, &path, &r#ref, target.get_pretty_version())? + self.update_to_commit(target.clone(), &path, &r#ref, &pretty_version)? { if target.get_dist_reference() == target.get_source_reference() { // TODO(phase-b): set_dist_reference requires &mut PackageInterface @@ -438,20 +442,24 @@ impl GitDownloader { .cloned() .unwrap_or_default(); if origin_url == composer_url - && Some(composer_url.as_str()) != target.get_source_url() + && Some(composer_url.as_str()) != target.get_source_url().as_deref() { update_origin_url = true; } } } if update_origin_url && target.get_source_url().is_some() { - self.update_origin_url(&path, target.get_source_url().unwrap()); + self.update_origin_url(&path, &target.get_source_url().unwrap()); } Ok(None) } - pub fn get_local_changes(&self, _package: &dyn PackageInterface, path: &str) -> Option<String> { + pub fn get_local_changes( + &self, + _package: PackageInterfaceHandle, + path: &str, + ) -> Option<String> { GitUtil::clean_env(&self.inner.process); if !self.has_metadata_repository(path) { return None; @@ -492,7 +500,7 @@ impl GitDownloader { pub fn get_unpushed_changes( &self, - _package: &dyn PackageInterface, + _package: PackageInterfaceHandle, path: &str, ) -> Option<String> { GitUtil::clean_env(&self.inner.process); @@ -686,14 +694,14 @@ impl GitDownloader { pub(crate) async fn clean_changes( &mut self, - package: &dyn PackageInterface, + package: PackageInterfaceHandle, path: &str, update: bool, ) -> Result<Option<PhpMixed>> { GitUtil::clean_env(&self.inner.process); let path = self.normalize_path(path); - let unpushed = self.get_unpushed_changes(package, &path); + let unpushed = self.get_unpushed_changes(package.clone(), &path); if let Some(unpushed) = unpushed.as_deref() { if self.inner.io.is_interactive() || self @@ -715,7 +723,7 @@ impl GitDownloader { } } - let changes = match self.get_local_changes(package, &path) { + let changes = match self.get_local_changes(package.clone(), &path) { Some(c) => c, None => return Ok(None), }; @@ -727,7 +735,10 @@ impl GitDownloader { } if discard_changes.as_string() == Some("stash") { if !update { - return self.inner.clean_changes(package, &path, update).await; + return self + .inner + .clean_changes(package.clone(), &path, update) + .await; } return self.stash_changes(&path).await; @@ -892,7 +903,7 @@ impl GitDownloader { /// @return null|string if a string is returned, it is the commit reference that was checked out if the original could not be found pub(crate) fn update_to_commit( &mut self, - package: &dyn PackageInterface, + package: PackageInterfaceHandle, path: &str, reference: &str, pretty_version: &str, @@ -1351,7 +1362,11 @@ impl GitDownloader { } impl DvcsDownloaderInterface for GitDownloader { - fn get_unpushed_changes(&self, package: &dyn PackageInterface, path: String) -> Option<String> { + fn get_unpushed_changes( + &self, + package: PackageInterfaceHandle, + path: String, + ) -> Option<String> { GitDownloader::get_unpushed_changes(self, package, &path) } } @@ -1367,9 +1382,9 @@ impl crate::downloader::DownloaderInterface for GitDownloader { async fn download( &self, - _package: &dyn PackageInterface, + _package: PackageInterfaceHandle, _path: &str, - _prev_package: Option<&dyn PackageInterface>, + _prev_package: Option<PackageInterfaceHandle>, _output: bool, ) -> anyhow::Result<Option<PhpMixed>> { todo!() @@ -1378,16 +1393,16 @@ impl crate::downloader::DownloaderInterface for GitDownloader { async fn prepare( &self, _type: &str, - _package: &dyn PackageInterface, + _package: PackageInterfaceHandle, _path: &str, - _prev_package: Option<&dyn PackageInterface>, + _prev_package: Option<PackageInterfaceHandle>, ) -> anyhow::Result<Option<PhpMixed>> { todo!() } async fn install( &self, - _package: &dyn PackageInterface, + _package: PackageInterfaceHandle, _path: &str, _output: bool, ) -> anyhow::Result<Option<PhpMixed>> { @@ -1396,8 +1411,8 @@ impl crate::downloader::DownloaderInterface for GitDownloader { async fn update( &self, - _initial: &dyn PackageInterface, - _target: &dyn PackageInterface, + _initial: PackageInterfaceHandle, + _target: PackageInterfaceHandle, _path: &str, ) -> anyhow::Result<Option<PhpMixed>> { todo!() @@ -1405,7 +1420,7 @@ impl crate::downloader::DownloaderInterface for GitDownloader { async fn remove( &self, - _package: &dyn PackageInterface, + _package: PackageInterfaceHandle, _path: &str, _output: bool, ) -> anyhow::Result<Option<PhpMixed>> { @@ -1415,9 +1430,9 @@ impl crate::downloader::DownloaderInterface for GitDownloader { async fn cleanup( &self, _type: &str, - _package: &dyn PackageInterface, + _package: PackageInterfaceHandle, _path: &str, - _prev_package: Option<&dyn PackageInterface>, + _prev_package: Option<PackageInterfaceHandle>, ) -> anyhow::Result<Option<PhpMixed>> { todo!() } diff --git a/crates/shirabe/src/downloader/gzip_downloader.rs b/crates/shirabe/src/downloader/gzip_downloader.rs index 55dff10..00adca9 100644 --- a/crates/shirabe/src/downloader/gzip_downloader.rs +++ b/crates/shirabe/src/downloader/gzip_downloader.rs @@ -6,7 +6,7 @@ use crate::downloader::ArchiveDownloader; use crate::downloader::FileDownloader; use crate::event_dispatcher::EventDispatcher; use crate::io::IOInterface; -use crate::package::PackageInterface; +use crate::package::PackageInterfaceHandle; use crate::util::Filesystem; use crate::util::HttpDownloader; use crate::util::Platform; @@ -51,7 +51,7 @@ impl GzipDownloader { pub(crate) async fn extract( &mut self, - package: &dyn PackageInterface, + package: PackageInterfaceHandle, file: &str, path: &str, ) -> Result<Option<PhpMixed>> { @@ -137,9 +137,9 @@ impl crate::downloader::DownloaderInterface for GzipDownloader { async fn download( &self, - package: &dyn PackageInterface, + package: PackageInterfaceHandle, path: &str, - prev_package: Option<&dyn PackageInterface>, + prev_package: Option<PackageInterfaceHandle>, output: bool, ) -> Result<Option<PhpMixed>> { self.inner @@ -150,9 +150,9 @@ impl crate::downloader::DownloaderInterface for GzipDownloader { async fn prepare( &self, r#type: &str, - package: &dyn PackageInterface, + package: PackageInterfaceHandle, path: &str, - prev_package: Option<&dyn PackageInterface>, + prev_package: Option<PackageInterfaceHandle>, ) -> Result<Option<PhpMixed>> { self.inner .prepare(r#type, package, path, prev_package) @@ -161,7 +161,7 @@ impl crate::downloader::DownloaderInterface for GzipDownloader { async fn install( &self, - package: &dyn PackageInterface, + package: PackageInterfaceHandle, path: &str, output: bool, ) -> Result<Option<PhpMixed>> { @@ -170,8 +170,8 @@ impl crate::downloader::DownloaderInterface for GzipDownloader { async fn update( &self, - initial: &dyn PackageInterface, - target: &dyn PackageInterface, + initial: PackageInterfaceHandle, + target: PackageInterfaceHandle, path: &str, ) -> Result<Option<PhpMixed>> { self.inner.update(initial, target, path).await @@ -179,7 +179,7 @@ impl crate::downloader::DownloaderInterface for GzipDownloader { async fn remove( &self, - package: &dyn PackageInterface, + package: PackageInterfaceHandle, path: &str, output: bool, ) -> Result<Option<PhpMixed>> { @@ -189,9 +189,9 @@ impl crate::downloader::DownloaderInterface for GzipDownloader { async fn cleanup( &self, r#type: &str, - package: &dyn PackageInterface, + package: PackageInterfaceHandle, path: &str, - prev_package: Option<&dyn PackageInterface>, + prev_package: Option<PackageInterfaceHandle>, ) -> Result<Option<PhpMixed>> { self.inner .cleanup(r#type, package, path, prev_package) diff --git a/crates/shirabe/src/downloader/hg_downloader.rs b/crates/shirabe/src/downloader/hg_downloader.rs index d4c53f3..7a48054 100644 --- a/crates/shirabe/src/downloader/hg_downloader.rs +++ b/crates/shirabe/src/downloader/hg_downloader.rs @@ -5,7 +5,7 @@ use crate::downloader::DownloaderInterface; use crate::downloader::VcsDownloaderBase; use crate::io::IOInterface; use crate::io::IOInterfaceImmutable; -use crate::package::PackageInterface; +use crate::package::PackageInterfaceHandle; use crate::util::Filesystem; use crate::util::Hg as HgUtils; use crate::util::ProcessExecutor; @@ -31,10 +31,10 @@ impl HgDownloader { pub(crate) async fn do_download( &self, - package: &dyn PackageInterface, + package: PackageInterfaceHandle, path: String, url: String, - prev_package: Option<&dyn PackageInterface>, + prev_package: Option<PackageInterfaceHandle>, ) -> Result<Option<PhpMixed>> { if HgUtils::get_version(&self.inner.process).is_none() { return Err(RuntimeException { @@ -49,7 +49,7 @@ impl HgDownloader { pub(crate) async fn do_install( &self, - package: &dyn PackageInterface, + package: PackageInterfaceHandle, path: String, url: String, ) -> Result<Option<PhpMixed>> { @@ -103,8 +103,8 @@ impl HgDownloader { pub(crate) async fn do_update( &self, - initial: &dyn PackageInterface, - target: &dyn PackageInterface, + initial: PackageInterfaceHandle, + target: PackageInterfaceHandle, path: String, url: String, ) -> Result<Option<PhpMixed>> { @@ -154,7 +154,7 @@ impl HgDownloader { pub fn get_local_changes( &self, - package: &dyn PackageInterface, + package: PackageInterfaceHandle, path: String, ) -> Option<String> { if !std::path::Path::new(&format!("{}/.hg", path)).is_dir() { @@ -229,9 +229,9 @@ impl DownloaderInterface for HgDownloader { async fn download( &self, - _package: &dyn PackageInterface, + _package: PackageInterfaceHandle, _path: &str, - _prev_package: Option<&dyn PackageInterface>, + _prev_package: Option<PackageInterfaceHandle>, _output: bool, ) -> Result<Option<PhpMixed>> { todo!() @@ -240,16 +240,16 @@ impl DownloaderInterface for HgDownloader { async fn prepare( &self, _type: &str, - _package: &dyn PackageInterface, + _package: PackageInterfaceHandle, _path: &str, - _prev_package: Option<&dyn PackageInterface>, + _prev_package: Option<PackageInterfaceHandle>, ) -> Result<Option<PhpMixed>> { todo!() } async fn install( &self, - _package: &dyn PackageInterface, + _package: PackageInterfaceHandle, _path: &str, _output: bool, ) -> Result<Option<PhpMixed>> { @@ -258,8 +258,8 @@ impl DownloaderInterface for HgDownloader { async fn update( &self, - _initial: &dyn PackageInterface, - _target: &dyn PackageInterface, + _initial: PackageInterfaceHandle, + _target: PackageInterfaceHandle, _path: &str, ) -> Result<Option<PhpMixed>> { todo!() @@ -267,7 +267,7 @@ impl DownloaderInterface for HgDownloader { async fn remove( &self, - _package: &dyn PackageInterface, + _package: PackageInterfaceHandle, _path: &str, _output: bool, ) -> Result<Option<PhpMixed>> { @@ -277,9 +277,9 @@ impl DownloaderInterface for HgDownloader { async fn cleanup( &self, _type: &str, - _package: &dyn PackageInterface, + _package: PackageInterfaceHandle, _path: &str, - _prev_package: Option<&dyn PackageInterface>, + _prev_package: Option<PackageInterfaceHandle>, ) -> Result<Option<PhpMixed>> { todo!() } diff --git a/crates/shirabe/src/downloader/path_downloader.rs b/crates/shirabe/src/downloader/path_downloader.rs index 44541d4..c50856e 100644 --- a/crates/shirabe/src/downloader/path_downloader.rs +++ b/crates/shirabe/src/downloader/path_downloader.rs @@ -20,7 +20,7 @@ use crate::downloader::VcsCapableDownloaderInterface; use crate::event_dispatcher::EventDispatcher; use crate::io::IOInterface; use crate::io::IOInterfaceImmutable; -use crate::package::PackageInterface; +use crate::package::PackageInterfaceHandle; use crate::package::archiver::ArchivableFilesFinder; use crate::package::dumper::ArrayDumper; use crate::package::version::VersionGuesser; @@ -63,9 +63,9 @@ impl PathDownloader { pub async fn download( &mut self, - package: &dyn PackageInterface, + package: PackageInterfaceHandle, path: String, - _prev_package: Option<&dyn PackageInterface>, + _prev_package: Option<PackageInterfaceHandle>, _output: bool, ) -> Result<Option<PhpMixed>> { let path = Filesystem::trim_trailing_slash(&path); @@ -125,7 +125,7 @@ impl PathDownloader { pub async fn install( &mut self, - package: &dyn PackageInterface, + package: PackageInterfaceHandle, path: String, output: bool, ) -> Result<Option<PhpMixed>> { @@ -144,11 +144,11 @@ impl PathDownloader { if realpath(&path).as_deref() == Some(&real_url) { if output { - let appendix = self.get_install_operation_appendix(package, &path)?; + let appendix = self.get_install_operation_appendix(package.clone(), &path)?; self.inner.io.write_error3( &format!( " - {}{}", - InstallOperation::format(package, false), + InstallOperation::format(package.clone(), false), appendix ), true, @@ -296,7 +296,7 @@ impl PathDownloader { pub async fn remove( &mut self, - package: &dyn PackageInterface, + package: PackageInterfaceHandle, path: String, output: bool, ) -> Result<Option<PhpMixed>> { @@ -314,7 +314,7 @@ impl PathDownloader { self.inner.io.write_error3( &format!( " - {}, source is still present in {}", - UninstallOperation::format(package, false), + UninstallOperation::format(package.clone(), false), path ), true, @@ -371,7 +371,7 @@ impl PathDownloader { self.inner.io.write_error3( &format!( " - {}, source is still present in {}", - UninstallOperation::format(package, false), + UninstallOperation::format(package.clone(), false), path ), true, @@ -385,7 +385,7 @@ impl PathDownloader { self.inner.remove(package, &path, output).await } - pub fn get_vcs_reference(&self, package: &dyn PackageInterface, path: &str) -> Option<String> { + pub fn get_vcs_reference(&self, package: PackageInterfaceHandle, path: &str) -> Option<String> { let path = Filesystem::trim_trailing_slash(path); let parser = VersionParser::new(); let mut guesser = VersionGuesser::new( @@ -396,7 +396,7 @@ impl PathDownloader { ); let dumper = ArrayDumper::new(); - let package_config = dumper.dump(package); + let package_config = dumper.dump(package.clone()); let package_version = guesser.guess_version(&package_config, &path); if let Ok(Some(version)) = package_version { return version.commit; @@ -407,7 +407,7 @@ impl PathDownloader { pub(crate) fn get_install_operation_appendix( &self, - package: &dyn PackageInterface, + package: PackageInterfaceHandle, path: &str, ) -> Result<String> { let url = package.get_dist_url().ok_or_else(|| RuntimeException { @@ -529,7 +529,7 @@ impl PathDownloader { } impl VcsCapableDownloaderInterface for PathDownloader { - fn get_vcs_reference(&self, package: &dyn PackageInterface, path: String) -> Option<String> { + fn get_vcs_reference(&self, package: PackageInterfaceHandle, path: String) -> Option<String> { PathDownloader::get_vcs_reference(self, package, &path) } } @@ -546,9 +546,9 @@ impl DownloaderInterface for PathDownloader { async fn download( &self, - package: &dyn PackageInterface, + package: PackageInterfaceHandle, path: &str, - prev_package: Option<&dyn PackageInterface>, + prev_package: Option<PackageInterfaceHandle>, output: bool, ) -> Result<Option<PhpMixed>> { self.inner @@ -559,9 +559,9 @@ impl DownloaderInterface for PathDownloader { async fn prepare( &self, r#type: &str, - package: &dyn PackageInterface, + package: PackageInterfaceHandle, path: &str, - prev_package: Option<&dyn PackageInterface>, + prev_package: Option<PackageInterfaceHandle>, ) -> Result<Option<PhpMixed>> { self.inner .prepare(r#type, package, path, prev_package) @@ -570,7 +570,7 @@ impl DownloaderInterface for PathDownloader { async fn install( &self, - package: &dyn PackageInterface, + package: PackageInterfaceHandle, path: &str, output: bool, ) -> Result<Option<PhpMixed>> { @@ -579,8 +579,8 @@ impl DownloaderInterface for PathDownloader { async fn update( &self, - initial: &dyn PackageInterface, - target: &dyn PackageInterface, + initial: PackageInterfaceHandle, + target: PackageInterfaceHandle, path: &str, ) -> Result<Option<PhpMixed>> { self.inner.update(initial, target, path).await @@ -588,7 +588,7 @@ impl DownloaderInterface for PathDownloader { async fn remove( &self, - package: &dyn PackageInterface, + package: PackageInterfaceHandle, path: &str, output: bool, ) -> Result<Option<PhpMixed>> { @@ -598,9 +598,9 @@ impl DownloaderInterface for PathDownloader { async fn cleanup( &self, r#type: &str, - package: &dyn PackageInterface, + package: PackageInterfaceHandle, path: &str, - prev_package: Option<&dyn PackageInterface>, + prev_package: Option<PackageInterfaceHandle>, ) -> Result<Option<PhpMixed>> { self.inner .cleanup(r#type, package, path, prev_package) diff --git a/crates/shirabe/src/downloader/perforce_downloader.rs b/crates/shirabe/src/downloader/perforce_downloader.rs index f967111..4a54511 100644 --- a/crates/shirabe/src/downloader/perforce_downloader.rs +++ b/crates/shirabe/src/downloader/perforce_downloader.rs @@ -6,6 +6,7 @@ use crate::downloader::VcsDownloaderBase; use crate::io::IOInterface; use crate::io::IOInterfaceImmutable; use crate::package::PackageInterface; +use crate::package::PackageInterfaceHandle; use crate::repository::VcsRepository; use crate::util::Filesystem; use crate::util::Perforce; @@ -36,17 +37,17 @@ impl PerforceDownloader { pub(crate) async fn do_download( &self, - _package: &dyn PackageInterface, + _package: PackageInterfaceHandle, _path: String, _url: String, - _prev_package: Option<&dyn PackageInterface>, + _prev_package: Option<PackageInterfaceHandle>, ) -> Result<Option<PhpMixed>> { Ok(None) } pub async fn do_install( &mut self, - package: &dyn PackageInterface, + package: PackageInterfaceHandle, path: String, url: String, ) -> Result<Option<PhpMixed>> { @@ -83,13 +84,14 @@ impl PerforceDownloader { None } - pub fn init_perforce(&mut self, package: &dyn PackageInterface, path: String, url: String) { + pub fn init_perforce(&mut self, package: PackageInterfaceHandle, path: String, url: String) { if self.perforce.is_some() { self.perforce.as_mut().unwrap().initialize_path(&path); return; } - let repository = package.get_repository(); + let package_rc = package.as_rc().borrow(); + let repository = package_rc.as_package_interface().get_repository(); let repo_config: Option<IndexMap<String, PhpMixed>> = if let Some(repo) = repository { if let Some(vcs_repo) = repo.as_any().downcast_ref::<VcsRepository>() { Some(self.get_repo_config(vcs_repo)) @@ -99,6 +101,7 @@ impl PerforceDownloader { } else { None }; + drop(package_rc); self.perforce = Some(Perforce::create( repo_config.unwrap_or_default(), url, @@ -114,8 +117,8 @@ impl PerforceDownloader { pub(crate) async fn do_update( &mut self, - _initial: &dyn PackageInterface, - target: &dyn PackageInterface, + _initial: PackageInterfaceHandle, + target: PackageInterfaceHandle, path: String, url: String, ) -> Result<Option<PhpMixed>> { @@ -124,7 +127,7 @@ impl PerforceDownloader { pub fn get_local_changes( &self, - _package: &dyn PackageInterface, + _package: PackageInterfaceHandle, _path: String, ) -> Option<String> { self.inner @@ -168,9 +171,9 @@ impl DownloaderInterface for PerforceDownloader { async fn download( &self, - _package: &dyn PackageInterface, + _package: PackageInterfaceHandle, _path: &str, - _prev_package: Option<&dyn PackageInterface>, + _prev_package: Option<PackageInterfaceHandle>, _output: bool, ) -> Result<Option<PhpMixed>> { todo!() @@ -179,16 +182,16 @@ impl DownloaderInterface for PerforceDownloader { async fn prepare( &self, _type: &str, - _package: &dyn PackageInterface, + _package: PackageInterfaceHandle, _path: &str, - _prev_package: Option<&dyn PackageInterface>, + _prev_package: Option<PackageInterfaceHandle>, ) -> Result<Option<PhpMixed>> { todo!() } async fn install( &self, - _package: &dyn PackageInterface, + _package: PackageInterfaceHandle, _path: &str, _output: bool, ) -> Result<Option<PhpMixed>> { @@ -197,8 +200,8 @@ impl DownloaderInterface for PerforceDownloader { async fn update( &self, - _initial: &dyn PackageInterface, - _target: &dyn PackageInterface, + _initial: PackageInterfaceHandle, + _target: PackageInterfaceHandle, _path: &str, ) -> Result<Option<PhpMixed>> { todo!() @@ -206,7 +209,7 @@ impl DownloaderInterface for PerforceDownloader { async fn remove( &self, - _package: &dyn PackageInterface, + _package: PackageInterfaceHandle, _path: &str, _output: bool, ) -> Result<Option<PhpMixed>> { @@ -216,9 +219,9 @@ impl DownloaderInterface for PerforceDownloader { async fn cleanup( &self, _type: &str, - _package: &dyn PackageInterface, + _package: PackageInterfaceHandle, _path: &str, - _prev_package: Option<&dyn PackageInterface>, + _prev_package: Option<PackageInterfaceHandle>, ) -> Result<Option<PhpMixed>> { todo!() } diff --git a/crates/shirabe/src/downloader/phar_downloader.rs b/crates/shirabe/src/downloader/phar_downloader.rs index 235e0bb..6a4ac97 100644 --- a/crates/shirabe/src/downloader/phar_downloader.rs +++ b/crates/shirabe/src/downloader/phar_downloader.rs @@ -7,7 +7,7 @@ use crate::downloader::DownloaderInterface; use crate::downloader::FileDownloader; use crate::event_dispatcher::EventDispatcher; use crate::io::IOInterface; -use crate::package::PackageInterface; +use crate::package::PackageInterfaceHandle; use crate::util::Filesystem; use crate::util::HttpDownloader; use crate::util::ProcessExecutor; @@ -47,7 +47,7 @@ impl PharDownloader { pub(crate) async fn extract( &self, - package: &dyn PackageInterface, + package: PackageInterfaceHandle, file: &str, path: &str, ) -> Result<Option<PhpMixed>> { @@ -71,9 +71,9 @@ impl DownloaderInterface for PharDownloader { async fn download( &self, - package: &dyn PackageInterface, + package: PackageInterfaceHandle, path: &str, - prev_package: Option<&dyn PackageInterface>, + prev_package: Option<PackageInterfaceHandle>, output: bool, ) -> Result<Option<PhpMixed>> { self.inner @@ -84,9 +84,9 @@ impl DownloaderInterface for PharDownloader { async fn prepare( &self, r#type: &str, - package: &dyn PackageInterface, + package: PackageInterfaceHandle, path: &str, - prev_package: Option<&dyn PackageInterface>, + prev_package: Option<PackageInterfaceHandle>, ) -> Result<Option<PhpMixed>> { self.inner .prepare(r#type, package, path, prev_package) @@ -95,7 +95,7 @@ impl DownloaderInterface for PharDownloader { async fn install( &self, - package: &dyn PackageInterface, + package: PackageInterfaceHandle, path: &str, output: bool, ) -> Result<Option<PhpMixed>> { @@ -104,8 +104,8 @@ impl DownloaderInterface for PharDownloader { async fn update( &self, - initial: &dyn PackageInterface, - target: &dyn PackageInterface, + initial: PackageInterfaceHandle, + target: PackageInterfaceHandle, path: &str, ) -> Result<Option<PhpMixed>> { self.inner.update(initial, target, path).await @@ -113,7 +113,7 @@ impl DownloaderInterface for PharDownloader { async fn remove( &self, - package: &dyn PackageInterface, + package: PackageInterfaceHandle, path: &str, output: bool, ) -> Result<Option<PhpMixed>> { @@ -123,9 +123,9 @@ impl DownloaderInterface for PharDownloader { async fn cleanup( &self, r#type: &str, - package: &dyn PackageInterface, + package: PackageInterfaceHandle, path: &str, - prev_package: Option<&dyn PackageInterface>, + prev_package: Option<PackageInterfaceHandle>, ) -> Result<Option<PhpMixed>> { self.inner .cleanup(r#type, package, path, prev_package) diff --git a/crates/shirabe/src/downloader/rar_downloader.rs b/crates/shirabe/src/downloader/rar_downloader.rs index bb0c2f8..9ce6c51 100644 --- a/crates/shirabe/src/downloader/rar_downloader.rs +++ b/crates/shirabe/src/downloader/rar_downloader.rs @@ -6,7 +6,7 @@ use crate::downloader::ArchiveDownloader; use crate::downloader::FileDownloader; use crate::event_dispatcher::EventDispatcher; use crate::io::IOInterface; -use crate::package::PackageInterface; +use crate::package::PackageInterfaceHandle; use crate::util::Filesystem; use crate::util::HttpDownloader; use crate::util::IniHelper; @@ -50,7 +50,7 @@ impl RarDownloader { pub(crate) async fn extract( &mut self, - _package: &dyn PackageInterface, + _package: PackageInterfaceHandle, file: &str, path: &str, ) -> Result<Option<PhpMixed>> { @@ -151,9 +151,9 @@ impl crate::downloader::DownloaderInterface for RarDownloader { async fn download( &self, - package: &dyn PackageInterface, + package: PackageInterfaceHandle, path: &str, - prev_package: Option<&dyn PackageInterface>, + prev_package: Option<PackageInterfaceHandle>, output: bool, ) -> Result<Option<PhpMixed>> { self.inner @@ -164,9 +164,9 @@ impl crate::downloader::DownloaderInterface for RarDownloader { async fn prepare( &self, r#type: &str, - package: &dyn PackageInterface, + package: PackageInterfaceHandle, path: &str, - prev_package: Option<&dyn PackageInterface>, + prev_package: Option<PackageInterfaceHandle>, ) -> Result<Option<PhpMixed>> { self.inner .prepare(r#type, package, path, prev_package) @@ -175,7 +175,7 @@ impl crate::downloader::DownloaderInterface for RarDownloader { async fn install( &self, - package: &dyn PackageInterface, + package: PackageInterfaceHandle, path: &str, output: bool, ) -> Result<Option<PhpMixed>> { @@ -184,8 +184,8 @@ impl crate::downloader::DownloaderInterface for RarDownloader { async fn update( &self, - initial: &dyn PackageInterface, - target: &dyn PackageInterface, + initial: PackageInterfaceHandle, + target: PackageInterfaceHandle, path: &str, ) -> Result<Option<PhpMixed>> { self.inner.update(initial, target, path).await @@ -193,7 +193,7 @@ impl crate::downloader::DownloaderInterface for RarDownloader { async fn remove( &self, - package: &dyn PackageInterface, + package: PackageInterfaceHandle, path: &str, output: bool, ) -> Result<Option<PhpMixed>> { @@ -203,9 +203,9 @@ impl crate::downloader::DownloaderInterface for RarDownloader { async fn cleanup( &self, r#type: &str, - package: &dyn PackageInterface, + package: PackageInterfaceHandle, path: &str, - prev_package: Option<&dyn PackageInterface>, + prev_package: Option<PackageInterfaceHandle>, ) -> Result<Option<PhpMixed>> { self.inner .cleanup(r#type, package, path, prev_package) diff --git a/crates/shirabe/src/downloader/svn_downloader.rs b/crates/shirabe/src/downloader/svn_downloader.rs index f3683dd..9f5d2ed 100644 --- a/crates/shirabe/src/downloader/svn_downloader.rs +++ b/crates/shirabe/src/downloader/svn_downloader.rs @@ -10,7 +10,7 @@ use crate::downloader::DownloaderInterface; use crate::downloader::VcsDownloaderBase; use crate::io::IOInterface; use crate::io::IOInterfaceImmutable; -use crate::package::PackageInterface; +use crate::package::PackageInterfaceHandle; use crate::repository::VcsRepository; use crate::util::Filesystem; use crate::util::ProcessExecutor; @@ -37,10 +37,10 @@ impl SvnDownloader { pub(crate) async fn do_download( &mut self, - package: &dyn PackageInterface, + package: PackageInterfaceHandle, path: &str, url: &str, - prev_package: Option<&dyn PackageInterface>, + prev_package: Option<PackageInterfaceHandle>, ) -> anyhow::Result<Option<PhpMixed>> { SvnUtil::clean_env(); let mut util = SvnUtil::new( @@ -62,23 +62,26 @@ impl SvnDownloader { pub(crate) async fn do_install( &mut self, - package: &dyn PackageInterface, + package: PackageInterfaceHandle, path: &str, url: &str, ) -> anyhow::Result<Option<PhpMixed>> { SvnUtil::clean_env(); let r#ref = package.get_source_reference(); - let repo = package.get_repository(); - if let Some(repo) = repo { - if let Some(vcs_repo) = repo.as_any().downcast_ref::<VcsRepository>() { - let repo_config = vcs_repo.get_repo_config(); - if repo_config.contains_key("svn-cache-credentials") { - if let Some(val) = repo_config - .get("svn-cache-credentials") - .and_then(|v| v.as_bool()) - { - self.cache_credentials = val; + { + let package_ref = package.as_rc().borrow(); + let repo = package_ref.as_package_interface().get_repository(); + if let Some(repo) = repo { + if let Some(vcs_repo) = repo.as_any().downcast_ref::<VcsRepository>() { + let repo_config = vcs_repo.get_repo_config(); + if repo_config.contains_key("svn-cache-credentials") { + if let Some(val) = repo_config + .get("svn-cache-credentials") + .and_then(|v| v.as_bool()) + { + self.cache_credentials = val; + } } } } @@ -106,8 +109,8 @@ impl SvnDownloader { pub(crate) async fn do_update( &mut self, - initial: &dyn PackageInterface, - target: &dyn PackageInterface, + initial: PackageInterfaceHandle, + target: PackageInterfaceHandle, path: &str, url: &str, ) -> anyhow::Result<Option<PhpMixed>> { @@ -137,7 +140,7 @@ impl SvnDownloader { } self.inner.io.write_error3( - &format!(" Checking out {}", r#ref.unwrap_or_default()), + &format!(" Checking out {}", r#ref.clone().unwrap_or_default()), true, io_interface::NORMAL, ); @@ -155,7 +158,7 @@ impl SvnDownloader { Ok(None) } - pub fn get_local_changes(&self, package: &dyn PackageInterface, path: &str) -> Option<String> { + pub fn get_local_changes(&self, package: PackageInterfaceHandle, path: &str) -> Option<String> { if !self.has_metadata_repository(path) { return None; } @@ -178,7 +181,7 @@ impl SvnDownloader { pub(crate) fn execute( &self, - package: &dyn PackageInterface, + package: PackageInterfaceHandle, base_url: &str, command: Vec<String>, url: &str, @@ -204,11 +207,11 @@ impl SvnDownloader { pub(crate) async fn clean_changes( &mut self, - package: &dyn PackageInterface, + package: PackageInterfaceHandle, path: &str, update: bool, ) -> anyhow::Result<Option<PhpMixed>> { - let changes = self.get_local_changes(package, path); + let changes = self.get_local_changes(package.clone(), path); if changes.is_none() { return Ok(None); } @@ -440,9 +443,9 @@ impl DownloaderInterface for SvnDownloader { async fn download( &self, - _package: &dyn PackageInterface, + _package: PackageInterfaceHandle, _path: &str, - _prev_package: Option<&dyn PackageInterface>, + _prev_package: Option<PackageInterfaceHandle>, _output: bool, ) -> anyhow::Result<Option<PhpMixed>> { todo!() @@ -451,16 +454,16 @@ impl DownloaderInterface for SvnDownloader { async fn prepare( &self, _type: &str, - _package: &dyn PackageInterface, + _package: PackageInterfaceHandle, _path: &str, - _prev_package: Option<&dyn PackageInterface>, + _prev_package: Option<PackageInterfaceHandle>, ) -> anyhow::Result<Option<PhpMixed>> { todo!() } async fn install( &self, - _package: &dyn PackageInterface, + _package: PackageInterfaceHandle, _path: &str, _output: bool, ) -> anyhow::Result<Option<PhpMixed>> { @@ -469,8 +472,8 @@ impl DownloaderInterface for SvnDownloader { async fn update( &self, - _initial: &dyn PackageInterface, - _target: &dyn PackageInterface, + _initial: PackageInterfaceHandle, + _target: PackageInterfaceHandle, _path: &str, ) -> anyhow::Result<Option<PhpMixed>> { todo!() @@ -478,7 +481,7 @@ impl DownloaderInterface for SvnDownloader { async fn remove( &self, - _package: &dyn PackageInterface, + _package: PackageInterfaceHandle, _path: &str, _output: bool, ) -> anyhow::Result<Option<PhpMixed>> { @@ -488,9 +491,9 @@ impl DownloaderInterface for SvnDownloader { async fn cleanup( &self, _type: &str, - _package: &dyn PackageInterface, + _package: PackageInterfaceHandle, _path: &str, - _prev_package: Option<&dyn PackageInterface>, + _prev_package: Option<PackageInterfaceHandle>, ) -> anyhow::Result<Option<PhpMixed>> { todo!() } diff --git a/crates/shirabe/src/downloader/tar_downloader.rs b/crates/shirabe/src/downloader/tar_downloader.rs index 7314ecd..07d8a5f 100644 --- a/crates/shirabe/src/downloader/tar_downloader.rs +++ b/crates/shirabe/src/downloader/tar_downloader.rs @@ -7,7 +7,7 @@ use crate::downloader::DownloaderInterface; use crate::downloader::FileDownloader; use crate::event_dispatcher::EventDispatcher; use crate::io::IOInterface; -use crate::package::PackageInterface; +use crate::package::PackageInterfaceHandle; use crate::util::Filesystem; use crate::util::HttpDownloader; use crate::util::ProcessExecutor; @@ -47,7 +47,7 @@ impl TarDownloader { pub(crate) async fn extract( &self, - package: &dyn PackageInterface, + package: PackageInterfaceHandle, file: &str, path: &str, ) -> Result<Option<PhpMixed>> { @@ -66,9 +66,9 @@ impl DownloaderInterface for TarDownloader { async fn download( &self, - package: &dyn PackageInterface, + package: PackageInterfaceHandle, path: &str, - prev_package: Option<&dyn PackageInterface>, + prev_package: Option<PackageInterfaceHandle>, output: bool, ) -> Result<Option<PhpMixed>> { self.inner @@ -79,9 +79,9 @@ impl DownloaderInterface for TarDownloader { async fn prepare( &self, r#type: &str, - package: &dyn PackageInterface, + package: PackageInterfaceHandle, path: &str, - prev_package: Option<&dyn PackageInterface>, + prev_package: Option<PackageInterfaceHandle>, ) -> Result<Option<PhpMixed>> { self.inner .prepare(r#type, package, path, prev_package) @@ -90,7 +90,7 @@ impl DownloaderInterface for TarDownloader { async fn install( &self, - package: &dyn PackageInterface, + package: PackageInterfaceHandle, path: &str, output: bool, ) -> Result<Option<PhpMixed>> { @@ -99,8 +99,8 @@ impl DownloaderInterface for TarDownloader { async fn update( &self, - initial: &dyn PackageInterface, - target: &dyn PackageInterface, + initial: PackageInterfaceHandle, + target: PackageInterfaceHandle, path: &str, ) -> Result<Option<PhpMixed>> { self.inner.update(initial, target, path).await @@ -108,7 +108,7 @@ impl DownloaderInterface for TarDownloader { async fn remove( &self, - package: &dyn PackageInterface, + package: PackageInterfaceHandle, path: &str, output: bool, ) -> Result<Option<PhpMixed>> { @@ -118,9 +118,9 @@ impl DownloaderInterface for TarDownloader { async fn cleanup( &self, r#type: &str, - package: &dyn PackageInterface, + package: PackageInterfaceHandle, path: &str, - prev_package: Option<&dyn PackageInterface>, + prev_package: Option<PackageInterfaceHandle>, ) -> Result<Option<PhpMixed>> { self.inner .cleanup(r#type, package, path, prev_package) diff --git a/crates/shirabe/src/downloader/vcs_capable_downloader_interface.rs b/crates/shirabe/src/downloader/vcs_capable_downloader_interface.rs index 68e9caa..c2d07f6 100644 --- a/crates/shirabe/src/downloader/vcs_capable_downloader_interface.rs +++ b/crates/shirabe/src/downloader/vcs_capable_downloader_interface.rs @@ -1,7 +1,7 @@ //! ref: composer/src/Composer/Downloader/VcsCapableDownloaderInterface.php -use crate::package::PackageInterface; +use crate::package::PackageInterfaceHandle; pub trait VcsCapableDownloaderInterface { - fn get_vcs_reference(&self, package: &dyn PackageInterface, path: String) -> Option<String>; + fn get_vcs_reference(&self, package: PackageInterfaceHandle, path: String) -> Option<String>; } diff --git a/crates/shirabe/src/downloader/vcs_downloader.rs b/crates/shirabe/src/downloader/vcs_downloader.rs index 736d433..b09841e 100644 --- a/crates/shirabe/src/downloader/vcs_downloader.rs +++ b/crates/shirabe/src/downloader/vcs_downloader.rs @@ -18,7 +18,7 @@ use crate::downloader::DownloaderInterface; use crate::downloader::VcsCapableDownloaderInterface; use crate::io::IOInterface; use crate::io::IOInterfaceImmutable; -use crate::package::PackageInterface; +use crate::package::PackageInterfaceHandle; use crate::package::dumper::ArrayDumper; use crate::package::version::VersionGuesser; use crate::package::version::VersionParser; @@ -61,7 +61,7 @@ impl VcsDownloaderBase { /// already verified that no local changes exist. pub async fn clean_changes( &self, - _package: &dyn PackageInterface, + _package: PackageInterfaceHandle, _path: &str, _update: bool, ) -> Result<Option<PhpMixed>> { @@ -88,16 +88,16 @@ pub trait VcsDownloader: /// Downloads data needed to run an install/update later async fn do_download( &mut self, - package: &dyn PackageInterface, + package: PackageInterfaceHandle, path: &str, url: &str, - prev_package: Option<&dyn PackageInterface>, + prev_package: Option<PackageInterfaceHandle>, ) -> Result<Option<PhpMixed>>; /// Downloads specific package into specific folder. async fn do_install( &mut self, - package: &dyn PackageInterface, + package: PackageInterfaceHandle, path: &str, url: &str, ) -> Result<Option<PhpMixed>>; @@ -105,8 +105,8 @@ pub trait VcsDownloader: /// Updates specific package in specific folder from initial to target version. async fn do_update( &mut self, - initial: &dyn PackageInterface, - target: &dyn PackageInterface, + initial: PackageInterfaceHandle, + target: PackageInterfaceHandle, path: &str, url: &str, ) -> Result<Option<PhpMixed>>; @@ -124,9 +124,9 @@ pub trait VcsDownloader: async fn download( &mut self, - package: &dyn PackageInterface, + package: PackageInterfaceHandle, path: &str, - prev_package: Option<&dyn PackageInterface>, + prev_package: Option<PackageInterfaceHandle>, ) -> Result<Option<PhpMixed>> { if package.get_source_reference().is_none() { return Err(InvalidArgumentException { @@ -143,8 +143,9 @@ pub trait VcsDownloader: while let Some(url) = array_shift(&mut urls) { // TODO(phase-b): use anyhow::Result<Result<T, E>> to model PHP try/catch - let attempt: Result<Option<PhpMixed>> = - self.do_download(package, path, &url, prev_package).await; + let attempt: Result<Option<PhpMixed>> = self + .do_download(package.clone(), path, &url, prev_package.clone()) + .await; match attempt { Ok(promise) => return Ok(promise), Err(e) => { @@ -190,12 +191,12 @@ pub trait VcsDownloader: async fn prepare( &mut self, r#type: &str, - package: &dyn PackageInterface, + package: PackageInterfaceHandle, path: &str, - prev_package: Option<&dyn PackageInterface>, + prev_package: Option<PackageInterfaceHandle>, ) -> Result<Option<PhpMixed>> { if r#type == "update" { - self.clean_changes(prev_package.unwrap(), path, true) + self.clean_changes(prev_package.clone().unwrap(), path, true) .await?; self.has_cleaned_changes_mut() .insert(prev_package.unwrap().get_unique_name(), true); @@ -213,12 +214,13 @@ pub trait VcsDownloader: async fn cleanup( &mut self, r#type: &str, - _package: &dyn PackageInterface, + _package: PackageInterfaceHandle, path: &str, - prev_package: Option<&dyn PackageInterface>, + prev_package: Option<PackageInterfaceHandle>, ) -> Result<Option<PhpMixed>> { if r#type == "update" && prev_package + .clone() .map(|p| { self.has_cleaned_changes() .contains_key(&p.get_unique_name()) @@ -235,7 +237,7 @@ pub trait VcsDownloader: async fn install( &mut self, - package: &dyn PackageInterface, + package: PackageInterfaceHandle, path: &str, ) -> Result<Option<PhpMixed>> { if package.get_source_reference().is_none() { @@ -250,7 +252,7 @@ pub trait VcsDownloader: } self.io_mut().write_error3( - &format!(" - {}: ", InstallOperation::format(package, false)), + &format!(" - {}: ", InstallOperation::format(package.clone(), false)), false, io_interface::NORMAL, ); @@ -258,7 +260,8 @@ pub trait VcsDownloader: let mut urls = self.prepare_urls(package.get_source_urls()); while let Some(url) = array_shift(&mut urls) { // TODO(phase-b): use anyhow::Result<Result<T, E>> to model PHP try/catch - let attempt: Result<Option<PhpMixed>> = self.do_install(package, path, &url).await; + let attempt: Result<Option<PhpMixed>> = + self.do_install(package.clone(), path, &url).await; match attempt { Ok(_) => break, Err(e) => { @@ -303,8 +306,8 @@ pub trait VcsDownloader: async fn update( &mut self, - initial: &dyn PackageInterface, - target: &dyn PackageInterface, + initial: PackageInterfaceHandle, + target: PackageInterfaceHandle, path: &str, ) -> Result<Option<PhpMixed>> { if target.get_source_reference().is_none() { @@ -319,7 +322,10 @@ pub trait VcsDownloader: } self.io_mut().write_error3( - &format!(" - {}: ", UpdateOperation::format(initial, target, false),), + &format!( + " - {}: ", + UpdateOperation::format(initial.clone(), target.clone(), false), + ), false, io_interface::NORMAL, ); @@ -329,8 +335,9 @@ pub trait VcsDownloader: let mut exception: Option<anyhow::Error> = None; while let Some(url) = array_shift(&mut urls) { // TODO(phase-b): use anyhow::Result<Result<T, E>> to model PHP try/catch - let attempt: Result<Option<PhpMixed>> = - self.do_update(initial, target, path, &url).await; + let attempt: Result<Option<PhpMixed>> = self + .do_update(initial.clone(), target.clone(), path, &url) + .await; match attempt { Ok(_) => { exception = None; @@ -369,20 +376,14 @@ pub trait VcsDownloader: // print the commit logs if in verbose mode and VCS metadata is present // because in case of missing metadata code would trigger another exception if exception.is_none() && self.io().is_verbose() && self.has_metadata_repository(path) { + let initial_ref = initial.get_source_reference().unwrap_or_default(); + let target_ref = target.get_source_reference().unwrap_or_default(); let mut message = "Pulling in changes:"; - let mut logs = self.get_commit_logs( - initial.get_source_reference().unwrap_or(""), - target.get_source_reference().unwrap_or(""), - path, - ); + let mut logs = self.get_commit_logs(&initial_ref, &target_ref, path); if trim(&logs, None) == "" { message = "Rolling back changes:"; - logs = self.get_commit_logs( - target.get_source_reference().unwrap_or(""), - initial.get_source_reference().unwrap_or(""), - path, - ); + logs = self.get_commit_logs(&target_ref, &initial_ref, path); } if trim(&logs, None) != "" { @@ -413,7 +414,7 @@ pub trait VcsDownloader: async fn remove( &mut self, - package: &dyn PackageInterface, + package: PackageInterfaceHandle, path: &str, ) -> Result<Option<PhpMixed>> { self.io_mut().write_error3( @@ -438,7 +439,7 @@ pub trait VcsDownloader: Ok(None) } - fn get_vcs_reference(&self, package: &dyn PackageInterface, path: &str) -> Option<String> { + fn get_vcs_reference(&self, package: PackageInterfaceHandle, path: &str) -> Option<String> { let parser = VersionParser::new(); let guesser = VersionGuesser::new( self.config().clone(), @@ -448,7 +449,7 @@ pub trait VcsDownloader: ); let dumper = ArrayDumper::new(); - let package_config = dumper.dump(package); + let package_config = dumper.dump(package.clone()); let mut guesser = guesser; if let Ok(Some(package_version)) = guesser.guess_version(&package_config, path) { return package_version.commit.clone(); @@ -463,7 +464,7 @@ pub trait VcsDownloader: /// if false (remove) the changes should be assumed to be lost if the operation is not aborted async fn clean_changes( &self, - package: &dyn PackageInterface, + package: PackageInterfaceHandle, path: &str, _update: bool, ) -> Result<Option<PhpMixed>> { diff --git a/crates/shirabe/src/downloader/xz_downloader.rs b/crates/shirabe/src/downloader/xz_downloader.rs index fd83b28..ac8b6ba 100644 --- a/crates/shirabe/src/downloader/xz_downloader.rs +++ b/crates/shirabe/src/downloader/xz_downloader.rs @@ -6,7 +6,7 @@ use crate::downloader::ArchiveDownloader; use crate::downloader::FileDownloader; use crate::event_dispatcher::EventDispatcher; use crate::io::IOInterface; -use crate::package::PackageInterface; +use crate::package::PackageInterfaceHandle; use crate::util::Filesystem; use crate::util::HttpDownloader; use crate::util::ProcessExecutor; @@ -46,7 +46,7 @@ impl XzDownloader { pub(crate) async fn extract( &mut self, - package: &dyn PackageInterface, + package: PackageInterfaceHandle, file: &str, path: &str, ) -> Result<Option<PhpMixed>> { @@ -85,9 +85,9 @@ impl crate::downloader::DownloaderInterface for XzDownloader { async fn download( &self, - package: &dyn PackageInterface, + package: PackageInterfaceHandle, path: &str, - prev_package: Option<&dyn PackageInterface>, + prev_package: Option<PackageInterfaceHandle>, output: bool, ) -> Result<Option<PhpMixed>> { self.inner @@ -98,9 +98,9 @@ impl crate::downloader::DownloaderInterface for XzDownloader { async fn prepare( &self, r#type: &str, - package: &dyn PackageInterface, + package: PackageInterfaceHandle, path: &str, - prev_package: Option<&dyn PackageInterface>, + prev_package: Option<PackageInterfaceHandle>, ) -> Result<Option<PhpMixed>> { self.inner .prepare(r#type, package, path, prev_package) @@ -109,7 +109,7 @@ impl crate::downloader::DownloaderInterface for XzDownloader { async fn install( &self, - package: &dyn PackageInterface, + package: PackageInterfaceHandle, path: &str, output: bool, ) -> Result<Option<PhpMixed>> { @@ -118,8 +118,8 @@ impl crate::downloader::DownloaderInterface for XzDownloader { async fn update( &self, - initial: &dyn PackageInterface, - target: &dyn PackageInterface, + initial: PackageInterfaceHandle, + target: PackageInterfaceHandle, path: &str, ) -> Result<Option<PhpMixed>> { self.inner.update(initial, target, path).await @@ -127,7 +127,7 @@ impl crate::downloader::DownloaderInterface for XzDownloader { async fn remove( &self, - package: &dyn PackageInterface, + package: PackageInterfaceHandle, path: &str, output: bool, ) -> Result<Option<PhpMixed>> { @@ -137,9 +137,9 @@ impl crate::downloader::DownloaderInterface for XzDownloader { async fn cleanup( &self, r#type: &str, - package: &dyn PackageInterface, + package: PackageInterfaceHandle, path: &str, - prev_package: Option<&dyn PackageInterface>, + prev_package: Option<PackageInterfaceHandle>, ) -> Result<Option<PhpMixed>> { self.inner .cleanup(r#type, package, path, prev_package) diff --git a/crates/shirabe/src/downloader/zip_downloader.rs b/crates/shirabe/src/downloader/zip_downloader.rs index 4c72b91..17eeae5 100644 --- a/crates/shirabe/src/downloader/zip_downloader.rs +++ b/crates/shirabe/src/downloader/zip_downloader.rs @@ -5,7 +5,7 @@ use crate::downloader::DownloaderInterface; use crate::downloader::FileDownloader; use crate::io::IOInterface; use crate::io::IOInterfaceImmutable; -use crate::package::PackageInterface; +use crate::package::PackageInterfaceHandle; use crate::util::IniHelper; use crate::util::Platform; use anyhow::Result; @@ -62,9 +62,9 @@ impl ZipDownloader { pub async fn download( &mut self, - package: &dyn PackageInterface, + package: PackageInterfaceHandle, path: &str, - prev_package: Option<&dyn PackageInterface>, + prev_package: Option<PackageInterfaceHandle>, output: bool, ) -> Result<Option<PhpMixed>> { { @@ -202,7 +202,7 @@ impl ZipDownloader { async fn extract_with_system_unzip( &mut self, - package: &dyn PackageInterface, + package: PackageInterfaceHandle, file: &str, path: &str, ) -> Result<Option<PhpMixed>> { @@ -282,7 +282,7 @@ impl ZipDownloader { match process_result { Ok(process) => { if !process.is_successful() { - if self.cleanup_executed.contains_key(package.get_name()) { + if self.cleanup_executed.contains_key(&package.get_name()) { return Err(RuntimeException { message: format!( "Failed to extract {} as the installation was aborted by another package operation.", @@ -337,7 +337,7 @@ impl ZipDownloader { is_last_chance: bool, file: &str, path: &str, - package: &dyn PackageInterface, + package: PackageInterfaceHandle, executable: &str, ) -> Result<Option<PhpMixed>> { if is_last_chance { @@ -390,17 +390,19 @@ impl ZipDownloader { substr(&file_get_contents(file).unwrap_or_default(), -100, None).as_bytes() ) )); - if strlen(package.get_dist_url().unwrap_or("")) > 0 { + if strlen(&package.get_dist_url().unwrap_or_default()) > 0 { self.inner.io.write_error(&format!( "Origin URL: {}", - self.inner - .process_url(package, package.get_dist_url().unwrap_or(""))? + self.inner.process_url( + package.clone(), + &package.get_dist_url().unwrap_or_default() + )? )); let headers = { let response_headers = crate::downloader::file_downloader::RESPONSE_HEADERS .lock() .unwrap(); - match response_headers.get(package.get_name()) { + match response_headers.get(&package.get_name()) { Some(list) => PhpMixed::List( list.iter() .map(|s| Box::new(PhpMixed::String(s.clone()))) @@ -422,7 +424,7 @@ impl ZipDownloader { async fn extract_with_zip_archive( &mut self, - package: &dyn PackageInterface, + package: PackageInterfaceHandle, file: &str, path: &str, ) -> Result<Option<PhpMixed>> { @@ -521,7 +523,7 @@ impl ZipDownloader { pub(crate) async fn extract( &mut self, - package: &dyn PackageInterface, + package: PackageInterfaceHandle, file: &str, path: &str, ) -> Result<Option<PhpMixed>> { @@ -562,9 +564,9 @@ impl crate::downloader::DownloaderInterface for ZipDownloader { async fn download( &self, - package: &dyn PackageInterface, + package: PackageInterfaceHandle, path: &str, - prev_package: Option<&dyn PackageInterface>, + prev_package: Option<PackageInterfaceHandle>, output: bool, ) -> Result<Option<PhpMixed>> { self.inner @@ -575,9 +577,9 @@ impl crate::downloader::DownloaderInterface for ZipDownloader { async fn prepare( &self, r#type: &str, - package: &dyn PackageInterface, + package: PackageInterfaceHandle, path: &str, - prev_package: Option<&dyn PackageInterface>, + prev_package: Option<PackageInterfaceHandle>, ) -> Result<Option<PhpMixed>> { self.inner .prepare(r#type, package, path, prev_package) @@ -586,7 +588,7 @@ impl crate::downloader::DownloaderInterface for ZipDownloader { async fn install( &self, - package: &dyn PackageInterface, + package: PackageInterfaceHandle, path: &str, output: bool, ) -> Result<Option<PhpMixed>> { @@ -595,8 +597,8 @@ impl crate::downloader::DownloaderInterface for ZipDownloader { async fn update( &self, - initial: &dyn PackageInterface, - target: &dyn PackageInterface, + initial: PackageInterfaceHandle, + target: PackageInterfaceHandle, path: &str, ) -> Result<Option<PhpMixed>> { self.inner.update(initial, target, path).await @@ -604,7 +606,7 @@ impl crate::downloader::DownloaderInterface for ZipDownloader { async fn remove( &self, - package: &dyn PackageInterface, + package: PackageInterfaceHandle, path: &str, output: bool, ) -> Result<Option<PhpMixed>> { @@ -614,9 +616,9 @@ impl crate::downloader::DownloaderInterface for ZipDownloader { async fn cleanup( &self, r#type: &str, - package: &dyn PackageInterface, + package: PackageInterfaceHandle, path: &str, - prev_package: Option<&dyn PackageInterface>, + prev_package: Option<PackageInterfaceHandle>, ) -> Result<Option<PhpMixed>> { self.inner .cleanup(r#type, package, path, prev_package) diff --git a/crates/shirabe/src/event_dispatcher/event_dispatcher.rs b/crates/shirabe/src/event_dispatcher/event_dispatcher.rs index 3a037c9..ef02660 100644 --- a/crates/shirabe/src/event_dispatcher/event_dispatcher.rs +++ b/crates/shirabe/src/event_dispatcher/event_dispatcher.rs @@ -1289,11 +1289,7 @@ impl EventDispatcher { // (PhpMixed in this port). let map = generator.parse_autoloads( package_map, - package - .as_rc() - .borrow() - .as_root_package_interface() - .unwrap(), + package.clone(), shirabe_php_shim::PhpMixed::Null, ); diff --git a/crates/shirabe/src/factory.rs b/crates/shirabe/src/factory.rs index 4c10db3..80f1548 100644 --- a/crates/shirabe/src/factory.rs +++ b/crates/shirabe/src/factory.rs @@ -1243,7 +1243,7 @@ impl Factory { im: &mut InstallationManager, ) -> anyhow::Result<()> { for package in repo.get_packages() { - if !im.is_package_installed(repo, &package)? { + if !im.is_package_installed(repo, package.clone())? { let _ = package; } } diff --git a/crates/shirabe/src/installer.rs b/crates/shirabe/src/installer.rs index 70062aa..14e75c0 100644 --- a/crates/shirabe/src/installer.rs +++ b/crates/shirabe/src/installer.rs @@ -78,7 +78,6 @@ use crate::package::Locker; use crate::package::Package; use crate::package::PackageInterface; use crate::package::PackageInterfaceHandle; -use crate::package::RootAliasPackage; use crate::package::RootPackageInterface; use crate::package::RootPackageInterfaceHandle; use crate::package::base_package::{self, BasePackage}; @@ -360,9 +359,7 @@ impl Installer { ]); if is_fresh_install { self.suggested_packages_reporter - .add_suggestions_from_package( - self.package.as_rc().borrow().as_package_interface(), - ); + .add_suggestions_from_package(self.package.clone().into()); } self.suggested_packages_reporter .output_minimalistic(Some(&installed_repo), None); @@ -413,11 +410,7 @@ impl Installer { self.autoload_generator.borrow_mut().dump( &*self.config.borrow(), self.repository_manager.borrow().get_local_repository(), - self.package - .as_rc() - .borrow() - .as_root_package_interface() - .unwrap(), + self.package.clone(), &mut *self.installation_manager.borrow_mut(), "composer", self.optimize_autoloader, @@ -432,11 +425,9 @@ impl Installer { let repository_manager = self.repository_manager.clone(); let repository_manager = repository_manager.borrow(); for package in repository_manager.get_local_repository().get_packages() { - // TODO(phase-c): InstallationManager APIs still take &dyn PackageInterface; bridge - // the handle until they migrate to handles. self.installation_manager .borrow_mut() - .ensure_binaries_presence(package.as_rc().borrow().as_package_interface()); + .ensure_binaries_presence(package.clone()); } } @@ -635,11 +626,7 @@ impl Installer { let fixed_root_package = self.fixed_root_package.clone(); let mut request = self.create_request( - fixed_root_package - .as_rc() - .borrow() - .as_root_package_interface() - .unwrap(), + fixed_root_package, &platform_repo, locked_repository.as_ref(), ); @@ -835,9 +822,7 @@ impl Installer { // collect suggestions if let Some(io) = operation.as_install_operation() { self.suggested_packages_reporter - .add_suggestions_from_package( - io.get_package().as_rc().borrow().as_package_interface(), - ); + .add_suggestions_from_package(io.get_package()); } // output op if lock file is enabled, but alias op only in debug verbosity @@ -929,7 +914,7 @@ impl Installer { let dumper = ArrayDumper::new(); for pkg in lock_transaction.get_new_lock_packages(false, false) { let loaded = loader.load( - dumper.dump(pkg.as_rc().borrow().as_package_interface()), + dumper.dump(pkg.clone()), Some("Composer\\Package\\CompletePackage".to_string()), )?; result_repo.add_package(loaded)?; @@ -938,15 +923,7 @@ impl Installer { let mut repository_set = self.create_repository_set(true, platform_repo, aliases, None); repository_set.add_repository(Box::new(result_repo))?; - let mut request = self.create_request( - self.fixed_root_package - .as_rc() - .borrow() - .as_root_package_interface() - .unwrap(), - platform_repo, - None, - ); + let mut request = self.create_request(self.fixed_root_package.clone(), platform_repo, None); self.require_packages_for_update(&mut request, locked_repository, false)?; let pool = repository_set.create_pool_with_all_packages()?; @@ -1028,15 +1005,8 @@ impl Installer { // creating requirements request let fixed_root_package = self.fixed_root_package.clone(); - let mut request = self.create_request( - fixed_root_package - .as_rc() - .borrow() - .as_root_package_interface() - .unwrap(), - &platform_repo, - Some(&locked_repository), - ); + let mut request = + self.create_request(fixed_root_package, &platform_repo, Some(&locked_repository)); if !self.locker.borrow_mut().is_fresh()? { self.io.write_error3( @@ -1047,14 +1017,10 @@ impl Installer { } let package_for_missing = self.package.clone(); - let missing_requirement_info = self.locker.borrow_mut().get_missing_requirement_info( - package_for_missing - .as_rc() - .borrow() - .as_root_package_interface() - .unwrap(), - self.dev_mode, - )?; + let missing_requirement_info = self + .locker + .borrow_mut() + .get_missing_requirement_info(package_for_missing, self.dev_mode)?; if !missing_requirement_info.is_empty() { self.io.write_error(&missing_requirement_info.join("\n")); @@ -1463,7 +1429,7 @@ impl Installer { fn create_request( &self, - root_package: &dyn RootPackageInterface, + root_package: RootPackageInterfaceHandle, platform_repo: &PlatformRepository, locked_repository: Option<&LockArrayRepository>, ) -> Request { @@ -1472,11 +1438,11 @@ impl Installer { let _ = locked_repository; let mut request = Request::new(None); - // TODO(phase-c): request.fix_package wants a BasePackageHandle; root_package is only a - // borrowed &dyn RootPackageInterface here and cannot be lifted back into a handle. - let _ = root_package; + // TODO(phase-c): request.fix_package wants a BasePackageHandle; root_package is wired in + // once Request migrates to handles. // request.fix_package(root_package); - if let Some(_alias) = root_package.as_any().downcast_ref::<RootAliasPackage>() { + let root_package_handle: PackageInterfaceHandle = root_package.clone().into(); + if let Some(_alias) = root_package_handle.as_root_alias_package() { // request.fix_package(alias.get_alias_of()); } diff --git a/crates/shirabe/src/installer/binary_installer.rs b/crates/shirabe/src/installer/binary_installer.rs index a555d83..64908bf 100644 --- a/crates/shirabe/src/installer/binary_installer.rs +++ b/crates/shirabe/src/installer/binary_installer.rs @@ -11,7 +11,7 @@ use shirabe_php_shim::{ use crate::io::IOInterface; use crate::io::IOInterfaceImmutable; -use crate::package::PackageInterface; +use crate::package::PackageInterfaceHandle; use crate::util::Filesystem; use crate::util::Platform; use crate::util::ProcessExecutor; @@ -48,11 +48,11 @@ impl BinaryInstaller { pub fn install_binaries( &mut self, - package: &dyn PackageInterface, + package: PackageInterfaceHandle, install_path: &str, warn_on_overwrite: bool, ) { - let binaries = self.get_binaries(package); + let binaries = self.get_binaries(package.clone()); if binaries.is_empty() { return; } @@ -123,7 +123,7 @@ impl BinaryInstaller { } if bin_compat == "full" { - self.install_full_binaries(&bin_path, &link, bin, package); + self.install_full_binaries(&bin_path, &link, bin, package.clone()); } else { self.install_unixy_proxy_binaries(&bin_path, &link); } @@ -134,7 +134,7 @@ impl BinaryInstaller { } } - pub fn remove_binaries(&mut self, package: &dyn PackageInterface) { + pub fn remove_binaries(&mut self, package: PackageInterfaceHandle) { self.initialize_bin_dir(); let binaries = self.get_binaries(package); @@ -192,7 +192,7 @@ impl BinaryInstaller { } /// @return string[] - pub(crate) fn get_binaries(&self, package: &dyn PackageInterface) -> Vec<String> { + pub(crate) fn get_binaries(&self, package: PackageInterfaceHandle) -> Vec<String> { package.get_binaries() } @@ -201,7 +201,7 @@ impl BinaryInstaller { bin_path: &str, link: &str, bin: &str, - package: &dyn PackageInterface, + package: PackageInterfaceHandle, ) { let mut link = link.to_string(); // add unixy support for cygwin and similar environments diff --git a/crates/shirabe/src/installer/binary_presence_interface.rs b/crates/shirabe/src/installer/binary_presence_interface.rs index 8830bab..2c4b2cc 100644 --- a/crates/shirabe/src/installer/binary_presence_interface.rs +++ b/crates/shirabe/src/installer/binary_presence_interface.rs @@ -1,7 +1,7 @@ //! ref: composer/src/Composer/Installer/BinaryPresenceInterface.php -use crate::package::PackageInterface; +use crate::package::PackageInterfaceHandle; pub trait BinaryPresenceInterface { - fn ensure_binaries_presence(&self, package: &dyn PackageInterface); + fn ensure_binaries_presence(&self, package: PackageInterfaceHandle); } diff --git a/crates/shirabe/src/installer/installation_manager.rs b/crates/shirabe/src/installer/installation_manager.rs index 5f312b6..95a1870 100644 --- a/crates/shirabe/src/installer/installation_manager.rs +++ b/crates/shirabe/src/installer/installation_manager.rs @@ -134,25 +134,24 @@ impl InstallationManager { pub fn is_package_installed( &mut self, repo: &dyn InstalledRepositoryInterface, - package: &PackageInterfaceHandle, + package: PackageInterfaceHandle, ) -> Result<bool> { if let Some(alias) = package.as_alias() { let alias_of: PackageInterfaceHandle = alias.get_alias_of().into(); return Ok( - repo.has_package(package.as_rc().borrow().as_package_interface()) - && self.is_package_installed(repo, &alias_of)?, + repo.has_package(package.clone()) && self.is_package_installed(repo, alias_of)? ); } Ok(self .get_installer(&package.get_type())? - .is_installed(repo, package.as_rc().borrow().as_package_interface())) + .is_installed(repo, package.clone())) } /// Install binary for the given package. /// If the installer associated to this package doesn't handle that function, it'll do nothing. - pub fn ensure_binaries_presence(&mut self, package: &dyn PackageInterface) { - let installer = self.get_installer(package.get_type()); + pub fn ensure_binaries_presence(&mut self, package: PackageInterfaceHandle) { + let installer = self.get_installer(&package.get_type()); let installer = match installer { Ok(i) => i, Err(_e) => { @@ -212,7 +211,7 @@ impl InstallationManager { // TODO(phase-b): instanceof downcasts for UpdateOperation/InstallOperation let is_update_or_install = false; if is_update_or_install { - let package: Option<&dyn PackageInterface> = None; + let package: Option<PackageInterfaceHandle> = None; let _ = package; let extra: IndexMap<String, PhpMixed> = IndexMap::new(); if extra @@ -307,8 +306,8 @@ impl InstallationManager { continue; } - let package: &dyn PackageInterface; - let initial_package: Option<&dyn PackageInterface>; + let package: PackageInterfaceHandle; + let initial_package: Option<PackageInterfaceHandle>; // TODO(phase-b): downcast for UpdateOperation / Install/Mark/Uninstall variants let update_op: Option<&UpdateOperation> = None; if op_type == "update" { @@ -325,7 +324,7 @@ impl InstallationManager { package = operation.get_package(); initial_package = None; } - let installer = self.get_installer(package.get_type())?; + let installer = self.get_installer(&package.get_type())?; // TODO(phase-b): closure captures installer + package; needs Rc-shared installer/package let _ = installer; @@ -349,7 +348,7 @@ impl InstallationManager { if op_type != "uninstall" { // TODO(phase-c-promise): PHP collects every download and runs them concurrently via // Loop::wait; the single-threaded loop awaits each serially instead. - let installer = self.get_installer(package.get_type())?; + let installer = self.get_installer(&package.get_type())?; installer.download(package, initial_package).await?; } } @@ -450,8 +449,8 @@ impl InstallationManager { continue; } - let package: &dyn PackageInterface; - let initial_package: Option<&dyn PackageInterface>; + let package: PackageInterfaceHandle; + let initial_package: Option<PackageInterfaceHandle>; let update_op: Option<&UpdateOperation> = None; if op_type == "update" { if let Some(_u) = update_op { @@ -488,7 +487,7 @@ impl InstallationManager { let _dispatcher = self.event_dispatcher.as_ref(); let _io = self.io.as_ref(); - let installer = self.get_installer(package.get_type())?; + let installer = self.get_installer(&package.get_type())?; // TODO(phase-c-promise): PHP chains prepare()->then(install/update/uninstall)->then(cleanup // + repo.write); the single-threaded loop awaits prepare and leaves the rest as phase-b work. installer @@ -526,8 +525,8 @@ impl InstallationManager { /// Executes download operation. /// /// @phpstan-return PromiseInterface<void|null>|null - pub async fn download(&mut self, package: &dyn PackageInterface) -> Option<PhpMixed> { - let installer = self.get_installer(package.get_type()).ok()?; + pub async fn download(&mut self, package: PackageInterfaceHandle) -> Option<PhpMixed> { + let installer = self.get_installer(&package.get_type()).ok()?; let promise = installer.cleanup("install", package, None).await.ok()?; promise @@ -541,11 +540,11 @@ impl InstallationManager { repo: &mut dyn InstalledRepositoryInterface, operation: &InstallOperation, ) -> Option<PhpMixed> { - let package = operation.get_package().clone(); + let package = operation.get_package(); let package_type = package.get_type(); let installer = self.get_installer(&package_type).ok()?; - let promise = installer.install(repo, &package).await.ok()?; - self.mark_for_notification(&package); + let promise = installer.install(repo, package.clone()).await.ok()?; + self.mark_for_notification(package.clone()); promise } @@ -566,19 +565,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).await.ok()?; - self.mark_for_notification(&target); + let promise = installer.update(repo, initial, target.clone()).await.ok()?; + self.mark_for_notification(target.clone()); promise } else { // PHP: uninstall initial, then install target via the target-type installer. let _ = self .get_installer(&initial_type) .ok()? - .uninstall(repo, &initial) + .uninstall(repo, initial) .await .ok()?; let installer = self.get_installer(&target_type).ok()?; - installer.install(repo, &target).await.ok()? + installer.install(repo, target).await.ok()? }; promise @@ -592,11 +591,11 @@ impl InstallationManager { repo: &mut dyn InstalledRepositoryInterface, operation: &UninstallOperation, ) -> Option<PhpMixed> { - let package = operation.get_package().clone(); + let package = operation.get_package(); let package_type = package.get_type(); let installer = self.get_installer(&package_type).ok()?; - installer.uninstall(repo, &package).await.ok()? + installer.uninstall(repo, package).await.ok()? } /// Executes markAliasInstalled operation. @@ -607,11 +606,8 @@ impl InstallationManager { ) { let package = operation.get_package(); - if !repo.has_package(package) { - // TODO(phase-c): MarkAliasInstalledOperation::get_package() yields a borrowed - // &AliasPackage; add_package now wants a shared PackageInterfaceHandle. - let package_handle: PackageInterfaceHandle = todo!(); - repo.add_package(package_handle); + if !repo.has_package(package.clone().into()) { + repo.add_package(package.into()); } } @@ -623,14 +619,14 @@ impl InstallationManager { ) { let package = operation.get_package(); - repo.remove_package(package); + repo.remove_package(package.clone().into()); } /// Returns the installation path of a package /// /// @return string|null absolute path to install to, which does not end with a slash, or null if the package does not have anything installed on disk - pub fn get_install_path(&mut self, package: &dyn PackageInterface) -> Option<String> { - let installer = self.get_installer(package.get_type()).ok()?; + pub fn get_install_path(&mut self, package: PackageInterfaceHandle) -> Option<String> { + let installer = self.get_installer(&package.get_type()).ok()?; installer.get_install_path(package) } @@ -767,7 +763,7 @@ impl InstallationManager { self.reset(); } - fn mark_for_notification(&mut self, package: &PackageInterfaceHandle) { + fn mark_for_notification(&mut self, package: PackageInterfaceHandle) { if let Some(notification_url) = package.get_notification_url() { self.notifiable_packages .entry(notification_url) diff --git a/crates/shirabe/src/installer/installer_interface.rs b/crates/shirabe/src/installer/installer_interface.rs index 8ab7efd..3056429 100644 --- a/crates/shirabe/src/installer/installer_interface.rs +++ b/crates/shirabe/src/installer/installer_interface.rs @@ -1,6 +1,5 @@ //! ref: composer/src/Composer/Installer/InstallerInterface.php -use crate::package::PackageInterface; use crate::package::PackageInterfaceHandle; use crate::repository::InstalledRepositoryInterface; use shirabe_php_shim::PhpMixed; @@ -12,49 +11,49 @@ pub trait InstallerInterface: std::fmt::Debug { fn is_installed( &self, repo: &dyn InstalledRepositoryInterface, - package: &dyn PackageInterface, + package: PackageInterfaceHandle, ) -> bool; async fn download( &self, - package: &dyn PackageInterface, - prev_package: Option<&dyn PackageInterface>, + package: PackageInterfaceHandle, + prev_package: Option<PackageInterfaceHandle>, ) -> anyhow::Result<Option<PhpMixed>>; async fn prepare( &self, r#type: &str, - package: &dyn PackageInterface, - prev_package: Option<&dyn PackageInterface>, + package: PackageInterfaceHandle, + prev_package: Option<PackageInterfaceHandle>, ) -> anyhow::Result<Option<PhpMixed>>; async fn install( &mut self, repo: &mut dyn InstalledRepositoryInterface, - package: &PackageInterfaceHandle, + package: PackageInterfaceHandle, ) -> anyhow::Result<Option<PhpMixed>>; async fn update( &mut self, repo: &mut dyn InstalledRepositoryInterface, - initial: &PackageInterfaceHandle, - target: &PackageInterfaceHandle, + initial: PackageInterfaceHandle, + target: PackageInterfaceHandle, ) -> anyhow::Result<Option<PhpMixed>>; async fn uninstall( &mut self, repo: &mut dyn InstalledRepositoryInterface, - package: &PackageInterfaceHandle, + package: PackageInterfaceHandle, ) -> anyhow::Result<Option<PhpMixed>>; async fn cleanup( &self, r#type: &str, - package: &dyn PackageInterface, - prev_package: Option<&dyn PackageInterface>, + package: PackageInterfaceHandle, + prev_package: Option<PackageInterfaceHandle>, ) -> anyhow::Result<Option<PhpMixed>>; - fn get_install_path(&self, package: &dyn PackageInterface) -> Option<String>; + fn get_install_path(&self, package: PackageInterfaceHandle) -> Option<String>; fn clone_box(&self) -> Box<dyn InstallerInterface> { todo!() diff --git a/crates/shirabe/src/installer/library_installer.rs b/crates/shirabe/src/installer/library_installer.rs index 17ec8d4..c1fedef 100644 --- a/crates/shirabe/src/installer/library_installer.rs +++ b/crates/shirabe/src/installer/library_installer.rs @@ -15,7 +15,6 @@ use crate::installer::BinaryInstaller; use crate::installer::BinaryPresenceInterface; use crate::installer::InstallerInterface; use crate::io::IOInterface; -use crate::package::PackageInterface; use crate::package::PackageInterfaceHandle; use crate::repository::InstalledRepositoryInterface; use crate::util::Filesystem; @@ -100,8 +99,8 @@ impl LibraryInstaller { } /// Make sure binaries are installed for a given package. - pub fn ensure_binaries_presence(&mut self, package: &dyn PackageInterface) { - let install_path = self.get_install_path(package).unwrap(); + pub fn ensure_binaries_presence(&mut self, package: PackageInterfaceHandle) { + let install_path = self.get_install_path(package.clone()).unwrap(); self.binary_installer .install_binaries(package, &install_path, false); } @@ -110,8 +109,8 @@ impl LibraryInstaller { /// /// It is used for BC as getInstallPath tends to be overridden by /// installer plugins but not getPackageBasePath - pub(crate) fn get_package_base_path(&self, package: &dyn PackageInterface) -> String { - let install_path = self.get_install_path(package).unwrap(); + pub(crate) fn get_package_base_path(&self, package: PackageInterfaceHandle) -> String { + let install_path = self.get_install_path(package.clone()).unwrap(); let target_dir = package.get_target_dir(); if let Some(target_dir) = target_dir { @@ -135,9 +134,9 @@ impl LibraryInstaller { /// @phpstan-return PromiseInterface<void|null>|null pub(crate) async fn install_code( &self, - package: &dyn PackageInterface, + package: PackageInterfaceHandle, ) -> Result<Option<PhpMixed>> { - let download_path = self.get_install_path(package).unwrap(); + let download_path = self.get_install_path(package.clone()).unwrap(); self.get_download_manager() .borrow() @@ -149,11 +148,11 @@ impl LibraryInstaller { /// @phpstan-return PromiseInterface<void|null>|null pub(crate) async fn update_code( &self, - initial: &dyn PackageInterface, - target: &dyn PackageInterface, + initial: PackageInterfaceHandle, + target: PackageInterfaceHandle, ) -> Result<Option<PhpMixed>> { - let initial_download_path = self.get_install_path(initial).unwrap(); - let target_download_path = self.get_install_path(target).unwrap(); + let initial_download_path = self.get_install_path(initial.clone()).unwrap(); + let target_download_path = self.get_install_path(target.clone()).unwrap(); if target_download_path != initial_download_path { // if the target and initial dirs intersect, we force a remove + install // to avoid the rename wiping the target dir as part of the initial dir cleanup @@ -180,9 +179,9 @@ impl LibraryInstaller { /// @phpstan-return PromiseInterface<void|null>|null pub(crate) async fn remove_code( &self, - package: &dyn PackageInterface, + package: PackageInterfaceHandle, ) -> Result<Option<PhpMixed>> { - let download_path = self.get_package_base_path(package); + let download_path = self.get_package_base_path(package.clone()); self.get_download_manager() .borrow() @@ -229,9 +228,9 @@ impl InstallerInterface for LibraryInstaller { fn is_installed( &self, repo: &dyn InstalledRepositoryInterface, - package: &dyn PackageInterface, + package: PackageInterfaceHandle, ) -> bool { - if !repo.has_package(package) { + if !repo.has_package(package.clone()) { return false; } @@ -258,12 +257,12 @@ impl InstallerInterface for LibraryInstaller { async fn download( &self, - package: &dyn PackageInterface, - prev_package: Option<&dyn PackageInterface>, + package: PackageInterfaceHandle, + prev_package: Option<PackageInterfaceHandle>, ) -> Result<Option<PhpMixed>> { // TODO(phase-b): initialize_vendor_dir requires &mut self // self.initialize_vendor_dir(); - let download_path = self.get_install_path(package).unwrap(); + let download_path = self.get_install_path(package.clone()).unwrap(); self.get_download_manager() .borrow() @@ -274,12 +273,12 @@ impl InstallerInterface for LibraryInstaller { async fn prepare( &self, r#type: &str, - package: &dyn PackageInterface, - prev_package: Option<&dyn PackageInterface>, + package: PackageInterfaceHandle, + prev_package: Option<PackageInterfaceHandle>, ) -> Result<Option<PhpMixed>> { // TODO(phase-b): initialize_vendor_dir requires &mut self // self.initialize_vendor_dir(); - let download_path = self.get_install_path(package).unwrap(); + let download_path = self.get_install_path(package.clone()).unwrap(); self.get_download_manager() .borrow() @@ -290,12 +289,12 @@ impl InstallerInterface for LibraryInstaller { async fn cleanup( &self, r#type: &str, - package: &dyn PackageInterface, - prev_package: Option<&dyn PackageInterface>, + package: PackageInterfaceHandle, + prev_package: Option<PackageInterfaceHandle>, ) -> Result<Option<PhpMixed>> { // TODO(phase-b): initialize_vendor_dir requires &mut self // self.initialize_vendor_dir(); - let download_path = self.get_install_path(package).unwrap(); + let download_path = self.get_install_path(package.clone()).unwrap(); self.get_download_manager() .borrow() @@ -306,35 +305,23 @@ impl InstallerInterface for LibraryInstaller { async fn install( &mut self, repo: &mut dyn InstalledRepositoryInterface, - package: &PackageInterfaceHandle, + package: PackageInterfaceHandle, ) -> Result<Option<PhpMixed>> { // TODO(phase-b): initialize_vendor_dir requires &mut self // self.initialize_vendor_dir(); - let download_path = self - .get_install_path(package.as_rc().borrow().as_package_interface()) - .unwrap(); + let download_path = self.get_install_path(package.clone()).unwrap(); // remove the binaries if it appears the package files are missing - if !Filesystem::is_readable(&download_path) - && repo.has_package(package.as_rc().borrow().as_package_interface()) - { - self.binary_installer - .remove_binaries(package.as_rc().borrow().as_package_interface()); + if !Filesystem::is_readable(&download_path) && repo.has_package(package.clone()) { + self.binary_installer.remove_binaries(package.clone()); } - let _ = self - .install_code(package.as_rc().borrow().as_package_interface()) - .await?; + let _ = self.install_code(package.clone()).await?; - let install_path = self - .get_install_path(package.as_rc().borrow().as_package_interface()) - .unwrap(); - self.binary_installer.install_binaries( - package.as_rc().borrow().as_package_interface(), - &install_path, - true, - ); - if !repo.has_package(package.as_rc().borrow().as_package_interface()) { + let install_path = self.get_install_path(package.clone()).unwrap(); + self.binary_installer + .install_binaries(package.clone(), &install_path, true); + if !repo.has_package(package.clone()) { repo.add_package(package.clone()); } @@ -344,10 +331,10 @@ impl InstallerInterface for LibraryInstaller { async fn update( &mut self, repo: &mut dyn InstalledRepositoryInterface, - initial: &PackageInterfaceHandle, - target: &PackageInterfaceHandle, + initial: PackageInterfaceHandle, + target: PackageInterfaceHandle, ) -> Result<Option<PhpMixed>> { - if !repo.has_package(initial.as_rc().borrow().as_package_interface()) { + if !repo.has_package(initial.clone()) { return Err(InvalidArgumentException { message: format!("Package is not installed: {}", initial), code: 0, @@ -358,25 +345,14 @@ impl InstallerInterface for LibraryInstaller { // TODO(phase-b): initialize_vendor_dir requires &mut self // self.initialize_vendor_dir(); - self.binary_installer - .remove_binaries(initial.as_rc().borrow().as_package_interface()); - let _ = self - .update_code( - initial.as_rc().borrow().as_package_interface(), - target.as_rc().borrow().as_package_interface(), - ) - .await?; + self.binary_installer.remove_binaries(initial.clone()); + let _ = self.update_code(initial.clone(), target.clone()).await?; - let install_path = self - .get_install_path(target.as_rc().borrow().as_package_interface()) - .unwrap(); - self.binary_installer.install_binaries( - target.as_rc().borrow().as_package_interface(), - &install_path, - true, - ); - repo.remove_package(initial.as_rc().borrow().as_package_interface()); - if !repo.has_package(target.as_rc().borrow().as_package_interface()) { + let install_path = self.get_install_path(target.clone()).unwrap(); + self.binary_installer + .install_binaries(target.clone(), &install_path, true); + repo.remove_package(initial.clone()); + if !repo.has_package(target.clone()) { repo.add_package(target.clone()); } @@ -386,9 +362,9 @@ impl InstallerInterface for LibraryInstaller { async fn uninstall( &mut self, repo: &mut dyn InstalledRepositoryInterface, - package: &PackageInterfaceHandle, + package: PackageInterfaceHandle, ) -> Result<Option<PhpMixed>> { - if !repo.has_package(package.as_rc().borrow().as_package_interface()) { + if !repo.has_package(package.clone()) { return Err(InvalidArgumentException { message: format!("Package is not installed: {}", package), code: 0, @@ -396,15 +372,11 @@ impl InstallerInterface for LibraryInstaller { .into()); } - let _ = self - .remove_code(package.as_rc().borrow().as_package_interface()) - .await?; + let _ = self.remove_code(package.clone()).await?; - let download_path = - self.get_package_base_path(package.as_rc().borrow().as_package_interface()); - self.binary_installer - .remove_binaries(package.as_rc().borrow().as_package_interface()); - repo.remove_package(package.as_rc().borrow().as_package_interface()); + let download_path = self.get_package_base_path(package.clone()); + self.binary_installer.remove_binaries(package.clone()); + repo.remove_package(package.clone()); if strpos(&package.get_name(), "/").map_or(false, |pos| pos != 0) { let package_vendor_dir = dirname(&download_path); @@ -421,7 +393,7 @@ impl InstallerInterface for LibraryInstaller { Ok(None) } - fn get_install_path(&self, package: &dyn PackageInterface) -> Option<String> { + fn get_install_path(&self, package: PackageInterfaceHandle) -> Option<String> { // TODO(phase-b): initialize_vendor_dir requires &mut self // self.initialize_vendor_dir(); @@ -449,7 +421,7 @@ impl InstallerInterface for LibraryInstaller { } impl BinaryPresenceInterface for LibraryInstaller { - fn ensure_binaries_presence(&self, _package: &dyn PackageInterface) { + fn ensure_binaries_presence(&self, _package: PackageInterfaceHandle) { // TODO(phase-b): trait takes &self but LibraryInstaller::ensure_binaries_presence // requires &mut self due to BinaryInstaller::install_binaries(&mut self, ...). // Revisit the trait or use interior mutability. diff --git a/crates/shirabe/src/installer/metapackage_installer.rs b/crates/shirabe/src/installer/metapackage_installer.rs index fe41dd3..820023b 100644 --- a/crates/shirabe/src/installer/metapackage_installer.rs +++ b/crates/shirabe/src/installer/metapackage_installer.rs @@ -7,7 +7,6 @@ use crate::installer::InstallerInterface; use crate::io::IOInterface; use crate::io::IOInterfaceImmutable; use crate::io::io_interface; -use crate::package::PackageInterface; use crate::package::PackageInterfaceHandle; use crate::repository::InstalledRepositoryInterface; use anyhow::Result; @@ -33,15 +32,15 @@ impl InstallerInterface for MetapackageInstaller { fn is_installed( &self, repo: &dyn InstalledRepositoryInterface, - package: &dyn PackageInterface, + package: PackageInterfaceHandle, ) -> bool { - repo.has_package(package) + repo.has_package(package.clone()) } async fn download( &self, - _package: &dyn PackageInterface, - _prev_package: Option<&dyn PackageInterface>, + _package: PackageInterfaceHandle, + _prev_package: Option<PackageInterfaceHandle>, ) -> Result<Option<PhpMixed>> { Ok(None) } @@ -49,8 +48,8 @@ impl InstallerInterface for MetapackageInstaller { async fn prepare( &self, _type: &str, - _package: &dyn PackageInterface, - _prev_package: Option<&dyn PackageInterface>, + _package: PackageInterfaceHandle, + _prev_package: Option<PackageInterfaceHandle>, ) -> Result<Option<PhpMixed>> { Ok(None) } @@ -58,8 +57,8 @@ impl InstallerInterface for MetapackageInstaller { async fn cleanup( &self, _type: &str, - _package: &dyn PackageInterface, - _prev_package: Option<&dyn PackageInterface>, + _package: PackageInterfaceHandle, + _prev_package: Option<PackageInterfaceHandle>, ) -> Result<Option<PhpMixed>> { Ok(None) } @@ -67,18 +66,15 @@ impl InstallerInterface for MetapackageInstaller { async fn install( &mut self, repo: &mut dyn InstalledRepositoryInterface, - package: &PackageInterfaceHandle, + package: PackageInterfaceHandle, ) -> Result<Option<PhpMixed>> { self.io.write_error3( - &format!( - " - {}", - InstallOperation::format(package.as_rc().borrow().as_package_interface(), false) - ), + &format!(" - {}", InstallOperation::format(package.clone(), false)), true, io_interface::NORMAL, ); - repo.add_package(package.clone()); + repo.add_package(package); Ok(None) } @@ -86,10 +82,10 @@ impl InstallerInterface for MetapackageInstaller { async fn update( &mut self, repo: &mut dyn InstalledRepositoryInterface, - initial: &PackageInterfaceHandle, - target: &PackageInterfaceHandle, + initial: PackageInterfaceHandle, + target: PackageInterfaceHandle, ) -> Result<Option<PhpMixed>> { - if !repo.has_package(initial.as_rc().borrow().as_package_interface()) { + if !repo.has_package(initial.clone()) { return Err(InvalidArgumentException { message: format!("Package is not installed: {}", initial), code: 0, @@ -100,18 +96,14 @@ impl InstallerInterface for MetapackageInstaller { self.io.write_error3( &format!( " - {}", - UpdateOperation::format( - initial.as_rc().borrow().as_package_interface(), - target.as_rc().borrow().as_package_interface(), - false - ) + UpdateOperation::format(initial.clone(), target.clone(), false) ), true, io_interface::NORMAL, ); - repo.remove_package(initial.as_rc().borrow().as_package_interface()); - repo.add_package(target.clone()); + repo.remove_package(initial.clone()); + repo.add_package(target); Ok(None) } @@ -119,9 +111,9 @@ impl InstallerInterface for MetapackageInstaller { async fn uninstall( &mut self, repo: &mut dyn InstalledRepositoryInterface, - package: &PackageInterfaceHandle, + package: PackageInterfaceHandle, ) -> Result<Option<PhpMixed>> { - if !repo.has_package(package.as_rc().borrow().as_package_interface()) { + if !repo.has_package(package.clone()) { return Err(InvalidArgumentException { message: format!("Package is not installed: {}", package), code: 0, @@ -130,20 +122,17 @@ impl InstallerInterface for MetapackageInstaller { } self.io.write_error3( - &format!( - " - {}", - UninstallOperation::format(package.as_rc().borrow().as_package_interface(), false) - ), + &format!(" - {}", UninstallOperation::format(package.clone(), false)), true, io_interface::NORMAL, ); - repo.remove_package(package.as_rc().borrow().as_package_interface()); + repo.remove_package(package.clone()); Ok(None) } - fn get_install_path(&self, _package: &dyn PackageInterface) -> Option<String> { + fn get_install_path(&self, _package: PackageInterfaceHandle) -> Option<String> { None } } diff --git a/crates/shirabe/src/installer/noop_installer.rs b/crates/shirabe/src/installer/noop_installer.rs index 12e7e95..dad5231 100644 --- a/crates/shirabe/src/installer/noop_installer.rs +++ b/crates/shirabe/src/installer/noop_installer.rs @@ -1,7 +1,6 @@ //! ref: composer/src/Composer/Installer/NoopInstaller.php use crate::installer::InstallerInterface; -use crate::package::PackageInterface; use crate::package::PackageInterfaceHandle; use crate::repository::InstalledRepositoryInterface; use shirabe_php_shim::{InvalidArgumentException, PhpMixed}; @@ -18,15 +17,15 @@ impl InstallerInterface for NoopInstaller { fn is_installed( &self, repo: &dyn InstalledRepositoryInterface, - package: &dyn PackageInterface, + package: PackageInterfaceHandle, ) -> bool { - repo.has_package(package) + repo.has_package(package.clone()) } async fn download( &self, - _package: &dyn PackageInterface, - _prev_package: Option<&dyn PackageInterface>, + _package: PackageInterfaceHandle, + _prev_package: Option<PackageInterfaceHandle>, ) -> anyhow::Result<Option<PhpMixed>> { Ok(None) } @@ -34,8 +33,8 @@ impl InstallerInterface for NoopInstaller { async fn prepare( &self, _type: &str, - _package: &dyn PackageInterface, - _prev_package: Option<&dyn PackageInterface>, + _package: PackageInterfaceHandle, + _prev_package: Option<PackageInterfaceHandle>, ) -> anyhow::Result<Option<PhpMixed>> { Ok(None) } @@ -43,8 +42,8 @@ impl InstallerInterface for NoopInstaller { async fn cleanup( &self, _type: &str, - _package: &dyn PackageInterface, - _prev_package: Option<&dyn PackageInterface>, + _package: PackageInterfaceHandle, + _prev_package: Option<PackageInterfaceHandle>, ) -> anyhow::Result<Option<PhpMixed>> { Ok(None) } @@ -52,9 +51,9 @@ impl InstallerInterface for NoopInstaller { async fn install( &mut self, repo: &mut dyn InstalledRepositoryInterface, - package: &PackageInterfaceHandle, + package: PackageInterfaceHandle, ) -> anyhow::Result<Option<PhpMixed>> { - if !repo.has_package(package.as_rc().borrow().as_package_interface()) { + if !repo.has_package(package.clone()) { repo.add_package(package.clone()); } @@ -64,10 +63,10 @@ impl InstallerInterface for NoopInstaller { async fn update( &mut self, repo: &mut dyn InstalledRepositoryInterface, - initial: &PackageInterfaceHandle, - target: &PackageInterfaceHandle, + initial: PackageInterfaceHandle, + target: PackageInterfaceHandle, ) -> anyhow::Result<Option<PhpMixed>> { - if !repo.has_package(initial.as_rc().borrow().as_package_interface()) { + if !repo.has_package(initial.clone()) { return Err(InvalidArgumentException { message: format!("Package is not installed: {}", initial), code: 0, @@ -75,8 +74,8 @@ impl InstallerInterface for NoopInstaller { .into()); } - repo.remove_package(initial.as_rc().borrow().as_package_interface()); - if !repo.has_package(target.as_rc().borrow().as_package_interface()) { + repo.remove_package(initial.clone()); + if !repo.has_package(target.clone()) { repo.add_package(target.clone()); } @@ -86,28 +85,28 @@ impl InstallerInterface for NoopInstaller { async fn uninstall( &mut self, repo: &mut dyn InstalledRepositoryInterface, - package: &PackageInterfaceHandle, + package: PackageInterfaceHandle, ) -> anyhow::Result<Option<PhpMixed>> { - if !repo.has_package(package.as_rc().borrow().as_package_interface()) { + if !repo.has_package(package.clone()) { return Err(InvalidArgumentException { message: format!("Package is not installed: {}", package), code: 0, } .into()); } - repo.remove_package(package.as_rc().borrow().as_package_interface()); + repo.remove_package(package.clone()); Ok(None) } - fn get_install_path(&self, package: &dyn PackageInterface) -> Option<String> { + fn get_install_path(&self, package: PackageInterfaceHandle) -> Option<String> { let target_dir = package.get_target_dir(); let pretty_name = package.get_pretty_name(); Some(if let Some(dir) = target_dir { format!("{}/{}", pretty_name, dir) } else { - pretty_name.to_string() + pretty_name }) } } diff --git a/crates/shirabe/src/installer/plugin_installer.rs b/crates/shirabe/src/installer/plugin_installer.rs index deadcb7..38fcb0d 100644 --- a/crates/shirabe/src/installer/plugin_installer.rs +++ b/crates/shirabe/src/installer/plugin_installer.rs @@ -6,7 +6,6 @@ use crate::installer::InstallerInterface; use crate::installer::LibraryInstaller; use crate::io::IOInterface; use crate::io::IOInterfaceImmutable; -use crate::package::PackageInterface; use crate::package::PackageInterfaceHandle; use crate::plugin::PluginManager; use crate::repository::InstalledRepositoryInterface; @@ -47,7 +46,7 @@ impl PluginInstaller { &mut self, e: anyhow::Error, repo: &mut dyn InstalledRepositoryInterface, - package: &PackageInterfaceHandle, + package: PackageInterfaceHandle, ) -> Result<()> { self.inner.io.write_error(&format!( "Plugin initialization failed ({}), uninstalling plugin", @@ -72,7 +71,7 @@ impl InstallerInterface for PluginInstaller { fn is_installed( &self, repo: &dyn InstalledRepositoryInterface, - package: &dyn PackageInterface, + package: PackageInterfaceHandle, ) -> bool { self.inner.is_installed(repo, package) } @@ -80,8 +79,8 @@ impl InstallerInterface for PluginInstaller { async fn prepare( &self, r#type: &str, - package: &dyn PackageInterface, - prev_package: Option<&dyn PackageInterface>, + package: PackageInterfaceHandle, + prev_package: Option<PackageInterfaceHandle>, ) -> Result<Option<PhpMixed>> { if (r#type == "install" || r#type == "update") && !self @@ -104,8 +103,8 @@ impl InstallerInterface for PluginInstaller { async fn download( &self, - package: &dyn PackageInterface, - prev_package: Option<&dyn PackageInterface>, + package: PackageInterfaceHandle, + prev_package: Option<PackageInterfaceHandle>, ) -> Result<Option<PhpMixed>> { let extra = package.get_extra(); let class = extra.get("class").cloned().unwrap_or(PhpMixed::Null); @@ -125,7 +124,7 @@ impl InstallerInterface for PluginInstaller { async fn install( &mut self, repo: &mut dyn InstalledRepositoryInterface, - package: &PackageInterfaceHandle, + package: PackageInterfaceHandle, ) -> Result<Option<PhpMixed>> { self.inner.install(repo, package).await?; @@ -139,8 +138,8 @@ impl InstallerInterface for PluginInstaller { async fn update( &mut self, repo: &mut dyn InstalledRepositoryInterface, - initial: &PackageInterfaceHandle, - target: &PackageInterfaceHandle, + initial: PackageInterfaceHandle, + target: PackageInterfaceHandle, ) -> Result<Option<PhpMixed>> { self.inner.update(repo, initial, target).await?; @@ -155,12 +154,12 @@ impl InstallerInterface for PluginInstaller { async fn uninstall( &mut self, repo: &mut dyn InstalledRepositoryInterface, - package: &PackageInterfaceHandle, + package: PackageInterfaceHandle, ) -> Result<Option<PhpMixed>> { // TODO(plugin): uninstall package from plugin manager self.get_plugin_manager() .borrow_mut() - .uninstall_package(package.as_rc().borrow().as_package_interface()); + .uninstall_package(package.clone()); self.inner.uninstall(repo, package).await } @@ -168,13 +167,13 @@ impl InstallerInterface for PluginInstaller { async fn cleanup( &self, r#type: &str, - package: &dyn PackageInterface, - prev_package: Option<&dyn PackageInterface>, + package: PackageInterfaceHandle, + prev_package: Option<PackageInterfaceHandle>, ) -> Result<Option<PhpMixed>> { self.inner.cleanup(r#type, package, prev_package).await } - fn get_install_path(&self, package: &dyn PackageInterface) -> Option<String> { + fn get_install_path(&self, package: PackageInterfaceHandle) -> Option<String> { self.inner.get_install_path(package) } } diff --git a/crates/shirabe/src/installer/project_installer.rs b/crates/shirabe/src/installer/project_installer.rs index 129810b..6c8a279 100644 --- a/crates/shirabe/src/installer/project_installer.rs +++ b/crates/shirabe/src/installer/project_installer.rs @@ -2,7 +2,6 @@ use crate::downloader::DownloadManager; use crate::installer::InstallerInterface; -use crate::package::PackageInterface; use crate::package::PackageInterfaceHandle; use crate::repository::InstalledRepositoryInterface; use crate::util::Filesystem; @@ -39,15 +38,15 @@ impl InstallerInterface for ProjectInstaller { fn is_installed( &self, _repo: &dyn InstalledRepositoryInterface, - _package: &dyn PackageInterface, + _package: PackageInterfaceHandle, ) -> bool { false } async fn download( &self, - package: &dyn PackageInterface, - prev_package: Option<&dyn PackageInterface>, + package: PackageInterfaceHandle, + prev_package: Option<PackageInterfaceHandle>, ) -> anyhow::Result<Option<PhpMixed>> { let install_path = &self.install_path; if std::path::Path::new(install_path).exists() @@ -72,8 +71,8 @@ impl InstallerInterface for ProjectInstaller { async fn prepare( &self, r#type: &str, - package: &dyn PackageInterface, - prev_package: Option<&dyn PackageInterface>, + package: PackageInterfaceHandle, + prev_package: Option<PackageInterfaceHandle>, ) -> anyhow::Result<Option<PhpMixed>> { self.download_manager .borrow() @@ -84,8 +83,8 @@ impl InstallerInterface for ProjectInstaller { async fn cleanup( &self, r#type: &str, - package: &dyn PackageInterface, - prev_package: Option<&dyn PackageInterface>, + package: PackageInterfaceHandle, + prev_package: Option<PackageInterfaceHandle>, ) -> anyhow::Result<Option<PhpMixed>> { self.download_manager .borrow() @@ -96,22 +95,19 @@ impl InstallerInterface for ProjectInstaller { async fn install( &mut self, _repo: &mut dyn InstalledRepositoryInterface, - package: &PackageInterfaceHandle, + package: PackageInterfaceHandle, ) -> anyhow::Result<Option<PhpMixed>> { self.download_manager .borrow() - .install( - package.as_rc().borrow().as_package_interface(), - &self.install_path, - ) + .install(package, &self.install_path) .await } async fn update( &mut self, _repo: &mut dyn InstalledRepositoryInterface, - _initial: &PackageInterfaceHandle, - _target: &PackageInterfaceHandle, + _initial: PackageInterfaceHandle, + _target: PackageInterfaceHandle, ) -> anyhow::Result<Option<PhpMixed>> { Err(InvalidArgumentException { message: "not supported".to_string(), @@ -123,7 +119,7 @@ impl InstallerInterface for ProjectInstaller { async fn uninstall( &mut self, _repo: &mut dyn InstalledRepositoryInterface, - _package: &PackageInterfaceHandle, + _package: PackageInterfaceHandle, ) -> anyhow::Result<Option<PhpMixed>> { Err(InvalidArgumentException { message: "not supported".to_string(), @@ -132,7 +128,7 @@ impl InstallerInterface for ProjectInstaller { .into()) } - fn get_install_path(&self, _package: &dyn PackageInterface) -> Option<String> { + fn get_install_path(&self, _package: PackageInterfaceHandle) -> Option<String> { Some(self.install_path.clone()) } } diff --git a/crates/shirabe/src/installer/suggested_packages_reporter.rs b/crates/shirabe/src/installer/suggested_packages_reporter.rs index 8faae9c..087e1b5 100644 --- a/crates/shirabe/src/installer/suggested_packages_reporter.rs +++ b/crates/shirabe/src/installer/suggested_packages_reporter.rs @@ -2,7 +2,7 @@ use crate::io::IOInterface; use crate::io::IOInterfaceImmutable; -use crate::package::PackageInterface; +use crate::package::PackageInterfaceHandle; use crate::repository::InstalledRepository; use crate::repository::RepositoryInterface; use indexmap::IndexMap; @@ -41,8 +41,8 @@ impl SuggestedPackagesReporter { self } - pub fn add_suggestions_from_package(&mut self, package: &dyn PackageInterface) -> &mut Self { - let source = package.get_pretty_name().to_string(); + pub fn add_suggestions_from_package(&mut self, package: PackageInterfaceHandle) -> &mut Self { + let source = package.get_pretty_name(); for (target, reason) in package.get_suggests() { self.add_package(source.clone(), target.clone(), reason.clone()); } @@ -54,9 +54,10 @@ impl SuggestedPackagesReporter { &self, mode: i64, installed_repo: Option<&InstalledRepository>, - only_dependents_of: Option<&dyn PackageInterface>, + only_dependents_of: Option<PackageInterfaceHandle>, ) { - let suggested_packages = self.get_filtered_suggestions(installed_repo, only_dependents_of); + let suggested_packages = + self.get_filtered_suggestions(installed_repo, only_dependents_of.clone()); let mut suggesters: IndexMap<String, IndexMap<String, String>> = IndexMap::new(); let mut suggested: IndexMap<String, IndexMap<String, String>> = IndexMap::new(); @@ -142,7 +143,7 @@ impl SuggestedPackagesReporter { pub fn output_minimalistic( &self, installed_repo: Option<&InstalledRepository>, - only_dependents_of: Option<&dyn PackageInterface>, + only_dependents_of: Option<PackageInterfaceHandle>, ) { let suggested_packages = self.get_filtered_suggestions(installed_repo, only_dependents_of); if !suggested_packages.is_empty() { @@ -156,7 +157,7 @@ impl SuggestedPackagesReporter { fn get_filtered_suggestions( &self, installed_repo: Option<&InstalledRepository>, - only_dependents_of: Option<&dyn PackageInterface>, + only_dependents_of: Option<PackageInterfaceHandle>, ) -> Vec<IndexMap<String, String>> { let suggested_packages = self.get_packages(); let mut installed_names: Vec<String> = Vec::new(); @@ -168,13 +169,14 @@ impl SuggestedPackagesReporter { let mut source_filter: Vec<String> = Vec::new(); if let Some(only_dependents_of) = only_dependents_of { - source_filter = only_dependents_of - .get_requires() + let requires = only_dependents_of.get_requires(); + let dev_requires = only_dependents_of.get_dev_requires(); + source_filter = requires .values() - .chain(only_dependents_of.get_dev_requires().values()) + .chain(dev_requires.values()) .map(|link| link.get_target().to_string()) .collect(); - source_filter.push(only_dependents_of.get_name().to_string()); + source_filter.push(only_dependents_of.get_name()); } let mut suggestions: Vec<IndexMap<String, String>> = Vec::new(); diff --git a/crates/shirabe/src/package/alias_package.rs b/crates/shirabe/src/package/alias_package.rs index 5558337..997685b 100644 --- a/crates/shirabe/src/package/alias_package.rs +++ b/crates/shirabe/src/package/alias_package.rs @@ -236,10 +236,6 @@ impl std::fmt::Display for AliasPackage { } impl PackageInterface for AliasPackage { - fn as_any(&self) -> &dyn std::any::Any { - self - } - fn get_name(&self) -> &str { // PHP delegates to aliasOf; the local name mirrors aliasOf->getName(), // so it is returned here to avoid borrowing across the shared handle. diff --git a/crates/shirabe/src/package/archiver/archive_manager.rs b/crates/shirabe/src/package/archiver/archive_manager.rs index e198a03..a4169ef 100644 --- a/crates/shirabe/src/package/archiver/archive_manager.rs +++ b/crates/shirabe/src/package/archiver/archive_manager.rs @@ -10,6 +10,7 @@ use shirabe_php_shim::{ use crate::downloader::DownloadManager; use crate::json::JsonFile; use crate::package::CompletePackageInterface; +use crate::package::CompletePackageInterfaceHandle; use crate::package::RootPackageInterface; use crate::package::archiver::ArchiverInterface; use crate::package::archiver::PharArchiver; @@ -57,11 +58,11 @@ impl ArchiveManager { pub fn get_package_filename_parts( &self, - package: &dyn CompletePackageInterface, + package: CompletePackageInterfaceHandle, ) -> anyhow::Result<IndexMap<String, String>> { let base_name = match package.get_archive_name() { Some(name) => name.to_string(), - None => Preg::replace("#[^a-z0-9-_]#i", "-", package.get_name())?, + None => Preg::replace("#[^a-z0-9-_]#i", "-", &package.get_name())?, }; let mut parts: IndexMap<String, String> = IndexMap::new(); @@ -89,7 +90,7 @@ impl ArchiveManager { } if let Some(source_reference) = package.get_source_reference() { - let hash = shirabe_php_shim::hash("sha1", source_reference); + let hash = shirabe_php_shim::hash("sha1", &source_reference); parts.insert("source_reference".to_string(), hash[..6].to_string()); } @@ -108,7 +109,7 @@ impl ArchiveManager { pub fn get_package_filename( &self, - package: &dyn CompletePackageInterface, + package: CompletePackageInterfaceHandle, ) -> anyhow::Result<String> { let parts = self.get_package_filename_parts(package)?; Ok(self.get_package_filename_from_parts(&parts)) @@ -116,7 +117,7 @@ impl ArchiveManager { pub fn archive( &mut self, - package: &mut dyn CompletePackageInterface, + package: CompletePackageInterfaceHandle, format: String, target_dir: String, file_name: Option<String>, @@ -152,7 +153,7 @@ impl ArchiveManager { let mut filesystem = Filesystem::new(None); - let is_root = package.as_root_package_interface().is_some(); + let is_root = package.as_rc().borrow().is_root(); let source_path: String; if is_root { @@ -169,7 +170,7 @@ impl ArchiveManager { Some(Box::pin(async { self.download_manager .borrow() - .download(package, &source_path, None) + .download(package.clone().into(), &source_path, None) .await .map(|_| ()) })), @@ -179,7 +180,7 @@ impl ArchiveManager { Some(Box::pin(async { self.download_manager .borrow() - .install(package, &source_path) + .install(package.clone().into(), &source_path) .await .map(|_| ()) })), @@ -219,7 +220,7 @@ impl ArchiveManager { let supported_formats = self.get_supported_formats(); let package_name_parts = match file_name { - None => self.get_package_filename_parts(package)?, + None => self.get_package_filename_parts(package.clone())?, Some(f) => { let mut parts = IndexMap::new(); parts.insert("base".to_string(), f); diff --git a/crates/shirabe/src/package/complete_package.rs b/crates/shirabe/src/package/complete_package.rs index dee84da..b0adf52 100644 --- a/crates/shirabe/src/package/complete_package.rs +++ b/crates/shirabe/src/package/complete_package.rs @@ -153,10 +153,6 @@ impl CompletePackageInterface for CompletePackage { } impl PackageInterface for CompletePackage { - fn as_any(&self) -> &dyn std::any::Any { - self - } - fn get_name(&self) -> &str { todo!() } diff --git a/crates/shirabe/src/package/dumper/array_dumper.rs b/crates/shirabe/src/package/dumper/array_dumper.rs index 4bd9b56..3d3b27a 100644 --- a/crates/shirabe/src/package/dumper/array_dumper.rs +++ b/crates/shirabe/src/package/dumper/array_dumper.rs @@ -3,11 +3,7 @@ use indexmap::IndexMap; use shirabe_php_shim::PhpMixed; -use crate::package::CompletePackage; -use crate::package::CompletePackageInterface; -use crate::package::PackageInterface; -use crate::package::RootPackage; -use crate::package::RootPackageInterface; +use crate::package::PackageInterfaceHandle; use crate::package::SUPPORTED_LINK_TYPES; #[derive(Debug)] @@ -18,7 +14,7 @@ impl ArrayDumper { Self } - pub fn dump(&self, package: &dyn PackageInterface) -> IndexMap<String, PhpMixed> { + pub fn dump(&self, package: PackageInterfaceHandle) -> IndexMap<String, PhpMixed> { let mut data: IndexMap<String, PhpMixed> = IndexMap::new(); data.insert( "name".to_string(), @@ -49,7 +45,7 @@ impl ArrayDumper { source.insert( "url".to_string(), Box::new(PhpMixed::String( - package.get_source_url().unwrap_or("").to_string(), + package.get_source_url().unwrap_or_default(), )), ); if let Some(reference) = package.get_source_reference() { @@ -90,9 +86,7 @@ impl ArrayDumper { ); dist.insert( "url".to_string(), - Box::new(PhpMixed::String( - package.get_dist_url().unwrap_or("").to_string(), - )), + Box::new(PhpMixed::String(package.get_dist_url().unwrap_or_default())), ); if let Some(reference) = package.get_dist_reference() { dist.insert( @@ -134,7 +128,7 @@ impl ArrayDumper { for (type_name, opts) in SUPPORTED_LINK_TYPES.iter() { // TODO(phase-b): PackageInterface needs get_links_by_method to mimic PHP magic call let links: Vec<crate::package::Link> = Vec::new(); - let _ = (&opts.method, package); + let _ = (&opts.method, &package); if links.is_empty() { continue; } @@ -262,7 +256,7 @@ impl ArrayDumper { ); } - if let Some(complete_pkg) = package.as_any().downcast_ref::<CompletePackage>() { + if let Some(complete_pkg) = package.as_complete() { if let Some(archive_name) = complete_pkg.get_archive_name() { let entry = data .entry("archive".to_string()) @@ -423,7 +417,7 @@ impl ArrayDumper { } } - if let Some(root_pkg) = package.as_any().downcast_ref::<RootPackage>() { + if let Some(root_pkg) = package.as_root() { let minimum_stability = root_pkg.get_minimum_stability(); if !minimum_stability.is_empty() { data.insert( diff --git a/crates/shirabe/src/package/handle.rs b/crates/shirabe/src/package/handle.rs index e1f0570..931e196 100644 --- a/crates/shirabe/src/package/handle.rs +++ b/crates/shirabe/src/package/handle.rs @@ -142,9 +142,6 @@ impl AnyPackage { macro_rules! delegate_package_interface_to_inner { ($Type:ty, $field:ident) => { impl crate::package::PackageInterface for $Type { - fn as_any(&self) -> &dyn std::any::Any { - self - } fn get_name(&self) -> &str { self.$field.get_name() } diff --git a/crates/shirabe/src/package/link.rs b/crates/shirabe/src/package/link.rs index d606c63..13bd66b 100644 --- a/crates/shirabe/src/package/link.rs +++ b/crates/shirabe/src/package/link.rs @@ -3,7 +3,7 @@ use shirabe_php_shim::UnexpectedValueException; use shirabe_semver::constraint::AnyConstraint; -use crate::package::PackageInterface; +use crate::package::PackageInterfaceHandle; pub struct Link { pub(crate) source: String, @@ -121,7 +121,7 @@ impl Link { ) } - pub fn get_pretty_string(&self, source_package: &dyn PackageInterface) -> String { + pub fn get_pretty_string(&self, source_package: PackageInterfaceHandle) -> String { format!( "{} {} {} {}", source_package.get_pretty_string(), diff --git a/crates/shirabe/src/package/locker.rs b/crates/shirabe/src/package/locker.rs index 8ba2cc2..e5eed78 100644 --- a/crates/shirabe/src/package/locker.rs +++ b/crates/shirabe/src/package/locker.rs @@ -20,7 +20,7 @@ use crate::package::CompleteAliasPackage; use crate::package::Link; use crate::package::PackageInterface; use crate::package::PackageInterfaceHandle; -use crate::package::RootPackageInterface; +use crate::package::RootPackageInterfaceHandle; use crate::package::dumper::ArrayDumper; use crate::package::loader::ArrayLoader; use crate::package::loader::LoaderInterface; @@ -766,9 +766,7 @@ impl Locker { .into()); } - let mut spec = self - .dumper - .dump(package.as_rc().borrow().as_package_interface()); + let mut spec = self.dumper.dump(package.clone()); spec.shift_remove("version_normalized"); // always move time to the end of the package definition @@ -778,8 +776,7 @@ impl Locker { && package.get_installation_source() == Some("source".to_string()) { // use the exact commit time of the current reference if it's a dev package - let pkg_time = - self.get_package_time(package.as_rc().borrow().as_package_interface())?; + let pkg_time = self.get_package_time(package.clone())?; pkg_time.map(PhpMixed::String).or(time) } else { time @@ -823,7 +820,7 @@ impl Locker { } /// Returns the packages's datetime for its source reference. - fn get_package_time(&mut self, package: &dyn PackageInterface) -> Result<Option<String>> { + fn get_package_time(&mut self, package: PackageInterfaceHandle) -> Result<Option<String>> { if !function_exists("proc_open") { return Ok(None); } @@ -831,7 +828,7 @@ impl Locker { let path = self .installation_manager .borrow_mut() - .get_install_path(package); + .get_install_path(package.clone()); if path.is_none() { return Ok(None); } @@ -841,7 +838,7 @@ impl Locker { if path.is_some() && in_array( - PhpMixed::String(source_type.unwrap_or("").to_string()), + PhpMixed::String(source_type.clone().unwrap_or_default()), &PhpMixed::List(vec![ Box::new(PhpMixed::String("git".to_string())), Box::new(PhpMixed::String("hg".to_string())), @@ -852,9 +849,8 @@ impl Locker { let source_ref = package .get_source_reference() .or_else(|| package.get_dist_reference()) - .unwrap_or("") - .to_string(); - match source_type.unwrap_or("") { + .unwrap_or_default(); + match source_type.as_deref().unwrap_or("") { "git" => { GitUtil::clean_env(&self.process); @@ -934,7 +930,7 @@ impl Locker { /// @return array<string> pub fn get_missing_requirement_info( &mut self, - package: &dyn RootPackageInterface, + package: RootPackageInterfaceHandle, include_dev: bool, ) -> Result<Vec<String>> { let mut missing_requirement_info: Vec<String> = vec![]; diff --git a/crates/shirabe/src/package/package.rs b/crates/shirabe/src/package/package.rs index da8451e..92836a2 100644 --- a/crates/shirabe/src/package/package.rs +++ b/crates/shirabe/src/package/package.rs @@ -579,9 +579,6 @@ impl std::fmt::Display for Package { } impl PackageInterface for Package { - fn as_any(&self) -> &dyn std::any::Any { - self - } fn get_name(&self) -> &str { todo!() } diff --git a/crates/shirabe/src/package/package_interface.rs b/crates/shirabe/src/package/package_interface.rs index 97aac26..0ec6e26 100644 --- a/crates/shirabe/src/package/package_interface.rs +++ b/crates/shirabe/src/package/package_interface.rs @@ -15,8 +15,6 @@ use crate::repository::RepositoryInterface; /// @phpstan-type DevAutoloadRules array{psr-0?: array<string, string|string[]>, psr-4?: array<string, string|string[]>, classmap?: list<string>, files?: list<string>} /// @phpstan-type PhpExtConfig array{extension-name?: string, priority?: int, support-zts?: bool, support-nts?: bool, build-path?: string|null, download-url-method?: string|list<string>, os-families?: non-empty-list<non-empty-string>, os-families-exclude?: non-empty-list<non-empty-string>, configure-options?: list<array{name: string, description?: string}>} pub trait PackageInterface: std::fmt::Display + std::fmt::Debug { - fn as_any(&self) -> &dyn std::any::Any; - /// Returns the package's name without version info, thus not a unique identifier /// /// @return string package name diff --git a/crates/shirabe/src/package/root_package.rs b/crates/shirabe/src/package/root_package.rs index b0fdf26..df676ff 100644 --- a/crates/shirabe/src/package/root_package.rs +++ b/crates/shirabe/src/package/root_package.rs @@ -234,10 +234,6 @@ impl std::fmt::Display for RootPackage { } impl PackageInterface for RootPackage { - fn as_any(&self) -> &dyn std::any::Any { - self - } - fn get_name(&self) -> &str { todo!() } diff --git a/crates/shirabe/src/package/version/version_bumper.rs b/crates/shirabe/src/package/version/version_bumper.rs index 8cc4b5d..e54ad10 100644 --- a/crates/shirabe/src/package/version/version_bumper.rs +++ b/crates/shirabe/src/package/version/version_bumper.rs @@ -1,6 +1,6 @@ //! ref: composer/src/Composer/Package/Version/VersionBumper.php -use crate::package::PackageInterface; +use crate::package::PackageInterfaceHandle; use crate::package::dumper::ArrayDumper; use crate::package::loader::ArrayLoader; use crate::package::version::VersionParser; @@ -18,7 +18,7 @@ impl VersionBumper { pub fn bump_requirement( &self, constraint: &AnyConstraint, - package: &dyn PackageInterface, + package: PackageInterfaceHandle, ) -> Result<String> { let parser = VersionParser::new(); let pretty_constraint = constraint.get_pretty_string(); @@ -33,7 +33,7 @@ impl VersionBumper { let _ = &parser; let loader = ArrayLoader::new(None, false); let dumper = ArrayDumper::new(); - let dumped = dumper.dump(package); + let dumped = dumper.dump(package.clone()); let extra = loader.get_branch_alias(&dumped)?; if extra.is_none() || extra.as_deref() == Some(VersionParser::DEFAULT_BRANCH_ALIAS) { diff --git a/crates/shirabe/src/package/version/version_selector.rs b/crates/shirabe/src/package/version/version_selector.rs index 28b9277..99b459e 100644 --- a/crates/shirabe/src/package/version/version_selector.rs +++ b/crates/shirabe/src/package/version/version_selector.rs @@ -16,7 +16,7 @@ use crate::filter::platform_requirement_filter::IgnoreListPlatformRequirementFil use crate::filter::platform_requirement_filter::PlatformRequirementFilterFactory; use crate::filter::platform_requirement_filter::PlatformRequirementFilterInterface; use crate::io::IOInterface; -use crate::package::PackageInterface; +use crate::package::PackageInterfaceHandle; use crate::package::base_package; use crate::package::dumper::ArrayDumper; use crate::package::loader::ArrayLoader; @@ -252,14 +252,15 @@ impl VersionSelector { pub fn find_recommended_require_version( &mut self, - package: &dyn PackageInterface, + package: PackageInterfaceHandle, ) -> anyhow::Result<String> { if package.get_name().starts_with("ext-") { let php_version = format!( "{}.{}.{}", PHP_MAJOR_VERSION, PHP_MINOR_VERSION, PHP_RELEASE_VERSION ); - let ext_parts: Vec<&str> = package.get_version().splitn(4, '.').collect(); + let package_version = package.get_version(); + let ext_parts: Vec<&str> = package_version.splitn(4, '.').collect(); let ext_version = ext_parts[..3.min(ext_parts.len())].join("."); if php_version == ext_version { return Ok("*".to_string()); @@ -270,14 +271,14 @@ impl VersionSelector { if !package.is_dev() { return self.transform_version( &version, - package.get_pretty_version(), - package.get_stability(), + &package.get_pretty_version(), + &package.get_stability(), ); } let loader = ArrayLoader::new(Some(self.get_parser().clone()), false); let dumper = ArrayDumper::new(); - let extra = loader.get_branch_alias(&dumper.dump(package))?; + let extra = loader.get_branch_alias(&dumper.dump(package.clone()))?; if let Some(extra) = extra { if extra != VersionParser::DEFAULT_BRANCH_ALIAS { let new_extra = diff --git a/crates/shirabe/src/plugin/plugin_manager.rs b/crates/shirabe/src/plugin/plugin_manager.rs index e2c39af..e2528ff 100644 --- a/crates/shirabe/src/plugin/plugin_manager.rs +++ b/crates/shirabe/src/plugin/plugin_manager.rs @@ -26,9 +26,8 @@ use crate::io::IOInterfaceImmutable; use crate::package::CompletePackage; use crate::package::Link; use crate::package::Locker; -use crate::package::PackageInterface; use crate::package::PackageInterfaceHandle; -use crate::package::RootPackageInterface; +use crate::package::RootPackageInterfaceHandle; use crate::package::base_package::{self, BasePackage}; use crate::package::version::VersionParser; use crate::plugin::Capable; @@ -140,17 +139,7 @@ impl PluginManager { // The root package borrow is also tied to `self.composer`; clone the package handle // (shared Rc) for the same reason as above. let root_package = self.composer_full().borrow().get_package().clone(); - self.load_repository( - &*repo, - false, - Some( - root_package - .as_rc() - .borrow() - .as_root_package_interface() - .unwrap(), - ), - )?; + self.load_repository(&*repo, false, Some(root_package))?; } if self.global_composer.is_some() && !self.are_plugins_disabled("global") { @@ -216,7 +205,7 @@ impl PluginManager { /// Register a plugin package, activate it etc. pub fn register_package( &mut self, - package: &dyn PackageInterface, + package: PackageInterfaceHandle, fail_on_missing_classes: bool, is_global_plugin: bool, ) -> anyhow::Result<()> { @@ -272,8 +261,8 @@ impl PluginManager { } if package.get_name() == "symfony/flex" - && Preg::is_match3("{^[0-9.]+$}", package.get_version(), None).unwrap_or(false) - && version_compare(package.get_version(), "1.9.8", "<") + && Preg::is_match3("{^[0-9.]+$}", &package.get_version(), None).unwrap_or(false) + && version_compare(&package.get_version(), "1.9.8", "<") { self.io.write_error(&format!("<warning>The \"{}\" plugin {}was skipped because it is not compatible with Composer 2+. Make sure to update it to version 1.9.8 or greater.</warning>", package.get_name(), @@ -288,7 +277,7 @@ impl PluginManager { .get("plugin-optional") .map(|v| v.as_bool() == Some(true)) .unwrap_or(false); - if !self.is_plugin_allowed(package.get_name(), is_global_plugin, plugin_optional, true)? { + if !self.is_plugin_allowed(&package.get_name(), is_global_plugin, plugin_optional, true)? { self.io.write_error(&format!( "Skipped loading \"{}\" {}as it is not in config.allow-plugins", package.get_name(), @@ -306,7 +295,7 @@ impl PluginManager { // The remainder of the function is mirrored as references but performs no actual loading. let _old_installer_plugin = package.get_type() == "composer-installer"; - if self.registered_plugins.contains_key(package.get_name()) { + if self.registered_plugins.contains_key(&package.get_name()) { return Ok(()); } @@ -354,15 +343,15 @@ impl PluginManager { } /// Deactivates a plugin package - pub fn deactivate_package(&mut self, package: &dyn PackageInterface) { + pub fn deactivate_package(&mut self, package: PackageInterfaceHandle) { // TODO(plugin): deactivation flow - if !self.registered_plugins.contains_key(package.get_name()) { + if !self.registered_plugins.contains_key(&package.get_name()) { return; } let plugins = self .registered_plugins - .shift_remove(package.get_name()) + .shift_remove(&package.get_name()) .unwrap_or_default(); for plugin in plugins { match plugin { @@ -381,15 +370,15 @@ impl PluginManager { } /// Uninstall a plugin package - pub fn uninstall_package(&mut self, package: &dyn PackageInterface) { + pub fn uninstall_package(&mut self, package: PackageInterfaceHandle) { // TODO(plugin): uninstall flow - if !self.registered_plugins.contains_key(package.get_name()) { + if !self.registered_plugins.contains_key(&package.get_name()) { return; } let plugins = self .registered_plugins - .shift_remove(package.get_name()) + .shift_remove(&package.get_name()) .unwrap_or_default(); for plugin in plugins { match plugin { @@ -418,7 +407,7 @@ impl PluginManager { &mut self, mut plugin: Box<dyn PluginInterface>, is_global_plugin: bool, - source_package: Option<&dyn PackageInterface>, + source_package: Option<PackageInterfaceHandle>, ) -> anyhow::Result<()> { // TODO(plugin): plugin activation if self.are_plugins_disabled(if is_global_plugin { "global" } else { "local" }) { @@ -431,13 +420,13 @@ impl PluginManager { E_USER_DEPRECATED, ); } else { - let sp = source_package.unwrap(); + let sp = source_package.as_ref().unwrap(); let plugin_optional = sp .get_extra() .get("plugin-optional") .map(|v| v.as_bool() == Some(true)) .unwrap_or(false); - if !self.is_plugin_allowed(sp.get_name(), is_global_plugin, plugin_optional, true)? { + if !self.is_plugin_allowed(&sp.get_name(), is_global_plugin, plugin_optional, true)? { self.io.write_error(&format!( "Skipped loading \"{} from {}\" {} as it is not in config.allow-plugins", get_class_obj(&*plugin), @@ -453,7 +442,7 @@ impl PluginManager { } let mut details: Vec<String> = vec![]; - if let Some(sp) = source_package { + if let Some(sp) = source_package.as_ref() { details.push(format!("from {}", sp.get_name())); } if is_global_plugin || self.running_in_global_dir { @@ -515,7 +504,7 @@ impl PluginManager { &mut self, repo: &dyn RepositoryInterface, is_global_repo: bool, - root_package: Option<&dyn RootPackageInterface>, + root_package: Option<RootPackageInterfaceHandle>, ) -> anyhow::Result<()> { // TODO(plugin): repository scan for plugin packages let packages = repo.get_packages(); @@ -544,7 +533,7 @@ impl PluginManager { let bucket: Vec<crate::package::BasePackageHandle> = vec![]; RepositoryUtils::filter_required_packages( packages.as_slice(), - root_package.unwrap() as &dyn PackageInterface, + root_package.unwrap().into(), true, bucket, ) @@ -579,18 +568,10 @@ impl PluginManager { } if "composer-plugin" == package.get_type() { - self.register_package( - package.as_rc().borrow().as_package_interface(), - false, - is_global_repo, - )?; + self.register_package(package.clone(), false, is_global_repo)?; // Backward compatibility } else if "composer-installer" == package.get_type() { - self.register_package( - package.as_rc().borrow().as_package_interface(), - false, - is_global_repo, - )?; + self.register_package(package.clone(), false, is_global_repo)?; } let _ = cp; } @@ -612,10 +593,10 @@ impl PluginManager { continue; } if "composer-plugin" == package.get_type() { - self.deactivate_package(package.as_rc().borrow().as_package_interface()); + self.deactivate_package(package.clone()); // Backward compatibility } else if "composer-installer" == package.get_type() { - self.deactivate_package(package.as_rc().borrow().as_package_interface()); + self.deactivate_package(package.clone()); } } } @@ -624,7 +605,7 @@ impl PluginManager { &self, installed_repo: &InstalledRepository, mut collected: IndexMap<String, PackageInterfaceHandle>, - package: &dyn PackageInterface, + package: PackageInterfaceHandle, ) -> IndexMap<String, PackageInterfaceHandle> { // TODO(plugin): used by registerPackage to assemble plugin dependency autoload map for (_k, require_link) in &package.get_requires() { @@ -636,7 +617,7 @@ impl PluginManager { collected = self.collect_dependencies( installed_repo, collected, - required_package.as_rc().borrow().as_package_interface(), + required_package.clone().into(), ); } } @@ -646,7 +627,11 @@ impl PluginManager { } /// Retrieves the path a package is installed to. - fn get_install_path(&mut self, package: &dyn PackageInterface, global: bool) -> Option<String> { + fn get_install_path( + &mut self, + package: PackageInterfaceHandle, + global: bool, + ) -> Option<String> { if !global { return self .composer_full() diff --git a/crates/shirabe/src/repository/array_repository.rs b/crates/shirabe/src/repository/array_repository.rs index 16f5f30..6467c14 100644 --- a/crates/shirabe/src/repository/array_repository.rs +++ b/crates/shirabe/src/repository/array_repository.rs @@ -12,7 +12,6 @@ use shirabe_semver::constraint::SimpleConstraint; use crate::package::BasePackageHandle; use crate::package::PackageHandle; -use crate::package::PackageInterface; use crate::package::PackageInterfaceHandle; use crate::package::version::StabilityFilter; use crate::package::version::VersionParser; @@ -96,7 +95,7 @@ impl ArrayRepository { } /// Removes package from repository. - pub fn remove_package(&self, package: &dyn PackageInterface) { + pub fn remove_package(&self, package: PackageInterfaceHandle) { let package_id = package.get_unique_name(); let mut packages_borrow = self.packages.borrow_mut(); @@ -367,7 +366,7 @@ impl RepositoryInterface for ArrayRepository { matches.into_values().collect() } - fn has_package(&self, package: &dyn PackageInterface) -> bool { + fn has_package(&self, package: PackageInterfaceHandle) -> bool { if self.package_map.borrow().is_none() { let mut map: IndexMap<String, BasePackageHandle> = IndexMap::new(); for repo_package in self.get_packages() { diff --git a/crates/shirabe/src/repository/composer_repository.rs b/crates/shirabe/src/repository/composer_repository.rs index d055e59..ddf8e31 100644 --- a/crates/shirabe/src/repository/composer_repository.rs +++ b/crates/shirabe/src/repository/composer_repository.rs @@ -1387,7 +1387,7 @@ impl ComposerRepository { Ok(vec![]) } - fn configure_package_transport_options(&self, package: &mut dyn PackageInterface) { + fn configure_package_transport_options(&self, package: PackageInterfaceHandle) { for url in package.get_dist_urls() { if url.starts_with(&self.base_url) { package.set_transport_options(self.options.clone()); @@ -1780,9 +1780,7 @@ impl ComposerRepository { /// Adds a new package to the repository pub fn add_package(&mut self, package: BasePackageHandle) { - self.configure_package_transport_options( - package.as_rc().borrow_mut().as_package_interface_mut(), - ); + self.configure_package_transport_options(package.clone()); self.inner.add_package(package.into()); } @@ -2762,9 +2760,7 @@ impl ComposerRepository { .collect(); package.set_dist_mirrors(Some(converted)); } - self.configure_package_transport_options( - package.as_rc().borrow_mut().as_package_interface_mut(), - ); + self.configure_package_transport_options(package.clone()); results.push(package.into()); } Ok(results) diff --git a/crates/shirabe/src/repository/composite_repository.rs b/crates/shirabe/src/repository/composite_repository.rs index 024f89a..12f1837 100644 --- a/crates/shirabe/src/repository/composite_repository.rs +++ b/crates/shirabe/src/repository/composite_repository.rs @@ -6,7 +6,6 @@ use indexmap::IndexMap; use shirabe_semver::constraint::AnyConstraint; use crate::package::BasePackageHandle; -use crate::package::PackageInterface; use crate::package::PackageInterfaceHandle; use crate::repository::{ FindPackageConstraint, LoadPackagesResult, ProviderInfo, RepositoryInterface, SearchResult, @@ -32,7 +31,7 @@ impl CompositeRepository { &self.repositories } - pub fn remove_package(&mut self, _package: &dyn PackageInterface) { + pub fn remove_package(&mut self, _package: PackageInterfaceHandle) { // TODO(phase-b): only call remove_package on WritableRepositoryInterface implementors; // requires a downcast helper such as `as_writable() -> Option<&mut dyn WritableRepositoryInterface>` on RepositoryInterface. for _repository in &mut self.repositories { @@ -67,9 +66,9 @@ impl RepositoryInterface for CompositeRepository { format!("composite repo ({})", names.join(", ")) } - fn has_package(&self, package: &dyn PackageInterface) -> bool { + fn has_package(&self, package: PackageInterfaceHandle) -> bool { for repository in &self.repositories { - if repository.has_package(package) { + if repository.has_package(package.clone()) { return true; } } diff --git a/crates/shirabe/src/repository/filesystem_repository.rs b/crates/shirabe/src/repository/filesystem_repository.rs index c8ffb7c..8232ecf 100644 --- a/crates/shirabe/src/repository/filesystem_repository.rs +++ b/crates/shirabe/src/repository/filesystem_repository.rs @@ -16,9 +16,7 @@ use shirabe_php_shim::{ use crate::installed_versions::InstalledVersions; use crate::installer::InstallationManager; use crate::json::JsonFile; -use crate::package::PackageInterface; use crate::package::PackageInterfaceHandle; -use crate::package::RootPackageInterface; use crate::package::RootPackageInterfaceHandle; use crate::package::dumper::ArrayDumper; use crate::package::loader::ArrayLoader; @@ -219,9 +217,8 @@ impl FilesystemRepository { let mut install_paths: IndexMap<String, Option<String>> = IndexMap::new(); for package in self.inner.get_canonical_packages() { - let mut pkg_array = dumper.dump(package.as_rc().borrow().as_package_interface()); - let path = installation_manager - .get_install_path(package.as_rc().borrow().as_package_interface()); + let mut pkg_array = dumper.dump(package.clone()); + let path = installation_manager.get_install_path(package.clone()); let mut install_path: Option<String> = None; if let Some(path_str) = &path { if !path_str.is_empty() { @@ -508,11 +505,7 @@ impl FilesystemRepository { "root".to_string(), PhpMixed::Array( self.dump_root_package( - current_root - .as_rc() - .borrow() - .as_root_package_interface() - .expect("current_root is a RootPackageInterface"), + current_root.clone(), install_paths, dev_mode, repo_dir, @@ -532,7 +525,7 @@ impl FilesystemRepository { } let dumped = self.dump_installed_package( - package.as_rc().borrow().as_package_interface(), + package.clone(), install_paths, repo_dir, &dev_packages, @@ -633,7 +626,7 @@ impl FilesystemRepository { /// @return array{pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev_requirement: bool} fn dump_installed_package( &self, - package: &dyn PackageInterface, + package: PackageInterfaceHandle, install_paths: &IndexMap<String, Option<String>>, repo_dir: &str, dev_packages: &PhpMixed, @@ -648,8 +641,8 @@ impl FilesystemRepository { } if reference.is_none() { // PHP: ($package->getSourceReference() ?: $package->getDistReference()) ?: null; - let source = package.get_source_reference().unwrap_or(""); - let dist = package.get_dist_reference().unwrap_or(""); + let source = package.get_source_reference().unwrap_or_default(); + let dist = package.get_dist_reference().unwrap_or_default(); let combined = if !source.is_empty() { source.to_string() } else { @@ -662,7 +655,7 @@ impl FilesystemRepository { }; } - let install_path = if package.as_root_package_interface().is_some() { + let install_path = if package.as_root().is_some() { let to = self.filesystem.borrow_mut().normalize_path( &realpath(&Platform::get_cwd(false).unwrap_or_default()).unwrap_or_default(), ); @@ -672,7 +665,7 @@ impl FilesystemRepository { .find_shortest_path(repo_dir, &to, true, false), ) } else { - install_paths.get(package.get_name()).cloned().flatten() + install_paths.get(&package.get_name()).cloned().flatten() }; let mut data: IndexMap<String, PhpMixed> = IndexMap::new(); @@ -708,7 +701,7 @@ impl FilesystemRepository { PhpMixed::Bool( dev_packages .as_array() - .map(|m| m.contains_key(package.get_name())) + .map(|m| m.contains_key(&package.get_name())) .unwrap_or(false), ), ); @@ -721,13 +714,18 @@ impl FilesystemRepository { /// @return array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool} fn dump_root_package( &self, - package: &dyn RootPackageInterface, + package: RootPackageInterfaceHandle, install_paths: &IndexMap<String, Option<String>>, dev_mode: bool, repo_dir: &str, dev_packages: &PhpMixed, ) -> IndexMap<String, PhpMixed> { - let data = self.dump_installed_package(package, install_paths, repo_dir, dev_packages); + let data = self.dump_installed_package( + package.clone().into(), + install_paths, + repo_dir, + dev_packages, + ); let mut result: IndexMap<String, PhpMixed> = IndexMap::new(); result.insert( diff --git a/crates/shirabe/src/repository/filter_repository.rs b/crates/shirabe/src/repository/filter_repository.rs index c67e4ff..2a339f5 100644 --- a/crates/shirabe/src/repository/filter_repository.rs +++ b/crates/shirabe/src/repository/filter_repository.rs @@ -1,7 +1,6 @@ //! ref: composer/src/Composer/Repository/FilterRepository.php use crate::package::BasePackageHandle; -use crate::package::PackageInterface; use crate::package::PackageInterfaceHandle; use crate::package::base_package::{self}; use crate::repository::{AdvisoryProviderInterface, SecurityAdvisoryResult}; @@ -159,7 +158,7 @@ impl shirabe_php_shim::Countable for FilterRepository { } impl RepositoryInterface for FilterRepository { - fn has_package(&self, package: &dyn PackageInterface) -> bool { + fn has_package(&self, package: PackageInterfaceHandle) -> bool { self.repo.has_package(package) } diff --git a/crates/shirabe/src/repository/installed_array_repository.rs b/crates/shirabe/src/repository/installed_array_repository.rs index f0244b6..ca2d8c7 100644 --- a/crates/shirabe/src/repository/installed_array_repository.rs +++ b/crates/shirabe/src/repository/installed_array_repository.rs @@ -5,7 +5,6 @@ use shirabe_php_shim::Countable; use shirabe_semver::constraint::AnyConstraint; use crate::package::BasePackageHandle; -use crate::package::PackageInterface; use crate::package::PackageInterfaceHandle; use crate::repository::AdvisoryProviderInterface; use crate::repository::InstalledRepositoryInterface; @@ -64,7 +63,7 @@ impl WritableRepositoryInterface for InstalledArrayRepository { fn remove_package( &mut self, - package: &dyn crate::package::PackageInterface, + package: crate::package::PackageInterfaceHandle, ) -> anyhow::Result<()> { todo!() } @@ -93,7 +92,7 @@ impl Countable for InstalledArrayRepository { } impl RepositoryInterface for InstalledArrayRepository { - fn has_package(&self, _package: &dyn PackageInterface) -> bool { + fn has_package(&self, _package: PackageInterfaceHandle) -> bool { todo!() } fn find_package( diff --git a/crates/shirabe/src/repository/installed_filesystem_repository.rs b/crates/shirabe/src/repository/installed_filesystem_repository.rs index 8a6359a..352d86f 100644 --- a/crates/shirabe/src/repository/installed_filesystem_repository.rs +++ b/crates/shirabe/src/repository/installed_filesystem_repository.rs @@ -7,7 +7,6 @@ use shirabe_semver::constraint::AnyConstraint; use crate::json::JsonFile; use crate::package::BasePackageHandle; -use crate::package::PackageInterface; use crate::package::PackageInterfaceHandle; use crate::package::RootPackageInterfaceHandle; use crate::repository::AdvisoryProviderInterface; @@ -74,7 +73,7 @@ impl WritableRepositoryInterface for InstalledFilesystemRepository { fn remove_package( &mut self, - package: &dyn crate::package::PackageInterface, + package: crate::package::PackageInterfaceHandle, ) -> anyhow::Result<()> { todo!() } @@ -103,7 +102,7 @@ impl Countable for InstalledFilesystemRepository { } impl RepositoryInterface for InstalledFilesystemRepository { - fn has_package(&self, _package: &dyn PackageInterface) -> bool { + fn has_package(&self, _package: PackageInterfaceHandle) -> bool { todo!() } fn find_package( diff --git a/crates/shirabe/src/repository/installed_repository.rs b/crates/shirabe/src/repository/installed_repository.rs index 33356e3..486d4bd 100644 --- a/crates/shirabe/src/repository/installed_repository.rs +++ b/crates/shirabe/src/repository/installed_repository.rs @@ -8,7 +8,6 @@ use shirabe_semver::constraint::SimpleConstraint; use crate::package::BasePackageHandle; use crate::package::Link; -use crate::package::PackageInterface; use crate::package::PackageInterfaceHandle; use crate::package::version::VersionParser; use crate::repository::CompositeRepository; @@ -424,7 +423,7 @@ impl RepositoryInterface for InstalledRepository { format!("installed repo ({})", names.join(", ")) } - fn has_package(&self, package: &dyn PackageInterface) -> bool { + fn has_package(&self, package: PackageInterfaceHandle) -> bool { self.inner.has_package(package) } diff --git a/crates/shirabe/src/repository/lock_array_repository.rs b/crates/shirabe/src/repository/lock_array_repository.rs index 3d00ecf..cbc8564 100644 --- a/crates/shirabe/src/repository/lock_array_repository.rs +++ b/crates/shirabe/src/repository/lock_array_repository.rs @@ -1,7 +1,6 @@ //! ref: composer/src/Composer/Repository/LockArrayRepository.php use crate::package::BasePackageHandle; -use crate::package::PackageInterface; use crate::package::PackageInterfaceHandle; use crate::repository::ArrayRepository; use crate::repository::CanonicalPackagesTrait; @@ -36,7 +35,7 @@ impl Countable for LockArrayRepository { } impl RepositoryInterface for LockArrayRepository { - fn has_package(&self, package: &dyn PackageInterface) -> bool { + fn has_package(&self, package: PackageInterfaceHandle) -> bool { self.inner.has_package(package) } diff --git a/crates/shirabe/src/repository/platform_repository.rs b/crates/shirabe/src/repository/platform_repository.rs index 31760bb..1b95ff7 100644 --- a/crates/shirabe/src/repository/platform_repository.rs +++ b/crates/shirabe/src/repository/platform_repository.rs @@ -1903,7 +1903,7 @@ impl PlatformRepository { // ---- helpers ---- - fn is_complete_package(_package: &dyn PackageInterface) -> bool { + fn is_complete_package(_package: PackageInterfaceHandle) -> bool { // TODO(phase-b): use Any-style downcasting once the trait carries it. true } @@ -1950,7 +1950,7 @@ impl shirabe_php_shim::Countable for PlatformRepository { } impl crate::repository::RepositoryInterface for PlatformRepository { - fn has_package(&self, package: &dyn PackageInterface) -> bool { + fn has_package(&self, package: PackageInterfaceHandle) -> bool { self.inner.has_package(package) } diff --git a/crates/shirabe/src/repository/repository_interface.rs b/crates/shirabe/src/repository/repository_interface.rs index 9cadc48..316f509 100644 --- a/crates/shirabe/src/repository/repository_interface.rs +++ b/crates/shirabe/src/repository/repository_interface.rs @@ -1,7 +1,6 @@ //! ref: composer/src/Composer/Repository/RepositoryInterface.php use crate::package::BasePackageHandle; -use crate::package::PackageInterface; use crate::package::PackageInterfaceHandle; use crate::repository::AdvisoryProviderInterface; use indexmap::IndexMap; @@ -54,7 +53,7 @@ pub const SEARCH_NAME: i64 = 1; pub const SEARCH_VENDOR: i64 = 2; pub trait RepositoryInterface: Countable + std::fmt::Debug { - fn has_package(&self, package: &dyn PackageInterface) -> bool; + fn has_package(&self, package: PackageInterfaceHandle) -> bool; fn find_package( &self, diff --git a/crates/shirabe/src/repository/repository_utils.rs b/crates/shirabe/src/repository/repository_utils.rs index 51b8673..667cea2 100644 --- a/crates/shirabe/src/repository/repository_utils.rs +++ b/crates/shirabe/src/repository/repository_utils.rs @@ -1,7 +1,6 @@ //! ref: composer/src/Composer/Repository/RepositoryUtils.php use crate::package::Link; -use crate::package::PackageInterface; use crate::repository::CompositeRepository; use crate::repository::FilterRepository; use crate::repository::RepositoryInterface; @@ -13,7 +12,7 @@ pub struct RepositoryUtils; impl RepositoryUtils { pub fn filter_required_packages( packages: &[crate::package::BasePackageHandle], - requirer: &dyn PackageInterface, + requirer: crate::package::PackageInterfaceHandle, include_require_dev: bool, mut bucket: Vec<crate::package::BasePackageHandle>, ) -> Vec<crate::package::BasePackageHandle> { diff --git a/crates/shirabe/src/repository/root_package_repository.rs b/crates/shirabe/src/repository/root_package_repository.rs index 71cd270..cb01a7c 100644 --- a/crates/shirabe/src/repository/root_package_repository.rs +++ b/crates/shirabe/src/repository/root_package_repository.rs @@ -1,7 +1,6 @@ //! ref: composer/src/Composer/Repository/RootPackageRepository.php use crate::package::BasePackageHandle; -use crate::package::PackageInterface; use crate::package::PackageInterfaceHandle; use crate::package::RootPackageInterfaceHandle; use crate::repository::ArrayRepository; @@ -32,7 +31,7 @@ impl shirabe_php_shim::Countable for RootPackageRepository { } impl RepositoryInterface for RootPackageRepository { - fn has_package(&self, package: &dyn PackageInterface) -> bool { + fn has_package(&self, package: PackageInterfaceHandle) -> bool { self.inner.has_package(package) } diff --git a/crates/shirabe/src/repository/writable_array_repository.rs b/crates/shirabe/src/repository/writable_array_repository.rs index ebe70c3..282f3c0 100644 --- a/crates/shirabe/src/repository/writable_array_repository.rs +++ b/crates/shirabe/src/repository/writable_array_repository.rs @@ -52,7 +52,10 @@ impl WritableArrayRepository { self.inner.add_package(package) } - pub fn remove_package(&mut self, package: &dyn crate::package::PackageInterface) -> Result<()> { + pub fn remove_package( + &mut self, + package: crate::package::PackageInterfaceHandle, + ) -> Result<()> { let _ = package; // TODO(phase-b): delegate to ArrayRepository once it implements remove_package Ok(()) diff --git a/crates/shirabe/src/repository/writable_repository_interface.rs b/crates/shirabe/src/repository/writable_repository_interface.rs index b5b1e35..abbcbe7 100644 --- a/crates/shirabe/src/repository/writable_repository_interface.rs +++ b/crates/shirabe/src/repository/writable_repository_interface.rs @@ -1,7 +1,6 @@ //! ref: composer/src/Composer/Repository/WritableRepositoryInterface.php use crate::installer::InstallationManager; -use crate::package::PackageInterface; use crate::package::PackageInterfaceHandle; use crate::repository::RepositoryInterface; use anyhow::Result; @@ -11,7 +10,7 @@ pub trait WritableRepositoryInterface: RepositoryInterface { fn add_package(&mut self, package: PackageInterfaceHandle) -> Result<()>; - fn remove_package(&mut self, package: &dyn PackageInterface) -> Result<()>; + fn remove_package(&mut self, package: PackageInterfaceHandle) -> Result<()>; fn get_canonical_packages(&self) -> Vec<PackageInterfaceHandle>; diff --git a/crates/shirabe/src/util/package_info.rs b/crates/shirabe/src/util/package_info.rs index 6660404..df34951 100644 --- a/crates/shirabe/src/util/package_info.rs +++ b/crates/shirabe/src/util/package_info.rs @@ -1,13 +1,12 @@ //! ref: composer/src/Composer/Util/PackageInfo.php -use crate::package::CompletePackageInterface; -use crate::package::PackageInterface; +use crate::package::PackageInterfaceHandle; pub struct PackageInfo; impl PackageInfo { - pub fn get_view_source_url(package: &dyn PackageInterface) -> Option<String> { - if let Some(complete) = package.as_complete_package_interface() { + pub fn get_view_source_url(package: PackageInterfaceHandle) -> Option<String> { + if let Some(complete) = package.as_complete() { let support = complete.get_support(); if let Some(source) = support.get("source") { if source != "" { @@ -16,14 +15,14 @@ impl PackageInfo { } } - package.get_source_url().map(|s| s.to_string()) + package.get_source_url() } - pub fn get_view_source_or_homepage_url(package: &dyn PackageInterface) -> Option<String> { - let url = Self::get_view_source_url(package).or_else(|| { + pub fn get_view_source_or_homepage_url(package: PackageInterfaceHandle) -> Option<String> { + let url = Self::get_view_source_url(package.clone()).or_else(|| { package - .as_complete_package_interface() - .and_then(|complete| complete.get_homepage().map(|s| s.to_string())) + .as_complete() + .and_then(|complete| complete.get_homepage()) }); if url.as_deref() == Some("") { diff --git a/crates/shirabe/src/util/sync_helper.rs b/crates/shirabe/src/util/sync_helper.rs index 7388b96..4181b23 100644 --- a/crates/shirabe/src/util/sync_helper.rs +++ b/crates/shirabe/src/util/sync_helper.rs @@ -2,7 +2,7 @@ use crate::downloader::DownloadManager; use crate::downloader::DownloaderInterface; -use crate::package::PackageInterface; +use crate::package::PackageInterfaceHandle; use crate::util::r#loop::Loop; use anyhow::Result; use shirabe_php_shim::PhpMixed; @@ -15,9 +15,9 @@ pub enum DownloaderOrManager<'a> { impl<'a> DownloaderOrManager<'a> { async fn download( &self, - package: &dyn PackageInterface, + package: PackageInterfaceHandle, path: &str, - prev_package: Option<&dyn PackageInterface>, + prev_package: Option<PackageInterfaceHandle>, ) -> Result<Option<PhpMixed>> { match self { Self::Interface(d) => d.download3(package, path, prev_package).await, @@ -28,9 +28,9 @@ impl<'a> DownloaderOrManager<'a> { async fn prepare( &self, r#type: &str, - package: &dyn PackageInterface, + package: PackageInterfaceHandle, path: &str, - prev_package: Option<&dyn PackageInterface>, + prev_package: Option<PackageInterfaceHandle>, ) -> Result<Option<PhpMixed>> { match self { Self::Interface(d) => d.prepare(r#type, package, path, prev_package).await, @@ -44,7 +44,7 @@ impl<'a> DownloaderOrManager<'a> { async fn install( &self, - package: &dyn PackageInterface, + package: PackageInterfaceHandle, path: &str, ) -> Result<Option<PhpMixed>> { match self { @@ -55,8 +55,8 @@ impl<'a> DownloaderOrManager<'a> { async fn update( &self, - package: &dyn PackageInterface, - prev_package: &dyn PackageInterface, + package: PackageInterfaceHandle, + prev_package: PackageInterfaceHandle, path: &str, ) -> Result<Option<PhpMixed>> { match self { @@ -68,9 +68,9 @@ impl<'a> DownloaderOrManager<'a> { async fn cleanup( &self, r#type: &str, - package: &dyn PackageInterface, + package: PackageInterfaceHandle, path: &str, - prev_package: Option<&dyn PackageInterface>, + prev_package: Option<PackageInterfaceHandle>, ) -> Result<Option<PhpMixed>> { match self { Self::Interface(d) => d.cleanup(r#type, package, path, prev_package).await, @@ -90,8 +90,8 @@ impl SyncHelper { r#loop: &std::rc::Rc<std::cell::RefCell<Loop>>, downloader: DownloaderOrManager<'_>, path: String, - package: &dyn PackageInterface, - prev_package: Option<&dyn PackageInterface>, + package: PackageInterfaceHandle, + prev_package: Option<PackageInterfaceHandle>, ) -> Result<()> { let r#type = if prev_package.is_some() { "update" @@ -104,7 +104,7 @@ impl SyncHelper { r#loop, Some(Box::pin(async { downloader - .download(package, &path, prev_package) + .download(package.clone(), &path, prev_package.clone()) .await .map(|_| ()) })), @@ -113,17 +113,20 @@ impl SyncHelper { r#loop, Some(Box::pin(async { downloader - .prepare(r#type, package, &path, prev_package) + .prepare(r#type, package.clone(), &path, prev_package.clone()) .await .map(|_| ()) })), )?; if r#type == "update" { - if let Some(prev) = prev_package { + if let Some(prev) = &prev_package { Self::r#await( r#loop, Some(Box::pin(async { - downloader.update(package, prev, &path).await.map(|_| ()) + downloader + .update(package.clone(), prev.clone(), &path) + .await + .map(|_| ()) })), )?; } @@ -131,7 +134,7 @@ impl SyncHelper { Self::r#await( r#loop, Some(Box::pin(async { - downloader.install(package, &path).await.map(|_| ()) + downloader.install(package.clone(), &path).await.map(|_| ()) })), )?; } @@ -143,7 +146,7 @@ impl SyncHelper { r#loop, Some(Box::pin(async { downloader - .cleanup(r#type, package, &path, prev_package) + .cleanup(r#type, package.clone(), &path, prev_package.clone()) .await .map(|_| ()) })), @@ -155,7 +158,7 @@ impl SyncHelper { r#loop, Some(Box::pin(async { downloader - .cleanup(r#type, package, &path, prev_package) + .cleanup(r#type, package.clone(), &path, prev_package.clone()) .await .map(|_| ()) })), |
