From 86d5ab84cb7b5b08259796b56ffb6d4e784f8980 Mon Sep 17 00:00:00 2001 From: Mariano Anaya Date: Fri, 31 May 2024 13:08:20 +0200 Subject: [PATCH] New hook for enforcing branch name Use a regex to validate the naming convention the branch should follow. If it's not correct, it fails. --- .pre-commit-hooks.yaml | 7 +++++ README.md | 12 ++++++++ pre_commit_hooks/enforce_branch_name.py | 38 +++++++++++++++++++++++++ setup.cfg | 1 + 4 files changed, 58 insertions(+) create mode 100644 pre_commit_hooks/enforce_branch_name.py diff --git a/.pre-commit-hooks.yaml b/.pre-commit-hooks.yaml index 44a8648..026733c 100644 --- a/.pre-commit-hooks.yaml +++ b/.pre-commit-hooks.yaml @@ -204,3 +204,10 @@ language: python types: [text] stages: [commit, push, manual] +- id: enforce-branch-name + name: enforce branch name + description: Make sure the current branch follows one of the accepted patterns. + entry: enforce-branch-name + language: python + pass_filenames: false + always_run: true diff --git a/README.md b/README.md index 97bfba6..cf67808 100644 --- a/README.md +++ b/README.md @@ -210,6 +210,18 @@ Trims trailing whitespace. - By default, this hook trims all whitespace from the ends of lines. To specify a custom set of characters to trim instead, use `args: [--chars,""]`. + +#### `enforce-branch-name` +Validates the branch name follows a pattern. + - `-p` / `--pattern` is used to pass the regex a valid branch name should have. + +Note that `enforce-branch-name` is configured by default to [`always_run`](https://pre-commit.com/#config-always_run). +As a result, it will ignore any setting of [`files`](https://pre-commit.com/#config-files), +[`exclude`](https://pre-commit.com/#config-exclude), [`types`](https://pre-commit.com/#config-types) +or [`exclude_types`](https://pre-commit.com/#config-exclude_types). +Set [`always_run: false`](https://pre-commit.com/#config-always_run) to allow this hook to be skipped according to these +file filters. Caveat: In this configuration, empty commits (`git commit --allow-empty`) would always be allowed by this hook. + ### Deprecated / replaced hooks - `check-byte-order-marker`: instead use fix-byte-order-marker diff --git a/pre_commit_hooks/enforce_branch_name.py b/pre_commit_hooks/enforce_branch_name.py new file mode 100644 index 0000000..170e1c2 --- /dev/null +++ b/pre_commit_hooks/enforce_branch_name.py @@ -0,0 +1,38 @@ +from __future__ import annotations + +import argparse +import re +from typing import AbstractSet +from typing import Sequence + +from pre_commit_hooks.util import CalledProcessError +from pre_commit_hooks.util import cmd_output + +OK = 0 +ERROR = 1 + + +def branch_follows_pattern(patterns: AbstractSet[str]) -> bool: + try: + ref_name = cmd_output("git", "symbolic-ref", "HEAD") + except CalledProcessError: + return False + chunks = ref_name.strip().split("/") + branch_name = "/".join(chunks[2:]) + return any(re.match(p, branch_name) for p in patterns) + + +def main(argv: Sequence[str] | None = None) -> int: + parser = argparse.ArgumentParser() + parser.add_argument( + "-p", + "--pattern", + action="append", + help=("regex pattern that the name of the branch must comply with"), + ) + args = parser.parse_args(argv) + return OK if branch_follows_pattern(frozenset(args.pattern)) else ERROR + + +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/setup.cfg b/setup.cfg index 82a5457..8045b40 100644 --- a/setup.cfg +++ b/setup.cfg @@ -63,6 +63,7 @@ console_scripts = requirements-txt-fixer = pre_commit_hooks.requirements_txt_fixer:main sort-simple-yaml = pre_commit_hooks.sort_simple_yaml:main trailing-whitespace-fixer = pre_commit_hooks.trailing_whitespace_fixer:main + enforce-branch-name = pre_commit_hooks.enforce_branch_name:main [bdist_wheel] universal = True