Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

docs: pin version in links to external docs #236

Merged
merged 9 commits into from
Mar 6, 2024
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Added

-
- docs: enable pin version in links to external docs ([#236](https://github.com/Lightning-AI/utilities/pull/236))


### Changed
Expand Down
6 changes: 6 additions & 0 deletions docs/source/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import lightning_utilities
import pt_lightning_sphinx_theme
from lightning_utilities.docs import fetch_external_assets
from lightning_utilities.docs.formatting import adjust_linked_external_docs

# -- Path setup --------------------------------------------------------------

Expand Down Expand Up @@ -46,6 +47,11 @@
# -- Project documents -------------------------------------------------------

fetch_external_assets(docs_folder=_PATH_HERE)
adjust_linked_external_docs(
source_link="https://numpy.org/doc/stable/",
target_link="https://numpy.org/doc/{numpy.__version__}/",
browse_folder=_PATH_HERE,
)


# export the READme
Expand Down
2 changes: 2 additions & 0 deletions requirements/_docs.txt
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,5 @@ sphinx-autodoc-typehints >=1.0
sphinx-paramlinks >=0.5.1
sphinx-togglebutton >=0.2
sphinx-copybutton >=0.3

numpy # for validation of custom/local version adjustemnt
79 changes: 78 additions & 1 deletion src/lightning_utilities/docs/formatting.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# http://www.apache.org/licenses/LICENSE-2.0
#
import glob
import importlib
import inspect
import logging
import os
import re
import sys
from typing import Tuple
from typing import Iterable, Optional, Tuple, Union


def _transform_changelog(path_in: str, path_out: str) -> None:
Expand Down Expand Up @@ -63,3 +67,76 @@ def find_source() -> Tuple[str, int, int]:
branch = {"latest": "master", "stable": "master"}.get(branch, branch)
filename = "/".join([branch] + filename.split("/")[1:])
return f"https://github.com/{github_user}/{github_repo}/blob/{filename}"


def _update_link_based_imported_package(link: str, pkg_ver: str, version_digits: Optional[int]) -> str:
"""Adjust the linked external docs to be local.

Args:
link: the source link to be replaced
pkg_ver: the target link to be replaced, if ``{package.version}`` is included it will be replaced accordingly
version_digits: for semantic versioning, how many digits to be considered

"""
pkg_att = pkg_ver.split(".")
# load the package with all additional sub-modules
module = importlib.import_module(".".join(pkg_att[:-1]))
# load the attribute
ver = getattr(module, pkg_att[-1])
# drop any additional context after `+`
ver = ver.split("+")[0]
# crop the version to the number of digits
ver = ".".join(ver.split(".")[:version_digits])
# replace the version
return link.replace(f"{{{pkg_ver}}}", ver)


def adjust_linked_external_docs(
source_link: str,
target_link: str,
browse_folder: Union[str, Iterable[str]],
file_extensions: Iterable[str] = (".rst", ".py"),
version_digits: int = 2,
) -> None:
r"""Adjust the linked external docs to be local.

Args:
source_link: the link to be replaced
target_link: the link to be replaced, if ``{package.version}`` is included it will be replaced accordingly
browse_folder: the location of the browsable folder
file_extensions: what kind of files shall be scanned
version_digits: for semantic versioning, how many digits to be considered

Examples:
>>> adjust_linked_external_docs(
... "https://numpy.org/doc/stable/",
... "https://numpy.org/doc/{numpy.__version__}/",
... "docs/source",
... )

"""
list_files = []
if isinstance(browse_folder, str):
browse_folder = [browse_folder]
for folder in browse_folder:
for ext in file_extensions:
list_files += glob.glob(os.path.join(folder, "**", f"*{ext}"), recursive=True)
if not list_files:
logging.warning(f'No files were listed in folder "{browse_folder}" and pattern "{file_extensions}"')
return

# find the expression for package version in {} brackets if any, use re to find it
pkg_ver_all = re.findall(r"{([\w.]+)}", target_link)
for pkg_ver in pkg_ver_all:
target_link = _update_link_based_imported_package(target_link, pkg_ver, version_digits)

# replace the source link with target link
for fpath in set(list_files):
with open(fpath, encoding="UTF-8") as fopen:
body = fopen.read()
body_ = body.replace(source_link, target_link)
if body == body_:
continue
logging.debug(f'links adjusting in {fpath}: "{source_link}" -> "{target_link}"')
with open(fpath, "w", encoding="UTF-8") as fw:
fw.write(body_)
Loading