Skip to content

Commit 80900f2

Browse files
committed
feat: script for automatic link update when releasing (#297)
* fix: cleanup links.rst * fix: PySeascape links * feat: automatically replace links * fix: pre-commit * fix: typo * feat: improve robustness * fix: pre-commit * fix: typo * docs: module docstring * Apply suggestions from code review
1 parent 924fc4d commit 80900f2

File tree

3 files changed

+167
-122
lines changed

3 files changed

+167
-122
lines changed

doc/source/getting_started.rst

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ Getting started
33

44
PyAnsys libraries fall into two categories:
55

6-
- Wrappers over products like `MAPDL <https://www.ansys.com/training-center/course-catalog/structures/ansys-mechanical-advanced-use-of-mapdl-in-mechanical>`_, `Fluent <https://www.ansys.com/products/fluids/ansys-fluent>`_, or `AEDT <https://www.ansys.com/products/electronics/ansys-maxwell>`_
6+
- Wrappers over products like `MAPDL <mapdl_course_>`_, `Fluent <ansys_fluent_page_>`_, or `AEDT <ansys_aedt_page_>`_
77
- Supporting libraries like `DPF <dpf_post_gh_>`_
88

99
Most PyAnsys packages require a local installation of Ansys. The version
@@ -15,7 +15,7 @@ the host machine.
1515

1616
For more information on getting a licensed copy of Ansys, visit `Ansys
1717
<ansys_>`_. If you are a student, consider installing a student version by
18-
visiting `Ansys for Students <https://www.ansys.com/academic/students>`_.
18+
visiting `Ansys for Students <ansys_students_>`_.
1919

2020

2121
************
@@ -44,7 +44,7 @@ User mode installation
4444
^^^^^^^^^^^^^^^^^^^^^^
4545

4646
Before installing ``pyansys`` in user mode, ensure that you have the latest
47-
version of `pip <https://pypi.org/project/pip/>`_ with:
47+
version of `pip`_ with:
4848

4949
.. code:: bash
5050
@@ -74,9 +74,8 @@ Offline mode installation
7474

7575
If you lack an internet connection on your installation machine, the
7676
recommended way of installing the ``pyansys`` metapackage is downloading the
77-
wheelhouse archive from the `Releases Page
78-
<https://github.com/ansys/pyansys/releases>`_ for your corresponding machine
79-
architecture.
77+
wheelhouse archive from the `Releases Page <pyansys_releases_>`_ for your
78+
corresponding machine architecture.
8079

8180
Each wheelhouse archive contains all the Python wheels necessary to install
8281
``pyansys`` metapackage from scratch on Windows, Linux, and MacOS from Python
@@ -93,7 +92,7 @@ it with the following:
9392
9493
If you're on Windows with Python 3.9, unzip to a wheelhouse directory and install using the same command as above.
9594

96-
Consider installing using a `virtual environment <https://docs.python.org/3/library/venv.html>`_.
95+
Consider installing using a `virtual environment <venv_docs_>`_.
9796

9897

9998
Versioning system

doc/source/links.rst

Lines changed: 8 additions & 115 deletions
Original file line numberDiff line numberDiff line change
@@ -1,118 +1,11 @@
1-
.. #Pyansys
2-
.. _pyansys: https://docs.pyansys.com
3-
.. _pyansys_support: [email protected]
4-
5-
.. #Other projects
6-
.. _dpf_core_gh: https://github.com/ansys/pydpf-core
1+
.. #Getting started
2+
.. _mapdl_course: https://www.ansys.com/training-center/course-catalog/structures/ansys-mechanical-advanced-use-of-mapdl-in-mechanical
3+
.. _ansys_fluent_page: https://www.ansys.com/products/fluids/ansys-fluent
4+
.. _ansys_aedt_page: https://www.ansys.com/products/electronics/ansys-maxwell
75
.. _dpf_post_gh: https://github.com/ansys/pydpf-post
8-
.. _dpf_core_docs: https://dpf.docs.pyansys.com/
9-
.. _dpf_post_docs: https://post.docs.pyansys.com/
10-
.. _legacy_reader_docs: https://reader.docs.pyansys.com/
11-
.. _example_data_repo: https://github.com/ansys/example-data
12-
13-
.. #PyAnsys Developer Guide
14-
.. _dev_guide_pyansys: https://dev.docs.pyansys.com/
15-
.. _dev_guide_contributing: https://dev.docs.pyansys.com/how-to/contributing.html
16-
.. _dev_guide_coding_style: https://dev.docs.pyansys.com/coding-style/index.html
17-
18-
.. #Other libraries
19-
.. _pyvista_docs: https://docs.pyvista.org
20-
.. _jupyter: https://jupyter.org/
216
.. _grpc: https://grpc.io/
22-
.. _numpy_docs: https://numpy.org/doc/stable/
23-
.. _matplotlib_docs: https://matplotlib.org/stable/contents.html
24-
.. _matplotlib_main: https://matplotlib.org
25-
.. _precommit: https://pre-commit.com/
26-
.. _gmsh: https://gmsh.info/
27-
.. _scipy_docs: https://docs.scipy.org/doc/scipy/reference/
28-
.. _docker: https://www.docker.com/
29-
30-
31-
.. #Ansys
327
.. _ansys: https://www.ansys.com/
33-
.. _ansys_student_version: https://www.ansys.com/academic/students
34-
.. _ansys_innovation_space: https://courses.ansys.com/
35-
.. _ansys_platform_support: https://www.ansys.com/solutions/solutions-by-role/it-professionals/platform-support
36-
.. _ansys_current_release: https://download.ansys.com/Current%20Release
37-
38-
.. # TechDemos related
39-
.. _tech_demo_intro: https://ansyshelp.ansys.com/Views/Secured/corp/v212/en/ans_tec/tecintro.html
40-
.. _tech_demo_repo: https://github.com/ansys/pymapdl-examples
41-
.. _tech_demos_doc: https://examples.mapdl.docs.pyansys.com/
42-
43-
.. #Ansys internal documentation
44-
.. _ansys_help: https://ansyshelp.ansys.com
45-
.. _ansys_installation_and_licensing: https://ansyshelp.ansys.com/account/secured?returnurl=/Views/Secured/prod_page.html?pn=Installation%20and%20Licensing&pid=InstallationAndLicensing&lang=en
46-
.. _ansys_parallel_computing_guide: https://ansyshelp.ansys.com/account/secured?returnurl=/Views/Secured/corp/v222/en/ans_dan/dantoc.html
47-
48-
.. # Ansys Structural Guide links:
49-
.. _ansys_krylov_sweep_harmonic_analysis: https://ansyshelp.ansys.com/account/secured?returnurl=/Views/Secured/corp/v222/en/ans_str/str_Krysweep.html
50-
51-
.. #Ansys learning
52-
.. _course_intro_python: https://courses.ansys.com/index.php/courses/intro-to-python/
53-
.. _course_getting_started_pymapdl: https://courses.ansys.com/index.php/courses/getting-started-with-pymapdl/
54-
.. _course_intro_apdl: https://courses.ansys.com/index.php/courses/intro-to-ansys-mechanical-apdl-scripting/
55-
56-
.. #External links
57-
.. _padt_post: https://www.padtinc.com/2022/07/18/ansys-scripting-python-p1-solve-post/
58-
.. _padt_licensing: https://www.padtinc.com/blog/15271-2/
59-
.. _install_wsl_microsoft: https://docs.microsoft.com/en-us/windows/wsl/install/
60-
.. _WikipediaWSL: https://en.wikipedia.org/wiki/Windows_Subsystem_for_Linux
61-
.. _What_is_the_Windows_Subsystem_for_Linux: https://docs.microsoft.com/en-us/windows/wsl/about
62-
.. _open_port_windows_10: https://answers.microsoft.com/en-us/windows/forum/all/how-to-open-port-in-windows-10-firewall/f38f67c8-23e8-459d-9552-c1b94cca579a/
63-
.. _disabling_firewall_on_wsl: https://github.com/cascadium/wsl-windows-toolbar-launcher#firewall-rules
64-
.. _article_good_unit_test: https://stackoverflow.com/questions/61400/what-makes-a-good-unit-test
65-
.. _vscode_attach_to_container: https://code.visualstudio.com/docs/devcontainers/attach-container
66-
.. _ubuntu_firewall: https://ubuntu.com/server/docs/security-firewall
67-
68-
.. #Github links:
69-
.. _gh_creating_pat: https://help.github.com/en/github/authenticating-to-github/creating-a-personal-access-token
70-
.. _gh_centos_wsl_1: https://github.com/wsldl-pg/CentWSL/
71-
.. _gh_centos_wsl_2: https://github.com/mishamosher/CentOS-WSL/
72-
.. _codecov: https://github.com/codecov
73-
74-
.. #PyMAPDL related
75-
.. _pymapdl_main: pymapdl_docs_
76-
.. _pymapdl_pypi: https://pypi.org/project/ansys-mapdl-core/
77-
.. _pymapdl_releases: https://github.com/ansys/pymapdl/releases
78-
.. _pymapdl_run_ubuntu: https://mapdl.docs.pyansys.com/troubleshoot/troubleshoot.html?#ubuntu
79-
.. _pymapdl_issues: https://github.com/ansys/pymapdl/issues
80-
.. _pymapdl_repo: https://github.com/ansys/pymapdl
81-
.. _pymapdl_docs: https://mapdl.docs.pyansys.com/
82-
.. _pymapdl_dev_docs: https://dev.mapdl.docs.pyansys.com/
83-
.. _pymapdl_discussions: https://github.com/ansys/PyMAPDL/discussions
84-
.. _pymapdl_cheatsheet: ./_assets/Cheat_Sheet_PyMAPDL.pdf
85-
.. _pymapdl_tests: https://github.com/ansys/pymapdl/tree/main/tests
86-
.. _pymapdl_test_math: https://github.com/ansys/pymapdl/blob/main/tests/test_math.py
87-
.. _pymapdl_user_guide_math: https://mapdl.docs.pyansys.com/user_guide/math.html
88-
.. _licensing_guide_pdf: ./_assets/lic_guide.pdf
89-
.. _mapdl_fixture: https://github.com/ansys/pymapdl/blob/fb5fb8b6201253f1bd56bdabee60a29abee8c7d8/tests/conftest.py#L254
90-
.. _pymapdl_examples: https://github.com/ansys/pymapdl/tree/main/examples
91-
.. _pymapdl_2d_plate_with_a_hole: https://github.com/ansys/pymapdl/blob/main/examples/00-mapdl-examples/2d_plate_with_a_hole.py
92-
.. _pymapdl_doc_2d_plate_with_a_hole: https://mapdl.docs.pyansys.com/examples/gallery_examples/00-mapdl-examples/2d_plate_with_a_hole.html
93-
.. _pymapdl_doc_krylov_example: https://dev.mapdl.docs.pyansys.com/examples/extended_examples/Krylov/krylov_example.html
94-
.. _pymapdl_doc_krylov_example_rst: https://raw.githubusercontent.com/pyansys/pymapdl/main/doc/source/examples/extended_examples/Krylov/krylov_example.rst
95-
.. _pymapdl_doc_source: https://github.com/ansys/pymapdl/tree/main/doc/source
96-
.. _pymapdl_techdemo_28_rst: https://raw.githubusercontent.com/pyansys/pymapdl-examples/main/doc/source/technology_showcase_examples/techdemo-28/ex_28-tecfricstir.rst
97-
.. _pymapdl_techdemo_28: https://examples.mapdl.docs.pyansys.com/technology_showcase_examples/techdemo-28/ex_28-tecfricstir.html
98-
.. _pymapdl_docker_dir: https://github.com/ansys/pymapdl/blob/main/docker
99-
.. _pymapdl_docker_compose_base: https://github.com/ansys/pymapdl/blob/main/docker/docker-compose.yml
100-
.. _pymapdl_docker_compose_local: https://github.com/ansys/pymapdl/blob/main/docker/docker-compose.local.yml
101-
.. _pymapdl_docker_compose_license_server: https://github.com/ansys/pymapdl/blob/main/docker/docker-compose.license_server.yml
102-
103-
.. #Python
104-
.. _using_venv: https://docs.python.org/3/library/venv.html
105-
.. _conda: https://conda.io
106-
.. _pytest: https://docs.pytest.org/en/7.2.x/
107-
.. _pytest_usage: https://docs.pytest.org/en/7.2.x/how-to/usage.html#specifying-which-tests-to-run
108-
109-
.. #Julia
110-
.. _julia: https://julialang.org/
111-
.. _julia_windows: https://julialang.org/downloads/platform/#windows
112-
.. _julia_linux_and_freebsd: https://julialang.org/downloads/platform/#linux_and_freebsd
113-
.. _julia_macos: https://julialang.org/downloads/platform/#macos
114-
.. _pycall: https://github.com/JuliaPy/PyCall.jl
115-
116-
.. # Ansys forums
117-
.. _ansys_forum: https://forum.ansys.com/
118-
.. _af_licensing_windows_ubuntu: https://forum.ansys.com/forums/topic/licensing-2022-r2-linux-ubuntu-and-also-windows/
8+
.. _ansys_students: https://www.ansys.com/academic/students
9+
.. _pip: https://pypi.org/project/pip/
10+
.. _pyansys_releases: https://github.com/ansys/pyansys/releases
11+
.. _venv_docs: https://docs.python.org/3/library/venv.html

tools/links.py

Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
"""
2+
Script for automatic replacement of released links.
3+
4+
Usage is very simple. Just run the script.
5+
6+
.. code:: python
7+
8+
python links.py
9+
"""
10+
11+
import os
12+
import re
13+
14+
ROOT_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
15+
"""Root directory of the project relative to this file."""
16+
17+
PYPROJECT_TOML_FILE = os.path.join(ROOT_DIR, "pyproject.toml")
18+
"""Path to pyproject.toml file."""
19+
20+
DOCS_DIRECTORY = os.path.join(ROOT_DIR, "doc", "source")
21+
"""Path to the documentation source directory"""
22+
23+
LINKS = {
24+
"ansys-mapdl-core": "https://mapdl.docs.pyansys.com/version/stable",
25+
"ansys-mapdl-reader": "https://reader.docs.pyansys.com/version/stable",
26+
"ansys-dpf-core": "https://dpf.docs.pyansys.com/version/stable",
27+
"ansys-dpf-post": "https://post.docs.pyansys.com/version/stable",
28+
"ansys-dpf-gate": None,
29+
"ansys-dpf-composites": "https://composites.dpf.docs.pyansys.com/version/stable", # noqa: E501
30+
"ansys-fluent-core": "https://fluent.docs.pyansys.com/version/stable",
31+
"ansys-fluent-visualization": "https://visualization.fluent.docs.pyansys.com/version/stable", # noqa: E501
32+
"ansys-fluent-parametric": "https://parametric.fluent.docs.pyansys.com/version/stable", # noqa: E501
33+
"pyaedt": "https://aedt.docs.pyansys.com/version/stable",
34+
"ansys-platform-instancemanagement": None,
35+
"ansys-grantami-bomanalytics": "https://bomanalytics.grantami.docs.pyansys.com/version/stable", # noqa: E501
36+
"ansys-grantami-recordlists": "https://recordlists.grantami.docs.pyansys.com/version/stable", # noqa: E501
37+
"ansys-openapi-common": None,
38+
"ansys-seascape": "https://seascape.docs.pyansys.com/version/stable",
39+
"ansys-sherlock-core": "https://sherlock.docs.pyansys.com/version/stable",
40+
"ansys-meshing-prime": "https://prime.docs.pyansys.com/version/stable",
41+
"pytwin": "https://twin.docs.pyansys.com/version/stable",
42+
"ansys-systemcoupling-core": "https://systemcoupling.docs.pyansys.com/version/stable", # noqa: E501
43+
"ansys-motorcad-core": "https://motorcad.docs.pyansys.com/version/stable",
44+
"ansys-math-core": "https://math.docs.pyansys.com/version/stable",
45+
"ansys-optislang-core": "https://optislang.docs.pyansys.com/version/stable", # noqa: E501
46+
"ansys-mechanical-core": "https://mechanical.docs.pyansys.com/version/stable", # noqa: E501
47+
}
48+
"""Dictionary with PyAnsys packages and their multi-version docs site."""
49+
50+
51+
def retrieve_major_minor(package: str):
52+
"""Extract the major and minor version of a pinned package.
53+
54+
Notes
55+
-----
56+
This function navigates to the package's pyproject.toml file
57+
58+
and processes it to retrieve the desired major, minor version.
59+
60+
61+
Parameters
62+
----------
63+
package : str
64+
The package to be searched for.
65+
66+
67+
Returns
68+
-------
69+
tuple of (int, int)
70+
The major and minor versions of the package.
71+
72+
"""
73+
with open(PYPROJECT_TOML_FILE, "r") as file:
74+
content = file.read()
75+
pattern = r"\b" + re.escape(package) + r"==(\d+)\.(\d+)"
76+
match = re.search(pattern, content)
77+
78+
if match:
79+
major_version = int(match.group(1))
80+
minor_version = int(match.group(2))
81+
return (major_version, minor_version)
82+
83+
return (None, None)
84+
85+
86+
def search_and_replace(link: str, new_link: str):
87+
"""Replace existing link with the newly provided link.
88+
89+
Parameters
90+
----------
91+
link : str
92+
The link to be searched for.
93+
new_link : str
94+
The link to replace the existing one.
95+
"""
96+
# Traverse the docs directory
97+
for root, _, files in os.walk(DOCS_DIRECTORY):
98+
# Skip the _static subdirectory
99+
if "_static" in root.split(os.sep):
100+
continue
101+
102+
# Process the files
103+
for file in files:
104+
file_path = os.path.join(root, file)
105+
with open(file_path, "r") as f:
106+
content = f.read()
107+
108+
# Search for the link in the content, replace and save
109+
if link in content:
110+
new_content = content.replace(link, new_link)
111+
112+
with open(file_path, "w") as f:
113+
f.write(new_content)
114+
115+
print(f"Replaced '{link}' with '{new_link}' in file: {file_path}") # noqa: E501
116+
117+
118+
def released_docs():
119+
"""Update links for released documentation.
120+
121+
Notes
122+
-----
123+
Links are expected to point to a certain version when released
124+
inside the metapackage, and not to the latest stable version. This
125+
module takes care of updating the links automatically. The script has to
126+
be run locally and the changes have to be committed to the release branch
127+
prior to releasing.
128+
"""
129+
# Loop over all the above defined packages
130+
for key, value in LINKS.items():
131+
# Packages that are not adapted to multi-version have a None
132+
# link associated as its value... skip them.
133+
if value is None:
134+
continue
135+
136+
# Retrieve the major and minor versions of the package
137+
major, minor = retrieve_major_minor(key)
138+
139+
if major is None and minor is None:
140+
# No match found for the link... throw message
141+
print(f"Error retrieving minor/major version of {key}... Skipping.") # noqa: E501
142+
continue
143+
144+
# Define the new link
145+
link_root = value.split("/version/")[0]
146+
new_link = f"{link_root}/version/{major}.{minor}"
147+
148+
# Search and replace through all our docs links
149+
search_and_replace(value, new_link)
150+
151+
152+
if __name__ == "__main__":
153+
released_docs()

0 commit comments

Comments
 (0)