# Code Quality Reference

Comprehensive guide to code quality analysis with SonarQube and related tools.

## SonarQube

Continuous code quality and security analysis platform.

**Container**: `sonarqube:10-community`
**URL**: http://localhost:9000
**Default Credentials**: admin/admin (change on first login)

### Initial Setup

```bash
# Start SonarQube
docker-compose up -d sonarqube sonarqube-db

# Wait for startup (can take 2-3 minutes)
docker-compose logs -f sonarqube

# Access UI
open http://localhost:9000
```

### Project Configuration

```properties
# sonar-project.properties
sonar.projectKey=my-project
sonar.projectName=My Project
sonar.projectVersion=1.0

# Source configuration
sonar.sources=src
sonar.tests=tests
sonar.exclusions=**/node_modules/**,**/vendor/**,**/*.test.js

# Language-specific settings
sonar.javascript.lcov.reportPaths=coverage/lcov.info
sonar.php.coverage.reportPaths=coverage/clover.xml
sonar.python.coverage.reportPaths=coverage.xml

# Encoding
sonar.sourceEncoding=UTF-8

# Quality gate
sonar.qualitygate.wait=true
sonar.qualitygate.timeout=300
```

### Running Analysis

```bash
# Using Docker scanner
docker run --rm \
  --network testing-network \
  -e SONAR_HOST_URL="http://sonarqube:9000" \
  -e SONAR_LOGIN="admin" \
  -e SONAR_PASSWORD="admin" \
  -v "${PWD}:/usr/src" \
  sonarsource/sonar-scanner-cli

# Using CLI scanner
sonar-scanner \
  -Dsonar.projectKey=my-project \
  -Dsonar.sources=. \
  -Dsonar.host.url=http://localhost:9000 \
  -Dsonar.login=YOUR_TOKEN

# For specific branch
sonar-scanner \
  -Dsonar.branch.name=feature/my-feature

# For pull request
sonar-scanner \
  -Dsonar.pullrequest.key=123 \
  -Dsonar.pullrequest.branch=feature/my-feature \
  -Dsonar.pullrequest.base=main
```

### Quality Gates

Quality gates define the conditions that must be met for code to pass.

#### Default Conditions

| Metric | Operator | Threshold |
|--------|----------|-----------|
| Coverage on New Code | < | 80% |
| Duplicated Lines on New Code | > | 3% |
| Maintainability Rating | > | A |
| Reliability Rating | > | A |
| Security Rating | > | A |
| Security Hotspots Reviewed | < | 100% |

#### Custom Quality Gate

```json
{
  "name": "Custom Strict Gate",
  "conditions": [
    {
      "metric": "coverage",
      "op": "LT",
      "error": "80"
    },
    {
      "metric": "duplicated_lines_density",
      "op": "GT",
      "error": "3"
    },
    {
      "metric": "blocker_violations",
      "op": "GT",
      "error": "0"
    },
    {
      "metric": "critical_violations",
      "op": "GT",
      "error": "0"
    },
    {
      "metric": "code_smells",
      "op": "GT",
      "error": "50"
    }
  ]
}
```

### Quality Profiles

Quality profiles define which rules are active for analysis.

#### Built-in Profiles

| Language | Profile | Rules |
|----------|---------|-------|
| Java | Sonar way | 400+ |
| JavaScript | Sonar way | 200+ |
| Python | Sonar way | 150+ |
| PHP | Sonar way | 150+ |
| TypeScript | Sonar way | 200+ |

#### Rule Categories

| Type | Description | Priority |
|------|-------------|----------|
| Bug | Code that is demonstrably wrong | Fix immediately |
| Vulnerability | Security-related issues | Fix immediately |
| Code Smell | Maintainability issues | Plan to fix |
| Security Hotspot | Code to review for security | Review manually |

### Metrics Explained

#### Size Metrics

| Metric | Description |
|--------|-------------|
| Lines of Code (LOC) | Physical lines of code |
| Statements | Number of statements |
| Functions | Number of functions |
| Classes | Number of classes |
| Files | Number of files |
| Directories | Number of directories |

#### Complexity Metrics

| Metric | Description | Target |
|--------|-------------|--------|
| Cyclomatic Complexity | Number of decision paths | < 10 per function |
| Cognitive Complexity | How hard code is to understand | < 15 per function |
| Complexity / Function | Average complexity | < 5 |

#### Duplication Metrics

| Metric | Description | Target |
|--------|-------------|--------|
| Duplicated Lines | Lines that are duplicated | < 3% |
| Duplicated Blocks | Number of duplicated blocks | Minimize |
| Duplicated Files | Files with duplication | 0 |

#### Coverage Metrics

| Metric | Description | Target |
|--------|-------------|--------|
| Coverage | Overall line coverage | > 80% |
| Line Coverage | Lines covered by tests | > 80% |
| Branch Coverage | Branches covered | > 70% |
| Condition Coverage | Conditions tested | > 70% |

#### Maintainability Metrics

| Rating | Technical Debt Ratio | Description |
|--------|---------------------|-------------|
| A | < 5% | Very maintainable |
| B | 5% - 10% | Maintainable |
| C | 10% - 20% | Needs attention |
| D | 20% - 50% | Poor maintainability |
| E | > 50% | Critical issues |

### API Usage

```bash
# Get project status
curl -u admin:admin "http://localhost:9000/api/qualitygates/project_status?projectKey=my-project"

# Get issues
curl -u admin:admin "http://localhost:9000/api/issues/search?componentKeys=my-project&types=BUG,VULNERABILITY&severities=CRITICAL,BLOCKER"

# Get metrics
curl -u admin:admin "http://localhost:9000/api/measures/component?component=my-project&metricKeys=coverage,bugs,vulnerabilities,code_smells"

# Generate token
curl -u admin:admin -X POST "http://localhost:9000/api/user_tokens/generate?name=ci-token"
```

