Skip to content

Commit 63a1e05

Browse files
committed
Reuse existing download in y.sh prepare if fresh
1 parent 55872cf commit 63a1e05

File tree

4 files changed

+101
-18
lines changed

4 files changed

+101
-18
lines changed

build_system/abi_cafe.rs

+8-2
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,13 @@ use super::prepare::GitRepo;
44
use super::utils::{spawn_and_wait, CargoProject, Compiler};
55
use super::{CodegenBackend, SysrootKind};
66

7-
static ABI_CAFE_REPO: GitRepo =
8-
GitRepo::github("Gankra", "abi-cafe", "4c6dc8c9c687e2b3a760ff2176ce236872b37212", "abi-cafe");
7+
static ABI_CAFE_REPO: GitRepo = GitRepo::github(
8+
"Gankra",
9+
"abi-cafe",
10+
"4c6dc8c9c687e2b3a760ff2176ce236872b37212",
11+
"588df6d66abbe105",
12+
"abi-cafe",
13+
);
914

1015
static ABI_CAFE: CargoProject = CargoProject::new(&ABI_CAFE_REPO.source_dir(), "abi_cafe_target");
1116

@@ -18,6 +23,7 @@ pub(crate) fn run(
1823
bootstrap_host_compiler: &Compiler,
1924
) {
2025
ABI_CAFE_REPO.fetch(dirs);
26+
ABI_CAFE_REPO.patch(dirs);
2127

2228
eprintln!("Building sysroot for abi-cafe");
2329
build_sysroot::build_sysroot(

build_system/bench.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ static SIMPLE_RAYTRACER_REPO: GitRepo = GitRepo::github(
1010
"ebobby",
1111
"simple-raytracer",
1212
"804a7a21b9e673a482797aa289a18ed480e4d813",
13+
"ad6f59a2331a3f56",
1314
"<none>",
1415
);
1516

@@ -24,9 +25,8 @@ fn benchmark_simple_raytracer(dirs: &Dirs, bootstrap_host_compiler: &Compiler) {
2425
std::process::exit(1);
2526
}
2627

27-
if !SIMPLE_RAYTRACER_REPO.source_dir().to_path(dirs).exists() {
28-
SIMPLE_RAYTRACER_REPO.fetch(dirs);
29-
}
28+
SIMPLE_RAYTRACER_REPO.fetch(dirs);
29+
SIMPLE_RAYTRACER_REPO.patch(dirs);
3030

3131
let bench_runs = env::var("BENCH_RUNS").unwrap_or_else(|_| "10".to_string()).parse().unwrap();
3232

build_system/prepare.rs

+75-9
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,17 @@ use super::tests::LIBCORE_TESTS_SRC;
1010
use super::utils::{copy_dir_recursively, git_command, retry_spawn_and_wait, spawn_and_wait};
1111

1212
pub(crate) fn prepare(dirs: &Dirs, rustc: &Path) {
13-
RelPath::DOWNLOAD.ensure_fresh(dirs);
13+
RelPath::DOWNLOAD.ensure_exists(dirs);
14+
super::tests::RAND_REPO.fetch(dirs);
15+
super::tests::REGEX_REPO.fetch(dirs);
16+
super::tests::PORTABLE_SIMD_REPO.fetch(dirs);
1417

1518
prepare_stdlib(dirs, rustc);
1619
prepare_coretests(dirs, rustc);
1720

18-
super::tests::RAND_REPO.fetch(dirs);
19-
super::tests::REGEX_REPO.fetch(dirs);
20-
super::tests::PORTABLE_SIMD_REPO.fetch(dirs);
21+
super::tests::RAND_REPO.patch(dirs);
22+
super::tests::REGEX_REPO.patch(dirs);
23+
super::tests::PORTABLE_SIMD_REPO.patch(dirs);
2124
}
2225

2326
fn prepare_stdlib(dirs: &Dirs, rustc: &Path) {
@@ -61,21 +64,57 @@ fn prepare_coretests(dirs: &Dirs, rustc: &Path) {
6164
pub(crate) struct GitRepo {
6265
url: GitRepoUrl,
6366
rev: &'static str,
67+
content_hash: &'static str,
6468
patch_name: &'static str,
6569
}
6670

6771
enum GitRepoUrl {
6872
Github { user: &'static str, repo: &'static str },
6973
}
7074

75+
// Note: This uses a hasher which is not cryptographically secure. This is fine as the hash is meant
76+
// to protect against accidental modification and outdated downloads, not against manipulation.
77+
fn hash_file(file: &std::path::Path) -> u64 {
78+
let contents = std::fs::read(file).unwrap();
79+
#[allow(deprecated)]
80+
let mut hasher = std::hash::SipHasher::new();
81+
std::hash::Hash::hash(&contents, &mut hasher);
82+
std::hash::Hasher::finish(&hasher)
83+
}
84+
85+
fn hash_dir(dir: &std::path::Path) -> u64 {
86+
let mut sub_hashes = std::collections::BTreeMap::new();
87+
for entry in std::fs::read_dir(dir).unwrap() {
88+
let entry = entry.unwrap();
89+
if entry.file_type().unwrap().is_dir() {
90+
sub_hashes
91+
.insert(entry.file_name().to_str().unwrap().to_owned(), hash_dir(&entry.path()));
92+
} else {
93+
sub_hashes
94+
.insert(entry.file_name().to_str().unwrap().to_owned(), hash_file(&entry.path()));
95+
}
96+
}
97+
#[allow(deprecated)]
98+
let mut hasher = std::hash::SipHasher::new();
99+
std::hash::Hash::hash(&sub_hashes, &mut hasher);
100+
std::hash::Hasher::finish(&hasher)
101+
}
102+
71103
impl GitRepo {
72104
pub(crate) const fn github(
73105
user: &'static str,
74106
repo: &'static str,
75107
rev: &'static str,
108+
content_hash: &'static str,
76109
patch_name: &'static str,
77110
) -> GitRepo {
78-
GitRepo { url: GitRepoUrl::Github { user, repo }, rev, patch_name }
111+
GitRepo { url: GitRepoUrl::Github { user, repo }, rev, content_hash, patch_name }
112+
}
113+
114+
fn download_dir(&self, dirs: &Dirs) -> PathBuf {
115+
match self.url {
116+
GitRepoUrl::Github { user: _, repo } => RelPath::DOWNLOAD.join(repo).to_path(dirs),
117+
}
79118
}
80119

81120
pub(crate) const fn source_dir(&self) -> RelPath {
@@ -85,15 +124,42 @@ impl GitRepo {
85124
}
86125

87126
pub(crate) fn fetch(&self, dirs: &Dirs) {
88-
let download_dir = match self.url {
89-
GitRepoUrl::Github { user: _, repo } => RelPath::DOWNLOAD.join(repo).to_path(dirs),
90-
};
91-
let source_dir = self.source_dir();
127+
let download_dir = self.download_dir(dirs);
128+
129+
if download_dir.exists() {
130+
let actual_hash = format!("{:016x}", hash_dir(&download_dir));
131+
if actual_hash == self.content_hash {
132+
println!("[FRESH] {}", download_dir.display());
133+
return;
134+
} else {
135+
println!(
136+
"Mismatched content hash for {download_dir}: {actual_hash} != {content_hash}. Downloading again.",
137+
download_dir = download_dir.display(),
138+
content_hash = self.content_hash,
139+
);
140+
}
141+
}
142+
92143
match self.url {
93144
GitRepoUrl::Github { user, repo } => {
94145
clone_repo_shallow_github(dirs, &download_dir, user, repo, self.rev);
95146
}
96147
}
148+
149+
let actual_hash = format!("{:016x}", hash_dir(&download_dir));
150+
if actual_hash != self.content_hash {
151+
println!(
152+
"Download of {download_dir} failed with mismatched content hash: {actual_hash} != {content_hash}",
153+
download_dir = download_dir.display(),
154+
content_hash = self.content_hash,
155+
);
156+
std::process::exit(1);
157+
}
158+
}
159+
160+
pub(crate) fn patch(&self, dirs: &Dirs) {
161+
let download_dir = self.download_dir(dirs);
162+
let source_dir = self.source_dir();
97163
source_dir.ensure_fresh(dirs);
98164
copy_dir_recursively(&download_dir, &source_dir.to_path(dirs));
99165
apply_patches(dirs, self.patch_name, &source_dir.to_path(dirs));

build_system/tests.rs

+15-4
Original file line numberDiff line numberDiff line change
@@ -94,20 +94,31 @@ const BASE_SYSROOT_SUITE: &[TestCase] = &[
9494

9595
// FIXME(rust-random/rand#1293): Newer rand versions fail to test on Windows. Update once this is
9696
// fixed.
97-
pub(crate) static RAND_REPO: GitRepo =
98-
GitRepo::github("rust-random", "rand", "50b9a447410860af8d6db9a208c3576886955874", "rand");
97+
pub(crate) static RAND_REPO: GitRepo = GitRepo::github(
98+
"rust-random",
99+
"rand",
100+
"50b9a447410860af8d6db9a208c3576886955874",
101+
"98b2276210b30e43",
102+
"rand",
103+
);
99104

100105
pub(crate) static RAND: CargoProject = CargoProject::new(&RAND_REPO.source_dir(), "rand_target");
101106

102-
pub(crate) static REGEX_REPO: GitRepo =
103-
GitRepo::github("rust-lang", "regex", "32fed9429eafba0ae92a64b01796a0c5a75b88c8", "regex");
107+
pub(crate) static REGEX_REPO: GitRepo = GitRepo::github(
108+
"rust-lang",
109+
"regex",
110+
"32fed9429eafba0ae92a64b01796a0c5a75b88c8",
111+
"d6af6507d565aa66",
112+
"regex",
113+
);
104114

105115
pub(crate) static REGEX: CargoProject = CargoProject::new(&REGEX_REPO.source_dir(), "regex_target");
106116

107117
pub(crate) static PORTABLE_SIMD_REPO: GitRepo = GitRepo::github(
108118
"rust-lang",
109119
"portable-simd",
110120
"ad8afa8c81273b3b49acbea38cd3bcf17a34cf2b",
121+
"1ba291009510070b",
111122
"portable-simd",
112123
);
113124

0 commit comments

Comments
 (0)