| 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()) |
| 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]): |
| |
| 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() |
|
|