### CI/CD Integration

#### GitHub Actions

```yaml
name: SonarQube Analysis
on: [push, pull_request]

jobs:
  sonarqube:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
        with:
          fetch-depth: 0

      - name: SonarQube Scan
        uses: sonarsource/sonarqube-scan-action@master
        env:
          SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
          SONAR_HOST_URL: ${{ secrets.SONAR_HOST_URL }}

      - name: Quality Gate
        uses: sonarsource/sonarqube-quality-gate-action@master
        timeout-minutes: 5
        env:
          SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
```

#### GitLab CI

```yaml
sonarqube-check:
  stage: test
  image: sonarsource/sonar-scanner-cli:latest
  variables:
    SONAR_USER_HOME: "${CI_PROJECT_DIR}/.sonar"
    GIT_DEPTH: 0
  cache:
    key: "${CI_JOB_NAME}"
    paths:
      - .sonar/cache
  script:
    - sonar-scanner
  allow_failure: true
  only:
    - merge_requests
    - main
```

## Code Quality Patterns

### Pattern 1: Pre-Commit Analysis

```bash
#!/bin/bash
# pre-commit hook

# Run quick analysis
sonar-scanner \
  -Dsonar.analysis.mode=preview \
  -Dsonar.issuesReport.console.enable=true \
  -Dsonar.issuesReport.html.enable=false

# Check for blockers
if grep -q "BLOCKER" .scannerwork/sonar-report.json; then
  echo "Blocker issues found. Commit blocked."
  exit 1
fi
```

### Pattern 2: Coverage Enforcement

```javascript
// jest.config.js
module.exports = {
  collectCoverage: true,
  coverageDirectory: 'coverage',
  coverageReporters: ['lcov', 'text'],
  coverageThreshold: {
    global: {
      branches: 80,
      functions: 80,
      lines: 80,
      statements: 80
    }
  }
};
```

### Pattern 3: Multi-Language Project

```properties
# sonar-project.properties for monorepo

sonar.projectKey=my-monorepo
sonar.projectName=My Monorepo

# Multiple modules
sonar.modules=frontend,backend,shared

# Frontend (React)
frontend.sonar.projectName=Frontend
frontend.sonar.sources=packages/frontend/src
frontend.sonar.tests=packages/frontend/tests
frontend.sonar.javascript.lcov.reportPaths=packages/frontend/coverage/lcov.info

# Backend (Python)
backend.sonar.projectName=Backend
backend.sonar.sources=packages/backend/src
backend.sonar.tests=packages/backend/tests
backend.sonar.python.coverage.reportPaths=packages/backend/coverage.xml

# Shared (TypeScript)
shared.sonar.projectName=Shared
shared.sonar.sources=packages/shared/src
shared.sonar.exclusions=**/*.test.ts
```

## Allure Integration

Generate comprehensive test reports that integrate with SonarQube findings.

### Configuration

```yaml
# allure environment
allure:
  image: frankescobar/allure-docker-service:latest
  environment:
    CHECK_RESULTS_EVERY_SECONDS: 3
    KEEP_HISTORY: 25
  volumes:
    - ./reports/allure-results:/app/allure-results
    - ./reports/allure-reports:/app/default-reports
```

### Generating Reports

```bash
# Generate report
curl -X GET "http://localhost:5050/allure-docker-service/generate-report"

# Clean results
curl -X GET "http://localhost:5050/allure-docker-service/clean-results"

# Get latest report URL
curl -X GET "http://localhost:5050/allure-docker-service/latest-report"
```

### Environment Properties

```properties
# allure-results/environment.properties
Project=My Project
Branch=main
SonarQube.URL=http://localhost:9000
SonarQube.Project=my-project
Environment=CI
Build.Number=${BUILD_NUMBER}
```

## Best Practices

### Code Quality

1. **Fix issues early** - Address issues when introduced
2. **Focus on new code** - Apply stricter standards to new code
3. **Track technical debt** - Monitor and plan remediation
4. **Set realistic thresholds** - Gradually increase standards
5. **Exclude generated code** - Don't analyze auto-generated files

### Coverage

1. **Test critical paths** - Focus on business-critical code
2. **Branch coverage** - Test all decision branches
3. **Avoid coverage hacks** - Don't write tests just for coverage
4. **Review uncovered code** - Determine if coverage is needed
5. **Track trends** - Monitor coverage over time

### Integration

1. **Fail fast** - Block builds on critical issues
2. **Provide feedback** - Show results in PR comments
3. **Automate** - Run analysis on every commit
4. **Monitor trends** - Track quality metrics over time
5. **Customize rules** - Tailor to your tech stack

## Troubleshooting

### SonarQube Won't Start

```bash
# Check Elasticsearch memory
sudo sysctl -w vm.max_map_count=262144

# Increase Docker memory
# Docker Desktop > Preferences > Resources > Memory > 4GB+

# Check logs
docker-compose logs sonarqube
```

### Analysis Fails

```bash
# Enable debug logging
sonar-scanner -X

# Check scanner logs
cat .scannerwork/sonar-scanner.log

# Verify connectivity
curl -u admin:admin http://localhost:9000/api/system/status
```

### Coverage Not Showing

```bash
# Verify report exists
ls -la coverage/lcov.info

# Check report path in config
cat sonar-project.properties | grep reportPaths

# Verify report format
head -20 coverage/lcov.info
```
