summaryrefslogtreecommitdiffstats
path: root/src/tools/suggest-tests
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:20:39 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:20:39 +0000
commit1376c5a617be5c25655d0d7cb63e3beaa5a6e026 (patch)
tree3bb8d61aee02bc7a15eab3f36e3b921afc2075d0 /src/tools/suggest-tests
parentReleasing progress-linux version 1.69.0+dfsg1-1~progress7.99u1. (diff)
downloadrustc-1376c5a617be5c25655d0d7cb63e3beaa5a6e026.tar.xz
rustc-1376c5a617be5c25655d0d7cb63e3beaa5a6e026.zip
Merging upstream version 1.70.0+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/tools/suggest-tests')
-rw-r--r--src/tools/suggest-tests/Cargo.toml9
-rw-r--r--src/tools/suggest-tests/src/dynamic_suggestions.rs23
-rw-r--r--src/tools/suggest-tests/src/lib.rs96
-rw-r--r--src/tools/suggest-tests/src/main.rs27
-rw-r--r--src/tools/suggest-tests/src/static_suggestions.rs24
-rw-r--r--src/tools/suggest-tests/src/tests.rs21
6 files changed, 200 insertions, 0 deletions
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<Suggestion>;
+
+pub(crate) const DYNAMIC_SUGGESTIONS: &[DynamicSuggestion] = &[|path: &Path| -> Vec<Suggestion> {
+ if path.starts_with("compiler/") || path.starts_with("library/") {
+ let path = path.components().take(2).collect::<Vec<_>>();
+
+ 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<T: AsRef<str>>(modified_files: &[T]) -> Vec<Suggestion> {
+ 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<u32>,
+ pub paths: Vec<String>,
+}
+
+impl Suggestion {
+ pub fn new(cmd: &str, stage: Option<u32>, 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<u32>, 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<Vec<(&'static str, Vec<Suggestion>)>>
+ = ::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::<Vec<_>>();
+ 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"]
+}