Skip to content

Commit 766c4a5

Browse files
committed
build-manifest: when Miri tests are not passing, do not add Miri component
1 parent ee83402 commit 766c4a5

File tree

3 files changed

+53
-5
lines changed

3 files changed

+53
-5
lines changed

Cargo.lock

+2
Original file line numberDiff line numberDiff line change
@@ -201,7 +201,9 @@ dependencies = [
201201
name = "build-manifest"
202202
version = "0.1.0"
203203
dependencies = [
204+
"reqwest",
204205
"serde",
206+
"serde_json",
205207
"toml",
206208
]
207209

src/tools/build-manifest/Cargo.toml

+2
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,5 @@ edition = "2018"
77
[dependencies]
88
toml = "0.5"
99
serde = { version = "1.0", features = ["derive"] }
10+
serde_json = "1.0"
11+
reqwest = "0.9"

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

+49-5
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,19 @@
1+
//! Build a dist manifest, hash and sign everything.
2+
//! This gets called by `promote-release`
3+
//! (https://github.com/rust-lang/rust-central-station/tree/master/promote-release)
4+
//! via `x.py dist hash-and-sign`; the cmdline arguments are set up
5+
//! by rustbuild (in `src/bootstrap/dist.rs`).
6+
17
use toml;
28
use serde::Serialize;
39

410
use std::collections::BTreeMap;
511
use std::env;
612
use std::fs;
7-
use std::io::{self, Read, Write};
13+
use std::io::{self, Read, Write, BufRead, BufReader};
814
use std::path::{PathBuf, Path};
915
use std::process::{Command, Stdio};
16+
use std::collections::HashMap;
1017

1118
static HOSTS: &[&str] = &[
1219
"aarch64-unknown-linux-gnu",
@@ -146,6 +153,9 @@ static MINGW: &[&str] = &[
146153
"x86_64-pc-windows-gnu",
147154
];
148155

156+
static TOOLSTATE: &str =
157+
"https://raw.githubusercontent.com/rust-lang-nursery/rust-toolstate/master/history/linux.tsv";
158+
149159
#[derive(Serialize)]
150160
#[serde(rename_all = "kebab-case")]
151161
struct Manifest {
@@ -270,6 +280,7 @@ fn main() {
270280
// Do not ask for a passphrase while manually testing
271281
let mut passphrase = String::new();
272282
if should_sign {
283+
// `x.py` passes the passphrase via stdin.
273284
t!(io::stdin().read_to_string(&mut passphrase));
274285
}
275286

@@ -353,6 +364,7 @@ impl Builder {
353364
self.lldb_git_commit_hash = self.git_commit_hash("lldb", "x86_64-unknown-linux-gnu");
354365
self.miri_git_commit_hash = self.git_commit_hash("miri", "x86_64-unknown-linux-gnu");
355366

367+
self.check_toolstate();
356368
self.digest_and_sign();
357369
let manifest = self.build_manifest();
358370
self.write_channel_files(&self.rust_release, &manifest);
@@ -362,6 +374,37 @@ impl Builder {
362374
}
363375
}
364376

377+
/// If a tool does not pass its tests, don't ship it.
378+
/// Right now, we do this only for Miri.
379+
fn check_toolstate(&mut self) {
380+
// Get the toolstate for this rust revision.
381+
let rev = self.rust_git_commit_hash.as_ref().expect("failed to determine rust git hash");
382+
let toolstates = reqwest::get(TOOLSTATE).expect("failed to get toolstates");
383+
let toolstates = BufReader::new(toolstates);
384+
let toolstate = toolstates.lines()
385+
.find_map(|line| {
386+
let line = line.expect("failed to read toolstate lines");
387+
let mut pieces = line.splitn(2, '\t');
388+
let commit = pieces.next().expect("malformed toolstate line");
389+
if commit != rev {
390+
// Not the right commit.
391+
return None;
392+
}
393+
// Return the 2nd piece, the JSON.
394+
Some(pieces.next().expect("malformed toolstate line").to_owned())
395+
})
396+
.expect("failed to find toolstate for rust commit");
397+
let toolstate: HashMap<String, String> =
398+
serde_json::from_str(&toolstate).expect("toolstate is malformed JSON");
399+
// Mark some tools as missing based on toolstate.
400+
if toolstate.get("miri").map(|s| &*s as &str) != Some("test-pass") {
401+
println!("Miri tests are not passing, removing component");
402+
self.miri_version = None;
403+
self.miri_git_commit_hash = None;
404+
}
405+
}
406+
407+
/// Hash all files, compute their signatures, and collect the hashes in `self.digests`.
365408
fn digest_and_sign(&mut self) {
366409
for file in t!(self.input.read_dir()).map(|e| t!(e).path()) {
367410
let filename = file.file_name().unwrap().to_str().unwrap();
@@ -532,19 +575,20 @@ impl Builder {
532575
.as_ref()
533576
.cloned()
534577
.map(|version| (version, true))
535-
.unwrap_or_default();
578+
.unwrap_or_default(); // `is_present` defaults to `false` here.
536579

537-
// miri needs to build std with xargo, which doesn't allow stable/beta:
538-
// <https://github.com/japaric/xargo/pull/204#issuecomment-374888868>
580+
// Miri is nightly-only; never ship it for other trains.
539581
if pkgname == "miri-preview" && self.rust_release != "nightly" {
540-
is_present = false; // ignore it
582+
is_present = false; // Pretend the component is entirely missing.
541583
}
542584

543585
let targets = targets.iter().map(|name| {
544586
if is_present {
587+
// The component generally exists, but it might still be missing for this target.
545588
let filename = self.filename(pkgname, name);
546589
let digest = match self.digests.remove(&filename) {
547590
Some(digest) => digest,
591+
// This component does not exist for this target -- skip it.
548592
None => return (name.to_string(), Target::unavailable()),
549593
};
550594
let xz_filename = filename.replace(".tar.gz", ".tar.xz");

0 commit comments

Comments
 (0)