Skip to content

Commit 9b2250c

Browse files
committed
compression: Refactor handling of compression formats
In preparation for adding zstd support to rustup, this rework means that we treat compression formats we have available (and know) generically without breaking if unexpected formats are present, or if no format we know is present. Signed-off-by: Daniel Silverstone <dsilvers@digital-scurf.org>
1 parent 3c8f954 commit 9b2250c

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)