feat(mod_format): Refactor formatting modules to new BaseFormatter and implement concrete analyze/apply logic
This commit is contained in:
@@ -1,8 +1,117 @@
|
||||
import { LegacyFormatter } from './legacy.formatter.js';
|
||||
import * as formatCopy from '../format.copy.js';
|
||||
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';
|
||||
|
||||
export class CopyFormatter extends LegacyFormatter {
|
||||
constructor(context: any, project: any) {
|
||||
super(context, project, 'copy', formatCopy);
|
||||
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}`);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user