agentsqripts
Version:
Comprehensive static code analysis toolkit for identifying technical debt, security vulnerabilities, performance issues, and code quality problems
83 lines (73 loc) • 3.01 kB
JavaScript
/**
* @file Project complexity analysis
* @description Analyzes complexity across entire project
*/
// Import from atomic modules
const { getAllFiles } = require('./fileCollector');
const { generateComplexityRecommendations } = require('./complexityRecommendationGenerator');
// Avoid circular dependency by importing analyzer components directly
const fs = require('fs');
const { promises: fsPromises } = require('fs');
const { calculateMaintainabilityIndex } = require('./maintainabilityCalculator');
const { calculateCyclomaticComplexity } = require('./cyclomaticCalculator');
const { calculateCognitiveComplexity } = require('./cognitiveComplexityCalculator');
const { determineComplexityLevel } = require('./complexityLevelDeterminer');
const { identifyComplexityIssues } = require('./complexityIssueDetector');
/**
* Analyze project-wide code complexity
* @param {string} projectPath - Project directory path
* @param {Object} options - Analysis options
* @returns {Object} Project complexity analysis
*/
async function analyzeProjectComplexity(projectPath, options = {}) {
const extensions = options.extensions || ['.js', '.ts', '.jsx', '.tsx'];
const excludePatterns = options.exclude || ['node_modules', '.git', 'dist', 'build'];
const files = await getAllFiles(projectPath, extensions, excludePatterns);
const results = [];
let totalComplexity = 0;
let highComplexityFiles = 0;
for (const file of files) {
try {
// Analyze file directly to avoid circular dependency
const content = await fsPromises.readFile(file, 'utf8');
const cyclomaticComplexity = calculateCyclomaticComplexity(content);
const cognitiveComplexity = calculateCognitiveComplexity(content);
const maintainabilityIndex = calculateMaintainabilityIndex(content);
const complexity = determineComplexityLevel(cyclomaticComplexity, cognitiveComplexity);
const issues = identifyComplexityIssues(content);
const analysis = {
file,
metrics: {
cyclomaticComplexity,
cognitiveComplexity,
maintainabilityIndex
},
complexity,
issues
};
results.push(analysis);
totalComplexity += cyclomaticComplexity;
if (complexity === 'HIGH' || complexity === 'CRITICAL') {
highComplexityFiles++;
}
} catch (error) {
console.warn(`Warning: Could not analyze ${file}: ${error.message}`);
}
}
const averageComplexity = results.length > 0
? Math.round(totalComplexity / results.length)
: 0;
return {
summary: {
filesAnalyzed: files.length,
averageComplexity,
highComplexityFiles,
totalIssues: results.reduce((sum, r) => sum + r.issues.length, 0)
},
files: results.filter(r => r.complexity === 'HIGH' || r.complexity === 'CRITICAL'),
recommendations: generateComplexityRecommendations(averageComplexity, highComplexityFiles)
};
}
module.exports = {
analyzeProjectComplexity
};