Skip to content

Commit 1df4c64

Browse files
committed
Introduced developer guide, moved pre-commit information to this guide
1 parent 40d573b commit 1df4c64

8 files changed

Lines changed: 343 additions & 70 deletions

File tree

.pre-commit-config.yaml

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,28 @@ repos:
1111
name: ruff linter
1212
alias: lint
1313
# Run the formatter
14-
- id: ruff-format
15-
name: ruff formatter
16-
alias: format
14+
# - id: ruff-format
15+
# name: ruff formatter
16+
# alias: format
17+
18+
- repo: https://github.com/jendrikseipp/vulture
19+
# Vulture version
20+
rev: v2.15
21+
hooks:
22+
# Run dead code detection
23+
# Paths are configured under [tool.vulture] in pyproject.toml
24+
- id: vulture
25+
name: vulture dead code
26+
alias: vulture
27+
28+
# ty has no official pre-commit hook yet (https://github.com/astral-sh/ty/issues/269).
29+
# Run it as a local hook using the system-installed binary
30+
- repo: local
31+
hooks:
32+
- id: ty
33+
name: ty type checker
34+
alias: ty
35+
entry: ty check --color always --project pyhope pyhope
36+
language: system
37+
pass_filenames: false
38+
types: [python]

README.md

Lines changed: 0 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -198,73 +198,6 @@ with Mesh('1-01-cartbox_mesh.h5') as m:
198198
lobatto_nodes = Basis.legendre_gauss_lobatto_nodes(order=m.nGeo)
199199
```
200200
201-
## Ruff linter and formatter
202-
203-
PyHOPE uses [Ruff](https://docs.astral.sh/ruff/) for code linting and formatting of all .py files to maintain consistent code quality and style.
204-
Ruff is a fast Python linter and formatter that combines multiple individual tools like flake8, black, isort, etc.
205-
206-
### Pre-commit Integration
207-
208-
Ruff is integrated with [pre-commit](https://pre-commit.com/) to automatically check and format code before each commit. The configuration is defined in `.pre-commit-config.yaml` and includes:
209-
210-
1. Ruff linter hook
211-
2. Ruff formatter hook
212-
213-
All hooks can be tested with pre-commit before commiting your changes with
214-
```
215-
pre-commit run
216-
```
217-
Note that all pre-commit hooks only run on files that have been staged. The pre-commit hooks can be ignored with the additional flag
218-
```
219-
--no-verify
220-
```
221-
222-
When creating a commit:
223-
1. The linter displays errors immediately
224-
2. The formatter
225-
- Fails if it finds issues
226-
- Applies automatic fixes
227-
- Unstages the modified files
228-
229-
After formatter changes:
230-
- Review the applied changes
231-
- Re-stage the files
232-
- Try committing again (formatter should pass if no new changes were made)
233-
234-
Some linter errors can be fixed automatically with
235-
```
236-
ruff check --fix
237-
```
238-
while others require manual corrections.
239-
Note that the flag `--unsafe-fixes` can change the functionality of the code, while `--fix` should keep it.
240-
241-
### Ruff configuration
242-
243-
Ruff's configuration is managed through the `pyproject.toml` file in the project root and specifies linting rules, checks, excludes, etc.
244-
245-
To suppress a violation inline, Ruff uses a `noqa` system similar to Flake8. To ignore an individual violation, add `# noqa: {code}` to the end of the line, like so:
246-
```
247-
# Ignore F841.
248-
x = 1 # noqa: F841
249-
# Ignore E741 and F841.
250-
i = 1 # noqa: E741, F841
251-
# Ignore _all_ violations.
252-
x = 1 # noqa
253-
```
254-
255-
Similar to the linter it is also possible to ignore code blocks for the formatter with
256-
```
257-
# fmt: off
258-
_code_
259-
# fmt: on
260-
```
261-
or a python specific block with
262-
```
263-
if condition: # fmt: skip
264-
```
265-
266-
```
267-
268201
# Cite
269202
This is a scientific project. If you use PyHOPE for publications or presentations in science, please support the project by citing the following article.
270203
```bibtex
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
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** |
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
# GitHub workflow
2+
3+
Overview of the development workflow
4+
5+
---
6+
7+
Code development is performed on [GitHub](https://github.com), with a protected `main` branch. The actual development is performed on feature branches, which are merged to `main` following a pull request and the completion of a code review. Continuous Integration (CI) tests are automatically performed on pull requests with a successful pass as a prerequisite for merging into `main`.
8+
9+
## Issues & Milestones
10+
Issues are created for bugs, improvements, features, regression testing and documentation. The issues should be named with a few keywords. Try to avoid describing the complete issue already in the title. The issue can be assigned to a certain milestone (if appropriate).
11+
12+
Milestones are created based on planned releases (e.g. Release 1.2.1) or as a grouping of multiple related issues (e.g. Documentation Version 1, Clean-up Emission Routines). A deadline can be given if applicable. The milestone should contain a short summary of the work performed (bullet-points) as its contents will be added to the description of the releases. Generally, pull requests should be associated with a milestone containing a release tag, while issues should be associated with the grouping milestones.
13+
14+
As soon as a developer wants to start working on an issue, she/he shall assign himself to the issue and a branch and pull request denoted as work in progress ("draft") should be created to allow others to contribute and track the progress. Ideally, issues should be created for every code development for documentation purposes. Branches without an issue should be avoided to reduce the number of orphaned/stale branches. Where a branch must be created outside the issue context, its name should carry a prefix that matches one of the existing GitHub labels
15+
16+
```
17+
bugfix.connect.internal
18+
feature.sort.hilbertmorton
19+
improvement.extrude.zones
20+
```
21+
22+
Pull requests should include a concise description of what changed and why, a reference to the issue being resolved (e.g. `Closes #42`), and a note on anything that reviewers should pay particular attention to.
23+
24+
## Code Review
25+
Every pull request requires at least one approving review before it can be merged. Reviewers should check at least the following points.
26+
27+
- The implementation is correct and consistent with the existing architecture
28+
- New code follows the conventions in the [Style Guide](style-guide.md)
29+
- Public functions carry type annotations and docstrings
30+
- New functionality is covered by tests or tutorials
31+
- The CI pipeline passes all checks without errors or warnings
32+
33+
Authors should respond to review comments promptly. If a comment is addressed by a code change, mark it as resolved. If it is addressed by explanation, reply in the thread and leave it for the reviewer to close.
34+
35+
## Commit Messages
36+
Commit messages should be written in the imperative mood and describe *what* the commit does, not *what was done*:
37+
38+
```
39+
# Good
40+
Add convergence test for CGNS mixed mesh
41+
42+
# Avoid
43+
Added convergence test
44+
Fixed stuff
45+
```
46+
47+
48+
## Release and Deploy
49+
50+
Releases follow [Semantic Versioning](https://semver.org): `MAJOR.MINOR.PATCH`. A new release is created from `main` by opening a pull request associated with the corresponding release milestone. Once merged, navigate to [Releases](https://github.com/hopr-framework/PyHOPE/releases) and select `Draft a new release`. Set the tag to `vMAJOR.MINOR.PATCH` and the title to `Release MAJOR.MINOR.PATCH`. The milestone description supplies the release notes.
51+
52+
Tagged releases are automatically packaged as a Python wheel and deployed to [PyPI](https://pypi.org/project/PyHOPE) by the CI pipeline.

docs/developer-guide/index.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
# Contributing to PyHOPE
2+
3+
How to get started as a developer
4+
5+
---
6+
7+
This guide describes how to develop PyHOPE. It covers the workflow, tooling, and conventions that keep the codebase consistent as the project grows.
8+
9+
10+
The project is developed openly on GitHub under the GPL-3.0 license. Contributions of all kinds are welcome - bug reports, documentation improvements, new features, and convergence tests.
11+
12+
**Contents**
13+
14+
- [GitHub Workflow](github-workflow.md): Branch strategy, pull requests, code review, and release process
15+
- [Environment Setup](get-the-source.md): Cloning, virtual environment, linting tools, and the CI pipeline
16+
- [Style Guide](style-guide.md): Coding conventions, naming rules, and documentation standards

0 commit comments

Comments
 (0)