aboutsummaryrefslogtreecommitdiffhomepage
path: root/crates/mozart
diff options
context:
space:
mode:
authornsfisis <nsfisis@gmail.com>2026-05-01 22:02:32 +0900
committernsfisis <nsfisis@gmail.com>2026-05-01 22:02:32 +0900
commit8a87adf120d5057b06d0474b293fab079e1ce967 (patch)
tree9dc4327244216e9bddf8aace63405e66f1b7d0fb /crates/mozart
parentbaa40325659a44938ad2e9ad6525ea3b3aaacfe2 (diff)
downloadphp-mozart-8a87adf120d5057b06d0474b293fab079e1ce967.tar.gz
php-mozart-8a87adf120d5057b06d0474b293fab079e1ce967.tar.zst
php-mozart-8a87adf120d5057b06d0474b293fab079e1ce967.zip
fix(install): preserve LockedPackage extra_fields in installed.json
Composer's InstalledFilesystemRepository::write() dumps the full package via ArrayDumper, so flags like `abandoned` and `default-branch` (which Mozart parks in LockedPackage::extra_fields) should round-trip from composer.lock into vendor/composer/installed.json. locked_to_installed_entry was zeroing the destination's extra_fields, silently stripping these flags every time installed.json got rewritten. Carry the extra_fields map across verbatim. The install-forces-reinstall-if-abandon-changes installer fixture is already exit-0 green at the harness layer; this aligns the actual end-state with Composer's EXPECT-INSTALLED so a future EXPECT-INSTALLED comparison won't re-flag this gap. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Diffstat (limited to 'crates/mozart')
-rw-r--r--crates/mozart/src/commands/install.rs35
-rw-r--r--crates/mozart/tests/installer.rs5
2 files changed, 35 insertions, 5 deletions
diff --git a/crates/mozart/src/commands/install.rs b/crates/mozart/src/commands/install.rs
index b9ff1af..a10dd69 100644
--- a/crates/mozart/src/commands/install.rs
+++ b/crates/mozart/src/commands/install.rs
@@ -204,6 +204,11 @@ pub fn compute_operations<'a>(
}
/// Convert a LockedPackage to an InstalledPackageEntry.
+///
+/// `LockedPackage::extra_fields` is forwarded verbatim so flags like
+/// `abandoned` and `default-branch` survive the lock → installed.json round
+/// trip, matching Composer's `InstalledFilesystemRepository::write()` (which
+/// dumps the full package via `ArrayDumper`).
pub fn locked_to_installed_entry(
pkg: &lockfile::LockedPackage,
_vendor_dir: &Path,
@@ -227,7 +232,7 @@ pub fn locked_to_installed_entry(
install_path: Some(install_path),
autoload: pkg.autoload.clone(),
aliases: vec![],
- extra_fields: BTreeMap::new(),
+ extra_fields: pkg.extra_fields.clone(),
}
}
@@ -1122,6 +1127,34 @@ mod tests {
assert!(entry.dist.is_some());
}
+ #[test]
+ fn test_locked_to_installed_entry_propagates_extra_fields() {
+ // Composer's installed.json carries package flags like `abandoned` and
+ // `default-branch` that LockedPackage stores in extra_fields. Make sure
+ // they survive the conversion so we don't strip them on rewrite.
+ let dir = tempdir().unwrap();
+ let vendor_dir = dir.path().join("vendor");
+
+ let mut pkg = make_locked_package("a/a", "1.0.0");
+ pkg.extra_fields.insert(
+ "abandoned".to_string(),
+ serde_json::Value::String("replacement".to_string()),
+ );
+ pkg.extra_fields
+ .insert("default-branch".to_string(), serde_json::Value::Bool(true));
+
+ let entry = locked_to_installed_entry(&pkg, &vendor_dir);
+
+ assert_eq!(
+ entry.extra_fields.get("abandoned"),
+ Some(&serde_json::Value::String("replacement".to_string()))
+ );
+ assert_eq!(
+ entry.extra_fields.get("default-branch"),
+ Some(&serde_json::Value::Bool(true))
+ );
+ }
+
// -----------------------------------------------------------------------
// installed.json generation tests
// -----------------------------------------------------------------------
diff --git a/crates/mozart/tests/installer.rs b/crates/mozart/tests/installer.rs
index 314771c..7af07b5 100644
--- a/crates/mozart/tests/installer.rs
+++ b/crates/mozart/tests/installer.rs
@@ -242,10 +242,7 @@ installer_fixture!(
install_dev_using_dist,
ignore = "mozart binary cannot yet run this fixture"
);
-installer_fixture!(
- install_forces_reinstall_if_abandon_changes,
- ignore = "mozart binary cannot yet run this fixture"
-);
+installer_fixture!(install_forces_reinstall_if_abandon_changes);
installer_fixture!(
install_from_incomplete_lock,
ignore = "mozart binary cannot yet run this fixture"