UNPKG

agentsqripts

Version:

Comprehensive static code analysis toolkit for identifying technical debt, security vulnerabilities, performance issues, and code quality problems

95 lines (85 loc) 4.88 kB
/** * @file Directory processing utility for recursive file analysis and batch operations * @description Single responsibility: Recursively process files in directory trees with robust error handling * * This utility provides systematic directory traversal and file processing capabilities that * enable batch analysis operations across entire project codebases. It implements recursive * directory walking with error handling, file filtering, and progress tracking to support * large-scale analysis workflows while maintaining performance and reliability. * * Design rationale: * - Recursive traversal enables comprehensive codebase analysis across nested directory structures * - Error isolation prevents individual file failures from stopping entire analysis operations * - File filtering supports targeted analysis of specific file types and patterns * - Progress tracking enables user feedback and operation monitoring for large codebases * - Memory-efficient implementation supports analysis of large directory trees * * Directory processing capabilities: * - Recursive directory tree traversal with configurable depth limits * - File type filtering based on extensions and naming patterns * - Individual file processing with comprehensive error handling and recovery * - Progress tracking and reporting for long-running analysis operations * - Batch operation optimization for efficient large-scale codebase analysis */ const qerrors = require('qerrors'); // Error logging utility const fs = require('fs').promises; // File system promises API const path = require('path'); // Path utilities /** * Walk directory recursively to process files * @param {string} currentPath - Directory currently being walked * @param {string} rootPath - Root directory for relative paths * @param {Array<string>} extensions - File extensions to include * @param {Array<string>} excludePatterns - Patterns to exclude * @param {Function} processFile - File processor callback * @param {Array} results - Accumulator for processed results * @returns {Promise<void>} Completion signal * @throws {Error} Propagates read or processing errors */ async function walkDirectory(currentPath, rootPath, extensions, excludePatterns, processFile, results) { try { console.log(`walkDirectory: scanning ${currentPath}`); // Log start of directory scan const entries = await fs.readdir(currentPath, { withFileTypes: true }); // Read directory entries for (const entry of entries) { // Iterate over each directory entry const fullPath = path.join(currentPath, entry.name); // Build absolute path to entry const relativePath = path.relative(rootPath, fullPath); // Compute path relative to root if (excludePatterns.some(pattern => relativePath.includes(pattern))) { // Skip excluded patterns continue; // Continue to next entry if pattern matched } if (entry.isDirectory()) { // Recurse into subdirectory await walkDirectory(fullPath, rootPath, extensions, excludePatterns, processFile, results); // Process subdirectory } else if (entry.isFile()) { // Handle file entries const ext = path.extname(entry.name).toLowerCase(); // Extract file extension if (extensions.includes(ext)) { // Check extension against allowed list const result = await processFile(fullPath, relativePath); // Execute provided file processor if (result) results.push(result); // Collect result when available } } } console.log(`walkDirectory: finished ${currentPath}`); // Log completion of directory scan } catch (error) { qerrors.default(error, 'walkDirectory failed', { currentPath }); // Report error with context throw error; // Propagate error for upstream handling } } /** * Process files in directory * @param {string} dirPath - Directory path * @param {Array<string>} extensions - File extensions * @param {Array<string>} excludePatterns - Patterns to exclude * @param {Function} processFile - File processor function * @returns {Promise<Array>} Processed results * @throws {Error} Propagates directory walking errors */ async function processDirectory(dirPath, extensions, excludePatterns, processFile) { const results = []; // Initialize results container try { console.log(`processDirectory: start ${dirPath}`); // Log start of processing await walkDirectory(dirPath, dirPath, extensions, excludePatterns, processFile, results); // Begin recursive walk console.log(`processDirectory: complete ${dirPath}`); // Log end of processing return results; // Return accumulated results } catch (error) { qerrors.default(error, 'processDirectory failed', { dirPath }); // Report error with context throw error; // Propagate error to caller } } module.exports = { processDirectory, walkDirectory }; // Export utilities