From cd7c3fce2472656b2a1247429751e43350976677 Mon Sep 17 00:00:00 2001 From: nsfisis Date: Wed, 19 Aug 2026 23:45:38 +0900 Subject: perf(package): hand out link maps behind Rc PackageInterface::getRequires() and friends return the array of Link objects; in PHP that is a copy-on-write array of object references, so a caller pays nothing to look at it. The port returned IndexMap by value, so every call deep-cloned the whole map, keys and constraints included. Pool building calls these accessors once per package per candidate, which put IndexMap::clone at 13.5% of `require laravel/laravel`. Store the maps as Rc> and return a handle. Callers that mutate the map clone it explicitly at the point of mutation, matching where PHP would separate the array. Co-Authored-By: Claude Opus 5 (1M context) --- crates/shirabe/src/autoload/autoload_generator.rs | 13 ++++-- crates/shirabe/src/command/bump_command.rs | 9 ++-- .../src/command/check_platform_reqs_command.rs | 45 +++++++++--------- crates/shirabe/src/command/remove_command.rs | 10 +++- crates/shirabe/src/command/require_command.rs | 10 +++- crates/shirabe/src/command/show_command.rs | 4 +- crates/shirabe/src/command/update_command.rs | 14 +++--- .../src/dependency_resolver/pool_builder.rs | 18 ++++---- .../src/dependency_resolver/pool_optimizer.rs | 4 +- .../src/dependency_resolver/rule_set_generator.rs | 4 +- crates/shirabe/src/dependency_resolver/solver.rs | 2 +- crates/shirabe/src/installer.rs | 24 +++++----- crates/shirabe/src/package/alias_package.rs | 45 +++++++++--------- crates/shirabe/src/package/complete_package.rs | 20 ++++---- crates/shirabe/src/package/handle.rs | 42 ++++++++++++----- crates/shirabe/src/package/package.rs | 54 +++++++++++----------- crates/shirabe/src/package/package_interface.rs | 17 ++++--- crates/shirabe/src/package/root_alias_package.rs | 45 ++++++++++-------- crates/shirabe/src/package/root_package.rs | 10 ++-- .../src/package/version/version_selector.rs | 2 +- crates/shirabe/src/plugin/php_plugin_proxy.rs | 10 ++-- crates/shirabe/src/plugin/plugin_manager.rs | 4 +- .../src/repository/filesystem_repository.rs | 4 +- .../shirabe/src/repository/installed_repository.rs | 29 +++++++----- crates/shirabe/src/repository/repository_utils.rs | 9 +++- crates/shirabe/src/repository/vcs/github_driver.rs | 2 +- crates/shirabe/src/repository/vcs/gitlab_driver.rs | 2 +- crates/shirabe/src/util/package_sorter.rs | 9 +++- .../tests/repository/platform_repository_test.rs | 6 +-- 29 files changed, 266 insertions(+), 201 deletions(-) diff --git a/crates/shirabe/src/autoload/autoload_generator.rs b/crates/shirabe/src/autoload/autoload_generator.rs index 5f435566..55124467 100644 --- a/crates/shirabe/src/autoload/autoload_generator.rs +++ b/crates/shirabe/src/autoload/autoload_generator.rs @@ -1149,8 +1149,11 @@ return array( for item in package_map { let package = &item.0; - let links = array_merge_map(package.get_replaces(), package.get_provides()); - for (_k, link) in &links { + let links = array_merge_map( + (*package.get_replaces()).clone(), + (*package.get_provides()).clone(), + ); + for (_k, link) in links.iter() { if let Some(matches) = preg_match(php_regex!("{^ext-(.+)$}iD"), link.get_target()) && let Some(ext) = matches.get(1).map(str::to_string) { @@ -1169,7 +1172,7 @@ return array( continue; } - for (_k, link) in &package.get_requires() { + for (_k, link) in package.get_requires().iter() { if self .platform_requirement_filter .borrow() @@ -2028,7 +2031,7 @@ class ComposerStaticInit{} let package = &item.0; let name = package.get_name(); packages.insert(name.clone(), package.clone()); - for (_k, replace) in &package.get_replaces() { + for (_k, replace) in package.get_replaces().iter() { replaced_by.insert(replace.get_target().to_string(), name.clone()); } } @@ -2040,7 +2043,7 @@ class ComposerStaticInit{} include: &mut IndexMap, replaced_by: &IndexMap, ) { - for (_k, link) in &package.get_requires() { + for (_k, link) in package.get_requires().iter() { let mut target = link.get_target().to_string(); if let Some(rep) = replaced_by.get(&target) { target = rep.clone(); diff --git a/crates/shirabe/src/command/bump_command.rs b/crates/shirabe/src/command/bump_command.rs index 8f95366f..71ee2ffe 100644 --- a/crates/shirabe/src/command/bump_command.rs +++ b/crates/shirabe/src/command/bump_command.rs @@ -167,10 +167,13 @@ impl BumpCommand { let bumper = VersionBumper; let mut tasks = indexmap::IndexMap::new(); if !dev_only { - tasks.insert("require", composer.get_package().get_requires()); + tasks.insert("require", (*composer.get_package().get_requires()).clone()); } if !no_dev_only { - tasks.insert("require-dev", composer.get_package().get_dev_requires()); + tasks.insert( + "require-dev", + (*composer.get_package().get_dev_requires()).clone(), + ); } let packages_filter = if !packages_filter.is_empty() { @@ -196,7 +199,7 @@ impl BumpCommand { let mut updates: indexmap::IndexMap<&str, indexmap::IndexMap> = indexmap::IndexMap::new(); for (key, reqs) in &tasks { - for (pkg_name, link) in reqs { + for (pkg_name, link) in reqs.iter() { if PlatformRepository::is_platform_package(pkg_name) { continue; } diff --git a/crates/shirabe/src/command/check_platform_reqs_command.rs b/crates/shirabe/src/command/check_platform_reqs_command.rs index 21e71fee..b672b9cd 100644 --- a/crates/shirabe/src/command/check_platform_reqs_command.rs +++ b/crates/shirabe/src/command/check_platform_reqs_command.rs @@ -243,7 +243,7 @@ impl Command for CheckPlatformReqsCommand { }; if !no_dev { - for (require, link) in composer.get_package().get_dev_requires() { + for (require, link) in composer.get_package().get_dev_requires().iter() { requires .entry(require.to_string()) .or_default() @@ -263,7 +263,7 @@ impl Command for CheckPlatformReqsCommand { if remove_packages.contains(&package.get_name().to_string()) { continue; } - for (require, link) in package.get_requires() { + for (require, link) in package.get_requires().iter() { requires .entry(require.to_string()) .or_default() @@ -289,27 +289,28 @@ impl Command for CheckPlatformReqsCommand { if !candidates.is_empty() { let mut req_results: Vec = vec![]; 'candidates: for candidate in &candidates { - let candidate_constraint: Option = if candidate.get_name() - == *require - { - let c = SimpleConstraint::new( - "=".to_string(), - candidate.get_version().to_string(), - Some(candidate.get_pretty_version().to_string()), - ); - Some(c.into()) - } else { - let mut found: Option = None; - let provides_and_replaces = - array_merge_map(candidate.get_provides(), candidate.get_replaces()); - for (_, link) in &provides_and_replaces { - if link.get_target() == require { - found = Some(link.get_constraint().clone()); - break; + let candidate_constraint: Option = + if candidate.get_name() == *require { + let c = SimpleConstraint::new( + "=".to_string(), + candidate.get_version().to_string(), + Some(candidate.get_pretty_version().to_string()), + ); + Some(c.into()) + } else { + let mut found: Option = None; + let provides_and_replaces = array_merge_map( + (*candidate.get_provides()).clone(), + (*candidate.get_replaces()).clone(), + ); + for (_, link) in &provides_and_replaces { + if link.get_target() == require { + found = Some(link.get_constraint().clone()); + break; + } } - } - found - }; + found + }; let candidate_constraint = match candidate_constraint { Some(c) => c, diff --git a/crates/shirabe/src/command/remove_command.rs b/crates/shirabe/src/command/remove_command.rs index 9004a9fd..e50999bb 100644 --- a/crates/shirabe/src/command/remove_command.rs +++ b/crates/shirabe/src/command/remove_command.rs @@ -479,8 +479,14 @@ impl Command for RemoveCommand { if dry_run { let root_package = composer.get_package(); let mut links: IndexMap> = IndexMap::new(); - links.insert("require".to_string(), root_package.get_requires()); - links.insert("require-dev".to_string(), root_package.get_dev_requires()); + links.insert( + "require".to_string(), + (*root_package.get_requires()).clone(), + ); + links.insert( + "require-dev".to_string(), + (*root_package.get_dev_requires()).clone(), + ); for (link_type, names) in &to_remove { for name in names { if let Some(section) = links.get_mut(link_type.as_str()) { diff --git a/crates/shirabe/src/command/require_command.rs b/crates/shirabe/src/command/require_command.rs index 15eae91b..197adfd6 100644 --- a/crates/shirabe/src/command/require_command.rs +++ b/crates/shirabe/src/command/require_command.rs @@ -200,8 +200,14 @@ impl RequireCommand { let root_package = composer.get_package(); let mut links: IndexMap> = IndexMap::new(); - links.insert("require".to_string(), root_package.get_requires()); - links.insert("require-dev".to_string(), root_package.get_dev_requires()); + links.insert( + "require".to_string(), + (*root_package.get_requires()).clone(), + ); + links.insert( + "require-dev".to_string(), + (*root_package.get_dev_requires()).clone(), + ); let loader = ArrayLoader::new(None, false); let requirements_mixed: IndexMap = requirements .iter() diff --git a/crates/shirabe/src/command/show_command.rs b/crates/shirabe/src/command/show_command.rs index f605e2b5..090678eb 100644 --- a/crates/shirabe/src/command/show_command.rs +++ b/crates/shirabe/src/command/show_command.rs @@ -939,7 +939,7 @@ impl ShowCommand { remote_repos: &RepositoryInterfaceHandle, ) -> PackageTree { let requires = { - let mut r: IndexMap = package.get_requires(); + let mut r: IndexMap = (*package.get_requires()).clone(); r.sort_keys(); r }; @@ -1055,7 +1055,7 @@ impl ShowCommand { }; let (package, _) = self.get_package(installed_repo, remote_repos, name, version_arg)?; if let Some(package) = package { - let mut requires = package.get_requires(); + let mut requires = (*package.get_requires()).clone(); requires.sort_keys(); for (require_name, require) in requires.iter() { let mut current_tree = packages_in_tree.to_vec(); diff --git a/crates/shirabe/src/command/update_command.rs b/crates/shirabe/src/command/update_command.rs index 0548fc02..09809eb2 100644 --- a/crates/shirabe/src/command/update_command.rs +++ b/crates/shirabe/src/command/update_command.rs @@ -83,8 +83,8 @@ impl UpdateCommand { let platform_req_filter = self.get_platform_requirement_filter(input); let stability_flags = composer_ref.get_package().get_stability_flags(); let requires = array_merge_map( - composer_ref.get_package().get_requires(), - composer_ref.get_package().get_dev_requires(), + (*composer_ref.get_package().get_requires()).clone(), + (*composer_ref.get_package().get_dev_requires()).clone(), ); let filter: Option = if !packages.is_empty() { @@ -156,7 +156,7 @@ impl UpdateCommand { } } if installed_packages.is_empty() { - for (req, _constraint) in &requires { + for (req, _constraint) in requires.iter() { if PlatformRepository::is_platform_package(req) { continue; } @@ -401,9 +401,11 @@ impl Command for UpdateCommand { let parser = VersionParser::new(); let mut temporary_constraints: IndexMap = IndexMap::new(); - let root_requirements = - array_merge_map(root_package.get_requires(), root_package.get_dev_requires()); - for (package, constraint) in &reqs { + let root_requirements = array_merge_map( + (*root_package.get_requires()).clone(), + (*root_package.get_dev_requires()).clone(), + ); + for (package, constraint) in reqs.iter() { let package = strtolower(package); let parsed_constraint = parser.parse_constraints(constraint)?; temporary_constraints.insert(package.clone(), parsed_constraint.clone()); diff --git a/crates/shirabe/src/dependency_resolver/pool_builder.rs b/crates/shirabe/src/dependency_resolver/pool_builder.rs index 98a0948d..a47952af 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 { .entry(locked_package.get_name()) .or_default() .push(locked_package.clone()); - for (_k, link) in &locked_package.get_replaces() { + for (_k, link) in locked_package.get_replaces().iter() { self.skipped_load .entry(link.get_target().to_string()) .or_default() @@ -202,7 +202,7 @@ impl PoolBuilder { ); // replace means conflict, so if a fixed package replaces a name, no need to load that one, packages would conflict anyways - for (_k, link) in &package.get_replaces() { + for (_k, link) in package.get_replaces().iter() { self.loaded_packages.insert( link.get_target().to_string(), MatchAllConstraint::new(None).into(), @@ -229,7 +229,7 @@ impl PoolBuilder { } } - for (package_name, constraint) in request.get_requires() { + for (package_name, constraint) in request.get_requires().iter() { // fixed and locked packages have already been added, so if a root require needs one of them, no need to do anything if self.loaded_packages.contains_key(package_name) { continue; @@ -662,7 +662,7 @@ impl PoolBuilder { } let requires = package.get_requires(); - for (_k, link) in &requires { + for (_k, link) in requires.iter() { let require = link.get_target().to_string(); let link_constraint = link.get_constraint(); @@ -702,7 +702,7 @@ impl PoolBuilder { // if we're doing a partial update with deps we also need to unlock packages which are being replaced in case // they are currently locked and thus prevent this updateable package from being installable/updateable if propagate_update && request.get_update_allow_transitive_dependencies() { - for (_k, link) in &package.get_replaces() { + for (_k, link) in package.get_replaces().iter() { let replace = link.get_target().to_string(); if self.loaded_packages.contains_key(&replace) && self.skipped_load.contains_key(&replace) @@ -762,7 +762,7 @@ impl PoolBuilder { if root_requires.contains_key(&package_or_replacer.get_name()) { matches.push(package_or_replacer.get_name()); } - for (_k, link) in &package_or_replacer.get_replaces() { + for (_k, link) in package_or_replacer.get_replaces().iter() { if root_requires.contains_key(link.get_target()) { if name != package_or_replacer.get_name() { matches.push(format!( @@ -817,7 +817,7 @@ impl PoolBuilder { } } // update pattern matches a root require? => all good, probably a new package - for (package_name, _constraint) in request.get_requires() { + for (package_name, _constraint) in request.get_requires().iter() { if preg_is_match(&pattern_regexp, package_name) { if PlatformRepository::is_platform_package(package_name) { matched_platform_package = true; @@ -964,7 +964,7 @@ impl PoolBuilder { ); } - for (_k, replace) in &locked_package.get_replaces() { + for (_k, replace) in locked_package.get_replaces().iter() { if requires.contains_key(replace.get_target()) && self.skipped_load.contains_key(replace.get_target()) { @@ -997,7 +997,7 @@ impl PoolBuilder { let pkgs: Vec = self.packages.values().cloned().collect(); for package in &pkgs { - for (_k, link) in &package.get_requires() { + for (_k, link) in package.get_requires().iter() { if name == link.get_target() { self.mark_package_name_for_loading( request, diff --git a/crates/shirabe/src/dependency_resolver/pool_optimizer.rs b/crates/shirabe/src/dependency_resolver/pool_optimizer.rs index 5aca700e..c71feb4d 100644 --- a/crates/shirabe/src/dependency_resolver/pool_optimizer.rs +++ b/crates/shirabe/src/dependency_resolver/pool_optimizer.rs @@ -103,7 +103,7 @@ impl PoolOptimizer { } // Extract requested package requirements - for (require, constraint) in request.get_requires() { + for (require, constraint) in request.get_requires().iter() { self.extract_require_constraints_per_package(require, constraint.clone()); } @@ -258,7 +258,7 @@ impl PoolOptimizer { } if !package.get_replaces().is_empty() { - for (_, link) in package.get_replaces() { + for (_, link) in package.get_replaces().iter() { if CompilingMatcher::r#match( link.get_constraint(), CmpOp::Eq, diff --git a/crates/shirabe/src/dependency_resolver/rule_set_generator.rs b/crates/shirabe/src/dependency_resolver/rule_set_generator.rs index aa9412c4..aebdac30 100644 --- a/crates/shirabe/src/dependency_resolver/rule_set_generator.rs +++ b/crates/shirabe/src/dependency_resolver/rule_set_generator.rs @@ -254,7 +254,7 @@ impl RuleSetGenerator { .into_iter() .collect(); - for conflict in &conflicts { + for conflict in conflicts.iter() { // define the conflict rule for regular packages, for alias packages it's only needed if the name // matches the conflict exactly, otherwise the name match is by provide/replace which means the // package which this is an alias of will conflict anyway, so no need to create additional rules @@ -328,7 +328,7 @@ impl RuleSetGenerator { self.add_rule(RuleSet::TYPE_REQUEST, Some(Rule::Generic(rule))); } - for (package_name, constraint) in request.get_requires() { + for (package_name, constraint) in request.get_requires().iter() { let mut constraint = constraint.clone(); if platform_requirement_filter.is_ignored(package_name) { continue; diff --git a/crates/shirabe/src/dependency_resolver/solver.rs b/crates/shirabe/src/dependency_resolver/solver.rs index cb398a0c..04cb5c9b 100644 --- a/crates/shirabe/src/dependency_resolver/solver.rs +++ b/crates/shirabe/src/dependency_resolver/solver.rs @@ -178,7 +178,7 @@ impl Solver { request: &Request, platform_requirement_filter: &dyn PlatformRequirementFilterInterface, ) -> anyhow::Result<()> { - for (package_name, constraint) in request.get_requires() { + for (package_name, constraint) in request.get_requires().iter() { let mut filtered: Option = None; let constraint_ref: &AnyConstraint = constraint; if platform_requirement_filter.is_ignored(package_name) { diff --git a/crates/shirabe/src/installer.rs b/crates/shirabe/src/installer.rs index ee60f59f..d1e38542 100644 --- a/crates/shirabe/src/installer.rs +++ b/crates/shirabe/src/installer.rs @@ -1082,13 +1082,13 @@ impl Installer { request.fix_locked_package(package.clone()); } - let mut root_requires = self.package.get_requires(); + let mut root_requires = (*self.package.get_requires()).clone(); if self.dev_mode { - for (k, v) in self.package.get_dev_requires() { - root_requires.insert(k, v); + for (k, v) in self.package.get_dev_requires().iter() { + root_requires.insert(k.clone(), v.clone()); } } - for (_key, link) in &root_requires { + for (_key, link) in root_requires.iter() { if PlatformRepository::is_platform_package(link.get_target()) { request.require_name(link.get_target(), Some(link.get_constraint().clone()))?; } @@ -1331,11 +1331,11 @@ impl Installer { // Convert Link map merge into ConstraintInterface map for use later let mut req_links: IndexMap = IndexMap::new(); - for (k, v) in self.package.get_requires() { - req_links.insert(k, v); + for (k, v) in self.package.get_requires().iter() { + req_links.insert(k.clone(), v.clone()); } - for (k, v) in self.package.get_dev_requires() { - req_links.insert(k, v); + for (k, v) in self.package.get_dev_requires().iter() { + req_links.insert(k.clone(), v.clone()); } // Translate to constraint map for downstream uniform handling. let mut tmp: IndexMap = IndexMap::new(); @@ -1579,13 +1579,13 @@ impl Installer { } } } else { - let mut links = self.package.get_requires(); + let mut links = (*self.package.get_requires()).clone(); if include_dev_requires { - for (k, v) in self.package.get_dev_requires() { - links.insert(k, v); + for (k, v) in self.package.get_dev_requires().iter() { + links.insert(k.clone(), v.clone()); } } - for (_key, link) in &links { + for (_key, link) in links.iter() { request.require_name(link.get_target(), Some(link.get_constraint().clone()))?; } } diff --git a/crates/shirabe/src/package/alias_package.rs b/crates/shirabe/src/package/alias_package.rs index 9df804f1..4eeb408a 100644 --- a/crates/shirabe/src/package/alias_package.rs +++ b/crates/shirabe/src/package/alias_package.rs @@ -39,15 +39,15 @@ pub struct AliasPackage { /// @var BasePackage pub(crate) alias_of: PackageHandle, /// @var Link[] - pub(crate) requires: IndexMap, + pub(crate) requires: std::rc::Rc>, /// @var Link[] - pub(crate) dev_requires: IndexMap, + pub(crate) dev_requires: std::rc::Rc>, /// @var array - pub(crate) conflicts: IndexMap, + pub(crate) conflicts: std::rc::Rc>, /// @var array - pub(crate) provides: IndexMap, + pub(crate) provides: std::rc::Rc>, /// @var array - pub(crate) replaces: IndexMap, + pub(crate) replaces: std::rc::Rc>, } impl AliasPackage { @@ -74,15 +74,15 @@ impl AliasPackage { stability, has_self_version_requires: false, alias_of, - requires: IndexMap::new(), - dev_requires: IndexMap::new(), - conflicts: IndexMap::new(), - provides: IndexMap::new(), - replaces: IndexMap::new(), + requires: std::rc::Rc::new(IndexMap::new()), + dev_requires: std::rc::Rc::new(IndexMap::new()), + conflicts: std::rc::Rc::new(IndexMap::new()), + provides: std::rc::Rc::new(IndexMap::new()), + replaces: std::rc::Rc::new(IndexMap::new()), }; for r#type in Link::types() { - let links: IndexMap = match r#type { + let links: std::rc::Rc> = match r#type { Link::TYPE_REQUIRE => this.alias_of.get_requires(), Link::TYPE_DEV_REQUIRE => this.alias_of.get_dev_requires(), Link::TYPE_PROVIDE => this.alias_of.get_provides(), @@ -90,7 +90,8 @@ impl AliasPackage { Link::TYPE_REPLACE => this.alias_of.get_replaces(), _ => unreachable!(), }; - let replaced = this.replace_self_version_dependencies(links, r#type); + let replaced = + std::rc::Rc::new(this.replace_self_version_dependencies((*links).clone(), r#type)); match r#type { Link::TYPE_REQUIRE => this.requires = replaced, Link::TYPE_DEV_REQUIRE => this.dev_requires = replaced, @@ -252,27 +253,27 @@ impl PackageInterface for AliasPackage { &self.pretty_version } - fn get_requires(&self) -> IndexMap { - self.requires.clone() + fn get_requires(&self) -> std::rc::Rc> { + std::rc::Rc::clone(&self.requires) } /// @inheritDoc - fn get_conflicts(&self) -> IndexMap { - self.conflicts.clone() + fn get_conflicts(&self) -> std::rc::Rc> { + std::rc::Rc::clone(&self.conflicts) } /// @inheritDoc - fn get_provides(&self) -> IndexMap { - self.provides.clone() + fn get_provides(&self) -> std::rc::Rc> { + std::rc::Rc::clone(&self.provides) } /// @inheritDoc - fn get_replaces(&self) -> IndexMap { - self.replaces.clone() + fn get_replaces(&self) -> std::rc::Rc> { + std::rc::Rc::clone(&self.replaces) } - fn get_dev_requires(&self) -> IndexMap { - self.dev_requires.clone() + fn get_dev_requires(&self) -> std::rc::Rc> { + std::rc::Rc::clone(&self.dev_requires) } fn get_type(&self) -> String { diff --git a/crates/shirabe/src/package/complete_package.rs b/crates/shirabe/src/package/complete_package.rs index 00b4a67c..b21edb44 100644 --- a/crates/shirabe/src/package/complete_package.rs +++ b/crates/shirabe/src/package/complete_package.rs @@ -279,24 +279,24 @@ impl PackageInterface for CompletePackage { self.inner.get_stability() } - fn get_requires(&self) -> IndexMap { - self.inner.get_requires().clone() + fn get_requires(&self) -> std::rc::Rc> { + PackageInterface::get_requires(&self.inner) } - fn get_conflicts(&self) -> IndexMap { - self.inner.get_conflicts().clone() + fn get_conflicts(&self) -> std::rc::Rc> { + PackageInterface::get_conflicts(&self.inner) } - fn get_provides(&self) -> IndexMap { - self.inner.get_provides().clone() + fn get_provides(&self) -> std::rc::Rc> { + PackageInterface::get_provides(&self.inner) } - fn get_replaces(&self) -> IndexMap { - self.inner.get_replaces().clone() + fn get_replaces(&self) -> std::rc::Rc> { + PackageInterface::get_replaces(&self.inner) } - fn get_dev_requires(&self) -> IndexMap { - self.inner.get_dev_requires().clone() + fn get_dev_requires(&self) -> std::rc::Rc> { + PackageInterface::get_dev_requires(&self.inner) } fn get_suggests(&self) -> IndexMap { diff --git a/crates/shirabe/src/package/handle.rs b/crates/shirabe/src/package/handle.rs index 45d46f49..fd7272de 100644 --- a/crates/shirabe/src/package/handle.rs +++ b/crates/shirabe/src/package/handle.rs @@ -322,19 +322,29 @@ macro_rules! delegate_package_interface_to_inner { fn get_stability(&self) -> &str { self.$field.get_stability() } - fn get_requires(&self) -> indexmap::IndexMap { + fn get_requires( + &self, + ) -> std::rc::Rc> { self.$field.get_requires() } - fn get_conflicts(&self) -> indexmap::IndexMap { + fn get_conflicts( + &self, + ) -> std::rc::Rc> { self.$field.get_conflicts() } - fn get_provides(&self) -> indexmap::IndexMap { + fn get_provides( + &self, + ) -> std::rc::Rc> { self.$field.get_provides() } - fn get_replaces(&self) -> indexmap::IndexMap { + fn get_replaces( + &self, + ) -> std::rc::Rc> { self.$field.get_replaces() } - fn get_dev_requires(&self) -> indexmap::IndexMap { + fn get_dev_requires( + &self, + ) -> std::rc::Rc> { self.$field.get_dev_requires() } fn get_suggests(&self) -> indexmap::IndexMap { @@ -585,23 +595,33 @@ macro_rules! impl_package_interface_handle { .to_string() } - pub fn get_requires(&self) -> indexmap::IndexMap { + pub fn get_requires( + &self, + ) -> std::rc::Rc> { self.0.borrow().as_package_interface().get_requires() } - pub fn get_conflicts(&self) -> indexmap::IndexMap { + pub fn get_conflicts( + &self, + ) -> std::rc::Rc> { self.0.borrow().as_package_interface().get_conflicts() } - pub fn get_provides(&self) -> indexmap::IndexMap { + pub fn get_provides( + &self, + ) -> std::rc::Rc> { self.0.borrow().as_package_interface().get_provides() } - pub fn get_replaces(&self) -> indexmap::IndexMap { + pub fn get_replaces( + &self, + ) -> std::rc::Rc> { self.0.borrow().as_package_interface().get_replaces() } - pub fn get_dev_requires(&self) -> indexmap::IndexMap { + pub fn get_dev_requires( + &self, + ) -> std::rc::Rc> { self.0.borrow().as_package_interface().get_dev_requires() } @@ -612,7 +632,7 @@ macro_rules! impl_package_interface_handle { pub fn get_links_for_type( &self, link_type: &str, - ) -> indexmap::IndexMap { + ) -> std::rc::Rc> { self.0 .borrow() .as_package_interface() diff --git a/crates/shirabe/src/package/package.rs b/crates/shirabe/src/package/package.rs index 388280fd..44770bc1 100644 --- a/crates/shirabe/src/package/package.rs +++ b/crates/shirabe/src/package/package.rs @@ -54,11 +54,11 @@ pub struct Package { stability: String, notification_url: Option, - requires: IndexMap, - conflicts: IndexMap, - provides: IndexMap, - replaces: IndexMap, - dev_requires: IndexMap, + requires: std::rc::Rc>, + conflicts: std::rc::Rc>, + provides: std::rc::Rc>, + replaces: std::rc::Rc>, + dev_requires: std::rc::Rc>, suggests: IndexMap, autoload: IndexMap, dev_autoload: IndexMap, @@ -98,11 +98,11 @@ impl Package { dev, stability, notification_url: None, - requires: IndexMap::new(), - conflicts: IndexMap::new(), - provides: IndexMap::new(), - replaces: IndexMap::new(), - dev_requires: IndexMap::new(), + requires: std::rc::Rc::new(IndexMap::new()), + conflicts: std::rc::Rc::new(IndexMap::new()), + provides: std::rc::Rc::new(IndexMap::new()), + replaces: std::rc::Rc::new(IndexMap::new()), + dev_requires: std::rc::Rc::new(IndexMap::new()), suggests: IndexMap::new(), autoload: IndexMap::new(), dev_autoload: IndexMap::new(), @@ -299,7 +299,7 @@ impl Package { requires = self.convert_links_to_map(requires, "setRequires"); } - self.requires = requires; + self.requires = std::rc::Rc::new(requires); } pub fn get_requires(&self) -> &IndexMap { @@ -311,7 +311,7 @@ impl Package { conflicts = self.convert_links_to_map(conflicts, "setConflicts"); } - self.conflicts = conflicts; + self.conflicts = std::rc::Rc::new(conflicts); } pub fn get_conflicts(&self) -> &IndexMap { @@ -323,7 +323,7 @@ impl Package { provides = self.convert_links_to_map(provides, "setProvides"); } - self.provides = provides; + self.provides = std::rc::Rc::new(provides); } pub fn get_provides(&self) -> &IndexMap { @@ -335,7 +335,7 @@ impl Package { replaces = self.convert_links_to_map(replaces, "setReplaces"); } - self.replaces = replaces; + self.replaces = std::rc::Rc::new(replaces); } pub fn get_replaces(&self) -> &IndexMap { @@ -347,7 +347,7 @@ impl Package { dev_requires = self.convert_links_to_map(dev_requires, "setDevRequires"); } - self.dev_requires = dev_requires; + self.dev_requires = std::rc::Rc::new(dev_requires); } pub fn get_dev_requires(&self) -> &IndexMap { @@ -604,12 +604,12 @@ impl PackageInterface for Package { names.insert(self.get_name().to_string()); if provides { - for (_, link) in self.get_provides() { + for (_, link) in self.get_provides().iter() { names.insert(link.get_target().to_string()); } } - for (_, link) in self.get_replaces() { + for (_, link) in self.get_replaces().iter() { names.insert(link.get_target().to_string()); } @@ -693,20 +693,20 @@ impl PackageInterface for Package { fn get_stability(&self) -> &str { &self.stability } - fn get_requires(&self) -> IndexMap { - self.requires.clone() + fn get_requires(&self) -> std::rc::Rc> { + std::rc::Rc::clone(&self.requires) } - fn get_conflicts(&self) -> IndexMap { - self.conflicts.clone() + fn get_conflicts(&self) -> std::rc::Rc> { + std::rc::Rc::clone(&self.conflicts) } - fn get_provides(&self) -> IndexMap { - self.provides.clone() + fn get_provides(&self) -> std::rc::Rc> { + std::rc::Rc::clone(&self.provides) } - fn get_replaces(&self) -> IndexMap { - self.replaces.clone() + fn get_replaces(&self) -> std::rc::Rc> { + std::rc::Rc::clone(&self.replaces) } - fn get_dev_requires(&self) -> IndexMap { - self.dev_requires.clone() + fn get_dev_requires(&self) -> std::rc::Rc> { + std::rc::Rc::clone(&self.dev_requires) } fn get_suggests(&self) -> IndexMap { self.suggests.clone() diff --git a/crates/shirabe/src/package/package_interface.rs b/crates/shirabe/src/package/package_interface.rs index ffbec286..d138fd83 100644 --- a/crates/shirabe/src/package/package_interface.rs +++ b/crates/shirabe/src/package/package_interface.rs @@ -159,31 +159,31 @@ pub trait PackageInterface: std::fmt::Display + std::fmt::Debug { /// this package can be installed /// /// @return array A map of package links defining required packages, indexed by the require package's name - fn get_requires(&self) -> IndexMap; + fn get_requires(&self) -> std::rc::Rc>; /// Returns a set of links to packages which must not be installed at the /// same time as this package /// /// @return array A map of package links defining conflicting packages - fn get_conflicts(&self) -> IndexMap; + fn get_conflicts(&self) -> std::rc::Rc>; /// Returns a set of links to virtual packages that are provided through /// this package /// /// @return array A map of package links defining provided packages - fn get_provides(&self) -> IndexMap; + fn get_provides(&self) -> std::rc::Rc>; /// Returns a set of links to packages which can alternatively be /// satisfied by installing this package /// /// @return array A map of package links defining replaced packages - fn get_replaces(&self) -> IndexMap; + fn get_replaces(&self) -> std::rc::Rc>; /// Returns a set of links to packages which are required to develop /// this package. These are installed if in dev mode. /// /// @return array A map of package links defining packages required for development, indexed by the require package's name - fn get_dev_requires(&self) -> IndexMap; + fn get_dev_requires(&self) -> std::rc::Rc>; /// Returns a set of package names and reasons why they are useful in /// combination with this package. @@ -192,14 +192,17 @@ pub trait PackageInterface: std::fmt::Display + std::fmt::Debug { fn get_suggests(&self) -> IndexMap; /// PHP helper that switches on the link kind (require/require-dev/conflict/etc.). - fn get_links_for_type(&self, link_type: &str) -> IndexMap { + fn get_links_for_type( + &self, + link_type: &str, + ) -> std::rc::Rc> { match link_type { "require" => self.get_requires(), "require-dev" => self.get_dev_requires(), "conflict" => self.get_conflicts(), "provide" => self.get_provides(), "replace" => self.get_replaces(), - _ => IndexMap::new(), + _ => std::rc::Rc::new(IndexMap::new()), } } diff --git a/crates/shirabe/src/package/root_alias_package.rs b/crates/shirabe/src/package/root_alias_package.rs index 4a4115d7..d5ea720e 100644 --- a/crates/shirabe/src/package/root_alias_package.rs +++ b/crates/shirabe/src/package/root_alias_package.rs @@ -78,44 +78,49 @@ impl RootPackageInterface for RootAliasPackage { } fn set_requires(&mut self, requires: IndexMap) { - self.inner.inner.requires = self - .inner - .inner - .replace_self_version_dependencies(requires.clone(), Link::TYPE_REQUIRE); + self.inner.inner.requires = std::rc::Rc::new( + self.inner + .inner + .replace_self_version_dependencies(requires.clone(), Link::TYPE_REQUIRE), + ); self.alias_of.set_requires(requires); } fn set_dev_requires(&mut self, dev_requires: IndexMap) { - self.inner.inner.dev_requires = self - .inner - .inner - .replace_self_version_dependencies(dev_requires.clone(), Link::TYPE_DEV_REQUIRE); + self.inner.inner.dev_requires = std::rc::Rc::new( + self.inner + .inner + .replace_self_version_dependencies(dev_requires.clone(), Link::TYPE_DEV_REQUIRE), + ); self.alias_of.set_dev_requires(dev_requires); } fn set_conflicts(&mut self, conflicts: IndexMap) { - self.inner.inner.conflicts = self - .inner - .inner - .replace_self_version_dependencies(conflicts.clone(), Link::TYPE_CONFLICT); + self.inner.inner.conflicts = std::rc::Rc::new( + self.inner + .inner + .replace_self_version_dependencies(conflicts.clone(), Link::TYPE_CONFLICT), + ); self.alias_of.set_conflicts(conflicts); } fn set_provides(&mut self, provides: IndexMap) { - self.inner.inner.provides = self - .inner - .inner - .replace_self_version_dependencies(provides.clone(), Link::TYPE_PROVIDE); + self.inner.inner.provides = std::rc::Rc::new( + self.inner + .inner + .replace_self_version_dependencies(provides.clone(), Link::TYPE_PROVIDE), + ); self.alias_of.set_provides(provides); } fn set_replaces(&mut self, replaces: IndexMap) { - self.inner.inner.replaces = self - .inner - .inner - .replace_self_version_dependencies(replaces.clone(), Link::TYPE_REPLACE); + self.inner.inner.replaces = std::rc::Rc::new( + self.inner + .inner + .replace_self_version_dependencies(replaces.clone(), Link::TYPE_REPLACE), + ); self.alias_of.set_replaces(replaces); } diff --git a/crates/shirabe/src/package/root_package.rs b/crates/shirabe/src/package/root_package.rs index 0807d15b..e1c4b35e 100644 --- a/crates/shirabe/src/package/root_package.rs +++ b/crates/shirabe/src/package/root_package.rs @@ -338,19 +338,19 @@ impl PackageInterface for RootPackage { fn get_stability(&self) -> &str { self.inner.get_stability() } - fn get_requires(&self) -> IndexMap { + fn get_requires(&self) -> std::rc::Rc> { self.inner.get_requires() } - fn get_conflicts(&self) -> IndexMap { + fn get_conflicts(&self) -> std::rc::Rc> { self.inner.get_conflicts() } - fn get_provides(&self) -> IndexMap { + fn get_provides(&self) -> std::rc::Rc> { self.inner.get_provides() } - fn get_replaces(&self) -> IndexMap { + fn get_replaces(&self) -> std::rc::Rc> { self.inner.get_replaces() } - fn get_dev_requires(&self) -> IndexMap { + fn get_dev_requires(&self) -> std::rc::Rc> { self.inner.get_dev_requires() } fn get_suggests(&self) -> IndexMap { diff --git a/crates/shirabe/src/package/version/version_selector.rs b/crates/shirabe/src/package/version/version_selector.rs index 61435870..230e886f 100644 --- a/crates/shirabe/src/package/version/version_selector.rs +++ b/crates/shirabe/src/package/version/version_selector.rs @@ -142,7 +142,7 @@ impl VersionSelector { for pkg in candidates.iter() { let reqs = pkg.get_requires(); let mut skip = false; - 'reqs: for (name, link) in &reqs { + 'reqs: for (name, link) in reqs.iter() { if !PlatformRepository::is_platform_package(name) || platform_requirement_filter.is_ignored(name) { diff --git a/crates/shirabe/src/plugin/php_plugin_proxy.rs b/crates/shirabe/src/plugin/php_plugin_proxy.rs index 4b99f528..0cd36b18 100644 --- a/crates/shirabe/src/plugin/php_plugin_proxy.rs +++ b/crates/shirabe/src/plugin/php_plugin_proxy.rs @@ -2005,11 +2005,11 @@ fn dispatch_package_method( )) } "getStability" => Ok(PluginValue::string(package.get_stability().to_string())), - "getRequires" => Ok(links(package.get_requires())), - "getConflicts" => Ok(links(package.get_conflicts())), - "getProvides" => Ok(links(package.get_provides())), - "getReplaces" => Ok(links(package.get_replaces())), - "getDevRequires" => Ok(links(package.get_dev_requires())), + "getRequires" => Ok(links((*package.get_requires()).clone())), + "getConflicts" => Ok(links((*package.get_conflicts()).clone())), + "getProvides" => Ok(links((*package.get_provides()).clone())), + "getReplaces" => Ok(links((*package.get_replaces()).clone())), + "getDevRequires" => Ok(links((*package.get_dev_requires()).clone())), "getSuggests" => { let suggests = package.get_suggests(); if suggests.is_empty() { diff --git a/crates/shirabe/src/plugin/plugin_manager.rs b/crates/shirabe/src/plugin/plugin_manager.rs index 2fff2d74..1ecb4153 100644 --- a/crates/shirabe/src/plugin/plugin_manager.rs +++ b/crates/shirabe/src/plugin/plugin_manager.rs @@ -224,7 +224,7 @@ impl PluginManager { if package.get_type() == "composer-plugin" { let requires_map = package.get_requires(); let mut requires_composer: Option<&shirabe_semver::constraint::AnyConstraint> = None; - for (_k, link) in &requires_map { + for (_k, link) in requires_map.iter() { if "composer-plugin-api" == link.get_target() { requires_composer = Some(link.get_constraint()); break; @@ -951,7 +951,7 @@ impl PluginManager { package: PackageInterfaceHandle, ) -> anyhow::Result> { // TODO(plugin): used by registerPackage to assemble plugin dependency autoload map - for (_k, require_link) in &package.get_requires() { + for (_k, require_link) in package.get_requires().iter() { for required_package in installed_repo .find_packages_with_replacers_and_providers(require_link.get_target(), None)? { diff --git a/crates/shirabe/src/repository/filesystem_repository.rs b/crates/shirabe/src/repository/filesystem_repository.rs index 54c2fa1f..5f06505a 100644 --- a/crates/shirabe/src/repository/filesystem_repository.rs +++ b/crates/shirabe/src/repository/filesystem_repository.rs @@ -510,7 +510,7 @@ impl FilesystemRepository { .as_array() .map(|m| m.contains_key(&package.get_name())) .unwrap_or(false); - for (_, replace) in package.get_replaces() { + for (_, replace) in package.get_replaces().iter() { // exclude platform replaces as when they are really there we can not check for their presence if PlatformRepository::is_platform_package(replace.get_target()) { continue; @@ -527,7 +527,7 @@ impl FilesystemRepository { is_dev_package, ); } - for (_, provide) in package.get_provides() { + for (_, provide) in package.get_provides().iter() { // exclude platform provides as when they are really there we can not check for their presence if PlatformRepository::is_platform_package(provide.get_target()) { continue; diff --git a/crates/shirabe/src/repository/installed_repository.rs b/crates/shirabe/src/repository/installed_repository.rs index 36ad510c..097fca84 100644 --- a/crates/shirabe/src/repository/installed_repository.rs +++ b/crates/shirabe/src/repository/installed_repository.rs @@ -84,8 +84,10 @@ impl InstalledRepository { continue; } - let provides_and_replaces = - array_merge_map(candidate.get_provides(), candidate.get_replaces()); + let provides_and_replaces = array_merge_map( + (*candidate.get_provides()).clone(), + (*candidate.get_replaces()).clone(), + ); for link in provides_and_replaces.values() { if name == link.get_target() && (constraint.is_none() @@ -126,12 +128,12 @@ impl InstalledRepository { } for package in self.inner.get_packages()? { - let mut links: IndexMap = package.get_requires(); + let mut links: IndexMap = (*package.get_requires()).clone(); let mut packages_in_tree = packages_found.clone(); if !invert { - for (k, v) in package.get_replaces() { - links.entry(k).or_insert(v); + for (k, v) in package.get_replaces().iter() { + links.entry(k.clone()).or_insert(v.clone()); } let needles_snapshot = needles.clone(); @@ -169,8 +171,8 @@ impl InstalledRepository { } if package.as_root().is_some() { - for (k, v) in package.get_dev_requires() { - links.entry(k).or_insert(v); + for (k, v) in package.get_dev_requires().iter() { + links.entry(k.clone()).or_insert(v.clone()); } } @@ -297,8 +299,10 @@ impl InstalledRepository { .into(); if link.get_target() != pkg.get_name().as_str() { - let replaces_and_provides = - array_merge_map(pkg.get_replaces(), pkg.get_provides()); + let replaces_and_provides = array_merge_map( + (*pkg.get_replaces()).clone(), + (*pkg.get_provides()).clone(), + ); for prov in replaces_and_provides.values() { if link.get_target() == prov.get_target() { version = prov.get_constraint().clone(); @@ -309,9 +313,10 @@ impl InstalledRepository { if !link.get_constraint().matches(&version) { if let Some(root_pkg) = root_package.as_ref() { - let mut root_reqs: IndexMap = root_pkg.get_requires(); - for (k, v) in root_pkg.get_dev_requires() { - root_reqs.entry(k).or_insert(v); + let mut root_reqs: IndexMap = + (*root_pkg.get_requires()).clone(); + for (k, v) in root_pkg.get_dev_requires().iter() { + root_reqs.entry(k.clone()).or_insert(v.clone()); } for root_req in root_reqs.values() { if pkg diff --git a/crates/shirabe/src/repository/repository_utils.rs b/crates/shirabe/src/repository/repository_utils.rs index c2997f31..3df86b05 100644 --- a/crates/shirabe/src/repository/repository_utils.rs +++ b/crates/shirabe/src/repository/repository_utils.rs @@ -16,9 +16,14 @@ impl RepositoryUtils { include_require_dev: bool, mut bucket: Vec, ) -> Vec { - let mut requires: IndexMap = requirer.get_requires(); + let mut requires: IndexMap = (*requirer.get_requires()).clone(); if include_require_dev { - requires.extend(requirer.get_dev_requires()); + requires.extend( + requirer + .get_dev_requires() + .iter() + .map(|(k, v)| (k.clone(), v.clone())), + ); } for candidate in packages { diff --git a/crates/shirabe/src/repository/vcs/github_driver.rs b/crates/shirabe/src/repository/vcs/github_driver.rs index f2b2d458..60920969 100644 --- a/crates/shirabe/src/repository/vcs/github_driver.rs +++ b/crates/shirabe/src/repository/vcs/github_driver.rs @@ -1230,7 +1230,7 @@ impl GitHubDriver { } let links = explode(",", &header); - for link in &links { + for link in links.iter() { if let Some(m) = preg_match(php_regex!(r#"{<(.+?)>; *rel="next"}"#), link) { return Some(m.get(1).unwrap_or_default().to_string()); } diff --git a/crates/shirabe/src/repository/vcs/gitlab_driver.rs b/crates/shirabe/src/repository/vcs/gitlab_driver.rs index d21a9ca1..f77eec5d 100644 --- a/crates/shirabe/src/repository/vcs/gitlab_driver.rs +++ b/crates/shirabe/src/repository/vcs/gitlab_driver.rs @@ -972,7 +972,7 @@ impl GitLabDriver { let header = response.get_header("link").unwrap_or_default(); let links = explode(",", &header); - for link in &links { + for link in links.iter() { if let Some(match_) = preg_match(php_regex!(r#"{<(.+?)>; *rel="next"}"#), link) { return Some(match_.get(1).unwrap_or_default().to_string()); } diff --git a/crates/shirabe/src/util/package_sorter.rs b/crates/shirabe/src/util/package_sorter.rs index 5687a339..9770375b 100644 --- a/crates/shirabe/src/util/package_sorter.rs +++ b/crates/shirabe/src/util/package_sorter.rs @@ -43,9 +43,14 @@ impl PackageSorter { let mut usage_list: IndexMap> = IndexMap::new(); for package in &packages { - let mut links: IndexMap = package.get_requires(); + let mut links: IndexMap = (*package.get_requires()).clone(); if let Some(root_package) = package.as_root() { - links.extend(root_package.get_dev_requires()); + links.extend( + root_package + .get_dev_requires() + .iter() + .map(|(k, v)| (k.clone(), v.clone())), + ); } for link in links.values() { let target = link.get_target().to_string(); diff --git a/crates/shirabe/tests/repository/platform_repository_test.rs b/crates/shirabe/tests/repository/platform_repository_test.rs index c16f3a3e..03c27750 100644 --- a/crates/shirabe/tests/repository/platform_repository_test.rs +++ b/crates/shirabe/tests/repository/platform_repository_test.rs @@ -1587,7 +1587,7 @@ fn assert_package_links( context: &str, expected_links: &[&str], source_package: &BasePackageHandle, - links: IndexMap, + links: &IndexMap, ) { assert_eq!( expected_links.len(), @@ -1707,13 +1707,13 @@ fn test_library_information() { "replaces", expected_replaces, &package, - package.get_replaces(), + &package.get_replaces(), ); assert_package_links( "provides", expected_provides, &package, - package.get_provides(), + &package.get_provides(), ); } } -- cgit v1.3.1-4-g156e