@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
JavaScript
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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