Files
cli/ts/mod_format/formatters/gitignore.formatter.ts

112 lines
2.7 KiB
TypeScript

import { BaseFormatter } from '../classes.baseformatter.js';
import type { IPlannedChange } from '../interfaces.format.js';
import * as plugins from '../mod.plugins.js';
import { logger } from '../../gitzone.logging.js';
// Standard gitignore template content (without front-matter)
const GITIGNORE_TEMPLATE = `.nogit/
# artifacts
coverage/
public/
# installs
node_modules/
# caches
.yarn/
.cache/
.rpt2_cache
# builds
dist/
dist_*/
# AI
.claude/
.serena/
#------# custom`;
export class GitignoreFormatter extends BaseFormatter {
get name(): string {
return 'gitignore';
}
async analyze(): Promise<IPlannedChange[]> {
const changes: IPlannedChange[] = [];
const gitignorePath = '.gitignore';
// Check if file exists and extract custom content
let customContent = '';
const exists = await plugins.smartfs.file(gitignorePath).exists();
if (exists) {
const existingContent = (await plugins.smartfs
.file(gitignorePath)
.encoding('utf8')
.read()) as string;
// Extract custom section content
const customMarkers = ['#------# custom', '# custom'];
for (const marker of customMarkers) {
const splitResult = existingContent.split(marker);
if (splitResult.length > 1) {
customContent = splitResult[1].trim();
break;
}
}
}
// Compute new content
let newContent = GITIGNORE_TEMPLATE;
if (customContent) {
newContent = GITIGNORE_TEMPLATE + '\n' + customContent + '\n';
} else {
newContent = GITIGNORE_TEMPLATE + '\n';
}
// Read current content to compare
let currentContent = '';
if (exists) {
currentContent = (await plugins.smartfs
.file(gitignorePath)
.encoding('utf8')
.read()) as string;
}
// Determine change type
if (!exists) {
changes.push({
type: 'create',
path: gitignorePath,
module: this.name,
description: 'Create .gitignore',
content: newContent,
});
} else if (newContent !== currentContent) {
changes.push({
type: 'modify',
path: gitignorePath,
module: this.name,
description: 'Update .gitignore (preserving custom section)',
content: newContent,
});
}
return changes;
}
async applyChange(change: IPlannedChange): Promise<void> {
if (!change.content) return;
if (change.type === 'create') {
await this.createFile(change.path, change.content);
logger.log('info', 'Created .gitignore');
} else if (change.type === 'modify') {
await this.modifyFile(change.path, change.content);
logger.log('info', 'Updated .gitignore (preserved custom section)');
}
}
}