Skip to content

Instantly share code, notes, and snippets.

@jesskfullwood
Created January 10, 2019 13:23
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jesskfullwood/17928e33ce9312e5281495214d7c73d3 to your computer and use it in GitHub Desktop.
Save jesskfullwood/17928e33ce9312e5281495214d7c73d3 to your computer and use it in GitHub Desktop.
librsvg oxidation chart
import json
import os
import re
import pandas
import matplotlib.pyplot as plt
import dateutil
from subprocess import run, PIPE
repo = "/home/jess/repo/librsvg"
tmp_csv = "/tmp/burndown.csv"
rx1 = re.compile("(\d+) insertions")
rx2 = re.compile("(\d+) deletions")
def inspect(info):
proc = run(["git", "show", "-s", "--format=%ci", "HEAD"], stdout=PIPE)
date = dateutil.parser.parse(proc.stdout)
date = date.replace(tzinfo=None)
proc = run(["git", "diff", "HEAD^", "HEAD", "--shortstat"], stdout=PIPE)
m1 = rx1.search(proc.stdout.decode("utf8"))
if m1:
addd = int(m1.groups(1)[0])
else:
addd = 0
m2 = rx2.search(proc.stdout.decode("utf8"))
if m2:
deld = int(m2.groups(1)[0])
else:
deld = 0
proc = run(["tokei", "-o", "json", "-t", "Rust,C,C Header"], stdout=PIPE)
out = json.loads(proc.stdout)
del out["C"]["stats"]
del out["CHeader"]["stats"]
try:
del out["Rust"]["stats"]
except KeyError:
# add the first non-rusty stats then reraise to catch in parent
info.append((date, out["C"]["lines"], 0, out["CHeader"]["lines"], addd, deld))
raise
info.append(
(
date,
out["C"]["lines"],
out["Rust"]["lines"],
out["CHeader"]["lines"],
addd,
deld,
)
)
def postprocess(df):
df.sort_index(inplace=True)
df.to_csv(tmp_csv)
ax = df[["C", "Rust", "CHeader"]].plot(title="librsvg burndown", drawstyle="steps")
ax.set_ylabel("LOC")
# df["Commit"] = 1
# df2 = df[["Added", "Deleted", "Commit"]].resample("D").sum().rolling("7D").mean()
# df2.plot(ax=ax, )
plt.show()
def new_run():
info = []
ct = 0
os.chdir(repo)
proc = run(["git", "checkout", "master"])
while True:
try:
inspect(info)
except KeyError:
break
ct += 1
print(ct)
_proc = run(["git", "checkout", "HEAD^"], stderr=PIPE)
assert _proc.returncode == 0
df = pandas.DataFrame.from_records(
info, "Date", columns=["Date", "C", "Rust", "CHeader", "Added", "Deleted"]
)
proc = run(["git", "checkout", "master"])
return df
if __name__ == "__main__":
try:
# delete tmp_csv file to re-run everything
df = pandas.read_csv(tmp_csv, index_col="Date", parse_dates=["Date"])
except:
df = new_run()
postprocess(df)
@jaccarmac
Copy link

May I cannibalize the code to generate a similar chart for Remacs? We like the chart over there and are working on tracking something similar for that project.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment