JDF Hooks
A comprehensive Git hooks framework with an interactive CLI to set up hooks for any project. Supports both lefthook and pre-commit for fast local development with standardized CI/CD validation.
Quick Start
# Set up hooks in your project
uvx jdf-hooks setup
# Or install globally
pip install jdf-hooks
cd your-project
jdf-hooks setup
The CLI will:
- Auto-detect languages in your project
- Let you select which hooks to enable
- Ask which hook manager you prefer (lefthook, pre-commit, or both)
- Generate the appropriate configuration files
Philosophy: Hybrid Approach
This repository supports both hook managers to get the best of both worlds:
| Feature | Lefthook | Pre-commit |
|---|---|---|
| Speed | Extremely fast (<1s commits) | Slower (5-10s commits) |
| Parallelization | Native parallel execution | Sequential by default |
| Setup | Requires tool installation | Auto-manages environments |
| CI/CD | Works, but less common | Industry standard |
| Flexibility | High (direct commands) | Moderate (hook-based) |
| Best For | Local development | CI/CD pipelines |
Recommended Setup
- Local Development: Use lefthook for fast, parallel hook execution
- CI/CD: Use pre-commit for reproducible, standardized validation
- Contributors: Install both (5-10x faster locally, same results in CI)
Supported Languages & Tools
Python
- pycln - Remove unused imports
- isort - Sort imports
- ruff - Format and lint (replaces black + pylint)
- pyright - Type checking (default, fast)
- ty - Experimental type checker (10-60x faster, optional)
JavaScript/TypeScript
- prettier - Format JS/TS/JSON/CSS/HTML/Markdown
Rust
- rustfmt - Format Rust code
- clippy - Rust linter
Java
- PMD - Java linter
- CPD - Copy-paste detector
- Checkstyle - Java style checker
Note: Automatic Java formatting (google-java-format) is temporarily unavailable as of 1.0.1 while its integration is redesigned without the previous git-submodule dependency. See jdf-suite#4 for status.
Markdown
- markdownlint - Lint Markdown files
YAML
- yamlfix - Format YAML files
TOML
- taplo - Format and lint TOML files
SQL
- sqlfluff - Format and lint SQL (Postgres dialect)
Shell
- shfmt - Format shell scripts
General File Checks
- keep-sorted - Automatically maintain sorted blocks in files
- YAML syntax validation
- End-of-file fixer
- Trailing whitespace trimmer
- Mixed line ending fixer
- Private key detector
- AWS credentials detector
- Large file checker (prevents files >500KB)
Installation
Using uvx (Recommended — no install needed)
cd your-project
uvx jdf-hooks setup
Alternative: install globally
pip install jdf-hooks
jdf-hooks setup
Manual Installation
Lefthook
- Install lefthook:
# macOS
brew install lefthook
# Or using npm
npm install -g lefthook
# Or using Go
go install github.com/evilmartians/lefthook@latest
- Install hooks:
lefthook install
- Test:
lefthook run pre-commit --all-files
Pre-commit
- Install pre-commit:
# Using uv (recommended)
uv tool install pre-commit
# Or using pipx
pipx install pre-commit
# Or using pip
pip install pre-commit
- Install hooks:
pre-commit install
- Test:
pre-commit run --all-files
Tool Installation (for Lefthook)
Lefthook requires tools to be installed in your PATH. Pre-commit auto-manages environments, so this is only needed for lefthook.
Python Tools
# Using uv (recommended)
uv tool install pycln isort ruff pyright yamlfix sqlfluff
# Or using pipx
pipx install pycln isort ruff pyright yamlfix sqlfluff
JavaScript Tools
npm install -g prettier markdownlint-cli
Rust Tools
# Add rustfmt and clippy components
rustup component add rustfmt clippy
# Install taplo for TOML
cargo install taplo-cli
Shell Tools
# macOS
brew install shfmt
# Ubuntu/Debian
sudo apt-get install shfmt
# Arch Linux
sudo pacman -S shfmt
Java Tools
Java tools (PMD, Checkstyle) are managed automatically by the hooks. CPD is bundled with PMD. Google Java Format is temporarily unavailable (see README note above).
General Tools
# Install keep-sorted using Go
go install github.com/google/keep-sorted/cmd/keep-sorted@latest
Usage
Using Lefthook
Run hooks on staged files:
git commit
Run hooks on all files:
lefthook run pre-commit --all-files
Skip hooks (not recommended):
LEFTHOOK=0 git commit
Skip specific hooks:
LEFTHOOK_EXCLUDE=ruff-check,pyright git commit
Using Pre-commit
Run hooks on staged files:
git commit
Run hooks on all files:
pre-commit run --all-files
Skip hooks (not recommended):
SKIP=all git commit
Skip specific hooks:
SKIP=ruff-check,pyright git commit
Update hook versions:
pre-commit autoupdate
Configuration
Shared Tool Settings
Both lefthook and pre-commit use the same tool configurations from configs/:
configs/markdown/- Markdown configsconfigs/yaml/- YAML configsconfigs/toml/- TOML configsconfigs/sql/- SQL configs
Customizing Hooks
For Lefthook: Edit lefthook.yml
For Pre-commit: Edit the generated .pre-commit-config.yaml in your project
Refer to AGENTS.md for guidelines on keeping both configurations in sync.
Project Structure
jdf-hooks/
├── src/jdf_hooks/ # Python CLI package
│ ├── cli.py # Interactive CLI
│ ├── detect.py # Language detection
│ └── generate.py # Config generation
├── configs/ # Tool configuration files
│ ├── markdown/
│ ├── yaml/
│ ├── toml/
│ └── sql/
├── tests/ # Test suite
├── lefthook.yml # Lefthook config (project-specific)
└── pyproject.toml # Package definition
CI/CD Integration
GitHub Actions (Pre-commit)
name: CI
on: [push, pull_request]
jobs:
pre-commit:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- uses: actions/setup-python@v6
- uses: pre-commit/action@v4.0.0
GitHub Actions (Lefthook)
name: CI
on: [push, pull_request]
jobs:
lefthook:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- name: Install lefthook
run: npm install -g lefthook
- name: Install tools
run: |
pip install pycln isort ruff pyright yamlfix sqlfluff
npm install -g prettier markdownlint-cli
rustup component add rustfmt clippy
- name: Run lefthook
run: lefthook run pre-commit --all-files
Recommendation: Use pre-commit in CI for standardization. This repository's CI runs both configurations to ensure consistency.
Testing
Run the automated test suite:
uv run pytest tests/test_generate.py
Run integration tests (requires actual tools installed):
uv run python tests/integration/test_precommit.py --verbose
uv run python tests/integration/test_lefthook.py --verbose
Troubleshooting
Lefthook Issues
Hook fails with "command not found"
- Install the missing tool (see Tool Installation section)
- Verify tool is in your PATH:
which <tool>
Lefthook hooks are slow
- Check if tools are using network (especially Docker-based hooks)
- Verify parallel execution is enabled in
lefthook.yml
Hooks don't run
- Verify installation:
lefthook run pre-commit --all-files - Check lefthook.yml syntax:
lefthook dump
Pre-commit Issues
Hooks fail to install
- Update pre-commit:
uv tool install --force pre-commit - Clear cache:
pre-commit clean
Pre-commit hooks are slow
- Pre-commit creates isolated environments (this is expected)
- Consider using lefthook for local development
Hook version conflicts
- Update hooks:
pre-commit autoupdate - Clear cache:
pre-commit clean
General Issues
Hooks modified files but commit still fails
- Re-stage modified files:
git add . - Commit again (hooks will pass on second run)
Java hooks fail
- Ensure JDK 11+ is installed:
java -version - Check Docker is running (for PMD)
Contributing
Contributions welcome! Please:
- Keep lefthook and pre-commit configurations in sync
- Update
AGENTS.mdwhen adding new hooks - Add test files to
tests/integration/example_files/for new languages - Update this README with new tools/hooks
- Test both configurations before submitting
License
MIT License - See LICENSE file for details
Acknowledgments
Built with:
- lefthook - Fast Git hooks manager
- pre-commit - Multi-language Git hooks framework
- Astral - ruff, uv, ty, and other amazing Python tooling
- All the amazing open-source tools integrated in this repository
Version: 1.0.1 | Hybrid Approach: Lefthook (local) + Pre-commit (CI)
Metadata
Release files for jdf-hooks 1.0.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| jdf_hooks-1.0.1.tar.gz | 18.4 kB | With provenance | Details for jdf_hooks-1.0.1.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| jdf_hooks-1.0.1-py3-none-any.whl | Python 3 | none | any | Details for jdf_hooks-1.0.1-py3-none-any.whl |
Total release size: 42.9 kB
Release files / jdf_hooks-1.0.1.tar.gz
| Download URL | jdf_hooks-1.0.1.tar.gz |
|---|---|
| Size | 18.4 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
61eadd2d4bf4746fd13ecfa22ec6e47410d0a5641edcaceb3492a615a76e0b57
|
|
BLAKE2b-256 checksum How to use checksums |
c89ac3801fee8e15ba1b1ba5f0b92801a04e1b207b40bbaa0d1a3e8ed830d32a
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Apr 18, 2026.
Transparency logRelease files / jdf_hooks-1.0.1-py3-none-any.whl
| Download URL | jdf_hooks-1.0.1-py3-none-any.whl |
|---|---|
| Size | 24.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
c0d3b03d738cb893e9189fc2361ef527f002e1a5fb3b99e183b560332591ff44
|
|
BLAKE2b-256 checksum How to use checksums |
66098bc5090819a62005f4ae18139040bdc9602f1193676d35c9241fcbd585d1
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Apr 18, 2026.
Transparency logSecurity for jdf-hooks 1.0.1
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
Full provenance
All 2 files in this release have been uploaded with provenance metadata.
Attestation for jdf_hooks-1.0.1.tar.gz
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Apr 18, 2026.
Transparency logA note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.