Skip to content

Commit

Permalink
Release version 1.0.1
Browse files Browse the repository at this point in the history
  • Loading branch information
boidolr committed Feb 3, 2022
1 parent 2185aef commit 6031960
Show file tree
Hide file tree
Showing 5 changed files with 166 additions and 1 deletion.
1 change: 1 addition & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ repos:
- id: prepare-message
args: [--ignore-branch=main]
- id: format-message

- repo: https://github.com/boidolr/pre-commit-text
rev: v1.0.0
hooks:
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ A collection of prepare message and commit message git hooks for use with the [p
Add this to your `.pre-commit-config.yaml`:
```
- repo: https://github.com/boidolr/pre-commit-msg
rev: v1.0.0 # Use the ref you want to point at
rev: v1.0.1 # Use the ref you want to point at
hooks:
- id: format-message
# - id: ...
Expand Down
1 change: 1 addition & 0 deletions build/lib/pre_commit_msg/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
VERSION = "1.0.0"
43 changes: 43 additions & 0 deletions build/lib/pre_commit_msg/format_message.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
#!/usr/bin/env python3
import argparse
import sys
from typing import Optional
from typing import Sequence


def _ensure_message_format(commit_msg_filepath: str, capitalize: bool) -> None:
# ensure there are always two empty lines between short description and description
with open(commit_msg_filepath, "r+") as fh:
lines = fh.read().splitlines()
if len(lines) > 0 and capitalize:
lines[0] = lines[0].capitalize()

if len(lines) > 1 and lines[1] != "":
lines.insert(1, "")

if len(lines) > 2 and lines[2] != "":
lines.insert(2, "")

while len(lines) >= 4 and lines[3] == "":
lines.pop(3)

fh.seek(0, 0)
fh.write("\n".join(lines))
fh.truncate()


def main(argv: Optional[Sequence[str]] = None) -> int:
parser = argparse.ArgumentParser()
parser.add_argument("filename", help="Commit message file path")
parser.add_argument(
"-c", "--capitalize", action="store_true", help="Capitalize subject line"
)
args = parser.parse_args(argv)

_ensure_message_format(args.filename, args.capitalize)

return 0


if __name__ == "__main__":
sys.exit(main())
120 changes: 120 additions & 0 deletions build/lib/pre_commit_msg/prepare_message.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
#!/usr/bin/env python3
import argparse
import re
import subprocess # nosec
import sys
from operator import methodcaller
from pathlib import Path
from typing import Match
from typing import Optional
from typing import Pattern
from typing import Sequence


def _execute_command(*args: str, returncode: Optional[int] = None) -> Optional[str]:
result = subprocess.run( # nosec
args, encoding="utf-8", stderr=subprocess.DEVNULL, stdout=subprocess.PIPE
)
if (
returncode is None
and result.returncode != 0
or returncode is not None
and result.returncode != returncode
):
return None
return result.stdout.strip()


def _get_current_git_path() -> Optional[str]:
return _execute_command("git", "rev-parse", "--git-path", ".")


def _git_op_in_progress() -> bool:
git_dir = _get_current_git_path()
if not git_dir:
raise FileNotFoundError("Failed to find git directory")
files = ("rebase-merge", "rebase-apply", "MERGE_HEAD", "MERGE_MSG")
paths = map(Path(git_dir).joinpath, files)
exists = map(methodcaller("exists"), paths)
return any(exists)


def _get_branch_name() -> Optional[str]:
return _execute_command("git", "symbolic-ref", "--short", "HEAD")


def _is_wrong_message_prefix(
commit_msg_filepath: str, prefix_pattern: Pattern[str]
) -> bool:
with open(commit_msg_filepath) as fh:
commit_msg_start = fh.readline()
return prefix_pattern.match(commit_msg_start) is None


def _update_message(
commit_msg_filepath: str,
branch_match: Optional[Match[str]],
prefix_pattern: Pattern[str],
) -> bool:
if branch_match is None:
return False

issue = branch_match.group(1)
prefix = f"{issue}: "
with open(commit_msg_filepath, "r+") as fh:
commit_msg = fh.read()
if not commit_msg.startswith((prefix, "Merge", "Revert", "fixup!", "squash!")):
msg = prefix_pattern.sub("", commit_msg, count=1)
fh.seek(0, 0)
fh.write(prefix)
fh.write(msg)
fh.truncate()

return True


def main(argv: Optional[Sequence[str]] = None) -> int:
parser = argparse.ArgumentParser()
parser.add_argument("filename", help="Commit message file path")
parser.add_argument(
"--ignore-branch",
nargs="*",
dest="ignore_branch",
help="Branches where no checking should be done.",
)
parser.add_argument(
"--pattern",
default=r"(?:feature|hotfix)\/(\w+-\d+)",
help="Pattern to match feature branch name (default: %(default)s).",
)
parser.add_argument(
"--prefix-pattern",
default=r"^\s*\w+-\d+\s*:?\s*",
dest="prefix",
help="Pattern to match the commit message prefix (default: %(default)s).",
)
args = parser.parse_args(argv)

if _git_op_in_progress():
return 0

branch_name = _get_branch_name()
if branch_name is None:
print("Not on a branch, returning early.", file=sys.stderr)
return 1

if args.ignore_branch is not None and branch_name in args.ignore_branch:
return 0

branch_name = branch_name.strip()
match = re.match(args.pattern, branch_name)
updated = _update_message(args.filename, match, re.compile(args.prefix))
if not updated:
print(f'Could not update message on branch "{branch_name}"', file=sys.stderr)
return 1

return 0


if __name__ == "__main__":
sys.exit(main())

0 comments on commit 6031960

Please sign in to comment.