Skip to content

Commit 31ebf26

Browse files
authored
Merge pull request #2675 from kinnison/tarball-compression-flexibility
compression: Refactor handling of compression formats
2 parents 6eccd9b + 9b2250c commit 31ebf26

File tree

4 files changed

+65
-54
lines changed

4 files changed

+65
-54
lines changed

src/dist/manifest.rs

Lines changed: 44 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -47,16 +47,34 @@ pub enum PackageTargets {
4747

4848
#[derive(Clone, Debug, PartialEq)]
4949
pub struct TargetedPackage {
50-
pub bins: Option<PackageBins>,
50+
pub bins: Vec<(CompressionKind, HashedBinary)>,
5151
pub components: Vec<Component>,
5252
}
5353

54+
#[derive(Clone, Copy, Debug, PartialEq)]
55+
pub enum CompressionKind {
56+
GZip,
57+
XZ,
58+
}
59+
60+
/// Each compression kind, in order of preference for use, from most desirable
61+
/// to least desirable.
62+
static COMPRESSION_KIND_PREFERENCE_ORDER: &[CompressionKind] =
63+
&[CompressionKind::XZ, CompressionKind::GZip];
64+
65+
impl CompressionKind {
66+
const fn key_prefix(self) -> &'static str {
67+
match self {
68+
Self::GZip => "",
69+
Self::XZ => "xz_",
70+
}
71+
}
72+
}
73+
5474
#[derive(Clone, Debug, PartialEq)]
55-
pub struct PackageBins {
75+
pub struct HashedBinary {
5676
pub url: String,
5777
pub hash: String,
58-
pub xz_url: Option<String>,
59-
pub xz_hash: Option<String>,
6078
}
6179

6280
#[derive(Clone, Debug, Eq, Ord, PartialOrd)]
@@ -417,19 +435,21 @@ impl TargetedPackage {
417435
)?);
418436

