Skip to content

Commit 80b81ad

Browse files
committed
switch stage0.txt to stage0.json and add a tool to generate it
1 parent 33fdb79 commit 80b81ad

13 files changed

+263
-117
lines changed

Cargo.lock

+11
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,17 @@ dependencies = [
220220
name = "build_helper"
221221
version = "0.1.0"
222222

223+
[[package]]
224+
name = "bump-stage0"
225+
version = "0.1.0"
226+
dependencies = [
227+
"anyhow",
228+
"curl",
229+
"serde",
230+
"serde_json",
231+
"toml",
232+
]
233+
223234
[[package]]
224235
name = "byte-tools"
225236
version = "0.3.1"

Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ members = [
3535
"src/tools/expand-yaml-anchors",
3636
"src/tools/jsondocck",
3737
"src/tools/html-checker",
38+
"src/tools/bump-stage0",
3839
]
3940

4041
exclude = [

src/bootstrap/bootstrap.py

+34-42
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import datetime
55
import distutils.version
66
import hashlib
7+
import json
78
import os
89
import re
910
import shutil
@@ -176,15 +177,6 @@ def require(cmd, exit=True):
176177
sys.exit(1)
177178

178179

179-
def stage0_data(rust_root):
180-
"""Build a dictionary from stage0.txt"""
181-
nightlies = os.path.join(rust_root, "src/stage0.txt")
182-
with open(nightlies, 'r') as nightlies:
183-
lines = [line.rstrip() for line in nightlies
184-
if not line.startswith("#")]
185-
return dict([line.split(": ", 1) for line in lines if line])
186-
187-
188180
def format_build_time(duration):
189181
"""Return a nicer format for build time
190182
@@ -371,13 +363,21 @@ def output(filepath):
371363
os.rename(tmp, filepath)
372364

373365

366+
class Stage0Toolchain:
367+
def __init__(self, stage0_payload):
368+
self.date = stage0_payload["date"]
369+
self.version = stage0_payload["version"]
370+
371+
def channel(self):
372+
return self.version + "-" + self.date
373+
374+
374375
class RustBuild(object):
375376
"""Provide all the methods required to build Rust"""
376377
def __init__(self):
377-
self.date = ''
378+
self.stage0_compiler = None
379+
self.stage0_rustfmt = None
378380
self._download_url = ''
379-
self.rustc_channel = ''
380-
self.rustfmt_channel = ''
381381
self.build = ''
382382
self.build_dir = ''
383383
self.clean = False
@@ -401,11 +401,10 @@ def download_toolchain(self, stage0=True, rustc_channel=None):
401401
will move all the content to the right place.
402402
"""
403403
if rustc_channel is None:
404-
rustc_channel = self.rustc_channel
405-
rustfmt_channel = self.rustfmt_channel
404+
rustc_channel = self.stage0_compiler.version
406405
bin_root = self.bin_root(stage0)
407406

408-
key = self.date
407+
key = self.stage0_compiler.date
409408
if not stage0:
410409
key += str(self.rustc_commit)
411410
if self.rustc(stage0).startswith(bin_root) and \
@@ -444,19 +443,23 @@ def download_toolchain(self, stage0=True, rustc_channel=None):
444443

445444
if self.rustfmt() and self.rustfmt().startswith(bin_root) and (
446445
not os.path.exists(self.rustfmt())
447-
or self.program_out_of_date(self.rustfmt_stamp(), self.rustfmt_channel)
446+
or self.program_out_of_date(
447+
self.rustfmt_stamp(),
448+
"" if self.stage0_rustfmt is None else self.stage0_rustfmt.channel()
449+
)
448450
):
449-
if rustfmt_channel:
451+
if self.stage0_rustfmt is not None:
450452
tarball_suffix = '.tar.xz' if support_xz() else '.tar.gz'
451-
[channel, date] = rustfmt_channel.split('-', 1)
452-
filename = "rustfmt-{}-{}{}".format(channel, self.build, tarball_suffix)
453+
filename = "rustfmt-{}-{}{}".format(
454+
self.stage0_rustfmt.version, self.build, tarball_suffix,
455+
)
453456
self._download_component_helper(
454-
filename, "rustfmt-preview", tarball_suffix, key=date
457+
filename, "rustfmt-preview", tarball_suffix, key=self.stage0_rustfmt.date
455458
)
456459
self.fix_bin_or_dylib("{}/bin/rustfmt".format(bin_root))
457460
self.fix_bin_or_dylib("{}/bin/cargo-fmt".format(bin_root))
458461
with output(self.rustfmt_stamp()) as rustfmt_stamp:
459-
rustfmt_stamp.write(self.rustfmt_channel)
462+
rustfmt_stamp.write(self.stage0_rustfmt.channel())
460463

461464
# Avoid downloading LLVM twice (once for stage0 and once for the master rustc)
462465
if self.downloading_llvm() and stage0:
@@ -517,7 +520,7 @@ def _download_component_helper(
517520
):
518521
if key is None:
519522
if stage0:
520-
key = self.date
523+
key = self.stage0_compiler.date
521524
else:
522525
key = self.rustc_commit
523526
cache_dst = os.path.join(self.build_dir, "cache")
@@ -815,7 +818,7 @@ def rustc(self, stage0):
815818

816819
def rustfmt(self):
817820
"""Return config path for rustfmt"""
818-
if not self.rustfmt_channel:
821+
if self.stage0_rustfmt is None:
819822
return None
820823
return self.program_config('rustfmt')
821824

@@ -1039,19 +1042,12 @@ def update_submodules(self):
10391042
self.update_submodule(module[0], module[1], recorded_submodules)
10401043
print("Submodules updated in %.2f seconds" % (time() - start_time))
10411044

1042-
def set_normal_environment(self):
1045+
def set_dist_environment(self, url):
10431046
"""Set download URL for normal environment"""
10441047
if 'RUSTUP_DIST_SERVER' in os.environ:
10451048
self._download_url = os.environ['RUSTUP_DIST_SERVER']
10461049
else:
1047-
self._download_url = 'https://static.rust-lang.org'
1048-
1049-
def set_dev_environment(self):
1050-
"""Set download URL for development environment"""
1051-
if 'RUSTUP_DEV_DIST_SERVER' in os.environ:
1052-
self._download_url = os.environ['RUSTUP_DEV_DIST_SERVER']
1053-
else:
1054-
self._download_url = 'https://dev-static.rust-lang.org'
1050+
self._download_url = url
10551051

10561052
def check_vendored_status(self):
10571053
"""Check that vendoring is configured properly"""
@@ -1160,17 +1156,13 @@ def bootstrap(help_triggered):
11601156
build_dir = build.get_toml('build-dir', 'build') or 'build'
11611157
build.build_dir = os.path.abspath(build_dir.replace("$ROOT", build.rust_root))
11621158

1163-
data = stage0_data(build.rust_root)
1164-
build.date = data['date']
1165-
build.rustc_channel = data['rustc']
1159+
with open(os.path.join(build.rust_root, "src", "stage0.json")) as f:
1160+
data = json.load(f)
1161+
build.stage0_compiler = Stage0Toolchain(data["compiler"])
1162+
if data.get("rustfmt") is not None:
1163+
build.stage0_rustfmt = Stage0Toolchain(data["rustfmt"])
11661164

1167-
if "rustfmt" in data:
1168-
build.rustfmt_channel = data['rustfmt']
1169-
1170-
if 'dev' in data:
1171-
build.set_dev_environment()
1172-
else:
1173-
build.set_normal_environment()
1165+
build.set_dist_environment(data["dist_server"])
11741166

11751167
build.build = args.build or build.build_triple()
11761168
build.update_submodules()

src/bootstrap/bootstrap_test.py

-20
Original file line numberDiff line numberDiff line change
@@ -13,25 +13,6 @@
1313
import bootstrap
1414

1515

16-
class Stage0DataTestCase(unittest.TestCase):
17-
"""Test Case for stage0_data"""
18-
def setUp(self):
19-
self.rust_root = tempfile.mkdtemp()
20-
os.mkdir(os.path.join(self.rust_root, "src"))
21-
with open(os.path.join(self.rust_root, "src",
22-
"stage0.txt"), "w") as stage0:
23-
stage0.write("#ignore\n\ndate: 2017-06-15\nrustc: beta\ncargo: beta\nrustfmt: beta")
24-
25-
def tearDown(self):
26-
rmtree(self.rust_root)
27-
28-
def test_stage0_data(self):
29-
"""Extract data from stage0.txt"""
30-
expected = {"date": "2017-06-15", "rustc": "beta", "cargo": "beta", "rustfmt": "beta"}
31-
data = bootstrap.stage0_data(self.rust_root)
32-
self.assertDictEqual(data, expected)
33-
34-
3516
class VerifyTestCase(unittest.TestCase):
3617
"""Test Case for verify"""
3718
def setUp(self):
@@ -99,7 +80,6 @@ def test_same_dates(self):
9980
TEST_LOADER = unittest.TestLoader()
10081
SUITE.addTest(doctest.DocTestSuite(bootstrap))
10182
SUITE.addTests([
102-
TEST_LOADER.loadTestsFromTestCase(Stage0DataTestCase),
10383
TEST_LOADER.loadTestsFromTestCase(VerifyTestCase),
10484
TEST_LOADER.loadTestsFromTestCase(ProgramOutOfDate)])
10585

src/bootstrap/builder.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -523,7 +523,7 @@ impl<'a> Builder<'a> {
523523
install::Src,
524524
install::Rustc
525525
),
526-
Kind::Run => describe!(run::ExpandYamlAnchors, run::BuildManifest),
526+
Kind::Run => describe!(run::ExpandYamlAnchors, run::BuildManifest, run::BumpStage0),
527527
}
528528
}
529529

src/bootstrap/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131
//! When you execute `x.py build`, the steps executed are:
3232
//!
3333
//! * First, the python script is run. This will automatically download the
34-
//! stage0 rustc and cargo according to `src/stage0.txt`, or use the cached
34+
//! stage0 rustc and cargo according to `src/stage0.json`, or use the cached
3535
//! versions if they're available. These are then used to compile rustbuild
3636
//! itself (using Cargo). Finally, control is then transferred to rustbuild.
3737
//!

src/bootstrap/run.rs

+21
Original file line numberDiff line numberDiff line change
@@ -82,3 +82,24 @@ impl Step for BuildManifest {
8282
builder.run(&mut cmd);
8383
}
8484
}
85+
86+
#[derive(Debug, PartialOrd, Ord, Copy, Clone, Hash, PartialEq, Eq)]
87+
pub struct BumpStage0;
88+
89+
impl Step for BumpStage0 {
90+
type Output = ();
91+
const ONLY_HOSTS: bool = true;
92+
93+
fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
94+
run.path("src/tools/bump-stage0")
95+
}
96+
97+
fn make_run(run: RunConfig<'_>) {
98+
run.builder.ensure(BumpStage0);
99+
}
100+
101+
fn run(self, builder: &Builder<'_>) -> Self::Output {
102+
let mut cmd = builder.tool_cmd(Tool::BumpStage0);
103+
builder.run(&mut cmd);
104+
}
105+
}

