Rollup merge of #126782 - mtilda:mtilda/patch/x-test-with-absolute-paths, r=onur-ozkan

Support absolute source paths in bootstrap

Fixes https://github.com/rust-lang/rust/issues/126765

`x test [PATHS]` should work when each path

1. Is the name of a build step, such as `tidy` in `x test tidy` or
2. Points to an existing file that is a descendant of the builder's source directory (root of this repository).
This commit is contained in:
Matthias Krüger 2024-06-23 09:45:29 +02:00 committed by GitHub
commit 92af6703b8
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 29 additions and 9 deletions

View File

@ -274,7 +274,7 @@ impl PathSet {
/// This is used for `StepDescription::krate`, which passes all matching crates at once to /// This is used for `StepDescription::krate`, which passes all matching crates at once to
/// `Step::make_run`, rather than calling it many times with a single crate. /// `Step::make_run`, rather than calling it many times with a single crate.
/// See `tests.rs` for examples. /// See `tests.rs` for examples.
fn intersection_removing_matches(&self, needles: &mut Vec<&Path>, module: Kind) -> PathSet { fn intersection_removing_matches(&self, needles: &mut Vec<PathBuf>, module: Kind) -> PathSet {
let mut check = |p| { let mut check = |p| {
for (i, n) in needles.iter().enumerate() { for (i, n) in needles.iter().enumerate() {
let matched = Self::check(p, n, module); let matched = Self::check(p, n, module);
@ -346,7 +346,7 @@ const PATH_REMAP: &[(&str, &[&str])] = &[
), ),
]; ];
fn remap_paths(paths: &mut Vec<&Path>) { fn remap_paths(paths: &mut Vec<PathBuf>) {
let mut remove = vec![]; let mut remove = vec![];
let mut add = vec![]; let mut add = vec![];
for (i, path) in paths.iter().enumerate().filter_map(|(i, path)| path.to_str().map(|s| (i, s))) for (i, path) in paths.iter().enumerate().filter_map(|(i, path)| path.to_str().map(|s| (i, s)))
@ -355,7 +355,7 @@ fn remap_paths(paths: &mut Vec<&Path>) {
// Remove leading and trailing slashes so `tests/` and `tests` are equivalent // Remove leading and trailing slashes so `tests/` and `tests` are equivalent
if path.trim_matches(std::path::is_separator) == search { if path.trim_matches(std::path::is_separator) == search {
remove.push(i); remove.push(i);
add.extend(replace.iter().map(Path::new)); add.extend(replace.iter().map(PathBuf::from));
break; break;
} }
} }
@ -438,8 +438,25 @@ impl StepDescription {
} }
} }
// strip CurDir prefix if present // Attempt to resolve paths to be relative to the builder source directory.
let mut paths: Vec<_> = paths.iter().map(|p| p.strip_prefix(".").unwrap_or(p)).collect(); let mut paths: Vec<PathBuf> = paths
.iter()
.map(|p| {
// If the path does not exist, it may represent the name of a Step, such as `tidy` in `x test tidy`
if !p.exists() {
return p.clone();
}
// Make the path absolute, strip the prefix, and convert to a PathBuf.
match std::path::absolute(p) {
Ok(p) => p.strip_prefix(&builder.src).unwrap_or(&p).to_path_buf(),
Err(e) => {
eprintln!("ERROR: {:?}", e);
panic!("Due to the above error, failed to resolve path: {:?}", p);
}
}
})
.collect();
remap_paths(&mut paths); remap_paths(&mut paths);
@ -629,7 +646,7 @@ impl<'a> ShouldRun<'a> {
/// (for now, just `all_krates` and `paths`, but we may want to add an `aliases` function in the future?) /// (for now, just `all_krates` and `paths`, but we may want to add an `aliases` function in the future?)
fn pathset_for_paths_removing_matches( fn pathset_for_paths_removing_matches(
&self, &self,
paths: &mut Vec<&Path>, paths: &mut Vec<PathBuf>,
kind: Kind, kind: Kind,
) -> Vec<PathSet> { ) -> Vec<PathSet> {
let mut sets = vec![]; let mut sets = vec![];

View File

@ -122,11 +122,14 @@ fn test_intersection() {
PathSet::Set(paths.into_iter().map(|p| TaskPath { path: p.into(), kind: None }).collect()) PathSet::Set(paths.into_iter().map(|p| TaskPath { path: p.into(), kind: None }).collect())
}; };
let library_set = set(&["library/core", "library/alloc", "library/std"]); let library_set = set(&["library/core", "library/alloc", "library/std"]);
let mut command_paths = let mut command_paths = vec![
vec![Path::new("library/core"), Path::new("library/alloc"), Path::new("library/stdarch")]; PathBuf::from("library/core"),
PathBuf::from("library/alloc"),
PathBuf::from("library/stdarch"),
];
let subset = library_set.intersection_removing_matches(&mut command_paths, Kind::Build); let subset = library_set.intersection_removing_matches(&mut command_paths, Kind::Build);
assert_eq!(subset, set(&["library/core", "library/alloc"]),); assert_eq!(subset, set(&["library/core", "library/alloc"]),);
assert_eq!(command_paths, vec![Path::new("library/stdarch")]); assert_eq!(command_paths, vec![PathBuf::from("library/stdarch")]);
} }
#[test] #[test]