diff options
| author | nsfisis <nsfisis@gmail.com> | 2026-06-07 10:32:26 +0900 |
|---|---|---|
| committer | nsfisis <nsfisis@gmail.com> | 2026-06-07 10:34:37 +0900 |
| commit | e1053c6881da1bba409a16783e01a89248507a66 (patch) | |
| tree | 17da41e7fe48b675434338e41e5ecefcff5894db /crates/shirabe/src/command/package_discovery_trait.rs | |
| parent | 971824aa15334fd12d08ae0f441f6bf6079344c3 (diff) | |
| download | php-shirabe-e1053c6881da1bba409a16783e01a89248507a66.tar.gz php-shirabe-e1053c6881da1bba409a16783e01a89248507a66.tar.zst php-shirabe-e1053c6881da1bba409a16783e01a89248507a66.zip | |
refactor(phase-c): share PlatformRepository and RepositorySet via handles
PHP shares a single PlatformRepository by reference across the RepositorySet,
createRequest, VersionSelector, and (in show) the installed repository. The
port worked with owned values / &mut, so it could not share: create_repository_set
silently dropped the platform repo from the pool (PlatformRepository is not
Clone), show rebuilt a fresh PlatformRepository per use, and the package
discovery / show version selectors were stubbed because VersionSelector wanted
an owned RepositorySet.
Thread the existing PlatformRepositoryHandle (Rc<RefCell<PlatformRepository>>)
through installer.rs and show, restoring the RootPackageRepository + platform
repo registration and implementing same_repository via RepositoryInterfaceHandle
ptr_eq. Hold package-discovery repos as a shared RepositoryInterfaceHandle, and
share RepositorySet as Rc<RefCell<RepositorySet>> in the set caches and
VersionSelector (which only reads it), unblocking both stubbed selector sites
and dropping show's placeholder set.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Diffstat (limited to 'crates/shirabe/src/command/package_discovery_trait.rs')
| -rw-r--r-- | crates/shirabe/src/command/package_discovery_trait.rs | 51 |
1 files changed, 29 insertions, 22 deletions
diff --git a/crates/shirabe/src/command/package_discovery_trait.rs b/crates/shirabe/src/command/package_discovery_trait.rs index 4162676..cd6c5a0 100644 --- a/crates/shirabe/src/command/package_discovery_trait.rs +++ b/crates/shirabe/src/command/package_discovery_trait.rs @@ -36,8 +36,10 @@ use crate::util::Filesystem; pub trait PackageDiscoveryTrait { // PHP: private $repos; private $repositorySets; // TODO(phase-b): trait fields require an associated state struct in Rust; expose via accessors - fn get_repos_mut(&mut self) -> &mut Option<CompositeRepository>; - fn get_repository_sets_mut(&mut self) -> &mut IndexMap<String, RepositorySet>; + fn get_repos_mut(&mut self) -> &mut Option<crate::repository::RepositoryInterfaceHandle>; + fn get_repository_sets_mut( + &mut self, + ) -> &mut IndexMap<String, std::rc::Rc<std::cell::RefCell<RepositorySet>>>; // PHP: trait dependencies (provided by BaseCommand) fn get_io(&self) -> std::rc::Rc<std::cell::RefCell<dyn IOInterface>>; @@ -56,15 +58,14 @@ pub trait PackageDiscoveryTrait { fn normalize_requirements(&self, requires: Vec<String>) -> Vec<IndexMap<String, String>>; - fn get_repos(&mut self) -> &mut CompositeRepository { + fn get_repos(&mut self) -> crate::repository::RepositoryInterfaceHandle { if self.get_repos_mut().is_none() { // PHP: array_merge([new PlatformRepository], RepositoryFactory::defaultReposWithDefaultManager($this->getIO())) - let mut repos: Vec<crate::repository::RepositoryInterfaceHandle> = vec![ - // TODO(phase-b): PlatformRepository::new() signature - crate::repository::RepositoryInterfaceHandle::new::<PlatformRepository>(todo!( - "PlatformRepository::new()" - )), - ]; + let mut repos: Vec<crate::repository::RepositoryInterfaceHandle> = + vec![crate::repository::RepositoryInterfaceHandle::new( + PlatformRepository::new(vec![], IndexMap::new()) + .expect("PlatformRepository::new should not fail"), + )]; let io_owned: std::rc::Rc<std::cell::RefCell<dyn IOInterface>> = self.get_io(); for (_, repo) in RepositoryFactory::default_repos_with_default_manager(io_owned) .unwrap() @@ -72,10 +73,12 @@ pub trait PackageDiscoveryTrait { { repos.push(repo); } - *self.get_repos_mut() = Some(CompositeRepository::new(repos)); + *self.get_repos_mut() = Some(crate::repository::RepositoryInterfaceHandle::new( + CompositeRepository::new(repos), + )); } - self.get_repos_mut().as_mut().unwrap() + self.get_repos_mut().as_ref().unwrap().clone() } /// @param key-of<BasePackage::STABILITIES>|null $minimumStability @@ -83,7 +86,7 @@ pub trait PackageDiscoveryTrait { &mut self, input: std::rc::Rc<std::cell::RefCell<dyn InputInterface>>, minimum_stability: Option<&str>, - ) -> &RepositorySet { + ) -> std::rc::Rc<std::cell::RefCell<RepositorySet>> { let key = minimum_stability.unwrap_or("default").to_string(); if !self.get_repository_sets_mut().contains_key(&key) { @@ -98,14 +101,15 @@ pub trait PackageDiscoveryTrait { IndexMap::new(), IndexMap::new(), ); - // TODO(phase-b): self.get_repos() returns reference; add_repository takes ownership - let repos = todo!("self.get_repos() owned/cloned for add_repository"); + let repos = self.get_repos(); let _ = repository_set.add_repository(repos); - self.get_repository_sets_mut() - .insert(key.clone(), repository_set); + self.get_repository_sets_mut().insert( + key.clone(), + std::rc::Rc::new(std::cell::RefCell::new(repository_set)), + ); } - self.get_repository_sets_mut().get(&key).unwrap() + self.get_repository_sets_mut().get(&key).unwrap().clone() } /// @return key-of<BasePackage::STABILITIES> @@ -515,9 +519,12 @@ pub trait PackageDiscoveryTrait { // find the latest version allowed in this repo set let repo_set = self.get_repository_set(input.clone(), None); - // TODO(phase-b): VersionSelector::new takes owned RepositorySet; we have a shared reference - let mut version_selector: VersionSelector = - todo!("VersionSelector::new with owned repo_set"); + let mut version_selector = match platform_repo { + Some(handle) => { + VersionSelector::new(repo_set.clone(), Some(&mut *handle.borrow_mut()))? + } + None => VersionSelector::new(repo_set.clone(), None)?, + }; let effective_minimum_stability = self.get_minimum_stability(input.clone()); let package = version_selector.find_best_candidate( @@ -539,7 +546,7 @@ pub trait PackageDiscoveryTrait { } // Check if it is a virtual package provided by others - let providers = repo_set.get_providers(name)?; + let providers = repo_set.borrow().get_providers(name)?; if count(&PhpMixed::List( providers.iter().map(|_| Box::new(PhpMixed::Null)).collect(), )) > 0 @@ -823,7 +830,7 @@ pub trait PackageDiscoveryTrait { .into()); } self.get_repos_mut() - .as_mut() + .as_ref() .unwrap() .search(package.to_string(), 0, None) })() { |
