|
| 1 | +# Environment Setup |
| 2 | + |
| 3 | +Get the source and start developing |
| 4 | + |
| 5 | +--- |
| 6 | + |
| 7 | +## Obtaining the Source |
| 8 | + |
| 9 | +PyHOPE uses [git](https://git-scm.com) to sync down source code. Some larger mesh files are stored in [Git LFS](https://git-lfs.com). `git-lfs` must be installed before cloning, otherwise those files will be replaced by pointer stubs. |
| 10 | + |
| 11 | +!!! info |
| 12 | + PyHOPE developers commonly put their virtual environment in `venv` within the git repository. All commands in this document assume that your virtual environment is in `venv`. |
| 13 | + |
| 14 | +```bash |
| 15 | +git clone https://github.com/hopr-framework/PyHOPE.git |
| 16 | +cd PyHOPE |
| 17 | +python -m venv venv |
| 18 | +source venv/bin/activate |
| 19 | +python -m pip install --upgrade -e . |
| 20 | +``` |
| 21 | + |
| 22 | +!!! info |
| 23 | + Changes in the source code are immediately reflected within the virtual environment without any explicit sync requirement. |
| 24 | + |
| 25 | +## Linting |
| 26 | + |
| 27 | +PyHOPE enforces code quality through three static analysis tools which are wired up as [pre-commit](https://pre-commit.com/) hooks and run as the first stage of the CI pipeline. |
| 28 | + |
| 29 | +### Tools |
| 30 | + |
| 31 | +**[Ruff](https://docs.astral.sh/ruff/)** is a fast Python linter that consolidates the roles of `flake8`, `black`, `isort`, and many others in a single tool. It checks style and common errors across all `.py` files. |
| 32 | + |
| 33 | +!!! note |
| 34 | + Some linter errors can be fixed automatically: |
| 35 | + ```bash |
| 36 | + ruff check --fix |
| 37 | + ``` |
| 38 | + Note that `--unsafe-fixes` may silently change program behaviour; `--fix` is guaranteed to be behaviour-preserving. |
| 39 | + |
| 40 | +**[ty](https://github.com/astral-sh/ty)** is a static type checker by Astral. It resolves all imports against the full installed dependency set. |
| 41 | + |
| 42 | +**[vulture](https://github.com/jendrikseipp/vulture)** detects dead code such as unused functions, unreachable branches, and variables that are assigned but never read. |
| 43 | + |
| 44 | +### Pre-commit Integration |
| 45 | + |
| 46 | +All three tools are configured as hooks in `.pre-commit-config.yaml`. Install them once after cloning. |
| 47 | + |
| 48 | +```bash |
| 49 | +pip install pre-commit |
| 50 | +pre-commit install |
| 51 | +``` |
| 52 | +From that point on, every `git commit` runs ruff, vulture, and ty against the staged files automatically. To run all hooks explicitly against the full codebase. |
| 53 | + |
| 54 | +```bash |
| 55 | +pre-commit run --all-files |
| 56 | +``` |
| 57 | +To skip the hooks for a specific commit, pass `--no-verify` to `git commit`. Use this sparingly as the CI pipeline enforces the same rules and will catch anything skipped locally. |
| 58 | + |
| 59 | +!!! note |
| 60 | + [ty](https://github.com/astral-sh/ty) does not yet have an official pre-commit hook ([astral-sh/ty#269](https://github.com/astral-sh/ty/issues/269)). The local hook in `.pre-commit-config.yaml` calls the system-installed `ty` binary directly. Make sure `ty` is installed in your virtual environment (`pip install ty`) before committing. |
| 61 | + |
| 62 | +### Ruff Configuration |
| 63 | + |
| 64 | +Ruff's rules, exclusions, and per-file overrides are managed through `pyproject.toml` in the project root. To suppress a specific violation on a single line, use a `# noqa` comment with the rule code: |
| 65 | + |
| 66 | +```python |
| 67 | +x = 1 # noqa: F841 # suppress unused-variable for this line only |
| 68 | +i = 1 # noqa: E741, F841 # suppress multiple rules |
| 69 | +x = 1 # noqa # suppress all violations on this line |
| 70 | +``` |
| 71 | + |
| 72 | +!!! note |
| 73 | + Use inline suppressions only when the violation is a known false positive or an intentional deviation. Document the reason in a comment where it is not obvious. |
| 74 | + |
| 75 | +## Continuous Integration |
| 76 | + |
| 77 | +PyHOPE runs a CI pipeline on every pull request. Only one pipeline run executes at a time per branch; a newer push cancels any run still in progress. The pipeline is structured in three stages that run in order. |
| 78 | + |
| 79 | +**1. Lint** |
| 80 | + |
| 81 | +The three tools described above run in parallel. All three must pass before the compatibility stage begins. Running `git commit` locally triggers the same checks automatically via pre-commit. |
| 82 | + |
| 83 | +**2. Compatibility** |
| 84 | + |
| 85 | +A matrix job runs the mesh generation pipeline against five Python versions: **3.10 – 3.14**. All versions run in parallel, so a failure on one version does not abort the others. Two representative tutorials are executed end-to-end: |
| 86 | + |
| 87 | +```bash |
| 88 | +pyhope tutorials/1-04-cartbox_multiple_stretch/parameter.ini |
| 89 | +pyhope tutorials/2-02-external_mesh_CGNS_mixed/parameter.ini |
| 90 | +``` |
| 91 | + |
| 92 | +**3. Verification** |
| 93 | + |
| 94 | +| Job | Description | |
| 95 | +| --- | --- | |
| 96 | +| **examples** | Runs the full tutorial suite with coverage instrumentation | |
| 97 | +| **healthcheck** | Runs PyHOPE's internal health checks: `coverage run -m pyhope --verify tutorials` | |
| 98 | +| **convergence** | Runs FLEXI solver convergence tests in a dedicated Fedora container (`ghcr.io/hopr-framework/nrg-fedora`). Requires `GITHUB_TOKEN` to pull from the GitHub Container Registry | |
| 99 | +| **coverage** | Merges `coverage.xml` artifacts from `examples` and `healthcheck`. On PRs targeting `main`, a bot posts a summary comment. Thresholds: **85% overall**, **90% for new code** | |
0 commit comments