Skip to content

Commit d759a3c

Browse files
authored
Merge pull request #2 from openscm/add-basic-fortran
Add Fortran build stuff and tests
2 parents b738b9b + 107a66f commit d759a3c

39 files changed

+1644
-800
lines changed

.fprettify.rc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
indent=4
2+
whitespace=4

.github/actions/setup/action.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,4 +26,4 @@ runs:
2626
shell: bash
2727
if: ${{ (inputs.run-uv-install == 'true') }}
2828
run: |
29-
uv sync ${{ inputs.uv-dependency-install-flags }}
29+
uv sync --no-editable ${{ inputs.uv-dependency-install-flags }}

.github/workflows/bump.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ jobs:
5656
echo "Bumping to version $NEW_VERSION"
5757
5858
# Build CHANGELOG
59-
uv run towncrier build --yes --version v$NEW_VERSION
59+
uv run --no-sync towncrier build --yes --version v$NEW_VERSION
6060
6161
# Commit, tag and push
6262
git commit -a -m "bump: version $BASE_VERSION -> $NEW_VERSION"

.github/workflows/ci.yaml

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ jobs:
2323
uv-dependency-install-flags: "--all-extras --group dev"
2424
- name: mypy
2525
run: |
26-
MYPYPATH=stubs uv run mypy src
26+
MYPYPATH=stubs uv run --no-sync mypy src
2727
2828
docs:
2929
if: ${{ !github.event.pull_request.draft }}
@@ -41,16 +41,16 @@ jobs:
4141
uv-dependency-install-flags: "--all-extras --group docs"
4242
- name: docs
4343
run: |
44-
uv run mkdocs build --strict
44+
uv run --no-sync mkdocs build --strict
4545
- uses: ./.github/actions/setup
4646
with:
4747
python-version: "3.11"
4848
uv-dependency-install-flags: "--all-extras --group docs --group dev"
4949
- name: docs-with-changelog
5050
run: |
5151
# Check CHANGELOG will build too
52-
uv run towncrier build --yes
53-
uv run mkdocs build --strict
52+
uv run --no-sync towncrier build --yes
53+
uv run --no-sync mkdocs build --strict
5454
# Just in case, undo the staged changes
5555
git restore --staged . && git restore .
5656
@@ -65,7 +65,9 @@ jobs:
6565
with:
6666
# Exclude local links
6767
# and the template link in pyproject.toml
68-
args: "--exclude 'file://' --exclude '^https://github\\.com/openscm/example-fgen-basic/pull/\\{issue\\}$' ."
68+
# Don't check for conda-forge while we haven't released there
69+
# Don't check https://www.readthedocs.org/ as it hits rate limits
70+
args: "--exclude 'file://' --exclude '^https://github\\.com/openscm/example-fgen-basic/pull/\\{issue\\}$' --exclude '^https://github.com/conda-forge/example-fgen-basic-feedstock$' --exclude '^https://www.readthedocs.org/$' ."
6971

7072
tests:
7173
strategy:
@@ -97,8 +99,10 @@ jobs:
9799
uv-dependency-install-flags: "--all-extras --group tests"
98100
- name: Run tests
99101
run: |
100-
uv run pytest -r a -v src tests --doctest-modules --cov=src --cov-report=term-missing --cov-report=xml
101-
uv run coverage report
102+
103+
COV_DIR=`uv run --no-sync python -c 'from pathlib import Path; import example_fgen_basic; print(Path(example_fgen_basic.__file__).parent)'`
104+
uv run --no-sync pytest -r a -v tests src --doctest-modules --doctest-report ndiff --cov=${COV_DIR} --cov-report=term-missing --cov-report=xml
105+
uv run --no-sync coverage report
102106
- name: Upload coverage reports to Codecov with GitHub Action
103107
uses: codecov/codecov-action@v4.2.0
104108
env:
@@ -220,15 +224,13 @@ jobs:
220224
steps:
221225
- name: Check out repository
222226
uses: actions/checkout@v4
223-
- name: Setup uv
224-
id: setup-uv
225-
uses: astral-sh/setup-uv@v4
227+
- uses: ./.github/actions/setup
226228
with:
227-
version: "0.8.8"
228229
python-version: ${{ matrix.python-version }}
230+
uv-dependency-install-flags: "--group dev"
229231
- name: Build package
230232
run: |
231-
uv run python scripts/add-locked-targets-to-pyproject-toml.py
233+
uv run --no-sync python scripts/add-locked-targets-to-pyproject-toml.py
232234
cat pyproject.toml
233235
uv build
234236
# Just in case, undo the changes to `pyproject.toml`
@@ -256,5 +258,5 @@ jobs:
256258
run: |
257259
TEMP_FILE=$(mktemp)
258260
uv export --no-dev > $TEMP_FILE
259-
uv run liccheck -r $TEMP_FILE -R licence-check.txt
261+
uv run --no-sync liccheck -r $TEMP_FILE -R licence-check.txt
260262
cat licence-check.txt

