Skip to main content

JDF Hooks

CI Status PyPI License

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:

  1. Auto-detect languages in your project
  2. Let you select which hooks to enable
  3. Ask which hook manager you prefer (lefthook, pre-commit, or both)
  4. 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

  1. Install lefthook:
# macOS
brew install lefthook

# Or using npm
npm install -g lefthook

# Or using Go
go install github.com/evilmartians/lefthook@latest
  1. Install hooks:
lefthook install
  1. Test:
lefthook run pre-commit --all-files

Pre-commit

  1. 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
  1. Install hooks:
pre-commit install
  1. 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 configs
  • configs/yaml/ - YAML configs
  • configs/toml/ - TOML configs
  • configs/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:

  1. Keep lefthook and pre-commit configurations in sync
  2. Update AGENTS.md when adding new hooks
  3. Add test files to tests/integration/example_files/ for new languages
  4. Update this README with new tools/hooks
  5. 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)

Source distribution for jdf-hooks 1.0.1
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)

Table of built distributions (wheels) for jdf-hooks 1.0.1
File Interpreter ABI Platform Actions
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 log

Release 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 log

Security 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.

Select from 2 files

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 log

A 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.

Release history Release notifications | RSS feed

This release

1.0.1 This release

2 release files Full provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page