summaryrefslogtreecommitdiffstats
path: root/src/tools/cargo/crates/cargo-test-support
diff options
context:
space:
mode:
Diffstat (limited to 'src/tools/cargo/crates/cargo-test-support')
-rw-r--r--src/tools/cargo/crates/cargo-test-support/Cargo.toml4
-rw-r--r--src/tools/cargo/crates/cargo-test-support/build.rs2
-rw-r--r--src/tools/cargo/crates/cargo-test-support/src/compare.rs37
-rw-r--r--src/tools/cargo/crates/cargo-test-support/src/lib.rs27
-rw-r--r--src/tools/cargo/crates/cargo-test-support/src/paths.rs12
-rw-r--r--src/tools/cargo/crates/cargo-test-support/src/registry.rs59
-rw-r--r--src/tools/cargo/crates/cargo-test-support/src/tools.rs32
7 files changed, 138 insertions, 35 deletions
diff --git a/src/tools/cargo/crates/cargo-test-support/Cargo.toml b/src/tools/cargo/crates/cargo-test-support/Cargo.toml
index fc32e1c9c..1098d598d 100644
--- a/src/tools/cargo/crates/cargo-test-support/Cargo.toml
+++ b/src/tools/cargo/crates/cargo-test-support/Cargo.toml
@@ -29,6 +29,10 @@ tar.workspace = true
time.workspace = true
toml.workspace = true
url.workspace = true
+walkdir.workspace = true
[target.'cfg(windows)'.dependencies]
windows-sys = { workspace = true, features = ["Win32_Storage_FileSystem"] }
+
+[lints]
+workspace = true
diff --git a/src/tools/cargo/crates/cargo-test-support/build.rs b/src/tools/cargo/crates/cargo-test-support/build.rs
index 478da7d99..8854f461a 100644
--- a/src/tools/cargo/crates/cargo-test-support/build.rs
+++ b/src/tools/cargo/crates/cargo-test-support/build.rs
@@ -1,3 +1,5 @@
+#![allow(clippy::disallowed_methods)]
+
fn main() {
println!(
"cargo:rustc-env=NATIVE_ARCH={}",
diff --git a/src/tools/cargo/crates/cargo-test-support/src/compare.rs b/src/tools/cargo/crates/cargo-test-support/src/compare.rs
index d9e8d5454..fc1663d34 100644
--- a/src/tools/cargo/crates/cargo-test-support/src/compare.rs
+++ b/src/tools/cargo/crates/cargo-test-support/src/compare.rs
@@ -591,15 +591,36 @@ fn find_json_mismatch_r<'a>(
.next()
}
(&Object(ref l), &Object(ref r)) => {
- let same_keys = l.len() == r.len() && l.keys().all(|k| r.contains_key(k));
- if !same_keys {
- return Some((expected, actual));
+ let mut expected_entries = l.iter();
+ let mut actual_entries = r.iter();
+
+ // Compilers older than 1.76 do not produce $message_type.
+ // Treat it as optional for now.
+ let mut expected_entries_without_message_type;
+ let expected_entries: &mut dyn Iterator<Item = _> =
+ if l.contains_key("$message_type") && !r.contains_key("$message_type") {
+ expected_entries_without_message_type =
+ expected_entries.filter(|entry| entry.0 != "$message_type");
+ &mut expected_entries_without_message_type
+ } else {
+ &mut expected_entries
+ };
+
+ loop {
+ match (expected_entries.next(), actual_entries.next()) {
+ (None, None) => return None,
+ (Some((expected_key, expected_value)), Some((actual_key, actual_value)))
+ if expected_key == actual_key =>
+ {
+ if let mismatch @ Some(_) =
+ find_json_mismatch_r(expected_value, actual_value, cwd)
+ {
+ return mismatch;
+ }
+ }
+ _ => return Some((expected, actual)),
+ }
}
-
- l.values()
- .zip(r.values())
- .filter_map(|(l, r)| find_json_mismatch_r(l, r, cwd))
- .next()
}
(&Null, &Null) => None,
// Magic string literal `"{...}"` acts as wildcard for any sub-JSON.
diff --git a/src/tools/cargo/crates/cargo-test-support/src/lib.rs b/src/tools/cargo/crates/cargo-test-support/src/lib.rs
index ec74ce0b2..4e3ef6118 100644
--- a/src/tools/cargo/crates/cargo-test-support/src/lib.rs
+++ b/src/tools/cargo/crates/cargo-test-support/src/lib.rs
@@ -2,7 +2,9 @@
//!
//! See <https://rust-lang.github.io/cargo/contrib/> for a guide on writing tests.
-#![allow(clippy::all)]
+#![allow(clippy::disallowed_methods)]
+#![allow(clippy::print_stderr)]
+#![allow(clippy::print_stdout)]
use std::env;
use std::ffi::OsStr;
@@ -521,29 +523,6 @@ pub fn cargo_exe() -> PathBuf {
snapbox::cmd::cargo_bin("cargo")
}
-/// A wrapper around `rustc` instead of calling `clippy`.
-pub fn wrapped_clippy_driver() -> PathBuf {
- let clippy_driver = project()
- .at(paths::global_root().join("clippy-driver"))
- .file("Cargo.toml", &basic_manifest("clippy-driver", "0.0.1"))
- .file(
- "src/main.rs",
- r#"
- fn main() {
- let mut args = std::env::args_os();
- let _me = args.next().unwrap();
- let rustc = args.next().unwrap();
- let status = std::process::Command::new(rustc).args(args).status().unwrap();
- std::process::exit(status.code().unwrap_or(1));
- }
- "#,
- )
- .build();
- clippy_driver.cargo("build").run();
-
- clippy_driver.bin("clippy-driver")
-}
-
/// This is the raw output from the process.
///
/// This is similar to `std::process::Output`, however the `status` is
diff --git a/src/tools/cargo/crates/cargo-test-support/src/paths.rs b/src/tools/cargo/crates/cargo-test-support/src/paths.rs
index 50040e1d4..a07491bcc 100644
--- a/src/tools/cargo/crates/cargo-test-support/src/paths.rs
+++ b/src/tools/cargo/crates/cargo-test-support/src/paths.rs
@@ -114,6 +114,10 @@ pub trait CargoPathExt {
fn rm_rf(&self);
fn mkdir_p(&self);
+ /// Returns a list of all files and directories underneath the given
+ /// directory, recursively, including the starting path.
+ fn ls_r(&self) -> Vec<PathBuf>;
+
fn move_into_the_past(&self) {
self.move_in_time(|sec, nsec| (sec - 3600, nsec))
}
@@ -155,6 +159,14 @@ impl CargoPathExt for Path {
.unwrap_or_else(|e| panic!("failed to mkdir_p {}: {}", self.display(), e))
}
+ fn ls_r(&self) -> Vec<PathBuf> {
+ walkdir::WalkDir::new(self)
+ .sort_by_file_name()
+ .into_iter()
+ .filter_map(|e| e.map(|e| e.path().to_owned()).ok())
+ .collect()
+ }
+
fn move_in_time<F>(&self, travel_amount: F)
where
F: Fn(i64, u32) -> (i64, u32),
diff --git a/src/tools/cargo/crates/cargo-test-support/src/registry.rs b/src/tools/cargo/crates/cargo-test-support/src/registry.rs
index 853829c56..6f9d558a9 100644
--- a/src/tools/cargo/crates/cargo-test-support/src/registry.rs
+++ b/src/tools/cargo/crates/cargo-test-support/src/registry.rs
@@ -557,6 +557,7 @@ pub struct Dependency {
registry: Option<String>,
package: Option<String>,
optional: bool,
+ default_features: bool,
}
/// Entry with data that corresponds to [`tar::EntryType`].
@@ -1161,12 +1162,15 @@ fn save_new_crate(
"name": name,
"req": dep.version_req,
"features": dep.features,
- "default_features": true,
+ "default_features": dep.default_features,
"target": dep.target,
"optional": dep.optional,
"kind": dep.kind,
"registry": dep.registry,
"package": package,
+ "artifact": dep.artifact,
+ "bindep_target": dep.bindep_target,
+ "lib": dep.lib,
})
})
.collect::<Vec<_>>();
@@ -1179,7 +1183,7 @@ fn save_new_crate(
new_crate.features,
false,
new_crate.links,
- None,
+ new_crate.rust_version.as_deref(),
None,
);
@@ -1415,7 +1419,7 @@ impl Package {
"name": dep.name,
"req": dep.vers,
"features": dep.features,
- "default_features": true,
+ "default_features": dep.default_features,
"target": dep.target,
"artifact": artifact,
"bindep_target": dep.bindep_target,
@@ -1523,6 +1527,30 @@ impl Package {
manifest.push_str(&format!("rust-version = \"{}\"", version));
}
+ if !self.features.is_empty() {
+ let features: Vec<String> = self
+ .features
+ .iter()
+ .map(|(feature, features)| {
+ if features.is_empty() {
+ format!("{} = []", feature)
+ } else {
+ format!(
+ "{} = [{}]",
+ feature,
+ features
+ .iter()
+ .map(|s| format!("\"{}\"", s))
+ .collect::<Vec<_>>()
+ .join(", ")
+ )
+ }
+ })
+ .collect();
+
+ manifest.push_str(&format!("\n[features]\n{}", features.join("\n")));
+ }
+
for dep in self.deps.iter() {
let target = match dep.target {
None => String::new(),
@@ -1540,6 +1568,9 @@ impl Package {
"#,
target, kind, dep.name, dep.vers
));
+ if dep.optional {
+ manifest.push_str("optional = true\n");
+ }
if let Some(artifact) = &dep.artifact {
manifest.push_str(&format!("artifact = \"{}\"\n", artifact));
}
@@ -1553,6 +1584,21 @@ impl Package {
assert_eq!(registry, "alternative");
manifest.push_str(&format!("registry-index = \"{}\"", alt_registry_url()));
}
+ if !dep.default_features {
+ manifest.push_str("default-features = false\n");
+ }
+ if !dep.features.is_empty() {
+ let mut features = String::new();
+ serde::Serialize::serialize(
+ &dep.features,
+ toml::ser::ValueSerializer::new(&mut features),
+ )
+ .unwrap();
+ manifest.push_str(&format!("features = {}\n", features));
+ }
+ if let Some(package) = &dep.package {
+ manifest.push_str(&format!("package = \"{}\"\n", package));
+ }
}
if self.proc_macro {
manifest.push_str("[lib]\nproc-macro = true\n");
@@ -1631,6 +1677,7 @@ impl Dependency {
package: None,
optional: false,
registry: None,
+ default_features: true,
}
}
@@ -1683,4 +1730,10 @@ impl Dependency {
self.optional = optional;
self
}
+
+ /// Adds `default-features = false` if the argument is `false`.
+ pub fn default_features(&mut self, default_features: bool) -> &mut Self {
+ self.default_features = default_features;
+ self
+ }
}
diff --git a/src/tools/cargo/crates/cargo-test-support/src/tools.rs b/src/tools/cargo/crates/cargo-test-support/src/tools.rs
index 2ce2849ae..b6fa4092f 100644
--- a/src/tools/cargo/crates/cargo-test-support/src/tools.rs
+++ b/src/tools/cargo/crates/cargo-test-support/src/tools.rs
@@ -7,6 +7,7 @@ use std::sync::OnceLock;
static ECHO_WRAPPER: OnceLock<Mutex<Option<PathBuf>>> = OnceLock::new();
static ECHO: OnceLock<Mutex<Option<PathBuf>>> = OnceLock::new();
+static CLIPPY_DRIVER: OnceLock<Mutex<Option<PathBuf>>> = OnceLock::new();
/// Returns the path to an executable that works as a wrapper around rustc.
///
@@ -107,3 +108,34 @@ pub fn echo_subcommand() -> Project {
p.cargo("build").run();
p
}
+
+/// A wrapper around `rustc` instead of calling `clippy`.
+pub fn wrapped_clippy_driver() -> PathBuf {
+ let mut lock = CLIPPY_DRIVER
+ .get_or_init(|| Default::default())
+ .lock()
+ .unwrap();
+ if let Some(path) = &*lock {
+ return path.clone();
+ }
+ let clippy_driver = project()
+ .at(paths::global_root().join("clippy-driver"))
+ .file("Cargo.toml", &basic_manifest("clippy-driver", "0.0.1"))
+ .file(
+ "src/main.rs",
+ r#"
+ fn main() {
+ let mut args = std::env::args_os();
+ let _me = args.next().unwrap();
+ let rustc = args.next().unwrap();
+ let status = std::process::Command::new(rustc).args(args).status().unwrap();
+ std::process::exit(status.code().unwrap_or(1));
+ }
+ "#,
+ )
+ .build();
+ clippy_driver.cargo("build").run();
+ let path = clippy_driver.bin("clippy-driver");
+ *lock = Some(path.clone());
+ path
+}