.github/workflows/deploy.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ jobs:
3636
python-version: ${{ matrix.python-version }}
3737
- name: Publish to PyPI
3838
run: |
39-
uv run python scripts/add-locked-targets-to-pyproject-toml.py
39+
uv run --no-sync python scripts/add-locked-targets-to-pyproject-toml.py
4040
uv build
4141
uv publish
4242
# Just in case, undo the changes to `pyproject.toml`

.github/workflows/release.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ jobs:
3333
echo "PROJECT_VERSION=$PROJECT_VERSION" >> $GITHUB_ENV
3434
- name: Build package for PyPI
3535
run: |
36-
uv run python scripts/add-locked-targets-to-pyproject-toml.py
36+
uv run --no-sync python scripts/add-locked-targets-to-pyproject-toml.py
3737
uv build
3838
# Just in case, undo the changes to `pyproject.toml`
3939
git restore --staged . && git restore .
@@ -43,7 +43,7 @@ jobs:
4343
echo "## Changelog" >> ".github/release_template.md"
4444
echo "" >> ".github/release_template.md"
4545
uv add typer
46-
uv run python scripts/changelog-to-release-template.py >> ".github/release_template.md"
46+
uv run --no-sync python scripts/changelog-to-release-template.py >> ".github/release_template.md"
4747
echo "" >> ".github/release_template.md"
4848
echo "## Changes" >> ".github/release_template.md"
4949
echo "" >> ".github/release_template.md"

.gitignore

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,29 @@
1+
# Local install dir
2+
install-example
3+
4+
# Cloned dependencies
5+
subprojects/test-drive
6+
17
# Notebooks
28
*.ipynb
39

