fix: use full update path when --custom-source is passed with --yes (#2336)

* fix: use full update path when --custom-source is passed with --yes

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.

* fix: address review feedback on choices.find() and comment clarity

* style: prettier fix for empty-body methods in custom-module-manager

---------

Co-authored-by: Brian <bmadcode@gmail.com>
This commit is contained in:
Jérôme Revillard 2026-04-28 03:49:21 +02:00 committed by GitHub
parent b4d73b7daf
commit 3e89b30b3c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 11 additions and 5 deletions

View File

@ -200,12 +200,15 @@ class UI {
actionType = options.action; actionType = options.action;
await prompts.log.info(`Using action from command-line: ${actionType}`); await prompts.log.info(`Using action from command-line: ${actionType}`);
} else if (options.yes) { } 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) { if (choices.length === 0) {
throw new Error('No valid actions available for this installation'); throw new Error('No valid actions available for this installation');
} }
const hasQuickUpdate = choices.some((c) => c.value === 'quick-update'); 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}`); await prompts.log.info(`Non-interactive mode (--yes): defaulting to ${actionType}`);
} else { } else {
actionType = await prompts.select({ actionType = await prompts.select({
@ -241,8 +244,11 @@ class UI {
.map((m) => m.trim()) .map((m) => m.trim())
.filter(Boolean); .filter(Boolean);
await prompts.log.info(`Using modules from command-line: ${selectedModules.join(', ')}`); await prompts.log.info(`Using modules from command-line: ${selectedModules.join(', ')}`);
} else if (options.customSource) { } else if (options.customSource && !options.yes) {
// Custom source without --modules: start with empty list (core added below) // Custom source without --modules or --yes: start with empty list
// (only custom source modules + core will be installed).
// When --yes is also set, fall through to the --yes branch so all
// installed modules are included alongside the custom source modules.
selectedModules = []; selectedModules = [];
} else if (options.yes) { } else if (options.yes) {
selectedModules = await this.getDefaultModules(installedModuleIds); selectedModules = await this.getDefaultModules(installedModuleIds);