UNPKG

@sun-asterisk/sunlint

Version:

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

410 lines (315 loc) 10.9 kB
# Quality Scoring & Summary Report Guide ## Overview SunLint includes a comprehensive quality scoring system and summary report generation feature designed for CI/CD integration and management dashboards. ## Features ### 1. Quality Scoring System The quality score is calculated based on multiple factors: ```javascript Score Formula: 100 - (errorCount × 5 + warningCount × 1) × (1000 / LOC) + (rulesChecked × 0.5) ``` **Scoring Components:** - **Base Score**: Starts at 100 (perfect quality) - **Error Penalty**: -5 points per error - **Warning Penalty**: -1 point per warning - **LOC Normalization**: Violations are normalized per 1000 lines of code - **Rule Bonus**: +0.5 points per rule checked (max 10 points) - **Final Range**: 0-100 **Grade Scale:** - **A+**: 95-100 - **A**: 90-94 - **B+**: 85-89 - **B**: 80-84 - **C+**: 75-79 - **C**: 70-74 - **D**: 60-69 - **F**: Below 60 ### 2. Summary Report Format The summary report is generated in JSON format, designed for easy integration with CI/CD pipelines and management dashboards. **Example Output:** ```json { "metadata": { "generated_at": "2025-10-07T03:48:00.636Z", "tool": "SunLint", "version": "1.3.9", "analysis_duration_ms": 390 }, "repository": { "repository_url": "https://github.com/org/repo", "branch": "main", "commit_hash": "abc123" }, "quality": { "score": 98.9, "grade": "A+", "metrics": { "errors": 0, "warnings": 520, "rulesChecked": 1, "linesOfCode": 319709, "violationsPerKLOC": 1.6 } }, "violations": { "total": 520, "by_severity": { "errors": 0, "warnings": 520 }, "by_rule": [ { "rule_code": "C065", "count": 520, "severity": "warning" } ] }, "analysis": { "files_analyzed": 1000, "rules_checked": 1, "lines_of_code": 319709 } } ``` ## Usage ### Basic Usage ```bash # Generate summary report only node cli.js --input=src --rule=C065 --output-summary=summary.json # Generate both detailed report and summary report node cli.js --input=src --rule=C065 --output=report.txt --output-summary=summary.json ``` ### CI/CD Integration #### GitHub Actions Example ```yaml name: Code Quality Check on: pull_request: branches: [ main ] push: branches: [ main ] jobs: quality-check: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - name: Setup Node.js uses: actions/setup-node@v3 with: node-version: '18' - name: Install dependencies run: npm install - name: Run SunLint Analysis run: | node cli.js \ --input=src \ --rule=C001,C005,C015,C065 \ --output-summary=quality-report.json env: GITHUB_REPOSITORY: ${{ github.repository }} GITHUB_REF_NAME: ${{ github.ref_name }} GITHUB_SHA: ${{ github.sha }} - name: Upload Quality Report uses: actions/upload-artifact@v3 with: name: quality-report path: quality-report.json - name: Post to Dashboard run: | curl -X POST https://your-dashboard.com/api/quality \ -H "Content-Type: application/json" \ -H "Authorization: Bearer ${{ secrets.DASHBOARD_TOKEN }}" \ -d @quality-report.json ``` ### Environment Variables The summary report automatically detects and uses Git information from environment variables (commonly available in CI/CD): | Variable | Description | Source | Fallback | |----------|-------------|--------|----------| | `GITHUB_REPOSITORY` | Repository name (e.g., `owner/repo`) | GitHub Actions | Git remote URL | | `GITHUB_REF_NAME` | Branch or tag name | GitHub Actions | `git rev-parse --abbrev-ref HEAD` | | `GITHUB_SHA` | Commit hash | GitHub Actions | `git rev-parse HEAD` | | `GITHUB_EVENT_PATH` | Path to event payload JSON | GitHub Actions | - | | `GITHUB_EVENT_HEAD_COMMIT_MESSAGE` | Commit message | GitHub Actions | `git log -1 --pretty=%B` | | `GITHUB_EVENT_HEAD_COMMIT_AUTHOR_EMAIL` | Author email | GitHub Actions | `git log -1 --pretty=%ae` | | `GITHUB_EVENT_HEAD_COMMIT_AUTHOR_NAME` | Author name | GitHub Actions | `git log -1 --pretty=%an` | **Additional Fields Auto-Detected:** - **`repository_name`**: Extracted from repository URL - **`project_path`**: Relative path from repo root (for mono-repo support) - **`commit_message`**: From git log or GitHub event - **`author_email`**: From git log or GitHub event - **`author_name`**: From git log or GitHub event - **`pr_number`**: Extracted from commit message (e.g., "#123") or branch name (e.g., "pr-123") If environment variables are not available, the tool will automatically detect all Git information from the local repository. ## CLI Options ### `--output-summary <file>` Generate a summary report in JSON format suitable for CI/CD and management dashboards. **Differences from `--output`:** | Feature | `--output` | `--output-summary` | |---------|-----------|-------------------| | Format | Text/JSON (ESLint-compatible) | JSON (Custom format) | | Detail Level | Full violation details | Summary only | | File Size | Large (includes all details) | Small (summary only) | | Purpose | Detailed debugging | CI/CD integration | | Includes Score | No | Yes | | Includes LOC | No | Yes | | Git Info | No | Yes | | Violation Count by Rule | No | Yes | **Example:** ```bash # Detailed report: Shows every violation with line numbers and messages node cli.js --input=src --rule=C065 --output=detailed-report.txt # Summary report: Shows total count per rule, score, and metrics node cli.js --input=src --rule=C065 --output-summary=summary.json # Both: Get detailed report for debugging + summary for dashboard node cli.js --input=src --rule=C065 \ --output=detailed-report.txt \ --output-summary=summary.json ``` ## Integration Examples ### 1. Send to Management Dashboard ```javascript const fs = require('fs'); const axios = require('axios'); const report = JSON.parse(fs.readFileSync('summary.json', 'utf8')); await axios.post('https://dashboard.company.com/api/quality', { project: 'my-project', ...report }, { headers: { 'Authorization': `Bearer ${process.env.DASHBOARD_TOKEN}` } }); ``` ### 2. Slack Notification ```javascript const fs = require('fs'); const axios = require('axios'); const report = JSON.parse(fs.readFileSync('summary.json', 'utf8')); const { quality, violations, analysis } = report; const message = { text: `Code Quality Report: ${quality.grade} (${quality.score})`, blocks: [ { type: "section", text: { type: "mrkdwn", text: `*Code Quality Analysis*\n` + `Score: *${quality.score}* (${quality.grade})\n` + `Violations: ${violations.total} (${violations.by_severity.errors} errors, ${violations.by_severity.warnings} warnings)\n` + `Files: ${analysis.files_analyzed} | LOC: ${analysis.lines_of_code.toLocaleString()}` } } ] }; await axios.post(process.env.SLACK_WEBHOOK_URL, message); ``` ### 3. Quality Gate in CI/CD ```bash #!/bin/bash # Run analysis node cli.js --input=src --rule=C001,C005,C015,C065 --output-summary=quality.json # Extract score SCORE=$(jq -r '.quality.score' quality.json) # Set minimum score threshold MIN_SCORE=80 # Check if score meets threshold if (( $(echo "$SCORE < $MIN_SCORE" | bc -l) )); then echo "❌ Quality score $SCORE is below threshold $MIN_SCORE" exit 1 else echo "✅ Quality score $SCORE meets threshold" exit 0 fi ``` ## Best Practices ### 1. Rule Selection Choose rules appropriate for your quality goals: ```bash # Security focus node cli.js --input=src --rule=S001,S004,S010 --output-summary=security.json # Code organization focus node cli.js --input=src --rule=C001,C005,C006,C015 --output-summary=organization.json # Testing focus node cli.js --input=src --rule=C065,C066 --output-summary=testing.json # Comprehensive check (slower) node cli.js --input=src --rule=security,cleancode --output-summary=full.json ``` ### 2. Performance Optimization For large projects: ```bash # Analyze only changed files (PR mode) node cli.js --input=src --rule=C001,C005 --changed-files --output-summary=pr-quality.json # Set file limits for faster analysis node cli.js --input=src --rule=C001,C005 --max-files=500 --output-summary=quick-check.json ``` ### 3. Trending Analysis Track quality over time: ```javascript const fs = require('fs'); // Save with timestamp const report = JSON.parse(fs.readFileSync('summary.json', 'utf8')); const timestamp = new Date().toISOString(); // Store in database or time-series storage await db.collection('quality_reports').insertOne({ ...report, timestamp }); // Query trends const last30Days = await db.collection('quality_reports') .find({ timestamp: { $gte: new Date(Date.now() - 30 * 24 * 60 * 60 * 1000) } }) .sort({ timestamp: 1 }) .toArray(); // Calculate trend const scores = last30Days.map(r => r.quality.score); const trend = scores[scores.length - 1] - scores[0]; console.log(`Quality trend (30 days): ${trend > 0 ? '+' : ''}${trend.toFixed(1)}`); ``` ## Scoring Interpretation ### Score Ranges - **95-100 (A+)**: Excellent code quality with minimal violations - **90-94 (A)**: Very good quality, minor improvements possible - **85-89 (B+)**: Good quality with some areas for improvement - **80-84 (B)**: Acceptable quality, several improvements recommended - **75-79 (C+)**: Below average, significant improvements needed - **70-74 (C)**: Poor quality, requires immediate attention - **60-69 (D)**: Very poor quality, major refactoring needed - **0-59 (F)**: Critical quality issues ### Metrics Understanding **Violations per KLOC (Violations per 1000 Lines of Code)** This metric normalizes violations by code size: - **< 1**: Excellent - **1-3**: Good - **3-5**: Fair - **5-10**: Poor - **> 10**: Critical ## Troubleshooting ### LOC Calculation Issues If LOC is 0 or incorrect: ```bash # Ensure input path is correct node cli.js --input=./src --rule=C065 --output-summary=summary.json # For multiple paths node cli.js --input=./src,./lib --rule=C065 --output-summary=summary.json ``` ### Git Information Not Detected In CI/CD, ensure environment variables are set: ```yaml env: GITHUB_REPOSITORY: ${{ github.repository }} GITHUB_REF_NAME: ${{ github.ref_name }} GITHUB_SHA: ${{ github.sha }} ``` For local development: ```bash # Check if git is available git rev-parse --git-dir # Run from repository root cd /path/to/repo node /path/to/sunlint/cli.js --input=src --output-summary=summary.json ``` ## See Also - [Configuration Guide](CONFIGURATION.md) - [CI/CD Integration Guide](CI-CD-GUIDE.md) - [Command Examples](COMMAND-EXAMPLES.md)