UNPKG

cfn-forge

Version:

CloudFormation deployment automation tool with git-based workflows

208 lines (173 loc) 5.9 kB
/** * CFN-Forge Templates Command * Lists and manages available project templates */ const chalk = require('chalk'); const { logger } = require('../utils/logger'); const { listTemplates } = require('../../lib/templates/engine'); /** * Format template information for display */ function formatTemplateInfo(template) { const sourceIcon = template.source === 'built-in' ? '🏗️' : '👤'; const sourceBadge = template.source === 'built-in' ? chalk.white('built-in') : chalk.green('user'); return { name: template.name, description: template.description || 'No description available', version: template.version || 'unknown', author: template.author || 'unknown', source: template.source, sourceIcon, sourceBadge, cfnForgeVersion: template.cfnForgeVersion || 'any', }; } /** * Display templates in table format */ function displayTemplatesTable(templates) { if (templates.length === 0) { logger.warn('No templates found'); logger.info(''); logger.info('💡 You can create custom templates using:'); logger.info(' cfn-forge templates --create'); return; } logger.info('📋 Available Templates'); logger.info(''); // Calculate column widths const maxNameLength = Math.max(8, ...templates.map((t) => t.name.length)); const maxDescLength = Math.max(15, ...templates.map((t) => (t.description || '').length)); // Header console.log( ` ${ 'NAME'.padEnd(maxNameLength + 2) }${'DESCRIPTION'.padEnd(maxDescLength + 2) }${'VERSION'.padEnd(10) }SOURCE`, ); console.log(` ${'─'.repeat(maxNameLength + maxDescLength + 25)}`); // Template rows templates.forEach((template) => { const info = formatTemplateInfo(template); console.log( ` ${ `${info.sourceIcon} ${chalk.cyan(info.name)}`.padEnd(maxNameLength + 4) }${(info.description || 'No description').padEnd(maxDescLength + 2) }${(info.version || 'N/A').padEnd(10) }${info.sourceBadge}`, ); }); logger.info(''); logger.info(`📊 Total: ${templates.length} template${templates.length === 1 ? '' : 's'}`); } /** * Display templates in JSON format */ function displayTemplatesJSON(templates) { const output = { templates: templates.map((template) => ({ name: template.name, description: template.description, version: template.version, author: template.author, source: template.source, cfnForgeVersion: template.cfnForgeVersion, path: template.path, })), total: templates.length, }; console.log(JSON.stringify(output, null, 2)); } /** * Display detailed template information */ function displayTemplatesDetailed(templates) { if (templates.length === 0) { logger.warn('No templates found'); return; } logger.info('📋 Available Templates (Detailed)'); logger.info(''); templates.forEach((template, index) => { const info = formatTemplateInfo(template); console.log(`${info.sourceIcon} ${chalk.cyan.bold(info.name)}`); console.log(` Description: ${info.description}`); console.log(` Version: ${info.version}`); console.log(` Author: ${info.author}`); console.log(` Source: ${info.sourceBadge}`); console.log(` CFN-Forge Version: ${info.cfnForgeVersion}`); if (template.variables && Object.keys(template.variables).length > 0) { console.log(' Variables:'); Object.entries(template.variables).forEach(([key, config]) => { const defaultVal = config.default ? ` (default: ${config.default})` : ''; console.log(` • ${key}${defaultVal}`); }); } if (template.hooks && template.hooks.postInstall) { console.log(` Post-install hooks: ${template.hooks.postInstall.length}`); } if (index < templates.length - 1) { console.log(''); } }); logger.info(''); logger.info(`📊 Total: ${templates.length} template${templates.length === 1 ? '' : 's'}`); } /** * Filter templates based on options */ function filterTemplates(templates, options) { let filtered = [...templates]; if (options.installed) { // Show only built-in templates that are "installed" with CFN-Forge filtered = filtered.filter((t) => t.source === 'built-in'); } return filtered; } /** * Main templates command handler */ async function templatesCommand(options) { try { logger.info('🔍 Loading templates...'); // Get all available templates const allTemplates = await listTemplates(); // Filter based on options const templates = filterTemplates(allTemplates, options); // Clear the loading message process.stdout.write('\r\x1b[K'); // Display templates based on output format if (options.json) { displayTemplatesJSON(templates); } else if (options.detailed) { displayTemplatesDetailed(templates); } else { displayTemplatesTable(templates); } // Additional usage information if (!options.json && templates.length > 0) { logger.info(''); logger.info('💡 Usage:'); logger.info(' cfn-forge init <template-name> # Initialize project with template'); logger.info(' cfn-forge init --list # List templates during init'); if (templates.some((t) => t.source === 'user')) { logger.info(' cfn-forge templates --installed # Show only built-in templates'); } } } catch (error) { logger.error(`Failed to load templates: ${error.message}`); if (process.env.DEBUG) { console.error(error.stack); } logger.info(''); logger.info('💡 Troubleshooting:'); logger.info(' • Check that CFN-Forge is properly installed'); logger.info(' • Verify templates directory exists'); logger.info(' • Run with DEBUG=cfn-forge:* for more details'); process.exit(1); } } module.exports = templatesCommand;