@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.
183 lines • 15.2 kB
JavaScript
import { BaseFormatter } from '../classes.baseformatter.js';
import * as plugins from '../mod.plugins.js';
import { logger, logVerbose } from '../../gitzone.logging.js';
export class PrettierFormatter extends BaseFormatter {
get name() {
return 'prettier';
}
async analyze() {
const changes = [];
// Define directories to format (TypeScript directories by default)
const includeDirs = ['ts', 'ts_*', 'test', 'tests'];
// File extensions to format
const extensions = '{ts,tsx,js,jsx,json,md,css,scss,html,xml,yaml,yml}';
// Also format root-level config files
const rootConfigFiles = [
'package.json',
'tsconfig.json',
'npmextra.json',
'.prettierrc',
'.prettierrc.json',
'.prettierrc.js',
'readme.md',
'README.md',
'changelog.md',
'CHANGELOG.md',
// Skip files without extensions as prettier can't infer parser
// 'license',
// 'LICENSE',
'*.md',
];
// Collect all files to format
const allFiles = [];
// Add files from TypeScript directories
for (const dir of includeDirs) {
const globPattern = `${dir}/**/*.${extensions}`;
const dirFiles = await plugins.smartfile.fs.listFileTree('.', globPattern);
allFiles.push(...dirFiles);
}
// Add root config files
for (const pattern of rootConfigFiles) {
const rootFiles = await plugins.smartfile.fs.listFileTree('.', pattern);
// Only include files at root level (no slashes in path)
const rootLevelFiles = rootFiles.filter((f) => !f.includes('/'));
allFiles.push(...rootLevelFiles);
}
// Remove duplicates
const uniqueFiles = [...new Set(allFiles)];
// Get all files that match the pattern
const files = uniqueFiles;
// Ensure we only process actual files (not directories)
const validFiles = [];
for (const file of files) {
try {
const stats = await plugins.smartfile.fs.stat(file);
if (!stats.isDirectory()) {
validFiles.push(file);
}
}
catch (error) {
// Skip files that can't be accessed
logVerbose(`Skipping ${file} - cannot access: ${error.message}`);
}
}
// Check which files need formatting
for (const file of validFiles) {
// Skip files that haven't changed
if (!(await this.shouldProcessFile(file))) {
logVerbose(`Skipping ${file} - no changes detected`);
continue;
}
changes.push({
type: 'modify',
path: file,
module: this.name,
description: 'Format with Prettier',
});
}
logger.log('info', `Found ${changes.length} files to format with Prettier`);
return changes;
}
async execute(changes) {
const startTime = this.stats.moduleStartTime(this.name);
this.stats.startModule(this.name);
try {
await this.preExecute();
logVerbose(`Processing ${changes.length} files sequentially`);
// Process files sequentially to avoid prettier cache/state issues
for (let i = 0; i < changes.length; i++) {
const change = changes[i];
logVerbose(`Processing file ${i + 1}/${changes.length}: ${change.path}`);
try {
await this.applyChange(change);
this.stats.recordFileOperation(this.name, change.type, true);
}
catch (error) {
this.stats.recordFileOperation(this.name, change.type, false);
logger.log('error', `Failed to format ${change.path}: ${error.message}`);
// Don't throw - continue with other files
}
}
await this.postExecute();
}
catch (error) {
// Rollback removed - no longer tracking operations
throw error;
}
finally {
this.stats.endModule(this.name, startTime);
}
}
async applyChange(change) {
if (change.type !== 'modify')
return;
try {
// Validate the path before processing
if (!change.path || change.path.trim() === '') {
logger.log('error', `Invalid empty path in change: ${JSON.stringify(change)}`);
throw new Error('Invalid empty path');
}
// Read current content
const content = plugins.smartfile.fs.toStringSync(change.path);
// Format with prettier
const prettier = await import('prettier');
// Skip files that prettier can't parse without explicit parser
const fileExt = plugins.path.extname(change.path).toLowerCase();
if (!fileExt || fileExt === '') {
// Files without extensions need explicit parser
logVerbose(`Skipping ${change.path} - no file extension for parser inference`);
return;
}
try {
const formatted = await prettier.format(content, {
filepath: change.path,
...(await this.getPrettierConfig()),
});
// Only write if content actually changed
if (formatted !== content) {
// Debug: log the path being written
logVerbose(`Writing formatted content to: ${change.path}`);
await this.modifyFile(change.path, formatted);
logVerbose(`Formatted ${change.path}`);
}
else {
logVerbose(`No formatting changes for ${change.path}`);
}
}
catch (prettierError) {
// Check if it's a parser error
if (prettierError.message &&
prettierError.message.includes('No parser could be inferred')) {
logVerbose(`Skipping ${change.path} - ${prettierError.message}`);
return; // Skip this file silently
}
throw prettierError;
}
}
catch (error) {
// Log the full error stack for debugging mkdir issues
if (error.message && error.message.includes('mkdir')) {
logger.log('error', `Failed to format ${change.path}: ${error.message}`);
logger.log('error', `Error stack: ${error.stack}`);
}
else {
logger.log('error', `Failed to format ${change.path}: ${error.message}`);
}
throw error;
}
}
async getPrettierConfig() {
// Try to load prettier config from the project
const prettierConfig = new plugins.npmextra.Npmextra();
return prettierConfig.dataFor('prettier', {
// Default prettier config
singleQuote: true,
trailingComma: 'all',
printWidth: 80,
tabWidth: 2,
semi: true,
arrowParens: 'always',
});
}
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHJldHRpZXIuZm9ybWF0dGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vdHMvbW9kX2Zvcm1hdC9mb3JtYXR0ZXJzL3ByZXR0aWVyLmZvcm1hdHRlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sNkJBQTZCLENBQUM7QUFFNUQsT0FBTyxLQUFLLE9BQU8sTUFBTSxtQkFBbUIsQ0FBQztBQUM3QyxPQUFPLEVBQUUsTUFBTSxFQUFFLFVBQVUsRUFBRSxNQUFNLDBCQUEwQixDQUFDO0FBRTlELE1BQU0sT0FBTyxpQkFBa0IsU0FBUSxhQUFhO0lBQ2xELElBQUksSUFBSTtRQUNOLE9BQU8sVUFBVSxDQUFDO0lBQ3BCLENBQUM7SUFFRCxLQUFLLENBQUMsT0FBTztRQUNYLE1BQU0sT0FBTyxHQUFxQixFQUFFLENBQUM7UUFFckMsbUVBQW1FO1FBQ25FLE1BQU0sV0FBVyxHQUFHLENBQUMsSUFBSSxFQUFFLE1BQU0sRUFBRSxNQUFNLEVBQUUsT0FBTyxDQUFDLENBQUM7UUFFcEQsNEJBQTRCO1FBQzVCLE1BQU0sVUFBVSxHQUFHLG9EQUFvRCxDQUFDO1FBRXhFLHNDQUFzQztRQUN0QyxNQUFNLGVBQWUsR0FBRztZQUN0QixjQUFjO1lBQ2QsZUFBZTtZQUNmLGVBQWU7WUFDZixhQUFhO1lBQ2Isa0JBQWtCO1lBQ2xCLGdCQUFnQjtZQUNoQixXQUFXO1lBQ1gsV0FBVztZQUNYLGNBQWM7WUFDZCxjQUFjO1lBQ2QsK0RBQStEO1lBQy9ELGFBQWE7WUFDYixhQUFhO1lBQ2IsTUFBTTtTQUNQLENBQUM7UUFFRiw4QkFBOEI7UUFDOUIsTUFBTSxRQUFRLEdBQWEsRUFBRSxDQUFDO1FBRTlCLHdDQUF3QztRQUN4QyxLQUFLLE1BQU0sR0FBRyxJQUFJLFdBQVcsRUFBRSxDQUFDO1lBQzlCLE1BQU0sV0FBVyxHQUFHLEdBQUcsR0FBRyxTQUFTLFVBQVUsRUFBRSxDQUFDO1lBQ2hELE1BQU0s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