mirror of
https://github.com/pre-commit/pre-commit-hooks.git
synced 2026-04-04 19:26:52 +00:00
Add prepare-commit-msg hook
Added new hook for templating prepare-commit-msg hook. Added 2 templates to use keepgin `prepare_commit_msg_append.j2`as default. The idea is that developers could create their own templates accordingly to teams commit conventions and override them in the hook arguments when configuring it.
This commit is contained in:
parent
18c2496e4c
commit
e01e1717b1
8 changed files with 236 additions and 0 deletions
123
pre_commit_hooks/prepare_commit_msg.py
Normal file
123
pre_commit_hooks/prepare_commit_msg.py
Normal file
|
|
@ -0,0 +1,123 @@
|
|||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import re
|
||||
from typing import Sequence
|
||||
|
||||
from jinja2 import Environment
|
||||
from jinja2 import PackageLoader
|
||||
from jinja2 import select_autoescape
|
||||
|
||||
from pre_commit_hooks.util import CalledProcessError
|
||||
from pre_commit_hooks.util import cmd_output
|
||||
|
||||
|
||||
def get_current_branch() -> str:
|
||||
try:
|
||||
ref_name = cmd_output('git', 'symbolic-ref', '--short', 'HEAD')
|
||||
except CalledProcessError:
|
||||
return ''
|
||||
|
||||
return ref_name.strip()
|
||||
|
||||
|
||||
def _configure_args(
|
||||
parser: argparse.ArgumentParser,
|
||||
) -> argparse.ArgumentParser:
|
||||
parser.add_argument(
|
||||
'-t', '--template', default='prepare_commit_msg_append.j2',
|
||||
help='Template to use for the commit message.',
|
||||
)
|
||||
parser.add_argument(
|
||||
'-b', '--branch', action='append', default=['main', 'master'],
|
||||
help='Branch to skip, may be specified multiple times.',
|
||||
)
|
||||
parser.add_argument(
|
||||
'-p', '--pattern', action='append', default=['(?<=feature/).*'],
|
||||
help='RegEx Pattern for recognising Ticket Numbers in branch, '
|
||||
'may be specified multiple times.',
|
||||
)
|
||||
parser.add_argument('COMMIT_MSG_FILE', nargs=argparse.REMAINDER)
|
||||
|
||||
return parser
|
||||
|
||||
|
||||
def get_jinja_env() -> Environment:
|
||||
return Environment(
|
||||
loader=PackageLoader('pre_commit_hooks'),
|
||||
autoescape=select_autoescape(),
|
||||
)
|
||||
|
||||
|
||||
def get_rendered_template(
|
||||
jinja: Environment,
|
||||
template_file: str,
|
||||
variables: dict[str, str],
|
||||
) -> str:
|
||||
template = jinja.get_template(template_file)
|
||||
return template.render(variables)
|
||||
|
||||
|
||||
def update_commit_file(
|
||||
jinja: Environment,
|
||||
commit_msg_file: str,
|
||||
template: str,
|
||||
ticket: str,
|
||||
) -> int:
|
||||
try:
|
||||
with open(commit_msg_file) as f:
|
||||
data = f.readlines()
|
||||
|
||||
data_as_str = ''.join([item for item in data])
|
||||
# if message already contain ticket number means
|
||||
# it is under git commit --amend or rebase or alike
|
||||
# where message was already set in the past
|
||||
if ticket in data_as_str:
|
||||
return 0
|
||||
|
||||
variables = {
|
||||
'ticket': ticket,
|
||||
'content': data_as_str,
|
||||
}
|
||||
|
||||
content = get_rendered_template(
|
||||
jinja=jinja,
|
||||
template_file=template,
|
||||
variables=variables,
|
||||
)
|
||||
with open(commit_msg_file, 'w') as f:
|
||||
f.write(content)
|
||||
|
||||
return 0
|
||||
except OSError as err:
|
||||
print(f'OS error: {err}')
|
||||
return 1
|
||||
|
||||
|
||||
def main(argv: Sequence[str] | None = None) -> int:
|
||||
parser = _configure_args(argparse.ArgumentParser())
|
||||
args = parser.parse_args(argv)
|
||||
|
||||
current = get_current_branch()
|
||||
branches = frozenset(args.branch)
|
||||
if current in branches:
|
||||
# checked black listed branches
|
||||
return 0
|
||||
|
||||
patterns = frozenset(args.pattern)
|
||||
matches = [
|
||||
match.group(0)
|
||||
for match in (re.search(pattern, current) for pattern in patterns)
|
||||
if match
|
||||
]
|
||||
if len(matches) == 0:
|
||||
# checked white listed branches
|
||||
return 0
|
||||
|
||||
jinja = get_jinja_env()
|
||||
commit_file = args.COMMIT_MSG_FILE[0]
|
||||
return update_commit_file(jinja, commit_file, args.template, matches[0])
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
raise SystemExit(main())
|
||||
3
pre_commit_hooks/templates/prepare_commit_msg_append.j2
Normal file
3
pre_commit_hooks/templates/prepare_commit_msg_append.j2
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
{{ content }}
|
||||
|
||||
Relates: {{ ticket }}
|
||||
1
pre_commit_hooks/templates/prepare_commit_msg_prepend.j2
Normal file
1
pre_commit_hooks/templates/prepare_commit_msg_prepend.j2
Normal file
|
|
@ -0,0 +1 @@
|
|||
[{{ ticket }}] {{ content }}
|
||||
Loading…
Add table
Add a link
Reference in a new issue