Skip to content

Commit 5a91e33

Browse files
authored
Merge pull request #1419 from pietroalbini/skip-missing-components
Remove components if they don't exist anymore during an update
2 parents 027ac51 + bd5ac16 commit 5a91e33

File tree

3 files changed

+104
-38
lines changed

3 files changed

+104
-38
lines changed

src/rustup-dist/src/manifestation.rs

+10-1
Original file line numberDiff line numberDiff line change
@@ -475,6 +475,7 @@ impl Update {
475475
rust_target_package,
476476
new_manifest,
477477
&changes,
478+
notify_handler,
478479
);
479480

480481
// If this is a full upgrade then the list of components to
@@ -520,6 +521,7 @@ impl Update {
520521
rust_target_package: &TargetedPackage,
521522
new_manifest: &Manifest,
522523
changes: &Changes,
524+
notify_handler: &Fn(Notification),
523525
) {
524526
// Add components required by the package, according to the
525527
// manifest
@@ -559,7 +561,14 @@ impl Update {
559561
if component_is_present {
560562
self.final_component_list.push(existing_component.clone());
561563
} else {
562-
self.missing_components.push(existing_component.clone());
564+
// If a component is not available anymore for the target remove it
565+
// This prevents errors when trying to update to a newer version with
566+
// a removed component.
567+
self.components_to_uninstall.push(existing_component.clone());
568+
notify_handler(Notification::ComponentUnavailable(
569+
&existing_component.pkg,
570+
existing_component.target.as_ref(),
571+
));
563572
}
564573
}
565574
}

src/rustup-dist/src/notifications.rs

+10-1
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ pub enum Notification<'a> {
3131
DownloadedManifest(&'a str, Option<&'a str>),
3232
DownloadingLegacyManifest,
3333
ManifestChecksumFailedHack,
34+
ComponentUnavailable(&'a str, Option<&'a TargetTriple>),
3435
}
3536

3637
impl<'a> From<rustup_utils::Notification<'a>> for Notification<'a> {
@@ -68,7 +69,8 @@ impl<'a> Notification<'a> {
6869
CantReadUpdateHash(_)
6970
| ExtensionNotInstalled(_)
7071
| MissingInstalledComponent(_)
71-
| CachedFileChecksumFailed => NotificationLevel::Warn,
72+
| CachedFileChecksumFailed
73+
| ComponentUnavailable(_, _) => NotificationLevel::Warn,
7274
NonFatalError(_) => NotificationLevel::Error,
7375
}
7476
}
@@ -132,6 +134,13 @@ impl<'a> Display for Notification<'a> {
132134
ManifestChecksumFailedHack => {
133135
write!(f, "update not yet available, sorry! try again later")
134136
}
137+
ComponentUnavailable(pkg, toolchain) => {
138+
if let Some(tc) = toolchain {
139+
write!(f, "component '{}' is not available anymore on target '{}'", pkg, tc)
140+
} else {
141+
write!(f, "component '{}' is not available anymore", pkg)
142+
}
143+
}
135144
}
136145
}
137146
}

src/rustup-dist/tests/dist.rs

