Skip to content

Commit b81ea36

Browse files
authored
Merge branch 'master' into clarify-survey-data-holder
2 parents 2549945 + e987bdf commit b81ea36

30 files changed

+666
-660
lines changed

.github/workflows/deploy.yml

+2
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ jobs:
1818
- uses: actions/checkout@v3
1919
- name: Install mdbook
2020
run: curl -sSL https://github.com/rust-lang/mdBook/releases/download/v0.4.35/mdbook-v0.4.35-x86_64-unknown-linux-gnu.tar.gz | tar -xz
21+
- name: Check blacksmith format
22+
run: cargo fmt --check --manifest-path=blacksmith/Cargo.toml
2123
- name: Build book
2224
run: ./mdbook build
2325
- name: Deploy book

blacksmith/Cargo.lock

+4-4
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

blacksmith/src/channel.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
use std::collections::BTreeMap;
21
use serde::Deserialize;
2+
use std::collections::BTreeMap;
33

44
#[derive(Deserialize)]
55
pub struct Target {
@@ -21,4 +21,3 @@ pub struct Packages {
2121
pub struct Channel {
2222
pub pkg: Packages,
2323
}
24-

blacksmith/src/lib.rs

+214-24
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ use mdbook::{
1515

1616
const CHANNELS: &[&str] = &["stable", "beta", "nightly"];
1717
const CHANNEL_URL_PREFIX: &str = "https://static.rust-lang.org/dist/channel-rust-";
18+
const MANIFESTS_URL: &str = "https://static.rust-lang.org/manifests.txt";
1819
const RUSTUP_URLS: &str =
1920
"https://raw.githubusercontent.com/rust-lang/rustup.rs/stable/ci/cloudfront-invalidation.txt";
2021

@@ -45,6 +46,8 @@ pub struct Blacksmith {
4546
rustup: Vec<String>,
4647
stable_version: Option<String>,
4748
platforms: BTreeMap<String, Platform>,
49+
#[serde(default)]
50+
previous_stable_versions: Vec<(String, Vec<String>)>,
4851
}
4952

5053
impl Blacksmith {
@@ -123,6 +126,140 @@ impl Blacksmith {
123126
}
124127
}
125128

129+
let latest_stable_version = &blacksmith.stable_version.clone().unwrap();
130+
131+
// We need to use a map to deduplicate entries and sort them in the correct order.
132+
// There are multiple entries for stable 1.8.0, 1.14.0, 1.15.1, 1.49.0 in MANIFESTS_URL.
133+
// Keys contain (minor_version, patch_version) and values contain (full_version, platforms).
134+
let mut previous_stable_version_map: BTreeMap<(u32, u32), (String, Vec<String>)> =
135+
BTreeMap::new();
136+
137+
// Go over stable versions in https://static.rust-lang.org/manifests.txt in reverse order.
138+
let manifests_content = reqwest::blocking::get(MANIFESTS_URL)?.text()?;
139+
let stable_manifest_url_regex = regex::Regex::new(
140+
r"^static\.rust-lang\.org/dist/\d{4}-\d{2}-\d{2}/channel-rust-1\.(\d+)\.(\d+)\.toml$",
141+
)
142+
.unwrap();
143+
for manifest_url in manifests_content.lines().rev() {
144+
let minor;
145+
let patch;
146+
147+
// Check if it's a stable version.
148+
if let Some(captures) = stable_manifest_url_regex.captures(&(manifest_url)) {
149+
minor = captures.get(1).unwrap().as_str().parse::<u32>().unwrap();
150+
patch = captures.get(2).unwrap().as_str().parse::<u32>().unwrap();
151+
} else {
152+
continue;
153+
}
154+
155+
let full_version = format!("1.{}.{}", minor, patch);
156+
157+
// Check if we already processed that version.
158+
if previous_stable_version_map.contains_key(&(minor, patch)) {
159+
continue;
160+
}
161+
162+
// Skip latest stable version.
163+
if &full_version == latest_stable_version {
164+
continue;
165+
}
166+
167+
// Download https://static.rust-lang.org/dist/channel-rust-{major.minor.patch}.toml and process it.
168+
let channel_url = format!("{}{}.toml", CHANNEL_URL_PREFIX, full_version);
169+
170+
let content = reqwest::blocking::get(&channel_url)?.text()?;
171+
let rust = toml::from_str::<crate::channel::Channel>(&content)?
172+
.pkg
173+
.rust;
174+
175+
log::info!(
176+
"Found {} targets for stable v{}",
177+
rust.target.len(),
178+
rust.version
179+
);
180+
181+
let version = rust.version.split(' ').next().unwrap().to_string();
182+
183+
// Sanity check.
184+
assert_eq!(&full_version, &version);
185+
186+
let platforms = rust
187+
.target
188+
.into_iter()
189+
.filter_map(|(target, content)| {
190+
if content.available {
191+
Some(target)
192+
} else {
193+
None
194+
}
195+
})
196+
.collect::<Vec<_>>();
197+
198+
previous_stable_version_map.insert((minor, patch), (version, platforms));
199+
}
200+
201+
// There are no manifests for stable versions before 1.8.0,
202+
// so we hardcode them instead.
203+
// i686-pc-windows-msvc wasn't supported until version 1.3.0.
204+
for minor in 3..8 {
205+
previous_stable_version_map.insert(
206+
(minor, 0),
207+
(
208+
format!("1.{}.0", minor),
209+
Vec::from([
210+
"i686-apple-darwin".to_string(),
211+
"i686-pc-windows-gnu".to_string(),
212+
"i686-pc-windows-msvc".to_string(),
213+
"i686-unknown-linux-gnu".to_string(),
214+
"x86_64-apple-darwin".to_string(),
215+
"x86_64-pc-windows-gnu".to_string(),
216+
"x86_64-pc-windows-msvc".to_string(),
217+
"x86_64-unknown-linux-gnu".to_string(),
218+
]),
219+
),
220+
);
221+
}
222+
223+
// x86_64-pc-windows-msvc wasn't supported until version 1.2.0.
224+
previous_stable_version_map.insert(
225+
(2, 0),
226+
(
227+
"1.2.0".to_string(),
228+
Vec::from([
229+
"i686-apple-darwin".to_string(),
230+
"i686-pc-windows-gnu".to_string(),
231+
"i686-unknown-linux-gnu".to_string(),
232+
"x86_64-apple-darwin".to_string(),
233+
"x86_64-pc-windows-gnu".to_string(),
234+
"x86_64-pc-windows-msvc".to_string(),
235+
"x86_64-unknown-linux-gnu".to_string(),
236+
]),
237+
),
238+
);
239+
240+
for minor in 0..2 {
241+
previous_stable_version_map.insert(
242+
(minor, 0),
243+
(
244+
format!("1.{}.0", minor),
245+
Vec::from([
246+
"i686-apple-darwin".to_string(),
247+
"i686-pc-windows-gnu".to_string(),
248+
"i686-unknown-linux-gnu".to_string(),
249+
"x86_64-apple-darwin".to_string(),
250+
"x86_64-pc-windows-gnu".to_string(),
251+
"x86_64-unknown-linux-gnu".to_string(),
252+
]),
253+
),
254+
);
255+
}
256+
257+
for (_, (version, platforms)) in previous_stable_version_map.into_iter().rev() {
258+
blacksmith
259+
.previous_stable_versions
260+
.push((version, platforms));
261+
}
262+
126263
blacksmith.last_update = unix_time();
127264
Ok(blacksmith)
128265
}
@@ -169,28 +306,28 @@ impl Blacksmith {
169306
writeln!(buffer, "---------|--------|------|--------").unwrap();
170307

171308
for (name, platform) in &self.platforms {
172-
let extension = if name.contains("windows") {
173-
"msi"
309+
let extensions: &[&str] = if name.contains("windows") {
310+
&["msi", "tar.xz"]
174311
} else if name.contains("darwin") {
175-
"pkg"
312+
&["pkg", "tar.xz"]
176313
} else {
177-
"tar.xz"
314+
&["tar.xz"]
178315
};
179316

180317
let stable_links = platform
181318
.stable
182319
.as_ref()
183-
.map(|version| generate_standalone_links("rust", version, name, extension))
320+
.map(|version| generate_standalone_links("rust", version, name, extensions))
184321
.unwrap_or_else(String::new);
185322

186323
let beta_links = if platform.beta {
187-
generate_standalone_links("rust", "beta", name, extension)
324+
generate_standalone_links("rust", "beta", name, extensions)
188325
} else {
189326
String::new()
190327
};
191328

192329
let nightly_links = if platform.nightly {
193-
generate_standalone_links("rust", "nightly", name, extension)
330+
generate_standalone_links("rust", "nightly", name, extensions)
194331
} else {
195332
String::new()
196333
};
@@ -209,6 +346,45 @@ impl Blacksmith {
209346
buffer
210347
}
211348

349+
/// Generates tables of links to the previous stable standalone installer packages for
350+
/// each platform.
351+
fn generate_previous_stable_standalone_installers_tables(&self) -> String {
352+
let mut buffer = String::new();
353+
354+
for (stable_version, platforms) in &self.previous_stable_versions {
355+
writeln!(buffer, "## Stable ({})", stable_version).unwrap();
356+
writeln!(buffer, "").unwrap();
357+
358+
writeln!(buffer, "platform | stable ({})", stable_version).unwrap();
359+
writeln!(buffer, "---------|--------").unwrap();
360+
361+
for name in platforms {
362+
let extensions: &[&str] = if name.contains("windows") {
363+
&["msi", "tar.gz"]
364+
} else if name.contains("darwin") {
365+
&["pkg", "tar.gz"]
366+
} else {
367+
&["tar.gz"]
368+
};
369+
370+
let stable_links =
371+
generate_standalone_links("rust", stable_version, name, extensions);
372+
373+
writeln!(
374+
buffer,
375+
"`{name}` | {stable}",
376+
name = name,
377+
stable = stable_links,
378+
)
379+
.unwrap();
380+
}
381+
382+
writeln!(buffer, "").unwrap();
383+
}
384+
385+
buffer
386+
}
387+
212388
/// Generates a similar table to `generate_standalone_installers_table`
213389
/// except for the rust source code packages.
214390
fn generate_source_code_table(&self) -> String {
@@ -224,15 +400,15 @@ impl Blacksmith {
224400
buffer,
225401
"stable ({}) | {}",
226402
stable_version,
227-
generate_standalone_links("rustc", stable_version, "src", "tar.xz")
403+
generate_standalone_links("rustc", stable_version, "src", &["tar.xz"])
228404
)
229405
.unwrap();
230406
} else {
231407
writeln!(
232408
buffer,
233409
"{} | {}",
234410
channel,
235-
generate_standalone_links("rustc", &channel, "src", "tar.xz")
411+
generate_standalone_links("rustc", &channel, "src", &["tar.xz"])
236412
)
237413
.unwrap();
238414
}
@@ -244,20 +420,27 @@ impl Blacksmith {
244420

245421
/// Generates links to standalone installers provided a rust version or channel,
246422
/// target name, and file extension.
247-
fn generate_standalone_links(base: &str, stem: &str, name: &str, extension: &str) -> String {
248-
let url = format!(
249-
"https://static.rust-lang.org/dist/{base}-{stem}-{name}.{extension}",
250-
extension = extension,
251-
name = name,
252-
stem = stem,
253-
base = base,
254-
);
255-
256-
format!(
257-
"[{extension}]({url}) <br> [{extension}.asc]({url}.asc)",
258-
extension = extension,
259-
url = url,
260-
)
423+
fn generate_standalone_links(base: &str, stem: &str, name: &str, extensions: &[&str]) -> String {
424+
let mut result = String::new();
425+
for extension in extensions {
426+
if !result.is_empty() {
427+
result.push_str(" <br> ");
428+
}
429+
let url = format!(
430+
"https://static.rust-lang.org/dist/{base}-{stem}-{name}.{extension}",
431+
extension = extension,
432+
name = name,
433+
stem = stem,
434+
base = base,
435+
);
436+
437+
result.push_str(&format!(
438+
"[{extension}]({url}) <br> [{extension}.asc]({url}.asc)",
439+
extension = extension,
440+
url = url,
441+
));
442+
}
443+
result
261444
}
262445

263446
fn unix_time() -> Option<u64> {
@@ -288,16 +471,23 @@ impl Preprocessor for Blacksmith {
288471

289472
let rustup_init_list = self.generate_rustup_init_list();
290473
let standalone_installers_table = self.generate_standalone_installers_table();
474+
let previous_stable_standalone_installers_tables =
475+
self.generate_previous_stable_standalone_installers_tables();
291476
let source_code_table = self.generate_source_code_table();
292477

293478
// TODO: Currently we're performing a global search for any of the
294479
// variables as that's the most flexible for adding more dynamic
295-
// content, and the time to traverse is fast enough to not be noticable.
480+
// content, and the time to traverse is fast enough to not be noticeable.
296481
// However if the processing time begins to become a bottleneck this
297482
// should change.
298483
for item in &mut book.sections {
299484
recursive_replace(item, "{{#rustup_init_list}}", &rustup_init_list);
300485
recursive_replace(item, "{{#installer_table}}", &standalone_installers_table);
486+
recursive_replace(
487+
item,
488+
"{{#previous_stable_standalone_installers_tables}}",
489+
&previous_stable_standalone_installers_tables,
490+
);
301491
recursive_replace(item, "{{#source_code_table}}", &source_code_table);
302492
}
303493

book.toml

+2-2
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@ command = "./build.bash"
1111

1212
[output.html]
1313
additional-js = ["js/moment.min.js", "js/index.js"]
14-
no-section-label=true
15-
git-repository-url="https://github.com/rust-lang/rust-forge"
14+
no-section-label = true
15+
git-repository-url = "https://github.com/rust-lang/rust-forge"
1616
edit-url-template = "https://github.com/rust-lang/rust-forge/edit/master/{path}"
1717
curly-quotes = true
1818

0 commit comments

Comments
 (0)