init: pristine aerc 0.20.0 source
This commit is contained in:
Executable
+122
@@ -0,0 +1,122 @@
|
||||
#!/usr/bin/env python3
|
||||
# SPDX-License-Identifier: MIT
|
||||
# Copyright (c) 2023 Bence Ferdinandy <bence@ferdinandy.com>
|
||||
|
||||
"""
|
||||
Create graphs about development statistics of releases.
|
||||
"""
|
||||
|
||||
from datetime import date
|
||||
from subprocess import check_output
|
||||
|
||||
from matplotlib import pyplot as plt
|
||||
|
||||
|
||||
def git(*args):
|
||||
return check_output(["git"] + list(args)).decode("utf-8").strip()
|
||||
|
||||
|
||||
def stats():
|
||||
"""
|
||||
Returns statistics from the git repo:
|
||||
|
||||
tags: sorted list of minor version tags (assumes semver)
|
||||
The first element is the hash of the first commit, last element is HEAD. All
|
||||
the other return values are one shorter as, there's no statistics returned for
|
||||
the first commit.
|
||||
counts: number of commits (between this and the previous release)
|
||||
dates: dates of the releases
|
||||
files: number of files changed (between this and the previous release)
|
||||
inserts: number of lines inserted (between this and the previous release)
|
||||
deletions: number of lines deleted (between this and the previous release)
|
||||
"""
|
||||
|
||||
tags = git("tag").split("\n")
|
||||
tags = [t for t in tags if t.split(".")[-1] == "0"] # drop patch versions
|
||||
tags = sorted(tags, key=lambda x: [int(t) for t in x.split(".")])
|
||||
first_commit = git("rev-list", "--max-parents=0", "HEAD")
|
||||
tags = [first_commit] + tags + ["HEAD"]
|
||||
counts = []
|
||||
dates = []
|
||||
files = []
|
||||
inserts = []
|
||||
deletions = []
|
||||
for i, t in enumerate(tags[:-1]):
|
||||
counts.append(int(git("rev-list", f"{t}..{tags[i+1]}", "--count")))
|
||||
dates.append(
|
||||
date.fromisoformat(
|
||||
git("show", "-s", "--format=%cs", tags[i + 1]).split("\n")[-1]
|
||||
)
|
||||
)
|
||||
statline = git("diff", "--stat", t, tags[i + 1]).split("\n")[-1]
|
||||
fnum, _, _, ins, _, dels, _ = statline.split()
|
||||
files.append(int(fnum))
|
||||
inserts.append(int(ins))
|
||||
deletions.append(int(dels))
|
||||
return tags, counts, dates, files, inserts, deletions
|
||||
|
||||
|
||||
def main(output):
|
||||
tags, counts, dates, files, inserts, deletions = stats()
|
||||
|
||||
fig, (ax1, ax2) = plt.subplots(2, figsize=(8, 11))
|
||||
fig.suptitle("aerc release statistics", fontweight="bold")
|
||||
# commit counts subplot
|
||||
ax1.plot(dates, counts, "o-")
|
||||
|
||||
# alternate placement of text above and below for readability
|
||||
text_y = []
|
||||
for i, t in enumerate(tags[1:]):
|
||||
downpad = 25 if len(t) == 5 else 30
|
||||
p = counts[i] + (-1) ** (i + 1) * 10 - (i + 1) % 2 * downpad
|
||||
if p < 5:
|
||||
p = counts[i] + 10
|
||||
text_y.append(p)
|
||||
for i, t in enumerate(tags[1:]):
|
||||
ax1.text(
|
||||
dates[i],
|
||||
text_y[i],
|
||||
t,
|
||||
horizontalalignment="center",
|
||||
rotation="vertical",
|
||||
)
|
||||
ax1.set_ylabel("# of commits")
|
||||
ax1.set_ylim(bottom=0)
|
||||
ax1.set_title("commits per release")
|
||||
|
||||
# lines added/deleted subplot
|
||||
#
|
||||
ax2.plot(dates, inserts, "o-", label="insertions(+)", color="green")
|
||||
ax2.plot(dates, deletions, "o-.", label="deletions(-)", color="red")
|
||||
ax2.set_ylabel("# of lines")
|
||||
ax2.legend(loc="upper left")
|
||||
ax2.set_ylim(top=max(max(inserts), max(deletions)) + 2000)
|
||||
for i, t in enumerate(tags[1:]):
|
||||
ax2.text(
|
||||
dates[i],
|
||||
max(inserts[i], deletions[i]) + 500,
|
||||
t,
|
||||
horizontalalignment="center",
|
||||
rotation="vertical",
|
||||
)
|
||||
ax2.set_xlabel("date")
|
||||
ax2.set_title("insertion/deletions per release")
|
||||
plt.tight_layout()
|
||||
plt.savefig(output, dpi=300)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
import argparse
|
||||
|
||||
parser = argparse.ArgumentParser(description=__doc__)
|
||||
parser.add_argument(
|
||||
"-o",
|
||||
"--output",
|
||||
default="aerc-release-stats.png",
|
||||
help="""
|
||||
Path to output image (defaults to 'aerc-release-stats.png',
|
||||
respects file extensions via matplotlib)
|
||||
""",
|
||||
)
|
||||
args = parser.parse_args()
|
||||
main(args.output)
|
||||
Reference in New Issue
Block a user