# Static Analysis

Linting, type checking, and static application security testing (SAST) for code quality and security.

---

## Static Analysis Categories

| Category | Purpose | When It Runs |
|---|---|---|
| **Linting** | Style, best practices, potential bugs | Every commit (pre-commit), CI |
| **Type Checking** | Type safety, contract verification | Every commit, CI |
| **SAST** | Security vulnerabilities in code | CI, scheduled, pre-merge |
| **Dependency Scanning** | Vulnerable/outdated dependencies | CI, scheduled, PR |
| **Secrets Detection** | Hardcoded secrets, API keys | Pre-commit, CI, push |

---

## Language-Specific Tooling

### TypeScript / JavaScript

| Tool | Purpose | Config |
|---|---|---|
| **Biome** | Lint + format (fast, Rust) | `biome.json` |
| **ESLint** | Lint (extensible, plugin ecosystem) | `eslint.config.js` (flat) |
| **Prettier** | Format (opinionated) | `.prettierrc` |
| **TypeScript** | Type check | `tsconfig.json` |
| **tsc --noEmit** | Fast type check | — |

**Recommended: Biome** (replaces ESLint + Prettier + lint-staged)
```json
// biome.json
{
  "$schema": "https://biomejs.dev/schemas/1.8.0/schema.json",
  "organizeImports": { "enabled": true },
  "linter": {
    "enabled": true,
    "rules": {
      "recommended": true,
      "correctness": { "noUnusedVariables": "error" },
      "style": { "useConst": "error", "noNonNullAssertion": "warn" },
      "suspicious": { "noExplicitAny": "error" }
    }
  },
  "formatter": {
    "enabled": true,
    "indentStyle": "space",
    "indentWidth": 2,
    "lineWidth": 100
  },
  "javascript": {
    "formatter": { "quoteStyle": "double", "trailingCommas": "es5" }
  }
}
```

**TypeScript Strict Config**
```json
// tsconfig.json
{
  "compilerOptions": {
    "target": "ES2022",
    "module": "NodeNext",
    "moduleResolution": "NodeNext",
    "lib": ["ES2022"],
    "strict": true,
    "noUncheckedIndexedAccess": true,
    "exactOptionalPropertyTypes": true,
    "noImplicitReturns": true,
    "noFallthroughCasesInSwitch": true,
    "forceConsistentCasingInFileNames": true,
    "skipLibCheck": true,
    "resolveJsonModule": true,
    "declaration": true,
    "declarationMap": true,
    "sourceMap": true
  }
}
```

---

### Python

| Tool | Purpose |
|---|---|
| **Ruff** | Lint + format (replaces flake8, black, isort, pyupgrade) |
| **mypy** | Type checking |
| **pyright** | Fast type checking (VS Code Pylance) |

**Ruff Config**
```toml
# pyproject.toml
[tool.ruff]
target-version = "py311"
line-length = 100
select = [
  "E",   # pycodestyle
  "F",   # pyflakes
  "I",   # isort
  "UP",  # pyupgrade
  "B",   # flake8-bugbear
  "C4",  # flake8-comprehensions
  "PTH", # flake8-use-pathlib
  "TRY", # tryceratops
  "EM",  # flake8-errmsg
  "PIE", # flake8-pie
  "T20", # flake8-print
]
ignore = ["E501"]
fixable = ["ALL"]
unfixable = []

[tool.ruff.format]
quote-style = "double"
indent-style = "space"
```

**mypy Config**
```toml
# pyproject.toml
[tool.mypy]
python_version = "3.11"
strict = true
warn_return_any = true
warn_unused_ignores = true
disallow_untyped_defs = true
no_implicit_optional = true
warn_redundant_casts = true
warn_unused_ignores = true
check_untyped_defs = true
```

---

### Go

| Tool | Purpose |
|---|---|
| **golangci-lint** | Aggregates 50+ linters |
| **go vet** | Built-in suspicious code |
| **staticcheck** | Advanced static analysis |
| **govulncheck** | Vulnerability scanning |

**golangci-lint Config**
```yaml
# .golangci.yml
linters:
  enable:
    - errcheck
    - gosec
    - govet
    - ineffassign
    - staticcheck
    - unused
    - misspell
    - nakedret
    - prealloc
    - bodyclose
    - noctx
    - rowserrcheck
    - sqlclosecheck
    - errorlint
    - revive
    - goimports
linters-settings:
  errcheck:
    check-type-assertions: true
    check-blank: true
  gosec:
    excludes: [G104] # errors unhandled
  revive:
    rules:
      - name: exported
        disabled: true
issues:
  exclude-rules:
    - path: _test\.go
      linters: [errcheck, gosec, revive]
```

---

### Rust

