From defab55922cd83a0f913c51ca6413f22030e18fb Mon Sep 17 00:00:00 2001 From: Jerome Revillard Date: Mon, 27 Apr 2026 12:17:38 +0200 Subject: [PATCH] fix: use full update path when --custom-source is passed with --yes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When --yes is used on an existing install, the installer auto-selects quick-update. However, quick-update never re-clones custom module repos — it only reads whatever is already in the cache. This means --custom-source with a new version tag (e.g. @1.1.0) is silently ignored and the previously cached version (e.g. 1.0.1) is reported as "already up to date". Default to the full update path when --custom-source is present, so the custom repo gets re-cloned at the requested version. Also ensure all installed modules are included in the selection when --yes is combined with --custom-source, preventing previously installed modules from being removed. --- tools/installer/ui.js | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/tools/installer/ui.js b/tools/installer/ui.js index 26b3619c1..3461c5808 100644 --- a/tools/installer/ui.js +++ b/tools/installer/ui.js @@ -86,12 +86,15 @@ class UI { actionType = options.action; await prompts.log.info(`Using action from command-line: ${actionType}`); } else if (options.yes) { - // Default to quick-update if available, otherwise first available choice + // Default to quick-update if available, unless flags that require the + // full update path are present (e.g. --custom-source which re-clones + // modules at a new version — quick-update skips that entirely). if (choices.length === 0) { throw new Error('No valid actions available for this installation'); } const hasQuickUpdate = choices.some((c) => c.value === 'quick-update'); - actionType = hasQuickUpdate ? 'quick-update' : choices[0].value; + const needsFullUpdate = !!options.customSource; + actionType = hasQuickUpdate && !needsFullUpdate ? 'quick-update' : choices.find((c) => c.value === 'update') || choices[0].value; await prompts.log.info(`Non-interactive mode (--yes): defaulting to ${actionType}`); } else { actionType = await prompts.select({ @@ -127,8 +130,11 @@ class UI { .map((m) => m.trim()) .filter(Boolean); await prompts.log.info(`Using modules from command-line: ${selectedModules.join(', ')}`); - } else if (options.customSource) { - // Custom source without --modules: start with empty list (core added below) + } else if (options.customSource && !options.yes) { + // Custom source without --modules or --yes: start with empty list + // (user will be prompted to select modules interactively; core added below). + // When --yes is also set, fall through to the --yes branch so all + // installed modules are included alongside the custom source modules. selectedModules = []; } else if (options.yes) { selectedModules = await this.getDefaultModules(installedModuleIds);