From 3930443fbafb267d3b96fa9ccf3a08e740897662 Mon Sep 17 00:00:00 2001 From: Julio Castillo Date: Wed, 11 Mar 2026 15:58:43 -0700 Subject: [PATCH 1/5] fix: replace pre-commit with plain shell git hooks Remove Python-based pre-commit dependency in favor of version-controlled .githooks/ directory with core.hooksPath. This eliminates the need for Python/pip on the host while keeping the same pre-push checks (format and lint) via Docker delegation. - Add .githooks/pre-push hook calling format.sh and lint.sh directly - Add scripts/install-hooks.sh for one-command setup after cloning - Remove .pre-commit-config.yaml - Remove pre-commit, cmake-format, and python3-pip from Dockerfile - Update CLAUDE.md with new hook install instructions --- .githooks/pre-push | 17 +++++++++++++++++ .pre-commit-config.yaml | 19 ------------------- CLAUDE.md | 2 +- Dockerfile | 5 ----- scripts/install-hooks.sh | 17 +++++++++++++++++ 5 files changed, 35 insertions(+), 25 deletions(-) create mode 100755 .githooks/pre-push delete mode 100644 .pre-commit-config.yaml create mode 100755 scripts/install-hooks.sh diff --git a/.githooks/pre-push b/.githooks/pre-push new file mode 100755 index 0000000..e2532b2 --- /dev/null +++ b/.githooks/pre-push @@ -0,0 +1,17 @@ +#!/usr/bin/env bash +set -e + +############################################################################### +# Git pre-push hook +# +# Runs formatting and linting checks before pushing. Delegates to the project +# scripts, which auto-delegate to Docker when run outside the container. +############################################################################### + +REPO_ROOT="$(git rev-parse --show-toplevel)" + +echo "=== Pre-push: checking formatting ===" +"$REPO_ROOT/scripts/format.sh" --check + +echo "=== Pre-push: running clang-tidy ===" +"$REPO_ROOT/scripts/lint.sh" diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml deleted file mode 100644 index b0851cc..0000000 --- a/.pre-commit-config.yaml +++ /dev/null @@ -1,19 +0,0 @@ -repos: - - repo: local - hooks: - - id: clang-format - name: clang-format - entry: ./scripts/format.sh --check - language: system - stages: [pre-push] - pass_filenames: false - types: [c, c++] - - - id: clang-tidy - name: clang-tidy - 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/CLAUDE.md b/CLAUDE.md index 735140a..8d58d13 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -15,7 +15,7 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co ./scripts/docs.sh # Generate Doxygen documentation ``` -Pre-commit hooks run on **pre-push** (not pre-commit): `pre-commit install --hook-type pre-push` +Git hooks live in `.githooks/` (version-controlled). Install once after cloning: `./scripts/install-hooks.sh` All scripts auto-delegate to Docker when run outside the container (`docker run --rm`). The delegation logic lives in `scripts/docker/exec.sh`, sourced by each script via `scripts/env.sh`. Inside the container or CI (`CI=true`), scripts run directly with no overhead. See `docs/ci-container-delegation.md` for details on the CI strategy and a GHCR upgrade path. diff --git a/Dockerfile b/Dockerfile index f545cb7..c429f7c 100644 --- a/Dockerfile +++ b/Dockerfile @@ -27,7 +27,6 @@ RUN apt-get update && apt-get install -y \ lcov \ gdb \ valgrind \ - python3-pip \ ca-certificates \ tree \ && rm -rf /var/lib/apt/lists/* @@ -70,10 +69,6 @@ RUN echo 'ubuntu ALL=(ALL) NOPASSWD:ALL' > /etc/sudoers.d/ubuntu \ # ------------------------------------------------------------------------------ # RUN sed -i 's/^#force_color_prompt=yes/force_color_prompt=yes/' /home/ubuntu/.bashrc -# ----------------------------------------------------------------------------- -# Install pre-commit for code quality checks -# ----------------------------------------------------------------------------- -RUN pip3 install --break-system-packages pre-commit cmake-format # ------------------------------------------------------------------------------ # Copy entrypoint script diff --git a/scripts/install-hooks.sh b/scripts/install-hooks.sh new file mode 100755 index 0000000..ff02d38 --- /dev/null +++ b/scripts/install-hooks.sh @@ -0,0 +1,17 @@ +#!/usr/bin/env bash +set -e + +############################################################################### +# Install git hooks +# +# Points git to the .githooks/ directory so that version-controlled hooks +# are used automatically. Run once after cloning: +# +# ./scripts/install-hooks.sh +############################################################################### + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +REPO_ROOT="$(dirname "$SCRIPT_DIR")" + +git -C "$REPO_ROOT" config core.hooksPath .githooks +echo "[INFO] Git hooks installed (.githooks/). core.hooksPath set." From 564462f737548d7c171c9143f9e3ff023a416bb7 Mon Sep 17 00:00:00 2001 From: Julio Castillo Date: Wed, 11 Mar 2026 16:00:52 -0700 Subject: [PATCH 2/5] docs: update README and devcontainer for new git hooks setup Replace pre-commit references with install-hooks.sh in the Quick Start, Code Quality section, and devcontainer postCreateCommand. --- .devcontainer/devcontainer.json | 2 +- README.md | 18 ++++++++---------- 2 files changed, 9 insertions(+), 11 deletions(-) diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 6b838f4..e503fa9 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -35,7 +35,7 @@ } }, - "postCreateCommand": "pre-commit install --hook-type pre-push", + "postCreateCommand": "./scripts/install-hooks.sh", "postStartCommand": "bash", // Clean container name and setup diff --git a/README.md b/README.md index 9614dea..a4226be 100644 --- a/README.md +++ b/README.md @@ -6,8 +6,8 @@ A modern, production-ready template for C++ development. | --------------- | -------------------------------------- | ------ | | Build | CMake ≥ 3.20 | ✔ | | Unit tests | GoogleTest (optional) | ✔ | -| Formatting | clang-format (pre-commit) | ✔ | -| Linting | clang-tidy (pre-commit) | ✔ | +| Formatting | clang-format (pre-push hook) | ✔ | +| Linting | clang-tidy (pre-push hook) | ✔ | | Docs | Doxygen | ✔ | | Dev environment | Docker image, VS Code DevContainer | ✔ | | CI | GitHub Actions (Ubuntu 24.04) | ✔ | @@ -19,8 +19,8 @@ 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 +# Install git hooks (optional — runs format + lint checks on push) +./scripts/install-hooks.sh cmake -S . -B build # -DENABLE_UNIT_TESTS=OFF to skip tests cmake --build build -j$(nproc) @@ -134,19 +134,17 @@ Docker-related scripts live under `scripts/docker/`: ### Pre-push Hooks -Install hooks once (runs on `git push`, not commit): +Git hooks live in `.githooks/` (version-controlled). Install once after cloning: ```bash -pre-commit install --hook-type pre-push +./scripts/install-hooks.sh ``` -Before each push, pre-commit will: +This sets `core.hooksPath` to `.githooks/`, so git uses the project's hooks. Before each push, the hook will: - Run `clang-format` to check code formatting - Run `clang-tidy` to analyze code quality -These checks ensure consistent code style across the team. - -**VS Code DevContainer users:** Hooks are installed automatically via `postCreateCommand`. +These checks delegate to Docker automatically (same as running the scripts directly). --- From 596b455301b9d08fcac1389319fc92ad4ffb0cf5 Mon Sep 17 00:00:00 2001 From: Julio Castillo Date: Wed, 11 Mar 2026 17:03:04 -0700 Subject: [PATCH 3/5] fix: skip clang-tidy in pre-push hook when build dir is missing Add preflight check for compile_commands.json before running lint. Format check still runs unconditionally. Update README to document the build requirement for lint. --- .githooks/pre-push | 10 +- README.md | 222 +++++++++++++++++---------------------------- 2 files changed, 90 insertions(+), 142 deletions(-) diff --git a/.githooks/pre-push b/.githooks/pre-push index e2532b2..113b893 100755 --- a/.githooks/pre-push +++ b/.githooks/pre-push @@ -13,5 +13,11 @@ REPO_ROOT="$(git rev-parse --show-toplevel)" echo "=== Pre-push: checking formatting ===" "$REPO_ROOT/scripts/format.sh" --check -echo "=== Pre-push: running clang-tidy ===" -"$REPO_ROOT/scripts/lint.sh" +BUILD_DIR="$REPO_ROOT/build" +if [ ! -f "$BUILD_DIR/compile_commands.json" ]; then + echo "=== Pre-push: skipping clang-tidy (no compile_commands.json) ===" + echo "Run ./scripts/build.sh first to enable lint checks." +else + echo "=== Pre-push: running clang-tidy ===" + "$REPO_ROOT/scripts/lint.sh" +fi diff --git a/README.md b/README.md index a4226be..9c1be13 100644 --- a/README.md +++ b/README.md @@ -1,15 +1,16 @@ # C++ Project Template -A modern, production-ready template for C++ development. +A modern, production-ready template for C++ development. All build and quality scripts run inside Docker automatically — no local toolchain required. | Capability | Tool / Setup | Status | | --------------- | -------------------------------------- | ------ | -| Build | CMake ≥ 3.20 | ✔ | -| Unit tests | GoogleTest (optional) | ✔ | +| Build | CMake >= 3.20, C++17 | ✔ | +| Unit tests | GoogleTest v1.14.0 (FetchContent) | ✔ | | Formatting | clang-format (pre-push hook) | ✔ | | Linting | clang-tidy (pre-push hook) | ✔ | +| Coverage | lcov / gcov | ✔ | | Docs | Doxygen | ✔ | -| Dev environment | Docker image, VS Code DevContainer | ✔ | +| Dev environment | Docker + VS Code DevContainer | ✔ | | CI | GitHub Actions (Ubuntu 24.04) | ✔ | --- @@ -19,58 +20,85 @@ A modern, production-ready template for C++ development. ```bash git clone my_project && cd my_project -# Install git hooks (optional — runs format + lint checks on push) +# Build the Docker image (one-time) +./scripts/docker/build_image.sh + +# Install git hooks (runs format + lint checks on push) ./scripts/install-hooks.sh -cmake -S . -B build # -DENABLE_UNIT_TESTS=OFF to skip tests -cmake --build build -j$(nproc) -./build/bin/main_exec -ctest --test-dir build --output-on-failure # if tests enabled +# Build, test, done — scripts auto-delegate to Docker +./scripts/build.sh +./scripts/test.sh ``` +Every script in `scripts/` auto-delegates to Docker when run from the host. You don't need CMake, clang-format, or any other tool installed locally — just Docker. See [docs/ci-container-delegation.md](docs/ci-container-delegation.md) for details. + --- ## Project layout ``` . -├── CMakeLists.txt root build script -├── src/ production code -│ ├── example_public_private/ PUBLIC vs PRIVATE visibility (see README) -│ ├── example_interface/ INTERFACE library (header-only) -│ ├── example_static/ static library example (.a) -│ ├── example_shared/ shared library example (.so + RPATH) -│ ├── example_plugin_loader/ runtime plugin loader (dlopen) -│ ├── example_plugin_impl/ sample plugin implementation -│ └── main/ console application -├── tests/ unit tests (GoogleTest) -├── external/ third-party code (empty by default) -├── scripts/ helper scripts -├── docs/ documentation (Doxygen, guides) -└── .devcontainer/ VS Code container files +├── CMakeLists.txt root build script +├── Dockerfile dev container image +├── src/ production code +│ ├── example_static/ static library (.a) +│ ├── example_shared/ shared library (.so + RPATH) +│ ├── example_interface/ header-only (INTERFACE) library +│ ├── example_public_private/ PUBLIC vs PRIVATE visibility demo +│ ├── example_plugin_loader/ runtime plugin loader (dlopen) +│ ├── example_plugin_impl/ sample plugin implementation +│ └── main/ console application +├── tests/ unit tests (GoogleTest) +├── scripts/ build, test, format, lint, coverage, docs +│ └── docker/ container management (build, run, attach, exec) +├── .githooks/ git hooks (pre-push: format + lint) +├── .devcontainer/ VS Code DevContainer config +├── cmake/ extra CMake modules +├── docs/ documentation and guides +└── external/ third-party code (empty by default) ``` ### Documentation -- **PUBLIC/PRIVATE visibility**: See [docs/public-private-guide.md](docs/public-private-guide.md) -- **RPATH configuration**: See [docs/rpath-guide.md](docs/rpath-guide.md) -- **DevContainer setup**: See [docs/devcontainer-guide.md](docs/devcontainer-guide.md) +- **PUBLIC/PRIVATE visibility**: [docs/public-private-guide.md](docs/public-private-guide.md) +- **RPATH configuration**: [docs/rpath-guide.md](docs/rpath-guide.md) +- **DevContainer setup**: [docs/devcontainer-guide.md](docs/devcontainer-guide.md) +- **CI and container delegation**: [docs/ci-container-delegation.md](docs/ci-container-delegation.md) +- **Remote debugging**: [docs/remote-debugging.md](docs/remote-debugging.md) --- -## Build options +## Scripts -### CMake +All scripts auto-delegate to Docker when run on the host. Inside the container or CI (`CI=true`), they run directly. -```bash -# Development build (Debug, with debug symbols) -cmake -S . -B build -DCMAKE_BUILD_TYPE=Debug +### Build and Development -# Release build (optimized, for packaging) -cmake -S . -B build -DCMAKE_BUILD_TYPE=Release -``` +| Script | Purpose | +| -------------------- | ------------------------------------------------- | +| `build.sh` | Debug build with tests enabled | +| `test.sh` | Run all tests | +| `package.sh` | Release build + CPack packaging | +| `coverage.sh` | Build with coverage, run tests, generate report | +| `format.sh` | Apply clang-format (`--check` for CI mode) | +| `lint.sh` | Run clang-tidy (build first for compile_commands) | +| `docs.sh` | Generate Doxygen HTML documentation | +| `install-hooks.sh` | Set `core.hooksPath` to `.githooks/` | + +### Docker + +| Script | Purpose | +| --------------------------- | ------------------------------------------ | +| `docker/build_image.sh` | Build the `cpp-dev:latest` image | +| `docker/run.sh` | Run the dev container with UID/GID remap | +| `docker/attach.sh` | Attach to running container as `ubuntu` | + +--- + +## Build options -**Key flags**: +The build scripts handle CMake configuration automatically. If you need to customize, these are the key CMake flags: | Flag | Effect | | ------------------------ | -------------------------------- | @@ -78,61 +106,26 @@ cmake -S . -B build -DCMAKE_BUILD_TYPE=Release | `-DENABLE_COVERAGE=ON` | Enable code coverage with gcov | | `-DBUILD_SHARED_LIBS=ON` | Build libraries as shared | -### Library Dependencies and RPATH +### RPATH -This project uses **RPATH** (Runtime Path) for portable library discovery: +Shared libraries and plugins use RPATH (`$ORIGIN/../lib`) for portable discovery — no `LD_LIBRARY_PATH` needed: ``` your-package/ ├── bin/ │ └── main_exec ← RPATH: $ORIGIN/../lib └── lib/ - ├── libexample_shared.so ← Found automatically - └── libexample_plugin_impl.so ← Found by dlopen() + ├── libexample_shared.so ← found automatically + └── libexample_plugin_impl.so ← found by dlopen() ``` -**Key Benefits:** -- **Self-contained packages** - work anywhere without installation -- **No environment setup** - no `LD_LIBRARY_PATH` needed -- **Plugin discovery** - `dlopen()` finds plugins via RPATH -- **Clean code** - no hardcoded paths - -**For detailed RPATH explanation, examples, and troubleshooting, see [docs/rpath-guide.md](docs/rpath-guide.md)** - ---- - -## Scripts - -### Build and Development - -| Script | Purpose | -| ------------- | ---------------------------------------------------- | -| `build.sh` | Configure and compile (Debug mode) | -| `package.sh` | Build and create distributable packages (Release) | -| `coverage.sh` | Build with coverage, run tests, generate report | -| `format.sh` | Run clang-format on sources (use --check for CI) | -| `lint.sh` | Run clang-tidy using compile commands | -| `docs.sh` | Generate HTML docs | - -**Build vs Package:** -- `./scripts/build.sh` — Debug build for development (fast compilation, debug symbols) -- `./scripts/package.sh` — Release build + CPack packaging (optimized, distributable) - -### Docker - -Docker-related scripts live under `scripts/docker/`: - -| Script | Purpose | -| ---------------- | ------------------------------------------------- | -| `build_image.sh` | Build the `cpp-dev:latest` image | -| `run.sh` | Run the dev container with UID/GID remap | -| `attach.sh` | Attach to running container as `ubuntu` | +See [docs/rpath-guide.md](docs/rpath-guide.md) for details. --- ## Code quality -### Pre-push Hooks +### Pre-push hooks Git hooks live in `.githooks/` (version-controlled). Install once after cloning: @@ -140,98 +133,47 @@ Git hooks live in `.githooks/` (version-controlled). Install once after cloning: ./scripts/install-hooks.sh ``` -This sets `core.hooksPath` to `.githooks/`, so git uses the project's hooks. Before each push, the hook will: -- Run `clang-format` to check code formatting -- Run `clang-tidy` to analyze code quality - -These checks delegate to Docker automatically (same as running the scripts directly). - ---- - -## API Documentation (Doxygen) - -Generate HTML documentation from code comments: - -```bash -./scripts/docs.sh -xdg-open docs/html/index.html -``` +Before each push, the hook runs format and lint checks — delegating to Docker automatically. Clang-tidy requires `compile_commands.json` from a prior build; if missing, the hook skips lint and warns (format still runs). --- ## Docker and DevContainer -This project uses a **portable Docker image** with runtime UID/GID remapping. The same image works for all users without rebuilding. - -Build image +Build the image (one-time): ```bash ./scripts/docker/build_image.sh ``` -Run interactive container +Run an interactive container: ```bash ./scripts/docker/run.sh ``` -Attach to the running container +Attach to a running container: ```bash ./scripts/docker/attach.sh ``` -This attaches as user `ubuntu` (with remapped UID/GID). If the container isn't running, the script will fail—start it first with `./scripts/docker/run.sh`. - -**Customize attach behavior:** - -To attach as root (for system administration): -```bash -docker exec -it -u root cpp-dev-${USER} bash -``` - -To attach with your host UID/GID directly: -```bash -docker exec -it -u "$(id -u):$(id -g)" cpp-dev-${USER} bash -``` - -**VS Code DevContainer:** - -VS Code users can reopen the workspace in the container. The Dev Container uses the prebuilt `cpp-dev:latest` image and relies on a runtime entrypoint to remap UID/GID (no extra `vsc-…-uid` image is created). - -**For detailed information about the DevContainer setup, see [docs/devcontainer-guide.md](docs/devcontainer-guide.md)** +**VS Code DevContainer:** Reopen the workspace in the container via the Dev Containers extension. It uses the prebuilt `cpp-dev:latest` image with runtime UID/GID remapping. See [docs/devcontainer-guide.md](docs/devcontainer-guide.md). --- ## Continuous integration (GitHub Actions) -The CI pipeline runs on every push and pull request: +The CI pipeline runs on every push and pull request using the same project scripts: ```yaml -on: [push, pull_request] -runs-on: ubuntu-24.04 - steps: - - Install dependencies (cmake, clang-format) - - Build project with CMake - - Run all unit tests with ctest + - Install dependencies (cmake, clang-format, clang-tidy) + - Format check (./scripts/format.sh --check) + - Build (./scripts/build.sh) + - Lint check (./scripts/lint.sh) + - Test (./scripts/test.sh) ``` -See [.github/workflows/ci.yml](.github/workflows/ci.yml) for the complete configuration. - ---- - -## Unit tests +GitHub Actions sets `CI=true`, so scripts skip Docker delegation and run directly on the runner. See [docs/ci-container-delegation.md](docs/ci-container-delegation.md) for a GHCR upgrade path. -Unit tests are **enabled by default** using GoogleTest (fetched automatically via CMake FetchContent). - -```bash -cmake -S . -B build -cmake --build build -ctest --test-dir build --output-on-failure -``` - -To disable tests: -```bash -cmake -S . -B build -DENABLE_UNIT_TESTS=OFF -``` +See [.github/workflows/ci.yml](.github/workflows/ci.yml) for the complete configuration. From e25dfb46a8421bfa8289adf4a4db49f174d962a2 Mon Sep 17 00:00:00 2001 From: Julio Castillo Date: Wed, 11 Mar 2026 17:28:24 -0700 Subject: [PATCH 4/5] refactor: single Docker invocation for pre-push hook - Pre-push hook now sources env.sh + docker/exec.sh and delegates itself, so both format and lint run in one container (not two) - install-hooks.sh sources env.sh for consistent logging - Fix "all scripts" wording in README and CLAUDE.md to clarify that install-hooks.sh runs directly on the host --- .githooks/pre-push | 23 +++++++++++++---------- CLAUDE.md | 4 ++-- README.md | 4 ++-- scripts/install-hooks.sh | 8 +++++--- 4 files changed, 22 insertions(+), 17 deletions(-) diff --git a/.githooks/pre-push b/.githooks/pre-push index 113b893..16363c2 100755 --- a/.githooks/pre-push +++ b/.githooks/pre-push @@ -4,20 +4,23 @@ set -e ############################################################################### # Git pre-push hook # -# Runs formatting and linting checks before pushing. Delegates to the project -# scripts, which auto-delegate to Docker when run outside the container. +# Runs formatting and linting checks before pushing. Delegates to Docker +# as a single container invocation (via the same mechanism as other scripts). ############################################################################### -REPO_ROOT="$(git rev-parse --show-toplevel)" +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/../scripts" && pwd)" +source "$SCRIPT_DIR/env.sh" +source "$SCRIPT_DIR/docker/exec.sh" +delegate_to_container "$@" -echo "=== Pre-push: checking formatting ===" -"$REPO_ROOT/scripts/format.sh" --check +log_info "Pre-push: checking formatting..." +"$PROJECT_ROOT/scripts/format.sh" --check -BUILD_DIR="$REPO_ROOT/build" +BUILD_DIR="$PROJECT_ROOT/build" if [ ! -f "$BUILD_DIR/compile_commands.json" ]; then - echo "=== Pre-push: skipping clang-tidy (no compile_commands.json) ===" - echo "Run ./scripts/build.sh first to enable lint checks." + log_warn "Pre-push: skipping clang-tidy (no compile_commands.json)" + log_warn "Run ./scripts/build.sh first to enable lint checks." else - echo "=== Pre-push: running clang-tidy ===" - "$REPO_ROOT/scripts/lint.sh" + log_info "Pre-push: running clang-tidy..." + "$PROJECT_ROOT/scripts/lint.sh" fi diff --git a/CLAUDE.md b/CLAUDE.md index 8d58d13..f625bdc 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -15,9 +15,9 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co ./scripts/docs.sh # Generate Doxygen documentation ``` -Git hooks live in `.githooks/` (version-controlled). Install once after cloning: `./scripts/install-hooks.sh` +Git hooks live in `.githooks/` (version-controlled). Install once after cloning: `./scripts/install-hooks.sh` (runs directly on the host). -All scripts auto-delegate to Docker when run outside the container (`docker run --rm`). The delegation logic lives in `scripts/docker/exec.sh`, sourced by each script via `scripts/env.sh`. Inside the container or CI (`CI=true`), scripts run directly with no overhead. See `docs/ci-container-delegation.md` for details on the CI strategy and a GHCR upgrade path. +Build and quality scripts auto-delegate to Docker when run outside the container (`docker run --rm`). The delegation logic lives in `scripts/docker/exec.sh`, sourced by each script via `scripts/env.sh`. Inside the container or CI (`CI=true`), scripts run directly with no overhead. See `docs/ci-container-delegation.md` for details on the CI strategy and a GHCR upgrade path. ## Architecture diff --git a/README.md b/README.md index 9c1be13..cefd7cf 100644 --- a/README.md +++ b/README.md @@ -31,7 +31,7 @@ git clone my_project && cd my_project ./scripts/test.sh ``` -Every script in `scripts/` auto-delegates to Docker when run from the host. You don't need CMake, clang-format, or any other tool installed locally — just Docker. See [docs/ci-container-delegation.md](docs/ci-container-delegation.md) for details. +Build and quality scripts auto-delegate to Docker when run from the host. You don't need CMake, clang-format, or any other tool installed locally — just Docker. See [docs/ci-container-delegation.md](docs/ci-container-delegation.md) for details. --- @@ -71,7 +71,7 @@ Every script in `scripts/` auto-delegates to Docker when run from the host. You ## Scripts -All scripts auto-delegate to Docker when run on the host. Inside the container or CI (`CI=true`), they run directly. +Build and quality scripts auto-delegate to Docker when run on the host. Inside the container or CI (`CI=true`), they run directly. `install-hooks.sh` runs directly on the host to configure git. ### Build and Development diff --git a/scripts/install-hooks.sh b/scripts/install-hooks.sh index ff02d38..fd90ee0 100755 --- a/scripts/install-hooks.sh +++ b/scripts/install-hooks.sh @@ -8,10 +8,12 @@ set -e # are used automatically. Run once after cloning: # # ./scripts/install-hooks.sh +# +# This script runs directly on the host (no Docker delegation). ############################################################################### SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" -REPO_ROOT="$(dirname "$SCRIPT_DIR")" +source "$SCRIPT_DIR/env.sh" -git -C "$REPO_ROOT" config core.hooksPath .githooks -echo "[INFO] Git hooks installed (.githooks/). core.hooksPath set." +git -C "$PROJECT_ROOT" config core.hooksPath .githooks +log_info "Git hooks installed (.githooks/). core.hooksPath set." From 9988003d2f9dd09414879b3313c8709de0c34031 Mon Sep 17 00:00:00 2001 From: Julio Castillo Date: Wed, 11 Mar 2026 17:52:34 -0700 Subject: [PATCH 5/5] fix: drain stdin in pre-push hook and fix install-hooks comment - Drain git's ref info from stdin before delegation to prevent pipe blocking on pushes with many refs - Reword install-hooks.sh comment since it also runs inside containers via devcontainer postCreateCommand --- .githooks/pre-push | 3 +++ scripts/install-hooks.sh | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/.githooks/pre-push b/.githooks/pre-push index 16363c2..528cd49 100755 --- a/.githooks/pre-push +++ b/.githooks/pre-push @@ -8,6 +8,9 @@ set -e # as a single container invocation (via the same mechanism as other scripts). ############################################################################### +# Drain stdin — git pipes ref info here; leaving it unconsumed can block. +cat > /dev/null + SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/../scripts" && pwd)" source "$SCRIPT_DIR/env.sh" source "$SCRIPT_DIR/docker/exec.sh" diff --git a/scripts/install-hooks.sh b/scripts/install-hooks.sh index fd90ee0..6ef3e72 100755 --- a/scripts/install-hooks.sh +++ b/scripts/install-hooks.sh @@ -9,7 +9,7 @@ set -e # # ./scripts/install-hooks.sh # -# This script runs directly on the host (no Docker delegation). +# This script runs directly (no Docker delegation). ############################################################################### SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"