Skip to content

Commit e3fe724

Browse files
committed
Reuse existing download in y.sh prepare if fresh
1 parent f1f76e7 commit e3fe724

File tree

4 files changed

+102
-18
lines changed

4 files changed

+102
-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

+76-9
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,18 @@ 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

18+
// FIXME do this on the fly?
1519
prepare_stdlib(dirs, rustc);
1620
prepare_coretests(dirs, rustc);
1721

18-
super::tests::RAND_REPO.fetch(dirs);
19-
super::tests::REGEX_REPO.fetch(dirs);
20-
super::tests::PORTABLE_SIMD_REPO.fetch(dirs);
22+
super::tests::RAND_REPO.patch(dirs);
23+
super::tests::REGEX_REPO.patch(dirs);
24+
super::tests::PORTABLE_SIMD_REPO.patch(dirs);
2125
}
2226

2327
fn prepare_stdlib(dirs: &Dirs, rustc: &Path) {
@@ -61,21 +65,57 @@ fn prepare_coretests(dirs: &Dirs, rustc: &Path) {
6165
pub(crate) struct GitRepo {
6266
url: GitRepoUrl,
6367
rev: &'static str,
68+
content_hash: &'static str,
6469
patch_name: &'static str,
6570
}
6671

6772
enum GitRepoUrl {
6873
Github { user: &'static str, repo: &'static str },
6974
}
7075

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

81121
pub(crate) const fn source_dir(&self) -> RelPath {
@@ -85,15 +125,42 @@ impl GitRepo {
85125
}
86126

87127
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();
128+
let download_dir = self.download_dir(dirs);
129+
130+
if download_dir.exists() {
131+
let actual_hash = format!("{:016x}", hash_dir(&download_dir));
132+
if actual_hash == self.content_hash {
133+
println!("[FRESH] {}", download_dir.display());
134+
return;
135+
} else {
136+
println!(
137+
"Mismatched content hash for {download_dir}: {actual_hash} != {content_hash}. Downloading again.",
138+
download_dir = download_dir.display(),
139+
content_hash = self.content_hash,
140+
);
141+
}
142+
}
143+
92144
match self.url {
93145
GitRepoUrl::Github { user, repo } => {
94146
clone_repo_shallow_github(dirs, &download_dir, user, repo, self.rev);
95147
}
96148
}
149+
150+
let actual_hash = format!("{:016x}", hash_dir(&download_dir));
151+
if actual_hash != self.content_hash {
152+
println!(
153+
"Download of {download_dir} failed with mismatched content hash: {actual_hash} != {content_hash}",
154+
download_dir = download_dir.display(),
155+
content_hash = self.content_hash,
156+
);
157+
std::process::exit(1);
158+
}
159+
}
160+
161+
pub(crate) fn patch(&self, dirs: &Dirs) {
162+
let download_dir = self.download_dir(dirs);
163+
let source_dir = self.source_dir();
97164
source_dir.ensure_fresh(dirs);
98165
copy_dir_recursively(&download_dir, &source_dir.to_path(dirs));
99166
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)