resolved blocking issues when folder name is changed during install

This commit is contained in:
Brian Madison 2025-11-13 18:58:50 -06:00
parent 4aed5a1193
commit face4e4367
2 changed files with 63 additions and 4 deletions

View File

@ -48,6 +48,36 @@ class ConfigCollector {
return path.join(projectDir, 'bmad'); return path.join(projectDir, 'bmad');
} }
/**
* Detect the existing BMAD folder name in a project
* @param {string} projectDir - Project directory
* @returns {Promise<string|null>} Folder name (just the name, not full path) or null if not found
*/
async detectExistingBmadFolder(projectDir) {
// Check if project directory exists
if (!(await fs.pathExists(projectDir))) {
return null;
}
// Look for ANY directory with _cfg/manifest.yaml
try {
const entries = await fs.readdir(projectDir, { withFileTypes: true });
for (const entry of entries) {
if (entry.isDirectory()) {
const manifestPath = path.join(projectDir, entry.name, '_cfg', 'manifest.yaml');
if (await fs.pathExists(manifestPath)) {
// Found a V6+ installation, return just the folder name
return entry.name;
}
}
}
} catch {
// Ignore errors
}
return null;
}
/** /**
* Load existing config if it exists from module config files * Load existing config if it exists from module config files
* @param {string} projectDir - Target project directory * @param {string} projectDir - Target project directory
@ -565,6 +595,15 @@ class ConfigCollector {
} }
} }
// Special handling for bmad_folder: detect existing folder name
if (moduleName === 'core' && key === 'bmad_folder' && !existingValue && this.currentProjectDir) {
// Try to detect the existing BMAD folder name
const detectedFolder = await this.detectExistingBmadFolder(this.currentProjectDir);
if (detectedFolder) {
existingValue = detectedFolder;
}
}
// Determine question type and default value // Determine question type and default value
let questionType = 'input'; let questionType = 'input';
let defaultValue = item.default; let defaultValue = item.default;

View File

@ -562,7 +562,12 @@ class Installer {
config.skipIde = toolSelection.skipIde; config.skipIde = toolSelection.skipIde;
const ideConfigurations = toolSelection.configurations; const ideConfigurations = toolSelection.configurations;
spinner.start('Continuing installation...'); // Check if spinner is already running (e.g., from folder name change scenario)
if (spinner.isSpinning) {
spinner.text = 'Continuing installation...';
} else {
spinner.start('Continuing installation...');
}
// Create bmad directory structure // Create bmad directory structure
spinner.text = 'Creating directory structure...'; spinner.text = 'Creating directory structure...';
@ -1753,8 +1758,19 @@ class Installer {
lastModified: new Date().toISOString(), lastModified: new Date().toISOString(),
}; };
// Now run the full installation with the collected configs // Check if bmad_folder has changed
spinner.start('Updating BMAD installation...'); const existingBmadFolderName = path.basename(bmadDir);
const newBmadFolderName = this.configCollector.collectedConfig.core?.bmad_folder || existingBmadFolderName;
if (existingBmadFolderName === newBmadFolderName) {
// Normal quick update - start the spinner
spinner.start('Updating BMAD installation...');
} else {
// Folder name has changed - stop spinner and let install() handle it
spinner.stop();
console.log(chalk.yellow(`\n⚠️ Folder name will change: ${existingBmadFolderName}${newBmadFolderName}`));
console.log(chalk.yellow('The installer will handle the folder migration.\n'));
}
// Build the config object for the installer // Build the config object for the installer
const installConfig = { const installConfig = {
@ -1773,7 +1789,11 @@ class Installer {
// Call the standard install method // Call the standard install method
const result = await this.install(installConfig); const result = await this.install(installConfig);
spinner.succeed('Quick update complete!'); // Only succeed the spinner if it's still spinning
// (install method might have stopped it if folder name changed)
if (spinner.isSpinning) {
spinner.succeed('Quick update complete!');
}
return { return {
success: true, success: true,