diff --git a/xtask/src/main.rs b/xtask/src/main.rs index 40e2a56..7814358 100644 --- a/xtask/src/main.rs +++ b/xtask/src/main.rs @@ -891,21 +891,34 @@ fn validate_cargo_metadata_dependency_closures( root: &Path, failures: &mut Vec, ) -> Result<(), String> { - let mut manifests = Vec::new(); - collect_cargo_manifests(root, &mut manifests)?; - let mut deps_by_package = BTreeMap::new(); - for manifest in manifests { - let policy = load_cargo_manifest_policy(&manifest)?; - let Some(package) = policy.package_name() else { - continue; - }; - deps_by_package.insert(package.to_string(), policy.dependency_names()); - } - + let metadata = workspace_metadata(root)?; + let deps_by_package = workspace_dependency_names(&metadata); validate_package_closure_excludes("fparkan-headless", &deps_by_package, failures); Ok(()) } +/// Returns declared direct dependencies for each workspace package from Cargo's +/// own metadata model. Cargo, rather than a source-text heuristic, resolves +/// package identities and workspace membership before this policy sees them. +fn workspace_dependency_names( + metadata: &cargo_metadata::Metadata, +) -> BTreeMap> { + metadata + .workspace_packages() + .iter() + .map(|package| { + ( + package.name.to_string(), + package + .dependencies + .iter() + .map(|dependency| dependency.name.clone()) + .collect(), + ) + }) + .collect() +} + fn validate_package_closure_excludes( package: &str, deps_by_package: &BTreeMap>, @@ -3481,6 +3494,18 @@ mod tests { Ok(()) } + #[test] + fn workspace_metadata_keeps_headless_closure_platform_free() -> Result<(), String> { + let metadata = workspace_metadata(&workspace_root_path())?; + let dependencies = workspace_dependency_names(&metadata); + let mut failures = Vec::new(); + + validate_package_closure_excludes("fparkan-headless", &dependencies, &mut failures); + + assert!(failures.is_empty(), "{failures:?}"); + Ok(()) + } + #[test] fn parses_manifest_dependencies_for_arch_policy() { let manifest = r#"