From 4c78f2a5d817a4f243a2cede4b91508d2b3bbd53 Mon Sep 17 00:00:00 2001 From: Abhiraj Adhikary Date: Tue, 10 Nov 2026 01:51:15 +0530 Subject: [PATCH] Pre-commit: add ruff and enforce all hooks in CI Config only (commit 1 of #270): add ruff (default rules E4/E7/E9/F, line length 88), the hygiene/prettier/shellcheck/hadolint hooks, the CI job that runs uvx pre-commit run --all-files, and the install instructions in CONTRIBUTING.md. The 63 ruff fixes and the first prettier reformat land in separate commits after release/26.11.1 merges to main. --- .github/workflows/pre-commit.yml | 49 +++++++++++++++++++++++++++ .pre-commit-config.yaml | 57 ++++++++++++++++++++++++++++---- .prettierrc.json | 10 ++++++ CONTRIBUTING.md | 15 +++++---- pyproject.toml | 16 +++++++++ 5 files changed, 135 insertions(+), 12 deletions(-) create mode 100644 .github/workflows/pre-commit.yml create mode 100644 .prettierrc.json diff --git a/.github/workflows/pre-commit.yml b/.github/workflows/pre-commit.yml new file mode 100644 index 00000000..b1358f34 --- /dev/null +++ b/.github/workflows/pre-commit.yml @@ -0,0 +1,49 @@ +# Enforces the pre-commit hooks (.pre-commit-config.yaml) on every pull request and push to main, +# so a contribution made without the local hooks is still checked. Contributors run the same hooks +# locally with `uvx pre-commit install` (see CONTRIBUTING.md). +name: Pre-commit + +on: + pull_request: + push: + branches: [main] + workflow_dispatch: + +permissions: + contents: read + +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.sha }} + cancel-in-progress: ${{ github.event_name == 'pull_request' }} + +jobs: + pre-commit: + name: Run pre-commit on all files + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + persist-credentials: false + + - name: Set up Python + uses: actions/setup-python@6d4fd22b20465ccc0f7354476588e8df7c9ca0e0 # v7.1.0 + with: + python-version: "3.12" + + # pre-commit and its hooks run through uvx (a throwaway environment), so nothing is installed + # into the runner's Python. uv is pinned in every install URL of this repo. + - name: Setup UV package manager + shell: bash + run: | + # Retry transient network failures (a connection reset failed a whole examples job on #8897); the + # script is downloaded first so a retried transfer is never piped half-written into sh. + installer="$(mktemp)" + curl -LsSf --retry 5 --retry-all-errors --retry-delay 5 -o "$installer" https://astral.sh/uv/0.12.0/install.sh + sh "$installer" + echo "$HOME/.local/bin" >> "$GITHUB_PATH" + export PATH="$HOME/.local/bin:$PATH" + uv --version + + - name: Run pre-commit on all files + run: uvx pre-commit run --all-files --show-diff-on-failure diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 501296e8..255ce3d4 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,4 +1,19 @@ repos: + # Basic file hygiene (validate and normalize), matching upstream ArcadeDB's pre-commit-hooks set. +- repo: https://github.com/pre-commit/pre-commit-hooks + rev: v6.0.0 + hooks: + - id: trailing-whitespace + - id: end-of-file-fixer + - id: check-merge-conflict + - id: check-added-large-files + - id: detect-private-key + - id: check-yaml + args: [--allow-multiple-documents] + - id: check-toml + - id: check-json + - id: check-xml + # Python formatting (unchanged): black + isort with the black profile. - repo: https://github.com/psf/black rev: 26.10.1 hooks: @@ -9,6 +24,32 @@ repos: hooks: - id: isort args: [--profile, black] + # Python linting: ruff with its default rules (E4, E7, E9, F) at line length 88 (pyproject.toml). + # Check only - fixes land in their own commit; black and isort remain the formatters. +- repo: https://github.com/astral-sh/ruff-pre-commit + rev: v0.17.4 + hooks: + - id: ruff-check + # Java, XML, Markdown and JSON formatting, matching upstream ArcadeDB (printWidth 160 for + # Java/XML is set in .prettierrc.json; Markdown prose is not hard-wrapped). types_or (OR) is + # required: types (AND) of [java, xml] would match no file. +- repo: https://github.com/rbubley/mirrors-prettier + rev: v3.9.10 + hooks: + - id: prettier + types_or: [java, xml, markdown, json] + additional_dependencies: + - prettier@3.9.10 + - prettier-plugin-java@2.11.0 + - prettier-plugin-xml + args: [--write, --list-different, --ignore-unknown] + # Shell formatting (unchanged). +- repo: https://github.com/scop/pre-commit-shfmt + rev: v3.14.1-1 + hooks: + - id: shfmt + args: [-i, '4', -ci, -sr, -w] + # YAML formatting (unchanged): workflows are linted by actionlint, not reformatted (as upstream). - repo: https://github.com/macisamuele/language-formatters-pre-commit-hooks rev: v2.16.0 hooks: @@ -16,18 +57,22 @@ repos: args: - --autofix - --indent=2 - # Workflows are linted by actionlint, not reformatted (as upstream). exclude: ^\.github/ -- repo: https://github.com/scop/pre-commit-shfmt - rev: v3.14.1-1 + # Shell linting (.sh files). Runs in Docker; actionlint already runs shellcheck over workflow run: blocks. +- repo: https://github.com/koalaman/shellcheck-precommit + rev: v0.11.0 hooks: - - id: shfmt - args: [-i, '4', -ci, -sr, -w] - # actionlint runs shellcheck over every `run:` block; per-file ignores live in .github/actionlint.yaml. + - id: shellcheck + # actionlint runs shellcheck over every run: block; per-file ignores live in .github/actionlint.yaml. - repo: https://github.com/rhysd/actionlint rev: v1.7.12 hooks: - id: actionlint + # Dockerfile linting (scripts/Dockerfile.build). Runs in Docker. +- repo: https://github.com/hadolint/hadolint + rev: v2.15.1 + hooks: + - id: hadolint-docker - repo: local hooks: - id: no-old-package-name diff --git a/.prettierrc.json b/.prettierrc.json new file mode 100644 index 00000000..0dcd0065 --- /dev/null +++ b/.prettierrc.json @@ -0,0 +1,10 @@ +{ + "printWidth": 80, + "proseWrap": "preserve", + "overrides": [ + { + "files": ["**/*.java", "**/*.xml"], + "options": { "printWidth": 160 } + } + ] +} diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index d816b517..7c06f60c 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -85,20 +85,23 @@ uv run --no-project --python 3.12 python native/wheel/build_wheel.py --lib-dir < ### Pre-commit -This project uses [pre-commit](https://pre-commit.com/) (black, isort, shfmt, pretty-format-yaml, actionlint). Run it on the files you changed before you push, and again if it reformatted something: +This project uses [pre-commit](https://pre-commit.com/): ruff (lint, default rules E4/E7/E9/F at line length 88), black and isort (Python formatting), prettier (Java, XML, Markdown, JSON), shfmt and shellcheck (shell), hadolint (Dockerfile), pretty-format-yaml and the basic hygiene hooks (trailing whitespace, end-of-file, merge-conflict markers, large files, private keys), and actionlint (GitHub Actions). The settings live in `pyproject.toml` (`[tool.ruff]`) and `.prettierrc.json`. + +Install the hooks once so they run on every commit: ```shell -uvx pre-commit run --files -uvx pre-commit run --all-files +uvx pre-commit install ``` -CI also runs Bandit, which must be clean: +Run them on the files you changed before you push, and again if something was reformatted: ```shell -uvx bandit==1.9.4 -c pyproject.toml -r src tests --severity-level low --confidence-level low -uvx bandit==1.9.4 -c pyproject.toml -r examples --severity-level medium --confidence-level high +uvx pre-commit run --files +uvx pre-commit run --all-files ``` +shellcheck and hadolint run in Docker; on a machine without Docker, skip them with `SKIP=shellcheck,hadolint-docker uvx pre-commit run --all-files`. CI runs the same hooks on every pull request and push. + ### Workflow 1. An [issue](https://github.com/ArcadeData/arcadedb-python/issues) states the problem. diff --git a/pyproject.toml b/pyproject.toml index 69caffed..d29bc0cc 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -178,3 +178,19 @@ exclude_dirs = ["/tests/.cache/", "/build/", "/dist/"] # (src/) intentionally contains no assert statements - so we skip it globally # rather than maintaining a per-file glob list. skips = ["B101"] + +[tool.ruff] +# Black's default; no hard limit on comments and strings (E501 is intentionally not enabled, so +# the ~2,904 lines Black deliberately leaves long are not flagged). See issue #270. +line-length = 88 +target-version = "py311" + +[tool.ruff.lint] +# Ruff's default rules: E4 (imports), E7 (statements), E9 (runtime), F (pyflakes). +select = ["E4", "E7", "E9", "F"] + +[tool.ruff.lint.per-file-ignores] +# pytest fixtures whose names shadow the fixture are a normal pattern (issue #270 lists 8 such +# F811s). The one real duplicate (TestInsertManyVertexType in tests/test_bulk_insert.py) is removed +# with the ruff-fixes commit, so nothing F811 should catch in tests remains except this pattern. +"tests/**" = ["F811"]