diff --git a/.github/workflows/Clang-format-checker.yml b/.github/workflows/Clang-format-checker.yml index 5b1aa6651..c30cc1064 100644 --- a/.github/workflows/Clang-format-checker.yml +++ b/.github/workflows/Clang-format-checker.yml @@ -12,10 +12,12 @@ jobs: steps: - uses: actions/checkout@v4 - - uses: DoozyX/clang-format-lint-action@v0.18 + - uses: actions/setup-python@v5 with: - source: '.' - exclude: './external' - extensions: 'h,cpp,cc' - clangFormatVersion: 18 # default is 18.1.8 - style: file + python-version: '3.x' + + - name: Install pre-commit + run: python -m pip install pre-commit + + - name: Check formatting + run: pre-commit run --all-files --show-diff-on-failure diff --git a/.gitignore b/.gitignore index 121ce206a..a89ab4e9f 100644 --- a/.gitignore +++ b/.gitignore @@ -47,7 +47,6 @@ test-data target tmp compile_commands.json -.pre-commit-config.yaml .codex diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 000000000..038c40069 --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,13 @@ +exclude: | + (?x)^( + external/| + rust/eloqstore-sys/vendor/ + ) + +repos: + - repo: https://github.com/pre-commit/mirrors-clang-format + rev: v18.1.8 + hooks: + - id: clang-format + files: \.(c|cc|cpp|cxx|h|hh|hpp|hxx)$ + args: [--style=file, --fallback-style=none] diff --git a/CLAUDE.md b/CLAUDE.md index e96105104..f81d1dd95 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -55,9 +55,17 @@ SDK tests (also run in CI): `python3 -m build --wheel` + pytest in `python/`; in ## Formatting -`bash scripts/format.sh` — installs clang-format 18.1.8 on first run and formats the tree. Style is Google-based with Allman braces, 4-space indent, right pointer alignment (see `.clang-format`). - -**Always run `bash scripts/format.sh` and commit any changes it makes before opening (or updating) a PR.** The main branch has a format check in CI that will fail the PR otherwise — hand-written code that looks fine often still gets re-wrapped by clang-format (e.g. a call that now fits on one line). Don't rely on writing conforming code by hand; run the script. +Install the Git hook once with `pre-commit install`. The hook uses an isolated, +pinned clang-format 18.1.8 environment, so no system clang-format installation +is needed. Style is Google-based with Allman braces, 4-space indent, and right +pointer alignment (see `.clang-format`). Third-party sources under `external/` +and the Rust vendor-link tree are excluded by `.pre-commit-config.yaml`. + +**Always run `pre-commit run --all-files` and commit any changes it makes before +opening (or updating) a PR.** The main branch runs the same command in CI and +will fail the PR otherwise — hand-written code that looks fine often still gets +re-wrapped by clang-format (e.g. a call that now fits on one line). Don't rely on +writing conforming code by hand; run the hook. ## Architecture diff --git a/README.md b/README.md index f7381956a..473c67f04 100644 --- a/README.md +++ b/README.md @@ -219,30 +219,26 @@ ctest --test-dir build/tests/ ./build/benchmark/simple_bench --kvoptions=./benchmark/opts_append.ini --workload=write-read --kv_size=1024 --batch_size=20000 --max_key=10000000 --read_per_part=4 --partitions=1 ``` -### Install git hooks +### Install pre-commit ```shell -git config core.hooksPath .githooks +python3 -m pip install pre-commit +pre-commit install ``` -The pre-commit hook auto-syncs `pyproject.toml` / `Cargo.toml` versions from `VERSION`. -Run once after cloning. Bypass with `git commit --no-verify`. +Run these commands once after cloning. The hook downloads and caches its own +clang-format 18.1.8 environment; it does not install clang-format system-wide. +Bypass the hook with `git commit --no-verify` only when necessary. -### Install Format Tool +### Format C/C++ code -```shell -bash scripts/format.sh +```shell +pre-commit run --all-files ``` -This script will execute when necessary: -- Install code format tools -- Format the code - -The first time this script is executed, it will install: -- libtinfo5 -- clang-format(18.1.8) - -**Note**: The main branch has code format checks; please run this script before committing the MR. +Only tracked C/C++ files are formatted. Third-party code under `external/` and +the Rust vendor-link tree are excluded. The main branch runs the same command; +please run it before opening or updating a PR. ## 🤝 Contributing diff --git a/scripts/format.sh b/scripts/format.sh deleted file mode 100755 index e028c04f6..000000000 --- a/scripts/format.sh +++ /dev/null @@ -1,100 +0,0 @@ -#!/bin/bash - -# Return 0 if clang-format exists and its version is exactly 18.1.8 -clang_format_is_18_1_8() { - command -v clang-format-18.1.8 >/dev/null 2>&1 || return 1 - clang-format-18.1.8 --version 2>/dev/null | grep -Eq 'clang-format version[[:space:]]+18\.1\.8\b' -} - -install_clang_format_18_1_8() { - cd $HOME - local SUDO="" - if [[ "${EUID:-$(id -u)}" -ne 0 ]]; then - SUDO="sudo" - fi - - local ARCH DPKG TINFO_PKG_URL LLVM_PKG_URL - ARCH="$(uname -m)" - DPKG="$(dpkg --print-architecture)" - - # 1) Install libtinfo5 via the exact commands you requested (amd64 deb) - echo "[INFO] Installing libtinfo5" - case "$ARCH" in - x86_64) - TINFO_PKG_URL="https://security.ubuntu.com/ubuntu/pool/universe/n/ncurses" - ;; - aarch64|arm64) - TINFO_PKG_URL="https://cn.ports.ubuntu.com/pool/universe/n/ncurses" - ;; - *) - echo "[ERROR] Unsupported arch: $ARCH" - return 1 - ;; - esac - - $SUDO apt update - local TINFO_DEB="libtinfo5_6.3-2ubuntu0.1_${DPKG}.deb" - local TINFO_URL="${TINFO_PKG_URL}/${TINFO_DEB}" - - echo "[INFO] Downloading ${TINFO_DEB} from ${TINFO_URL}" - - wget -q -O "./${TINFO_DEB}" "$TINFO_URL" || { echo "[ERROR] Download failed: ${TINFO_URL}" >&2; return 1; } - $SUDO apt install -y "./${TINFO_DEB}" || return 1 - - # 2) Download LLVM clang-format 18.1.8 - echo "[INFO] Downloading LLVM clang-format 18.1.8" - case "$ARCH" in - x86_64) - LLVM_PKG_URL="https://github.com/llvm/llvm-project/releases/download/llvmorg-18.1.8/clang+llvm-18.1.8-x86_64-linux-gnu-ubuntu-18.04.tar.xz" - ;; - aarch64|arm64) - LLVM_PKG_URL="https://github.com/llvm/llvm-project/releases/download/llvmorg-18.1.8/clang+llvm-18.1.8-aarch64-linux-gnu.tar.xz" - ;; - *) - echo "Unsupported arch: $ARCH" >&2 - return 1 - ;; - esac - - mkdir -p ./llvm-18.1.8 - - echo "[INFO] Downloading LLVM clang-format 18.1.8 from ${LLVM_PKG_URL}" - - curl -L "$LLVM_PKG_URL" -o /tmp/llvm-18.1.8.tar.xz - tar -xf /tmp/llvm-18.1.8.tar.xz -C ./llvm-18.1.8 --strip-components=1 - rm -f /tmp/llvm-18.1.8.tar.xz - - # 3) Link as versioned binary - $SUDO ln -sf "$(pwd)/llvm-18.1.8/bin/clang-format" /usr/local/bin/clang-format-18.1.8 - - cd - - echo "[INFO] Verifying clang-format-18.1.8" - - # 4) Verify - if /usr/local/bin/clang-format-18.1.8 --version 2>/dev/null | grep -Eq 'clang-format version[[:space:]]+18\.1\.8\b'; then - echo "[OK] Installed: $(/usr/local/bin/clang-format-18.1.8 --version)" - else - echo "[ERR] clang-format-18.1.8 install/link failed." >&2 - /usr/local/bin/clang-format-18.1.8 --version >&2 || true - return 1 - fi -} - -# One-shot entry: if check fails, install -ensure_clang_format_18_1_8() { - if clang_format_is_18_1_8; then - echo "[OK] clang-format already 18.1.8: $(clang-format-18.1.8 --version)" - return 0 - fi - echo "[ERR] clang-format not found, installing 18.1.8" - install_clang_format_18_1_8 -} - -# Format all files in the project -ensure_clang_format_18_1_8 || { echo "[ERROR] Format failed" >&2; exit 1; } - -git ls-files -z '*.c' '*.cc' '*.cpp' '*.h' '*.hpp' \ -| awk -v RS='\0' -v ORS='\0' '!/^(third_party|vendor|build|external)\//' \ -| xargs -0 -r clang-format-18.1.8 -i --style="file" - -echo "[OK] Format completed" \ No newline at end of file