Skip to content

Commit 0cf3ce4

Browse files
committed
build-manifest: refactor checksum generation into a struct
1 parent 0ee1e91 commit 0cf3ce4

File tree

2 files changed

+82
-50
lines changed

2 files changed

+82
-50
lines changed
+75
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
use crate::manifest::{FileHash, Manifest};
2+
use rayon::prelude::*;
3+
use sha2::{Digest, Sha256};
4+
use std::collections::{HashMap, HashSet};
5+
use std::error::Error;
6+
use std::fs::File;
7+
use std::io::BufReader;
8+
use std::path::{Path, PathBuf};
9+
use std::sync::Mutex;
10+
use std::time::Instant;
11+
12+
pub(crate) struct Checksums {
13+
collected: Mutex<HashMap<PathBuf, String>>,
14+
}
15+
16+
impl Checksums {
17+
pub(crate) fn new() -> Self {
18+
Checksums { collected: Mutex::new(HashMap::new()) }
19+
}
20+
21+
pub(crate) fn fill_missing_checksums(&mut self, manifest: &mut Manifest) {
22+
let need_checksums = self.find_missing_checksums(manifest);
23+
if !need_checksums.is_empty() {
24+
self.collect_checksums(&need_checksums);
25+
}
26+
self.replace_checksums(manifest);
27+
}
28+
29+
fn find_missing_checksums(&mut self, manifest: &mut Manifest) -> HashSet<PathBuf> {
30+
let mut need_checksums = HashSet::new();
31+
crate::manifest::visit_file_hashes(manifest, |file_hash| {
32+
if let FileHash::Missing(path) = file_hash {
33+
need_checksums.insert(path.clone());
34+
}
35+
});
36+
need_checksums
37+
}
38+
39+
fn replace_checksums(&mut self, manifest: &mut Manifest) {
40+
let collected = self.collected.lock().unwrap();
41+
crate::manifest::visit_file_hashes(manifest, |file_hash| {
42+
if let FileHash::Missing(path) = file_hash {
43+
match collected.get(path) {
44+
Some(hash) => *file_hash = FileHash::Present(hash.clone()),
45+
None => panic!("missing hash for file {}", path.display()),
46+
}
47+
}
48+
});
49+
}
50+
51+
fn collect_checksums(&mut self, files: &HashSet<PathBuf>) {
52+
let collection_start = Instant::now();
53+
println!(
54+
"collecting hashes for {} tarballs across {} threads",
55+
files.len(),
56+
rayon::current_num_threads().min(files.len()),
57+
);
58+
59+
files.par_iter().for_each(|path| match hash(path) {
60+
Ok(hash) => {
61+
self.collected.lock().unwrap().insert(path.clone(), hash);
62+
}
63+
Err(err) => eprintln!("error while fetching the hash for {}: {}", path.display(), err),
64+
});
65+
66+
println!("collected {} hashes in {:.2?}", files.len(), collection_start.elapsed());
67+
}
68+
}
69+
70+
fn hash(path: &Path) -> Result<String, Box<dyn Error>> {
71+
let mut file = BufReader::new(File::open(path)?);
72+
let mut sha256 = Sha256::default();
73+
std::io::copy(&mut file, &mut sha256)?;
74+
Ok(hex::encode(sha256.finalize()))
75+
}

src/tools/build-manifest/src/main.rs

+7-50
Original file line numberDiff line numberDiff line change
@@ -4,22 +4,19 @@
44
//! via `x.py dist hash-and-sign`; the cmdline arguments are set up
55
//! by rustbuild (in `src/bootstrap/dist.rs`).
66
7+
mod checksum;
78
mod manifest;
89
mod versions;
910

