diff --git a/Cargo.lock b/Cargo.lock index 2cd6891e49e..5c7f431a0ce 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -343,6 +343,16 @@ name = "log" version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "lzma-sys" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "filetime 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "gcc 0.3.45 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "markdown" version = "0.2.0" @@ -588,6 +598,7 @@ dependencies = [ "walkdir 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", "winreg 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", + "xz2 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -974,6 +985,14 @@ dependencies = [ "libc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "xz2" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "lzma-sys 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", +] + [metadata] "checksum advapi32-sys 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "307c92332867e586720c0222ee9d890bbe8431711efed8a1b06bc5b40fc66bd7" "checksum advapi32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e06588080cb19d0acb6739808aafa5f26bfb2ca015b2b6370028b44cf7cb8a9a" @@ -1012,6 +1031,7 @@ dependencies = [ "checksum libc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)" = "a51822fc847e7a8101514d1d44e354ba2ffa7d4c194dcab48870740e327cac70" "checksum libz-sys 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)" = "c18b5826abbfafb0160b37e1991e2d327c1fe38c955e496ea306f72c06d7570c" "checksum log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "ab83497bf8bf4ed2a74259c1c802351fcd67a65baa86394b6ba73c36f4838054" +"checksum lzma-sys 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c5eaaa53b35fa17482ee2c001b04242827b47ae0faba72663fee3dee32366248" "checksum markdown 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bdb7e864aa1dccbebb05751e899bc84c639df47490c0c24caf4b1a77770b6566" "checksum matches 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "15305656809ce5a4805b1ff2946892810992197ce1270ff79baded852187942e" "checksum memchr 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "d8b629fb514376c675b98c1421e80b151d3817ac42d7c667717d282761418d20" @@ -1078,3 +1098,4 @@ dependencies = [ "checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc" "checksum winreg 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e63857fb213f619b4c4fff86b158285c76766aac7e7474967e92fb6dbbfeefe9" "checksum xattr 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "06d6f0e8fd6536f3c623afab15488d87cf3a5dbb907361a22c05d739881136d7" +"checksum xz2 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "e9510bdf100731599107c61f77daf46713a69a568f75458999c1f9dbf6ba25b0" diff --git a/src/rustup-dist/Cargo.toml b/src/rustup-dist/Cargo.toml index 9bd788348be..32c2ad30e76 100644 --- a/src/rustup-dist/Cargo.toml +++ b/src/rustup-dist/Cargo.toml @@ -19,6 +19,7 @@ ole32-sys = "0.2.0" url = "1.1.0" tar = "0.4.0" flate2 = "0.2.9" +xz2 = "0.1.3" tempdir = "0.3.4" walkdir = "0.1.5" toml = "0.1.27" diff --git a/src/rustup-dist/src/component/package.rs b/src/rustup-dist/src/component/package.rs index a49ae5f48f6..a5a02d376e2 100644 --- a/src/rustup-dist/src/component/package.rs +++ b/src/rustup-dist/src/component/package.rs @@ -4,6 +4,7 @@ extern crate tar; extern crate flate2; +extern crate xz2; use component::components::*; use component::transaction::*; @@ -253,3 +254,35 @@ impl<'a> Package for TarGzPackage<'a> { self.0.components() } } + +#[derive(Debug)] +pub struct TarXzPackage<'a>(TarPackage<'a>); + +impl<'a> TarXzPackage<'a> { + pub fn new(stream: R, temp_cfg: &'a temp::Cfg) -> Result { + let stream = xz2::read::XzDecoder::new(stream); + + Ok(TarXzPackage(try!(TarPackage::new(stream, temp_cfg)))) + } + pub fn new_file(path: &Path, temp_cfg: &'a temp::Cfg) -> Result { + let file = try!(File::open(path).chain_err(|| ErrorKind::ExtractingPackage)); + Self::new(file, temp_cfg) + } +} + +impl<'a> Package for TarXzPackage<'a> { + fn contains(&self, component: &str, short_name: Option<&str>) -> bool { + self.0.contains(component, short_name) + } + fn install<'b>(&self, + target: &Components, + component: &str, + short_name: Option<&str>, + tx: Transaction<'b>) + -> Result> { + self.0.install(target, component, short_name, tx) + } + fn components(&self) -> Vec { + self.0.components() + } +} diff --git a/src/rustup-dist/src/manifest.rs b/src/rustup-dist/src/manifest.rs index 5fc5404fac7..9953ef32399 100644 --- a/src/rustup-dist/src/manifest.rs +++ b/src/rustup-dist/src/manifest.rs @@ -44,6 +44,8 @@ pub struct TargetedPackage { pub available: bool, pub url: String, pub hash: String, + pub xz_url: Option, + pub xz_hash: Option, pub components: Vec, pub extensions: Vec, } @@ -230,6 +232,8 @@ impl TargetedPackage { available: try!(get_bool(&mut table, "available", path)), url: try!(get_string(&mut table, "url", path)), hash: try!(get_string(&mut table, "hash", path)), + xz_url: get_string(&mut table, "xz_url", path).ok(), + xz_hash: get_string(&mut table, "xz_hash", path).ok(), components: try!(Self::toml_to_components(components, &format!("{}{}.", path, "components"))), extensions: try!(Self::toml_to_components(extensions, diff --git a/src/rustup-dist/src/manifestation.rs b/src/rustup-dist/src/manifestation.rs index db6d9ef9d76..b1bc3186ef5 100644 --- a/src/rustup-dist/src/manifestation.rs +++ b/src/rustup-dist/src/manifestation.rs @@ -4,7 +4,7 @@ use config::Config; use manifest::{Component, Manifest, TargetedPackage}; use dist::{download_and_check, DownloadCfg, TargetTriple, DEFAULT_DIST_SERVER, File}; -use component::{Components, Transaction, TarGzPackage, Package}; +use component::{Components, Transaction, TarGzPackage, TarXzPackage, Package}; use temp; use errors::*; use notifications::*; @@ -15,6 +15,11 @@ use std::path::Path; pub const DIST_MANIFEST: &'static str = "multirust-channel-manifest.toml"; pub const CONFIG_FILE: &'static str = "multirust-config.toml"; +enum Format { + Gz, + Xz, +} + #[derive(Debug)] pub struct Manifestation { installation: Components, @@ -114,20 +119,26 @@ impl Manifestation { } // Map components to urls and hashes - let mut components_urls_and_hashes: Vec<(Component, String, String)> = Vec::new(); + let mut components_urls_and_hashes: Vec<(Component, Format, String, String)> = Vec::new(); for component in components_to_install { let package = try!(new_manifest.get_package(&component.pkg)); let target_package = try!(package.get_target(component.target.as_ref())); - let c_u_h = (component, target_package.url.clone(), target_package.hash.clone()); + let c_u_h = + if let (Some(url), Some(hash)) = (target_package.xz_url.clone(), + target_package.xz_hash.clone()) { + (component, Format::Xz, url, hash) + } else { + (component, Format::Gz, target_package.url.clone(), target_package.hash.clone()) + }; components_urls_and_hashes.push(c_u_h); } let altered = temp_cfg.dist_server != DEFAULT_DIST_SERVER; // Download component packages and validate hashes - let mut things_to_install: Vec<(Component, File)> = Vec::new(); + let mut things_to_install: Vec<(Component, Format, File)> = Vec::new(); let mut things_downloaded: Vec = Vec::new(); - for (component, url, hash) in components_urls_and_hashes { + for (component, format, url, hash) in components_urls_and_hashes { notify_handler(Notification::DownloadingComponent(&component.pkg, &self.target_triple, @@ -145,7 +156,7 @@ impl Manifestation { })); things_downloaded.push(hash); - things_to_install.push((component, dowloaded_file)); + things_to_install.push((component, format, dowloaded_file)); } // Begin transaction @@ -161,13 +172,24 @@ impl Manifestation { } // Install components - for (component, installer_file) in things_to_install { + for (component, format, installer_file) in things_to_install { notify_handler(Notification::InstallingComponent(&component.pkg, &self.target_triple, component.target.as_ref())); - let package = try!(TarGzPackage::new_file(&installer_file, temp_cfg)); + let gz; + let xz; + let package: &Package = match format { + Format::Gz => { + gz = try!(TarGzPackage::new_file(&installer_file, temp_cfg)); + &gz + } + Format::Xz => { + xz = try!(TarXzPackage::new_file(&installer_file, temp_cfg)); + &xz + } + }; // For historical reasons, the rust-installer component // names are not the same as the dist manifest component