UNPKG

@sun-asterisk/sunlint

Version:

☀️ SunLint - Multi-language static analysis tool for code quality and security | Sun* Engineering Standards

244 lines (213 loc) 7.81 kB
/** * 🚀 Auto Performance Manager for SunLint * Automatically detects optimal performance settings based on project characteristics * GOAL: Simplify CLI by reducing user choices while maintaining performance */ const fs = require('fs'); const path = require('path'); class AutoPerformanceManager { constructor() { // Smart defaults based on project analysis this.performanceProfiles = { auto: { name: 'Auto-Detect', detect: true, description: 'Automatically choose best settings based on project size' }, fast: { name: 'Fast', timeout: 30000, // 30s batchSize: 20, maxFiles: 500, description: 'Quick analysis for small projects (<100 files)' }, careful: { name: 'Careful', timeout: 120000, // 2 minutes batchSize: 10, maxFiles: 1500, progressiveResults: true, description: 'Thorough analysis for large projects (>500 files)' } }; } /** * 🎯 Get optimal performance settings with minimal user input * Clarifies the difference between max-files and max-semantic-files: * - max-files: Total files to analyze (performance limit) * - max-semantic-files: Files to load into TypeScript symbol table (memory limit) */ getOptimalSettings(options, targetFiles = []) { const mode = options.performance || 'auto'; if (mode === 'auto') { return this.autoDetectSettings(options, targetFiles); } return this.getProfileSettings(mode, options); } /** * 🤖 Auto-detect optimal settings based on project characteristics */ autoDetectSettings(options, targetFiles) { const projectAnalysis = this.analyzeProject(options, targetFiles); const profile = this.selectOptimalProfile(projectAnalysis); if (options.verbose) { console.log(`🤖 Auto-detected performance profile: ${profile.name}`); console.log(` 📊 Project: ${projectAnalysis.fileCount} files, ${projectAnalysis.size} size`); console.log(` ⚡ Settings: ${profile.timeout/1000}s timeout, ${profile.batchSize} rules/batch`); } return { ...profile, autoDetected: true, projectAnalysis }; } /** * 📊 Analyze project to determine optimal settings */ analyzeProject(options, targetFiles) { const fileCount = targetFiles.length; const inputPath = options.input || process.cwd(); // Estimate project complexity const hasNodeModules = fs.existsSync(path.join(inputPath, 'node_modules')); const hasPackageJson = fs.existsSync(path.join(inputPath, 'package.json')); const hasTsConfig = fs.existsSync(path.join(inputPath, 'tsconfig.json')); const hasGitIgnore = fs.existsSync(path.join(inputPath, '.gitignore')); // Simple heuristics for project size let size = 'small'; let complexity = 'simple'; if (fileCount > 1000) { size = 'enterprise'; complexity = 'complex'; } else if (fileCount > 500) { size = 'large'; complexity = hasNodeModules && hasTsConfig ? 'complex' : 'medium'; } else if (fileCount > 100) { size = 'medium'; complexity = hasTsConfig ? 'medium' : 'simple'; } return { fileCount, size, complexity, hasNodeModules, hasPackageJson, hasTsConfig, hasGitIgnore, inputPath }; } /** * 🎯 Select optimal profile based on project analysis */ selectOptimalProfile(analysis) { if (analysis.fileCount <= 100) { return { name: 'Auto-Fast', timeout: 30000, batchSize: 20, maxFiles: 200, // Analysis limit maxSemanticFiles: 100, // Symbol table limit (smaller for memory) description: `Small project (${analysis.fileCount} files) - fast analysis` }; } if (analysis.fileCount <= 500) { return { name: 'Auto-Balanced', timeout: 60000, batchSize: 15, maxFiles: 600, // Analysis limit maxSemanticFiles: 300, // Symbol table limit progressiveResults: true, description: `Medium project (${analysis.fileCount} files) - balanced analysis` }; } if (analysis.fileCount <= 1000) { return { name: 'Auto-Careful', timeout: 120000, batchSize: 10, maxFiles: 1200, // Analysis limit maxSemanticFiles: 500, // Symbol table limit progressiveResults: true, streamingAnalysis: analysis.complexity === 'complex', description: `Large project (${analysis.fileCount} files) - careful analysis` }; } // Enterprise projects return { name: 'Auto-Enterprise', timeout: 300000, batchSize: 5, maxFiles: 1500, // Analysis limit maxSemanticFiles: 300, // Conservative symbol table limit progressiveResults: true, streamingAnalysis: true, smartSampling: true, description: `Enterprise project (${analysis.fileCount} files) - conservative analysis` }; } /** * ⚙️ Get predefined profile settings */ getProfileSettings(mode, options) { const profile = this.performanceProfiles[mode]; if (!profile) { console.warn(`⚠️ Unknown performance mode: ${mode}, using auto-detect`); return this.autoDetectSettings(options, []); } // Override with user-specified options const settings = { ...profile }; if (options.timeout && options.timeout !== '0') { settings.timeout = parseInt(options.timeout); } if (options.maxFiles && options.maxFiles !== '1000') { settings.maxFiles = parseInt(options.maxFiles); } return settings; } /** * 📋 Get user-friendly performance recommendations */ getPerformanceRecommendations(options, targetFiles) { const analysis = this.analyzeProject(options, targetFiles); const profile = this.selectOptimalProfile(analysis); const recommendations = [ `🎯 Recommended: sunlint --all --input=${options.input || 'src'} --performance=auto` ]; if (analysis.fileCount > 500) { recommendations.push(`💡 For faster results: sunlint --all --input=${options.input || 'src'} --performance=fast --max-files=300`); } if (analysis.complexity === 'complex') { recommendations.push(`⚡ For thorough analysis: sunlint --all --input=${options.input || 'src'} --performance=careful --verbose`); } return { analysis, profile, recommendations }; } /** * 🎛️ Show simplified CLI usage for common scenarios */ static getSimplifiedUsageExamples() { return { quickStart: [ 'sunlint --all --input=src', // Auto-detect everything 'sunlint --rules=C019,C041,S027 --input=src', // Specific rules 'sunlint --quality --input=src' // Quality rules only ], performance: [ 'sunlint --all --input=src --performance=auto', // Auto-detect (default) 'sunlint --all --input=src --performance=fast', // Quick scan 'sunlint --all --input=src --performance=careful', // Thorough analysis 'sunlint --all --input=src --timeout=60000' // Custom timeout ], advanced: [ 'sunlint --all --input=src --verbose', // See detailed progress 'sunlint --all --input=src --dry-run', // Preview analysis 'sunlint --all --input=src --format=json' // JSON output ] }; } } module.exports = AutoPerformanceManager;