Move the check-changelog-entries pre-commit local hook to tools.

Signed-off-by: Pedro Algarvio <palgarvio@vmware.com>
This commit is contained in:
Pedro Algarvio 2023-02-15 07:17:13 +00:00 committed by Pedro Algarvio
parent 3a04e21f70
commit d0630ae7af
3 changed files with 125 additions and 133 deletions

View file

@ -46,8 +46,19 @@ repos:
)$
- repo: https://github.com/s0undt3ch/python-tools-scripts
rev: "0.10.2"
rev: "0.10.4"
hooks:
- id: tools
alias: check-changelog-entries
name: Check Changelog Entries
args:
- changelog
- pre-commit-checks
additional_dependencies:
- boto3==1.21.46
- pyyaml==6.0
- jinja2==3.1.2
- packaging==23.0
- id: tools
alias: generate-workflows
name: Generate GitHub Workflow Templates
@ -1080,15 +1091,6 @@ repos:
- requirements/static/ci/tools.in
# <---- Tools -----------------------------------------------------------------------------------------------------
# ----- Local Hooks ----------------------------------------------------------------------------------------------->
- repo: local
hooks:
- id: check-changelog-entries
name: Check Changelog Entries
entry: .pre-commit-hooks/check-changelog-entries.py
language: script
# <---- Local Hooks ------------------------------------------------------------------------------------------------
# ----- Code Formatting ------------------------------------------------------------------------------------------->
- repo: https://github.com/asottile/pyupgrade
rev: v2.37.2

View file

@ -1,123 +0,0 @@
#!/usr/bin/env python3
# pylint: skip-file
import pathlib
import re
import sys
CODE_ROOT = pathlib.Path(__file__).resolve().parent.parent
DOCS_PATH = CODE_ROOT / "doc"
TESTS_INTEGRATION_FILES_PATH = CODE_ROOT / "tests" / "integration" / "files"
CHANGELOG_ENTRIES_PATH = CODE_ROOT / "changelog"
CHANGELOG_LIKE_RE = re.compile(r"([\d]+)\.([a-z]+)$")
CHANGELOG_EXTENSIONS = (
"removed",
"deprecated",
"changed",
"fixed",
"added",
"security",
)
CHANGELOG_ENTRY_RE = re.compile(
r"([\d]+|(CVE|cve)-[\d]{{4}}-[\d]+)\.({})(\.md)?$".format(
"|".join(CHANGELOG_EXTENSIONS)
)
)
def check_changelog_entries(files):
exitcode = 0
for entry in files:
path = pathlib.Path(entry).resolve()
# Is it under changelog/
try:
path.relative_to(CHANGELOG_ENTRIES_PATH)
if path.name == ".keep":
# This is the file we use so git doesn't delete the changelog/ directory
continue
# Is it named properly
if not CHANGELOG_ENTRY_RE.match(path.name):
print(
"The changelog entry '{}' should have one of the following extensions: {}.".format(
path.relative_to(CODE_ROOT),
", ".join(f"{ext}.md" for ext in CHANGELOG_EXTENSIONS),
),
file=sys.stderr,
flush=True,
)
exitcode = 1
continue
if not path.suffix == ".md":
print(
f"Please rename '{path.relative_to(CODE_ROOT)}' to "
f"'{path.relative_to(CODE_ROOT)}.md'",
file=sys.stderr,
flush=True,
)
exitcode = 1
continue
except ValueError:
# No, carry on
pass
# Does it look like a changelog entry
if CHANGELOG_LIKE_RE.match(path.name) and not CHANGELOG_ENTRY_RE.match(
path.name
):
try:
# Is this under doc/
path.relative_to(DOCS_PATH)
# Yes, carry on
continue
except ValueError:
# No, resume the check
pass
try:
# Is this under tests/integration/files
path.relative_to(TESTS_INTEGRATION_FILES_PATH)
# Yes, carry on
continue
except ValueError:
# No, resume the check
pass
print(
"The changelog entry '{}' should have one of the following extensions: {}.".format(
path.relative_to(CODE_ROOT),
", ".join(f"{ext}.md" for ext in CHANGELOG_EXTENSIONS),
),
file=sys.stderr,
flush=True,
)
exitcode = 1
continue
# Is it a changelog entry
if not CHANGELOG_ENTRY_RE.match(path.name):
# No? Carry on
continue
# Is the changelog entry in the right path?
try:
path.relative_to(CHANGELOG_ENTRIES_PATH)
except ValueError:
exitcode = 1
print(
"The changelog entry '{}' should be placed under '{}/', not '{}'".format(
path.name,
CHANGELOG_ENTRIES_PATH.relative_to(CODE_ROOT),
path.relative_to(CODE_ROOT).parent,
),
file=sys.stderr,
flush=True,
)
if not path.suffix == ".md":
print(
f"Please rename '{path.relative_to(CODE_ROOT)}' to "
f"'{path.relative_to(CODE_ROOT)}.md'",
file=sys.stderr,
flush=True,
)
exitcode = 1
sys.exit(exitcode)
if __name__ == "__main__":
check_changelog_entries(sys.argv[1:])

