diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 66799a6..0dda8e8 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -35,8 +35,8 @@ } }, + "postCreateCommand": "pre-commit install --hook-type pre-push", "postStartCommand": "bash", - // Clean container name and setup "runArgs": [ "--rm", diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 9e56b63..44ffab3 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -6,8 +6,12 @@ jobs: steps: - uses: actions/checkout@v4 - name: Install deps - run: sudo apt-get update && sudo apt-get install -y cmake clang-format + run: sudo apt-get update && sudo apt-get install -y cmake clang-format clang-tidy + - name: Format check + run: ./scripts/format.sh --check - name: Build run: mkdir -p build && cd build && cmake .. && make + - name: Lint check + run: ./scripts/lint.sh - name: Test run: cd build && ctest --output-on-failure \ No newline at end of file diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 5c40565..b0851cc 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,15 +1,19 @@ repos: - - repo: https://github.com/pre-commit/mirrors-clang-format - rev: v14.0.0 + - repo: local hooks: - id: clang-format - args: ["--style=file"] + name: clang-format + entry: ./scripts/format.sh --check + language: system + stages: [pre-push] + pass_filenames: false types: [c, c++] - - - repo: local - hooks: + - id: clang-tidy name: clang-tidy - entry: ./scripts/lint_precommit.sh + description: "Requires build directory with compile_commands.json to exist. Please build the project before pushing." + entry: ./scripts/lint.sh language: system + stages: [pre-push] + pass_filenames: false types: [c, c++] diff --git a/README.md b/README.md index 92b1649..75f503e 100644 --- a/README.md +++ b/README.md @@ -18,6 +18,10 @@ A modern, production-ready template for C++ development. ```bash git clone my_project && cd my_project + +# Install pre-commit hooks (for code quality checks on push) +pre-commit install --hook-type pre-push + ./scripts/fetch_googletest.sh # optional, only if you need tests cmake -S . -B build # -DENABLE_TESTS=OFF to skip tests cmake --build build -j$(nproc) diff --git a/scripts/format.sh b/scripts/format.sh index 33668d2..242f3a5 100755 --- a/scripts/format.sh +++ b/scripts/format.sh @@ -2,15 +2,24 @@ # -------------------------------------------------------------------- # Format all C++ source/header files in the project using clang-format +# Usage: +# ./format.sh - Format files in-place +# ./format.sh --check - Check formatting without modifying files # -------------------------------------------------------------------- -#!/usr/bin/env bash set -e SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" PROJECT_ROOT="$(dirname "$SCRIPT_DIR")" -echo "[INFO] Running clang-format on source files..." +# Check if --check flag is passed +CHECK_MODE=false +if [[ "$1" == "--check" ]]; then + CHECK_MODE=true + echo "[INFO] Running clang-format in check mode (no modifications)..." +else + echo "[INFO] Running clang-format on source files..." +fi EXTENSIONS=("*.cpp" "*.hpp" "*.cc" "*.h" "*.cxx" "*.hxx") FOUND=false @@ -20,8 +29,13 @@ for ext in "${EXTENSIONS[@]}"; do for f in $FILES; do FOUND=true - echo "Formatting $f" - clang-format -i "$f" + if $CHECK_MODE; then + echo "Checking $f" + clang-format --dry-run --Werror "$f" + else + echo "Formatting $f" + clang-format -i "$f" + fi done done