.pre-commit-config.yaml#

# .pre-commit-config.yaml
# Add robust pre-commit hook: always run mkdocs build before commit to ensure docs/code/ is synkroniserad och att dokumentationskällan kan byggas felfritt.
repos:
  - repo: https://github.com/pre-commit/pre-commit-hooks
    rev: v6.0.0
    hooks:
      - id: check-yaml
        args:
          - --allow-multiple-documents
        exclude: ^(backup_mkdocs_|site/)
      - id: end-of-file-fixer
      - id: trailing-whitespace

  # --- FORMATTER BLOCK: Format sources FIRST, synka till docs/code SEN med redan formatterad kod ---
  # 1. Run all formatters on src/app and everywhere else
  - repo: https://github.com/psf/black
    rev: 25.1.0
    hooks:
      - id: black
        name: black
        language_version: python3.11
        files: ^(src/|tests/|scripts/).+\.py$
        # Exclude generated documentation snapshots to avoid linting
        # duplicated sources under the docs tree (if present).
        exclude: ^docs/code/|^docs_sphinx/source/code/
        args:
          - --line-length=88
          - --target-version=py310

  - repo: https://github.com/PyCQA/isort
    rev: 6.0.1
    hooks:
      - id: isort
        name: isort (import sort)
        language_version: python3.11
        files: ^(src/|tests/|scripts/).+\.py$
        exclude: ^docs/code/|^docs_sphinx/source/code/
        args:
          - --profile=black

  # NOTE: autopep8 removed to avoid fighting Black formatting.
  # Running multiple formatters that change style differently causes infinite
  # modification loops (Black -> autopep8 -> rsync -> Black ...). Black is the
  # single source of truth for formatting; isort is aligned with Black.

  # 2. Now sync (rsync) formatterad kod till docs/code – nu får endast korrekt formatterad kod kopieras och inkluderas i docs.

# ================================================================================================ #
# SECTION: BASIC LINTERS                                                                            #
# ================================================================================================ #
# WHY: Basic code quality checks catch common mistakes and enforce style guidelines before
# code reaches more specialized linters.

  # -- Trailing Whitespace Remover --
  # Removes trailing whitespace that can cause diff noise and style inconsistencies
  - repo: https://github.com/pre-commit/pre-commit-hooks
    rev: v6.0.0
    hooks:
      - id: trailing-whitespace

# ================================================================================================ #
# SECTION: PYTHON-SPECIFIC LINTERS                                                                  #
# ================================================================================================ #
# WHY: Python-specific linters understand Python syntax and catch language-specific issues
# that general linters might miss.

  # -- Flake8 Linter --
  # Comprehensive Python linting with extensions for documentation, bug detection, and style
  - repo: https://github.com/PyCQA/flake8
    rev: 7.3.0
    hooks:
      - id: flake8
        additional_dependencies:
          - flake8-bugbear
          - flake8-docstrings
          - flake8-black
        # Ensure flake8 does not lint transient/duplicated doc snapshots.
        exclude: ^docs/code/|^docs_sphinx/source/code/
        args:
          - --max-line-length=88
          - --extend-ignore=E203,W503,W504
          - --select=E,F,W,B,B950
          - --docstring-convention=numpy

  # -- Documentation Linter --
  # Ensures reStructuredText files in documentation follow consistent formatting
  - repo: https://github.com/PyCQA/doc8
    rev: "v2.0.0"
    hooks:
      - id: doc8
        name: doc8 (reStructuredText lint)
        entry: doc8
        language: python
        additional_dependencies:
          - doc8
        types: [rst]

# ================================================================================================ #
# SECTION: STATIC TYPE ANALYSIS                                                                     #
# ================================================================================================ #
# WHY: Static analysis is disabled in pre-commit due to virtual environment conflicts.
# Run mypy manually with: mypy --strict --config-file=mypy.ini src/
#
# NOTE: Type checking must be performed separately to avoid environment-specific issues
# that can break the pre-commit workflow for different developers.

# ================================================================================================ #
# SECTION: SECURITY ANALYSIS                                                                        #
# ================================================================================================ #
# WHY: Security scanning catches potential vulnerabilities and insecure coding patterns
# before they reach production.

  # -- Bandit Security Linter --
  # Scans Python code for common security vulnerabilities and insecure practices
  - repo: https://github.com/PyCQA/bandit
    rev: 1.8.6
    hooks:
      - id: bandit
        name: bandit (security linter)
        # Avoid scanning generated documentation snapshots
        exclude: ^(tests/|persistent-data/logs/|docs/code/|docs_sphinx/source/code/)
        args:
          - --exclude=tests,persistent-data/logs,docs/code,docs_sphinx/source/code
          - --format=custom
          - --severity-level=medium

# ================================================================================================ #
# SECTION: DEPENDENCY SECURITY                                                                      #
# ================================================================================================ #
# WHY: Dependency vulnerabilities can introduce security risks even if application code
# is secure. Regular scanning ensures third-party dependencies are safe to use.

  # -- Local Dependency Vulnerability Scanner --
  # Uses pip-audit to check Python dependencies for known security vulnerabilities
  - repo: local
    hooks:
      - id: pip-audit
        name: pip-audit (dependency vulnerability scanner)
        entry: pip-audit
        language: python
        additional_dependencies:
          - pip-audit
        args:
          - --desc
          - --progress-spinner=off
          - --cache-dir=/tmp/pip-audit-cache
        pass_filenames: false