File size: 4,449 Bytes
b5f15bd
08b2a3e
 
 
 
 
 
 
 
 
 
71eab75
 
 
 
08b2a3e
5f81170
08b2a3e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3092d65
08b2a3e
 
 
 
 
 
 
 
3092d65
08b2a3e
9193632
08b2a3e
 
 
 
 
 
90a36fc
08b2a3e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3092d65
08b2a3e
3092d65
08b2a3e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3092d65
08b2a3e
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
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)
        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()