Skip to content

Commit

Permalink
Merge branch 'master' into clarify-survey-data-holder
Browse files Browse the repository at this point in the history
  • Loading branch information
apiraino authored Nov 18, 2024
2 parents 2549945 + e987bdf commit b81ea36
Show file tree
Hide file tree
Showing 30 changed files with 666 additions and 660 deletions.
2 changes: 2 additions & 0 deletions .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ jobs:
- uses: actions/checkout@v3
- name: Install mdbook
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
- name: Check blacksmith format
run: cargo fmt --check --manifest-path=blacksmith/Cargo.toml
- name: Build book
run: ./mdbook build
- name: Deploy book
Expand Down
8 changes: 4 additions & 4 deletions blacksmith/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 1 addition & 2 deletions blacksmith/src/channel.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use std::collections::BTreeMap;
use serde::Deserialize;
use std::collections::BTreeMap;

#[derive(Deserialize)]
pub struct Target {
Expand All @@ -21,4 +21,3 @@ pub struct Packages {
pub struct Channel {
pub pkg: Packages,
}

238 changes: 214 additions & 24 deletions blacksmith/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ use mdbook::{

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

Expand Down Expand Up @@ -45,6 +46,8 @@ pub struct Blacksmith {
rustup: Vec<String>,
stable_version: Option<String>,
platforms: BTreeMap<String, Platform>,
#[serde(default)]
previous_stable_versions: Vec<(String, Vec<String>)>,
}

impl Blacksmith {
Expand Down Expand Up @@ -123,6 +126,140 @@ impl Blacksmith {
}
}

let latest_stable_version = &blacksmith.stable_version.clone().unwrap();

// We need to use a map to deduplicate entries and sort them in the correct order.
// There are multiple entries for stable 1.8.0, 1.14.0, 1.15.1, 1.49.0 in MANIFESTS_URL.
// Keys contain (minor_version, patch_version) and values contain (full_version, platforms).
let mut previous_stable_version_map: BTreeMap<(u32, u32), (String, Vec<String>)> =
BTreeMap::new();

// Go over stable versions in https://static.rust-lang.org/manifests.txt in reverse order.
let manifests_content = reqwest::blocking::get(MANIFESTS_URL)?.text()?;
let stable_manifest_url_regex = regex::Regex::new(
r"^static\.rust-lang\.org/dist/\d{4}-\d{2}-\d{2}/channel-rust-1\.(\d+)\.(\d+)\.toml$",
)
.unwrap();
for manifest_url in manifests_content.lines().rev() {
let minor;
let patch;

// Check if it's a stable version.
if let Some(captures) = stable_manifest_url_regex.captures(&(manifest_url)) {
minor = captures.get(1).unwrap().as_str().parse::<u32>().unwrap();
patch = captures.get(2).unwrap().as_str().parse::<u32>().unwrap();
} else {
continue;
}

let full_version = format!("1.{}.{}", minor, patch);

// Check if we already processed that version.
if previous_stable_version_map.contains_key(&(minor, patch)) {
continue;
}

// Skip latest stable version.
if &full_version == latest_stable_version {
continue;
}

// Download https://static.rust-lang.org/dist/channel-rust-{major.minor.patch}.toml and process it.
let channel_url = format!("{}{}.toml", CHANNEL_URL_PREFIX, full_version);

let content = reqwest::blocking::get(&channel_url)?.text()?;
let rust = toml::from_str::<crate::channel::Channel>(&content)?
.pkg
.rust;

log::info!(
"Found {} targets for stable v{}",
rust.target.len(),
rust.version
);

let version = rust.version.split(' ').next().unwrap().to_string();

// Sanity check.
assert_eq!(&full_version, &version);

let platforms = rust
.target
.into_iter()
.filter_map(|(target, content)| {
if content.available {
Some(target)
} else {
None
}
})
.collect::<Vec<_>>();

previous_stable_version_map.insert((minor, patch), (version, platforms));
}

// There are no manifests for stable versions before 1.8.0,
// so we hardcode them instead.
// i686-pc-windows-msvc wasn't supported until version 1.3.0.
for minor in 3..8 {
previous_stable_version_map.insert(
(minor, 0),
(
format!("1.{}.0", minor),
Vec::from([
"i686-apple-darwin".to_string(),
"i686-pc-windows-gnu".to_string(),
"i686-pc-windows-msvc".to_string(),
"i686-unknown-linux-gnu".to_string(),
"x86_64-apple-darwin".to_string(),
"x86_64-pc-windows-gnu".to_string(),
"x86_64-pc-windows-msvc".to_string(),
"x86_64-unknown-linux-gnu".to_string(),
]),
),
);
}

// x86_64-pc-windows-msvc wasn't supported until version 1.2.0.
previous_stable_version_map.insert(
(2, 0),
(
"1.2.0".to_string(),
Vec::from([
"i686-apple-darwin".to_string(),
"i686-pc-windows-gnu".to_string(),
"i686-unknown-linux-gnu".to_string(),
"x86_64-apple-darwin".to_string(),
"x86_64-pc-windows-gnu".to_string(),
"x86_64-pc-windows-msvc".to_string(),
"x86_64-unknown-linux-gnu".to_string(),
]),
),
);

for minor in 0..2 {
previous_stable_version_map.insert(
(minor, 0),
(
format!("1.{}.0", minor),
Vec::from([
"i686-apple-darwin".to_string(),
"i686-pc-windows-gnu".to_string(),
"i686-unknown-linux-gnu".to_string(),
"x86_64-apple-darwin".to_string(),
"x86_64-pc-windows-gnu".to_string(),
"x86_64-unknown-linux-gnu".to_string(),
]),
),
);
}

for (_, (version, platforms)) in previous_stable_version_map.into_iter().rev() {
blacksmith
.previous_stable_versions
.push((version, platforms));
}

blacksmith.last_update = unix_time();
Ok(blacksmith)
}
Expand Down Expand Up @@ -169,28 +306,28 @@ impl Blacksmith {
writeln!(buffer, "---------|--------|------|--------").unwrap();

for (name, platform) in &self.platforms {
let extension = if name.contains("windows") {
"msi"
let extensions: &[&str] = if name.contains("windows") {
&["msi", "tar.xz"]
} else if name.contains("darwin") {
"pkg"
&["pkg", "tar.xz"]
} else {
"tar.xz"
&["tar.xz"]
};

let stable_links = platform
.stable
.as_ref()
.map(|version| generate_standalone_links("rust", version, name, extension))
.map(|version| generate_standalone_links("rust", version, name, extensions))
.unwrap_or_else(String::new);

let beta_links = if platform.beta {
generate_standalone_links("rust", "beta", name, extension)
generate_standalone_links("rust", "beta", name, extensions)
} else {
String::new()
};

let nightly_links = if platform.nightly {
generate_standalone_links("rust", "nightly", name, extension)
generate_standalone_links("rust", "nightly", name, extensions)
} else {
String::new()
};
Expand All @@ -209,6 +346,45 @@ impl Blacksmith {
buffer
}

/// Generates tables of links to the previous stable standalone installer packages for
/// each platform.
fn generate_previous_stable_standalone_installers_tables(&self) -> String {
let mut buffer = String::new();

for (stable_version, platforms) in &self.previous_stable_versions {
writeln!(buffer, "## Stable ({})", stable_version).unwrap();
writeln!(buffer, "").unwrap();

writeln!(buffer, "platform | stable ({})", stable_version).unwrap();
writeln!(buffer, "---------|--------").unwrap();

for name in platforms {
let extensions: &[&str] = if name.contains("windows") {
&["msi", "tar.gz"]
} else if name.contains("darwin") {
&["pkg", "tar.gz"]
} else {
&["tar.gz"]
};

let stable_links =
generate_standalone_links("rust", stable_version, name, extensions);

writeln!(
buffer,
"`{name}` | {stable}",
name = name,
stable = stable_links,
)
.unwrap();
}

writeln!(buffer, "").unwrap();
}

buffer
}

/// Generates a similar table to `generate_standalone_installers_table`
/// except for the rust source code packages.
fn generate_source_code_table(&self) -> String {
Expand All @@ -224,15 +400,15 @@ impl Blacksmith {
buffer,
"stable ({}) | {}",
stable_version,
generate_standalone_links("rustc", stable_version, "src", "tar.xz")
generate_standalone_links("rustc", stable_version, "src", &["tar.xz"])
)
.unwrap();
} else {
writeln!(
buffer,
"{} | {}",
channel,
generate_standalone_links("rustc", &channel, "src", "tar.xz")
generate_standalone_links("rustc", &channel, "src", &["tar.xz"])
)
.unwrap();
}
Expand All @@ -244,20 +420,27 @@ impl Blacksmith {

/// Generates links to standalone installers provided a rust version or channel,
/// target name, and file extension.
fn generate_standalone_links(base: &str, stem: &str, name: &str, extension: &str) -> String {
let url = format!(
"https://static.rust-lang.org/dist/{base}-{stem}-{name}.{extension}",
extension = extension,
name = name,
stem = stem,
base = base,
);

format!(
"[{extension}]({url}) <br> [{extension}.asc]({url}.asc)",
extension = extension,
url = url,
)
fn generate_standalone_links(base: &str, stem: &str, name: &str, extensions: &[&str]) -> String {
let mut result = String::new();
for extension in extensions {
if !result.is_empty() {
result.push_str(" <br> ");
}
let url = format!(
"https://static.rust-lang.org/dist/{base}-{stem}-{name}.{extension}",
extension = extension,
name = name,
stem = stem,
base = base,
);

result.push_str(&format!(
"[{extension}]({url}) <br> [{extension}.asc]({url}.asc)",
extension = extension,
url = url,
));
}
result
}

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

let rustup_init_list = self.generate_rustup_init_list();
let standalone_installers_table = self.generate_standalone_installers_table();
let previous_stable_standalone_installers_tables =
self.generate_previous_stable_standalone_installers_tables();
let source_code_table = self.generate_source_code_table();

// TODO: Currently we're performing a global search for any of the
// variables as that's the most flexible for adding more dynamic
// content, and the time to traverse is fast enough to not be noticable.
// content, and the time to traverse is fast enough to not be noticeable.
// However if the processing time begins to become a bottleneck this
// should change.
for item in &mut book.sections {
recursive_replace(item, "{{#rustup_init_list}}", &rustup_init_list);
recursive_replace(item, "{{#installer_table}}", &standalone_installers_table);
recursive_replace(
item,
"{{#previous_stable_standalone_installers_tables}}",
&previous_stable_standalone_installers_tables,
);
recursive_replace(item, "{{#source_code_table}}", &source_code_table);
}

Expand Down
4 changes: 2 additions & 2 deletions book.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ command = "./build.bash"

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

Expand Down
Loading

0 comments on commit b81ea36

Please sign in to comment.