diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs index 05d59e7d59565..609802c4767e5 100644 --- a/src/bootstrap/dist.rs +++ b/src/bootstrap/dist.rs @@ -365,6 +365,9 @@ impl Step for Rustc { // tiny morsel of metadata is used by rust-packaging let version = build.rust_version(); t!(t!(File::create(overlay.join("version"))).write_all(version.as_bytes())); + if let Some(sha) = build.rust_sha() { + t!(t!(File::create(overlay.join("git-commit-hash"))).write_all(sha.as_bytes())); + } // On MinGW we've got a few runtime DLL dependencies that we need to // include. The first argument to this script is where to put these DLLs @@ -844,6 +847,9 @@ impl Step for PlainSourceTarball { // Create the version file write_file(&plain_dst_src.join("version"), build.rust_version().as_bytes()); + if let Some(sha) = build.rust_sha() { + write_file(&plain_dst_src.join("git-commit-hash"), sha.as_bytes()); + } // If we're building from git sources, we need to vendor a complete distribution. if build.rust_info.is_git() { @@ -1157,6 +1163,9 @@ impl Step for Extended { install(&build.src.join("LICENSE-MIT"), &overlay, 0o644); let version = build.rust_version(); t!(t!(File::create(overlay.join("version"))).write_all(version.as_bytes())); + if let Some(sha) = build.rust_sha() { + t!(t!(File::create(overlay.join("git-commit-hash"))).write_all(sha.as_bytes())); + } install(&etc.join("README.md"), &overlay, 0o644); // When rust-std package split from rustc, we needed to ensure that during diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs index f21b382619d0a..67791e8758c0b 100644 --- a/src/bootstrap/lib.rs +++ b/src/bootstrap/lib.rs @@ -797,6 +797,11 @@ impl Build { self.rust_info.version(self, channel::CFG_RELEASE_NUM) } + /// Return the full commit hash + fn rust_sha(&self) -> Option<&str> { + self.rust_info.sha() + } + /// Returns the `a.b.c` version that the given package is at. fn release_num(&self, package: &str) -> String { let mut toml = String::new(); diff --git a/src/tools/build-manifest/src/main.rs b/src/tools/build-manifest/src/main.rs index e2be021e7cc39..0e91fa9c6022b 100644 --- a/src/tools/build-manifest/src/main.rs +++ b/src/tools/build-manifest/src/main.rs @@ -113,6 +113,7 @@ struct Manifest { #[derive(Serialize)] struct Package { version: String, + git_commit_hash: Option, target: BTreeMap, } @@ -167,6 +168,9 @@ struct Builder { rust_version: String, cargo_version: String, rls_version: String, + rust_git_commit_hash: Option, + cargo_git_commit_hash: Option, + rls_git_commit_hash: Option, } fn main() { @@ -194,6 +198,9 @@ fn main() { rust_version: String::new(), cargo_version: String::new(), rls_version: String::new(), + rust_git_commit_hash: None, + cargo_git_commit_hash: None, + rls_git_commit_hash: None, }.build(); } @@ -202,18 +209,16 @@ impl Builder { self.rust_version = self.version("rust", "x86_64-unknown-linux-gnu"); self.cargo_version = self.version("cargo", "x86_64-unknown-linux-gnu"); self.rls_version = self.version("rls", "x86_64-unknown-linux-gnu"); + self.rust_git_commit_hash = self.git_commit_hash("rust", "x86_64-unknown-linux-gnu"); + self.cargo_git_commit_hash = self.git_commit_hash("cargo", "x86_64-unknown-linux-gnu"); + self.rls_git_commit_hash = self.git_commit_hash("rls", "x86_64-unknown-linux-gnu"); self.digest_and_sign(); let manifest = self.build_manifest(); - let filename = format!("channel-rust-{}.toml", self.rust_release); - self.write_manifest(&toml::to_string(&manifest).unwrap(), &filename); - - let filename = format!("channel-rust-{}-date.txt", self.rust_release); - self.write_date_stamp(&manifest.date, &filename); + self.write_channel_files(&self.rust_release, &manifest); if self.rust_release != "beta" && self.rust_release != "nightly" { - self.write_manifest(&toml::to_string(&manifest).unwrap(), "channel-rust-stable.toml"); - self.write_date_stamp(&manifest.date, "channel-rust-stable-date.txt"); + self.write_channel_files("stable", &manifest); } } @@ -249,6 +254,7 @@ impl Builder { let mut pkg = Package { version: self.cached_version("rust").to_string(), + git_commit_hash: self.cached_git_commit_hash("rust").clone(), target: BTreeMap::new(), }; for host in HOSTS { @@ -342,6 +348,7 @@ impl Builder { dst.insert(pkgname.to_string(), Package { version: self.cached_version(pkgname).to_string(), + git_commit_hash: self.cached_git_commit_hash(pkgname).clone(), target: targets, }); } @@ -375,6 +382,16 @@ impl Builder { } } + fn cached_git_commit_hash(&self, component: &str) -> &Option { + if component == "cargo" { + &self.cargo_git_commit_hash + } else if component == "rls" || component == "rls-preview" { + &self.rls_git_commit_hash + } else { + &self.rust_git_commit_hash + } + } + fn version(&self, component: &str, target: &str) -> String { let mut cmd = Command::new("tar"); let filename = self.filename(component, target); @@ -382,14 +399,33 @@ impl Builder { .arg(self.input.join(&filename)) .arg(format!("{}/version", filename.replace(".tar.gz", ""))) .arg("-O"); - let version = t!(cmd.output()); - if !version.status.success() { + let output = t!(cmd.output()); + if !output.status.success() { panic!("failed to learn version:\n\n{:?}\n\n{}\n\n{}", cmd, - String::from_utf8_lossy(&version.stdout), - String::from_utf8_lossy(&version.stderr)); + String::from_utf8_lossy(&output.stdout), + String::from_utf8_lossy(&output.stderr)); + } + String::from_utf8_lossy(&output.stdout).trim().to_string() + } + + fn git_commit_hash(&self, component: &str, target: &str) -> Option { + let mut cmd = Command::new("tar"); + let filename = self.filename(component, target); + cmd.arg("xf") + .arg(self.input.join(&filename)) + .arg(format!("{}/git-commit-hash", filename.replace(".tar.gz", ""))) + .arg("-O"); + let output = t!(cmd.output()); + if output.status.success() { + Some(String::from_utf8_lossy(&output.stdout).trim().to_string()) + } else { + // This is always called after `.version()`. + // So if that didn’t fail but this does, + // that’s very probably because the tarball is valid + // but does not contain a `git-commit-hash` file. + None } - String::from_utf8_lossy(&version.stdout).trim().to_string() } fn hash(&self, path: &Path) -> String { @@ -425,16 +461,16 @@ impl Builder { assert!(t!(child.wait()).success()); } - fn write_manifest(&self, manifest: &str, name: &str) { - let dst = self.output.join(name); - t!(t!(File::create(&dst)).write_all(manifest.as_bytes())); - self.hash(&dst); - self.sign(&dst); + fn write_channel_files(&self, channel_name: &str, manifest: &Manifest) { + self.write(&toml::to_string(&manifest).unwrap(), channel_name, ".toml"); + self.write(&manifest.date, channel_name, "-date.txt"); + self.write(manifest.pkg["rust"].git_commit_hash.as_ref().unwrap(), + channel_name, "-git-commit-hash.txt"); } - fn write_date_stamp(&self, date: &str, name: &str) { - let dst = self.output.join(name); - t!(t!(File::create(&dst)).write_all(date.as_bytes())); + fn write(&self, contents: &str, channel_name: &str, suffix: &str) { + let dst = self.output.join(format!("channel-rust-{}{}", channel_name, suffix)); + t!(t!(File::create(&dst)).write_all(contents.as_bytes())); self.hash(&dst); self.sign(&dst); }