From d554b62e1b578a88b796f34e6eb82b5c452cd785 Mon Sep 17 00:00:00 2001 From: nsfisis Date: Sun, 3 May 2026 19:28:56 +0900 Subject: feat(resolver): honour audit.block-abandoned config Read `config.audit.block-abandoned` from composer.json (defaults to false) and propagate it to the resolver. When set, the pool builder skips packages whose `abandoned` field is truthy (`true` or a non-empty replacement string), matching `SecurityAdvisoryPoolFilter`'s behavior in `Composer\DependencyResolver`. With no candidates left, a root require that only matches abandoned versions fails resolution with exit 2. --- crates/mozart/src/commands/update.rs | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'crates/mozart/src/commands/update.rs') diff --git a/crates/mozart/src/commands/update.rs b/crates/mozart/src/commands/update.rs index 6003dd0..0d7d60e 100644 --- a/crates/mozart/src/commands/update.rs +++ b/crates/mozart/src/commands/update.rs @@ -1009,6 +1009,17 @@ pub async fn run( platform.apply_overrides(overrides); } + // Mirrors `Composer\Advisory\AuditConfig::fromConfig`: read + // `config.audit.block-abandoned` straight off composer.json. Defaults to + // false; when true the resolver drops abandoned packages from the pool. + let block_abandoned = composer_json + .extra_fields + .get("config") + .and_then(|c| c.get("audit")) + .and_then(|a| a.get("block-abandoned")) + .and_then(|v| v.as_bool()) + .unwrap_or(false); + let request = ResolveRequest { root_name: composer_json.name.clone(), root_version: composer_json.version.clone(), @@ -1042,6 +1053,7 @@ pub async fn run( .collect(), locked_package_names, locked_packages, + block_abandoned, }; // Step 6: Print header and run resolver @@ -2168,6 +2180,7 @@ mod tests { root_conflict: IndexMap::new(), locked_package_names: IndexSet::new(), locked_packages: Vec::new(), + block_abandoned: false, }; let resolved = resolve(&request).await.expect("Resolution should succeed"); -- cgit v1.3.1