419437
if get_bool(&mut table, "available", path)? {
420-
Ok(Self {
421-
bins: Some(PackageBins {
422-
url: get_string(&mut table, "url", path)?,
423-
hash: get_string(&mut table, "hash", path)?,
424-
xz_url: get_string(&mut table, "xz_url", path).ok(),
425-
xz_hash: get_string(&mut table, "xz_hash", path).ok(),
426-
}),
427-
components,
428-
})
438+
let mut bins = Vec::new();
439+
for kind in COMPRESSION_KIND_PREFERENCE_ORDER.iter().copied() {
440+
let url_key = format!("{}url", kind.key_prefix());
441+
let hash_key = format!("{}hash", kind.key_prefix());
442+
let url = get_string(&mut table, &url_key, path).ok();
443+
let hash = get_string(&mut table, &hash_key, path).ok();
444+
if let (Some(url), Some(hash)) = (url, hash) {
445+
bins.push((kind, HashedBinary { url, hash }));
446+
}
447+
}
448+
Ok(Self { bins, components })
429449
} else {
430450
Ok(Self {
431-
bins: None,
432-
components: vec![],
451+
bins: Vec::new(),
452+
components: Vec::new(),
433453
})
434454
}
435455
}
@@ -442,22 +462,22 @@ impl TargetedPackage {
442462
if !extensions.is_empty() {
443463
result.insert("extensions".to_owned(), toml::Value::Array(extensions));
444464
}
445-
if let Some(bins) = self.bins {
446-
result.insert("hash".to_owned(), toml::Value::String(bins.hash));
447-
result.insert("url".to_owned(), toml::Value::String(bins.url));
448-
if let (Some(xz_hash), Some(xz_url)) = (bins.xz_hash, bins.xz_url) {
449-
result.insert("xz_hash".to_owned(), toml::Value::String(xz_hash));
450-
result.insert("xz_url".to_owned(), toml::Value::String(xz_url));
465+
if self.bins.is_empty() {
466+
result.insert("available".to_owned(), toml::Value::Boolean(false));
467+
} else {
468+
for (kind, bin) in self.bins {
469+
let url_key = format!("{}url", kind.key_prefix());
470+
let hash_key = format!("{}hash", kind.key_prefix());
471+
result.insert(url_key, toml::Value::String(bin.url));
472+
result.insert(hash_key, toml::Value::String(bin.hash));
451473
}
452474
result.insert("available".to_owned(), toml::Value::Boolean(true));
453-
} else {
454-
result.insert("available".to_owned(), toml::Value::Boolean(false));
455475
}
456476
result
457477
}
458478

459479
pub fn available(&self) -> bool {
460-
self.bins.is_some()
480+
!self.bins.is_empty()
461481
}
462482

463483
fn toml_to_components(

src/dist/manifestation.rs

Lines changed: 17 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use crate::dist::component::{Components, Package, TarGzPackage, TarXzPackage, Tr
1111
use crate::dist::config::Config;
1212
use crate::dist::dist::{Profile, TargetTriple, DEFAULT_DIST_SERVER};
1313
use crate::dist::download::{DownloadCfg, File};
14-
use crate::dist::manifest::{Component, Manifest, TargetedPackage};
14+
use crate::dist::manifest::{Component, CompressionKind, Manifest, TargetedPackage};
1515
use crate::dist::notifications::*;
1616
use crate::dist::prefix::InstallPrefix;
1717
use crate::dist::temp;
@@ -22,11 +22,6 @@ use crate::utils::utils;
2222
pub const DIST_MANIFEST: &str = "multirust-channel-manifest.toml";
2323
pub const CONFIG_FILE: &str = "multirust-config.toml";
2424

25-
enum Format {
26-
Gz,
27-
Xz,
28-
}
29-
3025
#[derive(Debug)]
3126
pub struct Manifestation {
3227
installation: Components,
@@ -153,7 +148,7 @@ impl Manifestation {
153148
let altered = temp_cfg.dist_server != DEFAULT_DIST_SERVER;
154149

155150
// Download component packages and validate hashes
156-
let mut things_to_install: Vec<(Component, Format, File)> = Vec::new();
151+
let mut things_to_install: Vec<(Component, CompressionKind, File)> = Vec::new();
157152
let mut things_downloaded: Vec<String> = Vec::new();
158153
let components = update.components_urls_and_hashes(new_manifest)?;
159154

@@ -246,11 +241,11 @@ impl Manifestation {
246241
let reader =
247242
utils::FileReaderWithProgress::new_file(&installer_file, &notification_converter)?;
248243
let package: &dyn Package = match format {
249-
Format::Gz => {
244+
CompressionKind::GZip => {
250245
gz = TarGzPackage::new(reader, temp_cfg, Some(&notification_converter))?;
251246
&gz
252247
}
253-
Format::Xz => {
248+
CompressionKind::XZ => {
254249
xz = TarXzPackage::new(reader, temp_cfg, Some(&notification_converter))?;
255250
&xz
256251
}
@@ -683,28 +678,24 @@ impl Update {
683678
fn components_urls_and_hashes(
684679
&self,
685680
new_manifest: &Manifest,
686-
) -> Result<Vec<(Component, Format, String, String)>> {
681+
) -> Result<Vec<(Component, CompressionKind, String, String)>> {
687682
let mut components_urls_and_hashes = Vec::new();
688683
for component in &self.components_to_install {
689684
let package = new_manifest.get_package(&component.short_name_in_manifest())?;
690685
let target_package = package.get_target(component.target.as_ref())?;
691686

692-
let bins = match target_package.bins {
693-
None => continue,
694-
Some(ref bins) => bins,
695-
};
696-
let c_u_h = if let (Some(url), Some(hash)) = (bins.xz_url.clone(), bins.xz_hash.clone())
697-
{
698-
(component.clone(), Format::Xz, url, hash)
699-
} else {
700-
(
701-
component.clone(),
702-
Format::Gz,
703-
bins.url.clone(),
704-
bins.hash.clone(),
705-
)
706-
};
707-
components_urls_and_hashes.push(c_u_h);
687+
if target_package.bins.is_empty() {
688+
// This package is not available, no files to download.
689+
continue;
690+
}
691+
// We prefer the first format in the list, since the parsing of the
692+
// manifest leaves us with the files/hash pairs in preference order.
693+
components_urls_and_hashes.push((
694+
component.clone(),
695+
target_package.bins[0].0,
696+
target_package.bins[0].1.url.clone(),
697+
target_package.bins[0].1.hash.clone(),
698+
));
708699
}
709700

710701
Ok(components_urls_and_hashes)

tests/cli-v2.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1051,7 +1051,7 @@ fn make_component_unavailable(config: &Config, name: &str, target: &str) {
10511051
let std_pkg = manifest.packages.get_mut(name).unwrap();
10521052
let target = TargetTriple::new(target);
10531053
let target_pkg = std_pkg.targets.get_mut(&target).unwrap();
1054-
target_pkg.bins = None;
1054+
target_pkg.bins = Vec::new();
10551055
}
10561056
let manifest_str = manifest.stringify();
10571057
rustup::utils::raw::write_file(&manifest_path, &manifest_str).unwrap();

tests/dist_manifest.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,8 @@ fn parse_smoke_test() {
2727
.get_target(Some(&x86_64_unknown_linux_gnu))
2828
.unwrap();
2929
assert_eq!(rust_target_pkg.available(), true);
30-
assert_eq!(rust_target_pkg.bins.clone().unwrap().url, "example.com");
31-
assert_eq!(rust_target_pkg.bins.clone().unwrap().hash, "...");
30+
assert_eq!(rust_target_pkg.bins[0].1.url, "example.com");
31+
assert_eq!(rust_target_pkg.bins[0].1.hash, "...");
3232

3333
let component = &rust_target_pkg.components[0];
3434
assert_eq!(component.short_name_in_manifest(), "rustc");
@@ -42,7 +42,7 @@ fn parse_smoke_test() {
4242
let docs_target_pkg = docs_pkg
4343
.get_target(Some(&x86_64_unknown_linux_gnu))
4444
.unwrap();
45-
assert_eq!(docs_target_pkg.bins.clone().unwrap().url, "example.com");
45+
assert_eq!(docs_target_pkg.bins[0].1.url, "example.com");
4646
}
4747

4848
#[test]

0 commit comments

Comments
 (0)