diff options
Diffstat (limited to 'crates/shirabe/src/repository')
18 files changed, 87 insertions, 78 deletions
diff --git a/crates/shirabe/src/repository/array_repository.rs b/crates/shirabe/src/repository/array_repository.rs index 09c37766..30598b62 100644 --- a/crates/shirabe/src/repository/array_repository.rs +++ b/crates/shirabe/src/repository/array_repository.rs @@ -205,6 +205,16 @@ impl ArrayRepository { *self.packages.borrow_mut() = Some(vec![]); } + /// Shared body of `RepositoryInterface::count`, kept on `&self` for `get_repo_name` (PHP's + /// `getRepoName` also triggers lazy initialization through `count()`). + pub(crate) fn base_count(&self) -> usize { + if self.packages.borrow().is_none() { + self.initialize(); + } + + self.packages.borrow().as_ref().unwrap().len() + } + /// Resets the packages cache so the next access re-runs `initialize`. pub(crate) fn reset_packages(&self) { *self.packages.borrow_mut() = None; @@ -217,16 +227,12 @@ impl ArrayRepository { impl RepositoryInterface for ArrayRepository { /// Returns the number of packages in this repository - fn count(&self) -> anyhow::Result<usize> { - if self.packages.borrow().is_none() { - self.initialize(); - } - - Ok(self.packages.borrow().as_ref().unwrap().len()) + fn count(&mut self) -> anyhow::Result<usize> { + Ok(self.base_count()) } fn get_repo_name(&self) -> String { - let count = self.count().expect("ArrayRepository::count is infallible"); + let count = self.base_count(); format!( "array repo (defining {} package{})", count, @@ -409,7 +415,7 @@ impl RepositoryInterface for ArrayRepository { Ok(matches.into_values().collect()) } - fn has_package(&self, package: PackageInterfaceHandle) -> bool { + fn has_package(&mut self, package: PackageInterfaceHandle) -> anyhow::Result<bool> { if self.package_map.borrow().is_none() { let mut map: IndexMap<String, BasePackageHandle> = IndexMap::new(); for repo_package in self.get_packages_internal() { @@ -418,11 +424,12 @@ impl RepositoryInterface for ArrayRepository { *self.package_map.borrow_mut() = Some(map); } - self.package_map + Ok(self + .package_map .borrow() .as_ref() .unwrap() - .contains_key(&package.get_unique_name()) + .contains_key(&package.get_unique_name())) } fn get_providers( diff --git a/crates/shirabe/src/repository/artifact_repository.rs b/crates/shirabe/src/repository/artifact_repository.rs index 7d9c02b6..f18f7f04 100644 --- a/crates/shirabe/src/repository/artifact_repository.rs +++ b/crates/shirabe/src/repository/artifact_repository.rs @@ -247,16 +247,13 @@ impl RepositoryInterface for ArtifactRepository { // The structural methods are inherited from ArrayRepository in PHP, where the lazy directory // scan is driven by the overridden initialize(). Here each one first ensures that scan has // happened (see ensure_initialized), then delegates to the inner ArrayRepository. - fn count(&self) -> anyhow::Result<usize> { + fn count(&mut self) -> anyhow::Result<usize> { self.ensure_initialized()?; self.inner.count() } - fn has_package(&self, package: PackageInterfaceHandle) -> bool { - // TODO(phase-d): hasPackage returns bool and cannot surface an initialization error; a - // failed scan leaves the inner repository with whatever packages were added before the - // failure. - let _ = self.ensure_initialized(); + fn has_package(&mut self, package: PackageInterfaceHandle) -> anyhow::Result<bool> { + self.ensure_initialized()?; self.inner.has_package(package) } diff --git a/crates/shirabe/src/repository/composer_repository.rs b/crates/shirabe/src/repository/composer_repository.rs index 558d7e00..ba68d22c 100644 --- a/crates/shirabe/src/repository/composer_repository.rs +++ b/crates/shirabe/src/repository/composer_repository.rs @@ -79,15 +79,6 @@ pub struct ProviderListingEntry { #[derive(Debug)] pub struct ComposerRepository { - // TODO(phase-c): PHP's ArrayRepository methods that aren't overridden here (findPackage, - // findPackages, count, hasPackage) call $this->getPackages(), which virtual-dispatches back - // to ComposerRepository::getPackages() (see its "embedded inheritance does not dispatch back - // to the wrapper" comment below, and the identical guard in load_packages()). Composition - // doesn't get that dispatch for free: self.inner.find_package()/find_packages()/count()/ - // has_package() below call ArrayRepository::initialize() (a no-op stub) instead, and will - // silently see an empty package list if called before get_packages()/load_packages() has - // run once on this instance. Not yet known to be hit by any test; audit call sites and add - // the same `if !self.inner.is_initialized() { self.initialize()?; }` guard where needed. inner: ArrayRepository, /// Weak reference to the outermost repository handle wrapping this `ComposerRepository`, /// injected via `set_self_handle`. Used to wire package -> repository back-references. @@ -3409,11 +3400,20 @@ fn clone_root_data(rd: &RootData) -> RootData { } impl RepositoryInterface for ComposerRepository { - fn count(&self) -> anyhow::Result<usize> { + // PHP's ArrayRepository::count()/hasPackage() call $this->initialize(), which + // virtual-dispatches to ComposerRepository::initialize(); the guard restores that + // (same guard as in get_packages()). + fn count(&mut self) -> anyhow::Result<usize> { + if !self.inner.is_initialized() { + self.initialize()?; + } self.inner.count() } - fn has_package(&self, package: PackageInterfaceHandle) -> bool { + fn has_package(&mut self, package: PackageInterfaceHandle) -> anyhow::Result<bool> { + if !self.inner.is_initialized() { + self.initialize()?; + } self.inner.has_package(package) } diff --git a/crates/shirabe/src/repository/composite_repository.rs b/crates/shirabe/src/repository/composite_repository.rs index 9e5c9757..a9c55a0f 100644 --- a/crates/shirabe/src/repository/composite_repository.rs +++ b/crates/shirabe/src/repository/composite_repository.rs @@ -60,7 +60,7 @@ impl CompositeRepository { } impl RepositoryInterface for CompositeRepository { - fn count(&self) -> anyhow::Result<usize> { + fn count(&mut self) -> anyhow::Result<usize> { let mut total = 0; for repository in &self.repositories { total += repository.count()?; @@ -78,13 +78,13 @@ impl RepositoryInterface for CompositeRepository { format!("composite repo ({})", names.join(", ")) } - fn has_package(&self, package: PackageInterfaceHandle) -> bool { + fn has_package(&mut self, package: PackageInterfaceHandle) -> anyhow::Result<bool> { for repository in &self.repositories { - if repository.has_package(package.clone()) { - return true; + if repository.has_package(package.clone())? { + return Ok(true); } } - false + Ok(false) } fn find_package( diff --git a/crates/shirabe/src/repository/filesystem_repository.rs b/crates/shirabe/src/repository/filesystem_repository.rs index d4b9b72e..9186a836 100644 --- a/crates/shirabe/src/repository/filesystem_repository.rs +++ b/crates/shirabe/src/repository/filesystem_repository.rs @@ -716,11 +716,15 @@ impl FilesystemRepository { } impl RepositoryInterface for FilesystemRepository { - fn count(&self) -> anyhow::Result<usize> { + // PHP's ArrayRepository::count()/hasPackage() call $this->initialize(), which + // virtual-dispatches to FilesystemRepository::initialize(); the guard restores that. + fn count(&mut self) -> anyhow::Result<usize> { + self.ensure_initialized()?; self.inner.count() } - fn has_package(&self, package: PackageInterfaceHandle) -> bool { + fn has_package(&mut self, package: PackageInterfaceHandle) -> anyhow::Result<bool> { + self.ensure_initialized()?; self.inner.has_package(package) } diff --git a/crates/shirabe/src/repository/filter_repository.rs b/crates/shirabe/src/repository/filter_repository.rs index bdf17c54..32a32ba1 100644 --- a/crates/shirabe/src/repository/filter_repository.rs +++ b/crates/shirabe/src/repository/filter_repository.rs @@ -148,7 +148,7 @@ impl FilterRepository { } impl RepositoryInterface for FilterRepository { - fn count(&self) -> anyhow::Result<usize> { + fn count(&mut self) -> anyhow::Result<usize> { if self.repo.count()? > 0 { Ok(self .repo @@ -161,7 +161,7 @@ impl RepositoryInterface for FilterRepository { } } - fn has_package(&self, package: PackageInterfaceHandle) -> bool { + fn has_package(&mut self, package: PackageInterfaceHandle) -> anyhow::Result<bool> { self.repo.has_package(package) } diff --git a/crates/shirabe/src/repository/handle.rs b/crates/shirabe/src/repository/handle.rs index f093f66b..497e2b91 100644 --- a/crates/shirabe/src/repository/handle.rs +++ b/crates/shirabe/src/repository/handle.rs @@ -84,7 +84,7 @@ impl RepositoryInterfaceHandle { } pub fn count(&self) -> anyhow::Result<usize> { - self.0.borrow().count() + self.0.borrow_mut().count() } pub fn get_repo_name(&self) -> String { @@ -95,8 +95,8 @@ impl RepositoryInterfaceHandle { self.0.borrow_mut().get_packages() } - pub fn has_package(&self, package: PackageInterfaceHandle) -> bool { - self.0.borrow().has_package(package) + pub fn has_package(&self, package: PackageInterfaceHandle) -> anyhow::Result<bool> { + self.0.borrow_mut().has_package(package) } pub fn find_package( diff --git a/crates/shirabe/src/repository/installed_array_repository.rs b/crates/shirabe/src/repository/installed_array_repository.rs index dd0f7d38..b458ff61 100644 --- a/crates/shirabe/src/repository/installed_array_repository.rs +++ b/crates/shirabe/src/repository/installed_array_repository.rs @@ -39,10 +39,7 @@ impl InstalledRepositoryInterface for InstalledArrayRepository { } fn is_fresh(&self) -> bool { - self.inner - .count() - .expect("WritableArrayRepository::count is infallible") - == 0 + self.inner.base_count() == 0 } } @@ -82,11 +79,11 @@ impl WritableRepositoryInterface for InstalledArrayRepository { } impl RepositoryInterface for InstalledArrayRepository { - fn count(&self) -> anyhow::Result<usize> { + fn count(&mut self) -> anyhow::Result<usize> { self.inner.count() } - fn has_package(&self, package: PackageInterfaceHandle) -> bool { + fn has_package(&mut self, package: PackageInterfaceHandle) -> anyhow::Result<bool> { self.inner.has_package(package) } fn find_package( diff --git a/crates/shirabe/src/repository/installed_filesystem_repository.rs b/crates/shirabe/src/repository/installed_filesystem_repository.rs index 7fab762a..85fb514b 100644 --- a/crates/shirabe/src/repository/installed_filesystem_repository.rs +++ b/crates/shirabe/src/repository/installed_filesystem_repository.rs @@ -113,11 +113,11 @@ impl WritableRepositoryInterface for InstalledFilesystemRepository { } impl RepositoryInterface for InstalledFilesystemRepository { - fn count(&self) -> anyhow::Result<usize> { + fn count(&mut self) -> anyhow::Result<usize> { self.inner.count() } - fn has_package(&self, package: PackageInterfaceHandle) -> bool { + fn has_package(&mut self, package: PackageInterfaceHandle) -> anyhow::Result<bool> { self.inner.has_package(package) } fn find_package( diff --git a/crates/shirabe/src/repository/installed_repository.rs b/crates/shirabe/src/repository/installed_repository.rs index 388670d4..08b1f36b 100644 --- a/crates/shirabe/src/repository/installed_repository.rs +++ b/crates/shirabe/src/repository/installed_repository.rs @@ -376,7 +376,7 @@ impl InstalledRepository { } impl RepositoryInterface for InstalledRepository { - fn count(&self) -> anyhow::Result<usize> { + fn count(&mut self) -> anyhow::Result<usize> { self.inner.count() } @@ -390,7 +390,7 @@ impl RepositoryInterface for InstalledRepository { format!("installed repo ({})", names.join(", ")) } - fn has_package(&self, package: PackageInterfaceHandle) -> bool { + fn has_package(&mut self, package: PackageInterfaceHandle) -> anyhow::Result<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 390fae38..8b909fbc 100644 --- a/crates/shirabe/src/repository/lock_array_repository.rs +++ b/crates/shirabe/src/repository/lock_array_repository.rs @@ -31,11 +31,11 @@ impl LockArrayRepository { } impl RepositoryInterface for LockArrayRepository { - fn count(&self) -> anyhow::Result<usize> { + fn count(&mut self) -> anyhow::Result<usize> { self.inner.count() } - fn has_package(&self, package: PackageInterfaceHandle) -> bool { + fn has_package(&mut self, package: PackageInterfaceHandle) -> anyhow::Result<bool> { self.inner.has_package(package) } diff --git a/crates/shirabe/src/repository/package_repository.rs b/crates/shirabe/src/repository/package_repository.rs index 3397f071..06b28451 100644 --- a/crates/shirabe/src/repository/package_repository.rs +++ b/crates/shirabe/src/repository/package_repository.rs @@ -108,16 +108,13 @@ impl RepositoryInterface for PackageRepository { // The structural methods are inherited from ArrayRepository in PHP, where the lazy package load // is driven by the overridden initialize(). Here each one first ensures that load has happened // (see ensure_initialized), then delegates to the inner ArrayRepository. - fn count(&self) -> anyhow::Result<usize> { + fn count(&mut self) -> anyhow::Result<usize> { self.ensure_initialized()?; self.inner.count() } - fn has_package(&self, package: PackageInterfaceHandle) -> bool { - // TODO(phase-d): hasPackage returns bool and cannot surface an initialization error; a - // failed load leaves the inner repository with whatever packages were added before the - // failure. - let _ = self.ensure_initialized(); + fn has_package(&mut self, package: PackageInterfaceHandle) -> anyhow::Result<bool> { + self.ensure_initialized()?; self.inner.has_package(package) } diff --git a/crates/shirabe/src/repository/path_repository.rs b/crates/shirabe/src/repository/path_repository.rs index d7f24fa7..879b769c 100644 --- a/crates/shirabe/src/repository/path_repository.rs +++ b/crates/shirabe/src/repository/path_repository.rs @@ -141,7 +141,7 @@ impl PathRepository { ) -> anyhow::Result<bool> { self.initialize()?; use crate::repository::RepositoryInterface; - Ok(self.inner.has_package(package)) + self.inner.has_package(package) } // In PHP the inherited ArrayRepository methods lazily call the overridden initialize() to glob @@ -397,16 +397,13 @@ impl RepositoryInterface for PathRepository { // The structural methods are inherited from ArrayRepository in PHP, where the lazy package load // is driven by the overridden initialize(). Here each one first ensures that load has happened // (see ensure_initialized), then delegates to the inner ArrayRepository. - fn count(&self) -> anyhow::Result<usize> { + fn count(&mut self) -> anyhow::Result<usize> { self.ensure_initialized()?; self.inner.count() } - fn has_package(&self, package: PackageInterfaceHandle) -> bool { - // TODO(phase-d): hasPackage returns bool and cannot surface an initialization error; a - // failed load leaves the inner repository with whatever packages were added before the - // failure. - let _ = self.ensure_initialized(); + fn has_package(&mut self, package: PackageInterfaceHandle) -> anyhow::Result<bool> { + self.ensure_initialized()?; self.inner.has_package(package) } diff --git a/crates/shirabe/src/repository/platform_repository.rs b/crates/shirabe/src/repository/platform_repository.rs index e4d93d3b..30164237 100644 --- a/crates/shirabe/src/repository/platform_repository.rs +++ b/crates/shirabe/src/repository/platform_repository.rs @@ -1866,11 +1866,15 @@ impl PlatformRepository { } impl crate::repository::RepositoryInterface for PlatformRepository { - fn count(&self) -> anyhow::Result<usize> { + // PHP's ArrayRepository::count()/hasPackage() call $this->initialize(), which + // virtual-dispatches to PlatformRepository::initialize(); the guard restores that. + fn count(&mut self) -> anyhow::Result<usize> { + self.ensure_initialized()?; self.inner.count() } - fn has_package(&self, package: PackageInterfaceHandle) -> bool { + fn has_package(&mut self, package: PackageInterfaceHandle) -> anyhow::Result<bool> { + self.ensure_initialized()?; self.inner.has_package(package) } diff --git a/crates/shirabe/src/repository/repository_interface.rs b/crates/shirabe/src/repository/repository_interface.rs index 6dbc01da..ab25242c 100644 --- a/crates/shirabe/src/repository/repository_interface.rs +++ b/crates/shirabe/src/repository/repository_interface.rs @@ -52,9 +52,13 @@ pub const SEARCH_NAME: i64 = 1; pub const SEARCH_VENDOR: i64 = 2; pub trait RepositoryInterface: std::fmt::Debug { - fn count(&self) -> anyhow::Result<usize>; + // count/has_package take &mut self (and has_package returns Result) because PHP's + // ArrayRepository::count()/hasPackage() late-bind $this->initialize() to the concrete + // repository class, which lazily loads packages and can throw; lazy repositories need the + // same guard here (see FilesystemRepository/PlatformRepository/ComposerRepository). + fn count(&mut self) -> anyhow::Result<usize>; - fn has_package(&self, package: PackageInterfaceHandle) -> bool; + fn has_package(&mut self, package: PackageInterfaceHandle) -> anyhow::Result<bool>; fn find_package( &mut self, diff --git a/crates/shirabe/src/repository/root_package_repository.rs b/crates/shirabe/src/repository/root_package_repository.rs index 4357ed69..7630f6c5 100644 --- a/crates/shirabe/src/repository/root_package_repository.rs +++ b/crates/shirabe/src/repository/root_package_repository.rs @@ -26,11 +26,11 @@ impl RootPackageRepository { } impl RepositoryInterface for RootPackageRepository { - fn count(&self) -> anyhow::Result<usize> { + fn count(&mut self) -> anyhow::Result<usize> { self.inner.count() } - fn has_package(&self, package: PackageInterfaceHandle) -> bool { + fn has_package(&mut self, package: PackageInterfaceHandle) -> anyhow::Result<bool> { self.inner.has_package(package) } diff --git a/crates/shirabe/src/repository/vcs_repository.rs b/crates/shirabe/src/repository/vcs_repository.rs index c04b1b67..b7ce1a6c 100644 --- a/crates/shirabe/src/repository/vcs_repository.rs +++ b/crates/shirabe/src/repository/vcs_repository.rs @@ -1053,16 +1053,13 @@ impl RepositoryInterface for VcsRepository { // The structural methods are inherited from ArrayRepository in PHP, where the lazy package load // is driven by the overridden initialize(). Here each one first ensures that load has happened // (see ensure_initialized), then delegates to the inner ArrayRepository. - fn count(&self) -> anyhow::Result<usize> { + fn count(&mut self) -> anyhow::Result<usize> { self.ensure_initialized()?; self.inner.count() } - fn has_package(&self, package: PackageInterfaceHandle) -> bool { - // TODO(phase-d): hasPackage returns bool and cannot surface an initialization error; a - // failed load leaves the inner repository with whatever packages were added before the - // failure. - let _ = self.ensure_initialized(); + fn has_package(&mut self, package: PackageInterfaceHandle) -> anyhow::Result<bool> { + self.ensure_initialized()?; 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 e415a1e1..f5db2bd9 100644 --- a/crates/shirabe/src/repository/writable_array_repository.rs +++ b/crates/shirabe/src/repository/writable_array_repository.rs @@ -31,6 +31,11 @@ impl WritableArrayRepository { self.dev_mode } + /// See `ArrayRepository::base_count`; kept on `&self` for `is_fresh` callers. + pub(crate) fn base_count(&self) -> usize { + self.inner.base_count() + } + pub fn set_dev_package_names(&mut self, dev_package_names: Vec<String>) { self.dev_package_names = dev_package_names; } @@ -124,11 +129,11 @@ impl WritableArrayRepository { } impl RepositoryInterface for WritableArrayRepository { - fn count(&self) -> anyhow::Result<usize> { + fn count(&mut self) -> anyhow::Result<usize> { self.inner.count() } - fn has_package(&self, package: PackageInterfaceHandle) -> bool { + fn has_package(&mut self, package: PackageInterfaceHandle) -> anyhow::Result<bool> { self.inner.has_package(package) } |
