232 lines
9.1 KiB
YAML
232 lines
9.1 KiB
YAML
# See https://pre-commit.com for more information
|
|
# See https://pre-commit.com/hooks.html for more hooks
|
|
|
|
minimum_pre_commit_version: '2.8.2'
|
|
|
|
default_language_version:
|
|
python: python3
|
|
|
|
default_stages: [commit]
|
|
|
|
|
|
repos:
|
|
# General file checks and fixers
|
|
- repo: https://github.com/pre-commit/pre-commit-hooks
|
|
rev: v4.4.0
|
|
hooks:
|
|
- id: mixed-line-ending
|
|
name: "Normalize mixed line endings"
|
|
args: [--fix=lf]
|
|
- id: file-contents-sorter
|
|
name: "Sort codespell ignore list"
|
|
files: '.codespell/ignore-words.txt'
|
|
|
|
- id: check-case-conflict
|
|
name: "Check for case conflicts"
|
|
- id: check-merge-conflict
|
|
name: "Check for merge conflict markers"
|
|
- id: check-executables-have-shebangs
|
|
name: "Check that executables have shebangs"
|
|
- id: check-shebang-scripts-are-executable
|
|
name: "Check that shebangs are executable"
|
|
|
|
- id: check-vcs-permalinks
|
|
name: "Check that VCS links are permalinks"
|
|
|
|
# - id: check-ast
|
|
# name: "Check Python AST"
|
|
- id: check-json
|
|
name: "Check JSON"
|
|
- id: check-toml
|
|
name: "Check TOML"
|
|
- id: check-yaml
|
|
name: "Check YAML"
|
|
|
|
- repo: https://github.com/psf/black
|
|
rev: 23.7.0
|
|
hooks:
|
|
- id: black
|
|
name: "Format with Black"
|
|
args:
|
|
- '--target-version=py39'
|
|
- '--target-version=py310'
|
|
files: 'pep_sphinx_extensions/tests/.*'
|
|
|
|
- repo: https://github.com/astral-sh/ruff-pre-commit
|
|
rev: v0.0.287
|
|
hooks:
|
|
- id: ruff
|
|
name: "Lint with Ruff"
|
|
args:
|
|
- '--exit-non-zero-on-fix'
|
|
files: '^pep_sphinx_extensions/tests/'
|
|
|
|
- repo: https://github.com/tox-dev/tox-ini-fmt
|
|
rev: 1.3.1
|
|
hooks:
|
|
- id: tox-ini-fmt
|
|
name: "Format tox.ini"
|
|
|
|
- repo: https://github.com/sphinx-contrib/sphinx-lint
|
|
rev: v0.6.8
|
|
hooks:
|
|
- id: sphinx-lint
|
|
name: "Sphinx lint"
|
|
args: ["--disable=trailing-whitespace"]
|
|
|
|
# RST checks
|
|
- repo: https://github.com/pre-commit/pygrep-hooks
|
|
rev: v1.10.0
|
|
hooks:
|
|
- id: rst-backticks
|
|
name: "Check RST: No single backticks"
|
|
|
|
- id: rst-inline-touching-normal
|
|
name: "Check RST: No backticks touching text"
|
|
|
|
- id: rst-directive-colons
|
|
name: "Check RST: 2 colons after directives"
|
|
|
|
# Manual codespell check
|
|
- repo: https://github.com/codespell-project/codespell
|
|
rev: v2.2.5
|
|
hooks:
|
|
- id: codespell
|
|
name: "Check for common misspellings in text files"
|
|
stages: [manual]
|
|
|
|
# Local checks for PEP headers and more
|
|
- repo: local
|
|
hooks:
|
|
# # Hook to run "check-peps.py"
|
|
# - id: "check-peps"
|
|
# name: "Check PEPs for metadata and content enforcement"
|
|
# entry: "python check-peps.py"
|
|
# language: "system"
|
|
# files: "^pep-\d{4}\.(rst|txt)$"
|
|
# require_serial: true
|
|
|
|
- id: check-required-headers
|
|
name: "PEPs must have all required headers"
|
|
language: pygrep
|
|
entry: '(?-m:^PEP:(?=[\s\S]*\nTitle:)(?=[\s\S]*\nAuthor:)(?=[\s\S]*\nStatus:)(?=[\s\S]*\nType:)(?=[\s\S]*\nCreated:))'
|
|
args: ['--negate', '--multiline']
|
|
files: '^peps/pep-\d+\.rst$'
|
|
|
|
- id: check-header-order
|
|
name: "PEP header order must follow PEP 12"
|
|
language: pygrep
|
|
entry: '^PEP:[^\n]+\nTitle:[^\n]+\n(Version:[^\n]+\n)?(Last-Modified:[^\n]+\n)?Author:[^\n]+\n( +\S[^\n]+\n)*(Sponsor:[^\n]+\n)?((PEP|BDFL)-Delegate:[^\n]*\n)?(Discussions-To:[^\n]*\n)?Status:[^\n]+\nType:[^\n]+\n(Topic:[^\n]+\n)?(Content-Type:[^\n]+\n)?(Requires:[^\n]+\n)?Created:[^\n]+\n(Python-Version:[^\n]*\n)?(Post-History:[^\n]*\n( +\S[^\n]*\n)*)?(Replaces:[^\n]+\n)?(Superseded-By:[^\n]+\n)?(Resolution:[^\n]*\n)?\n'
|
|
args: ['--negate', '--multiline']
|
|
files: '^peps/pep-\d+\.rst$'
|
|
|
|
- id: validate-pep-number
|
|
name: "'PEP' header must be a number 1-9999"
|
|
language: pygrep
|
|
entry: '(?-m:^PEP:(?:(?! +(0|[1-9][0-9]{0,3})\n)))'
|
|
args: ['--multiline']
|
|
files: '^peps/pep-\d+\.rst$'
|
|
|
|
- id: validate-title
|
|
name: "'Title' must be 1-79 characters"
|
|
language: pygrep
|
|
entry: '(?<=\n)Title:(?:(?! +\S.{1,78}\n(?=[A-Z])))'
|
|
args: ['--multiline']
|
|
files: '^peps/pep-\d+\.rst$'
|
|
exclude: '^peps/pep-(0499)\.rst$'
|
|
|
|
- id: validate-author
|
|
name: "'Author' must be list of 'Name <email@example.com>, ...'"
|
|
language: pygrep
|
|
entry: '(?<=\n)Author:(?:(?!((( +|\n {1,8})[^!#$%&()*+,/:;<=>?@\[\\\]\^_`{|}~]+( <[\w!#$%&''*+\-/=?^_{|}~.]+(@| at )[\w\-.]+\.[A-Za-z0-9]+>)?)(,|(?=\n[^ ])))+\n(?=[A-Z])))'
|
|
args: ["--multiline"]
|
|
files: '^peps/pep-\d+\.rst$'
|
|
|
|
- id: validate-sponsor
|
|
name: "'Sponsor' must have format 'Name <email@example.com>'"
|
|
language: pygrep
|
|
entry: '^Sponsor:(?: (?! *[^!#$%&()*+,/:;<=>?@\[\\\]\^_`{|}~]+( <[\w!#$%&''*+\-/=?^_{|}~.]+(@| at )[\w\-.]+\.[A-Za-z0-9]+>)?$))'
|
|
files: '^peps/pep-\d+\.rst$'
|
|
|
|
- id: validate-delegate
|
|
name: "'Delegate' must have format 'Name <email@example.com>'"
|
|
language: pygrep
|
|
entry: '^(PEP|BDFL)-Delegate: (?:(?! *[^!#$%&()*+,/:;<=>?@\[\\\]\^_`{|}~]+( <[\w!#$%&''*+\-/=?^_{|}~.]+(@| at )[\w\-.]+\.[A-Za-z0-9]+>)?$))'
|
|
files: '^peps/pep-\d+\.rst$'
|
|
exclude: '^peps/pep-(0451)\.rst$'
|
|
|
|
- id: validate-discussions-to
|
|
name: "'Discussions-To' must be a thread URL"
|
|
language: pygrep
|
|
entry: '^Discussions-To: (?:(?!([\w\-]+@(python\.org|googlegroups\.com))|https://((discuss\.python\.org/t/([\w\-]+/)?\d+/?)|(mail\.python\.org/pipermail/[\w\-]+/\d{4}-[A-Za-z]+/[A-Za-z0-9]+\.html)|(mail\.python\.org/archives/list/[\w\-]+@python\.org/thread/[A-Za-z0-9]+/?))$))'
|
|
files: '^peps/pep-\d+\.rst$'
|
|
|
|
- id: validate-status
|
|
name: "'Status' must be a valid PEP status"
|
|
language: pygrep
|
|
entry: '^Status:(?:(?! +(Draft|Withdrawn|Rejected|Accepted|Final|Active|Provisional|Deferred|Superseded|April Fool!)$))'
|
|
files: '^peps/pep-\d+\.rst$'
|
|
|
|
- id: validate-type
|
|
name: "'Type' must be a valid PEP type"
|
|
language: pygrep
|
|
entry: '^Type:(?:(?! +(Standards Track|Informational|Process)$))'
|
|
files: '^peps/pep-\d+\.rst$'
|
|
|
|
- id: validate-topic
|
|
name: "'Topic' must be for a valid sub-index"
|
|
language: pygrep
|
|
entry: '^Topic:(?:(?! +(Governance|Packaging|Typing|Release)(, (Governance|Packaging|Typing|Release))*$))'
|
|
files: '^peps/pep-\d+\.rst$'
|
|
|
|
- id: validate-content-type
|
|
name: "'Content-Type' must be 'text/x-rst'"
|
|
language: pygrep
|
|
entry: '^Content-Type:(?:(?! +text/x-rst$))'
|
|
files: '^peps/pep-\d+\.rst$'
|
|
|
|
- id: validate-pep-references
|
|
name: "`Requires`/`Replaces`/`Superseded-By` must be 'NNN' PEP IDs"
|
|
language: pygrep
|
|
entry: '^(Requires|Replaces|Superseded-By):(?:(?! *( (0|[1-9][0-9]{0,3})(,|$))+$))'
|
|
files: '^peps/pep-\d+\.rst$'
|
|
|
|
- id: validate-created
|
|
name: "'Created' must be a 'DD-mmm-YYYY' date"
|
|
language: pygrep
|
|
entry: '^Created:(?:(?! +([0-2][0-9]|(3[01]))-(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)-(199[0-9]|20[0-9][0-9])$))'
|
|
files: '^peps/pep-\d+\.rst$'
|
|
|
|
- id: validate-python-version
|
|
name: "'Python-Version' must be a 'X.Y[.Z]` version"
|
|
language: pygrep
|
|
entry: '^Python-Version:(?:(?! *( [1-9]\.([0-9][0-9]?|x)(\.[1-9][0-9]?)?(,|$))+$))'
|
|
files: '^peps/pep-\d+\.rst$'
|
|
|
|
- id: validate-post-history
|
|
name: "'Post-History' must be '`DD-mmm-YYYY <Thread URL>`__, ...'"
|
|
language: pygrep
|
|
entry: '(?<=\n)Post-History:(?:(?! ?\n|((( +|\n {1,14})(([0-2][0-9]|(3[01]))-(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)-(199[0-9]|20[0-9][0-9])|`([0-2][0-9]|(3[01]))-(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)-(199[0-9]|20[0-9][0-9]) <https://((discuss\.python\.org/t/([\w\-]+/)?\d+(?:/\d+/|/?))|(mail\.python\.org/pipermail/[\w\-]+/\d{4}-[A-Za-z]+/[A-Za-z0-9]+\.html)|(mail\.python\.org/archives/list/[\w\-]+@python\.org/thread/[A-Za-z0-9]+/?(#[A-Za-z0-9]+)?))>`__)(,|(?=\n[^ ])))+\n(?=[A-Z\n]))))'
|
|
args: [--multiline]
|
|
files: '^peps/pep-\d+\.rst$'
|
|
|
|
- id: validate-resolution
|
|
name: "'Resolution' must be a direct thread/message URL"
|
|
language: pygrep
|
|
entry: '(?<!\n\n)(?<=\n)Resolution: (?:(?!https://((discuss\.python\.org/t/([\w\-]+/)?\d+(/\d+)?/?)|(mail\.python\.org/pipermail/[\w\-]+/\d{4}-[A-Za-z]+/[A-Za-z0-9]+\.html)|(mail\.python\.org/archives/list/[\w\-]+@python\.org/(message|thread)/[A-Za-z0-9]+/?(#[A-Za-z0-9]+)?))\n))'
|
|
args: ['--multiline']
|
|
files: '^peps/pep-\d+\.rst$'
|
|
|
|
- id: check-direct-pep-links
|
|
name: "Check that PEPs aren't linked directly"
|
|
language: pygrep
|
|
entry: '(dev/peps|peps\.python\.org)/pep-\d+'
|
|
files: '^peps/pep-\d+\.rst$'
|
|
exclude: '^peps/pep-(0009|0287|0676|0684|8001)\.rst$'
|
|
|
|
- id: check-direct-rfc-links
|
|
name: "Check that RFCs aren't linked directly"
|
|
language: pygrep
|
|
entry: '(rfc-editor\.org|ietf\.org)/[\.\-_\?\&\#\w/]*[Rr][Ff][Cc][\-_]?\d+'
|
|
types: ['rst']
|