From 4e14363751891bf1b17d940ae613efbe9d49d1bc Mon Sep 17 00:00:00 2001 From: shenxianpeng Date: Sun, 7 Sep 2025 22:18:56 +0300 Subject: [PATCH 1/6] refactor: reduce #275 its cognitive complexity --- commit_check/author.py | 87 +++++++++++++------ commit_check/branch.py | 100 +++++++++++++--------- commit_check/commit.py | 187 +++++++++++++++++++++-------------------- pyproject.toml | 6 ++ 4 files changed, 221 insertions(+), 159 deletions(-) diff --git a/commit_check/author.py b/commit_check/author.py index e3cfd208..01083fa2 100644 --- a/commit_check/author.py +++ b/commit_check/author.py @@ -1,34 +1,69 @@ """Check git author name and email""" import re +from typing import Optional from commit_check import YELLOW, RESET_COLOR, PASS, FAIL -from commit_check.util import get_commit_info, has_commits, print_error_header, print_error_message, print_suggestion +from commit_check.util import ( + get_commit_info, + has_commits, + print_error_header, + print_error_message, + print_suggestion, +) -def check_author(checks: list, check_type: str) -> int: - if has_commits() is False: - return PASS # pragma: no cover +_AUTHOR_FORMAT_MAP = { + "author_name": "an", + "author_email": "ae", +} + +def _find_check(checks: list, check_type: str) -> Optional[dict]: + """Return the first check dict matching check_type, else None.""" for check in checks: - if check['check'] == check_type: - if check['regex'] == "": - print( - f"{YELLOW}Not found regex for {check_type}. skip checking.{RESET_COLOR}", - ) - return PASS - if check_type == "author_name": - format_str = "an" - if check_type == 'author_email': - format_str = "ae" - config_value = str(get_commit_info(format_str)) - result = re.match(check['regex'], config_value) - if result is None: - if not print_error_header.has_been_called: - print_error_header() - print_error_message( - check['check'], check['regex'], - check['error'], config_value, - ) - if check['suggest']: - print_suggestion(check['suggest']) - return FAIL + if check.get("check") == check_type: + return check + return None + + +def _get_author_value(check_type: str) -> str: + """Fetch the author value from git for the given check type.""" + format_str = _AUTHOR_FORMAT_MAP.get(check_type, "") + return str(get_commit_info(format_str)) + + +def _evaluate_check(check: dict, value: str) -> int: + """Evaluate a single author check against the provided value.""" + regex = check.get("regex", "") + if regex == "": + print(f"{YELLOW}Not found regex for {check.get('check')}. skip checking.{RESET_COLOR}") + return PASS + + if re.match(regex, value) is None: + if not print_error_header.has_been_called: + print_error_header() + check_name = str(check.get("check", "")) + error_msg = str(check.get("error", "")) + print_error_message(check_name, regex, error_msg, value) + if check.get("suggest"): + print_suggestion(check["suggest"]) + return FAIL return PASS + + +def check_author(checks: list, check_type: str) -> int: + """Validate author name or email according to configured regex.""" + if has_commits() is False: + return PASS # pragma: no cover + + check = _find_check(checks, check_type) + if not check: + return PASS + + # If regex is empty, skip without fetching author info + regex = check.get("regex", "") + if regex == "": + print(f"{YELLOW}Not found regex for {check_type}. skip checking.{RESET_COLOR}") + return PASS + + value = _get_author_value(check_type) + return _evaluate_check(check, value) diff --git a/commit_check/branch.py b/commit_check/branch.py index b7446cc5..ff7c9af2 100644 --- a/commit_check/branch.py +++ b/commit_check/branch.py @@ -4,27 +4,39 @@ from commit_check.util import get_branch_name, git_merge_base, print_error_header, print_error_message, print_suggestion, has_commits -def check_branch(checks: list) -> int: +def _find_branch_check(checks: list) -> dict | None: + """Return the first branch check config or None if not present.""" for check in checks: - if check['check'] == 'branch': - if check['regex'] == "": - print( - f"{YELLOW}Not found regex for branch naming. skip checking.{RESET_COLOR}", - ) - return PASS - branch_name = get_branch_name() - result = re.match(check['regex'], branch_name) - if result is None: - if not print_error_header.has_been_called: - print_error_header() # pragma: no cover - print_error_message( - check['check'], check['regex'], - check['error'], branch_name, - ) - if check['suggest']: - print_suggestion(check['suggest']) - return FAIL - return PASS + if check.get('check') == 'branch': + return check + return None + + +def check_branch(checks: list) -> int: + check = _find_branch_check(checks) + if not check: + return PASS + + regex = check.get('regex', "") + if regex == "": + print( + f"{YELLOW}Not found regex for branch naming. skip checking.{RESET_COLOR}", + ) + return PASS + + branch_name = get_branch_name() + if re.match(regex, branch_name): + return PASS + + if not print_error_header.has_been_called: + print_error_header() # pragma: no cover + print_error_message( + check['check'], regex, + check['error'], branch_name, + ) + if check.get('suggest'): + print_suggestion(check['suggest']) + return FAIL def check_merge_base(checks: list) -> int: @@ -36,24 +48,30 @@ def check_merge_base(checks: list) -> int: if has_commits() is False: return PASS # pragma: no cover - for check in checks: - if check['check'] == 'merge_base': - if check['regex'] == "": - print( - f"{YELLOW}Not found target branch for checking merge base. skip checking.{RESET_COLOR}", - ) - return PASS - target_branch = check['regex'] if "origin/" in check['regex'] else f"origin/{check['regex']}" - current_branch = get_branch_name() - result = git_merge_base(target_branch, current_branch) - if result != 0: - if not print_error_header.has_been_called: - print_error_header() # pragma: no cover - print_error_message( - check['check'], check['regex'], - check['error'], current_branch, - ) - if check['suggest']: - print_suggestion(check['suggest']) - return FAIL - return PASS + # locate merge_base rule, if any + merge_check = next((c for c in checks if c.get('check') == 'merge_base'), None) + if not merge_check: + return PASS + + regex = merge_check.get('regex', "") + if regex == "": + print( + f"{YELLOW}Not found target branch for checking merge base. skip checking.{RESET_COLOR}", + ) + return PASS + + target_branch = regex if "origin/" in regex else f"origin/{regex}" + current_branch = get_branch_name() + result = git_merge_base(target_branch, current_branch) + if result == 0: + return PASS + + if not print_error_header.has_been_called: + print_error_header() # pragma: no cover + print_error_message( + merge_check['check'], regex, + merge_check['error'], current_branch, + ) + if merge_check.get('suggest'): + print_suggestion(merge_check['suggest']) + return FAIL diff --git a/commit_check/commit.py b/commit_check/commit.py index d9ef0ab2..fab7cb2a 100644 --- a/commit_check/commit.py +++ b/commit_check/commit.py @@ -27,117 +27,120 @@ def read_commit_msg(commit_msg_file) -> str: return str(get_commit_info("s") + "\n\n" + get_commit_info("b")) +def _find_check(checks: list, kind: str) -> dict | None: + """Return the first check config matching kind, else None.""" + for check in checks: + if check.get('check') == kind: + return check + return None + + +def _ensure_msg_file(commit_msg_file: str | None) -> str: + """Return a commit message file path, falling back to the default when empty.""" + if not commit_msg_file: + return get_default_commit_msg_file() + return commit_msg_file + + +def _print_failure(check: dict, regex: str, actual: str) -> None: + if not print_error_header.has_been_called: + print_error_header() # pragma: no cover + print_error_message(check['check'], regex, check['error'], actual) + if check.get('suggest'): + print_suggestion(check['suggest']) + + def check_commit_msg(checks: list, commit_msg_file: str = "") -> int: """Check commit message against the provided checks.""" if has_commits() is False: - return PASS # pragma: no cover + return PASS # pragma: no cover - if commit_msg_file is None or commit_msg_file == "": - commit_msg_file = get_default_commit_msg_file() + check = _find_check(checks, 'message') + if not check: + return PASS - commit_msg = read_commit_msg(commit_msg_file) + regex = check.get('regex', "") + if regex == "": + print(f"{YELLOW}Not found regex for commit message. skip checking.{RESET_COLOR}") + return PASS - for check in checks: - if check['check'] == 'message': - if check['regex'] == "": - print( - f"{YELLOW}Not found regex for commit message. skip checking.{RESET_COLOR}", - ) - return PASS - - result = re.match(check['regex'], commit_msg) - if result is None: - if not print_error_header.has_been_called: - print_error_header() # pragma: no cover - print_error_message( - check['check'], check['regex'], - check['error'], commit_msg, - ) - if check['suggest']: - print_suggestion(check['suggest']) - return FAIL - - return PASS + path = _ensure_msg_file(commit_msg_file) + commit_msg = read_commit_msg(path) + + if re.match(regex, commit_msg): + return PASS + + _print_failure(check, regex, commit_msg) + return FAIL def check_commit_signoff(checks: list, commit_msg_file: str = "") -> int: if has_commits() is False: - return PASS # pragma: no cover + return PASS # pragma: no cover - if commit_msg_file is None or commit_msg_file == "": - commit_msg_file = get_default_commit_msg_file() + check = _find_check(checks, 'commit_signoff') + if not check: + return PASS - for check in checks: - if check['check'] == 'commit_signoff': - if check['regex'] == "": - print( - f"{YELLOW}Not found regex for commit signoff. skip checking.{RESET_COLOR}", - ) - return PASS - - commit_msg = read_commit_msg(commit_msg_file) - - # Extract the subject line (first line of commit message) - subject = commit_msg.split('\n')[0].strip() - - # Skip if merge commit - if subject.startswith('Merge'): - return PASS - - commit_hash = get_commit_info("H") - result = re.search(check['regex'], commit_msg) - if result is None: - if not print_error_header.has_been_called: - print_error_header() # pragma: no cover - print_error_message( - check['check'], check['regex'], - check['error'], commit_hash, - ) - if check['suggest']: - print_suggestion(check['suggest']) - return FAIL - - return PASS + regex = check.get('regex', "") + if regex == "": + print(f"{YELLOW}Not found regex for commit signoff. skip checking.{RESET_COLOR}") + return PASS + + path = _ensure_msg_file(commit_msg_file) + commit_msg = read_commit_msg(path) + + # Extract the subject line (first line of commit message) + subject = commit_msg.split('\n')[0].strip() + + # Skip if merge commit + if subject.startswith('Merge'): + return PASS + + commit_hash = get_commit_info("H") + if re.search(regex, commit_msg): + return PASS + + if not print_error_header.has_been_called: + print_error_header() # pragma: no cover + print_error_message(check['check'], regex, check['error'], commit_hash) + if check.get('suggest'): + print_suggestion(check['suggest']) + return FAIL def check_imperative(checks: list, commit_msg_file: str = "") -> int: """Check if commit message uses imperative mood.""" if has_commits() is False: - return PASS # pragma: no cover + return PASS # pragma: no cover - if commit_msg_file is None or commit_msg_file == "": - commit_msg_file = get_default_commit_msg_file() + check = _find_check(checks, 'imperative') + if not check: + return PASS - for check in checks: - if check['check'] == 'imperative': - commit_msg = read_commit_msg(commit_msg_file) - - # Extract the subject line (first line of commit message) - subject = commit_msg.split('\n')[0].strip() - - # Skip if empty or merge commit - if not subject or subject.startswith('Merge'): - return PASS - - # For conventional commits, extract description after the colon - if ':' in subject: - description = subject.split(':', 1)[1].strip() - else: - description = subject - - # Check if the description uses imperative mood - if not _is_imperative(description): - if not print_error_header.has_been_called: - print_error_header() # pragma: no cover - print_error_message( - check['check'], 'imperative mood pattern', - check['error'], subject, - ) - if check['suggest']: - print_suggestion(check['suggest']) - return FAIL - - return PASS + path = _ensure_msg_file(commit_msg_file) + commit_msg = read_commit_msg(path) + + # Extract the subject line (first line of commit message) + subject = commit_msg.split('\n')[0].strip() + + # Skip if empty or merge commit + if not subject or subject.startswith('Merge'): + return PASS + + # For conventional commits, extract description after the colon + description = subject.split(':', 1)[1].strip() if ':' in subject else subject + + # Check if the description uses imperative mood + if _is_imperative(description): + return PASS + + if not print_error_header.has_been_called: + print_error_header() # pragma: no cover + print_error_message(check['check'], 'imperative mood pattern', check['error'], subject) + if check.get('suggest'): + print_suggestion(check['suggest']) + return FAIL def _is_imperative(description: str) -> bool: diff --git a/pyproject.toml b/pyproject.toml index 8f956392..b2e38487 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -67,3 +67,9 @@ omit = [ # don't include tests in coverage "tests/*", ] + +[tool.pytest.ini_options] +# Silence PytestUnknownMarkWarning for custom marks used in tests +markers = [ + "benchmark: performance-related tests (no-op marker in this project)", +] From 8d8d8df70bca368925806989087c79489cfc7df1 Mon Sep 17 00:00:00 2001 From: shenxianpeng Date: Mon, 8 Sep 2025 18:35:40 +0300 Subject: [PATCH 2/6] refactor: move _find_check to util --- commit_check/author.py | 10 +--------- commit_check/commit.py | 10 +--------- commit_check/util.py | 8 ++++++++ 3 files changed, 10 insertions(+), 18 deletions(-) diff --git a/commit_check/author.py b/commit_check/author.py index 01083fa2..74946a8d 100644 --- a/commit_check/author.py +++ b/commit_check/author.py @@ -1,6 +1,5 @@ """Check git author name and email""" import re -from typing import Optional from commit_check import YELLOW, RESET_COLOR, PASS, FAIL from commit_check.util import ( get_commit_info, @@ -8,6 +7,7 @@ print_error_header, print_error_message, print_suggestion, + _find_check, ) @@ -17,14 +17,6 @@ } -def _find_check(checks: list, check_type: str) -> Optional[dict]: - """Return the first check dict matching check_type, else None.""" - for check in checks: - if check.get("check") == check_type: - return check - return None - - def _get_author_value(check_type: str) -> str: """Fetch the author value from git for the given check type.""" format_str = _AUTHOR_FORMAT_MAP.get(check_type, "") diff --git a/commit_check/commit.py b/commit_check/commit.py index fab7cb2a..cc98d864 100644 --- a/commit_check/commit.py +++ b/commit_check/commit.py @@ -2,7 +2,7 @@ import re from pathlib import PurePath from commit_check import YELLOW, RESET_COLOR, PASS, FAIL -from commit_check.util import cmd_output, get_commit_info, print_error_header, print_error_message, print_suggestion, has_commits +from commit_check.util import _find_check, cmd_output, get_commit_info, print_error_header, print_error_message, print_suggestion, has_commits from commit_check.imperatives import IMPERATIVES @@ -27,14 +27,6 @@ def read_commit_msg(commit_msg_file) -> str: return str(get_commit_info("s") + "\n\n" + get_commit_info("b")) -def _find_check(checks: list, kind: str) -> dict | None: - """Return the first check config matching kind, else None.""" - for check in checks: - if check.get('check') == kind: - return check - return None - - def _ensure_msg_file(commit_msg_file: str | None) -> str: """Return a commit message file path, falling back to the default when empty.""" if not commit_msg_file: diff --git a/commit_check/util.py b/commit_check/util.py index 6d3c33b7..3f5595ae 100644 --- a/commit_check/util.py +++ b/commit_check/util.py @@ -12,6 +12,14 @@ from commit_check import RED, GREEN, YELLOW, RESET_COLOR +def _find_check(checks: list, check_type: str) -> dict | None: + """Return the first check dict matching check_type, else None.""" + for check in checks: + if check.get('check') == check_type: + return check + return None + + def get_branch_name() -> str: """Identify current branch name. .. note:: From 6d4fff68d9790600a02895f569b895b25aa0ea5f Mon Sep 17 00:00:00 2001 From: shenxianpeng Date: Mon, 8 Sep 2025 22:05:44 +0300 Subject: [PATCH 3/6] refactor: add _print_failure to call --- commit_check/author.py | 31 ++++++++++++---------------- commit_check/branch.py | 40 ++++++++++++------------------------ commit_check/commit.py | 46 +++++++++++++++++------------------------- 3 files changed, 44 insertions(+), 73 deletions(-) diff --git a/commit_check/author.py b/commit_check/author.py index 74946a8d..af6be064 100644 --- a/commit_check/author.py +++ b/commit_check/author.py @@ -23,23 +23,12 @@ def _get_author_value(check_type: str) -> str: return str(get_commit_info(format_str)) -def _evaluate_check(check: dict, value: str) -> int: - """Evaluate a single author check against the provided value.""" - regex = check.get("regex", "") - if regex == "": - print(f"{YELLOW}Not found regex for {check.get('check')}. skip checking.{RESET_COLOR}") - return PASS - - if re.match(regex, value) is None: - if not print_error_header.has_been_called: - print_error_header() - check_name = str(check.get("check", "")) - error_msg = str(check.get("error", "")) - print_error_message(check_name, regex, error_msg, value) - if check.get("suggest"): - print_suggestion(check["suggest"]) - return FAIL - return PASS +def _print_failure(check: dict, regex: str, actual: str) -> None: + if not print_error_header.has_been_called: + print_error_header() + print_error_message(check['check'], regex, check['error'], actual) + if check.get('suggest'): + print_suggestion(check['suggest']) def check_author(checks: list, check_type: str) -> int: @@ -58,4 +47,10 @@ def check_author(checks: list, check_type: str) -> int: return PASS value = _get_author_value(check_type) - return _evaluate_check(check, value) + + if re.match(regex, value): + return PASS + + _print_failure(check, regex, value) + + return FAIL diff --git a/commit_check/branch.py b/commit_check/branch.py index ff7c9af2..886fc673 100644 --- a/commit_check/branch.py +++ b/commit_check/branch.py @@ -1,19 +1,19 @@ """Check git branch naming convention.""" import re from commit_check import YELLOW, RESET_COLOR, PASS, FAIL -from commit_check.util import get_branch_name, git_merge_base, print_error_header, print_error_message, print_suggestion, has_commits +from commit_check.util import _find_check, get_branch_name, git_merge_base, print_error_header, print_error_message, print_suggestion, has_commits -def _find_branch_check(checks: list) -> dict | None: - """Return the first branch check config or None if not present.""" - for check in checks: - if check.get('check') == 'branch': - return check - return None +def _print_failure(check: dict, regex: str, actual: str) -> None: + if not print_error_header.has_been_called: + print_error_header() # pragma: no cover + print_error_message(check['check'], regex, check['error'], actual) + if check.get('suggest'): + print_suggestion(check['suggest']) def check_branch(checks: list) -> int: - check = _find_branch_check(checks) + check = _find_check(checks, 'branch') if not check: return PASS @@ -28,14 +28,7 @@ def check_branch(checks: list) -> int: if re.match(regex, branch_name): return PASS - if not print_error_header.has_been_called: - print_error_header() # pragma: no cover - print_error_message( - check['check'], regex, - check['error'], branch_name, - ) - if check.get('suggest'): - print_suggestion(check['suggest']) + _print_failure(check, regex, branch_name) return FAIL @@ -49,11 +42,11 @@ def check_merge_base(checks: list) -> int: return PASS # pragma: no cover # locate merge_base rule, if any - merge_check = next((c for c in checks if c.get('check') == 'merge_base'), None) - if not merge_check: + check = _find_check(checks, 'merge_base') + if not check: return PASS - regex = merge_check.get('regex', "") + regex = check.get('regex', "") if regex == "": print( f"{YELLOW}Not found target branch for checking merge base. skip checking.{RESET_COLOR}", @@ -66,12 +59,5 @@ def check_merge_base(checks: list) -> int: if result == 0: return PASS - if not print_error_header.has_been_called: - print_error_header() # pragma: no cover - print_error_message( - merge_check['check'], regex, - merge_check['error'], current_branch, - ) - if merge_check.get('suggest'): - print_suggestion(merge_check['suggest']) + _print_failure(check, regex, current_branch) return FAIL diff --git a/commit_check/commit.py b/commit_check/commit.py index cc98d864..a821816f 100644 --- a/commit_check/commit.py +++ b/commit_check/commit.py @@ -10,6 +10,20 @@ def _load_imperatives() -> set: """Load imperative verbs from imperatives module.""" return IMPERATIVES +def _ensure_msg_file(commit_msg_file: str | None) -> str: + """Return a commit message file path, falling back to the default when empty.""" + if not commit_msg_file: + return get_default_commit_msg_file() + return commit_msg_file + + +def _print_failure(check: dict, regex: str, actual: str) -> None: + if not print_error_header.has_been_called: + print_error_header() # pragma: no cover + print_error_message(check['check'], regex, check['error'], actual) + if check.get('suggest'): + print_suggestion(check['suggest']) + def get_default_commit_msg_file() -> str: """Get the default commit message file.""" @@ -26,22 +40,6 @@ def read_commit_msg(commit_msg_file) -> str: # Commit message is composed by subject and body return str(get_commit_info("s") + "\n\n" + get_commit_info("b")) - -def _ensure_msg_file(commit_msg_file: str | None) -> str: - """Return a commit message file path, falling back to the default when empty.""" - if not commit_msg_file: - return get_default_commit_msg_file() - return commit_msg_file - - -def _print_failure(check: dict, regex: str, actual: str) -> None: - if not print_error_header.has_been_called: - print_error_header() # pragma: no cover - print_error_message(check['check'], regex, check['error'], actual) - if check.get('suggest'): - print_suggestion(check['suggest']) - - def check_commit_msg(checks: list, commit_msg_file: str = "") -> int: """Check commit message against the provided checks.""" if has_commits() is False: @@ -49,7 +47,7 @@ def check_commit_msg(checks: list, commit_msg_file: str = "") -> int: check = _find_check(checks, 'message') if not check: - return PASS + return PASS # pragma: no cover regex = check.get('regex', "") if regex == "": @@ -72,7 +70,7 @@ def check_commit_signoff(checks: list, commit_msg_file: str = "") -> int: check = _find_check(checks, 'commit_signoff') if not check: - return PASS + return PASS # pragma: no cover regex = check.get('regex', "") if regex == "": @@ -93,11 +91,7 @@ def check_commit_signoff(checks: list, commit_msg_file: str = "") -> int: if re.search(regex, commit_msg): return PASS - if not print_error_header.has_been_called: - print_error_header() # pragma: no cover - print_error_message(check['check'], regex, check['error'], commit_hash) - if check.get('suggest'): - print_suggestion(check['suggest']) + _print_failure(check, regex, commit_hash) return FAIL @@ -127,11 +121,7 @@ def check_imperative(checks: list, commit_msg_file: str = "") -> int: if _is_imperative(description): return PASS - if not print_error_header.has_been_called: - print_error_header() # pragma: no cover - print_error_message(check['check'], 'imperative mood pattern', check['error'], subject) - if check.get('suggest'): - print_suggestion(check['suggest']) + _print_failure(check, 'imperative mood pattern', subject) return FAIL From bfb2edbb54ee9dd2c0fb6aedf87edf27c9048a1e Mon Sep 17 00:00:00 2001 From: shenxianpeng Date: Tue, 9 Sep 2025 02:36:14 +0300 Subject: [PATCH 4/6] refactor: add _print_failure to util --- commit_check/author.py | 12 +----------- commit_check/branch.py | 10 +--------- commit_check/commit.py | 10 +--------- commit_check/util.py | 13 +++++++++++++ tests/author_test.py | 8 ++++---- tests/branch_test.py | 8 ++++---- tests/commit_test.py | 2 +- 7 files changed, 25 insertions(+), 38 deletions(-) diff --git a/commit_check/author.py b/commit_check/author.py index af6be064..f0a1eec4 100644 --- a/commit_check/author.py +++ b/commit_check/author.py @@ -4,10 +4,8 @@ from commit_check.util import ( get_commit_info, has_commits, - print_error_header, - print_error_message, - print_suggestion, _find_check, + _print_failure, ) @@ -23,14 +21,6 @@ def _get_author_value(check_type: str) -> str: return str(get_commit_info(format_str)) -def _print_failure(check: dict, regex: str, actual: str) -> None: - if not print_error_header.has_been_called: - print_error_header() - print_error_message(check['check'], regex, check['error'], actual) - if check.get('suggest'): - print_suggestion(check['suggest']) - - def check_author(checks: list, check_type: str) -> int: """Validate author name or email according to configured regex.""" if has_commits() is False: diff --git a/commit_check/branch.py b/commit_check/branch.py index 886fc673..2436967e 100644 --- a/commit_check/branch.py +++ b/commit_check/branch.py @@ -1,15 +1,7 @@ """Check git branch naming convention.""" import re from commit_check import YELLOW, RESET_COLOR, PASS, FAIL -from commit_check.util import _find_check, get_branch_name, git_merge_base, print_error_header, print_error_message, print_suggestion, has_commits - - -def _print_failure(check: dict, regex: str, actual: str) -> None: - if not print_error_header.has_been_called: - print_error_header() # pragma: no cover - print_error_message(check['check'], regex, check['error'], actual) - if check.get('suggest'): - print_suggestion(check['suggest']) +from commit_check.util import _find_check, _print_failure, get_branch_name, git_merge_base, has_commits def check_branch(checks: list) -> int: diff --git a/commit_check/commit.py b/commit_check/commit.py index a821816f..14f5747a 100644 --- a/commit_check/commit.py +++ b/commit_check/commit.py @@ -2,7 +2,7 @@ import re from pathlib import PurePath from commit_check import YELLOW, RESET_COLOR, PASS, FAIL -from commit_check.util import _find_check, cmd_output, get_commit_info, print_error_header, print_error_message, print_suggestion, has_commits +from commit_check.util import _find_check, _print_failure, cmd_output, get_commit_info, has_commits from commit_check.imperatives import IMPERATIVES @@ -17,14 +17,6 @@ def _ensure_msg_file(commit_msg_file: str | None) -> str: return commit_msg_file -def _print_failure(check: dict, regex: str, actual: str) -> None: - if not print_error_header.has_been_called: - print_error_header() # pragma: no cover - print_error_message(check['check'], regex, check['error'], actual) - if check.get('suggest'): - print_suggestion(check['suggest']) - - def get_default_commit_msg_file() -> str: """Get the default commit message file.""" git_dir = cmd_output(['git', 'rev-parse', '--git-dir']).strip() diff --git a/commit_check/util.py b/commit_check/util.py index 3f5595ae..18b874e1 100644 --- a/commit_check/util.py +++ b/commit_check/util.py @@ -20,6 +20,19 @@ def _find_check(checks: list, check_type: str) -> dict | None: return None +def _print_failure( + check: dict, + regex: str, + actual: str +) -> None: + """Print a standardized failure message.""" + if not print_error_header.has_been_called: + print_error_header() + print_error_message(check['check'], regex, check['error'], actual) + if check.get('suggest'): + print_suggestion(check['suggest']) + + def get_branch_name() -> str: """Identify current branch name. .. note:: diff --git a/tests/author_test.py b/tests/author_test.py index fcc49391..30bad283 100644 --- a/tests/author_test.py +++ b/tests/author_test.py @@ -131,10 +131,10 @@ def test_check_author_with_result_none(self, mocker): return_value=None ) m_print_error_message = mocker.patch( - f"{LOCATION}.print_error_message" + "commit_check.util.print_error_message" ) m_print_suggestion = mocker.patch( - f"{LOCATION}.print_suggestion" + "commit_check.util.print_suggestion" ) retval = check_author(checks, "author_name") assert retval == FAIL @@ -246,10 +246,10 @@ def test_check_author_with_result_none(self, mocker): return_value=None ) m_print_error_message = mocker.patch( - f"{LOCATION}.print_error_message" + "commit_check.util.print_error_message" ) m_print_suggestion = mocker.patch( - f"{LOCATION}.print_suggestion" + "commit_check.util.print_suggestion" ) retval = check_author(checks, "author_email") assert retval == FAIL diff --git a/tests/branch_test.py b/tests/branch_test.py index 34e3a3b6..580cc1fe 100644 --- a/tests/branch_test.py +++ b/tests/branch_test.py @@ -107,10 +107,10 @@ def test_check_branch_with_result_none(self, mocker): return_value=None ) m_print_error_message = mocker.patch( - f"{LOCATION}.print_error_message" + "commit_check.util.print_error_message" ) m_print_suggestion = mocker.patch( - f"{LOCATION}.print_suggestion" + "commit_check.util.print_suggestion" ) retval = check_branch(checks) assert retval == FAIL @@ -160,8 +160,8 @@ def test_check_merge_base_fail_with_messages(self, mocker, capfd): "suggest": "Please rebase" }] mocker.patch(f"{LOCATION}.check_merge_base", return_value=1) - m_print_error = mocker.patch(f"{LOCATION}.print_error_message") - m_print_suggest = mocker.patch(f"{LOCATION}.print_suggestion") + m_print_error = mocker.patch("commit_check.util.print_error_message") + m_print_suggest = mocker.patch("commit_check.util.print_suggestion") retval = check_merge_base(checks) assert retval == FAIL diff --git a/tests/commit_test.py b/tests/commit_test.py index 2cabfb3f..2e9f98f9 100644 --- a/tests/commit_test.py +++ b/tests/commit_test.py @@ -5,7 +5,7 @@ # used by get_commit_info mock FAKE_BRANCH_NAME = "fake_commits_info" # The location of check_commit_msg() -LOCATION = "commit_check.commit" +LOCATION = "commit_check.util" # Commit message file MSG_FILE = '.git/COMMIT_EDITMSG' From bccd3dc01ccba60921ecac2cddcca4fb42742644 Mon Sep 17 00:00:00 2001 From: Xianpeng Shen Date: Tue, 9 Sep 2025 02:44:20 +0300 Subject: [PATCH 5/6] Update commit_check/util.py Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- commit_check/util.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/commit_check/util.py b/commit_check/util.py index 18b874e1..b1665d99 100644 --- a/commit_check/util.py +++ b/commit_check/util.py @@ -28,9 +28,9 @@ def _print_failure( """Print a standardized failure message.""" if not print_error_header.has_been_called: print_error_header() - print_error_message(check['check'], regex, check['error'], actual) + print_error_message(check['check'], regex, check.get('error', ''), actual) if check.get('suggest'): - print_suggestion(check['suggest']) + print_suggestion(check.get('suggest')) def get_branch_name() -> str: From 8a4161e3477c3f19744fa1b3eb90d54a330dc778 Mon Sep 17 00:00:00 2001 From: shenxianpeng Date: Tue, 9 Sep 2025 02:51:46 +0300 Subject: [PATCH 6/6] fix: update util to pass lint --- commit_check/util.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/commit_check/util.py b/commit_check/util.py index b1665d99..ca62d63c 100644 --- a/commit_check/util.py +++ b/commit_check/util.py @@ -180,7 +180,7 @@ def print_error_message(check_type: str, regex: str, error: str, reason: str): print(error) -def print_suggestion(suggest: str) -> None: +def print_suggestion(suggest: str | None) -> None: """Print suggestion to user :param suggest: what message to print out """