UNPKG

nodry

Version:

A CLI tool and Node.js library that warns about repetitive code to help you stay DRY.

68 lines (56 loc) 2.19 kB
const fs = require('fs').promises; const path = require('path'); async function analyze(filePath, options = {}) { const { lineThreshold = 3, blockSize = 2, blockThreshold = 2, } = options; const absolutePath = path.resolve(filePath); try { const content = await fs.readFile(absolutePath, 'utf-8'); // Remove block comments (/* ... */) and trim lines const uncommented = content.replace(/\/\*[\s\S]*?\*\//g, ''); const linesRaw = uncommented.split('\n'); const lines = linesRaw .map(l => l.trim()) .filter(l => l.length > 0 && !l.startsWith('//') && l !== '{' && l !== '}'); const lineCount = lines.reduce((acc, line) => { acc[line] = (acc[line] || 0) + 1; return acc; }, {}); const repeatedLines = Object.entries(lineCount) .filter(([, count]) => count >= lineThreshold); const blocksCount = {}; for (let i = 0; i <= lines.length - blockSize; i++) { const block = lines.slice(i, i + blockSize).join('\n'); blocksCount[block] = (blocksCount[block] || 0) + 1; } const repeatedBlocks = Object.entries(blocksCount) .filter(([, count]) => count >= blockThreshold); if (repeatedLines.length === 0 && repeatedBlocks.length === 0) { console.log(`[nodry] ✅ No significant repetition found in ${filePath}.`); return; } if (repeatedLines.length > 0) { console.warn(`[nodry] ⚠️ Repeated lines detected in ${filePath}:`); for (const [line, count] of repeatedLines) { console.warn(`- "${line}" repeated ${count} times`); } } if (repeatedBlocks.length > 0) { console.warn(`[nodry] ⚠️ Repeated blocks of ${blockSize} lines detected in ${filePath}:`); for (const [block, count] of repeatedBlocks) { const preview = block.split('\n').map(l => l.trim()).join(' | '); console.warn(`- Block repeated ${count} times: "${preview}"`); } } } catch (err) { if (err.code === 'ENOENT') { console.error(`[nodry] ❌ File not found: ${absolutePath}`); } else { console.error(`[nodry] ❌ Error reading file: ${err.message}`); } } } module.exports = analyze;