| Tool | Purpose |
|---|---|
| **clippy** | Lint (built-in) |
| **rustfmt** | Format (built-in) |
| **cargo-audit** | Vulnerability scanning |
| **cargo-deny** | License, bans, sources policy |

**Clippy Config**
```toml
# Cargo.toml
[workspace.lints]
rust_2021_incompatible_closure_captures = "warn"
rust_2021_prefixes_incompatible_syntax = "warn"
rust_2021_prelude_collisions = "warn"

# clippy.toml (optional)
# [clippy]
# pedantic = true
# nursery = true
```

---

### JVM (Kotlin/Java/Scala)

| Tool | Language | Purpose |
|---|---|---|
| **detekt** | Kotlin | Linting |
| **ktlint** | Kotlin | Formatting + linting |
| **scalafix** | Scala | Linting + rewrites |
| **scalafmt** | Scala | Formatting |
| **Checkstyle** | Java | Linting |
| **SpotBugs** | Java | Bug patterns |
| **Error Prone** | Java | Compile-time error detection |

**detekt + ktlint (Kotlin)**
```kotlin
// build.gradle.kts
plugins {
    id("io.gitlab.arturbosch.detekt") version "1.23.0"
    id("org.jlleitschuh.gradle.ktlint") version "12.0.0"
}

detekt {
    config = files("config/detekt/detekt.yml")
    baseline = file("config/detekt/baseline.xml")
    reports {
        html.enabled = true
        xml.enabled = true
        sarif.enabled = true
    }
}

ktlint {
    reporters {
        plain {}
        checkstyle.outputFile = file("$buildDir/reports/ktlint/ktlint-checkstyle.xml")
    }
}
```

---

## Security (SAST)

### Open Source SAST
| Tool | Languages | Integration |
|---|---|---|
| **Semgrep** | 30+ | CLI, CI, IDE, rules registry |
| **CodeQL** | 10+ | GitHub Actions, CLI |
| **SonarQube** | 25+ | Server, CI, IDE |
| **Bearer** | JS/TS, Python, Ruby, Go | CLI, CI |
| **TruffleHog** | Secrets | CLI, CI, pre-commit |
| **GitLeaks** | Secrets | CLI, CI, pre-commit |

### Semgrep (Recommended — Fast, Customizable)
```yaml
# .semgrep.yml
rules:
  - id: no-sql-injection
    pattern-either:
      - pattern: execute($X, ...)
      - pattern: query($X, ...)
    message: "Potential SQL injection - use parameterized queries"
    languages: [python, javascript, typescript, go, java]
    severity: ERROR

  - id: hardcoded-secret
    pattern-either:
      - pattern: $X = "sk-..."
      - pattern: $X = "ghp_..."
      - pattern: $X = "xoxb-..."
    message: "Hardcoded secret detected"
    languages: [generic]
    severity: ERROR

  - id: path-traversal
    pattern: open($PATH, ...) where $PATH.contains("..")
    message: "Potential path traversal"
    languages: [python, go, java]
    severity: WARNING
```

```bash
# Run
semgrep ci --config=.semgrep.yml
# Or use registry
semgrep ci --config=p/ci --config=p/secrets --config=p/security-audit
```

### GitHub CodeQL
```yaml
# .github/workflows/codeql.yml
name: "CodeQL"
on:
  push:
    branches: [main]
  pull_request:
    branches: [main]
  schedule:
    - cron: '0 0 * * 0'

jobs:
  analyze:
    name: Analyze
    runs-on: ubuntu-latest
    permissions:
      actions: read
      contents: read
      security-events: write
    strategy:
      fail-fast: false
      matrix:
        language: [javascript, typescript, python, go, java, rust]
    steps:
      - uses: actions/checkout@v4
      - uses: github/codeql-action/init@v3
        with:
          languages: ${{ matrix.language }}
      - uses: github/codeql-action/analyze@v3
```

---

## Dependency Scanning

| Tool | Ecosystem | Features |
|---|---|---|
| **OWASP Dependency Check** | All (Java, JS, .NET, etc.) | CVE, NVD, Sonatype OSS Index |
| **Snyk** | All | CLI, IDE, PR checks, auto-fix |
| **Dependabot** | GitHub native | Auto-PRs, security alerts |
| **Renovate** | All platforms | Flexible, auto-merge, group updates |
| **Trivy** | Containers, FS, Git | Vulns, misconfig, secrets, SBOM |
| **Grype** | Containers, FS | Syft SBOM input, fast |
| **cargo-audit / govulncheck / pip-audit** | Lang-specific | Lockfile analysis |

**Recommended: Renovate + Trivy**
```json
// renovate.json
{
  "$schema": "https://docs.renovatebot.com/renovate-schema.json",
  "extends": ["config:recommended"],
  "packageRules": [
    { "matchUpdateType": "minor", "matchCurrentVersion": "!/^0\\./", "automerge": true },
    { "matchUpdateType": "patch", "automerge": true },
    { "matchDatasource": "github-releases", "enabled": false }
  ],
  "schedule": ["every weekend"],
  "timezone": "UTC",
  "prConcurrentLimit": 10
}
```

