diff options
author | Treehugger Robot <android-test-infra-autosubmit@system.gserviceaccount.com> | 2024-05-13 16:23:27 +0000 |
---|---|---|
committer | Gerrit Code Review <noreply-gerritcodereview@google.com> | 2024-05-13 16:23:27 +0000 |
commit | 1cd8b42dfa667bed22fc90f2d4d391b11a16fbcb (patch) | |
tree | 4770e30be21cedd5fd2454c5c07f87d075e047fe | |
parent | 28a349948744486a975733437109765c6b1a78dd (diff) | |
parent | f7414a24d31ad0e31d3ac5eb720e53064c7e3af0 (diff) | |
download | development-1cd8b42dfa667bed22fc90f2d4d391b11a16fbcb.tar.gz |
Merge "Use extra_cfg for dependency resolution too." into main
-rw-r--r-- | tools/cargo_embargo/src/cargo/metadata.rs | 163 |
1 files changed, 151 insertions, 12 deletions
diff --git a/tools/cargo_embargo/src/cargo/metadata.rs b/tools/cargo_embargo/src/cargo/metadata.rs index 5f146f02f..127c81630 100644 --- a/tools/cargo_embargo/src/cargo/metadata.rs +++ b/tools/cargo_embargo/src/cargo/metadata.rs @@ -24,12 +24,12 @@ use std::path::{Path, PathBuf}; /// `cfg` strings for dependencies which should be considered enabled. It would be better to parse /// them properly, but this is good enough in practice so far. const ENABLED_CFGS: [&str; 6] = [ - r#"cfg(unix)"#, - r#"cfg(not(windows))"#, - r#"cfg(any(unix, target_os = "wasi"))"#, - r#"cfg(not(all(target_family = "wasm", target_os = "unknown")))"#, - r#"cfg(not(target_family = "wasm"))"#, - r#"cfg(any(target_os = "linux", target_os = "android"))"#, + r#"unix"#, + r#"not(windows)"#, + r#"any(unix, target_os = "wasi")"#, + r#"not(all(target_family = "wasm", target_os = "unknown"))"#, + r#"not(target_family = "wasm")"#, + r#"any(target_os = "linux", target_os = "android")"#, ]; /// `cargo metadata` output. @@ -39,7 +39,7 @@ pub struct WorkspaceMetadata { pub workspace_members: Vec<String>, } -#[derive(Clone, Debug, Deserialize, Eq, PartialEq)] +#[derive(Clone, Debug, Default, Deserialize, Eq, PartialEq)] pub struct PackageMetadata { pub name: String, pub version: String, @@ -62,17 +62,20 @@ pub struct DependencyMetadata { impl DependencyMetadata { /// Returns whether the dependency should be included when the given features are enabled. - fn enabled(&self, features: &[String]) -> bool { + fn enabled(&self, features: &[String], cfgs: &[String]) -> bool { if let Some(target) = &self.target { - if !ENABLED_CFGS.contains(&target.as_str()) { - return false; + if target.starts_with("cfg(") && target.ends_with(')') { + let target_cfg = &target[4..target.len() - 1]; + if !ENABLED_CFGS.contains(&target_cfg) && !cfgs.contains(&target_cfg.to_string()) { + return false; + } } } !self.optional || features.contains(&format!("dep:{}", self.name)) } } -#[derive(Clone, Debug, Deserialize, Eq, PartialEq)] +#[derive(Clone, Debug, Default, Deserialize, Eq, PartialEq)] #[allow(dead_code)] pub struct TargetMetadata { pub crate_types: Vec<CrateType>, @@ -172,6 +175,7 @@ fn parse_cargo_metadata( package, &metadata.packages, &features, + cfgs, &target_kinds, false, )?, @@ -195,6 +199,7 @@ fn parse_cargo_metadata( package, &metadata.packages, &features, + cfgs, &target_kinds, true, )?, @@ -211,6 +216,7 @@ fn get_externs( package: &PackageMetadata, packages: &[PackageMetadata], features: &[String], + cfgs: &[String], target_kinds: &[TargetKind], test: bool, ) -> Result<Vec<Extern>> { @@ -219,7 +225,7 @@ fn get_externs( .iter() .filter_map(|dependency| { // Kind is None for normal dependencies, as opposed to dev dependencies. - if dependency.enabled(features) + if dependency.enabled(features, cfgs) && dependency.kind.as_deref() != Some("build") && (dependency.kind.is_none() || test) { @@ -443,6 +449,139 @@ mod tests { } #[test] + fn get_externs_cfg() { + let package = PackageMetadata { + name: "test_package".to_string(), + dependencies: vec![ + DependencyMetadata { + name: "alwayslib".to_string(), + kind: None, + optional: false, + target: None, + rename: None, + }, + DependencyMetadata { + name: "unixlib".to_string(), + kind: None, + optional: false, + target: Some("cfg(unix)".to_string()), + rename: None, + }, + DependencyMetadata { + name: "windowslib".to_string(), + kind: None, + optional: false, + target: Some("cfg(windows)".to_string()), + rename: None, + }, + ], + features: [].into_iter().collect(), + targets: vec![], + ..Default::default() + }; + let packages = vec![ + package.clone(), + PackageMetadata { + name: "alwayslib".to_string(), + targets: vec![TargetMetadata { + name: "alwayslib".to_string(), + kind: vec![TargetKind::Lib], + ..Default::default() + }], + ..Default::default() + }, + PackageMetadata { + name: "unixlib".to_string(), + targets: vec![TargetMetadata { + name: "unixlib".to_string(), + kind: vec![TargetKind::Lib], + ..Default::default() + }], + ..Default::default() + }, + PackageMetadata { + name: "windowslib".to_string(), + targets: vec![TargetMetadata { + name: "windowslib".to_string(), + kind: vec![TargetKind::Lib], + ..Default::default() + }], + ..Default::default() + }, + ]; + assert_eq!( + get_externs(&package, &packages, &[], &[], &[], false).unwrap(), + vec![ + Extern { + name: "alwayslib".to_string(), + lib_name: "alwayslib".to_string(), + extern_type: ExternType::Rust + }, + Extern { + name: "unixlib".to_string(), + lib_name: "unixlib".to_string(), + extern_type: ExternType::Rust + }, + ] + ); + } + + #[test] + fn get_externs_extra_cfg() { + let package = PackageMetadata { + name: "test_package".to_string(), + dependencies: vec![ + DependencyMetadata { + name: "foolib".to_string(), + kind: None, + optional: false, + target: Some("cfg(foo)".to_string()), + rename: None, + }, + DependencyMetadata { + name: "barlib".to_string(), + kind: None, + optional: false, + target: Some("cfg(bar)".to_string()), + rename: None, + }, + ], + features: [].into_iter().collect(), + targets: vec![], + ..Default::default() + }; + let packages = vec![ + package.clone(), + PackageMetadata { + name: "foolib".to_string(), + targets: vec![TargetMetadata { + name: "foolib".to_string(), + kind: vec![TargetKind::Lib], + ..Default::default() + }], + ..Default::default() + }, + PackageMetadata { + name: "barlib".to_string(), + targets: vec![TargetMetadata { + name: "barlib".to_string(), + kind: vec![TargetKind::Lib], + ..Default::default() + }], + ..Default::default() + }, + ]; + assert_eq!( + get_externs(&package, &packages, &[], &["foo".to_string()], &[], false).unwrap(), + vec![Extern { + name: "foolib".to_string(), + lib_name: "foolib".to_string(), + extern_type: ExternType::Rust + },] + ); + } + + #[test] fn parse_metadata() { /// Remove anything before "external/rust/crates/" from the /// `package_dir` field. This makes the test robust since you |