Skip to content

Commit 7934e53

Browse files
committed
Add support for XZ-compressed packages
When XZ-compressed packages are available, prefer them in place of the GZip-compressed ones as they can provide significant savings interms of download size.
1 parent 0efe0bb commit 7934e53

File tree

5 files changed

+89
-8
lines changed

5 files changed

+89
-8
lines changed

Cargo.lock

Lines changed: 21 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/rustup-dist/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ ole32-sys = "0.2.0"
1919
url = "1.1.0"
2020
tar = "0.4.0"
2121
flate2 = "0.2.9"
22+
xz2 = "0.1.3"
2223
tempdir = "0.3.4"
2324
walkdir = "0.1.5"
2425
toml = "0.1.27"

src/rustup-dist/src/component/package.rs

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
55
extern crate tar;
66
extern crate flate2;
7+
extern crate xz2;
78

89
use component::components::*;
910
use component::transaction::*;
@@ -261,3 +262,35 @@ impl<'a> Package for TarGzPackage<'a> {
261262
self.0.components()
262263
}
263264
}
265+
266+
#[derive(Debug)]
267+
pub struct TarXzPackage<'a>(TarPackage<'a>);
268+
269+
impl<'a> TarXzPackage<'a> {
270+
pub fn new<R: Read>(stream: R, temp_cfg: &'a temp::Cfg) -> Result<Self> {
271+
let stream = xz2::read::XzDecoder::new(stream);
272+
273+
Ok(TarXzPackage(try!(TarPackage::new(stream, temp_cfg))))
274+
}
275+
pub fn new_file(path: &Path, temp_cfg: &'a temp::Cfg) -> Result<Self> {
276+
let file = try!(File::open(path).chain_err(|| ErrorKind::ExtractingPackage));
277+
Self::new(file, temp_cfg)
278+
}
279+
}
280+
281+
impl<'a> Package for TarXzPackage<'a> {
282+
fn contains(&self, component: &str, short_name: Option<&str>) -> bool {
283+
self.0.contains(component, short_name)
284+
}
285+
fn install<'b>(&self,
286+
target: &Components,
287+
component: &str,
288+
short_name: Option<&str>,
289+
tx: Transaction<'b>)
290+
-> Result<Transaction<'b>> {
291+
self.0.install(target, component, short_name, tx)
292+
}
293+
fn components(&self) -> Vec<String> {
294+
self.0.components()
295+
}
296+
}

src/rustup-dist/src/manifest.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,8 @@ pub struct TargetedPackage {
4444
pub available: bool,
4545
pub url: String,
4646
pub hash: String,
47+
pub xz_url: Option<String>,
48+
pub xz_hash: Option<String>,
4749
pub components: Vec<Component>,
4850
pub extensions: Vec<Component>,
4951
}
@@ -230,6 +232,8 @@ impl TargetedPackage {
230232
available: try!(get_bool(&mut table, "available", path)),
231233
url: try!(get_string(&mut table, "url", path)),
232234
hash: try!(get_string(&mut table, "hash", path)),
235+
xz_url: get_string(&mut table, "xz_url", path).ok(),
236+
xz_hash: get_string(&mut table, "xz_hash", path).ok(),
233237
components: try!(Self::toml_to_components(components,
234238
&format!("{}{}.", path, "components"))),
235239
extensions: try!(Self::toml_to_components(extensions,

src/rustup-dist/src/manifestation.rs

Lines changed: 30 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
use config::Config;
55
use manifest::{Component, Manifest, TargetedPackage};
66
use dist::{download_and_check, DownloadCfg, TargetTriple, DEFAULT_DIST_SERVER, File};
7-
use component::{Components, Transaction, TarGzPackage, Package};
7+
use component::{Components, Transaction, TarGzPackage, TarXzPackage, Package};
88
use temp;
99
use errors::*;
1010
use notifications::*;
@@ -15,6 +15,11 @@ use std::path::Path;
1515
pub const DIST_MANIFEST: &'static str = "multirust-channel-manifest.toml";
1616
pub const CONFIG_FILE: &'static str = "multirust-config.toml";
1717

18+
enum Format {
19+
Gz,
20+
Xz,
21+
}
22+
1823
#[derive(Debug)]
1924
pub struct Manifestation {
2025
installation: Components,
@@ -114,20 +119,26 @@ impl Manifestation {
114119
}
115120

116121
// Map components to urls and hashes
117-
let mut components_urls_and_hashes: Vec<(Component, String, String)> = Vec::new();
122+
let mut components_urls_and_hashes: Vec<(Component, Format, String, String)> = Vec::new();
118123
for component in components_to_install {
119124
let package = try!(new_manifest.get_package(&component.pkg));
120125
let target_package = try!(package.get_target(component.target.as_ref()));
121-
let c_u_h = (component, target_package.url.clone(), target_package.hash.clone());
126+
let c_u_h =
127+
if let (Some(url), Some(hash)) = (target_package.xz_url.clone(),
128+
target_package.xz_hash.clone()) {
129+
(component, Format::Xz, url, hash)
130+
} else {
131+
(component, Format::Gz, target_package.url.clone(), target_package.hash.clone())
132+
};
122133
components_urls_and_hashes.push(c_u_h);
123134
}
124135

125136
let altered = temp_cfg.dist_server != DEFAULT_DIST_SERVER;
126137

127138
// Download component packages and validate hashes
128-
let mut things_to_install: Vec<(Component, File)> = Vec::new();
139+
let mut things_to_install: Vec<(Component, Format, File)> = Vec::new();
129140
let mut things_downloaded: Vec<String> = Vec::new();
130-
for (component, url, hash) in components_urls_and_hashes {
141+
for (component, format, url, hash) in components_urls_and_hashes {
131142

132143
notify_handler(Notification::DownloadingComponent(&component.pkg,
133144
&self.target_triple,
@@ -145,7 +156,7 @@ impl Manifestation {
145156
}));
146157
things_downloaded.push(hash);
147158

148-
things_to_install.push((component, dowloaded_file));
159+
things_to_install.push((component, format, dowloaded_file));
149160
}
150161

151162
// Begin transaction
@@ -166,13 +177,24 @@ impl Manifestation {
166177
}
167178

168179
// Install components
169-
for (component, installer_file) in things_to_install {
180+
for (component, format, installer_file) in things_to_install {
170181

171182
notify_handler(Notification::InstallingComponent(&component.pkg,
172183
&self.target_triple,
173184
component.target.as_ref()));
174185

175-
let package = try!(TarGzPackage::new_file(&installer_file, temp_cfg));
186+
let gz;
187+
let xz;
188+
let package: &Package = match format {
189+
Format::Gz => {
190+
gz = try!(TarGzPackage::new_file(&installer_file, temp_cfg));
191+
&gz
192+
}
193+
Format::Xz => {
194+
xz = try!(TarXzPackage::new_file(&installer_file, temp_cfg));
195+
&xz
196+
}
197+
};
176198

177199
// For historical reasons, the rust-installer component
178200
// names are not the same as the dist manifest component

0 commit comments

Comments
 (0)