diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-30 18:31:44 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-30 18:31:44 +0000 |
commit | c23a457e72abe608715ac76f076f47dc42af07a5 (patch) | |
tree | 2772049aaf84b5c9d0ed12ec8d86812f7a7904b6 /src/tools/cargo/crates/cargo-test-support | |
parent | Releasing progress-linux version 1.73.0+dfsg1-1~progress7.99u1. (diff) | |
download | rustc-c23a457e72abe608715ac76f076f47dc42af07a5.tar.xz rustc-c23a457e72abe608715ac76f076f47dc42af07a5.zip |
Merging upstream version 1.74.1+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/tools/cargo/crates/cargo-test-support')
7 files changed, 106 insertions, 97 deletions
diff --git a/src/tools/cargo/crates/cargo-test-support/Cargo.toml b/src/tools/cargo/crates/cargo-test-support/Cargo.toml index 085041aff..fc32e1c9c 100644 --- a/src/tools/cargo/crates/cargo-test-support/Cargo.toml +++ b/src/tools/cargo/crates/cargo-test-support/Cargo.toml @@ -1,6 +1,7 @@ [package] name = "cargo-test-support" version = "0.1.0" +rust-version.workspace = true license.workspace = true edition.workspace = true publish = false @@ -9,6 +10,8 @@ publish = false doctest = false [dependencies] +anstream.workspace = true +anstyle.workspace = true anyhow.workspace = true cargo-test-macro.workspace = true cargo-util.workspace = true @@ -18,13 +21,11 @@ flate2.workspace = true git2.workspace = true glob.workspace = true itertools.workspace = true -lazy_static.workspace = true pasetors.workspace = true serde = { workspace = true, features = ["derive"] } serde_json.workspace = true snapbox.workspace = true tar.workspace = true -termcolor.workspace = true time.workspace = true toml.workspace = true url.workspace = true 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 21eb64d28..09e3a5a0c 100644 --- a/src/tools/cargo/crates/cargo-test-support/src/compare.rs +++ b/src/tools/cargo/crates/cargo-test-support/src/compare.rs @@ -206,6 +206,7 @@ fn substitute_macros(input: &str) -> String { ("[UPDATING]", " Updating"), ("[ADDING]", " Adding"), ("[REMOVING]", " Removing"), + ("[REMOVED]", " Removed"), ("[DOCTEST]", " Doc-tests"), ("[PACKAGING]", " Packaging"), ("[PACKAGED]", " Packaged"), diff --git a/src/tools/cargo/crates/cargo-test-support/src/diff.rs b/src/tools/cargo/crates/cargo-test-support/src/diff.rs index f3b283b10..3fedc839b 100644 --- a/src/tools/cargo/crates/cargo-test-support/src/diff.rs +++ b/src/tools/cargo/crates/cargo-test-support/src/diff.rs @@ -7,7 +7,6 @@ use std::fmt; use std::io::Write; -use termcolor::{Ansi, Color, ColorSpec, NoColor, WriteColor}; /// A single line change to be applied to the original. #[derive(Debug, Eq, PartialEq)] @@ -111,42 +110,35 @@ where } pub fn render_colored_changes<T: fmt::Display>(changes: &[Change<T>]) -> String { - // termcolor is not very ergonomic, but I don't want to bring in another dependency. - let mut red = ColorSpec::new(); - red.set_fg(Some(Color::Red)); - let mut green = ColorSpec::new(); - green.set_fg(Some(Color::Green)); - let mut dim = ColorSpec::new(); - dim.set_dimmed(true); - let mut v = Vec::new(); - let mut result: Box<dyn WriteColor> = if crate::is_ci() { + // anstyle is not very ergonomic, but I don't want to bring in another dependency. + let red = anstyle::AnsiColor::Red.on_default().render(); + let green = anstyle::AnsiColor::Green.on_default().render(); + let dim = (anstyle::Style::new() | anstyle::Effects::DIMMED).render(); + let bold = (anstyle::Style::new() | anstyle::Effects::BOLD).render(); + let reset = anstyle::Reset.render(); + + let choice = if crate::is_ci() { // Don't use color on CI. Even though GitHub can display colors, it // makes reading the raw logs more difficult. - Box::new(NoColor::new(&mut v)) + anstream::ColorChoice::Never } else { - Box::new(Ansi::new(&mut v)) + anstream::AutoStream::choice(&std::io::stdout()) }; + let mut buffer = anstream::AutoStream::new(Vec::new(), choice); for change in changes { let (nums, sign, color, text) = match change { - Change::Add(i, s) => (format!(" {:<4} ", i), '+', &green, s), - Change::Remove(i, s) => (format!("{:<4} ", i), '-', &red, s), - Change::Keep(x, y, s) => (format!("{:<4}{:<4} ", x, y), ' ', &dim, s), + Change::Add(i, s) => (format!(" {:<4} ", i), '+', green, s), + Change::Remove(i, s) => (format!("{:<4} ", i), '-', red, s), + Change::Keep(x, y, s) => (format!("{:<4}{:<4} ", x, y), ' ', dim, s), }; - result.set_color(&dim).unwrap(); - write!(result, "{}", nums).unwrap(); - let mut bold = color.clone(); - bold.set_bold(true); - result.set_color(&bold).unwrap(); - write!(result, "{}", sign).unwrap(); - result.reset().unwrap(); - result.set_color(&color).unwrap(); - write!(result, "{}", text).unwrap(); - result.reset().unwrap(); - writeln!(result).unwrap(); + write!( + buffer, + "{dim}{nums}{reset}{bold}{sign}{reset}{color}{text}{reset}" + ) + .unwrap(); } - drop(result); - String::from_utf8(v).unwrap() + String::from_utf8(buffer.into_inner()).unwrap() } #[cfg(test)] diff --git a/src/tools/cargo/crates/cargo-test-support/src/git.rs b/src/tools/cargo/crates/cargo-test-support/src/git.rs index 6fde96467..236011ca1 100644 --- a/src/tools/cargo/crates/cargo-test-support/src/git.rs +++ b/src/tools/cargo/crates/cargo-test-support/src/git.rs @@ -10,7 +10,7 @@ Example: ``` let git_project = git::new("dep1", |project| { project - .file("Cargo.toml", &basic_manifest("dep1")) + .file("Cargo.toml", &basic_manifest("dep1", "1.0.0")) .file("src/lib.rs", r#"pub fn f() { println!("hi!"); } "#) }); @@ -177,25 +177,8 @@ where /// Add all files in the working directory to the git index. pub fn add(repo: &git2::Repository) { - // FIXME(libgit2/libgit2#2514): apparently, `add_all` will add all submodules - // as well, and then fail because they're directories. As a stop-gap, we just - // ignore all submodules. - let mut s = t!(repo.submodules()); - for submodule in s.iter_mut() { - t!(submodule.add_to_index(false)); - } let mut index = t!(repo.index()); - t!(index.add_all( - ["*"].iter(), - git2::IndexAddOption::DEFAULT, - Some( - &mut (|a, _b| if s.iter().any(|s| a.starts_with(s.path())) { - 1 - } else { - 0 - }) - ) - )); + t!(index.add_all(["*"].iter(), git2::IndexAddOption::DEFAULT, None)); t!(index.write()); } 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 a2fa54c60..1a8742720 100644 --- a/src/tools/cargo/crates/cargo-test-support/src/lib.rs +++ b/src/tools/cargo/crates/cargo-test-support/src/lib.rs @@ -12,6 +12,7 @@ use std::os; use std::path::{Path, PathBuf}; use std::process::{Command, Output}; use std::str; +use std::sync::OnceLock; use std::time::{self, Duration}; use anyhow::{bail, Result}; @@ -569,6 +570,7 @@ pub struct Execs { expect_stdout_contains_n: Vec<(String, usize)>, expect_stdout_not_contains: Vec<String>, expect_stderr_not_contains: Vec<String>, + expect_stdout_unordered: Vec<String>, expect_stderr_unordered: Vec<String>, expect_stderr_with_without: Vec<(Vec<String>, Vec<String>)>, expect_json: Option<String>, @@ -670,6 +672,15 @@ impl Execs { self } + /// Verifies that all of the stdout output is equal to the given lines, + /// ignoring the order of the lines. + /// + /// See [`Execs::with_stderr_unordered`] for more details. + pub fn with_stdout_unordered<S: ToString>(&mut self, expected: S) -> &mut Self { + self.expect_stdout_unordered.push(expected.to_string()); + self + } + /// Verifies that all of the stderr output is equal to the given lines, /// ignoring the order of the lines. /// @@ -838,7 +849,7 @@ impl Execs { /// Enables nightly features for testing /// /// The list of reasons should be why nightly cargo is needed. If it is - /// becuase of an unstable feature put the name of the feature as the reason, + /// because of an unstable feature put the name of the feature as the reason, /// e.g. `&["print-im-a-teapot"]` pub fn masquerade_as_nightly_cargo(&mut self, reasons: &[&str]) -> &mut Self { if let Some(ref mut p) = self.process_builder { @@ -931,6 +942,7 @@ impl Execs { && self.expect_stdout_contains_n.is_empty() && self.expect_stdout_not_contains.is_empty() && self.expect_stderr_not_contains.is_empty() + && self.expect_stdout_unordered.is_empty() && self.expect_stderr_unordered.is_empty() && self.expect_stderr_with_without.is_empty() && self.expect_json.is_none() @@ -1035,6 +1047,9 @@ impl Execs { for expect in self.expect_stderr_not_contains.iter() { compare::match_does_not_contain(expect, stderr, cwd)?; } + for expect in self.expect_stdout_unordered.iter() { + compare::match_unordered(expect, stdout, cwd)?; + } for expect in self.expect_stderr_unordered.iter() { compare::match_unordered(expect, stderr, cwd)?; } @@ -1074,6 +1089,7 @@ pub fn execs() -> Execs { expect_stdout_contains_n: Vec::new(), expect_stdout_not_contains: Vec::new(), expect_stderr_not_contains: Vec::new(), + expect_stdout_unordered: Vec::new(), expect_stderr_unordered: Vec::new(), expect_stderr_with_without: Vec::new(), expect_json: None, @@ -1157,13 +1173,14 @@ impl RustcInfo { } } -lazy_static::lazy_static! { - static ref RUSTC_INFO: RustcInfo = RustcInfo::new(); +fn rustc_info() -> &'static RustcInfo { + static RUSTC_INFO: OnceLock<RustcInfo> = OnceLock::new(); + RUSTC_INFO.get_or_init(RustcInfo::new) } /// The rustc host such as `x86_64-unknown-linux-gnu`. pub fn rustc_host() -> &'static str { - &RUSTC_INFO.host + &rustc_info().host } /// The host triple suitable for use in a cargo environment variable (uppercased). @@ -1172,7 +1189,7 @@ pub fn rustc_host_env() -> String { } pub fn is_nightly() -> bool { - let vv = &RUSTC_INFO.verbose_version; + let vv = &rustc_info().verbose_version; // CARGO_TEST_DISABLE_NIGHTLY is set in rust-lang/rust's CI so that all // nightly-only tests are disabled there. Otherwise, it could make it // difficult to land changes which would need to be made simultaneously in @@ -1194,7 +1211,7 @@ fn _process(t: &OsStr) -> ProcessBuilder { /// Enable nightly features for testing pub trait ChannelChanger { /// The list of reasons should be why nightly cargo is needed. If it is - /// becuase of an unstable feature put the name of the feature as the reason, + /// because of an unstable feature put the name of the feature as the reason, /// e.g. `&["print-im-a-teapot"]`. fn masquerade_as_nightly_cargo(self, _reasons: &[&str]) -> Self; } @@ -1225,28 +1242,27 @@ pub trait TestEnv: Sized { if env::var_os("RUSTUP_TOOLCHAIN").is_some() { // Override the PATH to avoid executing the rustup wrapper thousands // of times. This makes the testsuite run substantially faster. - lazy_static::lazy_static! { - static ref RUSTC_DIR: PathBuf = { - match ProcessBuilder::new("rustup") - .args(&["which", "rustc"]) - .exec_with_output() - { - Ok(output) => { - let s = str::from_utf8(&output.stdout).expect("utf8").trim(); - let mut p = PathBuf::from(s); - p.pop(); - p - } - Err(e) => { - panic!("RUSTUP_TOOLCHAIN was set, but could not run rustup: {}", e); - } + static RUSTC_DIR: OnceLock<PathBuf> = OnceLock::new(); + let rustc_dir = RUSTC_DIR.get_or_init(|| { + match ProcessBuilder::new("rustup") + .args(&["which", "rustc"]) + .exec_with_output() + { + Ok(output) => { + let s = str::from_utf8(&output.stdout).expect("utf8").trim(); + let mut p = PathBuf::from(s); + p.pop(); + p } - }; - } + Err(e) => { + panic!("RUSTUP_TOOLCHAIN was set, but could not run rustup: {}", e); + } + } + }); let path = env::var_os("PATH").unwrap_or_default(); let paths = env::split_paths(&path); let new_path = - env::join_paths(std::iter::once(RUSTC_DIR.clone()).chain(paths)).unwrap(); + env::join_paths(std::iter::once(rustc_dir.clone()).chain(paths)).unwrap(); self = self.env("PATH", new_path); } @@ -1408,11 +1424,14 @@ pub fn is_coarse_mtime() -> bool { /// Architectures that do not have a modern processor, hardware emulation, etc. /// This provides a way for those setups to increase the cut off for all the time based test. pub fn slow_cpu_multiplier(main: u64) -> Duration { - lazy_static::lazy_static! { - static ref SLOW_CPU_MULTIPLIER: u64 = - env::var("CARGO_TEST_SLOW_CPU_MULTIPLIER").ok().and_then(|m| m.parse().ok()).unwrap_or(1); - } - Duration::from_secs(*SLOW_CPU_MULTIPLIER * main) + static SLOW_CPU_MULTIPLIER: OnceLock<u64> = OnceLock::new(); + let slow_cpu_multiplier = SLOW_CPU_MULTIPLIER.get_or_init(|| { + env::var("CARGO_TEST_SLOW_CPU_MULTIPLIER") + .ok() + .and_then(|m| m.parse().ok()) + .unwrap_or(1) + }); + Duration::from_secs(slow_cpu_multiplier * main) } #[cfg(windows)] diff --git a/src/tools/cargo/crates/cargo-test-support/src/publish.rs b/src/tools/cargo/crates/cargo-test-support/src/publish.rs index dccc8356d..f850330c1 100644 --- a/src/tools/cargo/crates/cargo-test-support/src/publish.rs +++ b/src/tools/cargo/crates/cargo-test-support/src/publish.rs @@ -131,8 +131,11 @@ pub fn validate_crate_contents( (name, contents) }) .collect(); - assert!(expected_crate_name.ends_with(".crate")); - let base_crate_name = Path::new(&expected_crate_name[..expected_crate_name.len() - 6]); + let base_crate_name = Path::new( + expected_crate_name + .strip_suffix(".crate") + .expect("must end with .crate"), + ); let actual_files: HashSet<PathBuf> = files.keys().cloned().collect(); let expected_files: HashSet<PathBuf> = expected_files .iter() 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 27c319656..853829c56 100644 --- a/src/tools/cargo/crates/cargo-test-support/src/registry.rs +++ b/src/tools/cargo/crates/cargo-test-support/src/registry.rs @@ -549,7 +549,9 @@ pub struct Dependency { name: String, vers: String, kind: String, - artifact: Option<(String, Option<String>)>, + artifact: Option<String>, + bindep_target: Option<String>, + lib: bool, target: Option<String>, features: Vec<String>, registry: Option<String>, @@ -779,6 +781,7 @@ impl HttpServer { let buf = buf.get_mut(); write!(buf, "HTTP/1.1 {}\r\n", response.code).unwrap(); write!(buf, "Content-Length: {}\r\n", response.body.len()).unwrap(); + write!(buf, "Connection: close\r\n").unwrap(); for header in response.headers { write!(buf, "{}\r\n", header).unwrap(); } @@ -788,7 +791,7 @@ impl HttpServer { } } - fn check_authorized(&self, req: &Request, mutation: Option<Mutation>) -> bool { + fn check_authorized(&self, req: &Request, mutation: Option<Mutation<'_>>) -> bool { let (private_key, private_key_subject) = if mutation.is_some() || self.auth_required { match &self.token { Token::Plaintext(token) => return Some(token) == req.authorization.as_ref(), @@ -830,7 +833,8 @@ impl HttpServer { url: &'a str, kip: &'a str, } - let footer: Footer = t!(serde_json::from_slice(untrusted_token.untrusted_footer()).ok()); + let footer: Footer<'_> = + t!(serde_json::from_slice(untrusted_token.untrusted_footer()).ok()); if footer.kip != paserk_pub_key_id { return false; } @@ -844,7 +848,6 @@ impl HttpServer { if footer.url != "https://github.com/rust-lang/crates.io-index" && footer.url != &format!("sparse+http://{}/index/", self.addr.to_string()) { - dbg!(footer.url); return false; } @@ -860,20 +863,18 @@ impl HttpServer { _challenge: Option<&'a str>, // todo: PASETO with challenges v: Option<u8>, } - let message: Message = t!(serde_json::from_str(trusted_token.payload()).ok()); + let message: Message<'_> = t!(serde_json::from_str(trusted_token.payload()).ok()); let token_time = t!(OffsetDateTime::parse(message.iat, &Rfc3339).ok()); let now = OffsetDateTime::now_utc(); if (now - token_time) > Duration::MINUTE { return false; } if private_key_subject.as_deref() != message.sub { - dbg!(message.sub); return false; } // - If the claim v is set, that it has the value of 1. if let Some(v) = message.v { if v != 1 { - dbg!(message.v); return false; } } @@ -883,22 +884,18 @@ impl HttpServer { if let Some(mutation) = mutation { // - That the operation matches the mutation field and is one of publish, yank, or unyank. if message.mutation != Some(mutation.mutation) { - dbg!(message.mutation); return false; } // - That the package, and version match the request. if message.name != mutation.name { - dbg!(message.name); return false; } if message.vers != mutation.vers { - dbg!(message.vers); return false; } // - If the mutation is publish, that the version has not already been published, and that the hash matches the request. if mutation.mutation == "publish" { if message.cksum != mutation.cksum { - dbg!(message.cksum); return false; } } @@ -1409,13 +1406,20 @@ impl Package { (true, Some("alternative")) => None, _ => panic!("registry_dep currently only supports `alternative`"), }; + let artifact = if let Some(artifact) = &dep.artifact { + serde_json::json!([artifact]) + } else { + serde_json::json!(null) + }; serde_json::json!({ "name": dep.name, "req": dep.vers, "features": dep.features, "default_features": true, "target": dep.target, - "artifact": dep.artifact, + "artifact": artifact, + "bindep_target": dep.bindep_target, + "lib": dep.lib, "optional": dep.optional, "kind": dep.kind, "registry": registry_url, @@ -1536,11 +1540,14 @@ impl Package { "#, target, kind, dep.name, dep.vers )); - if let Some((artifact, target)) = &dep.artifact { + if let Some(artifact) = &dep.artifact { manifest.push_str(&format!("artifact = \"{}\"\n", artifact)); - if let Some(target) = &target { - manifest.push_str(&format!("target = \"{}\"\n", target)) - } + } + if let Some(target) = &dep.bindep_target { + manifest.push_str(&format!("target = \"{}\"\n", target)); + } + if dep.lib { + manifest.push_str("lib = true\n"); } if let Some(registry) = &dep.registry { assert_eq!(registry, "alternative"); @@ -1617,6 +1624,8 @@ impl Dependency { vers: vers.to_string(), kind: "normal".to_string(), artifact: None, + bindep_target: None, + lib: false, target: None, features: Vec::new(), package: None, @@ -1646,7 +1655,8 @@ impl Dependency { /// Change the artifact to be of the given kind, like "bin", or "staticlib", /// along with a specific target triple if provided. pub fn artifact(&mut self, kind: &str, target: Option<String>) -> &mut Self { - self.artifact = Some((kind.to_string(), target)); + self.artifact = Some(kind.to_string()); + self.bindep_target = target; self } |