use std::collections::HashMap;
use std::convert::TryInto;
-const DIST_SERVER: &str = "https://static.rust-lang.org";
+const PATH: &str = "src/stage0.json";
const COMPILER_COMPONENTS: &[&str] = &["rustc", "rust-std", "cargo"];
const RUSTFMT_COMPONENTS: &[&str] = &["rustfmt-preview"];
struct Tool {
+ config: Config,
+ comments: Vec<String>,
+
channel: Channel,
version: [u16; 3],
checksums: IndexMap<String, String>,
.try_into()
.map_err(|_| anyhow::anyhow!("failed to parse version"))?;
- Ok(Self { channel, version, checksums: IndexMap::new() })
+ let existing: Stage0 = serde_json::from_slice(&std::fs::read(PATH)?)?;
+
+ Ok(Self {
+ channel,
+ version,
+ config: existing.config,
+ comments: existing.comments,
+ checksums: IndexMap::new(),
+ })
}
fn update_json(mut self) -> Result<(), Error> {
std::fs::write(
- "src/stage0.json",
+ PATH,
format!(
"{}\n",
serde_json::to_string_pretty(&Stage0 {
- comment: "Generated by `./x.py run src/tools/bump-stage0`. \
- Run that command again to update the bootstrap compiler.",
- dist_server: DIST_SERVER.into(),
compiler: self.detect_compiler()?,
rustfmt: self.detect_rustfmt()?,
checksums_sha256: {
// are added while filling the other struct fields just above this block.
self.checksums.sort_keys();
self.checksums
- }
+ },
+ config: self.config,
+ comments: self.comments,
})?
),
)?;
Channel::Nightly => "beta".to_string(),
};
- let manifest = fetch_manifest(&channel)?;
+ let manifest = fetch_manifest(&self.config, &channel)?;
self.collect_checksums(&manifest, COMPILER_COMPONENTS)?;
Ok(Stage0Toolchain {
date: manifest.date,
return Ok(None);
}
- let manifest = fetch_manifest("nightly")?;
+ let manifest = fetch_manifest(&self.config, "nightly")?;
self.collect_checksums(&manifest, RUSTFMT_COMPONENTS)?;
Ok(Some(Stage0Toolchain { date: manifest.date, version: "nightly".into() }))
}
fn collect_checksums(&mut self, manifest: &Manifest, components: &[&str]) -> Result<(), Error> {
- let prefix = format!("{}/", DIST_SERVER);
+ let prefix = format!("{}/", self.config.dist_server);
for component in components {
let pkg = manifest
.pkg
Ok(())
}
-fn fetch_manifest(channel: &str) -> Result<Manifest, Error> {
+fn fetch_manifest(config: &Config, channel: &str) -> Result<Manifest, Error> {
Ok(toml::from_slice(&http_get(&format!(
"{}/dist/channel-rust-{}.toml",
- DIST_SERVER, channel
+ config.dist_server, channel
))?)?)
}
Nightly,
}
-#[derive(Debug, serde::Serialize)]
+#[derive(Debug, serde::Serialize, serde::Deserialize)]
struct Stage0 {
- #[serde(rename = "__comment")]
- comment: &'static str,
- dist_server: String,
+ config: Config,
+ // Comments are explicitly below the config, do not move them above.
+ //
+ // Downstream forks of the compiler codebase can change the configuration values defined above,
+ // but doing so would risk merge conflicts whenever they import new changes that include a
+ // bootstrap compiler bump.
+ //
+ // To lessen the pain, a big block of comments is placed between the configuration and the
+ // auto-generated parts of the file, preventing git diffs of the config to include parts of the
+ // auto-egenrated content and vice versa. This should prevent merge conflicts.
+ #[serde(rename = "__comments")]
+ comments: Vec<String>,
compiler: Stage0Toolchain,
rustfmt: Option<Stage0Toolchain>,
checksums_sha256: IndexMap<String, String>,
}
-#[derive(Debug, serde::Serialize)]
+#[derive(Debug, serde::Serialize, serde::Deserialize)]
+struct Config {
+ dist_server: String,
+ artifacts_server: String,
+ artifacts_with_llvm_assertions_server: String,
+ git_merge_commit_email: String,
+}
+
+#[derive(Debug, serde::Serialize, serde::Deserialize)]
struct Stage0Toolchain {
date: String,
version: String,
}
-#[derive(Debug, serde::Deserialize)]
+#[derive(Debug, serde::Serialize, serde::Deserialize)]
struct Manifest {
date: String,
pkg: HashMap<String, ManifestPackage>,
}
-#[derive(Debug, serde::Deserialize)]
+#[derive(Debug, serde::Serialize, serde::Deserialize)]
struct ManifestPackage {
version: String,
target: HashMap<String, ManifestTargetPackage>,
}
-#[derive(Debug, serde::Deserialize)]
+#[derive(Debug, serde::Serialize, serde::Deserialize)]
struct ManifestTargetPackage {
url: Option<String>,
hash: Option<String>,