Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 77a4b86

Browse files
authoredMar 21, 2025
Unrolled build for rust-lang#138706
Rollup merge of rust-lang#138706 - Kobzol:bootstrap-git-refactor-1, r=onur-ozkan Improve bootstrap git modified path handling Drive-by improvements extracted out of rust-lang#138591. r? ``@onur-ozkan``
2 parents a4a11ac + b24dc75 commit 77a4b86

File tree

5 files changed

+58
-56
lines changed

5 files changed

+58
-56
lines changed
 

‎src/bootstrap/src/core/build_steps/format.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ fn get_modified_rs_files(build: &Builder<'_>) -> Result<Option<Vec<String>>, Str
9393
return Ok(None);
9494
}
9595

96-
get_git_modified_files(&build.config.git_config(), Some(&build.config.src), &["rs"])
96+
get_git_modified_files(&build.config.git_config(), Some(&build.config.src), &["rs"]).map(Some)
9797
}
9898

9999
#[derive(serde_derive::Deserialize)]

‎src/bootstrap/src/core/config/config.rs

+49-45
Original file line numberDiff line numberDiff line change
@@ -1429,52 +1429,56 @@ impl Config {
14291429

14301430
// Infer the rest of the configuration.
14311431

1432-
// Infer the source directory. This is non-trivial because we want to support a downloaded bootstrap binary,
1433-
// running on a completely different machine from where it was compiled.
1434-
let mut cmd = helpers::git(None);
1435-
// NOTE: we cannot support running from outside the repository because the only other path we have available
1436-
// is set at compile time, which can be wrong if bootstrap was downloaded rather than compiled locally.
1437-
// We still support running outside the repository if we find we aren't in a git directory.
1438-
1439-
// NOTE: We get a relative path from git to work around an issue on MSYS/mingw. If we used an absolute path,
1440-
// and end up using MSYS's git rather than git-for-windows, we would get a unix-y MSYS path. But as bootstrap
1441-
// has already been (kinda-cross-)compiled to Windows land, we require a normal Windows path.
1442-
cmd.arg("rev-parse").arg("--show-cdup");
1443-
// Discard stderr because we expect this to fail when building from a tarball.
1444-
let output = cmd
1445-
.as_command_mut()
1446-
.stderr(std::process::Stdio::null())
1447-
.output()
1448-
.ok()
1449-
.and_then(|output| if output.status.success() { Some(output) } else { None });
1450-
if let Some(output) = output {
1451-
let git_root_relative = String::from_utf8(output.stdout).unwrap();
1452-
// We need to canonicalize this path to make sure it uses backslashes instead of forward slashes,
1453-
// and to resolve any relative components.
1454-
let git_root = env::current_dir()
1455-
.unwrap()
1456-
.join(PathBuf::from(git_root_relative.trim()))
1457-
.canonicalize()
1458-
.unwrap();
1459-
let s = git_root.to_str().unwrap();
1460-
1461-
// Bootstrap is quite bad at handling /? in front of paths
1462-
let git_root = match s.strip_prefix("\\\\?\\") {
1463-
Some(p) => PathBuf::from(p),
1464-
None => git_root,
1465-
};
1466-
// If this doesn't have at least `stage0`, we guessed wrong. This can happen when,
1467-
// for example, the build directory is inside of another unrelated git directory.
1468-
// In that case keep the original `CARGO_MANIFEST_DIR` handling.
1469-
//
1470-
// NOTE: this implies that downloadable bootstrap isn't supported when the build directory is outside
1471-
// the source directory. We could fix that by setting a variable from all three of python, ./x, and x.ps1.
1472-
if git_root.join("src").join("stage0").exists() {
1473-
config.src = git_root;
1474-
}
1432+
if let Some(src) = flags.src {
1433+
config.src = src
14751434
} else {
1476-
// We're building from a tarball, not git sources.
1477-
// We don't support pre-downloaded bootstrap in this case.
1435+
// Infer the source directory. This is non-trivial because we want to support a downloaded bootstrap binary,
1436+
// running on a completely different machine from where it was compiled.
1437+
let mut cmd = helpers::git(None);
1438+
// NOTE: we cannot support running from outside the repository because the only other path we have available
1439+
// is set at compile time, which can be wrong if bootstrap was downloaded rather than compiled locally.
1440+
// We still support running outside the repository if we find we aren't in a git directory.
1441+
1442+
// NOTE: We get a relative path from git to work around an issue on MSYS/mingw. If we used an absolute path,
1443+
// and end up using MSYS's git rather than git-for-windows, we would get a unix-y MSYS path. But as bootstrap
1444+
// has already been (kinda-cross-)compiled to Windows land, we require a normal Windows path.
1445+
cmd.arg("rev-parse").arg("--show-cdup");
1446+
// Discard stderr because we expect this to fail when building from a tarball.
1447+
let output = cmd
1448+
.as_command_mut()
1449+
.stderr(std::process::Stdio::null())
1450+
.output()
1451+
.ok()
1452+
.and_then(|output| if output.status.success() { Some(output) } else { None });
1453+
if let Some(output) = output {
1454+
let git_root_relative = String::from_utf8(output.stdout).unwrap();
1455+
// We need to canonicalize this path to make sure it uses backslashes instead of forward slashes,
1456+
// and to resolve any relative components.
1457+
let git_root = env::current_dir()
1458+
.unwrap()
1459+
.join(PathBuf::from(git_root_relative.trim()))
1460+
.canonicalize()
1461+
.unwrap();
1462+
let s = git_root.to_str().unwrap();
1463+
1464+
// Bootstrap is quite bad at handling /? in front of paths
1465+
let git_root = match s.strip_prefix("\\\\?\\") {
1466+
Some(p) => PathBuf::from(p),
1467+
None => git_root,
1468+
};
1469+
// If this doesn't have at least `stage0`, we guessed wrong. This can happen when,
1470+
// for example, the build directory is inside of another unrelated git directory.
1471+
// In that case keep the original `CARGO_MANIFEST_DIR` handling.
1472+
//
1473+
// NOTE: this implies that downloadable bootstrap isn't supported when the build directory is outside
1474+
// the source directory. We could fix that by setting a variable from all three of python, ./x, and x.ps1.
1475+
if git_root.join("src").join("stage0").exists() {
1476+
config.src = git_root;
1477+
}
1478+
} else {
1479+
// We're building from a tarball, not git sources.
1480+
// We don't support pre-downloaded bootstrap in this case.
1481+
}
14781482
}
14791483

14801484
if cfg!(test) {

‎src/build_helper/src/git.rs

+6-3
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,7 @@ pub fn get_git_modified_files(
173173
config: &GitConfig<'_>,
174174
git_dir: Option<&Path>,
175175
extensions: &[&str],
176-
) -> Result<Option<Vec<String>>, String> {
176+
) -> Result<Vec<String>, String> {
177177
let merge_base = get_closest_merge_commit(git_dir, config, &[])?;
178178

179179
let mut git = Command::new("git");
@@ -186,7 +186,10 @@ pub fn get_git_modified_files(
186186
let (status, name) = f.trim().split_once(char::is_whitespace).unwrap();
187187
if status == "D" {
188188
None
189-
} else if Path::new(name).extension().map_or(false, |ext| {
189+
} else if Path::new(name).extension().map_or(extensions.is_empty(), |ext| {
190+
// If there is no extension, we allow the path if `extensions` is empty
191+
// If there is an extension, we allow it if `extension` is empty or it contains the
192+
// extension.
190193
extensions.is_empty() || extensions.contains(&ext.to_str().unwrap())
191194
}) {
192195
Some(name.to_owned())
@@ -195,7 +198,7 @@ pub fn get_git_modified_files(
195198
}
196199
})
197200
.collect();
198-
Ok(Some(files))
201+
Ok(files)
199202
}
200203

201204
/// Returns the files that haven't been added to git yet.

‎src/tools/compiletest/src/lib.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -747,8 +747,7 @@ fn modified_tests(config: &Config, dir: &Path) -> Result<Vec<PathBuf>, String> {
747747
}
748748

749749
let files =
750-
get_git_modified_files(&config.git_config(), Some(dir), &vec!["rs", "stderr", "fixed"])?
751-
.unwrap_or(vec![]);
750+
get_git_modified_files(&config.git_config(), Some(dir), &vec!["rs", "stderr", "fixed"])?;
752751
// Add new test cases to the list, it will be convenient in daily development.
753752
let untracked_files = get_git_untracked_files(&config.git_config(), None)?.unwrap_or(vec![]);
754753

‎src/tools/suggest-tests/src/main.rs

+1-5
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,7 @@ fn main() -> ExitCode {
1414
&Vec::new(),
1515
);
1616
let modified_files = match modified_files {
17-
Ok(Some(files)) => files,
18-
Ok(None) => {
19-
eprintln!("git error");
20-
return ExitCode::FAILURE;
21-
}
17+
Ok(files) => files,
2218
Err(err) => {
2319
eprintln!("Could not get modified files from git: \"{err}\"");
2420
return ExitCode::FAILURE;

0 commit comments

Comments
 (0)
Failed to load comments.