Repository navigation
Expand file tree
/
Copy pathpoe_tasks.toml
More file actions
204 lines (182 loc) · 9.13 KB
/
Copy pathpoe_tasks.toml
File metadata and controls
204 lines (182 loc) · 9.13 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
# SPDX-FileCopyrightText: 2025 Contributors to the OpenSTEF project <openstef@lfenergy.org>
#
# SPDX-License-Identifier: MPL-2.0
# Poe the Poet task definitions, split out of pyproject.toml and pulled back in
# via `[tool.poe] include` there. Run with `uv run poe <task>`.
[tool.poe.tasks.lint]
help = "Lint code (with ruff)"
cmd = 'ruff check --fix --show-fixes ${check:+ --no-fix} ${unsafe:+ --unsafe-fixes}'
args = [
{ name = "check", type = "boolean", help = "Does not correct files, only warns" },
{ name = "unsafe", type = "boolean", help = "Enables unsafe fixes, which may change the code in a way that is not reversible. Use with care." },
]
[tool.poe.tasks.format]
help = "Format code (with ruff)"
cmd = 'ruff format ${check:+ --diff}'
args = [ { name = "check", type = "boolean", help = "Does not correct files, only warns" } ]
[tool.poe.tasks.format-pyproject]
help = "Format pyproject.toml (with pyproject-fmt)"
# Invoked once per file (not as one multi-file call): pyproject-fmt only honors
# the first file's [tool.pyproject-fmt] config when given multiple files at once,
# silently ignoring each subsequent package's own overrides (e.g. max_supported_python).
shell = 'for f in pyproject.toml packages/*/pyproject.toml; do pyproject-fmt ${check:+ --check} -n "$f"; done'
args = [ { name = "check", type = "boolean", help = "Does not correct files, only warns" } ]
[tool.poe.tasks.lock]
help = "Asserts that dependencies are locked"
cmd = "uv lock --check"
[tool.poe.tasks.type]
help = "Check typing (with ty)"
cmd = "ty check tools examples packages/*/src"
[tool.poe.tasks.type-tests]
help = "Check typing (with ty)"
cmd = "ty check packages/*/tests"
[tool.poe.tasks.tests]
help = "Run pytest with xdist, marker filtering, and coverage"
cmd = "pytest --numprocesses=auto ${markers:+ -m $markers} ${relaxed:+ -W default} --cov --cov-report=term-missing --cov-report=xml:coverage.xml"
args = [
{ name = "markers", type = "string", default = "", help = "Only run tests matching the given pytest markers expression" },
{ name = "relaxed", type = "boolean", help = "Do not treat warnings as errors (used by CI; warnings fail locally by default)" },
]
[tool.poe.tasks.doctests]
help = "Run all docstring examples via pytest’s doctest plugin"
cmd = "pytest --numprocesses=auto ${relaxed:+ -W default} --doctest-modules packages/*/src --maxfail=1"
args = [
{ name = "relaxed", type = "boolean", help = "Do not treat warnings as errors (used by CI; warnings fail locally by default)" },
]
[tool.poe.tasks.notebooks]
help = "Sync jupytext .py percent sources → .ipynb notebooks (and vice versa)"
sequence = [
{ cmd = "jupytext --sync examples/tutorials/*.py" },
{ cmd = "jupytext --sync examples/benchmarks/custom/*.py examples/benchmarks/liander2024/*.py" },
]
[tool.poe.tasks.notebooks-clear]
help = "Strip outputs from all .ipynb notebooks"
sequence = [
{ cmd = "jupyter nbconvert --clear-output --inplace examples/tutorials/*.ipynb" },
{ cmd = "jupyter nbconvert --clear-output --inplace examples/benchmarks/custom/*.ipynb examples/benchmarks/liander2024/*.ipynb" },
]
[tool.poe.tasks.notebooks-check]
help = "Check that .ipynb notebooks are in sync with their jupytext .py sources and have no outputs"
sequence = [
{ cmd = "jupytext --sync examples/tutorials/*.py" },
{ cmd = "jupytext --sync examples/benchmarks/custom/*.py examples/benchmarks/liander2024/*.py" },
{ cmd = "git diff --exit-code -- examples/tutorials/ examples/benchmarks/" },
{ script = "tools.check_notebook_outputs:main" },
]
[tool.poe.tasks.report]
help = "Generate coverage report. Will use data from a previous cover command."
sequence = [
{ cmd = "coverage report", help = "Generate a coverage report" },
{ cmd = "coverage xml -o coverage.xml", help = "Generate XML coverage report for CI integration" },
]
[tool.poe.tasks.reuse]
help = "Check REUSE compliance (with optional fix)"
args = [ { name = "fix", type = "boolean", help = "Automatically fix REUSE compliance issues before lint check" } ]
control.expr = "fix"
switch = [
{ case = "True", cmd = "uv run tools/reuse-fix.py --license \"MPL-2.0\" --copyright \"Contributors to the OpenSTEF project <openstef@lfenergy.org>\"" },
{ cmd = "reuse lint" },
]
[tool.poe.tasks.licensecheck]
help = "Check licenses of dependencies for compatibility"
# --requirements-paths is required: our root pyproject.toml's only direct dependencies are our
# own workspace packages (all in [tool.licensecheck] skip_dependencies), so licensecheck also
# needs each workspace member's own pyproject.toml to find any real third-party dependencies.
cmd = '''
licensecheck
--requirements-paths pyproject.toml packages/openstef-beam/pyproject.toml packages/openstef-core/pyproject.toml packages/openstef-foundation-models/pyproject.toml packages/openstef-meta/pyproject.toml packages/openstef-models/pyproject.toml
${check:+ --show-only-failing --zero}
'''
args = [ { name = "check", type = "boolean", help = "Does not correct files, only warns" } ]
[tool.poe.tasks.licensecheck-third-party]
help = "Check licenses of dependencies for compatibility"
cmd = '''
licensecheck
--requirements-paths pyproject.toml packages/openstef-beam/pyproject.toml packages/openstef-core/pyproject.toml packages/openstef-foundation-models/pyproject.toml packages/openstef-meta/pyproject.toml packages/openstef-models/pyproject.toml
--format markdown --file THIRD_PARTY_NOTICES.md
'''
[tool.poe.tasks.all]
help = "Run all CI calls"
control.expr = "check" # There is no pass through option (yet?) so use a control expression to pass --check option to tasks when relevant
args = [ { name = "check", type = "boolean", help = "Does not correct files, only warns" } ]
# NB: ruff needs the linter (which will sort imports) to run before the formatter (which cannot sort imports).
switch = [
{ case = "check", sequence = [
"reuse",
"licensecheck --check",
"lint --check",
"format --check",
"format-pyproject --check",
"lock",
"type",
"type-tests",
"tests",
"doctests",
"notebooks-check",
], ignore_fail = "return_non_zero" },
{ sequence = [
"licensecheck --check",
"reuse --fix",
"lint",
"format",
"format-pyproject",
"lock",
"type",
"type-tests",
"tests",
"doctests",
"notebooks",
], ignore_fail = "return_non_zero" },
]
[tool.poe.tasks.version]
help = "Set the release version in pyproject.toml and packages' pyproject.toml files"
sequence = [
# Bumps the version in all pyproject.toml files
{ cmd = "uv version ${version} --frozen" },
{ cmd = "uv version --package openstef-beam ${version} --frozen" },
{ cmd = "uv version --package openstef-core ${version} --frozen" },
{ cmd = "uv version --package openstef-foundation-models ${version} --frozen" },
{ cmd = "uv version --package openstef-meta ${version} --frozen" },
{ cmd = "uv version --package openstef-models ${version} --frozen" },
# Pin these versions in the root pyproject.toml
{ cmd = "uv add openstef-beam==${version} --optional beam" },
{ cmd = "uv add openstef-foundation-models==${version} --optional foundation-models" },
{ cmd = "uv add openstef-meta==${version} --optional meta" },
{ cmd = "uv add openstef-models==${version} --optional models" },
{ cmd = "uv add openstef-core==${version} --optional core" },
{ cmd = "uv add openstef-meta==${version} --optional models" },
{ cmd = "uv add openstef-foundation-models==${version} openstef-meta==${version} openstef-models==${version} openstef-beam==${version} openstef-core==${version} --optional all" },
{ cmd = "uv add openstef-models==${version} openstef-core==${version}" },
]
args = [
{ name = "version", type = "string", help = "The version to set, e.g. 4.0.0" },
]
[tool.poe.tasks.build]
# Builds only the publishable distributions. `openstef-deployment-examples` is a workspace
# member (so `uv run --package openstef-deployment-examples ...` works) but must NOT be
# published to PyPI, so it is deliberately excluded here rather than using `--all-packages`.
help = "Build all publishable packages (excludes openstef-deployment-examples)"
sequence = [
{ cmd = "uv build --package openstef-core" },
{ cmd = "uv build --package openstef-models" },
{ cmd = "uv build --package openstef-beam" },
{ cmd = "uv build --package openstef-foundation-models" },
{ cmd = "uv build --package openstef-meta" },
{ cmd = "uv build .", help = "Build root meta package separately (not a workspace member)" },
]
[tool.poe.tasks._docs_sync]
help = "Sync tutorial and benchmark sources into docs/source for Sphinx (also runs automatically via conf.py)"
cmd = "python docs/sync_sources.py"
[tool.poe.tasks.docs]
help = "Build the documentation"
control.expr = "serve"
switch = [
{ case = "True", cmd = "sphinx-autobuild -d docs/build/doctrees docs/source docs/build/html --watch packages --watch examples" },
{ cmd = "sphinx-build -b html -d docs/build/doctrees docs/source docs/build/html" },
]
args = [
{ name = "serve", type = "boolean", default = false, help = "Serve the documentation with live reload" },
]
[tool.poe.tasks.docs-clean]
help = "Clean the documentation build artifacts"
cmd = "rm -rf docs/build/html docs/build/doctrees docs/source/api/generated"