Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
14 changes: 8 additions & 6 deletions docs/source/plugin_list.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,15 @@ Packages classified as inactive are excluded.

!!! warning

Please be aware that this list is not a curated collection of projects and does not
undergo a systematic review process. It serves purely as an informational resource to
aid in the discovery of `pytask` plugins.
```
Please be aware that this list is not a curated collection of projects and does not
undergo a systematic review process. It serves purely as an informational resource
to aid in the discovery of `pytask` plugins.

Do not presume any endorsement from the `pytask` project or its developers, and always
conduct your own quality assessment before incorporating any of these plugins into your
own projects.
Do not presume any endorsement from the `pytask` project or its developers, and
always conduct your own quality assessment before incorporating any of these plugins
into your own projects.
```

This list contains 6 plugins.

Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ docs = [
"zensical>=0.0.23",
]
docs-live = ["sphinx-autobuild>=2024.10.3"]
plugin-list = ["httpx>=0.27.0", "tabulate[widechars]>=0.9.0", "tqdm>=4.66.3"]
plugin-list = ["httpx>=0.27.0", "tabulate[widechars]>=0.9.0"]
test = [
"cloudpickle>=3.0.0",
"deepdiff>=7.0.0",
Expand Down
64 changes: 49 additions & 15 deletions scripts/update_plugin_list.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,27 +37,27 @@

import httpx
import packaging.version
import tabulate
import wcwidth
from tqdm import tqdm

if TYPE_CHECKING:
from collections.abc import Generator

_FILE_HEAD = """# Plugin List

PyPI projects that match `pytask-*` are considered plugins and are listed
automatically. Packages classified as inactive are excluded.
PyPI projects that match `pytask-*` are considered plugins and are listed automatically.
Packages classified as inactive are excluded.

!!! warning

Please be aware that this list is not a curated collection of projects and does not
undergo a systematic review process. It serves purely as an informational resource
to aid in the discovery of `pytask` plugins.
```
Please be aware that this list is not a curated collection of projects and does not
undergo a systematic review process. It serves purely as an informational resource
to aid in the discovery of `pytask` plugins.

Do not presume any endorsement from the `pytask` project or its developers, and
always conduct your own quality assessment before incorporating any of these plugins
into your own projects.
Do not presume any endorsement from the `pytask` project or its developers, and
always conduct your own quality assessment before incorporating any of these plugins
into your own projects.
```

"""

Expand Down Expand Up @@ -86,6 +86,43 @@ def _escape_markdown(text: str) -> str:
return text.replace("|", "\\|")


def _pad(text: str, width: int) -> str:
"""Pad text to the requested display width."""
return text + " " * (width - wcwidth.wcswidth(text))


def _create_table(entries: list[dict[str, str]]) -> str:
"""Create a markdown table in the repository's canonical format."""
if not entries:
msg = "Cannot create a plugin table without entries."
raise ValueError(msg)

headers = list(entries[0])
widths = [
max(
wcwidth.wcswidth(header),
*(wcwidth.wcswidth(row[header]) for row in entries),
)
for header in headers
]

header_cells = (
_pad(header, width) for header, width in zip(headers, widths, strict=False)
)
header = "| " + " | ".join(header_cells) + " |"
separator = "| " + " | ".join("-" * width for width in widths) + " |"
rows = [
"| "
+ " | ".join(
_pad(row[header], width)
for header, width in zip(headers, widths, strict=False)
)
+ " |"
for row in entries
]
return "\n".join([header, separator, *rows])


def _iter_plugins() -> Generator[dict[str, str], None, None]: # noqa: C901
"""Iterate over all plugins and format entries."""
regex = r">([\d\w-]*)</a>"
Expand All @@ -98,7 +135,7 @@ def _iter_plugins() -> Generator[dict[str, str], None, None]: # noqa: C901
and match.groups()[0] not in _EXCLUDED_PACKAGES
]

for match in tqdm(matches, smoothing=0):
for match in matches:
name = match.groups()[0]
response = httpx.get(f"https://pypi.org/pypi/{name}/json", timeout=20)
if response.status_code == 404: # noqa: PLR2004
Expand Down Expand Up @@ -168,10 +205,7 @@ def main() -> None:
with plugin_list.open("w") as f:
f.write(_FILE_HEAD)
f.write(f"This list contains {len(plugins)} plugins.\n\n")

assert wcwidth # reference library that must exist for tabulate to work
plugin_table = tabulate.tabulate(plugins, headers="keys", tablefmt="github")
f.write(plugin_table)
f.write(_create_table(plugins))
f.write("\n")


Expand Down
Loading
Loading