View file

@ -7,6 +7,8 @@ from __future__ import annotations
import datetime
import logging
import os
import pathlib
import re
import subprocess
import sys
import textwrap
@ -15,6 +17,20 @@ from ptscripts import Context, command_group
import tools.utils
REPO_ROOT = pathlib.Path(__file__).resolve().parent.parent
CHANGELOG_LIKE_RE = re.compile(r"([\d]+)\.([a-z]+)$")
CHANGELOG_TYPES = (
"removed",
"deprecated",
"changed",
"fixed",
"added",
"security",
)
CHANGELOG_ENTRY_RE = re.compile(
r"([\d]+|(CVE|cve)-[\d]{{4}}-[\d]+)\.({})(\.md)?$".format("|".join(CHANGELOG_TYPES))
)
log = logging.getLogger(__name__)
# Define the command group
@ -35,6 +51,103 @@ changelog = command_group(
)
@changelog.command(
name="pre-commit-checks",
arguments={
"files": {
"nargs": "*",
}
},
)
def check_changelog_entries(ctx: Context, files: list[pathlib.Path]):
"""
Run pre-commit checks on changelog snippets.
"""
docs_path = REPO_ROOT / "doc"
tests_integration_files_path = REPO_ROOT / "tests" / "integration" / "files"
changelog_entries_path = REPO_ROOT / "changelog"
exitcode = 0
for entry in files:
path = pathlib.Path(entry).resolve()
# Is it under changelog/
try:
path.relative_to(changelog_entries_path)
if path.name in (".keep", ".template.jinja"):
# This is the file we use so git doesn't delete the changelog/ directory
continue
# Is it named properly
if not CHANGELOG_ENTRY_RE.match(path.name):
ctx.error(
"The changelog entry '{}' should have one of the following extensions: {}.".format(
path.relative_to(REPO_ROOT),
", ".join(f"{ext}.md" for ext in CHANGELOG_TYPES),
),
)
exitcode = 1
continue
if path.suffix != ".md":
ctx.error(
f"Please rename '{path.relative_to(REPO_ROOT)}' to "
f"'{path.relative_to(REPO_ROOT)}.md'"
)
exitcode = 1
continue
except ValueError:
# No, carry on
pass
# Does it look like a changelog entry
if CHANGELOG_LIKE_RE.match(path.name) and not CHANGELOG_ENTRY_RE.match(
path.name
):
try:
# Is this under doc/
path.relative_to(docs_path)
# Yes, carry on
continue
except ValueError:
# No, resume the check
pass
try:
# Is this under tests/integration/files
path.relative_to(tests_integration_files_path)
# Yes, carry on
continue
except ValueError:
# No, resume the check
pass
ctx.error(
"The changelog entry '{}' should have one of the following extensions: {}.".format(
path.relative_to(REPO_ROOT),
", ".join(f"{ext}.md" for ext in CHANGELOG_TYPES),
)
)
exitcode = 1
continue
# Is it a changelog entry
if not CHANGELOG_ENTRY_RE.match(path.name):
# No? Carry on
continue
# Is the changelog entry in the right path?
try:
path.relative_to(changelog_entries_path)
except ValueError:
exitcode = 1
ctx.error(
"The changelog entry '{}' should be placed under '{}/', not '{}'".format(
path.name,
changelog_entries_path.relative_to(REPO_ROOT),
path.relative_to(REPO_ROOT).parent,
)
)
if path.suffix != ".md":
ctx.error(
f"Please rename '{path.relative_to(REPO_ROOT)}' to "
f"'{path.relative_to(REPO_ROOT)}.md'"
)
exitcode = 1
ctx.exit(exitcode)
def _get_changelog_contents(ctx: Context, version: str):
"""
Return the full changelog generated by towncrier.