diff --git a/scantags.py b/scantags.py index dd1dc1d..72b4335 100644 --- a/scantags.py +++ b/scantags.py @@ -2,9 +2,13 @@ Scan a repo such as https://github.com/os-autoinst/os-autoinst-distri-opensuse for tags """ +import contextlib import fnmatch +import logging import os import re +import shlex +import subprocess import sys from typing import Generator @@ -12,6 +16,24 @@ LINE_PATTERN = r"record_soft_failure.*?((?:bsc|poo)#[0-9]+|(?:gh|gl|gsd)#[^#]+#[0-9]+)" +def git_blame(file: str, line_number: int) -> str | None: + """ + Run git blame and return the e-mail + """ + cmd = f"git blame --porcelain -L {line_number},{line_number} {file}" + try: + output = subprocess.check_output( + shlex.split(cmd), shell=False, universal_newlines=True + ) + except subprocess.CalledProcessError as exc: + logging.error("%s: %s", file, exc) + return None + for line in output.splitlines(): + if "@" in line: + return line.split()[1] + return "unknown" + + def recursive_grep( directory: str, pattern: str, file_pattern: str = "*" ) -> Generator[tuple[str, int, str], None, None]: @@ -37,6 +59,8 @@ def scan_tags(directory: str) -> dict[str, dict[str, str | int]]: """ tags: dict[str, dict[str, str | int]] = {} for file, line_number, tag in recursive_grep(directory, LINE_PATTERN, FILE_PATTERN): + author = git_blame(file, line_number) + print(tag, file, line_number, author) if tag not in tags: tags[tag] = {} tags[tag] |= {"file": file, "lineno": line_number} @@ -47,10 +71,8 @@ def main(): """ Main """ - for file, line_number, tag in recursive_grep( - sys.argv[1], LINE_PATTERN, FILE_PATTERN - ): - print(file, line_number, tag) + with contextlib.chdir(sys.argv[1]): + scan_tags(sys.argv[1]) if __name__ == "__main__":