10-
use crate::manifest::{Component, FileHash, Manifest, Package, Rename, Target};
11+
use crate::checksum::Checksums;
12+
use crate::manifest::{Component, Manifest, Package, Rename, Target};
1113
use crate::versions::{PkgType, Versions};
12-
use rayon::prelude::*;
13-
use sha2::Digest;
1414
use std::collections::{BTreeMap, HashMap, HashSet};
1515
use std::env;
16-
use std::error::Error;
1716
use std::fs::{self, File};
18-
use std::io::{self, BufReader, Read, Write};
17+
use std::io::{self, Read, Write};
1918
use std::path::{Path, PathBuf};
2019
use std::process::{Command, Stdio};
21-
use std::sync::Mutex;
22-
use std::time::Instant;
2320

2421
static HOSTS: &[&str] = &[
2522
"aarch64-apple-darwin",
@@ -186,6 +183,7 @@ macro_rules! t {
186183

187184
struct Builder {
188185
versions: Versions,
186+
checksums: Checksums,
189187
shipped_files: HashSet<String>,
190188

191189
input: PathBuf,
@@ -240,6 +238,7 @@ fn main() {
240238

241239
Builder {
242240
versions: Versions::new(&channel, &input).unwrap(),
241+
checksums: Checksums::new(),
243242
shipped_files: HashSet::new(),
244243

245244
input,
@@ -321,7 +320,7 @@ impl Builder {
321320
self.add_renames_to(&mut manifest);
322321
manifest.pkg.insert("rust".to_string(), self.rust_package(&manifest));
323322

324-
self.fill_missing_hashes(&mut manifest);
323+
self.checksums.fill_missing_checksums(&mut manifest);
325324

326325
manifest
327326
}
@@ -595,41 +594,6 @@ impl Builder {
595594
assert!(t!(child.wait()).success());
596595
}
597596

598-
fn fill_missing_hashes(&self, manifest: &mut Manifest) {
599-
// First collect all files that need hashes
600-
let mut need_hashes = HashSet::new();
601-
crate::manifest::visit_file_hashes(manifest, |file_hash| {
602-
if let FileHash::Missing(path) = file_hash {
603-
need_hashes.insert(path.clone());
604-
}
605-
});
606-
607-
let collected = Mutex::new(HashMap::new());
608-
let collection_start = Instant::now();
609-
println!(
610-
"collecting hashes for {} tarballs across {} threads",
611-
need_hashes.len(),
612-
rayon::current_num_threads().min(need_hashes.len()),
613-
);
614-
need_hashes.par_iter().for_each(|path| match fetch_hash(path) {
615-
Ok(hash) => {
616-
collected.lock().unwrap().insert(path, hash);
617-
}
618-
Err(err) => eprintln!("error while fetching the hash for {}: {}", path.display(), err),
619-
});
620-
let collected = collected.into_inner().unwrap();
621-
println!("collected {} hashes in {:.2?}", collected.len(), collection_start.elapsed());
622-
623-
crate::manifest::visit_file_hashes(manifest, |file_hash| {
624-
if let FileHash::Missing(path) = file_hash {
625-
match collected.get(path) {
626-
Some(hash) => *file_hash = FileHash::Present(hash.clone()),
627-
None => panic!("missing hash for file {}", path.display()),
628-
}
629-
}
630-
})
631-
}
632-
633597
fn write_channel_files(&mut self, channel_name: &str, manifest: &Manifest) {
634598
self.write(&toml::to_string(&manifest).unwrap(), channel_name, ".toml");
635599
self.write(&manifest.date, channel_name, "-date.txt");
@@ -660,10 +624,3 @@ impl Builder {
660624
t!(std::fs::write(path, content.as_bytes()));
661625
}
662626
}
663-
664-
fn fetch_hash(path: &Path) -> Result<String, Box<dyn Error>> {
665-
let mut file = BufReader::new(File::open(path)?);
666-
let mut sha256 = sha2::Sha256::default();
667-
std::io::copy(&mut file, &mut sha256)?;
668-
Ok(hex::encode(sha256.finalize()))
669-
}

0 commit comments

Comments
 (0)