mirror of
https://github.com/enzet/map-machine.git
synced 2025-05-01 03:07:41 +02:00
133 lines
3.8 KiB
Python
Executable file
133 lines
3.8 KiB
Python
Executable file
#!/usr/bin/env python3
|
|
"""
|
|
Commit message checking.
|
|
"""
|
|
import sys
|
|
from typing import List, Optional
|
|
|
|
__author__ = "Sergey Vartanov"
|
|
__email__ = "me@enzet.ru"
|
|
|
|
SHORT_MESSAGE_MAX_LENGTH: int = 50
|
|
MESSAGE_MAX_LENGTH: int = 72
|
|
|
|
|
|
def check_file(file_name: str) -> Optional[str]:
|
|
"""
|
|
Exit program with exit code 1 if commit message does not conform the rules.
|
|
|
|
:param file_name: commit message file name
|
|
"""
|
|
with open(file_name, encoding="utf-8") as input_file:
|
|
parts: List[str] = list(map(lambda x: x[:-1], input_file.readlines()))
|
|
return check_commit_message(parts)
|
|
|
|
|
|
def check_commit_message(parts: List[str]) -> Optional[str]:
|
|
"""Check whether the commit message is well-formed."""
|
|
short_message: str = parts[0]
|
|
|
|
if short_message[0] != short_message[0].upper():
|
|
return (
|
|
short_message
|
|
+ "\n^"
|
|
+ "\nCommit message short description should start with uppercase "
|
|
+ "letter."
|
|
)
|
|
|
|
if len(short_message) > SHORT_MESSAGE_MAX_LENGTH:
|
|
return (
|
|
short_message
|
|
+ "\n"
|
|
+ " " * SHORT_MESSAGE_MAX_LENGTH
|
|
+ "^" * (len(short_message) - SHORT_MESSAGE_MAX_LENGTH)
|
|
+ "\nCommit message short description should not be longer than "
|
|
+ f"{SHORT_MESSAGE_MAX_LENGTH} symbols."
|
|
)
|
|
|
|
if len(parts) > 1:
|
|
if parts[1]:
|
|
return (
|
|
"Commit message should have new line after short description."
|
|
)
|
|
for part in parts[2:]:
|
|
if len(part.strip()) > 0 and part.strip()[0] == "#":
|
|
continue
|
|
if len(part) > MESSAGE_MAX_LENGTH:
|
|
return (
|
|
part
|
|
+ "\n"
|
|
+ " " * MESSAGE_MAX_LENGTH
|
|
+ "^" * (len(part) - MESSAGE_MAX_LENGTH)
|
|
+ "\nCommit message description should not be longer than "
|
|
+ f"{MESSAGE_MAX_LENGTH} symbols."
|
|
)
|
|
|
|
if not short_message.endswith("."):
|
|
return (
|
|
short_message
|
|
+ "\n"
|
|
+ " " * (len(short_message) - 1)
|
|
+ "^"
|
|
+ '\nCommit message should end with ".".'
|
|
)
|
|
|
|
def first_letter_uppercase(text: str):
|
|
"""Change first letter to upper case."""
|
|
return text[0].upper() + text[1:]
|
|
|
|
verbs_1 = ["add", "fix", "check", "refactor"]
|
|
verbs_2 = [
|
|
"change",
|
|
"remove",
|
|
"create",
|
|
"update",
|
|
"rename",
|
|
"move",
|
|
"swap",
|
|
"treat",
|
|
"suppress",
|
|
]
|
|
|
|
verbs = {"got": "get"}
|
|
for verb in verbs_1:
|
|
verbs[verb + "ed"] = verb
|
|
for verb in verbs_2:
|
|
verbs[verb + "d"] = verb
|
|
|
|
for wrong_verb, right_verb in verbs.items():
|
|
if short_message.startswith(
|
|
f"{wrong_verb} "
|
|
) or short_message.startswith(f"{first_letter_uppercase(wrong_verb)} "):
|
|
return (
|
|
f"Commit message should start with the verb in infinitive "
|
|
f"form. Please, use "
|
|
f'"{first_letter_uppercase(right_verb)} ..." instead of '
|
|
f'"{first_letter_uppercase(wrong_verb)} ...".'
|
|
)
|
|
|
|
|
|
def check(commit_message: str) -> None:
|
|
"""Print commit_message and checking result."""
|
|
print("\033[33m" + commit_message + "\033[0m")
|
|
print(check_commit_message(commit_message.split("\n")))
|
|
|
|
|
|
def test():
|
|
"""Test rules."""
|
|
check("start with lowercase letter.")
|
|
check("Added foo.")
|
|
check("Created foo.")
|
|
check("Doesn't end with dot")
|
|
check("To-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o long")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
if sys.argv[1] == "__test__":
|
|
test()
|
|
else:
|
|
print("Checking commit message...")
|
|
message = check_file(sys.argv[1])
|
|
if message is not None:
|
|
print(message)
|
|
sys.exit(1)
|