-
Notifications
You must be signed in to change notification settings - Fork 17
/
git_metrics.py
139 lines (120 loc) · 5.77 KB
/
git_metrics.py
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
"""Calculate age of commits in open remote branches
Usage:
git_metrics.py open-branches [--master-branch=<branch>] <path_to_git_repo>
git_metrics.py open-branches [--master-branch=<branch>] --plot <path_to_git_repo>
git_metrics.py release-lead-time [--tag-pattern=<fn_match>] [--earliest-date=<timestamp>] <path_to_git_repo>
git_metrics.py release-lead-time --plot [--tag-pattern=<fn_match>] <path_to_git_repo>
git_metrics.py plot --open-branches <csv_file>
git_metrics.py plot --release-lead-time <csv_file>
git_metrics.py batch --open-branches <path_to_git_repos>...
git_metrics.py batch --release-lead-time [--earliest-date=<timestamp>] <path_to_git_repos>...
git_metrics.py (-h | --help)
Options:
--master-branch=<branch> example: origin/gh-pages
"""
import time
from fnmatch import fnmatch
from functools import partial
import csv
import os
import docopt
import sys
from git_metrics_open_branches import plot_open_branches_metrics
from git_metrics_open_branches import get_branches
from git_metrics_open_branches import commit_author_time_and_branch_ref
from git_metrics_release_lead_time import commit_author_time_tag_author_time_and_from_to_tag_name
from git_metrics_release_lead_time import plot_release_lead_time_metrics
from process import mk_run
def read_open_branches_csv_file(filename):
with open(filename) as csv_file:
reader = csv.reader(csv_file, delimiter=',')
yield from ((int(n), int(t), b, repo_name) for n, t, b, repo_name in reader if n.isdigit())
def write_open_branches_csv_file(data):
writer = csv.writer(sys.stdout, delimiter=',', lineterminator='\n')
writer.writerow(("query timestamp", "commit timestamp", "branch name", "repo name"))
writer.writerows(data)
def read_release_lead_time_csv_file(filename):
with open(filename) as csv_file:
reader = csv.reader(csv_file, delimiter=',')
yield from ((int(n), int(t), tag1, tag2, repo_name) for n, t, tag1, tag2, repo_name in reader if n.isdigit())
def write_release_lead_time_csv_file(data):
writer = csv.writer(sys.stdout, delimiter=',', lineterminator='\n')
writer.writerow(("commit timestamp", "tag timestamp", "previous release tag", "release tag", "repo name"))
writer.writerows(data)
def main():
flags = docopt.docopt(__doc__)
now = int(time.time())
if flags['<path_to_git_repo>']:
path_to_git_repo = flags['<path_to_git_repo>']
repo_name = os.path.basename(os.path.abspath(path_to_git_repo))
run = mk_run(path_to_git_repo)
if flags["open-branches"]:
master_branch = flags['--master-branch'] or 'origin/master'
assert_master_branch(run, master_branch)
gen = commit_author_time_and_branch_ref(run, master_branch)
data = ((now, t, b, repo_name) for t, b in gen)
if flags['--plot']:
plot_open_branches_metrics(data)
else:
write_open_branches_csv_file(data)
elif flags["release-lead-time"]:
earliest_date = int(flags["--earliest-date"] or 0)
pattern = flags['--tag-pattern'] or '*'
gen = commit_author_time_tag_author_time_and_from_to_tag_name(
run,
partial(fnmatch, pat=pattern),
earliest_date,
)
data = ((cat, tat, old_tag, tag, repo_name) for cat, tat, old_tag, tag in gen)
if flags['--plot']:
plot_release_lead_time_metrics(data)
else:
write_release_lead_time_csv_file(data)
if flags["plot"]:
if flags["--open-branches"]:
data = read_open_branches_csv_file(flags["<csv_file>"])
plot_open_branches_metrics(data)
elif flags["--release-lead-time"]:
data = read_release_lead_time_csv_file(flags["<csv_file>"])
plot_release_lead_time_metrics(data)
elif flags["batch"] and flags["--open-branches"]:
for path_to_git_repo in flags['<path_to_git_repos>']:
print("checking master branch in repo:", path_to_git_repo, file=sys.stderr)
run = mk_run(path_to_git_repo)
assert_master_branch(run, 'origin/master')
data = []
for path_to_git_repo in flags['<path_to_git_repos>']:
print("fetching data from in repo:", path_to_git_repo, file=sys.stderr)
repo_name = os.path.basename(os.path.abspath(path_to_git_repo))
run = mk_run(path_to_git_repo)
gen = commit_author_time_and_branch_ref(run, 'origin/master')
data.extend((now, t, b, repo_name) for t, b in gen)
write_open_branches_csv_file(data)
elif flags["batch"] and flags["--release-lead-time"]:
earliest_date = int(flags["--earliest-date"] or 0)
data = []
for path_to_git_repo in flags['<path_to_git_repos>']:
print("fetching data from in repo:", path_to_git_repo, file=sys.stderr)
repo_name = os.path.basename(os.path.abspath(path_to_git_repo))
run = mk_run(path_to_git_repo)
gen = commit_author_time_tag_author_time_and_from_to_tag_name(
run,
lambda _: True,
earliest_date=earliest_date
)
data.extend((cat, tat, old_tag, tag, repo_name) for cat, tat, old_tag, tag in gen)
write_release_lead_time_csv_file(data)
def assert_master_branch(run, master_branch):
branches = list(get_branches(run))
if not any(branch.endswith(master_branch) for branch in branches):
error = partial(print, file=sys.stderr)
error(f"branch {master_branch} does not exist")
error()
error(f"try one of:")
for branch in branches:
error(branch)
error()
error("use -h for more help")
exit(1)
if __name__ == "__main__":
main()