UNPKG

@git.zone/cli

Version:

A comprehensive CLI tool for enhancing and managing local development workflows with gitzone utilities, focusing on project setup, version control, code formatting, and template management.

206 lines 18.5 kB
import * as plugins from './mod.plugins.js'; import { Project } from '../classes.project.js'; import { FormatContext } from './classes.formatcontext.js'; import { FormatPlanner } from './classes.formatplanner.js'; import { logger, setVerboseMode } from '../gitzone.logging.js'; // Import wrapper classes for formatters import { CleanupFormatter } from './formatters/cleanup.formatter.js'; import { NpmextraFormatter } from './formatters/npmextra.formatter.js'; import { LicenseFormatter } from './formatters/license.formatter.js'; import { PackageJsonFormatter } from './formatters/packagejson.formatter.js'; import { TemplatesFormatter } from './formatters/templates.formatter.js'; import { GitignoreFormatter } from './formatters/gitignore.formatter.js'; import { TsconfigFormatter } from './formatters/tsconfig.formatter.js'; import { PrettierFormatter } from './formatters/prettier.formatter.js'; import { ReadmeFormatter } from './formatters/readme.formatter.js'; import { CopyFormatter } from './formatters/copy.formatter.js'; export let run = async (options = {}) => { // Set verbose mode if requested if (options.verbose) { setVerboseMode(true); } const project = await Project.fromCwd(); const context = new FormatContext(); await context.initializeCache(); // Initialize the cache system const planner = new FormatPlanner(); // Get configuration from npmextra const npmextraConfig = new plugins.npmextra.Npmextra(); const formatConfig = npmextraConfig.dataFor('gitzone.format', { interactive: true, showDiffs: false, autoApprove: false, planTimeout: 30000, rollback: { enabled: true, autoRollbackOnError: true, backupRetentionDays: 7, maxBackupSize: '100MB', excludePatterns: ['node_modules/**', '.git/**'] }, modules: { skip: [], only: [], order: [] }, parallel: true, cache: { enabled: true, clean: true // Clean invalid entries from cache } }); // Clean cache if configured if (formatConfig.cache.clean) { await context.getChangeCache().clean(); } // Override config with command options const interactive = options.interactive ?? formatConfig.interactive; const autoApprove = options.yes ?? formatConfig.autoApprove; const parallel = options.parallel ?? formatConfig.parallel; try { // Initialize formatters const formatters = [ new CleanupFormatter(context, project), new NpmextraFormatter(context, project), new LicenseFormatter(context, project), new PackageJsonFormatter(context, project), new TemplatesFormatter(context, project), new GitignoreFormatter(context, project), new TsconfigFormatter(context, project), new PrettierFormatter(context, project), new ReadmeFormatter(context, project), new CopyFormatter(context, project), ]; // Filter formatters based on configuration const activeFormatters = formatters.filter(formatter => { if (formatConfig.modules.only.length > 0) { return formatConfig.modules.only.includes(formatter.name); } if (formatConfig.modules.skip.includes(formatter.name)) { return false; } return true; }); // Plan phase logger.log('info', 'Analyzing project for format operations...'); let plan = options.fromPlan ? JSON.parse(await plugins.smartfile.fs.toStringSync(options.fromPlan)) : await planner.planFormat(activeFormatters); // Display plan await planner.displayPlan(plan, options.detailed); // Save plan if requested if (options.savePlan) { await plugins.smartfile.memory.toFs(JSON.stringify(plan, null, 2), options.savePlan); logger.log('info', `Plan saved to ${options.savePlan}`); } // Exit if plan-only mode if (options.planOnly) { return; } // Dry-run mode if (options.dryRun) { logger.log('info', 'Dry-run mode - no changes will be made'); return; } // Interactive confirmation if (interactive && !autoApprove) { const interactInstance = new plugins.smartinteract.SmartInteract(); const response = await interactInstance.askQuestion({ type: 'confirm', name: 'proceed', message: 'Proceed with formatting?', default: true }); if (!response.proceed) { logger.log('info', 'Format operation cancelled by user'); return; } } // Execute phase logger.log('info', `Executing format operations${parallel ? ' in parallel' : ' sequentially'}...`); await planner.executePlan(plan, activeFormatters, context, parallel); // Finish statistics tracking context.getFormatStats().finish(); // Display statistics const showStats = npmextraConfig.dataFor('gitzone.format.showStats', true); if (showStats) { context.getFormatStats().displayStats(); } // Save stats if requested if (options.detailed) { const statsPath = `.nogit/format-stats-${Date.now()}.json`; await context.getFormatStats().saveReport(statsPath); } logger.log('success', 'Format operations completed successfully!'); } catch (error) { logger.log('error', `Format operation failed: ${error.message}`); // Automatic rollback if enabled if (formatConfig.rollback.enabled && formatConfig.rollback.autoRollbackOnError) { logger.log('info', 'Attempting automatic rollback...'); try { await context.rollbackOperation(); logger.log('success', 'Rollback completed successfully'); } catch (rollbackError) { logger.log('error', `Rollback failed: ${rollbackError.message}`); } } throw error; } }; // Export CLI command handlers export const handleRollback = async (operationId) => { const context = new FormatContext(); const rollbackManager = context.getRollbackManager(); if (!operationId) { // Rollback to last operation const backups = await rollbackManager.listBackups(); const lastOperation = backups .filter(op => op.status !== 'rolled-back') .sort((a, b) => b.timestamp - a.timestamp)[0]; if (!lastOperation) { logger.log('warn', 'No operations available for rollback'); return; } operationId = lastOperation.id; } try { await rollbackManager.rollback(operationId); logger.log('success', `Successfully rolled back operation ${operationId}`); } catch (error) { logger.log('error', `Rollback failed: ${error.message}`); throw error; } }; export const handleListBackups = async () => { const context = new FormatContext(); const rollbackManager = context.getRollbackManager(); const backups = await rollbackManager.listBackups(); if (backups.length === 0) { logger.log('info', 'No backup operations found'); return; } console.log('\nAvailable backups:'); console.log('━'.repeat(50)); for (const backup of backups) { const date = new Date(backup.timestamp).toLocaleString(); const status = backup.status; const filesCount = backup.files.length; console.log(`ID: ${backup.id}`); console.log(`Date: ${date}`); console.log(`Status: ${status}`); console.log(`Files: ${filesCount}`); console.log('─'.repeat(50)); } }; export const handleCleanBackups = async () => { const context = new FormatContext(); const rollbackManager = context.getRollbackManager(); // Get retention days from config const npmextraConfig = new plugins.npmextra.Npmextra(); const retentionDays = npmextraConfig.dataFor('gitzone.format.rollback.backupRetentionDays', 7); await rollbackManager.cleanOldBackups(retentionDays); logger.log('success', `Cleaned backups older than ${retentionDays} days`); }; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi90cy9tb2RfZm9ybWF0L2luZGV4LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sS0FBSyxPQUFPLE1BQU0sa0JBQWtCLENBQUM7QUFDNUMsT0FBTyxFQUFFLE9BQU8sRUFBRSxNQUFNLHVCQUF1QixDQUFDO0FBQ2hELE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQztBQUMzRCxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sNEJBQTRCLENBQUM7QUFDM0QsT0FBTyxFQUFFLE1BQU0sRUFBRSxjQUFjLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQztBQUUvRCx3Q0FBd0M7QUFDeEMsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sbUNBQW1DLENBQUM7QUFDckUsT0FBTyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sb0NBQW9DLENBQUM7QUFDdkUsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sbUNBQW1DLENBQUM7QUFDckUsT0FBTyxFQUFFLG9CQUFvQixFQUFFLE1BQU0sdUNBQXVDLENBQUM7QUFDN0UsT0FBTyxFQUFFLGtCQUFrQixFQUFFLE1BQU0scUNBQXFDLENBQUM7QUFDekUsT0FBTyxFQUFFLGtCQUFrQixFQUFFLE1BQU0scUNBQXFDLENBQUM7QUFDekUsT0FBTyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sb0NBQW9DLENBQUM7QUFDdkUsT0FBTyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sb0NBQW9DLENBQUM7QUFDdkUsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLGtDQUFrQyxDQUFDO0FBQ25FLE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSxnQ0FBZ0MsQ0FBQztBQUUvRCxNQUFNLENBQUMsSUFBSSxHQUFHLEdBQUcsS0FBSyxFQUFFLFVBVXBCLEVBQUUsRUFBZ0IsRUFBRTtJQUN0QixnQ0FBZ0M7SUFDaEMsSUFBSSxPQUFPLENBQUMsT0FBTyxFQUFFLENB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