diff --git a/Cargo.lock b/Cargo.lock index bf843975c..5ae58fa20 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -339,7 +339,7 @@ dependencies = [ "rusoto_credential 0.40.0 (registry+https://github.com/rust-lang/crates.io-index)", "rusoto_s3 0.40.0 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)", - "rustwide 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rustwide 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", "sass-rs 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "schemamama 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "schemamama_postgres 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1884,7 +1884,7 @@ dependencies = [ [[package]] name = "rustwide" -version = "0.4.0" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "base64 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3094,7 +3094,7 @@ dependencies = [ "checksum rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)" = "dcf128d1287d2ea9d80910b5f1120d0b8eede3fbf1abe91c40d39ea7d51e6fda" "checksum rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" "checksum rusttype 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "b8eb11f5b0a98c8eca2fb1483f42646d8c340e83e46ab416f8a063a0fd0eeb20" -"checksum rustwide 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bbeed4fee09d894d922ecc7f51d2368f8c6e5b11bb63667f5d5d604978436da0" +"checksum rustwide 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a9663f312745b9a53570c3a2170ba92f9e71a49ac3328e15ed5955dd462eaacb" "checksum ryu 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "7153dd96dade874ab973e098cb62fcdbb89a03682e46b144fd09550998d4a4a7" "checksum safemem 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e27a8b19b835f7aea908818e871f5cc3a5a186550c30773be987e155e8163d8f" "checksum safemem 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8dca453248a96cb0749e36ccdfe2b0b4e54a61bfef89fb97ec621eb8e0a93dd9" diff --git a/Cargo.toml b/Cargo.toml index 407769b13..bff8bc3f2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -38,7 +38,7 @@ tokio = "0.1" systemstat = "0.1.4" prometheus = { version = "0.7.0", default-features = false } lazy_static = "1.0.0" -rustwide = "0.4.0" +rustwide = "0.5.0" tempdir = "0.3" # iron dependencies diff --git a/src/docbuilder/rustwide_builder.rs b/src/docbuilder/rustwide_builder.rs index ed2954fcc..62782e9ca 100644 --- a/src/docbuilder/rustwide_builder.rs +++ b/src/docbuilder/rustwide_builder.rs @@ -9,8 +9,10 @@ use postgres::Connection; use rustc_serialize::json::ToJson; use rustwide::cmd::{Command, SandboxBuilder}; use rustwide::logging::{self, LogStorage}; +use rustwide::toolchain::ToolchainError; use rustwide::{Build, Crate, Toolchain, Workspace, WorkspaceBuilder}; use std::borrow::Cow; +use std::collections::HashSet; use std::path::Path; use utils::{copy_doc_dir, parse_rustc_version, CargoMetadata}; use Metadata; @@ -19,7 +21,6 @@ static USER_AGENT: &str = "docs.rs builder (https://github.com/rust-lang/docs.rs static DEFAULT_RUSTWIDE_WORKSPACE: &str = ".rustwide"; static TARGETS: &[&str] = &[ - "i686-apple-darwin", "i686-pc-windows-msvc", "i686-unknown-linux-gnu", "x86_64-apple-darwin", @@ -95,12 +96,43 @@ impl RustwideBuilder { // Ignore errors if detection fails. let old_version = self.detect_rustc_version().ok(); + let mut targets_to_install = TARGETS + .iter() + .map(|t| t.to_string()) + .collect::>(); + let installed_targets = match self.toolchain.installed_targets(&self.workspace) { + Ok(targets) => targets, + Err(err) => { + if let Some(&ToolchainError::NotInstalled) = err.downcast_ref::() { + Vec::new() + } else { + return Err(err); + } + } + }; + + // The extra targets are intentionally removed *before* trying to update. + // + // If a target is installed locally and it goes missing the next update, rustup will block + // the update to avoid leaving the system in a broken state. This is not a behavior we want + // though when we also remove the target from the list managed by docs.rs: we want that + // target gone, and we don't care if it's missing in the next update. + // + // Removing it beforehand works fine, and prevents rustup from blocking the update later in + // the method. + for target in installed_targets { + if !targets_to_install.remove(&target) { + self.toolchain.remove_target(&self.workspace, &target)?; + } + } + self.toolchain.install(&self.workspace)?; - for target in TARGETS { + + for target in &targets_to_install { self.toolchain.add_target(&self.workspace, target)?; } - self.rustc_version = self.detect_rustc_version()?; + self.rustc_version = self.detect_rustc_version()?; if old_version.as_ref().map(|s| s.as_str()) != Some(&self.rustc_version) { self.add_essential_files()?; }