From ad74285275e5981e326801dddd625a4df243d6ea Mon Sep 17 00:00:00 2001
From: bit-aloo <sshourya17@gmail.com>
Date: Sun, 16 Feb 2025 23:24:29 +0530
Subject: [PATCH 1/5] add exclude to config.toml

---
 config.example.toml                     |  4 +++
 src/bootstrap/src/core/config/config.rs | 38 ++++++++++++++-----------
 2 files changed, 26 insertions(+), 16 deletions(-)

diff --git a/config.example.toml b/config.example.toml
index c3d2ad094ceb..0700a3171099 100644
--- a/config.example.toml
+++ b/config.example.toml
@@ -446,6 +446,10 @@
 # a specific version.
 #ccache = false
 
+# List of paths to exclude from the build and test processes. 
+# For example, exclude = ["tests/ui", "src/tools/tidy"].
+#exclude = []
+
 # =============================================================================
 # General install configuration options
 # =============================================================================
diff --git a/src/bootstrap/src/core/config/config.rs b/src/bootstrap/src/core/config/config.rs
index a07c40bdc83e..18624a7c78f1 100644
--- a/src/bootstrap/src/core/config/config.rs
+++ b/src/bootstrap/src/core/config/config.rs
@@ -959,6 +959,7 @@ define_config! {
         jobs: Option<u32> = "jobs",
         compiletest_diff_tool: Option<String> = "compiletest-diff-tool",
         ccache: Option<StringOrBool> = "ccache",
+        exclude: Option<Vec<PathBuf>> = "exclude",
     }
 }
 
@@ -1397,22 +1398,6 @@ impl Config {
             "flags.exclude" = ?flags.exclude
         );
 
