This is an automated email from the ASF dual-hosted git repository.

xushiyan pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/hudi-rs.git


The following commit(s) were added to refs/heads/main by this push:
     new 41e1ba6  chore: add pre-commit hooks for code formatting and linting 
(#103)
41e1ba6 is described below

commit 41e1ba60ed134cf450c8d9b43aeabc1c5d595d6d
Author: muyihao <[email protected]>
AuthorDate: Sun Mar 22 01:57:44 2026 +0800

    chore: add pre-commit hooks for code formatting and linting (#103)
    
    Configure two-stage pre-commit hooks: fast formatting on commit
    (cargo fmt, ruff format, file hygiene) and thorough checks on push
    (cargo clippy, ruff check, mypy). Hooks reuse existing make targets
    for consistency with CI.
    
    Co-authored-by: Shiyan Xu <[email protected]>
---
 .pre-commit-config.yaml | 60 +++++++++++++++++++++++++++++++++++++++++++++++++
 CONTRIBUTING.md         | 27 +++++++++++++++++++++-
 Makefile                |  8 +++++++
 python/pyproject.toml   |  5 +++--
 4 files changed, 97 insertions(+), 3 deletions(-)

diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
new file mode 100644
index 0000000..5e4911d
--- /dev/null
+++ b/.pre-commit-config.yaml
@@ -0,0 +1,60 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+repos:
+  - repo: https://github.com/pre-commit/pre-commit-hooks
+    rev: v5.0.0
+    hooks:
+      - id: trailing-whitespace
+      - id: end-of-file-fixer
+      - id: check-yaml
+      - id: check-added-large-files
+      - id: check-merge-conflict
+
+  - repo: local
+    hooks:
+      # === pre-commit stage (every commit, fast ~5s) ===
+      - id: format-rust
+        name: format rust
+        entry: make format-rust
+        language: system
+        types: [rust]
+        pass_filenames: false
+
+      - id: format-python
+        name: format python
+        entry: make format-python
+        language: system
+        types: [python]
+        pass_filenames: false
+
+      # === pre-push stage (every push, thorough ~1-5min) ===
+      - id: check-rust
+        name: check rust (clippy + fmt)
+        entry: make check-rust
+        language: system
+        types: [rust]
+        pass_filenames: false
+        stages: [pre-push]
+
+      - id: check-python
+        name: check python (ruff + mypy)
+        entry: make check-python
+        language: system
+        types: [python]
+        pass_filenames: false
+        stages: [pre-push]
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index bea9872..2317ad6 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -48,6 +48,31 @@ view, instead, they will be linked to the corresponding 
issues.
 - Have a compatible Python version installed (check 
[`python/pyproject.toml`](./python/pyproject.toml) for current
   requirement)
 
+## Pre-commit hooks (recommended)
+
+This project provides [pre-commit](https://pre-commit.com/) hooks to catch 
issues locally
+before they reach CI. After setting up the virtual environment:
+
+```shell
+make setup-pre-commit
+```
+
+The hooks are split into two stages for a fast development cycle:
+
+**On every commit** (~5 seconds):
+
+- File hygiene: trailing whitespace, end-of-file fixer, YAML validation, large 
file check, merge conflict markers
+- Rust formatting: auto-formats via `cargo fmt` (same as `make format-rust`)
+- Python formatting: auto-formats via `ruff format` (same as `make 
format-python`)
+
+**On every push** (thorough, ~1-5 minutes):
+
+- Rust checks: `cargo clippy` and format verification (same as `make 
check-rust`)
+- Python checks: `ruff` linting and `mypy` type checking (same as `make 
check-python`)
+
+These are the same checks that run in CI. To skip hooks temporarily:
+`git commit --no-verify` or `git push --no-verify`.
+
 ## Commonly used dev commands
 
 For most of the time, use dev commands specified in the [`Makefile`](Makefile).
@@ -132,7 +157,7 @@ When submitting a pull request, please follow these 
guidelines:
 
 ### Code coverage
 
-We use [codecov](https://app.codecov.io/github/apache/hudi-rs) to generate 
code coverage report and enforce code 
+We use [codecov](https://app.codecov.io/github/apache/hudi-rs) to generate 
code coverage report and enforce code
 coverage rate. See [codecov.yml](./codecov.yml) for the configuration.
 
 ## Learning
diff --git a/Makefile b/Makefile
index 3979066..2c84394 100644
--- a/Makefile
+++ b/Makefile
@@ -70,6 +70,14 @@ setup: ## Setup the requirements
        $(info --- Setup dependencies ---)
        uv pip install "$(MATURIN_VERSION)"
 
+.PHONY: setup-pre-commit
+setup-pre-commit: ## Install pre-commit hooks for local development
+       $(call check_uv)
+       $(info --- Setup pre-commit hooks ---)
+       uv pip install pre-commit
+       pre-commit install
+       pre-commit install --hook-type pre-push
+
 .PHONY: build
 build: setup ## Build Python binding of hudi-rs
        $(info --- Build Python binding ---)
diff --git a/python/pyproject.toml b/python/pyproject.toml
index d0662c6..320cb89 100644
--- a/python/pyproject.toml
+++ b/python/pyproject.toml
@@ -46,10 +46,11 @@ devel = [
     "coverage==7.10.7",
     "ruff==0.14.13",
     "mypy==1.19.1",
-] 
+    "pre-commit",
+]
 lint = [
     "ruff==0.14.13",
-    "mypy==1.19.1",   
+    "mypy==1.19.1",
 ]
 datafusion = [
     "datafusion==52.3.0",

Reply via email to