Blueprint for creating and distributing custom pre-commit hooks using uvx.
This repository demonstrates how to:
- Build a central repository of custom pre-commit hooks
- Distribute hooks as a Python package
- Consume hooks in target projects via pre-commit
- Version and evolve hooks over time
A Python package with 4 custom hooks:
- no-print-statements: Detect print() in Python code
- check-yaml-syntax: Validate YAML files
- check-secrets: Detect potential secrets/credentials
- check-markdown-links: Validate Markdown links
Example project showing how to consume the hooks with intentional violations for testing.
# 1. Navigate to target project
cd target-project
# 2. Run hooks (using uvx - no installation needed!)
uvx pre-commit run --all-files
# You'll see:
# ❌ Print statements detected in src/app.py
# ❌ Invalid YAML in config/invalid.yaml
# ❌ Secrets detected in src/config.py
# ❌ Broken links in docs/README.md# 1. Add to your .pre-commit-config.yaml
cat > .pre-commit-config.yaml << 'EOF'
repos:
- repo: https://github.com/MarDuer/uvx-pre-commit-hooks-poc.git
rev: v0.2.0
hooks:
- id: no-print-statements
- id: check-yaml-syntax
- id: check-secrets
- id: check-markdown-links
EOF
# 2. Install hooks
uvx pre-commit install
# 3. Run manually (optional)
uvx pre-commit run --all-files- BLUEPRINT.md - Complete guide with all details
- hooks-repo/README.md - Hook documentation
- target-project/README.md - Usage example
┌─────────────────────────────────────────────────────────┐
│ Hooks Repository │
│ (Python package with CLI entry points) │
│ │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ check_no_ │ │ check_yaml │ │ check_ │ │
│ │ print.py │ │ .py │ │ secrets.py │ │
│ └──────────────┘ └──────────────┘ └──────────────┘ │
│ │
│ pyproject.toml: Defines entry points │
│ .pre-commit-hooks.yaml: Hook metadata │
└─────────────────────────────────────────────────────────┘
│
│ Referenced by
▼
┌─────────────────────────────────────────────────────────┐
│ Target Project │
│ │
│ .pre-commit-config.yaml: │
│ repos: │
│ - repo: /path/to/hooks-repo │
│ rev: v0.2.0 │
│ hooks: │
│ - id: no-print-statements │
│ │
│ pyproject.toml: │
│ [tool.custom-hooks.no-print] │
│ exclude_patterns = ["# debug"] │
└─────────────────────────────────────────────────────────┘
Python packages can define CLI commands via [project.scripts]:
[project.scripts]
my-command = "package.module:main"Pre-commit discovers hooks via .pre-commit-hooks.yaml:
- id: my-hook
entry: my-command
language: pythonHooks support both CLI args and config files:
# CLI args
hooks:
- id: my-hook
args: [--option, value]# Config file
[tool.custom-hooks.my-hook]
option = "value"This blueprint shows two versions:
v0.1.0: Basic hooks (no-print, yaml) v0.2.0: Added security (secrets) and docs (markdown-links)
See git tags:
cd hooks-repo
git tag -l
# v0.1.0
# v0.2.0# 1. Create hook module
cat > hooks-repo/src/custom_hooks/my_hook.py << 'EOF'
import sys
def main():
print("My hook!")
return 0
if __name__ == "__main__":
sys.exit(main())
EOF
# 2. Add entry point
# Edit hooks-repo/pyproject.toml:
# [project.scripts]
# my-hook = "custom_hooks.my_hook:main"
# 3. Add hook definition
# Edit hooks-repo/.pre-commit-hooks.yaml:
# - id: my-hook
# name: My Hook
# entry: my-hook
# language: python
# 4. Version and tag
cd hooks-repo
git add .
git commit -m "Add my-hook"
git tag v0.3.0- Team Standards: Enforce coding conventions
- Security: Detect secrets, unsafe patterns
- Documentation: Validate links, check formatting
- Quality: Check test coverage, docstrings
- Compliance: Ensure license headers, file naming
✅ Centralized: One repo for all team hooks ✅ Versioned: Use git tags for releases ✅ Flexible: CLI args + config file support ✅ Fast: uvx caches installations ✅ Isolated: Each hook runs in its own environment ✅ Reusable: Share across multiple projects
This is a complete working example demonstrating:
- ✅ Hook implementation patterns
- ✅ Configuration support (CLI + file)
- ✅ Version management (v0.1.0 → v0.2.0)
- ✅ Multiple hook types (Python, YAML, Markdown, Security)
- ✅ Target project integration
- ✅ Comprehensive documentation
This is a blueprint/template. Fork and adapt for your needs!
Ideas for additional hooks:
- check-docstrings
- check-imports
- check-file-size
- check-branch-name
- check-commit-message
- check-license-headers
MIT - Use freely!
Ready to dive deeper? Read BLUEPRINT.md for the complete guide.