From 1376c5a617be5c25655d0d7cb63e3beaa5a6e026 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Wed, 17 Apr 2024 14:20:39 +0200 Subject: Merging upstream version 1.70.0+dfsg1. Signed-off-by: Daniel Baumann --- src/tools/suggest-tests/Cargo.toml | 9 ++ src/tools/suggest-tests/src/dynamic_suggestions.rs | 23 ++++++ src/tools/suggest-tests/src/lib.rs | 96 ++++++++++++++++++++++ src/tools/suggest-tests/src/main.rs | 27 ++++++ src/tools/suggest-tests/src/static_suggestions.rs | 24 ++++++ src/tools/suggest-tests/src/tests.rs | 21 +++++ 6 files changed, 200 insertions(+) create mode 100644 src/tools/suggest-tests/Cargo.toml create mode 100644 src/tools/suggest-tests/src/dynamic_suggestions.rs create mode 100644 src/tools/suggest-tests/src/lib.rs create mode 100644 src/tools/suggest-tests/src/main.rs create mode 100644 src/tools/suggest-tests/src/static_suggestions.rs create mode 100644 src/tools/suggest-tests/src/tests.rs (limited to 'src/tools/suggest-tests') diff --git a/src/tools/suggest-tests/Cargo.toml b/src/tools/suggest-tests/Cargo.toml new file mode 100644 index 000000000..f4f4d548b --- /dev/null +++ b/src/tools/suggest-tests/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "suggest-tests" +version = "0.1.0" +edition = "2021" + +[dependencies] +glob = "0.3.0" +build_helper = { version = "0.1.0", path = "../build_helper" } +once_cell = "1.17.1" diff --git a/src/tools/suggest-tests/src/dynamic_suggestions.rs b/src/tools/suggest-tests/src/dynamic_suggestions.rs new file mode 100644 index 000000000..2b0213cdc --- /dev/null +++ b/src/tools/suggest-tests/src/dynamic_suggestions.rs @@ -0,0 +1,23 @@ +use std::path::Path; + +use crate::Suggestion; + +type DynamicSuggestion = fn(&Path) -> Vec; + +pub(crate) const DYNAMIC_SUGGESTIONS: &[DynamicSuggestion] = &[|path: &Path| -> Vec { + if path.starts_with("compiler/") || path.starts_with("library/") { + let path = path.components().take(2).collect::>(); + + vec![Suggestion::with_single_path( + "test", + None, + &format!( + "{}/{}", + path[0].as_os_str().to_str().unwrap(), + path[1].as_os_str().to_str().unwrap() + ), + )] + } else { + Vec::new() + } +}]; diff --git a/src/tools/suggest-tests/src/lib.rs b/src/tools/suggest-tests/src/lib.rs new file mode 100644 index 000000000..44cd3c7f6 --- /dev/null +++ b/src/tools/suggest-tests/src/lib.rs @@ -0,0 +1,96 @@ +use std::{ + fmt::{self, Display}, + path::Path, +}; + +use dynamic_suggestions::DYNAMIC_SUGGESTIONS; +use glob::Pattern; +use static_suggestions::STATIC_SUGGESTIONS; + +mod dynamic_suggestions; +mod static_suggestions; + +#[cfg(test)] +mod tests; + +macro_rules! sug { + ($cmd:expr) => { + Suggestion::new($cmd, None, &[]) + }; + + ($cmd:expr, $paths:expr) => { + Suggestion::new($cmd, None, $paths.as_slice()) + }; + + ($cmd:expr, $stage:expr, $paths:expr) => { + Suggestion::new($cmd, Some($stage), $paths.as_slice()) + }; +} + +pub(crate) use sug; + +pub fn get_suggestions>(modified_files: &[T]) -> Vec { + let mut suggestions = Vec::new(); + + // static suggestions + for sug in STATIC_SUGGESTIONS.iter() { + let glob = Pattern::new(&sug.0).expect("Found invalid glob pattern!"); + + for file in modified_files { + if glob.matches(file.as_ref()) { + suggestions.extend_from_slice(&sug.1); + } + } + } + + // dynamic suggestions + for sug in DYNAMIC_SUGGESTIONS { + for file in modified_files { + let sugs = sug(Path::new(file.as_ref())); + + suggestions.extend_from_slice(&sugs); + } + } + + suggestions.sort(); + suggestions.dedup(); + + suggestions +} + +#[derive(Clone, PartialOrd, Ord, PartialEq, Eq, Debug)] +pub struct Suggestion { + pub cmd: String, + pub stage: Option, + pub paths: Vec, +} + +impl Suggestion { + pub fn new(cmd: &str, stage: Option, paths: &[&str]) -> Self { + Self { cmd: cmd.to_owned(), stage, paths: paths.iter().map(|p| p.to_string()).collect() } + } + + pub fn with_single_path(cmd: &str, stage: Option, path: &str) -> Self { + Self::new(cmd, stage, &[path]) + } +} + +impl Display for Suggestion { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { + write!(f, "{} ", self.cmd)?; + + for path in &self.paths { + write!(f, "{} ", path)?; + } + + if let Some(stage) = self.stage { + write!(f, "{}", stage)?; + } else { + // write a sentinel value here (in place of a stage) to be consumed + // by the shim in bootstrap, it will be read and ignored. + write!(f, "N/A")?; + } + + Ok(()) + } +} diff --git a/src/tools/suggest-tests/src/main.rs b/src/tools/suggest-tests/src/main.rs new file mode 100644 index 000000000..0b541b60c --- /dev/null +++ b/src/tools/suggest-tests/src/main.rs @@ -0,0 +1,27 @@ +use std::process::ExitCode; + +use build_helper::git::get_git_modified_files; +use suggest_tests::get_suggestions; + +fn main() -> ExitCode { + let modified_files = get_git_modified_files(None, &Vec::new()); + let modified_files = match modified_files { + Ok(Some(files)) => files, + Ok(None) => { + eprintln!("git error"); + return ExitCode::FAILURE; + } + Err(err) => { + eprintln!("Could not get modified files from git: \"{err}\""); + return ExitCode::FAILURE; + } + }; + + let suggestions = get_suggestions(&modified_files); + + for sug in &suggestions { + println!("{sug}"); + } + + ExitCode::SUCCESS +} diff --git a/src/tools/suggest-tests/src/static_suggestions.rs b/src/tools/suggest-tests/src/static_suggestions.rs new file mode 100644 index 000000000..d8166ead8 --- /dev/null +++ b/src/tools/suggest-tests/src/static_suggestions.rs @@ -0,0 +1,24 @@ +use crate::{sug, Suggestion}; + +// FIXME: perhaps this could use `std::lazy` when it is stablizied +macro_rules! static_suggestions { + ($( $glob:expr => [ $( $suggestion:expr ),* ] ),*) => { + pub(crate) const STATIC_SUGGESTIONS: ::once_cell::unsync::Lazy)>> + = ::once_cell::unsync::Lazy::new(|| vec![ $( ($glob, vec![ $($suggestion),* ]) ),*]); + } +} + +static_suggestions! { + "*.md" => [ + sug!("test", 0, ["linkchecker"]) + ], + + "compiler/*" => [ + sug!("check"), + sug!("test", 1, ["src/test/ui", "src/test/run-make"]) + ], + + "src/librustdoc/*" => [ + sug!("test", 1, ["rustdoc"]) + ] +} diff --git a/src/tools/suggest-tests/src/tests.rs b/src/tools/suggest-tests/src/tests.rs new file mode 100644 index 000000000..5bc1a7df7 --- /dev/null +++ b/src/tools/suggest-tests/src/tests.rs @@ -0,0 +1,21 @@ +macro_rules! sugg_test { + ( $( $name:ident: $paths:expr => $suggestions:expr ),* ) => { + $( + #[test] + fn $name() { + let suggestions = crate::get_suggestions(&$paths).into_iter().map(|s| s.to_string()).collect::>(); + assert_eq!(suggestions, $suggestions); + } + )* + }; +} + +sugg_test! { + test_error_code_docs: ["compiler/rustc_error_codes/src/error_codes/E0000.md"] => + ["check N/A", "test compiler/rustc_error_codes N/A", "test linkchecker 0", "test src/test/ui src/test/run-make 1"], + + test_rustdoc: ["src/librustdoc/src/lib.rs"] => ["test rustdoc 1"], + + test_rustdoc_and_libstd: ["src/librustdoc/src/lib.rs", "library/std/src/lib.rs"] => + ["test library/std N/A", "test rustdoc 1"] +} -- cgit v1.2.3