diff --git a/src/cli/rustup_mode.rs b/src/cli/rustup_mode.rs index e1a88270ff..d03cbdc8eb 100644 --- a/src/cli/rustup_mode.rs +++ b/src/cli/rustup_mode.rs @@ -900,7 +900,11 @@ fn target_add(cfg: &Cfg, m: &ArgMatches<'_>) -> Result<()> { } for target in &targets { - let new_component = Component::new("rust-std".to_string(), Some(TargetTriple::new(target))); + let new_component = Component::new( + "rust-std".to_string(), + Some(TargetTriple::new(target)), + false, + ); toolchain.add_component(new_component)?; } @@ -911,7 +915,11 @@ fn target_remove(cfg: &Cfg, m: &ArgMatches<'_>) -> Result<()> { let toolchain = explicit_or_dir_toolchain(cfg, m)?; for target in m.values_of("target").expect("") { - let new_component = Component::new("rust-std".to_string(), Some(TargetTriple::new(target))); + let new_component = Component::new( + "rust-std".to_string(), + Some(TargetTriple::new(target)), + false, + ); toolchain.remove_component(new_component)?; } @@ -940,7 +948,7 @@ fn component_add(cfg: &Cfg, m: &ArgMatches<'_>) -> Result<()> { }); for component in m.values_of("component").expect("") { - let new_component = Component::new(component.to_string(), target.clone()); + let new_component = Component::new(component.to_string(), target.clone(), true); toolchain.add_component(new_component)?; } @@ -959,7 +967,7 @@ fn component_remove(cfg: &Cfg, m: &ArgMatches<'_>) -> Result<()> { }); for component in m.values_of("component").expect("") { - let new_component = Component::new(component.to_string(), target.clone()); + let new_component = Component::new(component.to_string(), target.clone(), true); toolchain.remove_component(new_component)?; } diff --git a/src/dist/config.rs b/src/dist/config.rs index 19c20629d7..a50146e7eb 100644 --- a/src/dist/config.rs +++ b/src/dist/config.rs @@ -67,7 +67,7 @@ impl Config { for (i, v) in arr.into_iter().enumerate() { if let toml::Value::Table(t) = v { let path = format!("{}[{}]", path, i); - result.push(Component::from_toml(t, &path)?); + result.push(Component::from_toml(t, &path, false)?); } } diff --git a/src/dist/dist.rs b/src/dist/dist.rs index 7baeea944f..347fafaa80 100644 --- a/src/dist/dist.rs +++ b/src/dist/dist.rs @@ -1,5 +1,4 @@ use crate::dist::download::DownloadCfg; -use crate::dist::manifest::Component; use crate::dist::manifest::Manifest as ManifestV2; use crate::dist::manifestation::{Changes, Manifestation, UpdateStatus}; use crate::dist::notifications::*; @@ -490,14 +489,6 @@ impl Profile { pub fn default_name() -> &'static str { "default" } - - // Non-required components that were required before profiles exist. - pub fn legacy_profile() -> Vec { - ["rust-std", "rustc", "cargo", "rust-docs"] - .into_iter() - .map(|s| (*s).to_owned()) - .collect() - } } impl Default for Profile { @@ -619,27 +610,13 @@ fn update_from_dist_<'a>( m.get_rust_version().ok(), )); - let add_components = profile - .and_then(|profile| { - m.get_profile_components(profile, &toolchain.target) - .ok() - .map(|v| { - v.iter() - .map(|name| { - Component::new(name.to_owned(), Some(toolchain.target.clone())) - }) - .collect::>() - }) - }) - .unwrap_or_else(|| { - Profile::legacy_profile() - .into_iter() - .map(|s| Component::new(s, Some(toolchain.target.clone()))) - .collect() - }); + let implicit_add_components = match profile { + Some(profile) => m.get_profile_components(profile, &toolchain.target)?, + None => Vec::new(), + }; let changes = Changes { - implicit_add_components: add_components, + implicit_add_components, explicit_add_components: Vec::new(), remove_components: Vec::new(), }; diff --git a/src/dist/manifest.rs b/src/dist/manifest.rs index 91c83226e5..f50d411cfc 100644 --- a/src/dist/manifest.rs +++ b/src/dist/manifest.rs @@ -55,10 +55,19 @@ pub struct PackageBins { pub xz_hash: Option, } -#[derive(Clone, Debug, Eq, PartialEq, Ord, PartialOrd, Hash)] +#[derive(Clone, Debug, Eq, Ord, PartialOrd, Hash)] pub struct Component { pkg: String, pub target: Option, + // Older Rustup distinguished between components (which are essential) and + // extensions (which are not). + is_extension: bool, +} + +impl PartialEq for Component { + fn eq(&self, other: &Component) -> bool { + self.pkg == other.pkg && self.target == other.target + } } impl Manifest { @@ -165,7 +174,10 @@ impl Manifest { path: &str, ) -> Result>> { let mut result = HashMap::new(); - let profile_table = get_table(table, "profiles", path)?; + let profile_table = match get_table(table, "profiles", path) { + Ok(t) => t, + Err(_) => return Ok(result), + }; for (k, v) in profile_table { if let toml::Value::Array(a) = v { @@ -201,11 +213,29 @@ impl Manifest { self.get_package("rust").map(|p| &*p.version) } + pub fn get_legacy_components(&self, target: &TargetTriple) -> Result> { + // Build a profile from the components/extensions. + let result = self + .get_package("rust")? + .get_target(Some(target))? + .components + .iter() + .filter(|c| !c.is_extension && c.target.as_ref().map(|t| t == target).unwrap_or(true)) + .map(|c| c.clone()) + .collect(); + + return Ok(result); + } pub fn get_profile_components( &self, profile: Profile, target: &TargetTriple, - ) -> Result> { + ) -> Result> { + // An older manifest with no profiles section. + if self.profiles.is_empty() { + return self.get_legacy_components(target); + } + let profile = self .profiles .get(&profile) @@ -214,8 +244,13 @@ impl Manifest { let rust_pkg = self.get_package("rust")?.get_target(Some(target))?; let result = profile .into_iter() - .filter(|s| rust_pkg.components.iter().any(|c| &c.pkg == *s)) - .map(|s| s.to_owned()) + .filter(|s| { + rust_pkg + .components + .iter() + .any(|c| &c.pkg == *s && c.target.as_ref().map(|t| t == target).unwrap_or(true)) + }) + .map(|s| Component::new(s.to_owned(), Some(target.clone()), false)) .collect(); Ok(result) } @@ -357,10 +392,11 @@ impl TargetedPackage { let extensions = get_array(&mut table, "extensions", path)?; let mut components = - Self::toml_to_components(components, &format!("{}{}.", path, "components"))?; + Self::toml_to_components(components, &format!("{}{}.", path, "components"), false)?; components.append(&mut Self::toml_to_components( extensions, &format!("{}{}.", path, "extensions"), + true, )?); if get_bool(&mut table, "available", path)? { @@ -381,11 +417,14 @@ impl TargetedPackage { } } pub fn into_toml(self) -> toml::value::Table { - let components = Self::components_to_toml(self.components); let mut result = toml::value::Table::new(); + let (components, extensions) = Self::components_to_toml(self.components); if !components.is_empty() { result.insert("components".to_owned(), toml::Value::Array(components)); } + if !extensions.is_empty() { + result.insert("extensions".to_owned(), toml::Value::Array(extensions)); + } if let Some(bins) = self.bins.clone() { result.insert("hash".to_owned(), toml::Value::String(bins.hash)); result.insert("url".to_owned(), toml::Value::String(bins.url)); @@ -404,38 +443,56 @@ impl TargetedPackage { self.bins.is_some() } - fn toml_to_components(arr: toml::value::Array, path: &str) -> Result> { + fn toml_to_components( + arr: toml::value::Array, + path: &str, + is_extension: bool, + ) -> Result> { let mut result = Vec::new(); for (i, v) in arr.into_iter().enumerate() { if let toml::Value::Table(t) = v { let path = format!("{}[{}]", path, i); - result.push(Component::from_toml(t, &path)?); + result.push(Component::from_toml(t, &path, is_extension)?); } } Ok(result) } - fn components_to_toml(components: Vec) -> toml::value::Array { - let mut result = toml::value::Array::new(); - for v in components { - result.push(toml::Value::Table(v.into_toml())); + fn components_to_toml(data: Vec) -> (toml::value::Array, toml::value::Array) { + let mut components = toml::value::Array::new(); + let mut extensions = toml::value::Array::new(); + for v in data { + if v.is_extension { + extensions.push(toml::Value::Table(v.into_toml())); + } else { + components.push(toml::Value::Table(v.into_toml())); + } } - result + (components, extensions) } } impl Component { - pub fn new(pkg: String, target: Option) -> Component { - Component { pkg, target } + pub fn new(pkg: String, target: Option, is_extension: bool) -> Component { + Component { + pkg, + target, + is_extension, + } } pub fn wildcard(&self) -> Component { Component { pkg: self.pkg.clone(), target: None, + is_extension: false, } } - pub fn from_toml(mut table: toml::value::Table, path: &str) -> Result { + pub fn from_toml( + mut table: toml::value::Table, + path: &str, + is_extension: bool, + ) -> Result { Ok(Component { pkg: get_string(&mut table, "pkg", path)?, target: get_string(&mut table, "target", path).map(|s| { @@ -445,6 +502,7 @@ impl Component { Some(TargetTriple::new(&s)) } })?, + is_extension, }) } pub fn into_toml(self) -> toml::value::Table { diff --git a/src/dist/manifestation.rs b/src/dist/manifestation.rs index 367263e0c6..003691814d 100644 --- a/src/dist/manifestation.rs +++ b/src/dist/manifestation.rs @@ -124,8 +124,8 @@ impl Manifestation { let update = Update::build_update(self, new_manifest, &changes, &config, notify_handler)?; if update.nothing_changes() { - // TODO changes and ,manifest are empty? - eprintln!("update: {:?}", update); + // TODO + eprintln!("no changes: {:?} {:?}", update, config); return Ok(UpdateStatus::Unchanged); } @@ -488,10 +488,16 @@ impl Update { changes.check_invariants(&config); // The list of components already installed, empty if a new install - let starting_list = config - .as_ref() - .map(|c| c.components.clone()) - .unwrap_or_default(); + let installed_components = manifestation.installation.list()?; + let looks_like_v1 = config.is_none() && !installed_components.is_empty(); + let starting_list = if looks_like_v1 { + new_manifest.get_legacy_components(&manifestation.target_triple)? + } else { + config + .as_ref() + .map(|c| c.components.clone()) + .unwrap_or_default() + }; let mut result = Update { components_to_uninstall: vec![], diff --git a/tests/cli-v2.rs b/tests/cli-v2.rs index 9a42d9b49b..39ede7f593 100644 --- a/tests/cli-v2.rs +++ b/tests/cli-v2.rs @@ -473,6 +473,7 @@ fn upgrade_v1_to_v2() { // Delete the v2 manifest so the first day we install from the v1s fs::remove_file(config.distdir.join("dist/channel-rust-nightly.toml.sha256")).unwrap(); expect_ok(config, &["rustup", "default", "nightly"]); + expect_stdout_ok(config, &["rustc", "--version"], "hash-n-1"); set_current_dist_date(config, "2015-01-02"); expect_ok(config, &["rustup", "update", "nightly", "--no-self-update"]); expect_stdout_ok(config, &["rustc", "--version"], "hash-n-2"); diff --git a/tests/dist.rs b/tests/dist.rs index 514b942c7a..0d27a5a699 100644 --- a/tests/dist.rs +++ b/tests/dist.rs @@ -61,26 +61,32 @@ pub fn create_mock_channel( MockComponent { name: "rustc".to_string(), target: "x86_64-apple-darwin".to_string(), + is_extension: false, }, MockComponent { name: "cargo".to_string(), target: "x86_64-apple-darwin".to_string(), + is_extension: false, }, MockComponent { name: "rust-std".to_string(), target: "x86_64-apple-darwin".to_string(), + is_extension: false, }, MockComponent { name: "rust-docs".to_string(), target: "x86_64-apple-darwin".to_string(), + is_extension: false, }, MockComponent { name: "rust-std".to_string(), target: "i686-apple-darwin".to_string(), + is_extension: false, }, MockComponent { name: "rust-std".to_string(), target: "i686-unknown-linux-gnu".to_string(), + is_extension: false, }, ], installer: MockInstallerBuilder { components: vec![] }, @@ -92,18 +98,22 @@ pub fn create_mock_channel( MockComponent { name: "rustc".to_string(), target: "i686-apple-darwin".to_string(), + is_extension: false, }, MockComponent { name: "cargo".to_string(), target: "i686-apple-darwin".to_string(), + is_extension: false, }, MockComponent { name: "rust-std".to_string(), target: "i686-apple-darwin".to_string(), + is_extension: false, }, MockComponent { name: "rust-docs".to_string(), target: "i686-apple-darwin".to_string(), + is_extension: false, }, ], installer: MockInstallerBuilder { components: vec![] }, @@ -302,6 +312,7 @@ fn rename_component() { tpkg.components.push(MockComponent { name: "bonus".to_string(), target: "x86_64-apple-darwin".to_string(), + is_extension: true, }); }; let edit_2 = &|_: &str, pkgs: &mut Vec| { @@ -313,6 +324,7 @@ fn rename_component() { tpkg.components.push(MockComponent { name: "bobo".to_string(), target: "x86_64-apple-darwin".to_string(), + is_extension: true, }); }; @@ -338,6 +350,7 @@ fn rename_component() { let adds = [Component::new( "bonus".to_string(), Some(TargetTriple::new("x86_64-apple-darwin")), + true, )]; change_channel_date(url, "nightly", "2016-02-01"); @@ -382,6 +395,7 @@ fn rename_component_new() { let adds = [Component::new( "bobo".to_string(), Some(TargetTriple::new("x86_64-apple-darwin")), + true, )]; // Install the basics from day 1 change_channel_date(url, "nightly", "2016-02-01"); @@ -426,11 +440,7 @@ fn update_from_dist( let trip = toolchain.target.clone(); let manifestation = Manifestation::open(prefix.clone(), trip.clone())?; - let implicit_components = manifest - .get_profile_components(Profile::Default, &trip)? - .iter() - .map(|s| Component::new(s.clone(), Some(trip.clone()))) - .collect::>(); + let implicit_components = manifest.get_profile_components(Profile::Default, &trip)?; let changes = Changes { explicit_add_components: add.to_owned(), @@ -609,6 +619,7 @@ fn unavailable_component() { tpkg.components.push(MockComponent { name: "bonus".to_string(), target: "x86_64-apple-darwin".to_string(), + is_extension: true, }); } @@ -629,6 +640,7 @@ fn unavailable_component() { let adds = [Component::new( "bonus".to_string(), Some(TargetTriple::new("x86_64-apple-darwin")), + true, )]; change_channel_date(url, "nightly", "2016-02-01"); @@ -661,6 +673,7 @@ fn removed_component() { tpkg.components.push(MockComponent { name: "bonus".to_string(), target: "x86_64-apple-darwin".to_string(), + is_extension: true, }); } else { pkgs.retain(|p| p.name != "bonus"); @@ -674,6 +687,7 @@ fn removed_component() { let adds = [Component::new( "bonus".to_string(), Some(TargetTriple::new("x86_64-apple-darwin")), + true, )]; // Update with bonus. @@ -702,10 +716,12 @@ fn update_preserves_extensions() { Component::new( "rust-std".to_string(), Some(TargetTriple::new("i686-apple-darwin")), + false, ), Component::new( "rust-std".to_string(), Some(TargetTriple::new("i686-unknown-linux-gnu")), + false, ), ]; @@ -758,10 +774,12 @@ fn add_extensions_for_initial_install() { Component::new( "rust-std".to_string(), Some(TargetTriple::new("i686-apple-darwin")), + false, ), Component::new( "rust-std".to_string(), Some(TargetTriple::new("i686-unknown-linux-gnu")), + false, ), ]; @@ -788,10 +806,12 @@ fn add_extensions_for_same_manifest() { Component::new( "rust-std".to_string(), Some(TargetTriple::new("i686-apple-darwin")), + false, ), Component::new( "rust-std".to_string(), Some(TargetTriple::new("i686-unknown-linux-gnu")), + false, ), ]; @@ -823,10 +843,12 @@ fn add_extensions_for_upgrade() { Component::new( "rust-std".to_string(), Some(TargetTriple::new("i686-apple-darwin")), + false, ), Component::new( "rust-std".to_string(), Some(TargetTriple::new("i686-unknown-linux-gnu")), + false, ), ]; @@ -852,6 +874,7 @@ fn add_extension_not_in_manifest() { let adds = vec![Component::new( "rust-bogus".to_string(), Some(TargetTriple::new("i686-apple-darwin")), + true, )]; update_from_dist(url, toolchain, prefix, &adds, &[], download_cfg, temp_cfg).unwrap(); @@ -869,6 +892,7 @@ fn add_extension_that_is_required_component() { let adds = vec![Component::new( "rustc".to_string(), Some(TargetTriple::new("x86_64-apple-darwin")), + false, )]; update_from_dist(url, toolchain, prefix, &adds, &[], download_cfg, temp_cfg).unwrap(); @@ -895,6 +919,7 @@ fn add_extensions_does_not_remove_other_components() { let adds = vec![Component::new( "rust-std".to_string(), Some(TargetTriple::new("i686-apple-darwin")), + false, )]; update_from_dist(url, toolchain, prefix, &adds, &[], download_cfg, temp_cfg).unwrap(); @@ -915,6 +940,7 @@ fn remove_extensions_for_initial_install() { let removes = vec![Component::new( "rustc".to_string(), Some(TargetTriple::new("x86_64-apple-darwin")), + false, )]; update_from_dist( @@ -941,10 +967,12 @@ fn remove_extensions_for_same_manifest() { Component::new( "rust-std".to_string(), Some(TargetTriple::new("i686-apple-darwin")), + false, ), Component::new( "rust-std".to_string(), Some(TargetTriple::new("i686-unknown-linux-gnu")), + false, ), ]; @@ -953,6 +981,7 @@ fn remove_extensions_for_same_manifest() { let removes = vec![Component::new( "rust-std".to_string(), Some(TargetTriple::new("i686-apple-darwin")), + false, )]; update_from_dist( @@ -988,10 +1017,12 @@ fn remove_extensions_for_upgrade() { Component::new( "rust-std".to_string(), Some(TargetTriple::new("i686-apple-darwin")), + false, ), Component::new( "rust-std".to_string(), Some(TargetTriple::new("i686-unknown-linux-gnu")), + false, ), ]; @@ -1002,6 +1033,7 @@ fn remove_extensions_for_upgrade() { let removes = vec![Component::new( "rust-std".to_string(), Some(TargetTriple::new("i686-apple-darwin")), + false, )]; update_from_dist( @@ -1041,6 +1073,7 @@ fn remove_extension_not_in_manifest() { let removes = vec![Component::new( "rust-bogus".to_string(), Some(TargetTriple::new("i686-apple-darwin")), + true, )]; update_from_dist( @@ -1070,6 +1103,7 @@ fn remove_extension_not_in_manifest_but_is_already_installed() { tpkg.components.push(MockComponent { name: "bonus".to_string(), target: "x86_64-apple-darwin".to_string(), + is_extension: true, }); } else { pkgs.retain(|p| p.name != "bonus"); @@ -1084,6 +1118,7 @@ fn remove_extension_not_in_manifest_but_is_already_installed() { let ref adds = vec![Component::new( "bonus".to_string(), Some(TargetTriple::new("x86_64-apple-darwin")), + true, )]; update_from_dist(url, toolchain, prefix, &adds, &[], download_cfg, temp_cfg).unwrap(); assert!(utils::path_exists(&prefix.path().join("bin/bonus"))); @@ -1093,6 +1128,7 @@ fn remove_extension_not_in_manifest_but_is_already_installed() { let removes = vec![Component::new( "bonus".to_string(), Some(TargetTriple::new("x86_64-apple-darwin")), + true, )]; update_from_dist( url, @@ -1121,6 +1157,7 @@ fn remove_extension_that_is_required_component() { let removes = vec![Component::new( "rustc".to_string(), Some(TargetTriple::new("x86_64-apple-darwin")), + false, )]; update_from_dist( @@ -1149,6 +1186,7 @@ fn remove_extension_not_installed() { let removes = vec![Component::new( "rust-std".to_string(), Some(TargetTriple::new("i686-apple-darwin")), + false, )]; update_from_dist( @@ -1178,6 +1216,7 @@ fn remove_extensions_does_not_remove_other_components() { let adds = vec![Component::new( "rust-std".to_string(), Some(TargetTriple::new("i686-apple-darwin")), + false, )]; update_from_dist(url, toolchain, prefix, &adds, &[], download_cfg, temp_cfg).unwrap(); @@ -1185,6 +1224,7 @@ fn remove_extensions_does_not_remove_other_components() { let removes = vec![Component::new( "rust-std".to_string(), Some(TargetTriple::new("i686-apple-darwin")), + false, )]; update_from_dist( @@ -1214,6 +1254,7 @@ fn add_and_remove_for_upgrade() { let adds = vec![Component::new( "rust-std".to_string(), Some(TargetTriple::new("i686-unknown-linux-gnu")), + false, )]; update_from_dist(url, toolchain, prefix, &adds, &[], download_cfg, temp_cfg).unwrap(); @@ -1223,11 +1264,13 @@ fn add_and_remove_for_upgrade() { let adds = vec![Component::new( "rust-std".to_string(), Some(TargetTriple::new("i686-apple-darwin")), + false, )]; let removes = vec![Component::new( "rust-std".to_string(), Some(TargetTriple::new("i686-unknown-linux-gnu")), + false, )]; update_from_dist( @@ -1260,6 +1303,7 @@ fn add_and_remove() { let adds = vec![Component::new( "rust-std".to_string(), Some(TargetTriple::new("i686-unknown-linux-gnu")), + false, )]; update_from_dist(url, toolchain, prefix, &adds, &[], download_cfg, temp_cfg).unwrap(); @@ -1267,11 +1311,13 @@ fn add_and_remove() { let adds = vec![Component::new( "rust-std".to_string(), Some(TargetTriple::new("i686-apple-darwin")), + false, )]; let removes = vec![Component::new( "rust-std".to_string(), Some(TargetTriple::new("i686-unknown-linux-gnu")), + false, )]; update_from_dist( @@ -1307,11 +1353,13 @@ fn add_and_remove_same_component() { let adds = vec![Component::new( "rust-std".to_string(), Some(TargetTriple::new("i686-apple-darwin")), + false, )]; let removes = vec![Component::new( "rust-std".to_string(), Some(TargetTriple::new("i686-apple_darwin")), + false, )]; update_from_dist( diff --git a/tests/mock/clitools.rs b/tests/mock/clitools.rs index 78cee24a2c..46f117a49f 100644 --- a/tests/mock/clitools.rs +++ b/tests/mock/clitools.rs @@ -595,45 +595,55 @@ fn build_mock_channel( target_pkg.components.push(MockComponent { name: "rust-std".to_string(), target: target.to_string(), + is_extension: false, }); target_pkg.components.push(MockComponent { name: "rustc".to_string(), target: target.to_string(), + is_extension: false, }); target_pkg.components.push(MockComponent { name: "cargo".to_string(), target: target.to_string(), + is_extension: false, }); target_pkg.components.push(MockComponent { name: "rust-docs".to_string(), target: target.to_string(), + is_extension: false, }); if rename_rls { target_pkg.components.push(MockComponent { name: "rls-preview".to_string(), target: target.to_string(), + is_extension: true, }); } else { target_pkg.components.push(MockComponent { name: "rls".to_string(), target: target.to_string(), + is_extension: true, }); } target_pkg.components.push(MockComponent { name: "rust-std".to_string(), target: CROSS_ARCH1.to_string(), + is_extension: false, }); target_pkg.components.push(MockComponent { name: "rust-std".to_string(), target: CROSS_ARCH2.to_string(), + is_extension: false, }); target_pkg.components.push(MockComponent { name: "rust-src".to_string(), target: "*".to_string(), + is_extension: true, }); target_pkg.components.push(MockComponent { name: "rust-analysis".to_string(), target: target.to_string(), + is_extension: true, }); } } diff --git a/tests/mock/dist.rs b/tests/mock/dist.rs index 255b2d2547..776fa98f09 100644 --- a/tests/mock/dist.rs +++ b/tests/mock/dist.rs @@ -101,6 +101,7 @@ pub struct MockTargetedPackage { pub struct MockComponent { pub name: String, pub target: String, + pub is_extension: bool, } #[derive(Clone)] @@ -151,6 +152,7 @@ impl MockDistServer { let component = MockComponent { name: package.name.to_string(), target: target_package.target.to_string(), + is_extension: false, }; hashes.insert( component, @@ -330,6 +332,7 @@ impl MockDistServer { let component = MockComponent { name: package.name.to_owned(), target: target.target.to_owned(), + is_extension: false, }; let hash = hashes[&component].clone(); toml_target.insert(String::from("hash"), toml::Value::String(hash.gz)); @@ -342,8 +345,9 @@ impl MockDistServer { toml_target.insert(String::from("xz_hash"), toml::Value::String(xz_hash)); } - // [pkg.*.target.*.components.*] + // [pkg.*.target.*.components.*] and [pkg.*.target.*.extensions.*] let mut toml_components = toml::value::Array::new(); + let mut toml_extensions = toml::value::Array::new(); for component in &target.components { let mut toml_component = toml::value::Table::new(); toml_component.insert( @@ -354,12 +358,20 @@ impl MockDistServer { String::from("target"), toml::Value::String(component.target.to_owned()), ); - toml_components.push(toml::Value::Table(toml_component)); + if component.is_extension { + toml_extensions.push(toml::Value::Table(toml_component)); + } else { + toml_components.push(toml::Value::Table(toml_component)); + } } toml_target.insert( String::from("components"), toml::Value::Array(toml_components), ); + toml_target.insert( + String::from("extensions"), + toml::Value::Array(toml_extensions), + ); toml_targets.insert(target.target.clone(), toml::Value::Table(toml_target)); }