App: a model install that also updates a working engine says from which version to which, that the old one is kept and that Settings can go back to it (#4823)

This commit is contained in:
Niko1221 committed 2026-10-31 23:12:53 +01:00
1 parent 2473978007
commit 0dfa2d9b19
2 files changed
+29 -3

No files matched your search

+6 -3
View File
@@ -43,12 +43,15 @@ export function createEngineStep({ control, signal = null, onChange = () => {} }
return { ...part };
}
const version = engine.offered?.version ?? null;
set({ state: 'downloading', version, name: `Engine ${version ?? ''}`.trim(), total_gb: round((engine.download_bytes ?? 0) / GB), message: 'Downloading the engine for this PC…' });
// An engine already works here: say what is about to change and that it can be undone (#4823), not only "downloading".
const before = engine.installed?.version ?? null;
const change = before && version && before !== version ? `Updating the engine from ${before} to ${version}. The engine you have now is kept, and Settings can go back to it.` : null;
set({ state: 'downloading', version, name: `Engine ${version ?? ''}`.trim(), total_gb: round((engine.download_bytes ?? 0) / GB), message: change ?? 'Downloading the engine for this PC…' });
const result = await control.update({
engine: true, control: false, signal,
onEvent: event => {
if (event.event === 'progress') {
set({ state: 'downloading', percent: event.percent ?? 0, done_gb: round((event.done ?? 0) / GB), total_gb: round((event.total ?? 0) / GB), message: `Downloading the engine for this PC: ${event.percent ?? 0}%` });
set({ state: 'downloading', percent: event.percent ?? 0, done_gb: round((event.done ?? 0) / GB), total_gb: round((event.total ?? 0) / GB), message: `${change ? `Updating the engine from ${before} to ${version}` : 'Downloading the engine for this PC'}: ${event.percent ?? 0}%` });
} else if (event.event === 'phase') {
const state = { verify: 'verifying', test: 'testing', switch: 'switching' }[event.phase];
if (state) set({ state, message: PHASE_TEXT[event.phase] ?? part.message });
@@ -58,7 +61,7 @@ export function createEngineStep({ control, signal = null, onChange = () => {} }
},
});
const done = (result.results ?? []).find(r => r.component === 'engine');
set({ state: 'done', percent: 100, done_gb: part.total_gb, version: done?.installed_after?.version ?? version, message: 'The engine for this PC is ready.' });
set({ state: 'done', percent: 100, done_gb: part.total_gb, version: done?.installed_after?.version ?? version, message: change ? `The engine was updated from ${before} to ${version}. Settings can go back to the one you had.` : 'The engine for this PC is ready.' });
} catch (error) {
const plain = plainUpdateError(error, 'engine');
note = `Your model is ready. The engine for this PC couldn't be downloaded. ${plain.next}`;
+23
View File
@@ -92,3 +92,26 @@ test('without a component updater the step is skipped and never throws', async (
assert.equal(part.state, 'skipped');
assert.equal(createEngineStep({ control: {} }).merge(null), null);
});
test('#4823: an engine that already works is not replaced without saying from which version to which, and that the old one is kept', async () => {
const messages = [];
const c = control({
usable: true,
check: offer('available', { installed: { version: '0.1.54' }, offered: { version: '0.1.55' } }),
update: async ({ onEvent }) => { onEvent({ event: 'progress', percent: 30, done: 0.15 * GB, total: 0.5 * GB }); return { ok: true, results: [{ component: 'engine', status: 'updated', installed_after: { version: '0.1.55' } }] }; },
});
const step = createEngineStep({ control: c, onChange: p => messages.push(p.message) });
const part = await step.run();
assert.match(messages.find(m => /Updating/.test(m)), /^Updating the engine from 0\.1\.54 to 0\.1\.55\. The engine you have now is kept, and Settings can go back to it\.$/);
assert.ok(messages.includes('Updating the engine from 0.1.54 to 0.1.55: 30%'));
assert.equal(part.message, 'The engine was updated from 0.1.54 to 0.1.55. Settings can go back to the one you had.');
});
test('a first engine keeps the plain download words', async () => {
const messages = [];
const c = control({ check: offer(), update: async () => updated });
const step = createEngineStep({ control: c, onChange: p => messages.push(p.message) });
await step.run();
assert.ok(messages.includes('Downloading the engine for this PC…'));
assert.ok(!messages.some(m => /Updating the engine from/.test(m)));
});