+84-36
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ use tempdir::TempDir;
3737
// Creates a mock dist server populated with some test data
3838
pub fn create_mock_dist_server(
3939
path: &Path,
40-
edit: Option<&Fn(&str, &mut MockPackage)>,
40+
edit: Option<&Fn(&str, &mut [MockPackage])>,
4141
) -> MockDistServer {
4242
MockDistServer {
4343
path: path.to_owned(),
@@ -51,7 +51,7 @@ pub fn create_mock_dist_server(
5151
pub fn create_mock_channel(
5252
channel: &str,
5353
date: &str,
54-
edit: Option<&Fn(&str, &mut MockPackage)>,
54+
edit: Option<&Fn(&str, &mut [MockPackage])>,
5555
) -> MockChannel {
5656
// Put the date in the files so they can be differentiated
5757
let contents = Arc::new(date.as_bytes().to_vec());
@@ -209,7 +209,7 @@ pub fn create_mock_channel(
209209
packages.push(bonus_component("bonus", contents.clone()));
210210

211211
if let Some(edit) = edit {
212-
edit(date, &mut packages[0]);
212+
edit(date, &mut packages);
213213
}
214214

215215
MockChannel {
@@ -289,8 +289,8 @@ fn rename_component() {
289289
let dist_tempdir = TempDir::new("rustup").unwrap();
290290
let ref url = Url::parse(&format!("file://{}", dist_tempdir.path().to_string_lossy())).unwrap();
291291

292-
let edit_1 = &|_: &str, pkg: &mut MockPackage| {
293-
let tpkg = pkg.targets
292+
let edit_1 = &|_: &str, pkgs: &mut [MockPackage]| {
293+
let tpkg = pkgs[0].targets
294294
.iter_mut()
295295
.find(|p| p.target == "x86_64-apple-darwin")
296296
.unwrap();
@@ -299,8 +299,8 @@ fn rename_component() {
299299
target: "x86_64-apple-darwin".to_string(),
300300
});
301301
};
302-
let edit_2 = &|_: &str, pkg: &mut MockPackage| {
303-
let tpkg = pkg.targets
302+
let edit_2 = &|_: &str, pkgs: &mut [MockPackage]| {
303+
let tpkg = pkgs[0].targets
304304
.iter_mut()
305305
.find(|p| p.target == "x86_64-apple-darwin")
306306
.unwrap();
@@ -347,8 +347,8 @@ fn rename_component_ignore() {
347347
let dist_tempdir = TempDir::new("rustup").unwrap();
348348
let ref url = Url::parse(&format!("file://{}", dist_tempdir.path().to_string_lossy())).unwrap();
349349

350-
let edit = &|_: &str, pkg: &mut MockPackage| {
351-
let tpkg = pkg.targets
350+
let edit = &|_: &str, pkgs: &mut [MockPackage]| {
351+
let tpkg = pkgs[0].targets
352352
.iter_mut()
353353
.find(|p| p.target == "x86_64-apple-darwin")
354354
.unwrap();
@@ -395,8 +395,8 @@ fn rename_component_new() {
395395
let dist_tempdir = TempDir::new("rustup").unwrap();
396396
let ref url = Url::parse(&format!("file://{}", dist_tempdir.path().to_string_lossy())).unwrap();
397397

398-
let edit_2 = &|_: &str, pkg: &mut MockPackage| {
399-
let tpkg = pkg.targets
398+
let edit_2 = &|_: &str, pkgs: &mut [MockPackage]| {
399+
let tpkg = pkgs[0].targets
400400
.iter_mut()
401401
.find(|p| p.target == "x86_64-apple-darwin")
402402
.unwrap();
@@ -526,7 +526,7 @@ fn uninstall(
526526
}
527527

528528
fn setup(
529-
edit: Option<&Fn(&str, &mut MockPackage)>,
529+
edit: Option<&Fn(&str, &mut [MockPackage])>,
530530
enable_xz: bool,
531531
f: &Fn(&Url, &ToolchainDesc, &InstallPrefix, &DownloadCfg, &temp::Cfg),
532532
) {
@@ -645,11 +645,12 @@ fn upgrade() {
645645
}
646646

647647
#[test]
648-
fn force_update() {
649-
// On day 1 install the 'bonus' component, on day 2 its no longer a component
650-
let edit = &|date: &str, pkg: &mut MockPackage| {
651-
if date == "2016-02-01" {
652-
let mut tpkg = pkg.targets
648+
fn unavailable_component() {
649+
// On day 2 the bonus component is no longer available
650+
let edit = &|date: &str, pkgs: &mut [MockPackage]| {
651+
// Require the bonus component every dat
652+
{
653+
let tpkg = pkgs[0].targets
653654
.iter_mut()
654655
.find(|p| p.target == "x86_64-apple-darwin")
655656
.unwrap();
@@ -658,6 +659,17 @@ fn force_update() {
658659
target: "x86_64-apple-darwin".to_string(),
659660
});
660661
}
662+
663+
// Mark the bonus package as unavailable in 2016-02-02
664+
if date == "2016-02-02" {
665+
let bonus_pkg = pkgs.iter_mut()
666+
.find(|p| p.name == "bonus")
667+
.unwrap();
668+
669+
for target in &mut bonus_pkg.targets {
670+
target.available = false;
671+
}
672+
}
661673
};
662674

663675
setup(
@@ -677,18 +689,54 @@ fn force_update() {
677689
ErrorKind::RequestedComponentsUnavailable(..) => {}
678690
_ => panic!(),
679691
}
680-
// Force update without bonus, should succeed, but bonus binary will be missing.
681-
update_from_dist_(
682-
url,
683-
toolchain,
684-
prefix,
685-
&[],
686-
&[],
687-
download_cfg,
688-
temp_cfg,
689-
true,
690-
).unwrap();
692+
},
693+
);
694+
}
695+
696+
#[test]
697+
fn removed_component() {
698+
// On day 1 install the 'bonus' component, on day 2 its no longer a component
699+
let edit = &|date: &str, pkgs: &mut [MockPackage]| {
700+
if date == "2016-02-01" {
701+
let tpkg = pkgs[0].targets
702+
.iter_mut()
703+
.find(|p| p.target == "x86_64-apple-darwin")
704+
.unwrap();
705+
tpkg.components.push(MockComponent {
706+
name: "bonus".to_string(),
707+
target: "x86_64-apple-darwin".to_string(),
708+
});
709+
}
710+
};
711+
712+
setup(
713+
Some(edit),
714+
false,
715+
&|url, toolchain, prefix, download_cfg, temp_cfg| {
716+
let received_notification = Arc::new(Cell::new(false));
717+
718+
let download_cfg = DownloadCfg {
719+
dist_root: download_cfg.dist_root,
720+
temp_cfg: download_cfg.temp_cfg,
721+
download_dir: download_cfg.download_dir,
722+
notify_handler: &|n| {
723+
if let Notification::ComponentUnavailable("bonus", Some(_)) = n {
724+
received_notification.set(true);
725+
}
726+
},
727+
};
728+
729+
change_channel_date(url, "nightly", "2016-02-01");
730+
// Update with bonus.
731+
update_from_dist(url, toolchain, prefix, &[], &[], &download_cfg, temp_cfg).unwrap();
732+
assert!(utils::path_exists(&prefix.path().join("bin/bonus")));
733+
change_channel_date(url, "nightly", "2016-02-02");
734+
735+
// Update without bonus, should emit a notify and remove the bonus component
736+
update_from_dist(url, toolchain, prefix, &[], &[], &download_cfg, temp_cfg).unwrap();
691737
assert!(!utils::path_exists(&prefix.path().join("bin/bonus")));
738+
739+
assert!(received_notification.get());
692740
},
693741
);
694742
}
@@ -735,9 +783,9 @@ fn update_preserves_extensions() {
735783

736784
#[test]
737785
fn update_preserves_extensions_that_became_components() {
738-
let edit = &|date: &str, pkg: &mut MockPackage| {
786+
let edit = &|date: &str, pkgs: &mut [MockPackage]| {
739787
if date == "2016-02-01" {
740-
let mut tpkg = pkg.targets
788+
let tpkg = pkgs[0].targets
741789
.iter_mut()
742790
.find(|p| p.target == "x86_64-apple-darwin")
743791
.unwrap();
@@ -747,7 +795,7 @@ fn update_preserves_extensions_that_became_components() {
747795
});
748796
}
749797
if date == "2016-02-02" {
750-
let mut tpkg = pkg.targets
798+
let tpkg = pkgs[0].targets
751799
.iter_mut()
752800
.find(|p| p.target == "x86_64-apple-darwin")
753801
.unwrap();
@@ -782,9 +830,9 @@ fn update_preserves_extensions_that_became_components() {
782830

783831
#[test]
784832
fn update_preserves_components_that_became_extensions() {
785-
let edit = &|date: &str, pkg: &mut MockPackage| {
833+
let edit = &|date: &str, pkgs: &mut [MockPackage]| {
786834
if date == "2016-02-01" {
787-
let mut tpkg = pkg.targets
835+
let tpkg = pkgs[0].targets
788836
.iter_mut()
789837
.find(|p| p.target == "x86_64-apple-darwin")
790838
.unwrap();
@@ -794,7 +842,7 @@ fn update_preserves_components_that_became_extensions() {
794842
});
795843
}
796844
if date == "2016-02-02" {
797-
let mut tpkg = pkg.targets
845+
let tpkg = pkgs[0].targets
798846
.iter_mut()
799847
.find(|p| p.target == "x86_64-apple-darwin")
800848
.unwrap();
@@ -1127,9 +1175,9 @@ fn remove_extension_not_in_manifest() {
11271175
#[test]
11281176
#[should_panic]
11291177
fn remove_extension_not_in_manifest_but_is_already_installed() {
1130-
let edit = &|date: &str, pkg: &mut MockPackage| {
1178+
let edit = &|date: &str, pkgs: &mut [MockPackage]| {
11311179
if date == "2016-02-01" {
1132-
let mut tpkg = pkg.targets
1180+
let tpkg = pkgs[0].targets
11331181
.iter_mut()
11341182
.find(|p| p.target == "x86_64-apple-darwin")
11351183
.unwrap();

0 commit comments

Comments
 (0)