aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authornsfisis <nsfisis@gmail.com>2026-05-04 10:01:20 +0900
committernsfisis <nsfisis@gmail.com>2026-05-04 10:05:06 +0900
commitbc72b70daea7db03456508540f96ab6f019ef5e3 (patch)
tree9d9e01170db00eda88d5f69f21e169762d2bc38c
parentba1463ea86ad25b910fff13d8527ac2c0f661ab4 (diff)
downloadphp-mozart-bc72b70daea7db03456508540f96ab6f019ef5e3.tar.gz
php-mozart-bc72b70daea7db03456508540f96ab6f019ef5e3.tar.zst
php-mozart-bc72b70daea7db03456508540f96ab6f019ef5e3.zip
fix(lockfile): preserve default-branch flag through lock round-trips
ArrayDumper emits `default-branch: true` into the lock for any package that came from a default branch, and ArrayLoader reads it back to synthesize the `9999999-dev` alias inside Locker::getLockedRepository. Mozart was dropping the flag in two places: packagist_version_to_locked_package ignored pv.default_branch when building the lock entry, and locked_package_to_packagist_version hardcoded default_branch=false when re-hydrating a lock-pinned package's metadata for partial updates. The result was that a non-allow-listed default-branch dev package (e.g. f/f in update-changes-url) ended up in the new lock without the marker, so collect_stale_installed_aliases thought its `9999999-dev` alias had been retired and emitted a spurious MarkAliasUninstalled trace.
-rw-r--r--crates/mozart-registry/src/lockfile.rs16
-rw-r--r--crates/mozart/tests/installer.rs9
2 files changed, 16 insertions, 9 deletions
diff --git a/crates/mozart-registry/src/lockfile.rs b/crates/mozart-registry/src/lockfile.rs
index 5a293fe..3ddc6a2 100644
--- a/crates/mozart-registry/src/lockfile.rs
+++ b/crates/mozart-registry/src/lockfile.rs
@@ -580,7 +580,11 @@ fn locked_package_to_packagist_version(pkg: &LockedPackage) -> PackagistVersion
.get("notification-url")
.and_then(|v| v.as_str())
.map(String::from),
- default_branch: false,
+ default_branch: pkg
+ .extra_fields
+ .get("default-branch")
+ .and_then(|v| v.as_bool())
+ .unwrap_or(false),
abandoned: pkg.extra_fields.get("abandoned").cloned(),
}
}
@@ -742,6 +746,16 @@ fn packagist_version_to_locked_package(name: &str, pv: &PackagistVersion) -> Loc
extra_fields.insert("abandoned".to_string(), abandoned.clone());
}
}
+ // Propagate `default-branch: true` so the lock surface — and the
+ // installed.json round-trip — keeps the marker that drives Composer's
+ // synthetic `9999999-dev` alias for default-branch dev packages.
+ // Without this, `Locker::getLockedRepository` (which Mozart mirrors via
+ // `collect_stale_installed_aliases` / `lock_alias_pretty_pairs`) can't
+ // tell that the package's default branch is still aliased and emits a
+ // spurious `MarkAliasUninstalled` for the missing `9999999-dev` alias.
+ if pv.default_branch {
+ extra_fields.insert("default-branch".to_string(), serde_json::Value::Bool(true));
+ }
LockedPackage {
name: name.to_string(),
diff --git a/crates/mozart/tests/installer.rs b/crates/mozart/tests/installer.rs
index b1c1968..78772fb 100644
--- a/crates/mozart/tests/installer.rs
+++ b/crates/mozart/tests/installer.rs
@@ -234,13 +234,6 @@ macro_rules! installer_fixture {
run_installer_fixture(stringify!($name));
}
};
- ($name:ident, ignore) => {
- #[test]
- #[ignore = "not implemented yet"]
- fn $name() {
- run_installer_fixture(stringify!($name));
- }
- };
}
installer_fixture!(abandoned_listed);
@@ -394,7 +387,7 @@ installer_fixture!(update_allow_list_with_dependencies_require_new);
installer_fixture!(update_allow_list_with_dependencies_require_new_replace);
installer_fixture!(update_allow_list_with_dependencies_require_new_replace_mutual);
installer_fixture!(update_allow_list_with_dependency_conflict);
-installer_fixture!(update_changes_url, ignore);
+installer_fixture!(update_changes_url);
installer_fixture!(update_dev_ignores_providers);
installer_fixture!(update_dev_packages_updates_repo_url);
installer_fixture!(update_dev_to_new_ref_picks_up_changes);