import tempfile import gradio as gr from git import Repo, Git import datetime import argparse from collections import Counter import os def greet(name): with tempfile.TemporaryDirectory() as d: Repo.clone_from(name, d, branch="main") repo = Repo(d) for commit in repo.iter_commits(): print(commit) return check_repo(d, datetime.datetime(2022, 1, 1), 10) def check(): parser = argparse.ArgumentParser( prog = 'ProgramName', description = 'What the program does', epilog = 'Text at the bottom of help') parser.add_argument('repo', nargs='?', default=default_repo()) # option that takes a value parser.add_argument('--since', type=lambda d: datetime.datetime.strptime(d, '%Y-%m-%d'), default=None, help='Set a start date') parser.add_argument('--filter', type=lambda d: d.split(","), default=None, help='Set a comma separated filter') parser.add_argument('--mincount', type=int, default=10, help='Set a comma separated filter') args = parser.parse_args() if "/" not in args.repo: args.repo = f"/home/nicolas/src/{args.repo}" with cd(args.repo): check_repo(args.repo, args.since, args.mincount) class cd: """Context manager for changing the current working directory""" def __init__(self, newPath): self.newPath = os.path.expanduser(newPath) def __enter__(self): self.savedPath = os.getcwd() os.chdir(self.newPath) def __exit__(self, etype, value, traceback): os.chdir(self.savedPath) def default_repo(): return os.getcwd() def check_repo(repo_path, since, mincount, filter_=None): most_common = 10 bugwords = [("revert", 1), ("bug", 1), ("fix", 1)] repo = Repo(repo_path) c = Counter() git = Git() commits = [] for commit in repo.iter_commits(): if since and commit.committed_datetime < since.astimezone(): break commits.append(commit.hexsha[:8]) files = Counter() bugfiles = Counter() current_commit = 0 current_files = [] out = git.show('--stat', '--oneline', '--name-only', f"{commits[-1]}..") is_bug = 0 for i, line in enumerate(out.split("\n")): line = line.strip() if not line: continue if line.startswith(commits[current_commit]): # files[commits[current_commit]] = files.copy() commit, message = line.lower().split(" ", 1) found = False for (bugword, count) in bugwords: if bugword in message: is_bug = count found = True break if not found: is_bug = 0 current_commit += 1 else: found = True if filter_: found = False for filter_ in filter_: if filter_ in line: found = True break if not found: continue files[line] += 1 if is_bug: bugfiles[line] += is_bug string = "" string += "=====" + "\n" string += "Most commonly changed files" + "\n" string += + "\n" for (filename, count) in files.most_common(most_common): string += f"{filename}: {count}" + "\n" string += + "\n" string += + "\n" string += "=====" + "\n" string += "Most commonly bugged files" + "\n" for (filename, count) in bugfiles.most_common(most_common): string += f"{filename}: {count}" + "\n" string += + "\n" string += + "\n" string += "=====" + "\n" string += "Most commonly bugged files (adjusted)" + "\n" adjusted = {} for (filename, count) in bugfiles.items(): if count < mincount: continue percentage = count / files[filename] adjusted[filename] = (percentage, count) for (filename, (percentage, count)) in sorted(adjusted.items(), key=lambda x: x[1], reverse=True)[:most_common]: string += f"{filename}: {percentage} ({count})" + "\n" return string iface = gr.Interface(fn=greet, inputs="text", outputs="text") iface.launch()