From c3b7fff4a8e5f205304df51625475b1835b6a0da Mon Sep 17 00:00:00 2001 From: timofey Date: Fri, 16 Jun 2023 21:08:03 +0000 Subject: [PATCH] metrics --- .gitignore | 162 ++++++++++++++++++++++++++++++++++++++++++ .vscode/settings.json | 3 + README.md | 3 + docker-compose.yml | 6 ++ metrics/Dockerfile | 14 ++++ metrics/metrics.py | 26 +++++++ metrics/render.py | 19 +++++ radn-rs/Dockerfile | 1 + 8 files changed, 234 insertions(+) create mode 100644 .gitignore create mode 100644 .vscode/settings.json create mode 100644 metrics/Dockerfile create mode 100644 metrics/metrics.py create mode 100644 metrics/render.py diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..56615bc --- /dev/null +++ b/.gitignore @@ -0,0 +1,162 @@ +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +share/python-wheels/ +*.egg-info/ +.installed.cfg +*.egg +MANIFEST + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.nox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +*.py,cover +.hypothesis/ +.pytest_cache/ +cover/ + +# Translations +*.mo +*.pot + +# Django stuff: +*.log +local_settings.py +db.sqlite3 +db.sqlite3-journal + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# PyBuilder +.pybuilder/ +target/ + +# Jupyter Notebook +.ipynb_checkpoints + +# IPython +profile_default/ +ipython_config.py + +# pyenv +# For a library or package, you might want to ignore these files since the code is +# intended to run in multiple environments; otherwise, check them in: +# .python-version + +# pipenv +# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. +# However, in case of collaboration, if having platform-specific dependencies or dependencies +# having no cross-platform support, pipenv may install dependencies that don't work, or not +# install all needed dependencies. +#Pipfile.lock + +# poetry +# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control. +# This is especially recommended for binary packages to ensure reproducibility, and is more +# commonly ignored for libraries. +# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control +#poetry.lock + +# pdm +# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control. +#pdm.lock +# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it +# in version control. +# https://pdm.fming.dev/#use-with-ide +.pdm.toml + +# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm +__pypackages__/ + +# Celery stuff +celerybeat-schedule +celerybeat.pid + +# SageMath parsed files +*.sage.py + +# Environments +.env +.venv +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ + +# Spyder project settings +.spyderproject +.spyproject + +# Rope project settings +.ropeproject + +# mkdocs documentation +/site + +# mypy +.mypy_cache/ +.dmypy.json +dmypy.json + +# Pyre type checker +.pyre/ + +# pytype static type analyzer +.pytype/ + +# Cython debug symbols +cython_debug/ + +# PyCharm +# JetBrains specific template is maintained in a separate JetBrains.gitignore that can +# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore +# and can be added to the global gitignore or merged into this file. For a more nuclear +# option (not recommended) you can uncomment the following to ignore the entire idea folder. +#.idea/ + +metrics.png diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..457f44d --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "python.analysis.typeCheckingMode": "basic" +} \ No newline at end of file diff --git a/README.md b/README.md index 74293a5..11dc075 100644 --- a/README.md +++ b/README.md @@ -2,3 +2,6 @@ cd /code/ git clone --recurse-submodules https://gitea.parrrate.ru/PTV/radn-rs.git ``` +```sh +clear && docker compose up -d --build metrics && docker cp radn-metrics:/code/metrics.png ./metrics/metrics.png +``` diff --git a/docker-compose.yml b/docker-compose.yml index 286ca3c..316b176 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -65,3 +65,9 @@ services: networks: radn: {} v6d: {} + metrics: + container_name: radn-metrics + build: + context: metrics + tty: true + stop_signal: SIGKILL diff --git a/metrics/Dockerfile b/metrics/Dockerfile new file mode 100644 index 0000000..118e89c --- /dev/null +++ b/metrics/Dockerfile @@ -0,0 +1,14 @@ +FROM rust:1.70 as metrics +RUN cargo install rust-code-analysis-cli +WORKDIR /code/ +RUN git clone https://gitea.parrrate.ru/PTV/radn-rs.git +WORKDIR /code/radn-rs/ +RUN git fetch && git checkout a89fd3416cb1eb9b0d34fc514d79cbf85b0e856a +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/metrics/metrics.py b/metrics/metrics.py new file mode 100644 index 0000000..62c8f38 --- /dev/null +++ b/metrics/metrics.py @@ -0,0 +1,26 @@ +import json +from subprocess import check_output + + +def filter_schema(obj, schema): + if schema is True: + return obj + return {key: filter_schema(obj[key], value) for key, value in schema.items()} + + +entry_schema = {"metrics": {"halstead": {"bugs": True, "difficulty": True}}} + +commits = check_output(['git', 'log', '--pretty=%H'], text=True).splitlines() +entries = [] +for (i, commit) in enumerate(commits): + print('running', commit) + check_output(['git', 'checkout', commit], text=True) + lines = check_output( + ["rust-code-analysis-cli", "-m", "-p", "src", "-O", "json"], text=True + ).splitlines() + print(len(lines)) + for line in lines: + entry = json.loads(line) + entries.append((i, filter_schema(entry, entry_schema))) +with open('/code/metrics.json', 'w') as file: + json.dump(entries, file) diff --git a/metrics/render.py b/metrics/render.py new file mode 100644 index 0000000..f658970 --- /dev/null +++ b/metrics/render.py @@ -0,0 +1,19 @@ +import gc +import json + +import matplotlib.pyplot as plt +import numpy as np + +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: + entries = json.load(file) + +units = [] +for i, entry in entries: + units.append((i, entry["metrics"]["halstead"]["difficulty"] or 0.0, entry["metrics"]["halstead"]["bugs"] or 0.0)) +X, Y, C = np.array(units).transpose() +plt.scatter(-X, Y, s=2.0, c=C) +plt.savefig('/code/metrics.png') diff --git a/radn-rs/Dockerfile b/radn-rs/Dockerfile index 699bfee..e8712c1 100644 --- a/radn-rs/Dockerfile +++ b/radn-rs/Dockerfile @@ -4,6 +4,7 @@ RUN cargo install cargo-watch RUN rustup component add rustfmt RUN rustup component add clippy RUN cargo install mdbook +RUN cargo install rust-code-analysis-cli RUN apt-get update RUN apt-get install -y cloc