Skip to content

Commit

Permalink
Merge pull request #31 from gskorokhod/main
Browse files Browse the repository at this point in the history
Add essence-feature-usage-stats tool
  • Loading branch information
ozgurakgun authored Nov 4, 2023
2 parents a74c59e + a422de1 commit 9280d47
Show file tree
Hide file tree
Showing 26 changed files with 1,467 additions and 1 deletion.
7 changes: 7 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,10 @@ updates:
assignees:
- "ozgurakgun"

- package-ecosystem: "pip"
directory: "/tools/essence-feature-usage-stats/"
schedule:
interval: "weekly"
assignees:
- "ozgurakgun"

66 changes: 66 additions & 0 deletions .github/workflows/essence-feature-stats.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
name: "tools/essence-feature-stats - Deploy to Github Pages"

on:
push:
branches:
- main

env:
ESSENCE_DIR: "./EssenceCatalog"
CONJURE_DIR: "./conjure"
ESSENCE_EXAMPLES_REPO: "https://github.com/conjure-cp/EssenceCatalog.git"
CONJURE_REPO: "https://github.com/conjure-cp/conjure"
OUTPUT_PATH: "./web/static/index.html"
KEYWORD_BLOCKLIST: >
mInfo,finds,givens,enumGivens,enumLettings,lettings,
unnameds,strategyQ,Auto,Interactive,strategyA,trailCompact,
nameGenState,nbExtraGivens,representations,representationsTree,
originalDomains,trailGeneralised,trailVerbose,trailRewrites,
mLanguage,language,version,mStatements,Name,Declaration,Op
jobs:
build:
name: "tools/essence-feature-stats: Build the tool and clone EssenceCatalog repo"

runs-on: ubuntu-latest

strategy:
matrix:
python-version: ["3.11"]

permissions:
contents: write

steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Install Python ${{ matrix.python-version }}
uses: actions/setup-python@v4
with:
python-version: ${{ matrix.python-version }}

- name: Install python dependencies
run: pip install -r requirements.txt
working-directory: ./tools/essence-feature-usage-stats

- name: Run main.py to generate the table
run: python main.py
working-directory: ./tools/essence-feature-usage-stats

- name: Fix file permissions
run: chmod -v -R +rwx ./web/static/
working-directory: ./tools/essence-feature-usage-stats

- name: Add the .nojekyll file
run: touch ./web/static/.nojekyll
working-directory: ./tools/essence-feature-usage-stats

- name: Deploy to GitHub Pages
uses: JamesIves/github-pages-deploy-action@v4.4.3
with:
branch: gh-pages
folder: ./tools/essence-feature-usage-stats/web/static
target-folder: tools/essence-feature-usage-stats
commit-message: "Actions: Deploy the essence features usage table 🚀"

12 changes: 11 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,13 @@
# rust/c++
target
solvers/**/vendor/build
coverage
solvers/**/vendor/build

# python
.env
venv
__pycache__
.ruff_cache

# IDE
.idea
59 changes: 59 additions & 0 deletions tools/essence-feature-usage-stats/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
# essence-feature-usage-stats

## About

This is an internal tool for the [conjure-oxide](https://github.com/conjure-cp/conjure-oxide) project.

It does the following:
- Given a directory containing Essence files, go through it and count how often every Essence language feature is used
- Display this data as a simple web page with a table

The purpose of this is to make it easier to find Essence examples to test specific Essence language features, which should be useful over the course of rewriting the conjure tool stack in Rust


## Building

The static HTML page is generated by running the main.py script.

The page is placed in the ./web/static directory by default.
This can be configured using the OUTPUT_PATH environment variable, but paths to the script and stylesheet
inside the index.html template will need to be updated.
The GitHub action also assumes that path and won't work if it's changed.

It is deployed using GitHub Pages: see https://conjure-cp.github.io/conjure-oxide/tools/essence-feature-usage-stats


## Usage

- Essence example files are taken from the [EssenceCatalog](https://github.com/conjure-cp/EssenceCatalog) repo. This can be changed using an environment variable - see bellow.
- Table headers show Essence keywords
- Table row headers show paths to Essence example files and the size of the files (in lines of code)
- Table cells show how often a given keyword is used in a given file
- Cells are colour coded. Red means a keyword is NOT used in this file, orange means it's used less than average, green means it's used more
- Columns are sortable. Click on table header cells to sort rows by how often this keyword is used in each file.
- Sorting by the first column (the one with file names) will sort by file size
- The section above the table is a list of Essence keywords, sorted by their total usage accross files
- The "Show" checkboxes in this section show/hide table columns
- The "Any", "Require", "Exclude" radio button allows you to filter the table by specific keywords:
- "Require" means that only files that have one or more usage of this keyword will be shown
- "Exclude" means that only files that don't use this keyword will be shown
- "Any" means that files will be shown regardless of whether they use this feature
- These can be combined to search for exactly the right files to test specific Essence features

## Configuration

- ESSENCE_DIR - local directory to store essence files
- CONJURE_DIR - local directory to store conjure binaries
- ESSENCE_EXAMPLES_REPO - repo to download Essence examples from
- CONJURE_REPO - repo to download the latest release of conjure from
- OUTPUT_PATH - path to save the generated HTML page. Be careful with changing this (see above).
- KEYWORD_BLOCKLIST - comma-separated list of Essence keywords to ignore

---

## Authors

- Georgii Skorokhod and Hannah Zheng, 2023
- University of St Andrews
- Developed as part of a Vertically Integrated Project by Ozgur Akgun et al
- (See [main repo](https://github.com/conjure-cp))
51 changes: 51 additions & 0 deletions tools/essence-feature-usage-stats/main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import datetime
import os
from pathlib import Path

from dotenv import load_dotenv
from jinja2 import Environment, FileSystemLoader, select_autoescape

from stats.essence_stats import EssenceStats

ENV_PATH = Path("./.env").resolve()
load_dotenv(dotenv_path=ENV_PATH)

KEYWORD_BLOCKLIST = [x.strip() for x in os.getenv("KEYWORD_BLOCKLIST").split(",")]
ESSENCE_DIR = Path(os.getenv("ESSENCE_DIR"))
CONJURE_DIR = Path(os.getenv("CONJURE_DIR"))
OUTPUT_PATH = Path(os.getenv("OUTPUT_PATH"))
CONJURE_REPO = os.getenv("CONJURE_REPO")
ESSENCE_EXAMPLES_REPO = os.getenv("ESSENCE_EXAMPLES_REPO")

jinja_env = Environment(
loader=FileSystemLoader(Path("web/templates")),
autoescape=select_autoescape(),
)

if __name__ == "__main__":
stats = EssenceStats(
CONJURE_DIR,
CONJURE_REPO,
ESSENCE_DIR,
ESSENCE_EXAMPLES_REPO,
"master",
KEYWORD_BLOCKLIST,
)

timestamp = datetime.datetime.now().strftime("%d.%m.%Y - %H:%M")
template = jinja_env.get_template("index.html")
html = template.render(
data={
"essence_stats": stats,
"n_keywords": 200,
"css_path": "styles.css",
"script_path": "script.js",
"timestamp": timestamp,
},
)

OUTPUT_PATH.parent.mkdir(parents=True, exist_ok=True)
with OUTPUT_PATH.open("w") as f:
f.write(html)
f.close()
print(f"Table created: {OUTPUT_PATH.resolve()}")
23 changes: 23 additions & 0 deletions tools/essence-feature-usage-stats/pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
[tool.ruff]
select = ["E", "F", "B", "I", "N", "UP",
"A", "COM", "C4", "ISC001", "ISC002",
"ICN", "G", "INP", "PIE", "Q", "RSE",
"RET", "SIM", "ARG", "D",
"FIX", "PL", "TRY", "FLY", "PERF",
"RUF", "ERA", "PTH", "SLF"]

# 2. Avoid enforcing line-length violations (`E501`) and module docstrings (D100)
# Use line breaks at the first line of doc string (D213), so ignore D212
# Don't use blank lines before class docstring, so ignore D203
ignore = ["E501", "D100", "D212", "D203"]

# 3. Unfixable rules
# ERA: Don't autoremove all commented code, I may actually need it
unfixable = ["ERA"]

exclude = ["EssenceCatalog"]

# 4. Ignore `E402` (import violations) in all `__init__.py` files, and in `path/to/file.py`.
[tool.ruff.per-file-ignores]
"web/colour.py" = ["PLR2004"]
"__init__.py" = ["D"]
19 changes: 19 additions & 0 deletions tools/essence-feature-usage-stats/requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
black==23.10.1
certifi==2023.7.22
charset-normalizer==3.3.2
click==8.1.7
gitdb==4.0.11
GitPython==3.1.40
idna==3.4
Jinja2==3.1.2
MarkupSafe==2.1.3
mypy-extensions==1.0.0
packaging==23.2
pathspec==0.11.2
platformdirs==3.11.0
python-dotenv==1.0.0
requests==2.31.0
ruff==0.1.3
smmap==5.0.1
tqdm==4.66.1
urllib3==2.0.7
Empty file.
Loading

0 comments on commit 9280d47

Please sign in to comment.