diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml
deleted file mode 100644
index 9408e44d..00000000
--- a/.github/FUNDING.yml
+++ /dev/null
@@ -1,2 +0,0 @@
-github: asottile
-open_collective: pre-commit
diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml
index 91ed3615..47422e09 100644
--- a/.github/workflows/deploy.yml
+++ b/.github/workflows/deploy.yml
@@ -1,18 +1,21 @@
-name: deploy
on:
pull_request:
push:
- branches: [master]
+ branches: [main]
schedule:
- cron: '30 8 * * *'
+permissions:
+ contents: write
+
jobs:
- build:
- name: pr
+ 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 2deee430..8658b840 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,8 +1,4 @@
*.html
*.pyc
-*.swp
-/.mypy_cache
-/all-hooks.json
/build
/node_modules
-/venv
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index fa39c888..1f2f8c10 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -1,59 +1,42 @@
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
- rev: v4.0.1
+ rev: v6.0.0
hooks:
- id: trailing-whitespace
- id: end-of-file-fixer
- id: check-yaml
- id: debug-statements
-- repo: https://github.com/PyCQA/flake8
- rev: 3.9.2
- hooks:
- - id: flake8
-- repo: https://github.com/pre-commit/mirrors-autopep8
- rev: v1.5.7
- hooks:
- - id: autopep8
-- repo: https://github.com/asottile/reorder_python_imports
- rev: v2.5.0
+ - id: double-quote-string-fixer
+ - id: name-tests-test
+ - id: requirements-txt-fixer
+- repo: https://github.com/asottile/reorder-python-imports
+ rev: v3.16.0
hooks:
- id: reorder-python-imports
- args: [--py36-plus]
- 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: v4.0.0
+ hooks:
+ - id: add-trailing-comma
- repo: https://github.com/asottile/pyupgrade
- rev: v2.19.4
+ rev: v3.21.2
hooks:
- id: pyupgrade
- args: [--py36-plus]
- exclude: ^install-local.py$
- - id: pyupgrade
- files: install-local.py
-- repo: https://github.com/asottile/add-trailing-comma
- rev: v2.1.0
+ args: [--py310-plus]
+- repo: https://github.com/hhatto/autopep8
+ rev: v2.3.2
hooks:
- - id: add-trailing-comma
+ - id: autopep8
+- repo: https://github.com/PyCQA/flake8
+ rev: 7.3.0
+ hooks:
+ - id: flake8
- repo: https://github.com/pre-commit/mirrors-mypy
- rev: v0.902
+ rev: v2.1.0
hooks:
- id: mypy
- additional_dependencies: [types-all]
-- repo: https://github.com/pre-commit/mirrors-eslint
- rev: v7.28.0
- hooks:
- - id: eslint
- args: [--fix]
-- repo: local
- hooks:
- - id: scss-lint
- name: scss-lint
- entry: scss-lint
- types: [scss]
- language: ruby
- additional_dependencies: ['scss_lint:0.57.0']
- - 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 13d63c35..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 node_modules *.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 4942a13b..c311257b 100644
--- a/README.md
+++ b/README.md
@@ -1,7 +1,7 @@
pre-commit.com
==============
-[](https://results.pre-commit.ci/latest/github/pre-commit/pre-commit.com/master)
-[](https://github.com/pre-commit/pre-commit.com/actions)
+[](https://results.pre-commit.ci/latest/github/pre-commit/pre-commit.com/main)
+[](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 be58a7f4..00000000
--- a/all-repos.yaml
+++ /dev/null
@@ -1,194 +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-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/guykisel/pre-commit-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/openstack-dev/bashate
-- 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/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://github.com/thg-consulting/inspectortiger
-- 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/JamesWoolfenden/pre-commit
-- 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/hakancelik96/unimport
-- 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/sirosen/check-jsonschema
-- https://github.com/sirosen/fix-smartquotes
-- 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/terraform-linters/tflint
-- 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
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 6ac25cb9..77ba61f4 100644
--- a/base.mako
+++ b/base.mako
@@ -54,27 +54,20 @@
A framework for managing and maintaining multi-language pre-commit hooks.
## https://buttons.github.io/
Star
-
- ## https://developer.twitter.com/en/docs/twitter-for-websites/tweet-button/overview
-
-
-
+
@@ -88,7 +81,7 @@
-
+
+${body}
diff --git a/install-local.py b/install-local.py
deleted file mode 100644
index 925cf4bf..00000000
--- a/install-local.py
+++ /dev/null
@@ -1,126 +0,0 @@
-#!/usr/bin/env python
-from __future__ import absolute_import
-from __future__ import print_function
-from __future__ import unicode_literals
-
-import contextlib
-import distutils.spawn
-import hashlib
-import io
-import os.path
-import shutil
-import subprocess
-import sys
-import tarfile
-
-
-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__':
- exit(main())
diff --git a/make_all_hooks.py b/make_all_hooks.py
deleted file mode 100644
index 63106c20..00000000
--- a/make_all_hooks.py
+++ /dev/null
@@ -1,55 +0,0 @@
-import functools
-import json
-import multiprocessing
-import os.path
-import subprocess
-import tempfile
-from typing import Any
-from typing import Dict
-from typing import List
-from typing import Tuple
-
-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__':
- exit(main())
diff --git a/make_templates.py b/make_templates.py
index 8b592b1d..aca62aed 100644
--- a/make_templates.py
+++ b/make_templates.py
@@ -1,8 +1,6 @@
-import collections
-import json
+from __future__ import annotations
+
import os.path
-from typing import Any
-from typing import Dict
import mako.lookup
import markupsafe
@@ -28,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))
@@ -49,32 +41,24 @@ 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
if __name__ == '__main__':
- exit(main())
+ raise SystemExit(main())
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/scss/_variables.scss b/scss/_variables.scss
index f231a640..c4339549 100644
--- a/scss/_variables.scss
+++ b/scss/_variables.scss
@@ -23,3 +23,5 @@ $code-color: #e83e8c !default;
$lead-font-size: 1.75rem !default;
$lead-font-weight: 400 !default;
+
+$enable-smooth-scroll: false;
diff --git a/sections/advanced.md b/sections/advanced.md
index d2d8d804..646f2ac1 100644
--- a/sections/advanced.md
+++ b/sections/advanced.md
@@ -18,199 +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]
- # ...
-```
+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` 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.
+### pre-rebase
-[post-checkout]: https://git-scm.com/docs/githooks#_post_checkout
+_new in 3.2.0_
-## Confining hooks to run at certain stages
+[git pre-rebase docs](https://git-scm.com/docs/githooks#_pre_rebase)
+
+`pre-rebase` is triggered before a rebase occurs. A hook failure can cancel a
+rebase from occurring.
+
+`pre-rebase` hooks do not operate on files so they must be set as
+`always_run: true` or they will always be skipped.
+
+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.
+
+### prepare-commit-msg
-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`, 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]`.
+[git prepare-commit-msg docs](https://git-scm.com/docs/githooks#_prepare_commit_msg)
+
+`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.
+
+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
@@ -219,8 +225,8 @@ arguments by specifying the [`args`](#config-args) property in your `.pre-commit
as follows:
```yaml
-- repo: https://gitlab.com/PyCQA/flake8
- rev: 3.8.3
+- repo: https://github.com/PyCQA/flake8
+ rev: 4.0.1
hooks:
- id: flake8
args: [--max-line-length=131]
@@ -266,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
@@ -285,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.
@@ -301,12 +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
@@ -319,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`.
@@ -337,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
@@ -390,7 +555,7 @@ Initialized empty Git repository in /tmp/sample/.git/
$ cd sample
$ git commit --allow-empty -m 'Initial commit'
`.pre-commit-config.yaml` config file not found. Skipping `pre-commit`.
-[master (root-commit) d1b39c1] Initial commit
+[main (root-commit) d1b39c1] Initial commit
```
To still require opt-in, but prompt the user to set up pre-commit use a
@@ -435,8 +600,8 @@ Some of the common tags you'll find from identify:
- `executable` - whether the file has the executable bit set
- `text` - whether the file looks like a text file
- `binary` - whether the file looks like a binary file
-- [tags by extension / naming convention](https://github.com/pre-commit/identify/blob/master/identify/extensions.py)
-- [tags by shebang (`#!`)](https://github.com/pre-commit/identify/blob/master/identify/interpreters.py)
+- [tags by extension / naming convention](https://github.com/pre-commit/identify/blob/main/identify/extensions.py)
+- [tags by shebang (`#!`)](https://github.com/pre-commit/identify/blob/main/identify/interpreters.py)
To discover the type of any file on disk, you can use `identify`'s cli:
@@ -455,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:
@@ -493,9 +658,6 @@ with `#!/usr/bin/env python3` will also be matched.
As with `files` and `exclude`, you can also exclude types if necessary using
`exclude_types`.
-If you'd like to use `types` with compatibility for older versions
-[here is a guide to ensuring compatibility](https://github.com/pre-commit/pre-commit/pull/551#issuecomment-312535540).
-
## Regular expressions
The patterns for `files` and `exclude` are python
@@ -543,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.
@@ -568,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
```
@@ -593,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
@@ -625,7 +789,7 @@ pre-commit.ci also has the following benefits:
- it will autofix pull requests
- it will periodically autoupdate your configuration
-[](https://github.com/pre-commit-ci-demo/demo#results)
+[](https://github.com/pre-commit-ci-demo/demo#results)
[pre-commit.ci]: https://pre-commit.ci
@@ -642,7 +806,7 @@ note: azure pipelines uses immutable caches so the python version and
`.pre-commit-config.yaml` hash must be included in the cache key. for a
repository template, see [asottile@job--pre-commit.yml].
-[asottile@job--pre-commit.yml]: https://github.com/asottile/azure-pipeline-templates/blob/master/job--pre-commit.yml
+[asottile@job--pre-commit.yml]: https://github.com/asottile/azure-pipeline-templates/blob/main/job--pre-commit.yml
```yaml
jobs:
@@ -703,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') }}
@@ -722,6 +886,9 @@ my_job:
- ${PRE_COMMIT_HOME}
```
+pre-commit's cache requires to be served from a constant location between the different builds. This isn't the default when using k8s runners
+on GitLab. In case you face the error `InvalidManifestError`, set `builds_dir` to something static e.g `builds_dir = "/builds"` in your `[[runner]]` config
+
### travis-ci example
```yaml
diff --git a/sections/cli.md b/sections/cli.md
index a22752b1..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,6 +68,8 @@ $ grep rev: .pre-commit-config.yaml
rev: 34a269fd7650d264e4de7603157c10d0a9bb8211 # frozen: v1.25.2
```
+pre-commit will preferentially pick tags containing a `.` if there are ties.
+
## pre-commit clean [options] #pre-commit-clean
Clean out cached pre-commit files.
@@ -76,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
@@ -88,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}`,
- `--hook-type {pre-commit,pre-merge-commit,pre-push,prepare-commit-msg,commit-msg,post-checkout,post-commit,post-merge}`:
+- `-t HOOK_TYPE, --hook-type HOOK_TYPE`:
which hook type to install.
Some example useful invocations:
@@ -132,20 +129,23 @@ 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}`,
- `--hook-type {pre-commit,pre-merge-commit,pre-push,prepare-commit-msg,commit-msg,post-checkout,post-commit,post-merge}`:
+- `-t HOOK_TYPE, --hook-type HOOK_TYPE`:
Specify which hook type to install.
- `--allow-missing-config`: Hook scripts will permit a missing configuration
file.
Some example useful invocations:
-- `pre-commit install`: Default invocation. Installs the pre-commit script
+- `pre-commit install`: Default invocation. Installs the hook scripts
alongside any existing git hooks.
- `pre-commit install --install-hooks --overwrite`: Idempotently replaces
existing git hook scripts with pre-commit, and also installs hook
environments.
+`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
Install all missing environments for the available hooks. Unless this command or
@@ -162,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)
@@ -179,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
@@ -206,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
@@ -238,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}`,
- `--hook-type {pre-commit,pre-merge-commit,pre-push,prepare-commit-msg,commit-msg,post-checkout,post-commit,post-merge}`:
- 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 c114c049..3d6d4d85 100644
--- a/sections/install.md
+++ b/sections/install.md
@@ -7,16 +7,6 @@ Using pip:
pip install pre-commit
```
-Non-administrative installation:
-
-- _to upgrade: run again, to uninstall: pass `uninstall` to python_
-- _does not work on platforms without symlink support (windows)_
-
-
-```bash
-curl https://pre-commit.com/install-local.py | python -
-```
-
In a python project, add the following to your requirements.txt (or
requirements-dev.txt):
@@ -32,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
@@ -74,7 +52,7 @@ repos:
- id: end-of-file-fixer
- id: trailing-whitespace
- repo: https://github.com/psf/black
- rev: 19.3b0
+ rev: 22.10.0
hooks:
- id: black
```
diff --git a/sections/new-hooks.md b/sections/new-hooks.md
index 181efcd1..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.
@@ -45,10 +47,14 @@ file that tells pre-commit:
=c= [`always_run`](_#hooks-always_run)
=c= (optional: default `false`) if `true` this hook will run even if there
are no matching files.
+=r=
+ =c= [`fail_fast`](_#hooks-fail_fast)
+ =c= (optional: default `false`) if `true` pre-commit will stop running
+ hooks if this hook fails.
=r=
=c= [`verbose`](_#hooks-verbose)
- =c= (optional) if `true`, forces the output of the hook to be printed even when
- the hook passes. _new in 1.6.0_.
+ =c= (optional: default `false`) if `true`, forces the output of the hook to be printed even when
+ the hook passes.
=r=
=c= [`pass_filenames`](_#hooks-pass_filenames)
=c= (optional: default `true`) if `false` no filenames will be passed to
@@ -56,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
@@ -74,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`, 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).
```
@@ -105,16 +109,14 @@ 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
-~/work/hook-repo $ git checkout origin/master -b feature
+~/work/hook-repo $ git checkout origin/main -b feature
# ... 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
@@ -140,27 +142,28 @@ Hello from foo hook!
- [conda](#conda)
- [coursier](#coursier)
+- [dart](#dart)
- [docker](#docker)
- [docker_image](#docker_image)
- [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.
@@ -168,25 +171,51 @@ 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.
+`mamba` or `micromamba` can be used to install instead via the
+`PRE_COMMIT_USE_MAMBA=1` or `PRE_COMMIT_USE_MICROMAMBA=1` environment
+variables.
+
__Support:__ `conda` hooks work as long as there is a system-installed `conda`
binary (such as [`miniconda`](https://docs.conda.io/en/latest/miniconda.html)).
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
+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)
for the hook to install. For configuring coursier hooks, your
[`entry`](#hooks-entry) should correspond to an executable installed from the
repository's `.pre-commit-channel` folder.
-__Support:__ `coursier` hooks are known to work on any system which has the `cs`
-package manager installed. The specific coursier applications you install may depend
-on various versions of the JVM, consult the hooks' documentation for clarification.
-It has been tested on linux.
+__Support:__ `coursier` hooks are known to work on any system which has the
+`cs` or `coursier` package manager installed. The specific coursier
+applications you install may depend on various versions of the JVM, consult
+the hooks' documentation for clarification. It has been tested on linux.
+
+pre-commit also supports the `coursier` naming of the package manager
+executable.
+
+_new in 3.0.0_: `language: coursier` hooks now support `repo: local` and
+`additional_dependencies`.
+
+### dart
+
+The hook repository must have a `pubspec.yaml` -- this must contain an
+`executables` section which will list the binaries that will be available
+after installation. Match the [`entry`](#hooks-entry) to an executable.
+
+`pre-commit` will build each executable using `dart compile exe bin/{executable}.dart`.
+
+`language: dart` also supports [`additional_dependencies`](#config-additional_dependencies).
+to specify a version for a dependency, separate the package name by a `:`:
+
+```yaml
+ additional_dependencies: ['hello_world_dart:1.0.0']
+```
+
+__Support:__ `dart` hooks are known to work on any system which has the `dart`
+sdk installed. It has been tested on linux, macOS, and windows.
### docker
@@ -243,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
@@ -257,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.
@@ -281,13 +306,80 @@ being added to the `changelog` directory:
### golang
The hook repository must contain go source code. It will be installed via
-`go get ./...`. pre-commit will create an isolated `GOPATH` for each hook and
-the [`entry`](#hooks-entry) should match an executable which will get installed into the
+`go install ./...`. pre-commit will create an isolated `GOPATH` for each hook
+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.
+### 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.
+
+__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.
+
+__Support:__ Lua hooks are known to work on any system which has Luarocks
+installed. It has been tested on linux and macOS and _may_ work on windows.
+
### node
The hook repository must have a `package.json`. It will be installed via
@@ -295,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
@@ -315,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
@@ -328,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`
@@ -379,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)),
@@ -396,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
@@ -410,37 +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]`.
-_new in 2.8.0_: To require all files to match, use `args: [--negate]`.
+For multiline matches, use `args: [--multiline]`.
+
+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 0245648d..96cb213c 100644
--- a/sections/plugins.md
+++ b/sections/plugins.md
@@ -6,17 +6,15 @@ 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)
=c= A list of [repository mappings](#pre-commit-configyaml---repos).
+=r=
+ =c= [`default_install_hook_types`](_#top_level-default_install_hook_types)
+ =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).
=r=
=c= [`default_language_version`](_#top_level-default_language_version)
=c= (optional: default `{}`) a mapping from language to the default
@@ -29,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
@@ -40,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:
@@ -78,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).
@@ -110,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.
@@ -132,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.
@@ -141,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`, 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
@@ -157,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/sections/usage.md b/sections/usage.md
index dbba2aab..94addae8 100644
--- a/sections/usage.md
+++ b/sections/usage.md
@@ -27,6 +27,6 @@ pyupgrade................................................................Passed
rst ``code`` is two backticks........................(no files to check)Skipped
rst..................................................(no files to check)Skipped
changelog filenames..................................(no files to check)Skipped
-[master 146c6c2c] Add super awesome feature
+[main 146c6c2c] Add super awesome feature
1 file changed, 1 insertion(+)
```
diff --git a/template_lib.py b/template_lib.py
index e9e5ef80..72286d70 100644
--- a/template_lib.py
+++ b/template_lib.py
@@ -1,22 +1,23 @@
+from __future__ import annotations
+
+import html
import os
import re
import shlex
import subprocess
import sys
-from typing import Optional
import markdown_code_blocks
import markupsafe
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:
@@ -64,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)
@@ -90,11 +91,13 @@ def _render_cmd(code: str) -> str:
class Renderer(markdown_code_blocks.CodeRenderer):
def link(
- self, link: str, text: Optional[str], title: Optional[str],
+ 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)
@@ -118,7 +121,21 @@ def codespan(self, text: str) -> str:
else:
return super().codespan(text)
- def block_code(self, code: str, info: Optional[str] = None) -> str:
+ def image(
+ self,
+ src: str,
+ alt: str = '',
+ title: str | None = None,
+ ) -> str:
+ return (
+ f'
'
+ )
+
+ def block_code(self, code: str, info: str | None = None) -> str:
copyable = False
if info is not None:
copyable_s = '#copyable'
@@ -136,7 +153,7 @@ def block_code(self, code: str, info: Optional[str] = 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)