This guide explains how to set up the pre-commit hooks for this repository on macOS.
Pre-commit hooks automatically validate your code before each commit, catching issues early and ensuring consistent code quality. This repository uses Docker-based pre-commit hooks to enforce:
- shellcheck - Validates shell script syntax and best practices
- shfmt - Auto-formats shell scripts consistently
- markdownlint-cli2 - Enforces markdown style guidelines
These same checks also run in GitHub Actions (checkshell.yml workflow), so using pre-commit hooks locally saves time by catching issues before pushing.
Before installing pre-commit hooks, ensure you have:
- Homebrew - macOS package manager
- Docker - Required for running the linting tools in containers
Follow these steps to set up pre-commit hooks on macOS:
Check that Docker is running:
docker --version
docker psIf Docker is not installed, download and install Docker Desktop.
Install pre-commit using Homebrew:
brew install pre-commitVerify installation:
pre-commit --versionNavigate to the repository and install the hooks:
cd /path/to/docker-node-minimal
pre-commit installYou should see:
pre-commit installed at .git/hooks/pre-commitTest that all hooks work correctly:
pre-commit run --all-filesYou should see output like:
shellcheck...Passed
shfmt........Passed
markdownlint-cli2...PassedAll three should pass without errors. Docker will automatically pull the required container images on first run.
Hooks run automatically when you commit. Docker containers are launched automatically:
git commit -m "Your commit message"If any hook fails, the commit is blocked. Fix the errors and commit again.
Run all hooks on all files:
pre-commit run --all-filesRun a specific hook:
pre-commit run shellcheck --all-files
pre-commit run shfmt-docker --all-files
pre-commit run markdownlint-cli2-docker --all-filesRun hooks only on changed files (default behavior at commit time):
pre-commit runUpdate hooks to their latest compatible versions:
pre-commit autoupdateFor emergency commits (not recommended), bypass hooks:
git commit --no-verifyHooks are defined in .pre-commit-config.yaml and run inside Docker containers. Here's what each hook does:
- Purpose: Validates shell script syntax and style
- Files checked:
*.shand*.bats - Configuration: Default shellcheck rules
- Docker image: Runs in
koalaman/shellcheckcontainer
Detects:
- Syntax errors
- Non-portable code
- Unsafe variable usage
- Unused variables
- Purpose: Auto-formats shell scripts
- Files checked:
*.shand*.bats - Flags:
-sr -i 2 -w -ci-sr: Simplify and space-align words-i 2: Indent with 2 spaces-w: Write changes back to files-ci: Indent switch cases
- Docker image: Runs in
mvdan/shcontainer
Matches the formatting used in CI (GitHub Actions checkshell.yml).
- Purpose: Enforces markdown style guidelines
- Files checked:
*.md - Configuration: Respects
.markdownlint.yamlin repository root - Docker image: Runs in
davidanson/markdownlint-cli2container
Current settings:
- MD013 (line length) is disabled to allow longer documentation lines
The pre-commit command is not in your PATH.
Solution:
- Verify installation:
brew list pre-commit - If not installed:
brew install pre-commit - If installed, add to PATH or reinstall:
brew uninstall pre-commit
brew install pre-commitHooks run Docker containers for linting tools. Ensure Docker is running.
Solution:
- Start Docker Desktop (if using macOS)
- Verify Docker is available:
docker ps - Check if containers can be pulled:
docker pull alpine(test)
Docker Desktop is not running or Docker is not installed.
Solution:
- Start Docker Desktop from Applications
- Or install Docker Desktop: https://www.docker.com/products/docker-desktop
Solution: Verify installation and reinstall:
# Check if installed
ls -la .git/hooks/pre-commit
# Reinstall
pre-commit installSolution: Check file permissions:
# Make hooks executable
chmod +x .git/hooks/pre-commitSolution: Hooks are cached. Clear the cache:
pre-commit clean
pre-commit run --all-filesDocker container images are large. The first run will pull required images (shellcheck, shfmt, markdownlint-cli2), which may take a few minutes.
Solution: Wait for initial pull to complete. Subsequent runs will be faster as images are cached locally.
These same checks run in the GitHub Actions CI pipeline (.github/workflows/checkshell.yml):
- shfmt job: Validates formatting matches the configured rules
- shellcheck job: Validates shell scripts
Using pre-commit hooks locally ensures your changes pass CI checks before pushing.
For more details on pre-commit framework, see the official documentation.
For specific tool documentation: