Skip to content

Commit 373737a

Browse files
committed
Migrate LLVM CI change detection to check_path_modifications
1 parent a28f34e commit 373737a

File tree

6 files changed

+58
-35
lines changed

6 files changed

+58
-35
lines changed

src/bootstrap/src/core/build_steps/gcc.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,13 @@ use std::fs;
1212
use std::path::{Path, PathBuf};
1313
use std::sync::OnceLock;
1414

15+
use build_helper::ci::CiEnv;
16+
1517
use crate::core::builder::{Builder, Cargo, Kind, RunConfig, ShouldRun, Step};
1618
use crate::core::config::TargetSelection;
1719
use crate::utils::build_stamp::{BuildStamp, generate_smart_stamp_hash};
1820
use crate::utils::exec::command;
1921
use crate::utils::helpers::{self, t};
20-
use build_helper::ci::CiEnv;
2122

2223
#[derive(Debug, Clone, Hash, PartialEq, Eq)]
2324
pub struct Gcc {
@@ -97,6 +98,8 @@ pub enum GccBuildStatus {
9798
/// Returns a path to the libgccjit.so file.
9899
#[cfg(not(test))]
99100
fn try_download_gcc(builder: &Builder<'_>, target: TargetSelection) -> Option<PathBuf> {
101+
use build_helper::git::PathFreshness;
102+
100103
// Try to download GCC from CI if configured and available
101104
if !matches!(builder.config.gcc_ci_mode, crate::core::config::GccCiMode::DownloadFromCi) {
102105
return None;

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

Lines changed: 23 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ use std::sync::OnceLock;
1515
use std::{env, fs};
1616

1717
use build_helper::ci::CiEnv;
18-
use build_helper::git::get_closest_merge_commit;
18+
use build_helper::git::{PathFreshness, check_path_modifications};
1919
#[cfg(feature = "tracing")]
2020
use tracing::instrument;
2121

@@ -174,35 +174,38 @@ pub fn prebuilt_llvm_config(
174174
LlvmBuildStatus::ShouldBuild(Meta { stamp, res, out_dir, root: root.into() })
175175
}
176176

177-
/// This retrieves the LLVM sha we *want* to use, according to git history.
178-
pub(crate) fn detect_llvm_sha(config: &Config, is_git: bool) -> String {
179-
let llvm_sha = if is_git {
180-
get_closest_merge_commit(
181-
Some(&config.src),
182-
&config.git_config(),
183-
&[
184-
config.src.join("src/llvm-project"),
185-
config.src.join("src/bootstrap/download-ci-llvm-stamp"),
186-
// the LLVM shared object file is named `LLVM-12-rust-{version}-nightly`
187-
config.src.join("src/version"),
188-
],
177+
/// Detect whether LLVM sources have been modified locally or not.
178+
pub(crate) fn detect_llvm_freshness(config: &Config, is_git: bool) -> PathFreshness {
179+
let freshness = if is_git {
180+
Some(
181+
check_path_modifications(
182+
Some(&config.src),
183+
&config.git_config(),
184+
&[
185+
"src/llvm-project",
186+
"src/bootstrap/download-ci-llvm-stamp",
187+
// the LLVM shared object file is named `LLVM-12-rust-{version}-nightly`
188+
"src/version",
189+
],
190+
CiEnv::current(),
191+
)
192+
.unwrap(),
189193
)
190-
.unwrap()
191194
} else if let Some(info) = crate::utils::channel::read_commit_info_file(&config.src) {
192-
info.sha.trim().to_owned()
195+
Some(PathFreshness::LastModifiedUpstream { upstream: info.sha.trim().to_owned() })
193196
} else {
194-
"".to_owned()
197+
None
195198
};
196199

197-
if llvm_sha.is_empty() {
200+
let Some(freshness) = freshness else {
198201
eprintln!("error: could not find commit hash for downloading LLVM");
199202
eprintln!("HELP: maybe your repository history is too shallow?");
200203
eprintln!("HELP: consider disabling `download-ci-llvm`");
201204
eprintln!("HELP: or fetch enough history to include one upstream commit");
202205
panic!();
203-
}
206+
};
204207

205-
llvm_sha
208+
freshness
206209
}
207210

208211
/// Returns whether the CI-found LLVM is currently usable.
@@ -282,12 +285,7 @@ pub(crate) fn is_ci_llvm_modified(config: &Config) -> bool {
282285
return false;
283286
}
284287

285-
let llvm_sha = detect_llvm_sha(config, true);
286-
let head_sha = crate::output(
287-
helpers::git(Some(&config.src)).arg("rev-parse").arg("HEAD").as_command_mut(),
288-
);
289-
let head_sha = head_sha.trim();
290-
llvm_sha == head_sha
288+
matches!(detect_llvm_freshness(config, true), PathFreshness::HasLocalModifications { .. })
291289
}
292290

293291
#[derive(Debug, Clone, Hash, PartialEq, Eq)]

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

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,9 @@ use std::{cmp, env, fs};
1515

1616
use build_helper::ci::CiEnv;
1717
use build_helper::exit;
18-
use build_helper::git::{GitConfig, get_closest_merge_commit, output_result};
18+
use build_helper::git::{
19+
GitConfig, PathFreshness, check_path_modifications, get_closest_merge_commit, output_result,
20+
};
1921
use serde::{Deserialize, Deserializer};
2022
use serde_derive::Deserialize;
2123
#[cfg(feature = "tracing")]
@@ -3107,9 +3109,7 @@ impl Config {
31073109
self.update_submodule("src/llvm-project");
31083110

31093111
// Check for untracked changes in `src/llvm-project`.
3110-
let has_changes = self
3111-
.last_modified_commit(&["src/llvm-project"], "download-ci-llvm", true)
3112-
.is_none();
3112+
let has_changes = self.has_changes_from_upstream(&["src/llvm-project"]);
31133113

31143114
// Return false if there are untracked changes, otherwise check if CI LLVM is available.
31153115
if has_changes { false } else { llvm::is_ci_llvm_available(self, asserts) }
@@ -3133,6 +3133,17 @@ impl Config {
31333133
}
31343134
}
31353135

3136+
/// Returns true if any of the `paths` have been modified locally.
3137+
fn has_changes_from_upstream(&self, paths: &[&str]) -> bool {
3138+
let freshness =
3139+
check_path_modifications(Some(&self.src), &self.git_config(), paths, CiEnv::current())
3140+
.unwrap();
3141+
match freshness {
3142+
PathFreshness::LastModifiedUpstream { .. } => false,
3143+
PathFreshness::HasLocalModifications { .. } => true,
3144+
}
3145+
}
3146+
31363147
/// Returns the last commit in which any of `modified_paths` were changed,
31373148
/// or `None` if there are untracked changes in the working directory and `if_unchanged` is true.
31383149
pub fn last_modified_commit(

src/bootstrap/src/core/download.rs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -721,16 +721,21 @@ download-rustc = false
721721
#[cfg(not(test))]
722722
pub(crate) fn maybe_download_ci_llvm(&self) {
723723
use build_helper::exit;
724+
use build_helper::git::PathFreshness;
724725

725-
use crate::core::build_steps::llvm::detect_llvm_sha;
726+
use crate::core::build_steps::llvm::detect_llvm_freshness;
726727
use crate::core::config::check_incompatible_options_for_ci_llvm;
727728

728729
if !self.llvm_from_ci {
729730
return;
730731
}
731732

732733
let llvm_root = self.ci_llvm_root();
733-
let llvm_sha = detect_llvm_sha(self, self.rust_info.is_managed_git_subrepository());
734+
let llvm_sha =
735+
match detect_llvm_freshness(self, self.rust_info.is_managed_git_subrepository()) {
736+
PathFreshness::LastModifiedUpstream { upstream } => upstream,
737+
PathFreshness::HasLocalModifications { upstream } => upstream,
738+
};
734739
let stamp_key = format!("{}{}", llvm_sha, self.llvm_assertions);
735740
let llvm_stamp = BuildStamp::new(&llvm_root).with_prefix("llvm").add_stamp(stamp_key);
736741
if !llvm_stamp.is_up_to_date() && !self.dry_run() {

src/build_helper/src/git.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -253,6 +253,11 @@ pub fn check_path_modifications(
253253
upstream_sha
254254
};
255255

256+
// For local environments, we want to find out if something has changed
257+
// from the latest upstream commit.
258+
// However, that should be equivalent to checking if something has changed
259+
// from the latest upstream commit *that modified `target_paths`*, and
260+
// with this approach we do not need to invoke git an additional time.
256261
if has_changed_since(git_dir, &upstream_sha, target_paths) {
257262
Ok(PathFreshness::HasLocalModifications { upstream: upstream_sha })
258263
} else {
@@ -261,7 +266,7 @@ pub fn check_path_modifications(
261266
}
262267

263268
/// Returns true if any of the passed `paths` have changed since the `base` commit.
264-
pub fn has_changed_since(git_dir: Option<&Path>, base: &str, paths: &[&Path]) -> bool {
269+
fn has_changed_since(git_dir: Option<&Path>, base: &str, paths: &[&str]) -> bool {
265270
let mut git = Command::new("git");
266271

267272
if let Some(git_dir) = git_dir {

src/build_helper/src/git/tests.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
1-
use crate::ci::CiEnv;
2-
use crate::git::{GitConfig, PathFreshness, check_path_modifications};
31
use std::ffi::OsStr;
42
use std::fs::OpenOptions;
53
use std::process::Command;
64

5+
use crate::ci::CiEnv;
6+
use crate::git::{GitConfig, PathFreshness, check_path_modifications};
7+
78
#[test]
89
fn test_pr_ci_unchanged_anywhere() {
910
git_test(|ctx| {

0 commit comments

Comments
 (0)