```yaml
# .github/workflows/trivy.yml
name: Trivy Scan
on: [push, pull_request]
jobs:
  fs:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Run Trivy
        uses: aquasecurity/trivy-action@master
        with:
          scan-type: 'fs'
          format: 'sarif'
          output: 'trivy-results.sarif'
      - name: Upload to Code Scanning
        uses: github/codeql-action/upload-sarif@v3
        with:
          sarif_file: 'trivy-results.sarif'
```

---

## Secrets Detection

### Pre-commit (Local)
```yaml
# .pre-commit-config.yaml
repos:
  - repo: https://github.com/gitleaks/gitleaks
    rev: v8.18.0
    hooks:
      - id: gitleaks
        args: [--verbose]

  - repo: https://github.com/trufflesecurity/trufflehog
    rev: v3.70.0
    hooks:
      - id: trufflehog
        args: [--no-fail, --json]

  - repo: https://github.com/pre-commit/pre-commit-hooks
    rev: v4.5.0
    hooks:
      - id: detect-private-key
      - id: detect-aws-credentials
```

### CI (Blocking)
```yaml
# .github/workflows/secrets.yml
name: Secrets Scan
on: [push, pull_request]
jobs:
  gitleaks:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with: { fetch-depth: 0 }
      - uses: gitleaks/gitleaks-action@v2
        env:
          GITLEAKS_LICENSE: ${{ secrets.GITLEAKS_LICENSE }}
```

---

## CI/CD Integration

### Pre-commit Hooks (All Languages)
```yaml
# .pre-commit-config.yaml
repos:
  - repo: local
    hooks:
      - id: biome
        name: Biome (JS/TS)
        entry: biome check --write
        language: system
        types: [javascript, typescript, json]
      - id: ruff
        name: Ruff (Python)
        entry: ruff check --fix
        language: system
        types: [python]
      - id: golangci-lint
        name: golangci-lint (Go)
        entry: golangci-lint run
        language: system
        types: [go]
      - id: cargo-clippy
        name: Clippy (Rust)
        entry: cargo clippy --workspace -- -D warnings
        language: system
        types: [rust]
```

### CI Pipeline Stages
```yaml
# .github/workflows/ci.yml
jobs:
  static-analysis:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      
      # Language-specific
      - name: Biome
        run: biome ci .
      - name: TypeScript
        run: tsc --noEmit
      - name: Ruff
        run: ruff check .
      - name: mypy
        run: mypy src
      - name: golangci-lint
        run: golangci-lint run ./...
      - name: Clippy
        run: cargo clippy --workspace -- -D warnings
      - name: detekt
        run: ./gradlew detekt
      
      # Security
      - name: Semgrep
        uses: returntocorp/semgrep-action@v1
      - name: Trivy FS
        uses: aquasecurity/trivy-action@master
        with:
          scan-type: 'fs'
      - name: Secrets
        uses: gitleaks/gitleaks-action@v2
```

---

## Metrics & Quality Gates

### Quality Gate Thresholds
| Metric | Warning | Fail |
|---|---|---|
| **Code Coverage** | < 80% | < 60% |
| **Duplicated Lines** | > 3% | > 5% |
| **Complexity (cyclomatic)** | > 15 | > 25 |
| **Maintainability Index** | < 70 | < 50 |
| **Security Hotspots** | > 0 | > 0 (critical) |
| **Vulnerable Dependencies** | Any | Any (high/critical) |

### SonarQube / SonarCloud
```yaml
# sonar-project.properties
sonar.projectKey=my-org_my-service
sonar.sources=src
sonar.tests=tests
sonar.exclusions=**/node_modules/**,**/target/**,**/dist/**
sonar.coverage.exclusions=**/*Test*,**/*Spec*
sonar.typescript.lcov.reportPaths=coverage/lcov.info
sonar.python.coverage.reportPaths=coverage.xml
sonar.go.coverage.reportPaths=coverage.out
```

---

## Related Notes

- [[Tools/Developer-Tools]] — IDE integration
- [[Tools/Build-Tools]] — Build pipeline integration
- [[Tools/Package-Management]] — Dependency scanning
- [[Security/Secure-Coding]] — Secure coding practices
- [[Security/Supply-Chain-Security]] — SBOM, signing
- [[DevOps/CI-CD-Best-Practices]] — Pipeline gates

---

*Sources: Biome, ESLint, TypeScript, Ruff, mypy, golangci-lint, clippy, detekt, ktlint, Semgrep, CodeQL, Trivy, Renovate, Dependabot, OWASP, GitHub Security, pre-commit*