Skip to content

Commit 07f65da

Browse files
committed
Auto merge of rust-lang#77145 - pietroalbini:refactor-build-manifest-versions, r=<try>
Refactor versions detection in build-manifest This PR refactors how `build-manifest` handles versions, making the following changes: * `build-manifest` now detects the "package releases" on its own, without relying on rustbuild providing them through CLI arguments. This drastically simplifies calling the tool outside of `x.py`, and will allow to ship the prebuilt tool in a tarball in the future, with the goal of stopping to invoke `x.py` during `promote-release`. * The `tar` command is not used to extract the version and the git hash from tarballs anymore. The `flate2` and `tar` crates are used instead. This makes detecting those pieces of data way faster, as the archive is decompressed just once and we stop parsing the archive once all the information is retrieved. * The code to extract the version and the git hash now stores all the collected data dynamically, without requiring to add new fields to the `Builder` struct every time. I tested the changes locally and it should behave the same as before. r? `@Mark-Simulacrum`
2 parents 3a4da87 + bb8430e commit 07f65da

File tree

6 files changed

+289
-217
lines changed

6 files changed

+289
-217
lines changed

Cargo.lock

+3
Original file line numberDiff line numberDiff line change
@@ -231,8 +231,11 @@ dependencies = [
231231
name = "build-manifest"
232232
version = "0.1.0"
233233
dependencies = [
234+
"anyhow",
235+
"flate2",
234236
"serde",
235237
"serde_json",
238+
"tar",
236239
"toml",
237240
]
238241

src/bootstrap/dist.rs

+2-8
Original file line numberDiff line numberDiff line change
@@ -2368,15 +2368,9 @@ impl Step for HashSign {
23682368
cmd.arg(sign);
23692369
cmd.arg(distdir(builder));
23702370
cmd.arg(today.trim());
2371-
cmd.arg(builder.rust_package_vers());
23722371
cmd.arg(addr);
2373-
cmd.arg(builder.package_vers(&builder.release_num("cargo")));
2374-
cmd.arg(builder.package_vers(&builder.release_num("rls")));
2375-
cmd.arg(builder.package_vers(&builder.release_num("rust-analyzer/crates/rust-analyzer")));
2376-
cmd.arg(builder.package_vers(&builder.release_num("clippy")));
2377-
cmd.arg(builder.package_vers(&builder.release_num("miri")));
2378-
cmd.arg(builder.package_vers(&builder.release_num("rustfmt")));
2379-
cmd.arg(builder.llvm_tools_package_vers());
2372+
cmd.arg(&builder.config.channel);
2373+
cmd.arg(&builder.src);
23802374

23812375
builder.create_dir(&distdir(builder));
23822376

src/tools/build-manifest/Cargo.toml

+3
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,6 @@ edition = "2018"
88
toml = "0.5"
99
serde = { version = "1.0", features = ["derive"] }
1010
serde_json = "1.0"
11+
anyhow = "1.0.32"
12+
flate2 = "1.0.16"
13+
tar = "0.4.29"

src/tools/build-manifest/README.md

+4-5
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,9 @@ Then, you can generate the manifest and all the packages from `path/to/dist` to
2121

2222
```
2323
$ BUILD_MANIFEST_DISABLE_SIGNING=1 cargo +nightly run \
24-
path/to/dist path/to/output 1970-01-01 \
25-
nightly nightly nightly nightly nightly nightly nightly nightly \
26-
http://example.com
24+
path/to/dist path/to/output 1970-01-01 http://example.com \
25+
CHANNEL path/to/rust/repo
2726
```
2827

29-
In the future, if the tool complains about missing arguments just add more
30-
`nightly`s in the middle.
28+
Remember to replace `CHANNEL` with the channel you produced dist artifacts of
29+
and `path/to/rust/repo` with the path to your checkout of the Rust repository.

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

+29-204
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,10 @@
44
//! via `x.py dist hash-and-sign`; the cmdline arguments are set up
55
//! by rustbuild (in `src/bootstrap/dist.rs`).
66
7-
use serde::Serialize;
7+
mod versions;
88

9+
use crate::versions::{PkgType, Versions};
10+
use serde::Serialize;
911
use std::collections::BTreeMap;
1012
use std::collections::HashMap;
1113
use std::env;
@@ -226,14 +228,7 @@ macro_rules! t {
226228
}
227229

228230
struct Builder {
229-
rust_release: String,
230-
cargo_release: String,
231-
rls_release: String,
232-
rust_analyzer_release: String,
233-
clippy_release: String,
234-
rustfmt_release: String,
235-
llvm_tools_release: String,
236-
miri_release: String,
231+
versions: Versions,
237232

238233
input: PathBuf,
239234
output: PathBuf,
@@ -242,24 +237,6 @@ struct Builder {
242237
s3_address: String,
243238
date: String,
244239

245-
rust_version: Option<String>,
246-
cargo_version: Option<String>,
247-
rls_version: Option<String>,
248-
rust_analyzer_version: Option<String>,
249-
clippy_version: Option<String>,
250-
rustfmt_version: Option<String>,
251-
llvm_tools_version: Option<String>,
252-
miri_version: Option<String>,
253-
254-
rust_git_commit_hash: Option<String>,
255-
cargo_git_commit_hash: Option<String>,
256-
rls_git_commit_hash: Option<String>,
257-
rust_analyzer_git_commit_hash: Option<String>,
258-
clippy_git_commit_hash: Option<String>,
259-
rustfmt_git_commit_hash: Option<String>,
260-
llvm_tools_git_commit_hash: Option<String>,
261-
miri_git_commit_hash: Option<String>,
262-
263240
should_sign: bool,
264241
}
265242

@@ -280,15 +257,9 @@ fn main() {
280257
let input = PathBuf::from(args.next().unwrap());
281258
let output = PathBuf::from(args.next().unwrap());
282259
let date = args.next().unwrap();
283-
let rust_release = args.next().unwrap();
284260
let s3_address = args.next().unwrap();
285-
let cargo_release = args.next().unwrap();
286-
let rls_release = args.next().unwrap();
287-
let rust_analyzer_release = args.next().unwrap();
288-
let clippy_release = args.next().unwrap();
289-
let miri_release = args.next().unwrap();
290-
let rustfmt_release = args.next().unwrap();
291-
let llvm_tools_release = args.next().unwrap();
261+
let channel = args.next().unwrap();
262+
let monorepo_path = args.next().unwrap();
292263

293264
// Do not ask for a passphrase while manually testing
294265
let mut passphrase = String::new();
@@ -298,14 +269,7 @@ fn main() {
298269
}
299270

300271
Builder {
301-
rust_release,
302-
cargo_release,
303-
rls_release,
304-
rust_analyzer_release,
305-
clippy_release,
306-
rustfmt_release,
307-
llvm_tools_release,
308-
miri_release,
272+
versions: Versions::new(&channel, &input, Path::new(&monorepo_path)).unwrap(),
309273

310274
input,
311275
output,
@@ -314,87 +278,21 @@ fn main() {
314278
s3_address,
315279
date,
316280

317-
rust_version: None,
318-
cargo_version: None,
319-
rls_version: None,
320-
rust_analyzer_version: None,
321-
clippy_version: None,
322-
rustfmt_version: None,
323-
llvm_tools_version: None,
324-
miri_version: None,
325-
326-
rust_git_commit_hash: None,
327-
cargo_git_commit_hash: None,
328-
rls_git_commit_hash: None,
329-
rust_analyzer_git_commit_hash: None,
330-
clippy_git_commit_hash: None,
331-
rustfmt_git_commit_hash: None,
332-
llvm_tools_git_commit_hash: None,
333-
miri_git_commit_hash: None,
334-
335281
should_sign,
336282
}
337283
.build();
338284
}
339285

340-
enum PkgType {
341-
RustSrc,
342-
Cargo,
343-
Rls,
344-
RustAnalyzer,
345-
Clippy,
346-
Rustfmt,
347-
LlvmTools,
348-
Miri,
349-
Other,
350-
}
351-
352-
impl PkgType {
353-
fn from_component(component: &str) -> Self {
354-
use PkgType::*;
355-
match component {
356-
"rust-src" => RustSrc,
357-
"cargo" => Cargo,
358-
"rls" | "rls-preview" => Rls,
359-
"rust-analyzer" | "rust-analyzer-preview" => RustAnalyzer,
360-
"clippy" | "clippy-preview" => Clippy,
361-
"rustfmt" | "rustfmt-preview" => Rustfmt,
362-
"llvm-tools" | "llvm-tools-preview" => LlvmTools,
363-
"miri" | "miri-preview" => Miri,
364-
_ => Other,
365-
}
366-
}
367-
}
368-
369286
impl Builder {
370287
fn build(&mut self) {
371-
self.rust_version = self.version("rust", "x86_64-unknown-linux-gnu");
372-
self.cargo_version = self.version("cargo", "x86_64-unknown-linux-gnu");
373-
self.rls_version = self.version("rls", "x86_64-unknown-linux-gnu");
374-
self.rust_analyzer_version = self.version("rust-analyzer", "x86_64-unknown-linux-gnu");
375-
self.clippy_version = self.version("clippy", "x86_64-unknown-linux-gnu");
376-
self.rustfmt_version = self.version("rustfmt", "x86_64-unknown-linux-gnu");
377-
self.llvm_tools_version = self.version("llvm-tools", "x86_64-unknown-linux-gnu");
378-
self.miri_version = self.version("miri", "x86_64-unknown-linux-gnu");
379-
380-
self.rust_git_commit_hash = self.git_commit_hash("rust", "x86_64-unknown-linux-gnu");
381-
self.cargo_git_commit_hash = self.git_commit_hash("cargo", "x86_64-unknown-linux-gnu");
382-
self.rls_git_commit_hash = self.git_commit_hash("rls", "x86_64-unknown-linux-gnu");
383-
self.rust_analyzer_git_commit_hash =
384-
self.git_commit_hash("rust-analyzer", "x86_64-unknown-linux-gnu");
385-
self.clippy_git_commit_hash = self.git_commit_hash("clippy", "x86_64-unknown-linux-gnu");
386-
self.rustfmt_git_commit_hash = self.git_commit_hash("rustfmt", "x86_64-unknown-linux-gnu");
387-
self.llvm_tools_git_commit_hash =
388-
self.git_commit_hash("llvm-tools", "x86_64-unknown-linux-gnu");
389-
self.miri_git_commit_hash = self.git_commit_hash("miri", "x86_64-unknown-linux-gnu");
390-
391288
self.check_toolstate();
392289
self.digest_and_sign();
393290
let manifest = self.build_manifest();
394-
self.write_channel_files(&self.rust_release, &manifest);
395291

396-
if self.rust_release != "beta" && self.rust_release != "nightly" {
397-
self.write_channel_files("stable", &manifest);
292+
let rust_version = self.versions.package_version(&PkgType::Rust).unwrap();
293+
self.write_channel_files(self.versions.channel(), &manifest);
294+
if self.versions.channel() != rust_version {
295+
self.write_channel_files(&rust_version, &manifest);
398296
}
399297
}
400298

@@ -415,8 +313,7 @@ impl Builder {
415313
// Mark some tools as missing based on toolstate.
416314
if toolstates.get("miri").map(|s| &*s as &str) != Some("test-pass") {
417315
println!("Miri tests are not passing, removing component");
418-
self.miri_version = None;
419-
self.miri_git_commit_hash = None;
316+
self.versions.disable_version(&PkgType::Miri);
420317
}
421318
}
422319

@@ -501,7 +398,7 @@ impl Builder {
501398
// The compiler libraries are not stable for end users, and they're also huge, so we only
502399
// `rustc-dev` for nightly users, and only in the "complete" profile. It's still possible
503400
// for users to install the additional component manually, if needed.
504-
if self.rust_release == "nightly" {
401+
if self.versions.channel() == "nightly" {
505402
self.extend_profile("complete", &mut manifest.profiles, &["rustc-dev"]);
506403
self.extend_profile("complete", &mut manifest.profiles, &["rustc-docs"]);
507404
}
@@ -518,13 +415,10 @@ impl Builder {
518415
}
519416

520417
fn rust_package(&mut self, manifest: &Manifest) -> Package {
418+
let version_info = self.versions.version(&PkgType::Rust).expect("missing Rust tarball");
521419
let mut pkg = Package {
522-
version: self
523-
.cached_version("rust")
524-
.as_ref()
525-
.expect("Couldn't find Rust version")
526-
.clone(),
527-
git_commit_hash: self.cached_git_commit_hash("rust").clone(),
420+
version: version_info.version.expect("missing Rust version"),
421+
git_commit_hash: version_info.git_commit,
528422
target: BTreeMap::new(),
529423
};
530424
for host in HOSTS {
@@ -539,7 +433,7 @@ impl Builder {
539433
}
540434

541435
fn target_host_combination(&mut self, host: &str, manifest: &Manifest) -> Option<Target> {
542-
let filename = self.filename("rust", host);
436+
let filename = self.versions.tarball_name(&PkgType::Rust, host).unwrap();
543437
let digest = self.digests.remove(&filename)?;
544438
let xz_filename = filename.replace(".tar.gz", ".tar.xz");
545439
let xz_digest = self.digests.remove(&xz_filename);
@@ -630,15 +524,14 @@ impl Builder {
630524
}
631525

632526
fn package(&mut self, pkgname: &str, dst: &mut BTreeMap<String, Package>, targets: &[&str]) {
633-
let (version, mut is_present) = self
634-
.cached_version(pkgname)
635-
.as_ref()
636-
.cloned()
637-
.map(|version| (version, true))
638-
.unwrap_or_default(); // `is_present` defaults to `false` here.
527+
let version_info = self
528+
.versions
529+
.version(&PkgType::from_component(pkgname))
530+
.expect("failed to load package version");
531+
let mut is_present = version_info.present;
639532

640533
// Never ship nightly-only components for other trains.
641-
if self.rust_release != "nightly" && NIGHTLY_ONLY_COMPONENTS.contains(&pkgname) {
534+
if self.versions.channel() != "nightly" && NIGHTLY_ONLY_COMPONENTS.contains(&pkgname) {
642535
is_present = false; // Pretend the component is entirely missing.
643536
}
644537

@@ -647,7 +540,10 @@ impl Builder {
647540
.map(|name| {
648541
if is_present {
649542
// The component generally exists, but it might still be missing for this target.
650-
let filename = self.filename(pkgname, name);
543+
let filename = self
544+
.versions
545+
.tarball_name(&PkgType::from_component(pkgname), name)
546+
.unwrap();
651547
let digest = match self.digests.remove(&filename) {
652548
Some(digest) => digest,
653549
// This component does not exist for this target -- skip it.
@@ -679,8 +575,8 @@ impl Builder {
679575
dst.insert(
680576
pkgname.to_string(),
681577
Package {
682-
version,
683-
git_commit_hash: self.cached_git_commit_hash(pkgname).clone(),
578+
version: version_info.version.unwrap_or_default(),
579+
git_commit_hash: version_info.git_commit,
684580
target: targets,
685581
},
686582
);
@@ -690,77 +586,6 @@ impl Builder {
690586
format!("{}/{}/{}", self.s3_address, self.date, filename)
691587
}
692588

693-
fn filename(&self, component: &str, target: &str) -> String {
694-
use PkgType::*;
695-
match PkgType::from_component(component) {
696-
RustSrc => format!("rust-src-{}.tar.gz", self.rust_release),
697-
Cargo => format!("cargo-{}-{}.tar.gz", self.cargo_release, target),
698-
Rls => format!("rls-{}-{}.tar.gz", self.rls_release, target),
699-
RustAnalyzer => {
700-
format!("rust-analyzer-{}-{}.tar.gz", self.rust_analyzer_release, target)
701-
}
702-
Clippy => format!("clippy-{}-{}.tar.gz", self.clippy_release, target),
703-
Rustfmt => format!("rustfmt-{}-{}.tar.gz", self.rustfmt_release, target),
704-
LlvmTools => format!("llvm-tools-{}-{}.tar.gz", self.llvm_tools_release, target),
705-
Miri => format!("miri-{}-{}.tar.gz", self.miri_release, target),
706-
Other => format!("{}-{}-{}.tar.gz", component, self.rust_release, target),
707-
}
708-
}
709-
710-
fn cached_version(&self, component: &str) -> &Option<String> {
711-
use PkgType::*;
712-
match PkgType::from_component(component) {
713-
Cargo => &self.cargo_version,
714-
Rls => &self.rls_version,
715-
RustAnalyzer => &self.rust_analyzer_version,
716-
Clippy => &self.clippy_version,
717-
Rustfmt => &self.rustfmt_version,
718-
LlvmTools => &self.llvm_tools_version,
719-
Miri => &self.miri_version,
720-
_ => &self.rust_version,
721-
}
722-
}
723-
724-
fn cached_git_commit_hash(&self, component: &str) -> &Option<String> {
725-
use PkgType::*;
726-
match PkgType::from_component(component) {
727-
Cargo => &self.cargo_git_commit_hash,
728-
Rls => &self.rls_git_commit_hash,
729-
RustAnalyzer => &self.rust_analyzer_git_commit_hash,
730-
Clippy => &self.clippy_git_commit_hash,
731-
Rustfmt => &self.rustfmt_git_commit_hash,
732-
LlvmTools => &self.llvm_tools_git_commit_hash,
733-
Miri => &self.miri_git_commit_hash,
734-
_ => &self.rust_git_commit_hash,
735-
}
736-
}
737-
738-
fn version(&self, component: &str, target: &str) -> Option<String> {
739-
self.untar(component, target, |filename| format!("{}/version", filename))
740-
}
741-
742-
fn git_commit_hash(&self, component: &str, target: &str) -> Option<String> {
743-
self.untar(component, target, |filename| format!("{}/git-commit-hash", filename))
744-
}
745-
746-
fn untar<F>(&self, component: &str, target: &str, dir: F) -> Option<String>
747-
where
748-
F: FnOnce(String) -> String,
749-
{
750-
let mut cmd = Command::new("tar");
751-
let filename = self.filename(component, target);
752-
cmd.arg("xf")
753-
.arg(self.input.join(&filename))
754-
.arg(dir(filename.replace(".tar.gz", "")))
755-
.arg("-O");
756-
let output = t!(cmd.output());
757-
if output.status.success() {
758-
Some(String::from_utf8_lossy(&output.stdout).trim().to_string())
759-
} else {
760-
None
761-
}
762-
}
763-
764589
fn hash(&self, path: &Path) -> String {
765590
let sha = t!(Command::new("shasum")
766591
.arg("-a")

0 commit comments

Comments
 (0)