craft-update: a pin made while a check runs still holds its answer

finish_check used the choice cached when the check started, so a launcher
pin made during the network request still opened the stable prompt. It now
re-reads the choice when the check finishes, as offer does.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
JeremyandClaude Opus 5.5 committed 2026-10-30 12:42:23 +00:00
1 parent 0db8c1ba47
commit a710ab7897
2 files changed
+24 -2

No files matched your search

+4 -2
View File
@@ -200,8 +200,10 @@ impl Updater {
let requested = std::mem::take(&mut self.requested);
match answer {
Ok(Some(release)) => {
self.status = Status::Idle;
if self.prompt.is_none() && self.install.is_none() && !self.installed && self.managed.is_none() {
// The launcher may have pinned the app while the check ran.
let managed = self.read_choice();
self.status = if managed && requested { Status::UpToDate } else { Status::Idle };
if self.prompt.is_none() && self.install.is_none() && !self.installed && !managed {
self.prompt = Some(StartupPrompt::new(self.app, release, self.version.clone()));
}
}
+20
View File
@@ -122,3 +122,23 @@ fn a_running_install_keeps_its_prompt_when_the_app_is_pinned() {
assert!(u.read_choice());
assert!(u.prompt_open(), "tick reports the running install through the prompt");
}
#[test]
fn a_pin_made_while_the_check_runs_still_holds_its_answer() {
let ctx = egui::Context::default();
let dir = tempfile::tempdir().unwrap();
let path = dir.path().join("versions.json");
let during = path.clone();
// The check itself pins the app before answering, as the launcher could mid-check.
let source: CheckSource = Arc::new(move || {
let mut pins = Pins::default();
pins.set(PHOTOCRAFT.id, &crate::pins::VersionTrack::Pinned("v0.13.0".into()));
pins.save(&during)?;
Ok(Some(newer()))
});
let mut u = Updater::new(&PHOTOCRAFT, "0.13.0").with_source(source).with_pins_path(&path);
u.check_now(&ctx);
settle(&mut u, &ctx);
assert!(!u.prompt_open());
assert_eq!(u.status(), &Status::UpToDate);
}