diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml
index ab6322fa..47422e09 100644
--- a/.github/workflows/deploy.yml
+++ b/.github/workflows/deploy.yml
@@ -5,12 +5,17 @@ on:
schedule:
- cron: '30 8 * * *'
+permissions:
+ contents: write
+
jobs:
pr:
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v1
- - uses: actions/setup-python@v1
+ - uses: actions/checkout@v3
+ - uses: actions/setup-python@v4
+ with:
+ python-version: 3.x
- run: pip install virtualenv
- run: make
- run: make push
diff --git a/.gitignore b/.gitignore
index 8a877944..8658b840 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,6 +1,4 @@
*.html
*.pyc
-*.swp
-/all-hooks.json
/build
/node_modules
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index 67dba743..1f2f8c10 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -1,6 +1,6 @@
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
- rev: v4.3.0
+ rev: v6.0.0
hooks:
- id: trailing-whitespace
- id: end-of-file-fixer
@@ -9,47 +9,34 @@ repos:
- id: double-quote-string-fixer
- id: name-tests-test
- id: requirements-txt-fixer
-- repo: https://github.com/asottile/reorder_python_imports
- rev: v3.8.2
+- repo: https://github.com/asottile/reorder-python-imports
+ rev: v3.16.0
hooks:
- id: reorder-python-imports
- args: [--py37-plus, --add-import, 'from __future__ import annotations']
- exclude: ^install-local.py$
+ args: [--py310-plus, --add-import, 'from __future__ import annotations']
- id: reorder-python-imports
- files: ^install-local.py$
- repo: https://github.com/asottile/add-trailing-comma
- rev: v2.2.3
+ rev: v4.0.0
hooks:
- id: add-trailing-comma
- args: [--py36-plus]
- repo: https://github.com/asottile/pyupgrade
- rev: v2.37.3
+ rev: v3.21.2
hooks:
- id: pyupgrade
- args: [--py37-plus]
- exclude: ^install-local.py$
-- repo: https://github.com/pre-commit/mirrors-autopep8
- rev: v1.7.0
+ args: [--py310-plus]
+- repo: https://github.com/hhatto/autopep8
+ rev: v2.3.2
hooks:
- id: autopep8
- repo: https://github.com/PyCQA/flake8
- rev: 5.0.4
+ rev: 7.3.0
hooks:
- id: flake8
- repo: https://github.com/pre-commit/mirrors-mypy
- rev: v0.971
+ rev: v2.1.0
hooks:
- id: mypy
- additional_dependencies: [types-all]
-- repo: https://github.com/pre-commit/mirrors-eslint
- rev: v8.22.0
- hooks:
- - id: eslint
- args: [--fix]
-- repo: local
- hooks:
- - id: no-github-dot-git
- name: No need for .git for github/gitlab urls
- entry: '(github|gitlab).*\.git'
- files: all-repos.yaml
- language: pygrep
+- repo: https://github.com/biomejs/pre-commit
+ rev: v2.5.0
+ hooks:
+ - id: biome-check
diff --git a/Makefile b/Makefile
index c4a58357..81533eda 100644
--- a/Makefile
+++ b/Makefile
@@ -1,4 +1,4 @@
-all: install-hooks build/main_bs5.css all-hooks.json index.html hooks.html
+all: install-hooks build/main_bs5.css index.html hooks.html
.PHONY: install-hooks
install-hooks: venv
@@ -7,10 +7,7 @@ install-hooks: venv
build/main_bs5.css: node_modules build scss/main_bs5.scss scss/_variables.scss
node_modules/.bin/sass --style=compressed --load-path=. scss/main_bs5.scss build/main_bs5.css
-all-hooks.json: venv make_all_hooks.py all-repos.yaml
- venv/bin/python make_all_hooks.py
-
-index.html hooks.html: venv all-hooks.json base.mako index.mako hooks.mako make_templates.py template_lib.py sections/*.md
+index.html hooks.html: venv base.mako index.mako hooks.mako make_templates.py template_lib.py sections/*.md
venv/bin/python make_templates.py
venv: requirements-dev.txt Makefile
@@ -28,11 +25,10 @@ node_modules: package.json
push: venv
venv/bin/markdown-to-presentation push \
.nojekyll README.md CNAME \
- build assets *.html *.png *.svg favicon.ico \
- all-hooks.json install-local.py
+ build assets *.html *.png *.svg favicon.ico
clean:
- rm -rf venv build node_modules *.html all-hooks.json
+ rm -rf venv build node_modules *.html
build:
mkdir -p build
diff --git a/README.md b/README.md
index 60489cfc..c311257b 100644
--- a/README.md
+++ b/README.md
@@ -2,6 +2,6 @@ pre-commit.com
==============
[](https://results.pre-commit.ci/latest/github/pre-commit/pre-commit.com/main)
-[](https://github.com/pre-commit/pre-commit.com/actions)
+[](https://github.com/pre-commit/pre-commit.com/actions)
This powers https://pre-commit.com
diff --git a/all-repos.yaml b/all-repos.yaml
deleted file mode 100644
index bafef002..00000000
--- a/all-repos.yaml
+++ /dev/null
@@ -1,223 +0,0 @@
-# This file is used to generate all-hooks.json
-- https://github.com/pre-commit/pre-commit-hooks
-- https://github.com/pre-commit/mirrors-autopep8
-- https://github.com/pre-commit/mirrors-clang-format
-- https://github.com/pre-commit/mirrors-coffeelint
-- https://github.com/pre-commit/mirrors-csslint
-- https://github.com/pre-commit/mirrors-eslint
-- https://github.com/pre-commit/mirrors-fixmyjs
-- https://github.com/pre-commit/mirrors-jshint
-- https://github.com/pre-commit/mirrors-mypy
-- https://github.com/pre-commit/mirrors-prettier
-- https://github.com/pre-commit/mirrors-puppet-lint
-- https://github.com/pre-commit/mirrors-ruby-lint
-- https://github.com/pre-commit/mirrors-scss-lint
-- https://github.com/pre-commit/mirrors-yapf
-- https://github.com/pre-commit/pygrep-hooks
-- https://github.com/FalconSocial/pre-commit-mirrors-pep257
-- https://github.com/FalconSocial/pre-commit-python-sorter
-- https://github.com/MarketSquare/robotframework-tidy
-- https://github.com/guykisel/prospector-mirror
-- https://github.com/asottile/add-trailing-comma
-- https://github.com/asottile/pyupgrade
-- https://github.com/asottile/reorder_python_imports
-- https://github.com/asottile/yesqa
-- https://github.com/asottile/blacken-docs
-- https://github.com/asottile/dead
-- https://github.com/asottile/setup-cfg-fmt
-- https://github.com/asottile/cheetah_lint
-- https://github.com/digitalpulp/pre-commit-php
-- https://github.com/elidupuis/mirrors-jscs
-- https://github.com/elidupuis/mirrors-sass-lint
-- https://github.com/jumanjihouse/pre-commit-hooks
-- https://github.com/jumanjihouse/pre-commit-hook-yamlfmt
-- https://github.com/Lucas-C/pre-commit-hooks
-- https://github.com/Lucas-C/pre-commit-hooks-go
-- https://github.com/Lucas-C/pre-commit-hooks-java
-- https://github.com/Lucas-C/pre-commit-hooks-lxml
-- https://github.com/Lucas-C/pre-commit-hooks-markup
-- https://github.com/Lucas-C/pre-commit-hooks-nodejs
-- https://github.com/Lucas-C/pre-commit-hooks-safety
-- https://github.com/chriskuehl/puppet-pre-commit-hooks
-- https://github.com/golangci/golangci-lint
-- https://github.com/Bahjat/pre-commit-golang
-- https://github.com/dnephin/pre-commit-golang
-- https://github.com/troian/pre-commit-golang
-- https://github.com/jstewmon/check-swagger
-- https://github.com/detailyang/pre-commit-shell
-- https://github.com/lovesegfault/beautysh
-- https://github.com/antonbabenko/pre-commit-terraform
-- https://github.com/ansible-community/ansible-lint
-- https://github.com/doublify/pre-commit-clang-format
-- https://github.com/doublify/pre-commit-go
-- https://github.com/doublify/pre-commit-hindent
-- https://github.com/doublify/pre-commit-rust
-- https://github.com/kintoandar/pre-commit
-- https://github.com/awebdeveloper/pre-commit-stylelint
-- https://github.com/awebdeveloper/pre-commit-tslint
-- https://github.com/adrienverge/yamllint
-- https://github.com/thlorenz/doctoc
-- https://github.com/noahsark769/xcodeproj-sort-pre-commit-hook
-- https://github.com/jorisroovers/gitlint
-- https://github.com/psf/black
-- https://github.com/IamTheFij/ansible-pre-commit
-- https://github.com/IamTheFij/docker-pre-commit
-- https://github.com/mattlqx/pre-commit-ruby
-- https://github.com/mattlqx/pre-commit-sign
-- https://github.com/mattlqx/pre-commit-search-and-replace
-- https://github.com/pryorda/dockerfilelint-precommit-hooks
-- https://github.com/alessandrojcm/commitlint-pre-commit-hook
-- https://github.com/henryykt/pre-commit-perl
-- https://github.com/juancarlospaco/pre-commit-nim
-- https://github.com/aws-cloudformation/cfn-python-lint
-- https://github.com/thoughtworks/talisman
-- https://github.com/PyCQA/flake8
-- https://github.com/PyCQA/bandit
-- https://github.com/PyCQA/pydocstyle
-- https://github.com/PyCQA/pylint
-- https://github.com/PyCQA/doc8
-- https://github.com/PyCQA/prospector
-- https://github.com/PyCQA/isort
-- https://github.com/miki725/importanize
-- https://github.com/motet-a/jinjalint
-- https://github.com/milin/giticket
-- https://github.com/milin/gitown
-- https://github.com/sqlalchemyorg/zimports
-- https://github.com/peterdemin/pip-compile-multi
-- https://github.com/homebysix/pre-commit-macadmin
-- https://github.com/fortman/pre-commit-prometheus
-- https://github.com/syntaqx/git-hooks
-- https://github.com/lunarmodules/luacheck
-- https://github.com/Koihik/LuaFormatter
-- https://github.com/Calinou/pre-commit-luacheck
-- https://github.com/belminf/pre-commit-chef
-- https://github.com/pocc/pre-commit-hooks
-- https://github.com/dwightgunning/pre-commit-nglint
-- https://github.com/codespell-project/codespell
-- https://gitlab.com/smop/pre-commit-hooks
-- https://github.com/seddonym/import-linter
-- https://github.com/marco-c/taskcluster_yml_validator
-- https://github.com/myint/docformatter
-- https://github.com/myint/rstcheck
-- https://github.com/myint/autoflake
-- https://github.com/lorenzwalthert/precommit
-- https://github.com/FelixSeptem/pre-commit-golang
-- https://gitlab.com/daverona/pre-commit/cpp
-- https://github.com/codingjoe/relint
-- https://github.com/nix-community/nixpkgs-fmt
-- https://github.com/d6e/beancount-check
-- https://gitlab.com/iamlikeme/nbhooks
-- https://github.com/Vimjas/vint
-- https://github.com/eschulte/lisp-format
-- https://github.com/shellcheck-py/shellcheck-py
-- https://github.com/APIDevTools/swagger-cli
-- https://github.com/kynan/nbstripout
-- https://gitlab.com/devopshq/gitlab-ci-linter
-- https://github.com/bmorcos/pre-commit-hooks-cpp
-- https://github.com/igorshubovych/markdownlint-cli
-- https://github.com/TekWizely/pre-commit-golang
-- https://github.com/markdownlint/markdownlint
-- https://github.com/jguttman94/pre-commit-gradle
-- https://github.com/Yelp/detect-secrets
-- https://github.com/dmitri-lerko/pre-commit-docker-kustomize
-- https://github.com/perltidy/perltidy
-- https://github.com/talos-systems/conform
-- https://github.com/twu/skjold
-- https://github.com/commitizen-tools/commitizen
-- https://github.com/gherynos/pre-commit-java
-- https://github.com/lietu/go-pre-commit
-- https://github.com/macisamuele/language-formatters-pre-commit-hooks
-- https://github.com/jlebar/pre-commit-hooks
-- https://github.com/jazzband/pip-tools
-- https://github.com/pappasam/toml-sort
-- https://github.com/arenadotio/pre-commit-ocamlformat
-- https://github.com/hcodes/yaspeller
-- https://github.com/maltzj/google-style-precommit-hook
-- https://github.com/jvstein/pre-commit-dotnet-format
-- https://github.com/PeterMosmans/jenkinslint
-- https://github.com/nicklockwood/SwiftFormat
-- https://github.com/executablebooks/mdformat
-- https://gitlab.com/daverona/pre-commit/php
-- https://github.com/anderseknert/pre-commit-opa
-- https://github.com/radix-ai/auto-smart-commit
-- https://github.com/thibaudcolas/curlylint
-- https://github.com/cheshirekow/cmake-format-precommit
-- https://github.com/aorumbayev/pydantic-to-schema
-- https://github.com/hadialqattan/pycln
-- https://github.com/nbQA-dev/nbQA
-- https://github.com/Scony/godot-gdscript-toolkit
-- https://github.com/avilaton/add-msg-issue-prefix-hook
-- https://github.com/dustinsand/pre-commit-jvm
-- https://github.com/alan-turing-institute/CleverCSV-pre-commit
-- https://gitlab.com/jvenom/elixir-pre-commit-hooks
-- https://github.com/Cretezy/flutter-format-pre-commit
-- https://github.com/dluksza/flutter-analyze-pre-commit
-- https://github.com/fluttercommunity/import_sorter
-- https://github.com/editorconfig-checker/editorconfig-checker.python
-- https://gitlab.com/pablodiehl/pre-commit-lua-formatter
-- https://github.com/frnmst/md-toc
-- https://github.com/mgedmin/check-manifest
-- https://github.com/ecugol/pre-commit-hooks-django
-- https://github.com/PrincetonUniversity/blocklint
-- https://github.com/python-jsonschema/check-jsonschema
-- https://github.com/sirosen/texthooks
-- https://github.com/snok/pep585-upgrade
-- https://github.com/jendrikseipp/vulture
-- https://github.com/mwouts/jupytext
-- https://github.com/ejba/pre-commit-maven
-- https://github.com/tfsec/tfsec
-- https://github.com/yoheimuta/protolint
-- https://github.com/hadolint/hadolint
-- https://github.com/google/go-jsonnet
-- https://github.com/guid-empty/flutter-dependency-validation-pre-commit
-- https://github.com/cpplint/cpplint
-- https://github.com/MarcoGorelli/absolufy-imports
-- https://github.com/domdfcoding/flake2lint
-- https://github.com/dotnet/format
-- https://github.com/ashwin153/pre-commit-vagrant
-- https://github.com/AleksaC/hadolint-py
-- https://github.com/AleksaC/circleci-cli-py
-- https://github.com/AleksaC/mirrors-cfn-nag
-- https://github.com/cmake-lint/cmake-lint
-- https://github.com/priv-kweihmann/oelint-adv
-- https://github.com/jggomez/pre-commit-android-kotlin
-- https://github.com/Carreau/velin
-- https://github.com/chrismgrayftsinc/jsonnetfmt
-- https://github.com/zricethezav/gitleaks
-- https://github.com/hugoh/pre-commit-fish
-- https://github.com/redwarp/optimize-png-hooks
-- https://github.com/nbyl/pre-commit-license-checks
-- https://github.com/jonasbb/pre-commit-latex-hooks
-- https://github.com/dfm/black_nbconvert
-- https://github.com/crate-ci/typos
-- https://github.com/snakemake/snakefmt
-- https://github.com/regebro/pyroma
-- https://github.com/tox-dev/tox-ini-fmt
-- https://github.com/janosh/format-ipy-cells
-- https://github.com/FalcoSuessgott/lint-gitlab-ci
-- https://github.com/comkieffer/xml-linter-hook
-- https://github.com/jackdewinter/pymarkdown
-- https://github.com/klieret/jekyll-relative-url-check
-- https://github.com/tarioch/flux-check-hook
-- https://github.com/streetsidesoftware/cspell-cli
-- https://github.com/rapidsai/frigate
-- https://github.com/norwoodj/helm-docs
-- https://github.com/sqlfluff/sqlfluff
-- https://github.com/adamchainz/pre-commit-dprint
-- https://github.com/scop/pre-commit-shfmt
-- https://github.com/BlankSpruce/gersemi
-- https://github.com/realm/SwiftLint
-- https://gitlab.com/bmares/check-json5
-- https://github.com/semaphor-dk/dansabel
-- https://github.com/gitguardian/gg-shield
-- https://github.com/JohnnyMorganz/StyLua
-- https://github.com/shssoichiro/oxipng
-- https://github.com/datarootsio/databooks
-- https://github.com/standard/standard
-- https://github.com/Sceptre/sceptrelint
-- https://github.com/lyz-code/yamlfix
-- https://github.com/dannysepler/rm_unneeded_f_str
-- https://github.com/cmhughes/latexindent.pl
-- https://github.com/sirwart/ripsecrets
-- https://github.com/bagerard/graphviz-dot-hooks
-- https://github.com/omnilib/ufmt
diff --git a/assets/copyable.js b/assets/copyable.js
index 8aba102f..7d18e25b 100644
--- a/assets/copyable.js
+++ b/assets/copyable.js
@@ -1,6 +1,8 @@
-(function () {
+'use strict';
+
+(() => {
function copyTextToClipboard(text) {
- var textArea = document.createElement('textarea');
+ const textArea = document.createElement('textarea');
textArea.value = text;
textArea.style.position = 'fixed';
textArea.style.left = '-1';
@@ -11,17 +13,15 @@
document.execCommand('copy');
document.body.removeChild(textArea);
}
- var codeBlockElements = document.getElementsByClassName('copyable');
- for (var i = 0; i < codeBlockElements.length; i++) {
- var block = codeBlockElements[i];
- var copyIcon = new Image(16, 16);
+ for (const block of document.getElementsByClassName('copyable')) {
+ const copyIcon = new Image(16, 16);
copyIcon.setAttribute('src', './assets/copy-icon.svg');
copyIcon.setAttribute('alt', 'copy');
copyIcon.setAttribute('title', 'copy to clipboard');
block.insertBefore(copyIcon, block.children[0]);
- copyIcon.addEventListener('click', function(block) {
- var text = block.getElementsByTagName('pre')[0].innerText;
+ copyIcon.addEventListener('click', () => {
+ const text = block.getElementsByTagName('pre')[0].innerText;
copyTextToClipboard(text);
- }.bind(null, block));
+ });
}
})();
diff --git a/assets/filter_repos.js b/assets/filter_repos.js
deleted file mode 100644
index 718cb73d..00000000
--- a/assets/filter_repos.js
+++ /dev/null
@@ -1,41 +0,0 @@
-'use strict';
-
-(() => {
- const searchInput = document.getElementById('search-hook-id');
- const selectInput = document.getElementById('select-hook-type');
-
- const hooks = document.getElementById('hooks');
- const repos = hooks.getElementsByTagName('ul');
-
- const filterHooks = () => {
- const id = searchInput.value.toLowerCase();
- const type = selectInput.value;
-
- for (let i = 0; i < repos.length; i += 1) {
- const repo = repos[i];
- let hasVisibleHooks = false;
- const repoHooks = repo.getElementsByTagName('li');
-
- if (repoHooks) {
- for (let j = 0; j < repoHooks.length; j += 1) {
- const repoHook = repoHooks[j];
- const hookId = repoHook.dataset.id.toLowerCase();
- const hookTypes = repoHook.dataset.types.split(', ');
-
- if (hookId.includes(id) && (type === '' || hookTypes.includes(type))) {
- repoHook.hidden = false;
- hasVisibleHooks = true;
- } else {
- repoHook.hidden = true;
- }
- }
- }
-
- repo.hidden = !hasVisibleHooks;
- hooks.querySelector(`h3[data-repo="${repo.dataset.repo}"]`).hidden = !hasVisibleHooks;
- }
- };
-
- searchInput.addEventListener('input', filterHooks);
- selectInput.addEventListener('change', filterHooks);
-})();
diff --git a/base.mako b/base.mako
index b0545d26..77ba61f4 100644
--- a/base.mako
+++ b/base.mako
@@ -54,11 +54,8 @@
A framework for managing and maintaining multi-language pre-commit hooks.
-
+
@@ -88,7 +81,7 @@
-
+
+${body}
diff --git a/install-local.py b/install-local.py
deleted file mode 100644
index e46e9816..00000000
--- a/install-local.py
+++ /dev/null
@@ -1,127 +0,0 @@
-#!/usr/bin/env python
-from __future__ import absolute_import
-from __future__ import print_function
-from __future__ import unicode_literals
-
-import contextlib
-import hashlib
-import io
-import os.path
-import shutil
-import subprocess
-import sys
-import tarfile
-
-import distutils.spawn
-
-
-if str is bytes:
- from urllib import urlopen # type: ignore
-else:
- from urllib.request import urlopen
-
-if False:
- from typing import Generator
-
-
-TGZ = (
- 'https://files.pythonhosted.org/packages/a4/e3/'
- '1f067de470e3a86875ed915438dc3bd781fb0346254f541190a09472b677/'
- 'virtualenv-16.7.10.tar.gz'
-)
-CHECKSUM = 'e88fdcb08b0ecb11da97868f463dd06275923f50d87f4b9c8b2fc0994eec40f4'
-PKG_PATH = '/tmp/.virtualenv-pkg'
-
-
-def clean(dirname):
- # type: (str) -> None
- if os.path.exists(dirname):
- shutil.rmtree(dirname)
-
-
-@contextlib.contextmanager
-def clean_path():
- # type: (...) -> Generator[None, None, None]
- try:
- yield
- finally:
- clean(PKG_PATH)
-
-
-def virtualenv(path):
- # type: (str) -> int
- clean(PKG_PATH)
- clean(path)
-
- print('Downloading ' + TGZ)
- tar_bytes = urlopen(TGZ).read()
- checksum = hashlib.sha256(tar_bytes).hexdigest()
- if checksum != CHECKSUM:
- print(
- 'Checksums did not match. '
- 'Got {}, expected {}.'.format(checksum, CHECKSUM),
- file=sys.stderr,
- )
- return 1
-
- tar_stream = io.BytesIO(tar_bytes)
- with contextlib.closing(tarfile.open(fileobj=tar_stream)) as tarfile_obj:
- # Chop off the first path segment to avoid having the version in
- # the path
- for member in tarfile_obj.getmembers():
- _, _, member.name = member.name.partition('/')
- if member.name:
- tarfile_obj.extract(member, PKG_PATH)
- print('Done.')
-
- with clean_path():
- return subprocess.call((
- sys.executable, os.path.join(PKG_PATH, 'virtualenv.py'), path,
- ))
-
-
-def main():
- # type: (...) -> int
- venv_path = os.path.join(os.environ['HOME'], '.pre-commit-venv')
- bin_dir = os.path.join(os.environ['HOME'], 'bin')
- script_src = os.path.join(venv_path, 'bin', 'pre-commit')
- script_dest = os.path.join(bin_dir, 'pre-commit')
-
- if sys.argv[1:] == ['uninstall']:
- clean(PKG_PATH)
- clean(venv_path)
- if os.path.lexists(script_dest):
- os.remove(script_dest)
- print('Cleaned ~/.pre-commit-venv ~/bin/pre-commit')
- return 0
-
- if virtualenv(venv_path):
- return 1
-
- subprocess.check_call((
- os.path.join(venv_path, 'bin', 'pip'), 'install', 'pre-commit',
- ))
-
- print('*' * 79)
- print('Installing pre-commit to {}'.format(script_dest))
- print('*' * 79)
-
- if not os.path.exists(bin_dir):
- os.mkdir(bin_dir)
-
- # os.symlink is not idempotent
- if os.path.exists(script_dest):
- os.remove(script_dest)
-
- os.symlink(script_src, script_dest)
-
- if not distutils.spawn.find_executable('pre-commit'):
- print('It looks like {} is not on your path'.format(bin_dir))
- print('You may want to add it.')
- print('Often this does the trick: source ~/.profile')
-
- return 0
-
-
-if __name__ == '__main__':
- raise SystemExit(main())
diff --git a/make_all_hooks.py b/make_all_hooks.py
deleted file mode 100644
index d88d9ce6..00000000
--- a/make_all_hooks.py
+++ /dev/null
@@ -1,54 +0,0 @@
-from __future__ import annotations
-
-import functools
-import json
-import multiprocessing
-import os.path
-import subprocess
-import tempfile
-from typing import Any
-
-import yaml
-from pre_commit.clientlib import load_manifest
-
-Loader = getattr(yaml, 'CSafeLoader', yaml.SafeLoader)
-fast_load = functools.partial(yaml.load, Loader=Loader)
-
-
-def get_manifest(repo_path: str) -> tuple[bool, str, list[dict[str, Any]]]:
- print(f'*** {repo_path}')
- with tempfile.TemporaryDirectory() as directory:
- repo_dir = os.path.join(directory, 'repo')
- cmd = ('git', 'clone', '--depth', '1', '-q', repo_path, repo_dir)
- subprocess.check_call(cmd)
- manifest_path = os.path.join(repo_dir, '.pre-commit-hooks.yaml')
- # Validate the manifest just to make sure it's ok.
- manifest = load_manifest(manifest_path)
- # hooks should not set debugging `verbose: true` flag
- for hook in manifest:
- if hook['verbose']:
- print(f'{repo_path} ({hook["id"]}) sets `verbose: true`')
- return False, repo_path, []
-
- with open(manifest_path) as f:
- return True, repo_path, fast_load(f)
-
-
-def main() -> int:
- with open('all-repos.yaml') as f:
- repos = fast_load(f)
-
- hooks_json = {}
- with multiprocessing.Pool(4) as pool:
- for ok, path, manifest in pool.map(get_manifest, repos):
- if not ok:
- return 1
- hooks_json[path] = manifest
-
- with open('all-hooks.json', 'w') as hooks_json_file:
- json.dump(hooks_json, hooks_json_file, indent=4)
- return 0
-
-
-if __name__ == '__main__':
- raise SystemExit(main())
diff --git a/make_templates.py b/make_templates.py
index 2e5c2de8..aca62aed 100644
--- a/make_templates.py
+++ b/make_templates.py
@@ -1,9 +1,6 @@
from __future__ import annotations
-import collections
-import json
import os.path
-from typing import Any
import mako.lookup
import markupsafe
@@ -29,13 +26,7 @@
)
-ALL_TEMPLATES = [
- filename for filename in os.listdir('.')
- if filename.endswith('.mako') and filename != 'base.mako'
-]
-
-
-def get_env() -> dict[str, Any]:
+def index_body() -> markupsafe.Markup:
body_parts = []
for title, filename in SECTIONS:
div_id, _ = os.path.splitext(os.path.basename(filename))
@@ -50,30 +41,22 @@ def get_env() -> dict[str, Any]:
f'\n',
),
)
- body = markupsafe.Markup().join(body_parts)
+ return markupsafe.Markup().join(body_parts)
- all_hooks = json.loads(
- open('all-hooks.json').read(),
- object_pairs_hook=collections.OrderedDict,
- )
- all_types = {
- hook_type
- for properties in all_hooks.values()
- for hook_type in (
- properties[0].get('types', []) + properties[0].get('types_or', [])
- )
- }
- return {'all_hooks': all_hooks, 'all_types': all_types, 'body': body}
+
+def hooks_body() -> markupsafe.Markup:
+ with open('sections/hooks.md') as f:
+ return md(f.read())
def main() -> int:
- env = get_env()
- for template in ALL_TEMPLATES:
- template_name, _ = os.path.splitext(template)
- env['template_name'] = template_name
- with open(f'{template_name}.html', 'w') as html_file:
- template_obj = template_lookup.get_template(template)
- html_file.write(template_obj.render(**env))
+ with open('index.html', 'w') as f:
+ tmpl = template_lookup.get_template('index.mako')
+ f.write(tmpl.render(body=index_body(), template_name='index'))
+
+ with open('hooks.html', 'w') as f:
+ tmpl = template_lookup.get_template('hooks.mako')
+ f.write(tmpl.render(body=hooks_body(), template_name='hooks'))
return 0
diff --git a/package.json b/package.json
index a4bd6cb4..8a5f9f53 100644
--- a/package.json
+++ b/package.json
@@ -2,30 +2,7 @@
"repository": "github.com/pre-commit/pre-commit.com",
"license": "MIT",
"dependencies": {
- "bootstrap": "^5.0.0",
+ "bootstrap": "5.0.2",
"sass": "^1.32.13"
- },
- "eslintConfig": {
- "extends": "eslint:recommended",
- "rules": {
- "indent": [
- "error",
- 4
- ],
- "quotes": [
- "error",
- "single"
- ],
- "semi": [
- "error",
- "always"
- ]
- },
- "parserOptions": {
- "ecmaVersion": 6
- },
- "env": {
- "browser": true
- }
}
}
diff --git a/sections/advanced.md b/sections/advanced.md
index 818dc8ac..646f2ac1 100644
--- a/sections/advanced.md
+++ b/sections/advanced.md
@@ -18,221 +18,205 @@ entire commit.
$ SKIP=flake8 git commit -m "foo"
```
-## pre-commit during commits
+## Confining hooks to run at certain stages
+
+pre-commit supports many different types of `git` hooks (not just
+`pre-commit`!).
+
+Providers of hooks can select which git hooks they run on by setting the
+[`stages`](#hooks-stages) property in `.pre-commit-hooks.yaml` -- this can
+also be overridden by setting [`stages`](#config-stages) in
+`.pre-commit-config.yaml`. If `stages` is not set in either of those places
+the default value will be pulled from the top-level
+[`default_stages`](#top_level-default_stages) option (which defaults to _all_
+stages). By default, tools are enabled for [every hook type](#supported-git-hooks)
+that pre-commit supports.
+
+_new in 3.2.0_: The values of `stages` match the hook names. Previously,
+`commit`, `push`, and `merge-commit` matched `pre-commit`, `pre-push`, and
+`pre-merge-commit` respectively.
-Running hooks on unstaged changes can lead to both false-positives and
-false-negatives during committing. pre-commit only runs on the staged
-contents of files by temporarily saving the contents of your files at commit
-time and stashing the unstaged changes while running hooks.
+The `manual` stage (via `stages: [manual]`) is a special stage which will not
+be automatically triggered by any `git` hook -- this is useful if you want to
+add a tool which is not automatically run, but is run on demand using
+`pre-commit run --hook-stage manual [hookid]`.
-_new in 2.4.0_: pre-commit can be used to manage [post-commit] hooks.
+If you are authoring a tool, it is usually a good idea to provide an appropriate
+`stages` property. For example a reasonable setting for a linter or code
+formatter would be `stages: [pre-commit, pre-merge-commit, pre-push, manual]`.
-To use `post-commit` hooks with pre-commit, run:
+To install `pre-commit` for particular git hooks, pass `--hook-type` to
+`pre-commit install`. This can be specified multiple times such as:
```console
-$ pre-commit install --hook-type post-commit
-pre-commit installed at .git/hooks/post-commit
+$ pre-commit install --hook-type pre-commit --hook-type pre-push
+pre-commit installed at .git/hooks/pre-commit
+pre-commit installed at .git/hooks/pre-push
```
-`post-commit` hooks fire after the commit succeeds and cannot be used to
-prevent the commit from happening (use `pre-commit` instead). Since
-`post-commit` does not operate on files, any hooks must set `always_run`:
+Additionally, one can specify a default set of git hook types to be installed
+for by setting the top-level [`default_install_hook_types`](#top_level-default_install_hook_types).
+
+For example:
```yaml
-- repo: local
- hooks:
- - id: post-commit-local
- name: post commit
- always_run: true
- stages: [post-commit]
- # ...
+default_install_hook_types: [pre-commit, pre-push, commit-msg]
```
-[post-commit]: https://git-scm.com/docs/githooks#_post_commit
+```console
+$ pre-commit install
+pre-commit installed at .git/hooks/pre-commit
+pre-commit installed at .git/hooks/pre-push
+pre-commit installed at .git/hooks/commit-msg
+```
-## pre-commit during merges
+[anchor](__#pre-commit-during-commits)
+[anchor](__#pre-commit-during-merges)
+[anchor](__#pre-commit-during-clean-merges)
+[anchor](__#pre-commit-during-push)
+[anchor](__#pre-commit-for-commit-messages)
+[anchor](__#pre-commit-for-switching-branches)
+[anchor](__#pre-commit-for-rewriting)
-The biggest gripe we’ve had in the past with pre-commit hooks was during merge
-conflict resolution. When working on very large projects a merge often
-results in hundreds of committed files. I shouldn’t need to run hooks on all
-of these files that I didn’t even touch! This often led to running commit
-with `--no-verify` and allowed introduction of real bugs that hooks could have
-caught.
+## Supported git hooks
-pre-commit solves this by only running hooks on files that conflict or were
-manually edited during conflict resolution. This also includes files which
-were automatically merged by git. Git isn't perfect and this can often catch
-implicit conflicts (such as with removed python imports).
+- [commit-msg](#commit-msg)
+- [post-checkout](#post-checkout)
+- [post-commit](#post-commit)
+- [post-merge](#post-merge)
+- [post-rewrite](#post-rewrite)
+- [pre-commit](#pre-commit)
+- [pre-merge-commit](#pre-merge-commit)
+- [pre-push](#pre-push)
+- [pre-rebase](#pre-rebase)
+- [prepare-commit-msg](#prepare-commit-msg)
-_new in 2.11.0_ pre-commit can be used to manage [post-merge] hooks.
+### commit-msg
-To use `post-merge` hooks with pre-commit, run:
+[git commit-msg docs](https://git-scm.com/docs/githooks#_commit_msg)
-```console
-$ pre-commit install --hook-type post-merge
-pre-commit installed at .git/hooks/post-merge
-```
+`commit-msg` hooks will be passed a single filename -- this file contains the
+current contents of the commit message to be validated. The commit will be
+aborted if there is a nonzero exit code.
-The hook fires after a successful `git merge`.
+### post-checkout
-[post-merge]: https://git-scm.com/docs/githooks#_post_merge
+[git post-checkout docs](https://git-scm.com/docs/githooks#_post_checkout)
-## pre-commit during clean merges
+post-checkout hooks run *after* a `checkout` has occurred and can be used to
+set up or manage state in the repository.
-_new in 1.21.0_ pre-commit can be used to manage [pre-merge-commit] hooks.
+`post-checkout` hooks do not operate on files so they must be set as
+`always_run: true` or they will always be skipped.
-To use `pre-merge-commit` hooks with pre-commit, run:
+environment variables:
+- `PRE_COMMIT_FROM_REF`: the first argument to the `post-checkout` git hook
+- `PRE_COMMIT_TO_REF`: the second argument to the `post-checkout` git hook
+- `PRE_COMMIT_CHECKOUT_TYPE`: the third argument to the `post-checkout` git hook
-```console
-$ pre-commit install --hook-type pre-merge-commit
-pre-commit installed at .git/hooks/pre-merge-commit
-```
+### post-commit
-The hook fires after a merge succeeds but before the merge commit is created.
+[git post-commit docs](https://git-scm.com/docs/githooks#_post_commit)
-Note that you need to be using at least git 2.24 which added support for the
-pre-merge-commit hook.
+`post-commit` runs after the commit has already succeeded so it cannot be used
+to prevent the commit from happening.
-[pre-merge-commit]: https://git-scm.com/docs/githooks#_pre_merge_commit
+`post-commit` hooks do not operate on files so they must be set as
+`always_run: true` or they will always be skipped.
-## pre-commit during push
+### post-merge
-To use `pre-push` hooks with pre-commit, run:
+[git post-merge docs](https://git-scm.com/docs/githooks#_post_merge)
-```console
-$ pre-commit install --hook-type pre-push
-pre-commit installed at .git/hooks/pre-push
-```
+`post-merge` runs after a successful `git merge`.
-During a push, pre-commit will export the following environment variables:
-- `PRE_COMMIT_FROM_REF`: the remote revision that is being pushed to.
- - _new in 2.2.0_ prior to 2.2.0 the variable was `PRE_COMMIT_SOURCE`.
-- `PRE_COMMIT_TO_REF`: the local revision that is being pushed to the remote.
- - _new in 2.2.0_ prior to 2.2.0 the variable was `PRE_COMMIT_ORIGIN`.
-- `PRE_COMMIT_REMOTE_NAME`: _new in 2.0.0_ which remote is being pushed to
- (for example `origin`)
-- `PRE_COMMIT_REMOTE_URL`: _new in 2.0.0_ the url of the remote that is being
- pushed to (for example `git@github.com:pre-commit/pre-commit`.
+`post-merge` hooks do not operate on files so they must be set as
+`always_run: true` or they will always be skipped.
-[pre-push]: https://git-scm.com/docs/githooks#_pre_push
+environment variables:
+- `PRE_COMMIT_IS_SQUASH_MERGE`: the first argument to the `post-merge` git hook.
-## pre-commit for commit messages
+### post-rewrite
-pre-commit can be used to manage [commit-msg] hooks.
+[git post-rewrite docs](https://git-scm.com/docs/githooks#_post_rewrite)
-To use `commit-msg` hooks with pre-commit, run:
+`post-rewrite` runs after a git command which modifies history such as
+`git commit --amend` or `git rebase`.
-```console
-$ pre-commit install --hook-type commit-msg
-pre-commit installed at .git/hooks/commit-msg
-```
+`post-rewrite` hooks do not operate on files so they must be set as
+`always_run: true` or they will always be skipped.
-`commit-msg` hooks can be configured by setting `stages: [commit-msg]`.
-`commit-msg` hooks will be passed a single filename -- this file contains the
-current contents of the commit message which can be validated. If a hook
-exits nonzero, the commit will be aborted.
+environment variables:
+- `PRE_COMMIT_REWRITE_COMMAND`: the first argument to the `post-rewrite` git hook.
-_new in 1.16.0_: pre-commit can be used to manage [prepare-commit-msg] hooks.
+### pre-commit
-To use `prepare-commit-msg` hooks with pre-commit, run:
+[git pre-commit docs](https://git-scm.com/docs/githooks#_pre_commit)
-```console
-$ pre-commit install --hook-type prepare-commit-msg
-pre-commit installed at .git/hooks/prepare-commit-msg
-```
+`pre-commit` is triggered before the commit is finalized to allow checks on the
+code being committed. Running hooks on unstaged changes can lead to both
+false-positives and false-negatives during committing. pre-commit only runs
+on the staged contents of files by temporarily stashing the unstaged changes
+while running hooks.
-`prepare-commit-msg` hooks can be used to create dynamic templates for commit
-messages. `prepare-commit-msg` hooks can be configured by setting
-`stages: [prepare-commit-msg]`. `prepare-commit-msg` hooks will be passed a
-single filename -- this file contains any initial commit message (e.g. from
-`git commit -m "..."` or a template) and can be modified by the hook before
-the editor is shown. A hook may want to check for `GIT_EDITOR=:` as this
-indicates that no editor will be launched. If a hook exits nonzero,
-the commit will be aborted.
+### pre-merge-commit
-[commit-msg]: https://git-scm.com/docs/githooks#_commit_msg
-[prepare-commit-msg]: https://git-scm.com/docs/githooks#_prepare_commit_msg
+[git pre-merge-commit docs](https://git-scm.com/docs/githooks#_pre_merge_commit)
+`pre-merge-commit` fires after a merge succeeds but before the merge commit is
+created. This hook runs on all staged files from the merge.
-## pre-commit for switching branches
-_new in 2.2.0_: pre-commit can be used to manage [post-checkout] hooks.
+Note that you need to be using at least git 2.24 for this hook.
-To use `post-checkout` hooks with pre-commit, run:
+### pre-push
-```console
-$ pre-commit install --hook-type post-checkout
-pre-commit installed at .git/hooks/post-checkout
-```
+[git pre-push docs](https://git-scm.com/docs/githooks#_pre_push)
-`post-checkout` hooks can be used to perform repository validity checks,
-auto-display differences from the previous HEAD if different,
-or set working dir metadata properties. Since `post-checkout` doesn't operate
-on files, any hooks must set `always_run`:
+`pre-push` is triggered on `git push`.
-```yaml
-- repo: local
- hooks:
- - id: post-checkout-local
- name: Post checkout
- always_run: true
- stages: [post-checkout]
- # ...
-```
-
-`post-checkout` hooks have three environment variables they can check to
-do their work: `$PRE_COMMIT_FROM_REF`, `$PRE_COMMIT_TO_REF`,
-and `$PRE_COMMIT_CHECKOUT_TYPE`. These correspond to the first, second,
-and third arguments (respectively) that are normally passed to a regular
-post-checkout hook from Git.
+environment variables:
+- `PRE_COMMIT_FROM_REF`: the revision that is being pushed to.
+- `PRE_COMMIT_TO_REF`: the local revision that is being pushed to the remote.
+- `PRE_COMMIT_REMOTE_NAME`: which remote is being pushed to (for example `origin`)
+- `PRE_COMMIT_REMOTE_URL`: the url of the remote that is being pushed to (for
+ example `git@github.com:pre-commit/pre-commit`)
+- `PRE_COMMIT_REMOTE_BRANCH`: the name of the remote branch to which we are
+ pushing (for example `refs/heads/target-branch`)
+- `PRE_COMMIT_LOCAL_BRANCH`: the name of the local branch that is being pushed
+ to the remote (for example `HEAD`)
-[post-checkout]: https://git-scm.com/docs/githooks#_post_checkout
+### pre-rebase
-## pre-commit for rewriting
+_new in 3.2.0_
-_new in 2.15.0_: pre-commit can be used to manage [post-rewrite] hooks.
+[git pre-rebase docs](https://git-scm.com/docs/githooks#_pre_rebase)
-To use `post-rewrite` hooks with pre-commit, run:
+`pre-rebase` is triggered before a rebase occurs. A hook failure can cancel a
+rebase from occurring.
-```console
-$ pre-commit install --hook-type post-rewrite
-pre-commit installed at .git/hooks/post-rewrite
-```
+`pre-rebase` hooks do not operate on files so they must be set as
+`always_run: true` or they will always be skipped.
-`post-rewrite` is triggered after git commands which modify history such as
-`git commit --amend` and `git rebase`.
+environment variables:
+- `PRE_COMMIT_PRE_REBASE_UPSTREAM`: the first argument to the `pre-rebase` git hook
+- `PRE_COMMIT_PRE_REBASE_BRANCH`: the second argument to the `pre-rebase` git hook.
-since `post-rewrite` does not operate on any files, you must set
-[`always_run: true`](#hooks-always_run).
+### prepare-commit-msg
-`git` tells the `post-rewrite` hook which command triggered the rewrite.
-`pre-commit` exposes this as `$PRE_COMMIT_REWRITE_COMMAND`.
+[git prepare-commit-msg docs](https://git-scm.com/docs/githooks#_prepare_commit_msg)
-[post-rewrite]: https://git-scm.com/docs/githooks#_post_rewrite
+`prepare-commit-msg` hooks will be passed a single filename -- this file may
+be empty or it could contain the commit message from `-m` or from other
+templates. `prepare-commit-msg` hooks can modify the contents of this file to
+change what will be committed. A hook may want to check for `GIT_EDITOR=:` as
+this indicates that no editor will be launched. If a hook exits nonzero, the
+commit will be aborted.
-## Confining hooks to run at certain stages
-
-Since the [`default_stages`](#top_level-default_stages) top level configuration property of the
-`.pre-commit-config.yaml` file is set to all stages by default, when installing
-hooks using the `-t`/`--hook-type` option (see [pre-commit
-install [options]](#pre-commit-install)), all hooks will be installed by default
-to run at the stage defined through that option. For instance,
-`pre-commit install --hook-type pre-push` will install by default all hooks
-to run at the `push` stage.
-
-Hooks can however be confined to a stage by setting the [`stages`](#config-stages)
-property in your `.pre-commit-config.yaml`. The [`stages`](#config-stages) property
-is an array and can contain any of `commit`, `merge-commit`, `push`, `prepare-commit-msg`,
-`commit-msg`, `post-checkout`, `post-commit`, `post-merge`, `post-rewrite`, and `manual`.
-
-If you do not want to have hooks installed by default on the stage passed
-during a `pre-commit install --hook-type ...`, please set the [`default_stages`](#top_level-default_stages)
-top level configuration property to the desired stages, also as an array.
-
-_new in 1.8.0_: An additional `manual` stage is available for one off execution
-that won't run in any hook context. This special stage is useful for taking
-advantage of `pre-commit`'s cross-platform / cross-language package management
-without running it on every commit. Hooks confined to `stages: [manual]` can
-be executed by running `pre-commit run --hook-stage manual [hookid]`.
+environment variables:
+- `PRE_COMMIT_COMMIT_MSG_SOURCE`: the second argument to the
+ `prepare-commit-msg` git hook
+- `PRE_COMMIT_COMMIT_OBJECT_NAME`: the third argument to the
+ `prepare-commit-msg` git hook
## Passing arguments to hooks
@@ -288,9 +272,9 @@ For example:
hooks:
- id: check-requirements
name: check requirements files
- language: system
+ language: unsupported
entry: python -m scripts.check_requirements --compare
- files: ^requirements.*.txt$
+ files: ^requirements.*\.txt$
```
## Repository local hooks
@@ -307,7 +291,7 @@ You can configure repository-local hooks by specifying the [`repo`](#repos-repo)
sentinel `local`.
local hooks can use any language which supports [`additional_dependencies`](#config-additional_dependencies)
-or `docker_image` / `fail` / `pygrep` / `script` / `system`.
+or [`docker_image`](#docker_image) / [`fail`](#fail) / [`pygrep`](#pygrep) / [`unsupported`](#unsupported) / [`unsupported_script`](#unsupported_script).
This enables you to install things which previously would require a trivial
mirror repository.
@@ -323,13 +307,13 @@ Here's an example configuration with a few `local` hooks:
- id: pylint
name: pylint
entry: pylint
- language: system
+ language: unsupported
types: [python]
require_serial: true
- id: check-x
name: Check X
entry: ./bin/check-x.sh
- language: script
+ language: unsupported_script
files: \.x$
- id: scss-lint
name: scss-lint
@@ -342,8 +326,6 @@ Here's an example configuration with a few `local` hooks:
## meta hooks
-_new in 1.4.0_
-
`pre-commit` provides several hooks which are useful for checking the
pre-commit configuration itself. These can be enabled using `repo: meta`.
@@ -360,22 +342,182 @@ The currently available `meta` hooks:
=c= [`check-hooks-apply`](_#meta-check_hooks_apply)
=c= ensures that the configured hooks apply to at least one file in the
repository.
- _new in 1.4.0_.
=r=
=c= [`check-useless-excludes`](_#meta-check_useless_excludes)
=c= ensures that `exclude` directives apply to _any_ file in the
repository.
- _new in 1.4.0_.
=r=
=c= [`identity`](_#meta-identity)
=c= a simple hook which prints all arguments passed to it, useful for
debugging.
- _new in 1.14.0_.
```
+## `pre-commit hazmat`
+
+"hazardous materials"
+
+pre-commit provides a few `entry` prefix "helpers" for unusual situations.
+
+in case it's not clear, using these is _usually_ a bad idea.
+
+_note_: hazmat helpers do not work on languages which adjust `entry` (`docker`
+/ `docker_image` / `fail` / `julia` / `pygrep` / `r` / `unsupported_script`).
+
+### `pre-commit hazmat cd`
+
+_new in 4.5.0_
+
+for "monorepo" usage one can use this to target a subdirectory.
+
+this entry prefix will cd to the target subdir and adjust filename arguments
+
+example usage:
+
+```yaml
+# recommended:
+# minimum_pre_commit_version: 4.5.0
+repos:
+- repo: ...
+ rev: ...
+ hooks:
+ - id: example
+ alias: example-repo1
+ name: example (repo1)
+ files: ^repo1/
+ # important! ends with `--`
+ # important! copy `args: [...]` to entry and blank out `args: []`
+ entry: pre-commit hazmat cd repo1 example-bin --arg1 --
+ args: []
+
+ - id: example
+ alias: example-repo2
+ name: example (repo2)
+ files: ^repo2/
+ entry: pre-commit hazmat cd repo2 example-bin --arg1 --
+ args: []
+
+ # ... etc.
+```
+
+### `pre-commit hazmat ignore-exit-code`
+
+_new in 4.5.0_
+
+it's a bad idea to introduce warning noise but this gives you a way to do it.
+
+example:
+
+```yaml
+# recommended:
+# minimum_pre_commit_version: 4.5.0
+repos:
+- repo: ...
+ rev: ...
+ hooks:
+ - id: example
+ # important! copy `args: [...]` to entry and blank out `args: []`
+ entry: pre-commit hazmat ignore-exit-code example-bin --arg1 --
+ args: []
+ # otherwise the output will always be hidden
+ verbose: true
+```
+
+### `pre-commit hazmat n1`
+
+_new in 4.5.0_
+
+some hooks only take one filename argument. this runs them one at a time
+(which is super slow!)
+
+example:
+
+```yaml
+# recommended:
+# minimum_pre_commit_version: 4.5.0
+repos:
+- repo: ...
+ rev: ...
+ hooks:
+ - id: example
+ # important! ends with `--`
+ # important! copy `args: [...]` to entry and blank out `args: []`
+ entry: pre-commit hazmat n1 example-bin --arg1 --
+ args: []
+```
+
+## usage with git 2.54+ hook configuration
+
+_new in 4.6.0_: pre-commit improved support for `git config`-based hooks.
+a later version will change `pre-commit install` to use this approach.
+
+[git 2.54] introduced a new way to install git hook tools via `git config`.
+
+the basic gist is the following enables a hook in a git repo:
+
+```bash
+git config set hook..event pre-push
+git config set hook..command 'some command here'
+```
+
+an example setup with `pre-commit` might look like:
+
+```bash
+# note, the "hook" name here is `pre-commit.pre-commit`
+# for the `pre-commit` "tool" and the `pre-commit` "event"
+git config set hook.pre-commit.pre-commit.event pre-commit
+git config set hook.pre-commit.pre-commit.command 'pre-commit hook-impl --hook-type pre-commit --'
+
+# please follow that naming scheme for future compatibility with `pre-commit install`
+
+# an example with pre-push:
+#
+# git config set hook.pre-commit.pre-push.event pre-push
+# git config set hook.pre-commit.pre-push.command 'pre-commit hook-impl --hook-type pre-push --'
+```
+
+`pre-commit hook-impl` is a "hidden" implementation command with these options:
+- `--hook-type ...`: the [hook type](#supported-git-hooks) to use
+- `--config ...`: (optional) path to `.pre-commit-config.yaml`
+- `--skip-on-missing-config`: silently pass when a config is missing
+
+some interesting applications of this:
+
+### "global" installation of pre-commit
+
+with `git config set --global ...` this can automatically enable pre-commit
+for all repositories:
+
+```bash
+git config set --global hook.pre-commit.pre-commit.event pre-commit
+git config set --global hook.pre-commit.pre-commit.command 'pre-commit hook-impl --hook-type pre-commit --skip-on-missing-config --'
+```
+
+- this setup **not recommended** as it can lead to accidentally running hooks
+ when interacting with an untrusted repository.
+- `--skip-on-missing-config` is recommended here as arbitrary git repositories
+ may not have a `.pre-commit-config.yaml`.
+
+### always running a hook on all files
+
+since you can configure pre-commit as many times as you want you *could* invoke
+pre-commit to run a particular hook always and on all files
+
+```bash
+git config set hook.pre-commit.pre-commit-always.event pre-commit
+git config set hook.pre-commit.pre-commit-always.command 'pre-commit run hookid --hook-stage pre-commit --all-files'
+```
+
+*note*: this is not recommended as it has the tendancy to be slow and deviates
+from the normal expectations of pre-commit.
+
+[git 2.54]: https://github.blog/open-source/git/highlights-from-git-2-54/#h-config-based-hooks
+
## automatically enabling pre-commit on repositories
-_new in 1.18.0_
+*note*: if you are on a new-enough version of `git` you may want to use
+[this approach](#global-installation-of-pre-commit) instead.
+
+___
`pre-commit init-templatedir` can be used to set up a skeleton for `git`'s
`init.templateDir` option. This means that any newly cloned repository will
@@ -478,7 +620,7 @@ If a file extension you use is not supported, please
`types`, `types_or`, and `files` are evaluated together with `AND` when
filtering. Tags within `types` are also evaluated using `AND`.
-_new in 2.9.0_: Tags within `types_or` are evaluated using `OR`.
+Tags within `types_or` are evaluated using `OR`.
For example:
@@ -563,15 +705,17 @@ This tells pre-commit to use ruby `2.1.5` to run the `scss-lint` hook.
Valid values for specific languages are listed below:
- python: Whatever system installed python interpreters you have. The value of
this argument is passed as the `-p` to `virtualenv`.
- - _new in 1.4.3_: on windows the
+ - on windows the
[pep394](https://www.python.org/dev/peps/pep-0394/) name will be
translated into a py launcher call for portability. So continue to use
names like `python3` (`py -3`) or `python3.6` (`py -3.6`) even on
windows.
- node: See [nodeenv](https://github.com/ekalinin/nodeenv#advanced).
- ruby: See [ruby-build](https://github.com/sstephenson/ruby-build/tree/master/share/ruby-build).
+- rust: `language_version` is passed to `rustup`
+- _new in 3.0.0_ golang: use the versions on [go.dev/dl](https://go.dev/dl/) such as `1.19.5`
-_new in 1.14.0_: you can now set [`default_language_version`](#top_level-default_language_version)
+you can set [`default_language_version`](#top_level-default_language_version)
at the [top level](#pre-commit-configyaml---top-level) in your configuration to
control the default versions across all hooks of a language.
@@ -588,24 +732,24 @@ default_language_version:
you can add a badge to your repository to show your contributors / users that
you use pre-commit!
-[](https://github.com/pre-commit/pre-commit)
+[](https://github.com/pre-commit/pre-commit)
- Markdown:
```md#copyable
- [](https://github.com/pre-commit/pre-commit)
+ [](https://github.com/pre-commit/pre-commit)
```
- HTML:
```html#copyable
-
+
```
- reStructuredText:
```rst#copyable
- .. image:: https://img.shields.io/badge/pre--commit-enabled-brightgreen?logo=pre-commit&logoColor=white
+ .. image:: https://img.shields.io/badge/pre--commit-enabled-brightgreen?logo=pre-commit
:target: https://github.com/pre-commit/pre-commit
:alt: pre-commit
```
@@ -613,7 +757,7 @@ you use pre-commit!
- AsciiDoc:
```#copyable
- image:https://img.shields.io/badge/pre--commit-enabled-brightgreen?logo=pre-commit&logoColor=white[pre-commit, link=https://github.com/pre-commit/pre-commit]
+ image:https://img.shields.io/badge/pre--commit-enabled-brightgreen?logo=pre-commit[pre-commit, link=https://github.com/pre-commit/pre-commit]
```
## Usage in continuous integration
@@ -723,7 +867,7 @@ immutable caches:
```yaml
- name: set PY
run: echo "PY=$(python -VV | sha256sum | cut -d' ' -f1)" >> $GITHUB_ENV
- - uses: actions/cache@v1
+ - uses: actions/cache@v3
with:
path: ~/.cache/pre-commit
key: pre-commit|${{ env.PY }}|${{ hashFiles('.pre-commit-config.yaml') }}
diff --git a/sections/cli.md b/sections/cli.md
index 94aba71f..56b74d76 100644
--- a/sections/cli.md
+++ b/sections/cli.md
@@ -1,12 +1,12 @@
All pre-commit commands take the following options:
- `--color {auto,always,never}`: whether to use color in output.
- Defaults to `auto`. _new in 1.18.0_: can be overridden by using
+ Defaults to `auto`. can be overridden by using
`PRE_COMMIT_COLOR={auto,always,never}` or disabled using `TERM=dumb`.
- `-c CONFIG`, `--config CONFIG`: path to alternate config file
- `-h`, `--help`: show help and available options.
-_new in 2.8.0_: `pre-commit` now exits with more specific codes:
+`pre-commit` exits with specific codes:
- `1`: a detected / expected error
- `3`: an unexpected error
- `130`: the process was interrupted by `^C`
@@ -19,10 +19,10 @@ Options:
- `--bleeding-edge`: update to the bleeding edge of the default branch instead
of the latest tagged version (the default behaviour).
-- `--freeze`: _new in 1.21.0_: Store "frozen" hashes in [`rev`](#repos-rev)
- instead of tag names.
-- `--repo REPO`: _new in 1.4.1_: Only update this repository. _new in 1.7.0_:
- This option may be specified multiple times.
+- `--freeze`: Store "frozen" hashes in [`rev`](#repos-rev) instead of tag names.
+- `--repo REPO`: Only update this repository. This option may be specified
+ multiple times.
+- `-j` / `--jobs`: _new in 3.3.0_ Number of threads to use (default: 1).
Here are some sample invocations using this `.pre-commit-config.yaml`:
@@ -68,8 +68,7 @@ $ grep rev: .pre-commit-config.yaml
rev: 34a269fd7650d264e4de7603157c10d0a9bb8211 # frozen: v1.25.2
```
-_new in 2.18.0_: pre-commit will preferentially pick tags containing a `.` if
-there are ties.
+pre-commit will preferentially pick tags containing a `.` if there are ties.
## pre-commit clean [options] #pre-commit-clean
@@ -79,8 +78,6 @@ Options: (no additional options)
## pre-commit gc [options] #pre-commit-gc
-_new in 1.14.0_
-
Clean unused cached repos.
`pre-commit` keeps a cache of installed hook repositories which grows over
@@ -91,15 +88,12 @@ Options: (no additional options)
## pre-commit init-templatedir DIRECTORY [options] #pre-commit-init-templatedir
-_new in 1.18.0_
-
Install hook script in a directory intended for use with
`git config init.templateDir`.
Options:
-- `-t {pre-commit,pre-merge-commit,pre-push,prepare-commit-msg,commit-msg,post-checkout,post-commit,post-merge,post-rewrite}`,
- `--hook-type {pre-commit,pre-merge-commit,pre-push,prepare-commit-msg,commit-msg,post-checkout,post-commit,post-merge,post-rewrite}`:
+- `-t HOOK_TYPE, --hook-type HOOK_TYPE`:
which hook type to install.
Some example useful invocations:
@@ -135,8 +129,7 @@ Options:
- `--install-hooks`: Also install environments for all available hooks now
(rather than when they are first executed). See [`pre-commit
install-hooks`](#pre-commit-install-hooks).
-- `-t {pre-commit,pre-merge-commit,pre-push,prepare-commit-msg,commit-msg,post-checkout,post-commit,post-merge,post-rewrite}`,
- `--hook-type {pre-commit,pre-merge-commit,pre-push,prepare-commit-msg,commit-msg,post-checkout,post-commit,post-merge,post-rewrite}`:
+- `-t HOOK_TYPE, --hook-type HOOK_TYPE`:
Specify which hook type to install.
- `--allow-missing-config`: Hook scripts will permit a missing configuration
file.
@@ -149,8 +142,8 @@ Some example useful invocations:
existing git hook scripts with pre-commit, and also installs hook
environments.
-_new in 2.18.0_: `pre-commit install` will now install hooks from
-[`default_install_hook_types`](#top_level-default_language_version) if
+`pre-commit install` will install hooks from
+[`default_install_hook_types`](#top_level-default_install_hook_types) if
`--hook-type` is not specified on the command line.
## pre-commit install-hooks [options] #pre-commit-install-hooks
@@ -169,8 +162,6 @@ Options: (no additional options)
## pre-commit migrate-config [options] #pre-commit-migrate-config
-_new in 1.0.0_
-
Migrate list configuration to the new map configuration format.
Options: (no additional options)
@@ -186,8 +177,6 @@ Options:
- `--files [FILES [FILES ...]]`: specific filenames to run hooks on.
- `--from-ref FROM_REF` + `--to-ref TO_REF`: run against the files changed
between `FROM_REF...TO_REF` in git.
- - _new in 2.2.0_: prior to 2.2.0 the arguments were `--source` and
- `--origin`.
- `--hook-stage STAGE`: select a [`stage` to run](#confining-hooks-to-run-at-certain-stages).
- `--show-diff-on-failure`: when hooks fail, run `git diff` directly afterward.
- `-v`, `--verbose`: produce hook output independent of success. Include hook
@@ -213,8 +202,6 @@ Options: (no additional options)
## pre-commit try-repo REPO [options] #pre-commit-try-repo
-_new in 1.3.0_
-
Try the hooks in a repository, useful for developing new hooks.
`try-repo` can also be used for testing out a repository before adding it to
your configuration. `try-repo` prints a configuration it generates based on
@@ -245,6 +232,12 @@ Uninstall the pre-commit script.
Options:
-- `-t {pre-commit,pre-merge-commit,pre-push,prepare-commit-msg,commit-msg,post-checkout,post-commit,post-merge,post-rewrite}`,
- `--hook-type {pre-commit,pre-merge-commit,pre-push,prepare-commit-msg,commit-msg,post-checkout,post-commit,post-merge,post-rewrite}`:
- which hook type to uninstall.
+- `-t HOOK_TYPE, --hook-type HOOK_TYPE`: which hook type to uninstall.
+
+## pre-commit validate-config [options] [filenames ...] #pre-commit-validate-config
+
+Validate .pre-commit-config.yaml files
+
+## pre-commit validate-manifest [options] [filenames ...] #pre-commit-validate-manifest
+
+Validate .pre-commit-hooks.yaml files
diff --git a/sections/hooks.md b/sections/hooks.md
new file mode 100644
index 00000000..a045f6f6
--- /dev/null
+++ b/sections/hooks.md
@@ -0,0 +1,167 @@
+## featured hooks
+
+here are a few hand-picked repositories which provide pre-commit integrations.
+
+these are fairly popular and are generally known to work well in most setups!
+
+_this list is not intended to be exhaustive_
+
+provided by the pre-commit team:
+- [pre-commit/pre-commit-hooks]: a handful of language-agnostic hooks which
+ are universally useful!
+- [pre-commit/pygrep-hooks]: a few quick regex-based hooks for a handful of
+ quick syntax checks
+- [pre-commit/sync-pre-commit-deps]: sync pre-commit hook dependencies based
+ on other installed hooks
+- [pre-commit/mirrors-*]: pre-commit mirrors of a handful of popular tools
+
+[pre-commit/pre-commit-hooks]: https://github.com/pre-commit/pre-commit-hooks
+[pre-commit/pygrep-hooks]: https://github.com/pre-commit/pygrep-hooks
+[pre-commit/sync-pre-commit-deps]: https://github.com/pre-commit/sync-pre-commit-deps
+[pre-commit/mirrors-*]: https://github.com/orgs/pre-commit/repositories?language=&q=%22mirrors-%22+archived%3AFalse&sort=
+
+for python projects:
+- [asottile/pyupgrade]: automatically upgrade syntax for newer versions of the
+ language
+- [asottile/(others)]: a few other repos by the pre-commit creator
+- [psf/black]: The uncompromising Python code formatter
+- [hhatto/autopep8]: automatically fixes PEP8 violations
+- [astral-sh/ruff-pre-commit]: the ruff linter and formatter for python
+- [google/yapf]: a highly configurable python formatter
+- [PyCQA/flake8]: a linter framework for python
+- [PyCQA/isort]: an import sorter for python
+- [PyCQA/(others)]: a few other python code quality tools
+- [adamchainz/django-upgrade]: automatically upgrade your Django project code
+
+[asottile/pyupgrade]: https://github.com/asottile/pyupgrade
+[asottile/(others)]: https://sourcegraph.com/search?q=context:global+file:%5E%5C.pre-commit-hooks%5C.yaml%24+repo:%5Egithub.com/asottile/
+[psf/black]: https://github.com/psf/black
+[hhatto/autopep8]: https://github.com/hhatto/autopep8
+[astral-sh/ruff-pre-commit]: https://github.com/astral-sh/ruff-pre-commit
+[google/yapf]: https://github.com/google/yapf
+[PyCQA/flake8]: https://github.com/PyCQA/flake8
+[PyCQA/isort]: https://github.com/PyCQA/isort
+[PyCQA/(others)]: https://sourcegraph.com/search?q=context:global+file:%5E%5C.pre-commit-hooks%5C.yaml%24+repo:%5Egithub.com/PyCQA/
+[adamchainz/django-upgrade]: https://github.com/adamchainz/django-upgrade
+
+for shell scripts:
+- [shellcheck-py/shellcheck-py]: runs shellcheck on your scripts
+- [openstack/bashate]: code style enforcement for bash programs
+
+[shellcheck-py/shellcheck-py]: https://github.com/shellcheck-py/shellcheck-py
+[openstack/bashate]: https://github.com/openstack/bashate
+
+for the web:
+- [biomejs/pre-commit]: a fast formatter / fixer written in rust
+- [standard/standard]: linter / fixer
+- [oxipng/oxipng]: optimize png files
+
+[biomejs/pre-commit]: https://github.com/biomejs/pre-commit
+[standard/standard]: https://github.com/standard/standard
+[oxipng/oxipng]: https://github.com/oxipng/oxipng
+
+for configuration files:
+- [python-jsonschema/check-jsonschema]: check many common configurations with jsonschema
+- [rhysd/actionlint]: lint your GitHub Actions workflow files
+- [google/yamlfmt]: a formatter for yaml files
+- [adrienverge/yamllint]: a linter for YAML files
+
+[python-jsonschema/check-jsonschema]: https://github.com/python-jsonschema/check-jsonschema
+[rhysd/actionlint]: https://github.com/rhysd/actionlint
+[google/yamlfmt]: https://github.com/google/yamlfmt
+[adrienverge/yamllint]: https://github.com/adrienverge/yamllint
+
+for text / docs / prose:
+- [crate-ci/typos]: find and fix common typographical errors
+- [thlorenz/doctoc]: generate a table-of-contents in markdown files
+- [amperser/proselint]: A linter for prose.
+- [markdownlint/markdownlint]: a Markdown lint tool in Ruby
+- [DavidAnson/markdownlint-cli2]: a Markdown lint tool in Node
+- [codespell-project/codespell]: check code for common misspellings
+
+[crate-ci/typos]: https://github.com/crate-ci/typos
+[thlorenz/doctoc]: https://github.com/thlorenz/doctoc
+[amperser/proselint]: https://github.com/amperser/proselint
+[markdownlint/markdownlint]: https://github.com/markdownlint/markdownlint
+[DavidAnson/markdownlint-cli2]: https://github.com/DavidAnson/markdownlint-cli2
+[codespell-project/codespell]: https://github.com/codespell-project/codespell
+
+for linting commit messages:
+- [jorisroovers/gitlint]
+- [commitizen-tools/commitizen]
+
+[jorisroovers/gitlint]: https://github.com/jorisroovers/gitlint
+[commitizen-tools/commitizen]: https://github.com/commitizen-tools/commitizen
+
+for secret scanning / security:
+- [gitleaks/gitleaks]
+- [trufflesecurity/truffleHog]
+- [thoughtworks/talisman]
+
+[gitleaks/gitleaks]: https://github.com/gitleaks/gitleaks
+[trufflesecurity/truffleHog]: https://github.com/trufflesecurity/truffleHog
+[thoughtworks/talisman]: https://github.com/thoughtworks/talisman
+
+for other programming languages:
+- [realm/SwiftLint]: enforce Swift style and conventions
+- [nicklockwood/SwiftFormat]: a formatter for Swift
+- [AleksaC/terraform-py]: format and validate terraform syntax
+- [rubocop/rubocop]: static analysis and formatting for Ruby
+- [bufbuild/buf]: tooling for Protocol Buffers
+- [sqlfluff/sqlfluff]: a modular linter and auto formatter for SQL
+- [aws-cloudformation/cfn-lint]: aws CloudFormation linter
+- [google/go-jsonnet]: linter / formatter for jsonnet
+- [JohnnyMorganz/StyLua]: an opinionated Lua code formatter
+- [Koihik/LuaFormatter]: a formatter for Lua code
+- [mrtazz/checkmake]: linter for Makefile syntax
+- [nbqa-dev/nbqa]: run common linters on Jupyter Notebooks
+
+[realm/SwiftLint]: https://github.com/realm/SwiftLint
+[nicklockwood/SwiftFormat]: https://github.com/nicklockwood/SwiftFormat
+[AleksaC/terraform-py]: https://github.com/AleksaC/terraform-py
+[rubocop/rubocop]: https://github.com/rubocop/rubocop
+[bufbuild/buf]: https://github.com/bufbuild/buf
+[sqlfluff/sqlfluff]: https://github.com/sqlfluff/sqlfluff
+[aws-cloudformation/cfn-lint]: https://github.com/aws-cloudformation/cfn-lint
+[google/go-jsonnet]: https://github.com/google/go-jsonnet
+[JohnnyMorganz/StyLua]: https://github.com/JohnnyMorganz/StyLua
+[Koihik/LuaFormatter]: https://github.com/Koihik/LuaFormatter
+[mrtazz/checkmake]: https://github.com/mrtazz/checkmake
+[nbqa-dev/nbqa]: https://github.com/nbQA-dev/nbQA
+
+## finding hooks
+
+it's recommended to use your favorite searching tool to find existing hooks to
+use in your project.
+
+for example, here's some searches you may find useful using [sourcegraph]:
+
+- hooks which run on python files: [`file:^\.pre-commit-hooks\.yaml$ "types: [python]"`](https://sourcegraph.com/search?q=context:global+file:^\.pre-commit-hooks\.yaml%24+%22types:+[python]%22)
+- hooks which run on shell files: [`file:^\.pre-commit-hooks\.yaml$ "types: [shell]"`](https://sourcegraph.com/search?q=context:global+file:^\.pre-commit-hooks\.yaml%24+"types:+[shell]")
+- pre-commit configurations in popular projects: [`file:^\.pre-commit-config\.yaml$`](https://sourcegraph.com/search?q=context:global+file:^\.pre-commit-hooks\.yaml)
+
+[sourcegraph]: https://sourcegraph.com/search
+
+you may also find [github's search] useful as well, though its querying and
+sorting capabilities are quite limited plus it requires a login:
+
+- repositories providing hooks: [`path:.pre-commit-hooks.yaml language:YAML`](https://github.com/search?q=path%3A.pre-commit-hooks.yaml+language%3AYAML&type=code&l=YAML)
+
+[github's search]: https://github.com/search
+
+
+## adding to this page
+
+the previous iteration of this page was a laundry list of hooks and maintaining
+quality of the listed tools was cumbersome.
+
+**this page is not intended to be exhaustive**
+
+you may send [a pull request] to expand this list however there are a few
+requirements you *must* follow or your PR will be closed without comment:
+
+- the tool must already be fairly popular (>500 stars)
+- the tool must use a managed language (no `unsupported` / `unsupported_script` / `docker` hooks)
+- the tool must operate on files
+
+[a pull request]: https://github.com/pre-commit/pre-commit.com/blob/main/sections/hooks.md
diff --git a/sections/install.md b/sections/install.md
index 06aec41f..3d6d4d85 100644
--- a/sections/install.md
+++ b/sections/install.md
@@ -22,18 +22,6 @@ As a 0-dependency [zipapp]:
[zipapp]: https://docs.python.org/3/library/zipapp.html
[github releases]: https://github.com/pre-commit/pre-commit/releases
-Using [homebrew](https://brew.sh):
-
-```bash
-brew install pre-commit
-```
-
-Using [conda](https://conda.io) (via [conda-forge](https://conda-forge.org)):
-
-```bash
-conda install -c conda-forge pre-commit
-```
-
## Quick start
### 1. Install pre-commit
@@ -64,7 +52,7 @@ repos:
- id: end-of-file-fixer
- id: trailing-whitespace
- repo: https://github.com/psf/black
- rev: 21.12b0
+ rev: 22.10.0
hooks:
- id: black
```
diff --git a/sections/new-hooks.md b/sections/new-hooks.md
index 3e67d936..7f21d439 100644
--- a/sections/new-hooks.md
+++ b/sections/new-hooks.md
@@ -4,9 +4,12 @@ installable package (gem, npm, pypi, etc.) or exposes an executable, it can be
used with pre-commit. Each git repo can support as many languages/hooks as you
want.
+_new in 2.5.0_: `pre-commit` sets the `PRE_COMMIT=1` environment variable
+during hook execution.
+
The hook must exit nonzero on failure or modify files.
-A git repo containing pre-commit plugins must contain a .pre-commit-hooks.yaml
+A git repo containing pre-commit plugins must contain a `.pre-commit-hooks.yaml`
file that tells pre-commit:
```table
@@ -37,7 +40,6 @@ file that tells pre-commit:
=c= [`types_or`](_#hooks-types_or)
=c= (optional: default `[]`) list of file types to run on (OR). See
[Filtering files with types](#filtering-files-with-types).
- _new in 2.9.0_.
=r=
=c= [`exclude_types`](_#hooks-exclude_types)
=c= (optional: default `[]`) the pattern of files to exclude.
@@ -48,11 +50,11 @@ file that tells pre-commit:
=r=
=c= [`fail_fast`](_#hooks-fail_fast)
=c= (optional: default `false`) if `true` pre-commit will stop running
- hooks if this hook fails. _new in 2.16.0_.
+ hooks if this hook fails.
=r=
=c= [`verbose`](_#hooks-verbose)
=c= (optional: default `false`) if `true`, forces the output of the hook to be printed even when
- the hook passes. _new in 1.6.0_.
+ the hook passes.
=r=
=c= [`pass_filenames`](_#hooks-pass_filenames)
=c= (optional: default `true`) if `false` no filenames will be passed to
@@ -60,7 +62,7 @@ file that tells pre-commit:
=r=
=c= [`require_serial`](_#hooks-require_serial)
=c= (optional: default `false`) if `true` this hook will execute using a
- single process instead of in parallel. _new in 1.13.0_.
+ single process instead of in parallel.
=r=
=c= [`description`](_#hooks-description)
=c= (optional: default `''`) description of the hook. used for metadata
@@ -78,10 +80,8 @@ file that tells pre-commit:
=c= (optional: default `[]`) list of additional parameters to pass to the hook.
=r=
=c= [`stages`](_#hooks-stages)
- =c= (optional: default (all stages)) confines the hook to the `commit`, `merge-commit`,
- `push`, `prepare-commit-msg`, `commit-msg`, `post-checkout`, `post-commit`,
- `post-merge`, `post-rewrite`, or `manual` stage. See
- [Confining hooks to run at certain stages](#confining-hooks-to-run-at-certain-stages).
+ =c= (optional: default (all stages)) selects which git hook(s) to run for.
+ See [Confining hooks to run at certain stages](#confining-hooks-to-run-at-certain-stages).
```
@@ -109,7 +109,7 @@ interactively:
_note_: you may need to provide `--commit-msg-filename` when using this
command with hook types `prepare-commit-msg` and `commit-msg`.
-_new in 1.14.0_: a commit is no longer necessary to `try-repo` on a local
+a commit is not necessary to `try-repo` on a local
directory. `pre-commit` will clone any tracked uncommitted changes.
```pre-commit
@@ -117,8 +117,6 @@ directory. `pre-commit` will clone any tracked uncommitted changes.
# ... make some changes
-# new in 1.14.0: a commit is no longer necessary for `try-repo`
-
# In another terminal or tab
~/work/other-repo $ pre-commit try-repo ../hook-repo foo --verbose --all-files
@@ -150,23 +148,22 @@ Hello from foo hook!
- [dotnet](#dotnet)
- [fail](#fail)
- [golang](#golang)
+- [haskell](#haskell)
+- [julia](#julia)
- [lua](#lua)
- [node](#node)
- [perl](#perl)
- [python](#python)
-- [python_venv](#python_venv)
- [r](#r)
- [ruby](#ruby)
- [rust](#rust)
- [swift](#swift)
- [pygrep](#pygrep)
-- [script](#script)
-- [system](#system)
+- [unsupported](#unsupported)
+- [unsupported_script](#unsupported_script)
### conda
-_new in 1.21.0_
-
The hook repository must contain an `environment.yml` file which will be used
via `conda env create --file environment.yml ...` to create the environment.
@@ -174,7 +171,7 @@ The `conda` language also supports [`additional_dependencies`](#config-additiona
and will pass any of the values directly into `conda install`. This language can therefore be
used with [local](#repository-local-hooks) hooks.
-_new in 2.17.0_: `mamba` or `micromamba` can be used to install instead via the
+`mamba` or `micromamba` can be used to install instead via the
`PRE_COMMIT_USE_MAMBA=1` or `PRE_COMMIT_USE_MICROMAMBA=1` environment
variables.
@@ -184,8 +181,6 @@ It has been tested on linux, macOS, and windows.
### coursier
-_new in 2.8.0_
-
The hook repository must have a `.pre-commit-channel` folder and that folder
must contain the coursier
[application descriptors](https://get-coursier.io/docs/2.0.0-RC6-10/cli-install.html#application-descriptor-reference)
@@ -198,12 +193,13 @@ __Support:__ `coursier` hooks are known to work on any system which has the
applications you install may depend on various versions of the JVM, consult
the hooks' documentation for clarification. It has been tested on linux.
-_new in 2.18.0_: pre-commit now supports the `coursier` naming of the package
-manager executable.
+pre-commit also supports the `coursier` naming of the package manager
+executable.
-### dart
+_new in 3.0.0_: `language: coursier` hooks now support `repo: local` and
+`additional_dependencies`.
-_new in 2.15.0_
+### dart
The hook repository must have a `pubspec.yaml` -- this must contain an
`executables` section which will list the binaries that will be available
@@ -276,8 +272,6 @@ For example:
### dotnet
-_new in 2.8.0_
-
dotnet hooks are installed using the system installation of the dotnet CLI.
Hook repositories must contain a dotnet CLI tool which can be `pack`ed and
@@ -290,8 +284,6 @@ CLI installed. It has been tested on linux and windows.
### fail
-_new in 1.11.0_
-
A lightweight [`language`](#hooks-language) to forbid files by filename. The `fail` language is
especially useful for [local](#repository-local-hooks) hooks.
@@ -318,14 +310,70 @@ The hook repository must contain go source code. It will be installed via
and the [`entry`](#hooks-entry) should match an executable which will get installed into the
`GOPATH`'s `bin` directory.
+This language supports `additional_dependencies` and will pass any of the values directly to `go
+install`. It can be used as a `repo: local` hook.
+
_changed in 2.17.0_: previously `go get ./...` was used
+_new in 3.0.0_: pre-commit will bootstrap `go` if it is not present. `language: golang`
+also now supports `language_version`
+
__Support:__ golang hooks are known to work on any system which has go
installed. It has been tested on linux, macOS, and windows.
-### lua
+### haskell
+
+_new in 3.4.0_
+
+The hook repository must have one or more `*.cabal` files. Once installed
+the `executable`s from these packages will be available to use with `entry`.
+
+This language supports `additional_dependencies` so it can be used as a
+`repo: local` hook.
-_new in 2.17.0_
+__Support:__ haskell hooks are known to work on any system which has `cabal`
+installed. It has been tested on linux, macOS, and windows.
+
+### julia
+
+_new in 4.1.0_
+
+For configuring julia hooks, your [`entry`](#hooks-entry) should be a path to a julia source
+file relative to the hook repository (optionally with arguments).
+
+Hooks run in an isolated package environment defined by a `Project.toml` file (optionally
+with a `Manifest.toml` file) in the hook repository. If no `Project.toml` file is found the
+hook is run in an empty environment.
+
+Julia hooks support [`additional_dependencies`](#config-additional_dependencies) which can
+be used to augment, or override, the existing environment in the hooks repository. This also
+means that julia can be used as a `repo: local` hook. `additional_dependencies` are passed
+to `pkg> add` and should be specified using
+[Pkg REPL mode syntax](https://pkgdocs.julialang.org/v1/repl/#repl-add).
+
+Examples:
+
+```yaml
+- id: foo-without-args
+ name: ...
+ language: julia
+ entry: bin/foo.jl
+- id: bar-with-args
+ name: ...
+ language: julia
+ entry: bin/bar.jl --arg1 --arg2
+- id: baz-with-extra-deps
+ name: ...
+ language: julia
+ entry: bin/baz.jl
+ additional_dependencies:
+ - 'ExtraDepA@1'
+ - 'ExtraDepB@2.4'
+```
+
+__Support:__ julia hooks are known to work on any system which has `julia` installed.
+
+### lua
Lua hooks are installed with the version of Lua that is used by Luarocks.
@@ -339,17 +387,12 @@ The hook repository must have a `package.json`. It will be installed via
match the [`entry`](#hooks-entry) – usually through `bin` in package.json.
__Support:__ node hooks work without any system-level dependencies. It has
-been tested on linux and macOS and _may_ work under cygwin.
-
-_new in 1.5.0_: windows is now supported for node hooks. Currently python3
-only due to [a bug in cpython](https://bugs.python.org/issue32539).
+been tested on linux, windows, and macOS and _may_ work under cygwin.
### perl
-_new in 2.1.0_
-
Perl hooks are installed using the system installation of
-[cpan](https://perldoc.perl.org/5.30.0/cpan.html), the CPAN package installer
+[cpan](https://perldoc.perl.org/cpan), the CPAN package installer
that comes with Perl.
Hook repositories must have something that `cpan` supports, typically
@@ -359,7 +402,7 @@ via `cpan -T .` (with the installed files stored in your pre-commit cache,
not polluting other Perl installations).
When specifying [`additional_dependencies`](#config-additional_dependencies) for Perl, you can use any of the
-[install argument formats understood by `cpan`](https://perldoc.perl.org/5.30.0/CPAN.html#get%2c-make%2c-test%2c-install%2c-clean-modules-or-distributions).
+[install argument formats understood by `cpan`](https://perldoc.perl.org/CPAN#get%2c-make%2c-test%2c-install%2c-clean-modules-or-distributions).
__Support:__ Perl hooks currently require a pre-existing Perl installation,
including the `cpan` tool in `PATH`. It has been tested on linux, macOS, and
@@ -372,29 +415,15 @@ The hook repository must be installable via `pip install .` (usually by either
executable that will match the [`entry`](#hooks-entry) – usually through `console_scripts` or
`scripts` in setup.py.
-__Support:__ python hooks work without any system-level dependencies. It
-has been tested on linux, macOS, windows, and cygwin.
-
-### python_venv
-
-_new in 1.9.0_
-
-_new in 2.4.0_: The `python_venv` language is now an alias to `python` since
-`virtualenv>=20` creates equivalently structured environments. Previously,
-this [`language`](#hooks-language) created environments using the [venv] module.
-
-This [`language`](#hooks-language) will be removed eventually so it is suggested to use `python`
-instead.
-
-[venv]: https://docs.python.org/3/library/venv.html
+This language also supports `additional_dependencies`
+so it can be used with [local](#repository-local-hooks) hooks.
+The specified dependencies will be appended to the `pip install` command.
__Support:__ python hooks work without any system-level dependencies. It
has been tested on linux, macOS, windows, and cygwin.
### r
-_new in 2.11.0_
-
This hook repository must have a `renv.lock` file that will be restored with
[`renv::restore()`](https://rstudio.github.io/renv/reference/restore.html) on
hook installation. If the repository is an R package (i.e. has `Type: Package`
@@ -423,10 +452,8 @@ been tested on linux and macOS and _may_ work under cygwin.
### rust
-_new in 1.10.0_
-
-Rust hooks are installed using the system installation of
-[Cargo](https://github.com/rust-lang/cargo), Rust's official package manager.
+Rust hooks are installed using [Cargo](https://github.com/rust-lang/cargo),
+Rust's official package manager.
Hook repositories must have a `Cargo.toml` file which produces at least one
binary ([example](https://github.com/chriskuehl/example-rust-pre-commit-hook)),
@@ -440,8 +467,10 @@ build _your_ hook repo), or the special syntax
`cli:{package_name}:{package_version}` for a CLI dependency (built separately,
with binaries made available for use by hooks).
-__Support:__ Rust hooks currently require a pre-existing Rust installation. It
-has been tested on linux, Windows, and macOS.
+pre-commit will bootstrap `rust` if it is not present.
+`language: rust` also supports `language_version`
+
+__Support:__ It has been tested on linux, Windows, and macOS.
### swift
@@ -454,38 +483,40 @@ installed. It has been tested on linux and macOS.
### pygrep
-_new in 1.2.0_
-
A cross-platform python implementation of `grep` – pygrep hooks are a quick
way to write a simple hook which prevents commits by file matching. Specify
the regex as the [`entry`](#hooks-entry). The [`entry`](#hooks-entry) may be any python
[regular expression](#regular-expressions). For case insensitive regexes you
can apply the `(?i)` flag as the start of your entry, or use `args: [-i]`.
-_new in 1.8.0_: For multiline matches, use `args: [--multiline]`.
+For multiline matches, use `args: [--multiline]`.
-_new in 2.8.0_: To require all files to match, use `args: [--negate]`.
+To require all files to match, use `args: [--negate]`.
__Support:__ pygrep hooks are supported on all platforms which pre-commit runs
on.
-### script
+### unsupported
-Script hooks provide a way to write simple scripts which validate files. The
-[`entry`](#hooks-entry) should be a path relative to the root of the hook repository.
+[anchor](__#system)
+_new in 4.4.0_: previously `language: system`. the alias will be removed in a
+future version
+
+System hooks provide a way to write hooks for system-level executables which
+don't have a supported language above (or have special environment
+requirements that don't allow them to run in isolation such as pylint).
This hook type will not be given a virtual environment to work with – if it
needs additional dependencies the consumer must install them manually.
-__Support:__ the support of script hooks depend on the scripts themselves.
+### unsupported_script
-### system
+[anchor](__#script)
+_new in 4.4.0_: previously `language: script`. the alias will be removed in a
+future version
-System hooks provide a way to write hooks for system-level executables which
-don't have a supported language above (or have special environment
-requirements that don't allow them to run in isolation such as pylint).
+Script hooks provide a way to write simple scripts which validate files. The
+[`entry`](#hooks-entry) should be a path relative to the root of the hook repository.
This hook type will not be given a virtual environment to work with – if it
needs additional dependencies the consumer must install them manually.
-
-__Support:__ the support of system hooks depend on the executables.
diff --git a/sections/plugins.md b/sections/plugins.md
index f59b6b1d..96cb213c 100644
--- a/sections/plugins.md
+++ b/sections/plugins.md
@@ -6,13 +6,6 @@ pre-commit config file describes what repositories and hooks are installed.
## .pre-commit-config.yaml - top level
-_new in 1.0.0_: The default configuration file top-level was changed from a
-list to a map. If you're using an old version of pre-commit, the top-level
-list is the same as the value of [`repos`](#pre-commit-configyaml---repos).
-If you'd like to migrate to the new configuration format, run
-[`pre-commit migrate-config`](#pre-commit-migrate-config) to automatically
-migrate your configuration.
-
```table
=r=
=c= [`repos`](_#top_level-repos)
@@ -22,8 +15,6 @@ migrate your configuration.
=c= (optional: default `[pre-commit]`) a list of `--hook-type`s which will
be used by default when running
[`pre-commit install`](#pre-commit-install).
-
- _new in 2.18.0_
=r=
=c= [`default_language_version`](_#top_level-default_language_version)
=c= (optional: default `{}`) a mapping from language to the default
@@ -36,8 +27,6 @@ migrate your configuration.
default_language_version:
python: python3.7
```
-
- _new in 1.14.0_
=r=
=c= [`default_stages`](_#top_level-default_stages)
=c= (optional: default (all stages)) a configuration-wide default for
@@ -47,24 +36,21 @@ migrate your configuration.
For example:
```yaml
- default_stages: [commit, push]
+ default_stages: [pre-commit, pre-push]
```
-
- _new in 1.14.0_
=r=
=c= [`files`](_#top_level-files)
- =c= (optional: default `''`) global file include pattern. _new in 1.21.0_.
+ =c= (optional: default `''`) global file include pattern.
=r=
=c= [`exclude`](_#top_level-exclude)
- =c= (optional: default `^$`) global file exclude pattern. _new in 1.1.0_.
+ =c= (optional: default `^$`) global file exclude pattern.
=r=
=c= [`fail_fast`](_#top_level-fail_fast)
=c= (optional: default `false`) set to `true` to have pre-commit stop
- running hooks after the first failure. _new in 1.1.0_.
+ running hooks after the first failure.
=r=
=c= [`minimum_pre_commit_version`](_#top_level-minimum_pre_commit_version)
=c= (optional: default `'0'`) require a minimum version of pre-commit.
- _new in 1.15.0_.
```
A sample top-level:
@@ -85,9 +71,12 @@ from.
=r=
=c= [`repo`](_#repos-repo)
=c= the repository url to `git clone` from
+ or one of the special sentinel values:
+ [`local`](#repository-local-hooks),
+ [`meta`](#meta-hooks).
=r=
=c= [`rev`](_#repos-rev)
- =c= the revision or tag to clone at. _new in 1.7.0_: previously `sha`
+ =c= the revision or tag to clone at.
=r=
=c= [`hooks`](_#repos-hooks)
=c= A list of [hook mappings](#pre-commit-configyaml---hooks).
@@ -117,7 +106,6 @@ repository's configuration.
=c= [`alias`](_#config-alias)
=c= (optional) allows the hook to be referenced using an additional id when
using `pre-commit run `.
- _new in 1.14.0_.
=r=
=c= [`name`](_#config-name)
=c= (optional) override the name of the hook - shown during hook execution.
@@ -139,7 +127,6 @@ repository's configuration.
=c= [`types_or`](_#config-types_or)
=c= (optional) override the default file types to run on (OR). See
[Filtering files with types](#filtering-files-with-types).
- _new in 2.9.0_.
=r=
=c= [`exclude_types`](_#config-exclude_types)
=c= (optional) file types to exclude.
@@ -148,10 +135,8 @@ repository's configuration.
=c= (optional) list of additional parameters to pass to the hook.
=r=
=c= [`stages`](_#config-stages)
- =c= (optional) confines the hook to the `commit`, `merge-commit`, `push`,
- `prepare-commit-msg`, `commit-msg`, `post-checkout`, `post-commit`,
- `post-merge`, `post-rewrite`, or `manual` stage. See
- [Confining hooks to run at certain stages](#confining-hooks-to-run-at-certain-stages).
+ =c= (optional) selects which git hook(s) to run for.
+ See [Confining hooks to run at certain stages](#confining-hooks-to-run-at-certain-stages).
=r=
=c= [`additional_dependencies`](_#config-additional_dependencies)
=c= (optional) a list of dependencies that will be installed in the
@@ -164,7 +149,7 @@ repository's configuration.
=r=
=c= [`verbose`](_#config-verbose)
=c= (optional) if `true`, forces the output of the hook to be printed even when
- the hook passes. _new in 1.6.0_.
+ the hook passes.
=r=
=c= [`log_file`](_#config-log_file)
=c= (optional) if present, the hook output will additionally be written to
diff --git a/template_lib.py b/template_lib.py
index 138546f4..72286d70 100644
--- a/template_lib.py
+++ b/template_lib.py
@@ -12,13 +12,12 @@
ID_RE = re.compile(r' #([a-z0-9-]+)$')
-SPECIAL_CHARS_RE = re.compile('[^a-z0-9 _-]')
+SPECIAL_CHARS_RE = re.compile('(&[a-z]+;|[^a-z0-9 _-])')
ROW = '=r='
COL = ' =c= '
INDENT = ' ' * 8
-SELF_LINK_PREFIX = '_#'
def _render_table(code: str) -> str:
@@ -66,13 +65,13 @@ def _maybe_end_row() -> None:
output.append('')
elif line.startswith(COL):
_maybe_end_col()
- col_buffer = line[len(COL):]
+ col_buffer = line.removeprefix(COL)
elif col_buffer is not None:
if line == '\n':
col_buffer += line
else:
assert line.startswith(INDENT), line
- col_buffer += line[len(INDENT):]
+ col_buffer += line.removeprefix(INDENT)
else:
raise AssertionError(line)
@@ -94,9 +93,11 @@ class Renderer(markdown_code_blocks.CodeRenderer):
def link(
self, link: str, text: str | None, title: str | None,
) -> str:
- if link.startswith(SELF_LINK_PREFIX):
- a_id = link[len(SELF_LINK_PREFIX):]
+ if link.startswith('_#'):
+ a_id = link.removeprefix('_#')
return f'{text}'
+ elif link.startswith('__#'):
+ return f''
else:
return super().link(link, text, title)
@@ -152,7 +153,7 @@ def block_code(self, code: str, info: str | None = None) -> str:
return ret
-def md(s: str) -> str:
+def md(s: str) -> markupsafe.Markup:
html = markdown_code_blocks.highlight(s, Renderer=Renderer)
# manually bless the highlighted output.
return markupsafe.Markup(html)