UNPKG

@re-shell/cli

Version:

Full-stack development platform uniting microservices and microfrontends. Build complete applications with .NET (ASP.NET Core Web API, Minimal API), Java (Spring Boot, Quarkus, Micronaut, Vert.x), Rust (Actix-Web, Warp, Rocket, Axum), Python (FastAPI, Dja

393 lines (392 loc) 15.4 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.addGitSubmodule = addGitSubmodule; exports.removeGitSubmodule = removeGitSubmodule; exports.updateGitSubmodules = updateGitSubmodules; exports.showSubmoduleStatus = showSubmoduleStatus; exports.initSubmodules = initSubmodules; exports.manageSubmodules = manageSubmodules; const chalk_1 = __importDefault(require("chalk")); const prompts_1 = __importDefault(require("prompts")); const submodule_1 = require("../utils/submodule"); const monorepo_1 = require("../utils/monorepo"); /** * Add a new Git submodule */ async function addGitSubmodule(repositoryUrl, options = {}) { const { spinner } = options; try { if (spinner) { spinner.setText('Checking Git repository...'); } // Ensure we're in a Git repository if (!(await (0, submodule_1.isGitRepository)())) { throw new Error('Not in a Git repository. Initialize Git first with: git init'); } if (spinner) { spinner.stop(); } // Interactive prompts for missing options const responses = await (0, prompts_1.default)([ { type: options.path ? null : 'text', name: 'path', message: 'Submodule path:', initial: repositoryUrl.split('/').pop()?.replace('.git', '') || 'submodule', validate: (value) => (value.trim() ? true : 'Path is required'), }, { type: options.branch ? null : 'text', name: 'branch', message: 'Branch to track:', initial: 'main', }, ]); const finalOptions = { path: options.path || responses.path, branch: options.branch || responses.branch || 'main', }; if (spinner) { spinner.start(); spinner.setText(`Adding submodule: ${repositoryUrl}`); } console.log(chalk_1.default.cyan(`Adding submodule: ${repositoryUrl}`)); console.log(chalk_1.default.gray(`Path: ${finalOptions.path}`)); console.log(chalk_1.default.gray(`Branch: ${finalOptions.branch}`)); await (0, submodule_1.addSubmodule)(finalOptions.path, repositoryUrl, finalOptions.branch); if (spinner) { spinner.setText('Updating documentation...'); } // Update documentation const submodules = await (0, submodule_1.getSubmoduleStatus)(); const monorepoRoot = (await (0, monorepo_1.findMonorepoRoot)()) || process.cwd(); await (0, submodule_1.createSubmoduleDocumentation)(monorepoRoot, submodules); if (spinner) { spinner.succeed(chalk_1.default.green(`✓ Submodule added successfully: ${finalOptions.path}`)); } else { console.log(chalk_1.default.green(`✓ Submodule added successfully: ${finalOptions.path}`)); } console.log(chalk_1.default.gray('Documentation updated in docs/SUBMODULES.md')); } catch (error) { if (spinner) { spinner.fail(chalk_1.default.red('Error adding submodule')); } console.error(chalk_1.default.red('Error adding submodule:'), error); throw error; } } /** * Remove a Git submodule */ async function removeGitSubmodule(submodulePath, options = {}) { const { spinner } = options; try { if (spinner) { spinner.setText('Checking Git repository...'); } // Ensure we're in a Git repository if (!(await (0, submodule_1.isGitRepository)())) { throw new Error('Not in a Git repository.'); } if (spinner) { spinner.setText('Loading submodule information...'); } // Get current submodules to validate path const submodules = await (0, submodule_1.getSubmoduleStatus)(); const submodule = submodules.find(sub => sub.path === submodulePath || sub.name === submodulePath); if (!submodule) { throw new Error(`Submodule not found: ${submodulePath}`); } if (spinner) { spinner.stop(); } // Confirmation prompt unless force option is used if (!options.force) { const { confirm } = await (0, prompts_1.default)({ type: 'confirm', name: 'confirm', message: `Are you sure you want to remove submodule "${submodule.path}"?`, initial: false, }); if (!confirm) { console.log(chalk_1.default.yellow('Operation cancelled.')); return; } } if (spinner) { spinner.start(); spinner.setText(`Removing submodule: ${submodule.path}`); } console.log(chalk_1.default.cyan(`Removing submodule: ${submodule.path}`)); await (0, submodule_1.removeSubmodule)(submodule.path); if (spinner) { spinner.setText('Updating documentation...'); } // Update documentation const updatedSubmodules = await (0, submodule_1.getSubmoduleStatus)(); const monorepoRoot = (await (0, monorepo_1.findMonorepoRoot)()) || process.cwd(); await (0, submodule_1.createSubmoduleDocumentation)(monorepoRoot, updatedSubmodules); if (spinner) { spinner.succeed(chalk_1.default.green(`✓ Submodule removed successfully: ${submodule.path}`)); } else { console.log(chalk_1.default.green(`✓ Submodule removed successfully: ${submodule.path}`)); } console.log(chalk_1.default.gray('Documentation updated in docs/SUBMODULES.md')); } catch (error) { if (spinner) { spinner.fail(chalk_1.default.red('Error removing submodule')); } console.error(chalk_1.default.red('Error removing submodule:'), error); throw error; } } /** * Update Git submodules */ async function updateGitSubmodules(options = {}) { const { spinner } = options; try { if (spinner) { spinner.setText('Checking Git repository...'); } // Ensure we're in a Git repository if (!(await (0, submodule_1.isGitRepository)())) { throw new Error('Not in a Git repository.'); } if (options.path) { if (spinner) { spinner.setText(`Updating submodule: ${options.path}`); } console.log(chalk_1.default.cyan(`Updating submodule: ${options.path}`)); await (0, submodule_1.updateSubmodules)(options.path); if (spinner) { spinner.succeed(chalk_1.default.green(`✓ Submodule updated: ${options.path}`)); } else { console.log(chalk_1.default.green(`✓ Submodule updated: ${options.path}`)); } } else { if (spinner) { spinner.setText('Updating all submodules...'); } console.log(chalk_1.default.cyan('Updating all submodules...')); await (0, submodule_1.updateSubmodules)(); if (spinner) { spinner.succeed(chalk_1.default.green('✓ All submodules updated')); } else { console.log(chalk_1.default.green('✓ All submodules updated')); } } if (spinner) { spinner.setText('Updating documentation...'); } // Update documentation const submodules = await (0, submodule_1.getSubmoduleStatus)(); const monorepoRoot = (await (0, monorepo_1.findMonorepoRoot)()) || process.cwd(); await (0, submodule_1.createSubmoduleDocumentation)(monorepoRoot, submodules); } catch (error) { if (spinner) { spinner.fail(chalk_1.default.red('Error updating submodules')); } console.error(chalk_1.default.red('Error updating submodules:'), error); throw error; } } /** * Show Git submodule status */ async function showSubmoduleStatus() { try { // Ensure we're in a Git repository with timeout const isGitRepo = await Promise.race([ (0, submodule_1.isGitRepository)(), new Promise((_, reject) => setTimeout(() => reject(new Error('Timeout checking Git repository')), 3000)), ]); if (!isGitRepo) { throw new Error('Not in a Git repository.'); } const submodules = await Promise.race([ (0, submodule_1.getSubmoduleStatus)(), new Promise((_, reject) => setTimeout(() => reject(new Error('Timeout getting submodule status')), 5000)), ]); if (submodules.length === 0) { console.log(chalk_1.default.yellow('No submodules found.')); return; } console.log(chalk_1.default.cyan('\n📁 Submodule Status\n')); submodules.forEach((submodule) => { const statusColor = getStatusColor(submodule.status); const statusIcon = getStatusIcon(submodule.status); console.log(`${statusIcon} ${chalk_1.default.bold(submodule.name)} ${statusColor(submodule.status)}`); console.log(` ${chalk_1.default.gray('Path:')} ${submodule.path}`); console.log(` ${chalk_1.default.gray('URL:')} ${submodule.url}`); console.log(` ${chalk_1.default.gray('Branch:')} ${submodule.branch}`); console.log(` ${chalk_1.default.gray('Commit:')} ${submodule.commit}`); console.log(); }); console.log(chalk_1.default.gray(`Total: ${submodules.length} submodules`)); // Show summary by status const statusCounts = submodules.reduce((acc, sub) => { acc[sub.status] = (acc[sub.status] || 0) + 1; return acc; }, {}); if (Object.keys(statusCounts).length > 1) { console.log(chalk_1.default.gray('\nStatus Summary:')); Object.entries(statusCounts).forEach(([status, count]) => { const color = getStatusColor(status); console.log(` ${color(status)}: ${count}`); }); } } catch (error) { console.error(chalk_1.default.red('Error getting submodule status:'), error); throw error; } } /** * Initialize submodules (for new clones) */ async function initSubmodules() { try { // Ensure we're in a Git repository if (!(await (0, submodule_1.isGitRepository)())) { throw new Error('Not in a Git repository.'); } console.log(chalk_1.default.cyan('Initializing submodules...')); await (0, submodule_1.updateSubmodules)(); // This will init and update console.log(chalk_1.default.green('✓ Submodules initialized')); } catch (error) { console.error(chalk_1.default.red('Error initializing submodules:'), error); throw error; } } /** * Interactive submodule management */ async function manageSubmodules() { try { // Ensure we're in a Git repository if (!(await (0, submodule_1.isGitRepository)())) { throw new Error('Not in a Git repository.'); } const { action } = await (0, prompts_1.default)({ type: 'select', name: 'action', message: 'What would you like to do?', choices: [ { title: 'Show status', value: 'status' }, { title: 'Add submodule', value: 'add' }, { title: 'Update submodules', value: 'update' }, { title: 'Remove submodule', value: 'remove' }, { title: 'Initialize submodules', value: 'init' }, ], }); switch (action) { case 'status': await showSubmoduleStatus(); break; case 'add': { const { url } = await (0, prompts_1.default)({ type: 'text', name: 'url', message: 'Repository URL:', validate: (value) => (value.trim() ? true : 'URL is required'), }); await addGitSubmodule(url); break; } case 'update': { const submodules = await (0, submodule_1.getSubmoduleStatus)(); if (submodules.length === 0) { console.log(chalk_1.default.yellow('No submodules to update.')); return; } const { updateTarget } = await (0, prompts_1.default)({ type: 'select', name: 'updateTarget', message: 'What to update?', choices: [ { title: 'All submodules', value: 'all' }, ...submodules.map((sub) => ({ title: sub.path, value: sub.path })), ], }); if (updateTarget === 'all') { await updateGitSubmodules(); } else { await updateGitSubmodules({ path: updateTarget }); } break; } case 'remove': { const currentSubmodules = await (0, submodule_1.getSubmoduleStatus)(); if (currentSubmodules.length === 0) { console.log(chalk_1.default.yellow('No submodules to remove.')); return; } const { removeTarget } = await (0, prompts_1.default)({ type: 'select', name: 'removeTarget', message: 'Which submodule to remove?', choices: currentSubmodules.map((sub) => ({ title: sub.path, value: sub.path, })), }); await removeGitSubmodule(removeTarget); break; } case 'init': { await initSubmodules(); break; } } } catch (error) { console.error(chalk_1.default.red('Error managing submodules:'), error); throw error; } } function getStatusColor(status) { switch (status) { case 'clean': return chalk_1.default.green; case 'modified': return chalk_1.default.yellow; case 'untracked': return chalk_1.default.red; case 'ahead': return chalk_1.default.blue; case 'behind': return chalk_1.default.magenta; default: return chalk_1.default.gray; } } function getStatusIcon(status) { switch (status) { case 'clean': return chalk_1.default.green('✓'); case 'modified': return chalk_1.default.yellow('●'); case 'untracked': return chalk_1.default.red('✗'); case 'ahead': return chalk_1.default.blue('↑'); case 'behind': return chalk_1.default.magenta('↓'); default: return chalk_1.default.gray('?'); } }