Skip to content

Commit 2b5a982

Browse files
committed
abstract merge-base commit logic
Signed-off-by: onur-ozkan <[email protected]>
1 parent cb12b52 commit 2b5a982

File tree

4 files changed

+54
-41
lines changed

4 files changed

+54
-41
lines changed

src/bootstrap/src/core/build_steps/llvm.rs

+12-21
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@ use crate::{generate_smart_stamp_hash, CLang, GitRepo, Kind};
2626

2727
use crate::utils::exec::command;
2828
use build_helper::ci::CiEnv;
29-
use build_helper::git::get_git_merge_base;
3029

3130
#[derive(Clone)]
3231
pub struct LlvmResult {
@@ -154,26 +153,18 @@ pub fn prebuilt_llvm_config(builder: &Builder<'_>, target: TargetSelection) -> L
154153
/// This retrieves the LLVM sha we *want* to use, according to git history.
155154
pub(crate) fn detect_llvm_sha(config: &Config, is_git: bool) -> String {
156155
let llvm_sha = if is_git {
157-
// We proceed in 2 steps. First we get the closest commit that is actually upstream. Then we
158-
// walk back further to the last bors merge commit that actually changed LLVM. The first
159-
// step will fail on CI because only the `auto` branch exists; we just fall back to `HEAD`
160-
// in that case.
161-
let closest_upstream = get_git_merge_base(&config.git_config(), Some(&config.src))
162-
.unwrap_or_else(|_| "HEAD".into());
163-
let mut rev_list = helpers::git(Some(&config.src));
164-
rev_list.args(&[
165-
PathBuf::from("rev-list"),
166-
format!("--author={}", config.stage0_metadata.config.git_merge_commit_email).into(),
167-
"-n1".into(),
168-
"--first-parent".into(),
169-
closest_upstream.into(),
170-
"--".into(),
171-
config.src.join("src/llvm-project"),
172-
config.src.join("src/bootstrap/download-ci-llvm-stamp"),
173-
// the LLVM shared object file is named `LLVM-12-rust-{version}-nightly`
174-
config.src.join("src/version"),
175-
]);
176-
output(rev_list.as_command_mut()).trim().to_owned()
156+
helpers::get_closest_merge_base_commit(
157+
Some(&config.src),
158+
&config.git_config(),
159+
&config.stage0_metadata.config.git_merge_commit_email,
160+
&[
161+
config.src.join("src/llvm-project"),
162+
config.src.join("src/bootstrap/download-ci-llvm-stamp"),
163+
// the LLVM shared object file is named `LLVM-12-rust-{version}-nightly`
164+
config.src.join("src/version"),
165+
],
166+
)
167+
.unwrap()
177168
} else if let Some(info) = channel::read_commit_info_file(&config.src) {
178169
info.sha.trim().to_owned()
179170
} else {

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

+17-19
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ use crate::core::build_steps::llvm;
2020
use crate::core::config::flags::{Color, Flags, Warnings};
2121
use crate::utils::cache::{Interned, INTERNER};
2222
use crate::utils::channel::{self, GitInfo};
23-
use crate::utils::helpers::{self, exe, output, t};
23+
use crate::utils::helpers::{self, exe, get_closest_merge_base_commit, output, t};
2424
use build_helper::exit;
2525
use serde::{Deserialize, Deserializer};
2626
use serde_derive::Deserialize;
@@ -2471,14 +2471,13 @@ impl Config {
24712471

24722472
// Look for a version to compare to based on the current commit.
24732473
// Only commits merged by bors will have CI artifacts.
2474-
let merge_base = output(
2475-
helpers::git(Some(&self.src))
2476-
.arg("rev-list")
2477-
.arg(format!("--author={}", self.stage0_metadata.config.git_merge_commit_email))
2478-
.args(["-n1", "--first-parent", "HEAD"])
2479-
.as_command_mut(),
2480-
);
2481-
let commit = merge_base.trim_end();
2474+
let commit = get_closest_merge_base_commit(
2475+
Some(&self.src),
2476+
&self.git_config(),
2477+
&self.stage0_metadata.config.git_merge_commit_email,
2478+
&[],
2479+
)
2480+
.unwrap();
24822481
if commit.is_empty() {
24832482
println!("ERROR: could not find commit hash for downloading rustc");
24842483
println!("HELP: maybe your repository history is too shallow?");
@@ -2489,7 +2488,7 @@ impl Config {
24892488

24902489
// Warn if there were changes to the compiler or standard library since the ancestor commit.
24912490
let has_changes = !t!(helpers::git(Some(&self.src))
2492-
.args(["diff-index", "--quiet", commit])
2491+
.args(["diff-index", "--quiet", &commit])
24932492
.arg("--")
24942493
.args([self.src.join("compiler"), self.src.join("library")])
24952494
.as_command_mut()
@@ -2565,14 +2564,13 @@ impl Config {
25652564
) -> Option<String> {
25662565
// Look for a version to compare to based on the current commit.
25672566
// Only commits merged by bors will have CI artifacts.
2568-
let merge_base = output(
2569-
helpers::git(Some(&self.src))
2570-
.arg("rev-list")
2571-
.arg(format!("--author={}", self.stage0_metadata.config.git_merge_commit_email))
2572-
.args(["-n1", "--first-parent", "HEAD"])
2573-
.as_command_mut(),
2574-
);
2575-
let commit = merge_base.trim_end();
2567+
let commit = get_closest_merge_base_commit(
2568+
Some(&self.src),
2569+
&self.git_config(),
2570+
&self.stage0_metadata.config.git_merge_commit_email,
2571+
&[],
2572+
)
2573+
.unwrap();
25762574
if commit.is_empty() {
25772575
println!("error: could not find commit hash for downloading components from CI");
25782576
println!("help: maybe your repository history is too shallow?");
@@ -2583,7 +2581,7 @@ impl Config {
25832581

25842582
// Warn if there were changes to the compiler or standard library since the ancestor commit.
25852583
let mut git = helpers::git(Some(&self.src));
2586-
git.args(["diff-index", "--quiet", commit, "--"]);
2584+
git.args(["diff-index", "--quiet", &commit, "--"]);
25872585

25882586
// Handle running from a directory other than the top level
25892587
let top_level = &self.src;

src/bootstrap/src/utils/helpers.rs

+24
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
//! Simple things like testing the various filesystem operations here and there,
44
//! not a lot of interesting happenings here unfortunately.
55
6+
use build_helper::git::{get_git_merge_base, output_result, GitConfig};
67
use build_helper::util::fail;
78
use std::env;
89
use std::ffi::OsStr;
@@ -521,3 +522,26 @@ pub fn git(source_dir: Option<&Path>) -> BootstrapCommand {
521522

522523
git
523524
}
525+
526+
/// Returns the closest commit available from upstream for the given `author` and `target_paths`.
527+
///
528+
/// If it fails to find the commit from upstream using `git merge-base`, fallbacks to HEAD.
529+
pub fn get_closest_merge_base_commit(
530+
source_dir: Option<&Path>,
531+
config: &GitConfig<'_>,
532+
author: &str,
533+
target_paths: &[PathBuf],
534+
) -> Result<String, String> {
535+
let mut git = git(source_dir).capture_stdout();
536+
537+
let merge_base = get_git_merge_base(config, source_dir).unwrap_or_else(|_| "HEAD".into());
538+
539+
git.arg(Path::new("rev-list"));
540+
git.args([&format!("--author={author}"), "-n1", "--first-parent", &merge_base]);
541+
542+
if !target_paths.is_empty() {
543+
git.arg("--").args(target_paths);
544+
}
545+
546+
Ok(output_result(git.as_command_mut())?.trim().to_owned())
547+
}

src/tools/build_helper/src/git.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ pub struct GitConfig<'a> {
77
}
88

99
/// Runs a command and returns the output
10-
fn output_result(cmd: &mut Command) -> Result<String, String> {
10+
pub fn output_result(cmd: &mut Command) -> Result<String, String> {
1111
let output = match cmd.stderr(Stdio::inherit()).output() {
1212
Ok(status) => status,
1313
Err(e) => return Err(format!("failed to run command: {:?}: {}", cmd, e)),

0 commit comments

Comments
 (0)