src/bootstrap/sanity.rs

+1-11
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ use std::fs;
1515
use std::path::PathBuf;
1616
use std::process::Command;
1717

18-
use build_helper::{output, t};
18+
use build_helper::output;
1919

2020
use crate::cache::INTERNER;
2121
use crate::config::Target;
@@ -227,14 +227,4 @@ $ pacman -R cmake && pacman -S mingw-w64-x86_64-cmake
227227
if let Some(ref s) = build.config.ccache {
228228
cmd_finder.must_have(s);
229229
}
230-
231-
if build.config.channel == "stable" {
232-
let stage0 = t!(fs::read_to_string(build.src.join("src/stage0.txt")));
233-
if stage0.contains("\ndev:") {
234-
panic!(
235-
"bootstrapping from a dev compiler in a stable release, but \
236-
should only be bootstrapping from a released compiler!"
237-
);
238-
}
239-
}
240230
}

src/bootstrap/tool.rs

+1
Original file line numberDiff line numberDiff line change
@@ -377,6 +377,7 @@ bootstrap_tool!(
377377
LintDocs, "src/tools/lint-docs", "lint-docs";
378378
JsonDocCk, "src/tools/jsondocck", "jsondocck";
379379
HtmlChecker, "src/tools/html-checker", "html-checker";
380+
BumpStage0, "src/tools/bump-stage0", "bump-stage0";
380381
);
381382

382383
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq, Ord, PartialOrd)]

src/stage0.json

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
{
2+
"__comment": "Generated by `./x.py run src/tools/bump-stage0`. Run that command again to update the bootstrap compiler.",
3+
"dist_server": "https://static.rust-lang.org",
4+
"compiler": {
5+
"date": "2021-08-22",
6+
"version": "beta"
7+
},
8+
"rustfmt": {
9+
"date": "2021-08-26",
10+
"version": "nightly"
11+
}
12+
}

src/stage0.txt

-42
This file was deleted.

src/tools/bump-stage0/Cargo.toml

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
[package]
2+
name = "bump-stage0"
3+
version = "0.1.0"
4+
edition = "2018"
5+
6+
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
7+
8+
[dependencies]
9+
anyhow = "1.0.34"
10+
curl = "0.4.38"
11+
serde = { version = "1.0.125", features = ["derive"] }
12+
serde_json = "1.0.59"
13+
toml = "0.5.7"

0 commit comments

Comments
 (0)