aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authornsfisis <nsfisis@gmail.com>2026-08-02 19:46:36 +0900
committernsfisis <nsfisis@gmail.com>2026-08-02 19:46:36 +0900
commit7db937af313d857d0f66bebaf8ac72d518559bac (patch)
treeb213d5dfe962abc67c1a06188b5cbf6db8b940db
parent97b5211ab3a41d63ea50d0ca1ecfde6ad3323525 (diff)
downloadphp-shirabe-7db937af313d857d0f66bebaf8ac72d518559bac.tar.gz
php-shirabe-7db937af313d857d0f66bebaf8ac72d518559bac.tar.zst
php-shirabe-7db937af313d857d0f66bebaf8ac72d518559bac.zip
fix(repository): restore late-bound initialize in ComposerRepository fallthroughs
findPackage()/findPackages()/search() delegate their non-lazy, non-provider fallthrough to the inner ArrayRepository, whose self-initialization froze the packages array before ComposerRepository::initialize could read the root file, so a plain v1-style repo (inline "packages" in packages.json) always answered empty. Guard the delegations with the same is_initialized() check used by count()/hasPackage(). getProviders() had the inverse defect: PHP reads the raw $this->packages property, but the port went through count(), whose initialize poisoned the initialization flag so the root file would never load afterwards. Check the raw field for non-empty instead, matching PHP's truthiness test. Same defect class as 97b5211a and the 3e367f78 downloader fix. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
-rw-r--r--crates/shirabe/src/repository/composer_repository.rs29
1 files changed, 28 insertions, 1 deletions
diff --git a/crates/shirabe/src/repository/composer_repository.rs b/crates/shirabe/src/repository/composer_repository.rs
index c15c6e12..18de557b 100644
--- a/crates/shirabe/src/repository/composer_repository.rs
+++ b/crates/shirabe/src/repository/composer_repository.rs
@@ -860,6 +860,12 @@ impl ComposerRepository {
return Ok(results);
}
+ // PHP's ArrayRepository::search() calls $this->getPackages(), which
+ // virtual-dispatches to ComposerRepository::initialize(); the guard restores that
+ // (same guard as in count()).
+ if !self.inner.is_initialized() {
+ self.initialize()?;
+ }
let inner_results = self.inner.search(query, mode, None)?;
let converted: Vec<IndexMap<String, PhpMixed>> = inner_results
.into_iter()
@@ -1220,7 +1226,16 @@ impl ComposerRepository {
}
}
- if self.inner.count()? > 0 {
+ // PHP checks the raw $this->packages property (`if ($this->packages)`); going through
+ // count() would run ArrayRepository::initialize() and freeze the initialization flag,
+ // so the root file would never be loaded afterwards.
+ if self
+ .inner
+ .packages
+ .borrow()
+ .as_ref()
+ .is_some_and(|p| !p.is_empty())
+ {
for (k, v) in self.inner.get_providers(package_name.to_string())? {
let mut entry: IndexMap<String, PhpMixed> = IndexMap::new();
entry.insert("name".to_string(), PhpMixed::String(v.name));
@@ -3484,6 +3499,12 @@ impl RepositoryInterface for ComposerRepository {
return Ok(None);
}
+ // PHP's ArrayRepository::findPackage() calls $this->getPackages(), which
+ // virtual-dispatches to ComposerRepository::initialize(); the guard restores that
+ // (same guard as in count()).
+ if !self.inner.is_initialized() {
+ self.initialize()?;
+ }
self.inner.find_package(
&name,
crate::repository::FindPackageConstraint::Constraint(constraint),
@@ -3554,6 +3575,12 @@ impl RepositoryInterface for ComposerRepository {
return Ok(vec![]);
}
+ // PHP's ArrayRepository::findPackages() calls $this->getPackages(), which
+ // virtual-dispatches to ComposerRepository::initialize(); the guard restores that
+ // (same guard as in count()).
+ if !self.inner.is_initialized() {
+ self.initialize()?;
+ }
self.inner.find_packages(
&name,
constraint.map(crate::repository::FindPackageConstraint::Constraint),