diff --git a/.vscode/settings.json b/.vscode/settings.json index 752f527..6c48529 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,11 +1,5 @@ { "python.analysis.typeCheckingMode": "basic", - "python.formatting.blackArgs": [ - "--line-length", - "120" - ], - "isort.args": [ - "--profile", - "black" - ] -} \ No newline at end of file + "python.formatting.blackArgs": ["--line-length", "120"], + "isort.args": ["--profile", "black"] +} diff --git a/xmetrics/Dockerfile b/xmetrics/Dockerfile new file mode 100644 index 0000000..f1cf677 --- /dev/null +++ b/xmetrics/Dockerfile @@ -0,0 +1,35 @@ +FROM python:3.11 as metrics-base +WORKDIR /code/ + +FROM metrics-base as metrics-tmg +RUN git clone https://github.com/OnGoTeam/TMGmod.git +WORKDIR /code/TMGmod/ +RUN git fetch && git checkout 82db35f2db92572c98d84ef781f64f8d65d2f023 +ENV SRCDIR="build/src" +ENV SRCPATTERN="*.cs" + +FROM metrics-base as metrics-radn +RUN git clone https://gitea.parrrate.ru/PTV/radn-rs.git +WORKDIR /code/radn-rs/ +RUN git fetch && git checkout a60e4f09e0463b3b2fc0f91b21c9928d98d03213 + +FROM metrics-base as metrics-mdbook +RUN git clone https://github.com/rust-lang/mdBook.git +WORKDIR /code/mdBook/ +RUN git fetch && git checkout 904aa530b5f59387f19feb0dbe0e959de3f247d2 + +FROM metrics-base as metrics-rustup +RUN git clone https://github.com/rust-lang/rustup.git +WORKDIR /code/rustup/ +RUN git fetch && git checkout 849adb7c1b8c97e4145e350a934c3a665f61798e + +FROM metrics-radn as metrics +COPY metrics.py /code/metrics.py +RUN python3 /code/metrics.py + +FROM python:3.11 +RUN python3 -m pip install matplotlib +WORKDIR /code/ +COPY --from=metrics /code/metrics.json metrics.json +COPY render.py render.py +RUN python3 render.py diff --git a/xmetrics/docker-compose.yml b/xmetrics/docker-compose.yml new file mode 100644 index 0000000..6d3cb9c --- /dev/null +++ b/xmetrics/docker-compose.yml @@ -0,0 +1,6 @@ +services: + metrics: + container_name: temp-metrics + build: . + tty: true + stop_signal: SIGKILL diff --git a/xmetrics/metrics.py b/xmetrics/metrics.py new file mode 100644 index 0000000..c032c1d --- /dev/null +++ b/xmetrics/metrics.py @@ -0,0 +1,42 @@ +import json +import os +from collections import Counter +from pathlib import Path +from subprocess import check_output + +commits = check_output(["git", "log", "--pretty=%H", "--topo-order"], text=True).splitlines() +entries = [] +last_ctr = Counter() +last_cor = [] +cors = [] +for i, commit in enumerate(reversed(commits)): + print("running", commit) + check_output(["git", "checkout", commit], text=True) + current_ctr = Counter() + for path in Path(os.getenv("SRCDIR", "src")).rglob(os.getenv("SRCPATTERN", "*.rs")): + lines = path.read_bytes().splitlines() + lines = (line.strip() for line in lines) + lines = (line for line in lines if line) + current_ctr.update(lines) + added = current_ctr - last_ctr + deleted = last_ctr - current_ctr + entries.append((i, current_ctr.total(), added.total(), deleted.total())) + current_cor = [] + common_ctr = current_ctr & last_ctr + for j, line in reversed(last_cor): + if common_ctr[line]: + common_ctr[line] -= 1 + current_cor.append((j, line)) + current_cor.reverse() + for line in added.elements(): + current_cor.append((i, line)) + cor_ctr = Counter(j for j, _ in current_cor) + assert len(current_cor) == cor_ctr.total() == current_ctr.total() + cors.append([0] * i) + for j, cor in enumerate(cors): + cor.append(cor_ctr[j]) + last_ctr = current_ctr + last_cor = current_cor +print(sum(sum(cor) for cor in cors)) +with open("/code/metrics.json", "w") as file: + json.dump({"entries": entries, "cors": cors}, file) diff --git a/xmetrics/render.py b/xmetrics/render.py new file mode 100644 index 0000000..02de14a --- /dev/null +++ b/xmetrics/render.py @@ -0,0 +1,43 @@ +import json + +import matplotlib.pyplot as plt +import numpy as np +from matplotlib.colors import hsv_to_rgb + +plt.rcParams["figure.figsize"] = [18, 9] +plt.style.use("dark_background") +plt.subplots_adjust(left=0.05, right=0.99, top=0.95, bottom=0.05) + + +with open("metrics.json", "r") as file: + metrics = json.load(file) + entries = metrics["entries"] + cors = metrics["cors"] + + +def render_ploc(): + X, Y, Ya, Yd = np.array(entries).transpose() + plt.clf() + plt.plot(X, Y) + plt.fill_between(X, Y, Y - Ya, alpha=0.5, color="green") + plt.fill_between(X, Y, Y + Yd, alpha=0.5, color="red") + plt.savefig("/code/metrics.png") + + +def render_cors(): + N = len(cors[0]) + X = np.arange(N) + Y = np.array(cors) + plt.clf() + C = N + plt.stackplot( + X, + Y, + colors=[hsv_to_rgb((i / C, 0.25, 0.75)) for i in range(C)], + aa=False, + ) + plt.savefig("/code/metrics-cors.png") + + +render_ploc() +render_cors() diff --git a/xmetrics/render.sh b/xmetrics/render.sh new file mode 100755 index 0000000..0d8980f --- /dev/null +++ b/xmetrics/render.sh @@ -0,0 +1,6 @@ +clear +docker compose up -d --build metrics +mkdir metrics +docker cp temp-metrics:/code/metrics.png ./metrics/metrics.png +docker cp temp-metrics:/code/metrics-cors.png ./metrics/metrics-cors.png +docker compose down