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.

183 lines 15.2 kB
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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