Skip to content

Commit 2f3bb61

Browse files
authored
Merge branch 'main' into dependabot/pip/requirements/pytest-cov-7.0.0
2 parents 3ded3e8 + c125927 commit 2f3bb61

File tree

85 files changed

+2921
-366
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

85 files changed

+2921
-366
lines changed

.github/workflows/ci.yml

Lines changed: 0 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -206,39 +206,3 @@ jobs:
206206
DOCSTRING: false
207207
standalone_suffix: ${{ matrix.version == '241' && '.sp01' || '' }}
208208
secrets: inherit
209-
210-
sync-main-with-master:
211-
name: "Sync main with master"
212-
if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/main' }}
213-
runs-on: ubuntu-latest
214-
steps:
215-
- name: "Install Git and clone project"
216-
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
217-
with:
218-
token: ${{ secrets.MIGRATION_PAT }}
219-
fetch-depth: 0
220-
221-
- name: "Verify that main is the default branch"
222-
shell: bash
223-
run: |
224-
head_branch=$(git remote show origin | grep "HEAD branch:")
225-
main_branch=${head_branch#*: }
226-
227-
if [[ $main_branch != "main" ]]; then
228-
echo "The default branch is not 'main'. It is set to '$main_branch'."
229-
echo "Please set 'main' as the default branch in the repository settings."
230-
exit 1
231-
fi
232-
233-
- name: "Configure git username and email"
234-
shell: bash
235-
run: |
236-
git config --global user.name "${{ secrets.PYANSYS_CI_BOT_USERNAME }}"
237-
git config --global user.email "${{ secrets.PYANSYS_CI_BOT_EMAIL }}"
238-
239-
- name: "Sync main to master"
240-
shell: bash
241-
run: |
242-
git checkout master
243-
git reset --hard main
244-
git push

.github/workflows/docs.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ jobs:
7979
- name: "Build the wheel"
8080
shell: pwsh
8181
run: |
82-
tox -e build-wheel
82+
tox -e build-wheel -- "any"
8383
8484
- name: "Expose the wheel"
8585
shell: bash

.github/workflows/pydpf-post.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,7 @@ jobs:
152152
PACKAGE_NAME: ansys-dpf-post
153153
working-directory: pydpf-post/src
154154
if: inputs.test_docstrings == 'true'
155-
timeout-minutes: 10
155+
timeout-minutes: 12
156156
continue-on-error: true
157157

158158
- uses: mainmatter/continue-on-error-comment@v1

.github/workflows/test_docker.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,7 @@ jobs:
136136
- name: "Test API test_server"
137137
uses: nick-fields/retry@v3
138138
with:
139-
timeout_minutes: 5
139+
timeout_minutes: 8
140140
max_attempts: 2
141141
shell: bash
142142
command: |
@@ -208,7 +208,7 @@ jobs:
208208
- name: "Test Documentation"
209209
uses: nick-fields/retry@v3
210210
with:
211-
timeout_minutes: 4
211+
timeout_minutes: 8
212212
max_attempts: 2
213213
shell: bash
214214
command: |

.github/workflows/tests.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -234,7 +234,7 @@ jobs:
234234
- name: "Run compatible tests in parallel"
235235
uses: nick-fields/retry@v3
236236
with:
237-
timeout_minutes: 15
237+
timeout_minutes: 20
238238
max_attempts: 2
239239
shell: bash
240240
command: |

doc/source/_static/dpf_operators.html

Lines changed: 232 additions & 174 deletions
Large diffs are not rendered by default.

doc/source/getting_started/contribute/developer.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -254,10 +254,10 @@ Testing on Linux via WSL
254254
Some system dependencies required for VTK to run properly might be missing when running tests on linux via WSL (or even linux in general).
255255
The identified workaround for this is to install the OSMesa wheel variant that leverages offscreen rendering with OSMesa.
256256
This wheel is being built for both Linux and Windows at this time and bundles all of the necessary libraries into the wheel. This is
257-
achieved by adding ``-x testenv.commands_pre="uv pip install --extra-index-url https://wheels.vtk.org vtk-osmesa==<version>"``
257+
achieved by adding ``-x testenv.commands_pre="uv pip install --index-url https://wheels.vtk.org vtk-osmesa==<version>"``
258258

259259
For example, to run all tests sequentially on linux, while using a Standalone DPF Server whose path is ``ansys_dpf_server_lin_v2025.1.pre0``, simply run:
260260

261261
.. code-block:: text
262262
263-
python -m tox --parallel -x testenv.deps+="-e ansys_dpf_server_lin_v2025.1.pre0" -x testenv.commands_pre="uv pip install --extra-index-url https://wheels.vtk.org vtk-osmesa==9.2.20230527.dev0"
263+
python -m tox --parallel -x testenv.deps+="-e ansys_dpf_server_lin_v2025.1.pre0" -x testenv.commands_pre="uv pip install --index-url https://wheels.vtk.org vtk-osmesa==9.2.20230527.dev0"

doc/source/user_guide/tutorials/custom_operators_and_plugins/update_pydpf_core.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ installer's Python interpreter.
1414

1515
- ``-awp_root``: Path to the Ansys root installation folder. For example, the 2023 R1 installation folder ends
1616
with ``Ansys Inc/v231``, and the default environment variable is ``AWP_ROOT231``.
17-
- ``-pip_args``: Optional arguments to add to the ``pip`` command. For example, ``--extra-index-url`` or
17+
- ``-pip_args``: Optional arguments to add to the ``pip`` command. For example, ``--index-url`` or
1818
``--trusted-host``.
1919

2020
If you ever want to uninstall the ``ansys-dpf-core`` module from the Ansys installation, you can do so.

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ requires = ["setuptools>=61.0.0", "wheel"]
55
[project]
66
# Check https://setuptools.pypa.io/en/stable/userguide/quickstart.html for all available sections
77
name = "ansys-dpf-core"
8-
version = "0.14.2.dev0"
8+
version = "0.14.3.dev0"
99
description = "Data Processing Framework - Python Core "
1010
readme = "README.md"
1111
requires-python = ">=3.9, <4"

src/ansys/dpf/core/documentation/generate_operators_doc.py

Lines changed: 123 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,9 @@
2424
from __future__ import annotations
2525

2626
import argparse
27-
from os import PathLike
27+
import os
2828
from pathlib import Path
29+
import re
2930

3031
from ansys.dpf import core as dpf
3132
from ansys.dpf.core.changelog import Changelog
@@ -51,7 +52,7 @@ def __init__(
5152

5253

5354
def initialize_server(
54-
ansys_path: str | PathLike = None,
55+
ansys_path: str | os.PathLike = None,
5556
include_composites: bool = False,
5657
include_sound: bool = False,
5758
verbose: bool = False,
@@ -105,6 +106,98 @@ def initialize_server(
105106
return server
106107

107108

109+
def extract_operator_description_update(content: str) -> str:
110+
"""Extract the updated description to use for an operator.
111+
112+
Parameters
113+
----------
114+
content:
115+
The contents of the '*_upd.md' file.
116+
117+
Returns
118+
-------
119+
description_update:
120+
The updated description to use for the operator.
121+
"""
122+
match = re.search(r"## Description\s*(.*?)\s*(?=## |\Z)", content, re.DOTALL)
123+
return match.group(0) + os.linesep if match else None
124+
125+
126+
def replace_operator_description(original_documentation: str, new_description: str):
127+
"""Replace the original operator description with a new one in the operator documentation file.
128+
129+
Parameters
130+
----------
131+
original_documentation:
132+
Original operator documentation.
133+
new_description:
134+
New operator description
135+
136+
Returns
137+
-------
138+
updated_documentation:
139+
The updated operator documentation content
140+
141+
"""
142+
return re.sub(
143+
r"## Description\s*.*?(?=## |\Z)", new_description, original_documentation, flags=re.DOTALL
144+
)
145+
146+
147+
def update_operator_descriptions(
148+
docs_path: Path,
149+
verbose: bool = False,
150+
):
151+
"""Update operator descriptions based on '*_upd.md' files in DPF documentation sources.
152+
153+
Parameters
154+
----------
155+
docs_path:
156+
Root path of the DPF documentation to update operator descriptions for.
157+
verbose:
158+
Whether to print progress information.
159+
160+
"""
161+
all_md_files = {}
162+
specs_path = docs_path / Path("operator-specifications")
163+
# Walk through the target directory and all subdirectories
164+
for root, _, files in os.walk(specs_path):
165+
for file in files:
166+
if file.endswith(".md"):
167+
full_path = Path(root) / Path(file)
168+
all_md_files[str(full_path)] = file # Store full path and just filename
169+
170+
for base_path, file_name in all_md_files.items():
171+
if file_name.endswith("_upd.md"):
172+
continue # Skip update files
173+
174+
# Construct the expected update file name and path
175+
upd_file_name = f"{file_name[:-3]}_upd.md"
176+
177+
# Look for the update file in the same folder
178+
upd_path = Path(base_path).parent / Path(upd_file_name)
179+
if not upd_path.exists():
180+
continue
181+
182+
# Load contents
183+
with Path(base_path).open(mode="r", encoding="utf-8") as bf:
184+
base_content = bf.read()
185+
with Path(upd_path).open(mode="r", encoding="utf-8") as uf:
186+
upd_content = uf.read()
187+
188+
# Extract and replace description
189+
new_description = extract_operator_description_update(upd_content)
190+
if new_description:
191+
updated_content = replace_operator_description(base_content, new_description)
192+
with Path(base_path).open(mode="w", encoding="utf-8") as bf:
193+
bf.write(updated_content)
194+
if verbose:
195+
print(f"Updated description for: {file_name}")
196+
else:
197+
if verbose:
198+
print(f"No operator description found in: {upd_path}")
199+
200+
108201
def fetch_doc_info(server: dpf.AnyServerType, operator_name: str) -> dict:
109202
"""Fetch information about the specifications of a given operator.
110203
@@ -265,14 +358,14 @@ def generate_operator_doc(
265358
if not include_private and operator_info["exposure"] == "private":
266359
return
267360
template_path = Path(__file__).parent / "operator_doc_template.md"
268-
spec_folder = output_path / "operator-specifications"
361+
spec_folder = output_path / Path("operator-specifications")
269362
category_dir = spec_folder / category
270363
spec_folder.mkdir(parents=True, exist_ok=True)
271364
if category is not None:
272365
category_dir.mkdir(parents=True, exist_ok=True) # Ensure all parent directories are created
273366
file_dir = category_dir
274367
else:
275-
file_dir = output_path / "operator-specifications"
368+
file_dir = spec_folder
276369
with Path.open(template_path, "r") as file:
277370
template = jinja2.Template(file.read())
278371

@@ -281,8 +374,8 @@ def generate_operator_doc(
281374
file.write(output)
282375

283376

284-
def generate_toc_tree(docs_path: Path):
285-
"""Write the global toc.yml file for the DPF documentation based on the operators found.
377+
def update_toc_tree(docs_path: Path):
378+
"""Update the global toc.yml file for the DPF documentation based on the operators found.
286379
287380
Parameters
288381
----------
@@ -291,14 +384,14 @@ def generate_toc_tree(docs_path: Path):
291384
292385
"""
293386
data = []
294-
specs_path = docs_path / "operator-specifications"
387+
specs_path = docs_path / Path("operator-specifications")
295388
for folder in specs_path.iterdir():
296389
if folder.is_dir(): # Ensure 'folder' is a directory
297390
category = folder.name
298391
operators = [] # Reset operators for each category
299392
for file in folder.iterdir():
300393
if (
301-
file.is_file() and file.suffix == ".md"
394+
file.is_file() and file.suffix == ".md" and not file.name.endswith("_upd.md")
302395
): # Ensure 'file' is a file with .md extension
303396
file_name = file.name
304397
file_path = f"{category}/{file_name}"
@@ -308,18 +401,27 @@ def generate_toc_tree(docs_path: Path):
308401

309402
# Render the Jinja2 template
310403
template_path = Path(__file__).parent / "toc_template.j2"
311-
with Path.open(template_path, "r") as template_file:
404+
with template_path.open(mode="r") as template_file:
312405
template = jinja2.Template(template_file.read())
313406
output = template.render(data=data) # Pass 'data' as a named argument
314407

315-
# Write the rendered output to toc.yml at the operators_doc level
316-
with Path.open(docs_path / "toc.yml", "w") as file:
317-
file.write(output)
408+
# Update the original toc.yml file with the rendered output for operator_specifications
409+
toc_path = docs_path / Path("toc.yml")
410+
with toc_path.open(mode="r") as file:
411+
original_toc = file.read()
412+
new_toc = re.sub(
413+
pattern=r"- name: Operator specifications\s*.*?(?=- name: Changelog|\Z)",
414+
repl=output,
415+
string=original_toc,
416+
flags=re.DOTALL,
417+
)
418+
with toc_path.open(mode="w") as file:
419+
file.write(new_toc)
318420

319421

320422
def generate_operators_doc(
321-
ansys_path: Path,
322423
output_path: Path,
424+
ansys_path: Path = None,
323425
include_composites: bool = False,
324426
include_sound: bool = False,
325427
include_private: bool = False,
@@ -334,10 +436,10 @@ def generate_operators_doc(
334436
335437
Parameters
336438
----------
337-
ansys_path:
338-
Path to an Ansys/DPF installation.
339439
output_path:
340440
Path to write the output files at.
441+
ansys_path:
442+
Path to an Ansys/DPF installation.
341443
include_composites:
342444
Whether to include operators of the Composites plugin.
343445
include_sound:
@@ -357,7 +459,10 @@ def generate_operators_doc(
357459
operators = get_plugin_operators(server, desired_plugin)
358460
for operator_name in operators:
359461
generate_operator_doc(server, operator_name, include_private, output_path)
360-
generate_toc_tree(output_path)
462+
# Generate the toc tree
463+
update_toc_tree(output_path)
464+
# Use update files in output_path
465+
update_operator_descriptions(output_path)
361466

362467

363468
def run_with_args(): # pragma: nocover
@@ -368,9 +473,7 @@ def run_with_args(): # pragma: nocover
368473
parser.add_argument(
369474
"--ansys_path", default=None, help="Path to Ansys DPF Server installation directory"
370475
)
371-
parser.add_argument(
372-
"--output_path", default=None, help="Path to output directory", required=True
373-
)
476+
parser.add_argument("--output_path", default=".", help="Path to output directory")
374477
parser.add_argument("--include_private", action="store_true", help="Include private operators")
375478
parser.add_argument(
376479
"--include_composites", action="store_true", help="Include Composites operators"
@@ -389,8 +492,8 @@ def run_with_args(): # pragma: nocover
389492
args = parser.parse_args()
390493

391494
generate_operators_doc(
392-
ansys_path=args.ansys_path,
393495
output_path=args.output_path,
496+
ansys_path=args.ansys_path,
394497
include_composites=args.include_composites,
395498
include_sound=args.include_sound,
396499
include_private=args.include_private,

0 commit comments

Comments
 (0)