UNPKG

agentsqripts

Version:

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

175 lines (156 loc) 6.04 kB
/** * @file Report exporter for problem-scope CLI * @description Exports analysis results to various formats */ const fs = require('fs').promises; const path = require('path'); /** * Export analysis report to file * @param {Object} results - Analysis results * @param {string} filePath - Output file path */ async function exportReport(results, filePath) { const extension = path.extname(filePath).toLowerCase(); try { switch (extension) { case '.json': await exportJSON(results, filePath); break; case '.md': await exportMarkdown(results, filePath); break; case '.html': await exportHTML(results, filePath); break; default: // Default to JSON await exportJSON(results, filePath); } console.log(`📄 Report exported to: ${filePath}`); } catch (error) { console.error(`❌ Failed to export report: ${error.message}`); throw error; } } /** * Export results as JSON * @param {Object} results - Analysis results * @param {string} filePath - Output file path */ async function exportJSON(results, filePath) { const jsonContent = JSON.stringify(results, null, 2); await fs.writeFile(filePath, jsonContent, 'utf8'); } /** * Export results as Markdown * @param {Object} results - Analysis results * @param {string} filePath - Output file path */ async function exportMarkdown(results, filePath) { let markdown = `# Problem Scope Analysis Report\n\n`; // Metadata markdown += `## Analysis Metadata\n`; markdown += `- **Project Path**: ${results.metadata.projectPath}\n`; markdown += `- **Analysis Types**: ${results.metadata.analysisTypes.join(', ')}\n`; markdown += `- **Timestamp**: ${results.metadata.timestamp}\n`; markdown += `- **Execution Time**: ${results.metadata.executionTime}ms\n\n`; // Summary markdown += `## Summary\n`; markdown += `- **Overall Risk Level**: ${results.summary.overallRiskLevel}\n`; markdown += `- **Total Issues**: ${results.summary.totalIssues}\n`; markdown += `- **Critical Issues**: ${results.summary.criticalIssues}\n`; markdown += `- **Recommendations**: ${results.summary.recommendationsCount}\n\n`; // Individual analyses Object.entries(results.analyses).forEach(([type, analysis]) => { markdown += `## ${type.charAt(0).toUpperCase() + type.slice(1)} Analysis\n`; if (analysis.error) { markdown += `❌ **Error**: ${analysis.error}\n\n`; } else { markdown += `**Severity**: ${analysis.severity || 'N/A'}\n\n`; if (analysis.vulnerabilities) { markdown += `### Vulnerabilities (${analysis.vulnerabilities.length})\n`; analysis.vulnerabilities.slice(0, 5).forEach(vuln => { markdown += `- **${vuln.severity}**: ${vuln.title || vuln.description}\n`; }); if (analysis.vulnerabilities.length > 5) { markdown += `- ... and ${analysis.vulnerabilities.length - 5} more\n`; } markdown += `\n`; } if (analysis.violations) { markdown += `### Violations (${analysis.violations.length})\n`; analysis.violations.slice(0, 5).forEach(violation => { markdown += `- **${violation.severity}**: ${violation.description}\n`; }); if (analysis.violations.length > 5) { markdown += `- ... and ${analysis.violations.length - 5} more\n`; } markdown += `\n`; } } }); await fs.writeFile(filePath, markdown, 'utf8'); } /** * Export results as HTML * @param {Object} results - Analysis results * @param {string} filePath - Output file path */ async function exportHTML(results, filePath) { const html = ` <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Problem Scope Analysis Report</title> <style> body { font-family: Arial, sans-serif; margin: 40px; line-height: 1.6; } .header { background: #f4f4f4; padding: 20px; border-radius: 5px; } .summary { background: #e8f4f8; padding: 15px; border-radius: 5px; margin: 20px 0; } .analysis { margin: 20px 0; padding: 15px; border-left: 4px solid #007acc; } .critical { border-left-color: #d32f2f; } .high { border-left-color: #f57c00; } .medium { border-left-color: #fbc02d; } .low { border-left-color: #388e3c; } .error { background: #ffebee; color: #c62828; padding: 10px; border-radius: 3px; } ul { list-style-type: none; padding-left: 0; } li { padding: 5px 0; } </style> </head> <body> <div class="header"> <h1>Problem Scope Analysis Report</h1> <p><strong>Project:</strong> ${results.metadata.projectPath}</p> <p><strong>Analysis Types:</strong> ${results.metadata.analysisTypes.join(', ')}</p> <p><strong>Generated:</strong> ${results.metadata.timestamp}</p> </div> <div class="summary"> <h2>Summary</h2> <ul> <li><strong>Overall Risk Level:</strong> ${results.summary.overallRiskLevel}</li> <li><strong>Total Issues:</strong> ${results.summary.totalIssues}</li> <li><strong>Critical Issues:</strong> ${results.summary.criticalIssues}</li> <li><strong>Recommendations:</strong> ${results.summary.recommendationsCount}</li> </ul> </div> ${Object.entries(results.analyses).map(([type, analysis]) => ` <div class="analysis ${(analysis.severity || 'low').toLowerCase()}"> <h3>${type.charAt(0).toUpperCase() + type.slice(1)} Analysis</h3> ${analysis.error ? `<div class="error">Error: ${analysis.error}</div>` : `<p><strong>Severity:</strong> ${analysis.severity || 'N/A'}</p>` } </div> `).join('')} </body> </html> `; await fs.writeFile(filePath, html, 'utf8'); } module.exports = { exportReport, exportJSON, exportMarkdown, exportHTML };