exclude: '(crates/assets/js/bindings|crates/schema/bindings|vendor)/.*'

repos:
-   repo: https://github.com/pre-commit/pre-commit-hooks
    rev: v4.6.0
    hooks:
    -   id: check-byte-order-marker
    -   id: check-case-conflict
    -   id: check-merge-conflict
    -   id: check-symlinks
    # TODO: Looks like check-yaml struggles with some valid `pnpm-lock.yaml`s
    # -   id: check-yaml
    -   id: end-of-file-fixer
    -   id: mixed-line-ending
    -   id: trailing-whitespace

# Self-validation for pre-commit manifest.
-   repo: https://github.com/pre-commit/pre-commit
    rev: v3.8.0
    hooks:
    -   id: validate_manifest

-   repo: local
    hooks:
    ### Rust ###
    - id: cargofmt
      name: Cargo Format
      entry: cargo fmt -- --check
      # NOTE: `system` refers to the `entry` above, which is shell.
      language: system
      # NOTE: types are based on `identify-cli <filename>`, e.g. ["file", "python", "text"].
      types: [rust]
      exclude: '^vendor/'
      pass_filenames: false

    - id: cargoclippy
      name: Cargo Clippy
      # Be verbose to at least still see warnings scroll by.
      verbose: true
      entry: sh -c 'pnpm i --frozen-lockfile --prefer-offline && PNPM_OFFLINE=TRUE cargo clippy --workspace  --features=geos,wasm --no-deps'
      language: system
      types: [rust]
      exclude: '^vendor/'
      pass_filenames: false

    - id: cargotest
      name: Cargo Test
      entry: sh -c 'pnpm i --frozen-lockfile --prefer-offline && PNPM_OFFLINE=TRUE cargo test --workspace --features=geos,wasm -- --show-output'
      language: system
      types: [rust]
      exclude: '^(vendor|bindings)/'
      pass_filenames: false

    ### JS/TypeScript: Cient, Admin UI, Auth UI, Docs, examples ... ###
    - id: prettier
      name: Prettier
      entry: pnpm -r format --check
      language: system
      types_or: [javascript, jsx, ts, tsx, astro, markdown, mdx]
      # NOTE: We're relying on pnpm workspaces instead.
      pass_filenames: false

    - id: pnpm_check
      name: PNPM Check
      entry: pnpm -r check
      language: system
      types_or: [javascript, jsx, ts, tsx, astro]
      # NOTE: We're relying on pnpm workspaces instead.
      pass_filenames: false

    - id: pnpm_test
      name: PNPM Test
      entry: pnpm -r test
      language: system
      types_or: [javascript, jsx, ts, tsx, astro]
      # NOTE: We're relying on pnpm workspaces instead.
      pass_filenames: false

    - id: build_website
      name: Build Website
      entry: sh -c 'pnpm i --frozen-lockfile --prefer-offline && pnpm -C docs build'
      language: system
      types_or: [javascript, jsx, ts, tsx, astro, markdown, mdx]
      pass_filenames: false

    ### Dart: client and example
    - id: dart_analyze
      name: Dart analyze
      entry: sh -c 'dart pub get && dart analyze'
      language: system
      types: [dart]
      # Unlike formatting, analyzing & testing require a project rather than a list of files.
      pass_filenames: false

    - id: dart_format
      name: Dart format
      entry: dart format -o none --show all --set-exit-if-changed
      language: system
      types: [dart]

    - id: dart_test
      name: Dart test
      entry: sh -c 'dart pub get && cd client/dart && dart test'
      language: system
      types: [dart]
      # Unlike formatting, analyzing & testing require a project rather than a list of files.
      pass_filenames: false

    ### Dotnet client
    - id: dotnet_format
      name: Dotnet format
      entry: sh -c 'dotnet format client/dotnet/trailbase --verify-no-changes && dotnet format client/dotnet/test --verify-no-changes'
      language: system
      types: [c#, csproj]
      pass_filenames: false

    - id: dotnet_test
      name: Dotnet test
      entry: dotnet test client/dotnet/test
      language: system
      types: [c#, csproj]
      pass_filenames: false

    ### Python client
    - id: python_format
      name: Python format
      entry: poetry -C client/python run black --config pyproject.toml --check .
      language: system
      types: [python]
      pass_filenames: false

    - id: python_check
      name: Python check
      entry: sh -c 'poetry -C client/python run pyright --outputjson && poetry -C client/python run flake8'
      language: system
      types: [python]
      pass_filenames: false

    - id: python_test
      name: Python test
      entry: poetry -C client/python run pytest
      language: system
      types: [python]
      pass_filenames: false

    ### Swift client
    - id: swift_format
      name: Swift format
      # NOTE: `swift-format` always exits with code 0, meaning we depend on
      # "--in-place" and the pre-commit framework's "Post Run" hook to fail
      # if files were altered.
      entry: swift format -r --in-place client/swift/trailbase/**/*.swift
      language: system
      types: [swift]
      pass_filenames: false

    - id: swift_test
      name: Swift test
      # NOTE: cannot test `docs/examples/record_api_swift`, since not hermetic
      entry: swift test --package-path client/swift/trailbase
      language: system
      types: [swift]
      pass_filenames: false

    ### Go client
    - id: go_format
      name: Go format
      # gofmt always returns zero exit code :sigh:
      entry: sh -c 'DIFF=$(gofmt -d -e client/go/trailbase/) && echo "${DIFF}" && test -z "${DIFF}"'
      language: system
      types: [go]
      # files: .*\.(go)$
      pass_filenames: false

    - id: go_test
      name: Go test
      entry: sh -c 'cd client/go/trailbase && go test -v'
      language: system
      types: [go]
      pass_filenames: false

    # Kotlin test
    - id: kotlin_test
      name: Kotlin test
      entry: sh -c 'cd client/kotlin && ./gradlew allTests'
      language: system
      types: [kotlin]
      pass_filenames: false
