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.

118 lines (100 loc) 3.61 kB
import { BaseFormatter } from '../classes.baseformatter.js'; import type { IPlannedChange } from '../interfaces.format.js'; import * as plugins from '../mod.plugins.js'; import { logger, logVerbose } from '../../gitzone.logging.js'; interface ICopyPattern { from: string; to: string; preservePath?: boolean; } export class CopyFormatter extends BaseFormatter { get name(): string { return 'copy'; } async analyze(): Promise<IPlannedChange[]> { const changes: IPlannedChange[] = []; // Get copy configuration from npmextra.json const npmextraConfig = new plugins.npmextra.Npmextra(); const copyConfig = npmextraConfig.dataFor<{ patterns: ICopyPattern[] }>( 'gitzone.format.copy', { patterns: [] }, ); if (!copyConfig.patterns || copyConfig.patterns.length === 0) { logVerbose('No copy patterns configured in npmextra.json'); return changes; } for (const pattern of copyConfig.patterns) { if (!pattern.from || !pattern.to) { logVerbose('Invalid copy pattern - missing "from" or "to" field'); continue; } try { // Handle glob patterns const entries = await plugins.smartfs .directory('.') .recursive() .filter(pattern.from) .list(); const files = entries.map((entry) => entry.path); for (const file of files) { const sourcePath = file; let destPath = pattern.to; // If destination is a directory, preserve filename if (pattern.to.endsWith('/')) { const filename = plugins.path.basename(file); destPath = plugins.path.join(pattern.to, filename); } // Handle template variables in destination path if (pattern.preservePath) { const relativePath = plugins.path.relative( plugins.path.dirname(pattern.from.replace(/\*/g, '')), file, ); destPath = plugins.path.join(pattern.to, relativePath); } // Read source content const content = (await plugins.smartfs .file(sourcePath) .encoding('utf8') .read()) as string; // Check if destination exists and has same content let needsCopy = true; const destExists = await plugins.smartfs.file(destPath).exists(); if (destExists) { const existingContent = (await plugins.smartfs .file(destPath) .encoding('utf8') .read()) as string; if (existingContent === content) { needsCopy = false; } } if (needsCopy) { changes.push({ type: destExists ? 'modify' : 'create', path: destPath, module: this.name, description: `Copy from ${sourcePath}`, content: content, }); } } } catch (error) { logVerbose(`Failed to process pattern ${pattern.from}: ${error.message}`); } } return changes; } async applyChange(change: IPlannedChange): Promise<void> { if (!change.content) return; // Ensure destination directory exists const destDir = plugins.path.dirname(change.path); await plugins.smartfs.directory(destDir).recursive().create(); if (change.type === 'create') { await this.createFile(change.path, change.content); } else { await this.modifyFile(change.path, change.content); } logger.log('info', `Copied to ${change.path}`); } }