410
# Auto-generated docs and helper files
511
docs/api/*
612
!docs/api/.gitkeep
7-
8-
# pdm stuff
9-
.pdm-python
13+
docs/fgen/api/*
14+
!docs/fgen/api/.gitkeep
15+
docs/fgen-runtime/api/*
16+
!docs/fgen-runtime/api/.gitkeep
1017

1118
# Databases
1219
*.db
1320

21+
# Downloaded wheels
22+
*.whl
23+
24+
# cmake
25+
cmake-build-*
26+
1427
# Jupyter cache
1528
.jupyter_cache
1629

.pre-commit-config.yaml

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,12 @@ ci:
44
autoupdate_schedule: quarterly
55
autoupdate_branch: pre-commit-autoupdate
66
# Currently network access isn't supported in the pre-commit CI product.
7-
skip: [uv-sync, uv-lock, uv-export]
7+
skip: [
8+
propagate-pyproject-metadata,
9+
uv-sync,
10+
uv-lock,
11+
uv-export,
12+
]
813

914
# See https://pre-commit.com/hooks.html for more hooks
1015
repos:
@@ -63,3 +68,24 @@ repos:
6368
args: ["-o", "requirements-only-tests-locked.txt", "--no-hashes", "--no-dev", "--no-emit-project", "--only-group", "tests"]
6469
# # Not released yet
6570
# - id: uv-sync
71+
- repo: local
72+
hooks:
73+
- id: propagate-pyproject-metadata
74+
name: propagate-pyproject-metadata
75+
entry: uv run --no-sync python scripts/propogate-pyproject-metadata.py
76+
files: |
77+
(?x)^(
78+
meson.build|
79+
scripts/propogate-pyproject-metadata.py|
80+
pyproject.toml
81+
)$
82+
language: system
83+
require_serial: true
84+
pass_filenames: false
85+
- id: inject-srcs-into-meson-build
86+
name: inject-srcs-into-meson-build
87+
entry: uv run --no-sync python scripts/inject-srcs-into-meson-build.py
88+
files: \.(py|f90|build)$
89+
language: system
90+
require_serial: true
91+
pass_filenames: false

.readthedocs.yaml

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,10 @@ version: 2
99
build:
1010
os: ubuntu-22.04
1111
tools:
12-
python: "3.11"
12+
python: "mambaforge-22.9"
1313
jobs:
1414
post_install:
15-
# RtD seems to be not happy with pdm installs,
16-
# hence use pip directly instead.
15+
- which python
1716
- python -m pip install -r requirements-docs-locked.txt
1817
- python -m pip list
1918
pre_build:
@@ -22,3 +21,6 @@ build:
2221
mkdocs:
2322
configuration: mkdocs.yml
2423
fail_on_warning: true
24+
25+
conda:
26+
environment: environment-docs-conda-base.yml

Makefile

Lines changed: 47 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@
44
# Will likely fail on Windows, but Makefiles are in general not Windows
55
# compatible so we're not too worried
66
TEMP_FILE := $(shell mktemp)
7+
# Directory in which to build the Fortran when using a standalone build
8+
BUILD_DIR := build
9+
# Coverage directory - needed to trick code cov to look in the right place
10+
COV_DIR := $(shell uv run --no-sync python -c 'from pathlib import Path; import example_fgen_basic; print(Path(example_fgen_basic.__file__).parent)')
711

812
# A helper script to get short descriptions of each target in the Makefile
913
define PRINT_HELP_PYSCRIPT
@@ -24,8 +28,8 @@ help: ## print short description of each target
2428

2529
.PHONY: checks
2630
checks: ## run all the linting checks of the codebase
27-
@echo "=== pre-commit ==="; uv run pre-commit run --all-files || echo "--- pre-commit failed ---" >&2; \
28-
echo "=== mypy ==="; MYPYPATH=stubs uv run mypy src || echo "--- mypy failed ---" >&2; \
31+
@echo "=== pre-commit ==="; uv run --no-sync pre-commit run --all-files || echo "--- pre-commit failed ---" >&2; \
32+
echo "=== mypy ==="; MYPYPATH=stubs uv run --no-sync mypy src || echo "--- mypy failed ---" >&2; \
2933
echo "======"
3034

3135
.PHONY: ruff-fixes
@@ -37,8 +41,17 @@ ruff-fixes: ## fix the code using ruff
3741
uv run ruff format src tests scripts docs
3842

3943
.PHONY: test
40-
test: ## run the tests
41-
uv run pytest src tests -r a -v --doctest-modules --doctest-report ndiff --cov=src
44+
test: ## run the tests (re-installs the package every time so you might want to run by hand if you're certain that step isn't needed)
45+
# Note: passing `src` to pytest causes the `src` directory to be imported
46+
# if the package has not already been installed.
47+
# This is a problem, as the package is not importable from `src` by itself because the extension module is not available.
48+
# As a result, you have to pass `pytest tests src` rather than `pytest src tests`
49+
# to ensure that the package is imported from the venv and not `src`.
50+
# The issue with this is that code coverage then doesn't work,
51+
# because it is looking for lines in `src` to be run,
52+
# but they're not because lines in `.venv` are run instead.
53+
# We don't have a solution to this yet.
54+
uv run --no-editable --reinstall-package example-fgen-basic pytest -r a -v tests src --doctest-modules --doctest-report ndiff --cov=$(COV_DIR)
4255

4356
# Note on code coverage and testing:
4457
# You must specify cov=src.
@@ -55,15 +68,15 @@ test: ## run the tests
5568

5669
.PHONY: docs
5770
docs: ## build the docs
58-
uv run mkdocs build
71+
uv run --no-sync mkdocs build
5972

6073
.PHONY: docs-strict
6174
docs-strict: ## build the docs strictly (e.g. raise an error on warnings, this most closely mirrors what we do in the CI)
62-
uv run mkdocs build --strict
75+
uv run --no-sync mkdocs build --strict
6376

6477
.PHONY: docs-serve
6578
docs-serve: ## serve the docs locally
66-
uv run mkdocs serve
79+
uv run --no-sync mkdocs serve
6780

6881
.PHONY: changelog-draft
6982
changelog-draft: ## compile a draft of the next changelog
@@ -79,5 +92,30 @@ licence-check: ## Check that licences of the dependencies are suitable
7992

8093
.PHONY: virtual-environment
8194
virtual-environment: ## update virtual environment, create a new one if it doesn't already exist
82-
uv sync --all-extras --group all-dev
83-
uv run pre-commit install
95+
uv sync --no-editable --all-extras --group all-dev
96+
uv run --no-sync pre-commit install
97+
98+
.PHONY: format-fortran
99+
format-fortran: ## format the Fortran files
100+
uv run fprettify -r src -c .fprettify.rc
101+
102+
$(BUILD_DIR): # setup the standlone Fortran build directory
103+
uv run meson setup $(BUILD_DIR)
104+
105+
.PHONY: build-fortran
106+
build-fortran: | $(BUILD_DIR) ## build/compile the Fortran (including the extension module)
107+
uv run meson compile -C build -v
108+
109+
.PHONY: test-fortran
110+
test-fortran: build-fortran ## run the Fortran tests
111+
uv run meson test -C build -v
112+
113+
.PHONY: install-fortran
114+
install-fortran: build-fortran ## install the Fortran (including the extension module)
115+
uv run meson install -C build -v
116+
# # Can also do this to see where things go without making a mess
117+
# uv run meson install -C build --destdir ../install-example
118+
119+
.PHONY: clean
120+
clean: ## clean all build artefacts
121+
rm -rf $(BUILD_DIR)

0 commit comments

Comments
 (0)