From 771066c00c76ab3eeb1bfb90d8a888b054c67dd7 Mon Sep 17 00:00:00 2001 From: Yerkebulan Tulibergenov Date: Sat, 4 May 2024 17:22:56 -0700 Subject: [PATCH] Add Archive of Rust Stable Standalone Installers --- blacksmith/src/lib.rs | 109 +++++++++++++++++- src/SUMMARY.md | 1 + .../archive-stable-version-installers.md | 9 ++ src/infra/other-installation-methods.md | 27 +---- src/infra/shared-standalone-installers.md | 20 ++++ 5 files changed, 141 insertions(+), 25 deletions(-) create mode 100644 src/infra/archive-stable-version-installers.md create mode 100644 src/infra/shared-standalone-installers.md diff --git a/blacksmith/src/lib.rs b/blacksmith/src/lib.rs index 887926e36..5c8bd6968 100644 --- a/blacksmith/src/lib.rs +++ b/blacksmith/src/lib.rs @@ -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"; @@ -45,6 +46,8 @@ pub struct Blacksmith { rustup: Vec, stable_version: Option, platforms: BTreeMap, + #[serde(default)] + previous_stable_versions: Vec<(String, Vec)>, } impl Blacksmith { @@ -123,6 +126,64 @@ impl Blacksmith { } } + let latest_stable_version = &blacksmith.stable_version.clone().unwrap(); + + // 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(); + patch = captures.get(2).unwrap().as_str(); + } else { + continue + } + + let full_version = format!("1.{}.{}", minor, patch); + + // 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::(&content)? + .pkg + .rust; + + log::info!( + "Found {} targets for stable v{}", + rust.target.len(), + rust.version + ); + + let version = rust.version.split(' ').next().unwrap().to_string(); + + let platforms = rust + .target + .into_iter() + .filter_map(|(target, content)| { + if content.available { + Some(target) + } else { + None + } + }) + .collect::>(); + + blacksmith + .previous_stable_versions + .push((version.clone(), platforms)); + } + blacksmith.last_update = unix_time(); Ok(blacksmith) } @@ -209,6 +270,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 extension = if name.contains("windows") { + "msi" + } else if name.contains("darwin") { + "pkg" + } else { + "tar.gz" + }; + + let stable_links = + generate_standalone_links("rust", stable_version, name, extension); + + 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 { @@ -288,16 +388,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); } diff --git a/src/SUMMARY.md b/src/SUMMARY.md index cab30a065..87d284deb 100644 --- a/src/SUMMARY.md +++ b/src/SUMMARY.md @@ -68,6 +68,7 @@ - [Moderation](./governance/moderation.md) - [Infrastructure](./infra/README.md) - [Other Installation Methods](./infra/other-installation-methods.md) + - [Archive of Rust Stable Standalone Installers](./infra/archive-stable-version-installers.md) - [Release Channel Layout](./infra/channel-layout.md) - [Service Infrastructure](./infra/service-infrastructure.md) - [Team Maintenance](./infra/team-maintenance.md) diff --git a/src/infra/archive-stable-version-installers.md b/src/infra/archive-stable-version-installers.md new file mode 100644 index 000000000..2dcf349cf --- /dev/null +++ b/src/infra/archive-stable-version-installers.md @@ -0,0 +1,9 @@ +# Archive of Rust Stable Standalone Installers + +**Note: The Rust project only supports the latest stable release with security patches. +Generally speaking these archives should not be used without some extra mechanisms +to provide for patching.** + +{{#include shared-standalone-installers.md}} + +{{#previous_stable_standalone_installers_tables}} diff --git a/src/infra/other-installation-methods.md b/src/infra/other-installation-methods.md index c43fd8cb1..1d661b554 100644 --- a/src/infra/other-installation-methods.md +++ b/src/infra/other-installation-methods.md @@ -79,26 +79,9 @@ what they each specifically generate. -The official Rust standalone installers contain a single release of Rust, and -are suitable for offline installation. They come in three forms: tarballs -(extension `.tar.xz`), that work in any Unix-like environment, Windows -installers (`.msi`), and Mac installers (`.pkg`). These installers come with -`rustc`, `cargo`, `rustdoc`, the standard library, and the standard -documentation, but do not provide access to additional cross-targets like -`rustup` does. +{{#include shared-standalone-installers.md}} -The most common reasons to use these are: - -- Offline installation -- Preferring a more platform-integrated, graphical installer on Windows - -Each of these binaries is signed with the [Rust signing key], which is -[available on keybase.io], by the Rust build infrastructure, with [GPG]. In the -tables below, the `.asc` files are the signatures. - - +Past releases can be found in [the archive]. {{#installer_table}} @@ -170,8 +153,4 @@ diff rustc-*-src.tar build/dist/rustc-*-src.tar [chocolatey]: http://chocolatey.org/ [scoop]: https://scoop.sh/ [three tiers]: https://doc.rust-lang.org/nightly/rustc/platform-support.html -[rust signing key]: https://static.rust-lang.org/rust-key.gpg.ascii -[gpg]: https://gnupg.org/ -[available on keybase.io]: https://keybase.io/rust -[the archives]: https://static.rust-lang.org/dist/index.html - +[the archive]: ../infra/archive-stable-version-installers.md diff --git a/src/infra/shared-standalone-installers.md b/src/infra/shared-standalone-installers.md new file mode 100644 index 000000000..0824b88ce --- /dev/null +++ b/src/infra/shared-standalone-installers.md @@ -0,0 +1,20 @@ +The official Rust standalone installers contain a single release of Rust, and +are suitable for offline installation. They come in three forms: tarballs +(extension `.tar.xz`), that work in any Unix-like environment, Windows +installers (`.msi`), and Mac installers (`.pkg`). These installers come with +`rustc`, `cargo`, `rustdoc`, the standard library, and the standard +documentation, but do not provide access to additional cross-targets like +`rustup` does. + +The most common reasons to use these are: + +- Offline installation +- Preferring a more platform-integrated, graphical installer on Windows + +Each of these binaries is signed with the [Rust signing key], which is +[available on keybase.io], by the Rust build infrastructure, with [GPG]. In the +tables below, the `.asc` files are the signatures. + +[rust signing key]: https://static.rust-lang.org/rust-key.gpg.ascii +[available on keybase.io]: https://keybase.io/rust +[gpg]: https://gnupg.org/