-        config.skip = flags
-            .skip
-            .into_iter()
-            .chain(flags.exclude)
-            .map(|p| {
-                // Never return top-level path here as it would break `--skip`
-                // logic on rustc's internal test framework which is utilized
-                // by compiletest.
-                if cfg!(windows) {
-                    PathBuf::from(p.to_str().unwrap().replace('/', "\\"))
-                } else {
-                    p
-                }
-            })
-            .collect();
-
         #[cfg(feature = "tracing")]
         span!(
             target: "CONFIG_HANDLING",
@@ -1658,8 +1643,29 @@ impl Config {
             jobs,
             compiletest_diff_tool,
             mut ccache,
+            exclude,
         } = toml.build.unwrap_or_default();
 
+        let mut paths: Vec<PathBuf> = flags.skip.into_iter().chain(flags.exclude).collect();
+
+        if let Some(exclude) = exclude {
+            paths.extend(exclude);
+        }
+
+        config.skip = paths
+            .into_iter()
+            .map(|p| {
+                // Never return top-level path here as it would break `--skip`
+                // logic on rustc's internal test framework which is utilized
+                // by compiletest.
+                if cfg!(windows) {
+                    PathBuf::from(p.to_str().unwrap().replace('/', "\\"))
+                } else {
+                    p
+                }
+            })
+            .collect();
+
         config.jobs = Some(threads_from_config(flags.jobs.unwrap_or(jobs.unwrap_or(0))));
 
         if let Some(file_build) = build {

From 7d1537e4251caa7e08bea7ad41b2f1e3ad38a29d Mon Sep 17 00:00:00 2001
From: bit-aloo <sshourya17@gmail.com>
Date: Mon, 17 Feb 2025 01:28:39 +0530
Subject: [PATCH 2/5] add test for exclude feature

---
 src/bootstrap/src/core/config/tests.rs | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/src/bootstrap/src/core/config/tests.rs b/src/bootstrap/src/core/config/tests.rs
index eff5e0337428..27968bea3186 100644
--- a/src/bootstrap/src/core/config/tests.rs
+++ b/src/bootstrap/src/core/config/tests.rs
@@ -515,3 +515,17 @@ fn test_explicit_stage() {
     assert!(!config.explicit_stage_from_config);
     assert!(!config.is_explicit_stage());
 }
+
+#[test]
+fn test_exclude() {
+    let config = parse("build.exclude=[\"test/codegen\"]");
+
+    let first_excluded = config
+        .skip
+        .first()
+        .expect("Expected at least one excluded path")
+        .to_str()
+        .expect("Failed to convert excluded path to string");
+
+    assert_eq!(first_excluded, "test/codegen");
+}

From 22571da9f8fa91f96edc4809f05a15a5b38a0d84 Mon Sep 17 00:00:00 2001
From: bit-aloo <sshourya17@gmail.com>
Date: Mon, 17 Feb 2025 01:34:32 +0530
Subject: [PATCH 3/5] Add change info to change tracker

---
 src/bootstrap/src/utils/change_tracker.rs | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/src/bootstrap/src/utils/change_tracker.rs b/src/bootstrap/src/utils/change_tracker.rs
index 8036c5921086..f8478725c4cd 100644
--- a/src/bootstrap/src/utils/change_tracker.rs
+++ b/src/bootstrap/src/utils/change_tracker.rs
@@ -380,4 +380,9 @@ pub const CONFIG_CHANGE_HISTORY: &[ChangeInfo] = &[
         severity: ChangeSeverity::Warning,
         summary: "Removed `src/tools/rls` tool as it was deprecated long time ago.",
     },
+    ChangeInfo {
+        change_id: 137147,
+        severity: ChangeSeverity::Info,
+        summary: "New option `build.exclude` that adds support for excluding test.",
+    },
 ];

From 9d5f0742a999c177fea10da93a77d5d8b797710d Mon Sep 17 00:00:00 2001
From: bit-aloo <sshourya17@gmail.com>
Date: Wed, 5 Mar 2025 03:07:01 +0530
Subject: [PATCH 4/5] make test platform agnostic

---
 src/bootstrap/src/core/config/tests.rs | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/src/bootstrap/src/core/config/tests.rs b/src/bootstrap/src/core/config/tests.rs
index 27968bea3186..217df313c58a 100644
--- a/src/bootstrap/src/core/config/tests.rs
+++ b/src/bootstrap/src/core/config/tests.rs
@@ -518,7 +518,9 @@ fn test_explicit_stage() {
 
 #[test]
 fn test_exclude() {
-    let config = parse("build.exclude=[\"test/codegen\"]");
+    use std::path::MAIN_SEPARATOR;
+    let exclude_path = format!("test{}codegen", MAIN_SEPARATOR);
+    let config = parse(&format!("build.exclude=[\"{}\"]", exclude_path));
 
     let first_excluded = config
         .skip
@@ -527,5 +529,5 @@ fn test_exclude() {
         .to_str()
         .expect("Failed to convert excluded path to string");
 
-    assert_eq!(first_excluded, "test/codegen");
+    assert_eq!(first_excluded, exclude_path);
 }

From c6ecd8c95c84cd45e4de8abb767093d0f9aec670 Mon Sep 17 00:00:00 2001
From: bit-aloo <sshourya17@gmail.com>
Date: Sun, 9 Mar 2025 16:29:42 +0530
Subject: [PATCH 5/5] update the test_exclude to not use paths with path
 separators

---
 src/bootstrap/src/core/config/tests.rs | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/src/bootstrap/src/core/config/tests.rs b/src/bootstrap/src/core/config/tests.rs
index 217df313c58a..c7b6f3681b89 100644
--- a/src/bootstrap/src/core/config/tests.rs
+++ b/src/bootstrap/src/core/config/tests.rs
@@ -518,8 +518,7 @@ fn test_explicit_stage() {
 
 #[test]
 fn test_exclude() {
-    use std::path::MAIN_SEPARATOR;
-    let exclude_path = format!("test{}codegen", MAIN_SEPARATOR);
+    let exclude_path = "compiler";
     let config = parse(&format!("build.exclude=[\"{}\"]", exclude_path));
 
     let first_excluded = config