refactor(installer): extract _installAndConfigure from install()
Move module installation, directory creation, config generation, and manifest generation into a single method. The install() execution section is now five named method calls followed by summary and return.
This commit is contained in:
parent
1befede51d
commit
5ecd498c10
|
|
@ -272,144 +272,8 @@ class Installer {
|
|||
|
||||
await this._cacheCustomModules(paths, addResult);
|
||||
|
||||
const finalCustomContent = customConfig.customContent;
|
||||
const { officialModules, allModules } = await this._buildModuleLists(config, customConfig, paths);
|
||||
|
||||
// ─────────────────────────────────────────────────────────────────────────
|
||||
// FIRST TASKS BLOCK: Core installation through manifests (non-interactive)
|
||||
// ─────────────────────────────────────────────────────────────────────────
|
||||
const isQuickUpdate = config.isQuickUpdate();
|
||||
|
||||
// Collect directory creation results for output after tasks() completes
|
||||
const dirResults = { createdDirs: [], movedDirs: [], createdWdsFolders: [] };
|
||||
|
||||
// Build task list conditionally
|
||||
const installTasks = [];
|
||||
|
||||
// Module installation task (core is just another module in the list)
|
||||
if (allModules.length > 0) {
|
||||
installTasks.push({
|
||||
title: isQuickUpdate ? `Updating ${allModules.length} module(s)` : `Installing ${allModules.length} module(s)`,
|
||||
task: async (message) => {
|
||||
const installedModuleNames = new Set();
|
||||
|
||||
await this._installOfficialModules(config, paths, moduleConfigs, officialModules, addResult, isQuickUpdate, {
|
||||
message,
|
||||
installedModuleNames,
|
||||
});
|
||||
|
||||
await this._installCustomModules(customConfig, paths, moduleConfigs, finalCustomContent, addResult, isQuickUpdate, {
|
||||
message,
|
||||
installedModuleNames,
|
||||
});
|
||||
|
||||
return `${allModules.length} module(s) ${isQuickUpdate ? 'updated' : 'installed'}`;
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
// Module directory creation task
|
||||
installTasks.push({
|
||||
title: 'Creating module directories',
|
||||
task: async (message) => {
|
||||
const verboseMode = process.env.BMAD_VERBOSE_INSTALL === 'true' || config.verbose;
|
||||
const moduleLogger = {
|
||||
log: async (msg) => (verboseMode ? await prompts.log.message(msg) : undefined),
|
||||
error: async (msg) => await prompts.log.error(msg),
|
||||
warn: async (msg) => await prompts.log.warn(msg),
|
||||
};
|
||||
|
||||
// Module directories (core is in config.modules like any other module)
|
||||
if (config.modules && config.modules.length > 0) {
|
||||
for (const moduleName of config.modules) {
|
||||
message(`Setting up ${moduleName}...`);
|
||||
const result = await this.officialModules.createModuleDirectories(moduleName, paths.bmadDir, {
|
||||
installedIDEs: config.ides || [],
|
||||
moduleConfig: moduleConfigs[moduleName] || {},
|
||||
existingModuleConfig: this.configCollector.existingConfig?.[moduleName] || {},
|
||||
coreConfig: moduleConfigs.core || {},
|
||||
logger: moduleLogger,
|
||||
silent: true,
|
||||
});
|
||||
if (result) {
|
||||
dirResults.createdDirs.push(...result.createdDirs);
|
||||
dirResults.movedDirs.push(...(result.movedDirs || []));
|
||||
dirResults.createdWdsFolders.push(...result.createdWdsFolders);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
addResult('Module directories', 'ok');
|
||||
return 'Module directories created';
|
||||
},
|
||||
});
|
||||
|
||||
// Configuration generation task (stored as named reference for deferred execution)
|
||||
const configTask = {
|
||||
title: 'Generating configurations',
|
||||
task: async (message) => {
|
||||
// Generate clean config.yaml files for each installed module
|
||||
await this.generateModuleConfigs(paths.bmadDir, moduleConfigs);
|
||||
addResult('Configurations', 'ok', 'generated');
|
||||
|
||||
// Pre-register manifest files
|
||||
this.installedFiles.add(paths.manifestFile());
|
||||
this.installedFiles.add(paths.agentManifest());
|
||||
|
||||
// Generate CSV manifests for agents, skills AND ALL FILES with hashes
|
||||
// This must happen BEFORE mergeModuleHelpCatalogs because it depends on agent-manifest.csv
|
||||
message('Generating manifests...');
|
||||
const manifestGen = new ManifestGenerator();
|
||||
|
||||
const allModulesForManifest = config.isQuickUpdate()
|
||||
? customConfig._existingModules || allModules || []
|
||||
: customConfig._preserveModules
|
||||
? [...allModules, ...customConfig._preserveModules]
|
||||
: allModules || [];
|
||||
|
||||
let modulesForCsvPreserve;
|
||||
if (config.isQuickUpdate()) {
|
||||
modulesForCsvPreserve = customConfig._existingModules || allModules || [];
|
||||
} else {
|
||||
modulesForCsvPreserve = customConfig._preserveModules ? [...allModules, ...customConfig._preserveModules] : allModules;
|
||||
}
|
||||
|
||||
const manifestStats = await manifestGen.generateManifests(paths.bmadDir, allModulesForManifest, [...this.installedFiles], {
|
||||
ides: config.ides || [],
|
||||
preservedModules: modulesForCsvPreserve,
|
||||
});
|
||||
|
||||
// Merge help catalogs
|
||||
message('Generating help catalog...');
|
||||
await this.mergeModuleHelpCatalogs(paths.bmadDir);
|
||||
addResult('Help catalog', 'ok');
|
||||
|
||||
return 'Configurations generated';
|
||||
},
|
||||
};
|
||||
installTasks.push(configTask);
|
||||
|
||||
// Run all tasks except config (which runs after directory output)
|
||||
const mainTasks = installTasks.filter((t) => t !== configTask);
|
||||
await prompts.tasks(mainTasks);
|
||||
|
||||
// Render directory creation output right after directory task
|
||||
const color = await prompts.getColor();
|
||||
if (dirResults.movedDirs.length > 0) {
|
||||
const lines = dirResults.movedDirs.map((d) => ` ${d}`).join('\n');
|
||||
await prompts.log.message(color.cyan(`Moved directories:\n${lines}`));
|
||||
}
|
||||
if (dirResults.createdDirs.length > 0) {
|
||||
const lines = dirResults.createdDirs.map((d) => ` ${d}`).join('\n');
|
||||
await prompts.log.message(color.yellow(`Created directories:\n${lines}`));
|
||||
}
|
||||
if (dirResults.createdWdsFolders.length > 0) {
|
||||
const lines = dirResults.createdWdsFolders.map((f) => color.dim(` \u2713 ${f}/`)).join('\n');
|
||||
await prompts.log.message(color.cyan(`Created WDS folder structure:\n${lines}`));
|
||||
}
|
||||
|
||||
// Now run configuration generation
|
||||
await prompts.tasks([configTask]);
|
||||
await this._installAndConfigure(config, customConfig, paths, moduleConfigs, officialModules, allModules, addResult);
|
||||
|
||||
await this._setupIdes(config, ideConfigurations, allModules, paths, addResult);
|
||||
|
||||
|
|
@ -517,6 +381,132 @@ class Installer {
|
|||
return { officialModules, allModules };
|
||||
}
|
||||
|
||||
/**
|
||||
* Install modules, create directories, generate configs and manifests.
|
||||
*/
|
||||
async _installAndConfigure(config, customConfig, paths, moduleConfigs, officialModules, allModules, addResult) {
|
||||
const isQuickUpdate = config.isQuickUpdate();
|
||||
const finalCustomContent = customConfig.customContent;
|
||||
|
||||
const dirResults = { createdDirs: [], movedDirs: [], createdWdsFolders: [] };
|
||||
|
||||
const installTasks = [];
|
||||
|
||||
if (allModules.length > 0) {
|
||||
installTasks.push({
|
||||
title: isQuickUpdate ? `Updating ${allModules.length} module(s)` : `Installing ${allModules.length} module(s)`,
|
||||
task: async (message) => {
|
||||
const installedModuleNames = new Set();
|
||||
|
||||
await this._installOfficialModules(config, paths, moduleConfigs, officialModules, addResult, isQuickUpdate, {
|
||||
message,
|
||||
installedModuleNames,
|
||||
});
|
||||
|
||||
await this._installCustomModules(customConfig, paths, moduleConfigs, finalCustomContent, addResult, isQuickUpdate, {
|
||||
message,
|
||||
installedModuleNames,
|
||||
});
|
||||
|
||||
return `${allModules.length} module(s) ${isQuickUpdate ? 'updated' : 'installed'}`;
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
installTasks.push({
|
||||
title: 'Creating module directories',
|
||||
task: async (message) => {
|
||||
const verboseMode = process.env.BMAD_VERBOSE_INSTALL === 'true' || config.verbose;
|
||||
const moduleLogger = {
|
||||
log: async (msg) => (verboseMode ? await prompts.log.message(msg) : undefined),
|
||||
error: async (msg) => await prompts.log.error(msg),
|
||||
warn: async (msg) => await prompts.log.warn(msg),
|
||||
};
|
||||
|
||||
if (config.modules && config.modules.length > 0) {
|
||||
for (const moduleName of config.modules) {
|
||||
message(`Setting up ${moduleName}...`);
|
||||
const result = await this.officialModules.createModuleDirectories(moduleName, paths.bmadDir, {
|
||||
installedIDEs: config.ides || [],
|
||||
moduleConfig: moduleConfigs[moduleName] || {},
|
||||
existingModuleConfig: this.configCollector.existingConfig?.[moduleName] || {},
|
||||
coreConfig: moduleConfigs.core || {},
|
||||
logger: moduleLogger,
|
||||
silent: true,
|
||||
});
|
||||
if (result) {
|
||||
dirResults.createdDirs.push(...result.createdDirs);
|
||||
dirResults.movedDirs.push(...(result.movedDirs || []));
|
||||
dirResults.createdWdsFolders.push(...result.createdWdsFolders);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
addResult('Module directories', 'ok');
|
||||
return 'Module directories created';
|
||||
},
|
||||
});
|
||||
|
||||
const configTask = {
|
||||
title: 'Generating configurations',
|
||||
task: async (message) => {
|
||||
await this.generateModuleConfigs(paths.bmadDir, moduleConfigs);
|
||||
addResult('Configurations', 'ok', 'generated');
|
||||
|
||||
this.installedFiles.add(paths.manifestFile());
|
||||
this.installedFiles.add(paths.agentManifest());
|
||||
|
||||
message('Generating manifests...');
|
||||
const manifestGen = new ManifestGenerator();
|
||||
|
||||
const allModulesForManifest = config.isQuickUpdate()
|
||||
? customConfig._existingModules || allModules || []
|
||||
: customConfig._preserveModules
|
||||
? [...allModules, ...customConfig._preserveModules]
|
||||
: allModules || [];
|
||||
|
||||
let modulesForCsvPreserve;
|
||||
if (config.isQuickUpdate()) {
|
||||
modulesForCsvPreserve = customConfig._existingModules || allModules || [];
|
||||
} else {
|
||||
modulesForCsvPreserve = customConfig._preserveModules ? [...allModules, ...customConfig._preserveModules] : allModules;
|
||||
}
|
||||
|
||||
await manifestGen.generateManifests(paths.bmadDir, allModulesForManifest, [...this.installedFiles], {
|
||||
ides: config.ides || [],
|
||||
preservedModules: modulesForCsvPreserve,
|
||||
});
|
||||
|
||||
message('Generating help catalog...');
|
||||
await this.mergeModuleHelpCatalogs(paths.bmadDir);
|
||||
addResult('Help catalog', 'ok');
|
||||
|
||||
return 'Configurations generated';
|
||||
},
|
||||
};
|
||||
installTasks.push(configTask);
|
||||
|
||||
// Run install + dirs first, then render dir output, then run config generation
|
||||
const mainTasks = installTasks.filter((t) => t !== configTask);
|
||||
await prompts.tasks(mainTasks);
|
||||
|
||||
const color = await prompts.getColor();
|
||||
if (dirResults.movedDirs.length > 0) {
|
||||
const lines = dirResults.movedDirs.map((d) => ` ${d}`).join('\n');
|
||||
await prompts.log.message(color.cyan(`Moved directories:\n${lines}`));
|
||||
}
|
||||
if (dirResults.createdDirs.length > 0) {
|
||||
const lines = dirResults.createdDirs.map((d) => ` ${d}`).join('\n');
|
||||
await prompts.log.message(color.yellow(`Created directories:\n${lines}`));
|
||||
}
|
||||
if (dirResults.createdWdsFolders.length > 0) {
|
||||
const lines = dirResults.createdWdsFolders.map((f) => color.dim(` \u2713 ${f}/`)).join('\n');
|
||||
await prompts.log.message(color.cyan(`Created WDS folder structure:\n${lines}`));
|
||||
}
|
||||
|
||||
await prompts.tasks([configTask]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set up IDE integrations for each selected IDE.
|
||||
*/
|
||||
|
|
|
|||
Loading…
Reference in New Issue