diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md
index ac1a1c98..f88f4119 100644
--- a/RELEASE_NOTES.md
+++ b/RELEASE_NOTES.md
@@ -2,7 +2,7 @@
## Summary
-
+This release introduces a new MkDocs macros *pluglet* system that simplifies documentation setup and provides enhanced functionality for version information and code annotations. It also includes changes to how pytest warnings are handled in templates.
## Upgrading
@@ -15,13 +15,21 @@
### Cookiecutter template
-All upgrading should be done via the migration script or regenerating the templates. But you might still need to adapt your code:
+All upgrading should be done via the migration script or regenerating the templates.
+
+```bash
+curl -sSL https://raw.githubusercontent.com/frequenz-floss/frequenz-repo-config-python/v0.12/cookiecutter/migrate.py | python3
+```
+
+But you might still need to adapt your code:
- `pytest` now uses `-Werror` by default (but still treat deprecations as normal warnings), so if your tests run with warnings, they will now be turned to errors, and you'll need to fix them.
+- Projects using `docs/_scripts/macros.py` with customized scripts can use the new provided utility functions. See the [`mkdocstrings_macros` documentation](https://frequenz-floss.github.io/frequenz-repo-config-python/v0.12/reference/frequenz/repo/config/mkdocs/mkdocstrings_macros/) for the new features and setup.
+
## New Features
-
+- Two new modules were introduced to facilitate the configuration of `macros` for use within docstrings via `mkdocstrings`: [`mkdocstrings_macros`](https://frequenz-floss.github.io/frequenz-repo-config-python/v0.12/reference/frequenz/repo/config/mkdocs/mkdocstrings_macros/) and [`annotations`](https://frequenz-floss.github.io/frequenz-repo-config-python/v0.12/reference/frequenz/repo/config/mkdocs/annotations/).
### Cookiecutter template
@@ -29,8 +37,6 @@ All upgrading should be done via the migration script or regenerating the templa
## Bug Fixes
-
-
### Cookiecutter template
- Fixed a compatibility issue in the macros doc script with `mkdocsstrings` 0.28.
diff --git a/cookiecutter/migrate.py b/cookiecutter/migrate.py
index a20ca6da..de0f83ae 100644
--- a/cookiecutter/migrate.py
+++ b/cookiecutter/migrate.py
@@ -20,6 +20,7 @@
And remember to follow any manual instructions for each run.
""" # noqa: E501
+import hashlib
import os
import subprocess
import tempfile
@@ -30,8 +31,8 @@
def main() -> None:
"""Run the migration steps."""
add_default_pytest_options()
-
- # Add a separation line like this one after each migration step.
+ print("=" * 72)
+ migrate_mkdocs_macros()
print("=" * 72)
@@ -64,6 +65,92 @@ def add_default_pytest_options() -> None:
)
+def migrate_mkdocs_macros() -> None:
+ """Migrate from custom macros.py to standard module."""
+ macros_file = Path("docs/_scripts/macros.py")
+ mkdocs_yaml = Path("mkdocs.yaml")
+ if not mkdocs_yaml.exists():
+ mkdocs_yaml = Path("mkdocs.yml")
+
+ known_hashes = {
+ "47a991286132471b6cb666577beb89e78c0f5d4975c53f0dcb319c4338a2c3cb",
+ "6bb960c72b370ac77918f49d7a35f39c0ddb58fe52cf2d12caa2577098fd8469",
+ "7351276ac314955a343bab09d1602e50300887291f841643e9fb79c94acc923c",
+ "8fa5f9f3fd928e17f590e3ab056434474633259d615971404db0d2f3034adb62",
+ "ba3ff5f1612b3dd22372a8ca95394b8ea468f18dcefc494c73811c8433fcb880",
+ "dd32e8759abc43232bb3db5b33c0a7cf8d8442db6135c594968c499d8bae0ce5",
+ }
+
+ print("Checking if docs/_scripts/macros.py can be migrated...")
+
+ file_hash = calculate_file_sha256_skip_lines(macros_file, 2)
+ if not file_hash:
+ return
+
+ if file_hash not in known_hashes:
+ manual_step("The macros.py file seems to be customized. You have two options:")
+ manual_step("")
+ manual_step(
+ "1. Switch to the standard module (if you don't have custom macros):"
+ )
+ manual_step(" a. Update mkdocs.yaml to use the standard module:")
+ manual_step(
+ ' module_name: docs/_scripts/macros -> modules: ["frequenz.repo.config.mkdocs.mkdocstrings_macros"]' # noqa: E501
+ )
+ manual_step(" b. Remove docs/_scripts/macros.py")
+ manual_step("")
+ manual_step("2. Keep your custom macros but use the standard functionality:")
+ manual_step(" a. Update mkdocs.yaml:")
+ manual_step(" - Keep using module_name: docs/_scripts/macros")
+ manual_step(" b. Update your macros.py to be minimal:")
+ manual_step(" ```python")
+ manual_step(
+ " from frequenz.repo.config.mkdocs.mkdocstrings_macros import hook_env_with_everything" # noqa: E501
+ )
+ manual_step("")
+ manual_step(" def define_env(env):")
+ manual_step(" # Add your custom variables, filters, and macros here")
+ manual_step(" env.variables.my_var = 'Example'")
+ manual_step(" env.filters.my_filter = lambda x: x.upper()")
+ manual_step("")
+ manual_step(
+ " # This must be at the end to enable all standard features"
+ )
+ manual_step(" hook_env_with_everything(env)")
+ manual_step(" ```")
+ manual_step("")
+ manual_step("See the docs for more details:")
+ manual_step(
+ "https://frequenz-floss.github.io/frequenz-repo-config-python/v0.12/reference/frequenz/repo/config/mkdocs/mkdocstrings_macros/" # noqa: E501
+ )
+ return
+
+ if not mkdocs_yaml.exists():
+ print("mkdocs.yaml/yml not found, skipping macros migration")
+ return
+
+ content = mkdocs_yaml.read_text(encoding="utf-8")
+ if "module_name: docs/_scripts/macros" not in content:
+ print("Custom macros configuration not found in mkdocs.yaml")
+ return
+
+ print("Updating mkdocs.yaml to use standard module...")
+ new_content = content.replace(
+ "module_name: docs/_scripts/macros",
+ 'modules: ["frequenz.repo.config.mkdocs.mkdocstrings_macros"]',
+ )
+ new_content = new_content.replace(
+ "# inside docstrings. See the comment in `docs/_scripts/macros.py` for more\n"
+ " # details\n",
+ "# inside docstrings.\n",
+ )
+
+ replace_file_contents_atomically(mkdocs_yaml, content, new_content)
+
+ print("Removing docs/_scripts/macros.py...")
+ macros_file.unlink()
+
+
def apply_patch(patch_content: str) -> None:
"""Apply a patch using the patch utility."""
subprocess.run(["patch", "-p1"], input=patch_content.encode(), check=True)
@@ -134,5 +221,25 @@ def manual_step(message: str) -> None:
print(f"\033[0;33m>>> {message}\033[0m")
+def calculate_file_sha256_skip_lines(filepath: Path, skip_lines: int) -> str | None:
+ """Calculate SHA256 of file contents excluding the first N lines.
+
+ Args:
+ filepath: Path to the file to hash
+ skip_lines: Number of lines to skip at the beginning
+
+ Returns:
+ The SHA256 hex digest, or None if the file doesn't exist
+ """
+ if not filepath.exists():
+ return None
+
+ # Read file and normalize line endings to LF
+ content = filepath.read_text(encoding="utf-8").replace("\r\n", "\n")
+ # Skip first N lines and ensure there's a trailing newline
+ remaining_content = "\n".join(content.splitlines()[skip_lines:]) + "\n"
+ return hashlib.sha256(remaining_content.encode()).hexdigest()
+
+
if __name__ == "__main__":
main()
diff --git a/cookiecutter/{{cookiecutter.github_repo_name}}/docs/_scripts/macros.py b/cookiecutter/{{cookiecutter.github_repo_name}}/docs/_scripts/macros.py
deleted file mode 100644
index 9afe325c..00000000
--- a/cookiecutter/{{cookiecutter.github_repo_name}}/docs/_scripts/macros.py
+++ /dev/null
@@ -1,80 +0,0 @@
-# License: {{cookiecutter.license}}
-# Copyright © {{copyright_year}} {{cookiecutter.author_name}}
-
-"""This module defines macros for use in Markdown files."""
-
-from typing import Any
-
-import markdown as md
-from markdown.extensions import toc
-from mkdocs_macros import plugin as macros
-
-_CODE_ANNOTATION_MARKER: str = (
- r''
- r''
- r''
- r""
- r""
-)
-
-
-def _slugify(text: str) -> str:
- """Slugify a text.
-
- Args:
- text: The text to slugify.
-
- Returns:
- The slugified text.
- """
- return toc.slugify_unicode(text, "-")
-
-
-def _hook_macros_plugin(env: macros.MacrosPlugin) -> None:
- """Integrate the `mkdocs-macros` plugin into `mkdocstrings`.
-
- This is a temporary workaround to make `mkdocs-macros` work with
- `mkdocstrings` until a proper `mkdocs-macros` *pluglet* is available. See
- https://github.com/mkdocstrings/mkdocstrings/issues/615 for details.
-
- Args:
- env: The environment to hook the plugin into.
- """
- # get mkdocstrings' Python handler
- python_handler = env.conf["plugins"]["mkdocstrings"].get_handler("python")
-
- # get the `update_env` method of the Python handler
- update_env = python_handler.update_env
-
- # override the `update_env` method of the Python handler
- def patched_update_env(md: md.Markdown, config: dict[str, Any]) -> None:
- update_env(md=md, config=config)
-
- # get the `convert_markdown` filter of the env
- convert_markdown = python_handler.env.filters["convert_markdown"]
-
- # build a chimera made of macros+mkdocstrings
- def render_convert(markdown: str, *args: Any, **kwargs: Any) -> Any:
- return convert_markdown(env.render(markdown), *args, **kwargs)
-
- # patch the filter
- python_handler.env.filters["convert_markdown"] = render_convert
-
- # patch the method
- python_handler.update_env = patched_update_env
-
-
-def define_env(env: macros.MacrosPlugin) -> None:
- """Define the hook to create macro functions for use in Markdown.
-
- Args:
- env: The environment to define the macro functions in.
- """
- # A variable to easily show an example code annotation from mkdocs-material.
- # https://squidfunk.github.io/mkdocs-material/reference/code-blocks/#adding-annotations
- env.variables["code_annotation_marker"] = _CODE_ANNOTATION_MARKER
-
- # TODO(cookiecutter): Add any other macros, variables and filters here.
-
- # This hook needs to be done at the end of the `define_env` function.
- _hook_macros_plugin(env)
diff --git a/cookiecutter/{{cookiecutter.github_repo_name}}/mkdocs.yml b/cookiecutter/{{cookiecutter.github_repo_name}}/mkdocs.yml
index 4110b297..2bb2105b 100644
--- a/cookiecutter/{{cookiecutter.github_repo_name}}/mkdocs.yml
+++ b/cookiecutter/{{cookiecutter.github_repo_name}}/mkdocs.yml
@@ -129,10 +129,9 @@ plugins:
{%- endif %}
- https://typing-extensions.readthedocs.io/en/stable/objects.inv
# Note this plugin must be loaded after mkdocstrings to be able to use macros
- # inside docstrings. See the comment in `docs/_scripts/macros.py` for more
- # details
+ # inside docstrings.
- macros:
- module_name: docs/_scripts/macros
+ modules: ["frequenz.repo.config.mkdocs.mkdocstrings_macros"]
on_undefined: strict
on_error_fail: true
- search
diff --git a/cookiecutter/{{cookiecutter.github_repo_name}}/pyproject.toml b/cookiecutter/{{cookiecutter.github_repo_name}}/pyproject.toml
index 4f95d637..7b254021 100644
--- a/cookiecutter/{{cookiecutter.github_repo_name}}/pyproject.toml
+++ b/cookiecutter/{{cookiecutter.github_repo_name}}/pyproject.toml
@@ -3,17 +3,17 @@
[build-system]
requires = [
- "setuptools == 75.5.0",
+ "setuptools == 75.8.0",
"setuptools_scm[toml] == 8.1.0",
- "frequenz-repo-config[{{cookiecutter.type}}] == 0.11.0",
+ "frequenz-repo-config[{{cookiecutter.type}}] == 0.12.0",
{%- if cookiecutter.type == "api" %}
# We need to pin the protobuf, grpcio and grpcio-tools dependencies to make
# sure the code is generated using the minimum supported versions, as older
# versions can't work with code that was generated with newer versions.
# https://protobuf.dev/support/cross-version-runtime-guarantee/#backwards
- "protobuf == 5.28.0",
- "grpcio-tools == 1.66.1",
- "grpcio == 1.66.1",
+ "protobuf == 5.29.3",
+ "grpcio-tools == 1.70.0",
+ "grpcio == 1.70.0",
{%- endif %}
]
build-backend = "setuptools.build_meta"
@@ -48,7 +48,7 @@ dependencies = [
# Make sure to update the version for cross-referencing also in the
# mkdocs.yml file when changing the version here (look for the config key
# plugins.mkdocstrings.handlers.python.import)
- "frequenz-sdk >= 1.0.0rc1300, < 1.0.0rc1400",
+ "frequenz-sdk >= 1.0.0rc1500, < 1.0.0rc1600",
]
{%- elif cookiecutter.type == "app" %}
dependencies = [
@@ -56,19 +56,19 @@ dependencies = [
# Make sure to update the version for cross-referencing also in the
# mkdocs.yml file when changing the version here (look for the config key
# plugins.mkdocstrings.handlers.python.import)
- "frequenz-sdk == 1.0.0rc1300",
+ "frequenz-sdk == 1.0.0rc1500",
]
{%- elif cookiecutter.type == "api" %}
dependencies = [
- "frequenz-api-common >= 0.6.2, < 0.7.0",
+ "frequenz-api-common >= 0.6.3, < 0.7.0",
# We can't widen beyond the current value unless we bump the minimum
# requirements too because of protobuf cross-version runtime guarantees:
# https://protobuf.dev/support/cross-version-runtime-guarantee/#major
- "protobuf >= 5.28.0, < 7", # Do not widen beyond 7!
+ "protobuf >= 5.29.3, < 7", # Do not widen beyond 7!
# We couldn't find any document with a spec about the cross-version runtime
# guarantee for grpcio, so unless we find one in the future, we'll assume
# major version jumps are not compatible
- "grpcio >= 1.66.1, < 2", # Do not widen beyond 2!
+ "grpcio >= 1.70.0, < 2", # Do not widen beyond 2!
]
{%- else %}
dependencies = [
@@ -87,34 +87,34 @@ dev-flake8 = [
"flake8 == 7.1.1",
"flake8-docstrings == 1.7.0",
"flake8-pyproject == 1.2.3", # For reading the flake8 config from pyproject.toml
- "pydoclint == 0.5.9",
+ "pydoclint == 0.6.0",
"pydocstyle == 6.3.0",
]
-dev-formatting = ["black == 24.10.0", "isort == 5.13.2"]
+dev-formatting = ["black == 25.1.0", "isort == 6.0.0"]
dev-mkdocs = [
"Markdown == 3.7",
- "black == 24.10.0",
+ "black == 25.1.0",
"mike == 2.1.3",
"mkdocs-gen-files == 0.5.0",
"mkdocs-literate-nav == 0.6.1",
"mkdocs-macros-plugin == 1.3.7",
- "mkdocs-material == 9.5.45",
+ "mkdocs-material == 9.6.2",
"mkdocstrings[python] == 0.28.0",
"mkdocstrings-python == 1.14.0",
- "frequenz-repo-config[{{cookiecutter.type}}] == 0.11.0",
+ "frequenz-repo-config[{{cookiecutter.type}}] == 0.12.0",
]
dev-mypy = [
"mypy == 1.9.0",
{%- if cookiecutter.type == "api" %}
- "grpc-stubs == 1.53.0.2",
+ "grpc-stubs == 1.53.0.5",
{%- endif %}
- "types-Markdown == 3.7.0.20240822",
+ "types-Markdown == 3.7.0.20241204",
# For checking the noxfile, docs/ script, and tests
"{{cookiecutter.pypi_package_name}}[dev-mkdocs,dev-noxfile,dev-pytest]",
]
dev-noxfile = [
"nox == 2024.10.9",
- "frequenz-repo-config[{{cookiecutter.type}}] == 0.11.0",
+ "frequenz-repo-config[{{cookiecutter.type}}] == 0.12.0",
]
dev-pylint = [
# dev-pytest already defines a dependency to pylint because of the examples
@@ -122,13 +122,13 @@ dev-pylint = [
"{{cookiecutter.pypi_package_name}}[dev-mkdocs,dev-noxfile,dev-pytest]",
]
dev-pytest = [
- "pytest == 8.3.3",
- "pylint == 3.3.1", # We need this to check for the examples
- "frequenz-repo-config[extra-lint-examples] == 0.11.0",
+ "pytest == 8.3.4",
+ "pylint == 3.3.4", # We need this to check for the examples
+ "frequenz-repo-config[extra-lint-examples] == 0.12.0",
{%- if cookiecutter.type != "api" %}
"pytest-mock == 3.14.0",
- "pytest-asyncio == 0.24.0",
- "async-solipsism == 0.6",
+ "pytest-asyncio == 0.25.3",
+ "async-solipsism == 0.7",
{%- endif %}
]
dev = [
diff --git a/docs/_scripts/macros.py b/docs/_scripts/macros.py
deleted file mode 100644
index 82d79d7d..00000000
--- a/docs/_scripts/macros.py
+++ /dev/null
@@ -1,108 +0,0 @@
-# License: MIT
-# Copyright © 2023 Frequenz Energy-as-a-Service GmbH
-
-"""This module defines macros for use in Markdown files."""
-
-import logging
-from typing import Any
-
-import markdown as md
-from markdown.extensions import toc
-from mkdocs_macros import plugin as macros
-
-from frequenz.repo.config import github
-
-_logger = logging.getLogger(__name__)
-
-_CODE_ANNOTATION_MARKER: str = (
- r''
- r''
- r''
- r""
- r""
-)
-
-
-def _slugify(text: str) -> str:
- """Slugify a text.
-
- Args:
- text: The text to slugify.
-
- Returns:
- The slugified text.
- """
- return toc.slugify_unicode(text, "-")
-
-
-def _add_version_variables(env: macros.MacrosPlugin) -> None:
- """Add variables with git information to the environment.
-
- Args:
- env: The environment to add the variables to.
- """
- env.variables["version"] = None
- env.variables["version_requirement"] = ""
- try:
- version_info = github.get_repo_version_info()
- except Exception as exc: # pylint: disable=broad-except
- _logger.warning("Failed to get version info: %s", exc)
- else:
- env.variables["version"] = version_info
- if version_info.current_tag:
- env.variables["version_requirement"] = f" == {version_info.current_tag}"
- elif version_info.current_branch:
- env.variables["version_requirement"] = (
- " @ git+https://github.com/frequenz-floss/frequenz-repo-config-python"
- f"@{version_info.current_branch}"
- )
-
-
-def _hook_macros_plugin(env: macros.MacrosPlugin) -> None:
- """Integrate the `mkdocs-macros` plugin into `mkdocstrings`.
-
- This is a temporary workaround to make `mkdocs-macros` work with
- `mkdocstrings` until a proper `mkdocs-macros` *pluglet* is available. See
- https://github.com/mkdocstrings/mkdocstrings/issues/615 for details.
-
- Args:
- env: The environment to hook the plugin into.
- """
- # get mkdocstrings' Python handler
- python_handler = env.conf["plugins"]["mkdocstrings"].get_handler("python")
-
- # get the `update_env` method of the Python handler
- update_env = python_handler.update_env
-
- # override the `update_env` method of the Python handler
- def patched_update_env(md: md.Markdown, config: dict[str, Any]) -> None:
- update_env(md=md, config=config)
-
- # get the `convert_markdown` filter of the env
- convert_markdown = python_handler.env.filters["convert_markdown"]
-
- # build a chimera made of macros+mkdocstrings
- def render_convert(markdown: str, *args: Any, **kwargs: Any) -> Any:
- return convert_markdown(env.render(markdown), *args, **kwargs)
-
- # patch the filter
- python_handler.env.filters["convert_markdown"] = render_convert
-
- # patch the method
- python_handler.update_env = patched_update_env
-
-
-def define_env(env: macros.MacrosPlugin) -> None:
- """Define the hook to create macro functions for use in Markdown.
-
- Args:
- env: The environment to define the macro functions in.
- """
- # A variable to easily show an example code annotation from mkdocs-material.
- # https://squidfunk.github.io/mkdocs-material/reference/code-blocks/#adding-annotations
- env.variables["code_annotation_marker"] = _CODE_ANNOTATION_MARKER
-
- _add_version_variables(env)
-
- # This hook needs to be done at the end of the `define_env` function.
- _hook_macros_plugin(env)
diff --git a/mkdocs.yml b/mkdocs.yml
index b26e85f6..f9a0397a 100644
--- a/mkdocs.yml
+++ b/mkdocs.yml
@@ -124,10 +124,9 @@ plugins:
- https://sybil.readthedocs.io/en/stable/objects.inv
- https://typing-extensions.readthedocs.io/en/stable/objects.inv
# Note this plugin must be loaded after mkdocstrings to be able to use macros
- # inside docstrings. See the comment in `docs/_scripts/macros.py` for more
- # details
+ # inside docstrings.
- macros:
- module_name: docs/_scripts/macros
+ modules: ["frequenz.repo.config.mkdocs.mkdocstrings_macros"]
on_undefined: strict
on_error_fail: true
- search
diff --git a/src/frequenz/repo/config/mkdocs/annotations.py b/src/frequenz/repo/config/mkdocs/annotations.py
new file mode 100644
index 00000000..08e0e7db
--- /dev/null
+++ b/src/frequenz/repo/config/mkdocs/annotations.py
@@ -0,0 +1,80 @@
+# License: MIT
+# Copyright © 2025 Frequenz Energy-as-a-Service GmbH
+
+"""Code annotations using numbers.
+
+This module is provided almost exclusively as a documentation source.
+
+# Introduction
+
+Normally annotations are shown with a `(+)` button that expands the annotation. To be
+able to explain code step by step, it is good to have annotations with numbers, shown as
+`(1)`, `(2)`, etc., to be able to follow the notes in a particular order.
+
+To do this, we need some custom CSS rules. Before this customization was officially
+supported and documented, but now they are not officially supported anymore, so it could
+eventually break (it already did once).
+
+If that happens we either need to look into how to fix the CSS ourselves or remove the
+feature. To do the customization, this is what we should be able to count on:
+
+> You can be sure that the data-md-annotation-id attribute will always be present in the
+> source, which means you can always number them in any way you like.
+
+# How to implement it
+
+To implement numbered annotations, you need to add a custom CSS file to your
+`mkdocs.yml` configuration file:
+
+```yaml title="mkdocs.yml"
+extra_css:
+ - path/to/style.css
+```
+
+The CSS file should contain the following rules:
+
+```css title="path/to/style.css"
+.md-typeset .md-annotation__index > ::before {
+ content: attr(data-md-annotation-id);
+}
+.md-typeset :focus-within > .md-annotation__index > ::before {
+ transform: none;
+}
+.md-typeset .md-annotation__index {
+ width: 4ch;
+}
+```
+
+# Macros integration
+
+If you want to show an example on how an annotation looks like, you can use the
+[`CODE_ANNOTATION_MARKER`][frequenz.repo.config.mkdocs.annotations.CODE_ANNOTATION_MARKER]
+variable to inject the appropriate HTML code. See
+[frequenz.repo.config.mkdocs.mkdocstrings_macros][] for more information.
+
+# References
+
+* [Code annotation in
+ `mkdocs-material`](https://squidfunk.github.io/mkdocs-material/reference/code-blocks/#code-annotations)
+
+* [Original docs on how to enable numbered
+ annotations](https://web.archive.org/web/20230724161216/https://squidfunk.github.io/mkdocs-material/reference/code-blocks/#annotations-with-numbers)
+
+* [The PR fixing the numbered annotations when they
+ broke](https://github.com/frequenz-floss/frequenz-sdk-python/pull/684)
+
+* [The regression reported when it was decided to drop support for numbered annotations
+ officially](https://github.com/squidfunk/mkdocs-material/issues/6042)
+
+* [The `sphinx-immaterial` documentation on how to do numbered
+ annotations](https://sphinx-immaterial.readthedocs.io/en/latest/code_annotations.html#annotation-buttons-with-numbers)
+"""
+
+CODE_ANNOTATION_MARKER: str = (
+ r''
+ r''
+ r''
+ r""
+ r""
+)
+"""A variable to easily show an example code annotation."""
diff --git a/src/frequenz/repo/config/mkdocs/mkdocstrings_macros.py b/src/frequenz/repo/config/mkdocs/mkdocstrings_macros.py
new file mode 100644
index 00000000..82e4f78f
--- /dev/null
+++ b/src/frequenz/repo/config/mkdocs/mkdocstrings_macros.py
@@ -0,0 +1,261 @@
+# License: MIT
+# Copyright © 2025 Frequenz Energy-as-a-Service GmbH
+
+"""Integration between `mkdocstrings` and `macros` extensions to work together.
+
+# Introduction
+
+To be able to use macros inside docstrings, we need to integrate the `mkdocs-macros`
+extension into `mkdocstrings`. This module provides the necessary functions to make this
+integration work.
+
+
+# Basic usage
+
+If you don't want to define your own macros, variables or filters, you can use this
+module as a [pluglet](https://mkdocs-macros-plugin.readthedocs.io/en/latest/pluglets/):
+
+```yaml title="mkdocs.yml"
+plugins:
+ # Order is important! mkdocstrings must come before macros!
+ - mkdocstrings:
+ default_handler: python
+ # ...
+ - macros:
+ modules: ["frequenz.repo.config.mkdocs.mkdocstrings_macros"]
+ on_undefined: strict
+ on_error_fail: true
+```
+
+This will do the hooking and provide some useful variables and filters:
+
+* [`slugify`][frequenz.repo.config.mkdocs.mkdocstrings_macros.slugify]: A filter to
+ slugify a text. Useful to generate anchors for headings.
+* [`code_annotation_marker`]: A variable to inject the appropriate HTML code for showing
+ an example code annotation as a number (see
+ [frequenz.repo.config.mkdocs.annotations][] for more information).
+* [`version`]: A varaible with the version information of the repository as exposed by
+ [`get_repo_version_info()`][frequenz.repo.config.github.get_repo_version_info],
+ which means some environment variables are required (this variable will be `None`
+ otherwise), please read the function documentation for more details.
+* [`version_requirement`]: A variable with the version requirement for the current
+ version of the repository. It is built using the information from `version`. Also
+ only available if the rigth environment variables are set, and if the resulting
+ version is a tag (will be empty for branches). If you want to get the version
+ requirement for a branch, you need to provide a `repo_url` variable in the
+ `mkdocs.yaml` file or do a custom setup. Please read the [Customized usage]
+ section for more details.
+
+
+# Customized usage
+
+If you want to define your own macros, variables or filters, but you also want to get
+the default behaviour described in [Basic usage], you need to provide your own [macros
+module](https://mkdocs-macros-plugin.readthedocs.io/en/latest/macros/) with
+a `define_env()` function. You can specify it in the `mkdocs.yml` configuration file:
+
+```yaml title="mkdocs.yml"
+plugins:
+ # Order is important! mkdocstrings must come before macros!
+ - mkdocstrings:
+ default_handler: python
+ # ...
+ - macros:
+ module_name: "path/to/macros" # Note: no .py extension here!
+ on_undefined: strict
+ on_error_fail: true
+```
+
+Then you need to add the `define_env()` function to the `path/to/macros.py` file.
+A convenience [`hook_env_with_everything()`] is provided to pull all the same default
+variables and filters and call the hooking function at the end as with the *pluglet*.
+
+You also need to make sure to call the function at the end, after you define your own
+variables, filters and macros. You can optionally pass a `repo_url` in this case so the
+`version_requirement` variable can work when the current version is a branch. If a
+`repo_url` variable is present in the `mkdocs.yml` file, it will be used as the default.
+
+Here is an example of how to do it:
+
+```py title="path/to/macros.py"
+from frequenz.repo.config.mkdocs.mkdocstrings_macros import hook_env_with_everything
+
+def define_env(env: macros.MacrosPlugin) -> None:
+ env.variables.my_var = "Example"
+
+ # This hook needs to be done at the end of the `define_env` function.
+ hook_env_with_everything(env, "https://your-repo-url")
+```
+
+# Advanced usage
+
+If you don't want to pull in all the default variables and filters, you can still define
+your own `define_env()` function and do the same configuration in the `mkdocs.yml` file
+as in the [Customized usage] section, but instead call the
+[`hook_macros_plugin()`][frequenz.repo.config.mkdocs.mkdocstrings_macros.hook_macros_plugin]
+at the end.
+
+Here is an example of how to do it:
+
+```py title="path/to/macros.py"
+from frequenz.repo.config.mkdocs.mkdocstrings_macros import hook_macros_plugin
+
+def define_env(env: macros.MacrosPlugin) -> None:
+ env.variables.my_var = "Example"
+
+ # This hook needs to be done at the end of the `define_env` function.
+ hook_macros_plugin(env)
+```
+"""
+
+
+import logging
+from typing import Any
+
+import markdown as md
+from markdown.extensions import toc
+from mkdocs_macros import plugin as macros
+
+from ..github import get_repo_version_info
+from .annotations import CODE_ANNOTATION_MARKER
+
+_logger = logging.getLogger(__name__)
+
+
+def slugify(text: str) -> str:
+ """Slugify a text.
+
+ Useful to generate anchors for headings.
+
+ Example:
+ ```markdown
+ Some URL: https://example.com/#{{ "My Heading" | slugify }}.
+ ```
+
+ Args:
+ text: The text to slugify.
+
+ Returns:
+ The slugified text.
+ """
+ return toc.slugify_unicode(text, "-")
+
+
+def add_version_variables(
+ env: macros.MacrosPlugin, *, repo_url: str | None = None
+) -> None:
+ """Add variables with git information to the environment.
+
+ This function will add 2 new macro variables to `env`:
+
+ * [`version`]: A varaible with the version information of the repository as exposed by
+ [`get_repo_version_info()`][frequenz.repo.config.github.get_repo_version_info],
+ which means some environment variables are required (this variable will be `None`
+ otherwise), please read the function documentation for more details.
+ * [`version_requirement`]: A variable with the version requirement for the current
+ version of the repository. It is built using the information from `version`. Also
+ only available if the rigth environment variables are set, and if the resulting
+ version is a tag (will be empty for branches). If you want to get the version
+ requirement for a branch, you need to provide a `repo_url` or a `repo_url`
+ config in the `mkdocs.yml` file.
+
+ Args:
+ env: The environment to add the variables to.
+ repo_url: The URL of the repository to use in the `version_requirement`
+ variable. If `None` the `config.repo_url` mkdocs variable will be used. Only
+ needed if you want to use the `version_requirement` variable for branches.
+ """
+ env.variables["version"] = None
+ env.variables["version_requirement"] = ""
+
+ if repo_url is None:
+ repo_url = env.variables.get("config", {}).get("repo_url")
+ if repo_url is None:
+ _logger.warning(
+ "No repo_url provided, can't build the 'version_requirement' variable"
+ )
+
+ version_info = None
+ try:
+ version_info = get_repo_version_info()
+ except Exception as exc: # pylint: disable=broad-except
+ _logger.warning("Failed to get version info: %s", exc)
+ else:
+ env.variables["version"] = version_info
+ if version_info.current_tag:
+ env.variables["version_requirement"] = f" == {version_info.current_tag}"
+
+ ref = None
+ if version_info is not None:
+ ref = version_info.current_branch or version_info.sha
+ ref = ref or env.variables.get("git", {}).get("commit")
+ if ref and repo_url is not None:
+ env.variables["version_requirement"] = f" @ git+{repo_url}@{ref}"
+
+
+def hook_macros_plugin(env: macros.MacrosPlugin) -> None:
+ """Integrate the `mkdocs-macros` plugin into `mkdocstrings`.
+
+ This is a temporary workaround to make `mkdocs-macros` work with
+ `mkdocstrings` until a proper `mkdocs-macros` *pluglet* is available. See
+ https://github.com/mkdocstrings/mkdocstrings/issues/615 for details.
+
+ Args:
+ env: The environment to hook the plugin into.
+ """
+ # get mkdocstrings' Python handler
+ python_handler = env.conf["plugins"]["mkdocstrings"].get_handler("python")
+
+ # get the `update_env` method of the Python handler
+ update_env = python_handler.update_env
+
+ # override the `update_env` method of the Python handler
+ def patched_update_env(md: md.Markdown, config: dict[str, Any]) -> None:
+ update_env(md, config)
+
+ # get the `convert_markdown` filter of the env
+ convert_markdown = python_handler.env.filters["convert_markdown"]
+
+ # build a chimera made of macros+mkdocstrings
+ def render_convert(markdown: str, *args: Any, **kwargs: Any) -> Any:
+ return convert_markdown(env.render(markdown), *args, **kwargs)
+
+ # patch the filter
+ python_handler.env.filters["convert_markdown"] = render_convert
+
+ # patch the method
+ python_handler.update_env = patched_update_env
+
+
+def hook_env_with_everything(
+ env: macros.MacrosPlugin, *, repo_url: str | None = None
+) -> None:
+ """Hooks the `env` with all the default variables and filters.
+
+ This function is a convenience function that adds all variables and filters and
+ macros provided by this module and calls
+ [`hook_macros_plugin()`][frequenz.repo.config.mkdocs.mkdocstrings_macros.hook_macros_plugin]
+ at the end.
+
+ Args:
+ env: The environment to hook.
+ repo_url: The URL of the repository to use in the `version_requirement`
+ variable. If `None` the `config.repo_url` mkdocs variable will be used. Only
+ needed if you want to use the `version_requirement` variable for branches.
+ """
+ env.variables.code_annotation_marker = CODE_ANNOTATION_MARKER
+ add_version_variables(env, repo_url=repo_url)
+
+ env.filter(slugify, "slugify") # type: ignore[no-untyped-call]
+
+ # This hook needs to be done at the end of the `define_env` function.
+ hook_macros_plugin(env)
+
+
+def define_env(env: macros.MacrosPlugin) -> None:
+ """Define the hook to create macro functions for use in Markdown.
+
+ Args:
+ env: The environment to define the macro functions in.
+ """
+ hook_env_with_everything(env)
diff --git a/src/frequenz/repo/config/version.py b/src/frequenz/repo/config/version.py
index 39fed3ba..2acf96e0 100644
--- a/src/frequenz/repo/config/version.py
+++ b/src/frequenz/repo/config/version.py
@@ -516,3 +516,10 @@ def is_branch_latest(self) -> bool:
)
return False
return branch == latest[0]
+
+ def __repr__(self) -> str:
+ """Return a string representation of the object."""
+ return (
+ f"{self.__class__.__name__}(sha={self._sha!r}, ref={self._ref!r}, "
+ f"tags={self._tags!r}, branches={self._branches!r})"
+ )
diff --git a/tests_golden/integration/test_cookiecutter_generation/actor/cookiecutter-stdout.txt b/tests_golden/integration/test_cookiecutter_generation/actor/cookiecutter-stdout.txt
index f4aaaaa2..8371360e 100644
--- a/tests_golden/integration/test_cookiecutter_generation/actor/cookiecutter-stdout.txt
+++ b/tests_golden/integration/test_cookiecutter_generation/actor/cookiecutter-stdout.txt
@@ -12,7 +12,6 @@
./CODEOWNERS:# TODO(cookiecutter): Add more specific code-owners, check if the default is correct
./CODEOWNERS:* TODO(cookiecutter): Add codeowners (like @{github_org}/some-team)# Temporary, should probably change
./README.md:TODO(cookiecutter): Improve the README file
-./docs/_scripts/macros.py: # TODO(cookiecutter): Add any other macros, variables and filters here.
./mkdocs.yml: # TODO(cookiecutter): You might want to add other external references here
./mkdocs.yml: # TODO(cookiecutter): You might want to change the logo, the file is located in "docs/"
./mkdocs.yml: # TODO(cookiecutter): You probably want to update the social links
diff --git a/tests_golden/integration/test_cookiecutter_generation/actor/frequenz-actor-test/docs/_scripts/macros.py b/tests_golden/integration/test_cookiecutter_generation/actor/frequenz-actor-test/docs/_scripts/macros.py
deleted file mode 100644
index 2ae42657..00000000
--- a/tests_golden/integration/test_cookiecutter_generation/actor/frequenz-actor-test/docs/_scripts/macros.py
+++ /dev/null
@@ -1,80 +0,0 @@
-# License: MIT
-# Copyright © 2023 Frequenz Energy-as-a-Service GmbH
-
-"""This module defines macros for use in Markdown files."""
-
-from typing import Any
-
-import markdown as md
-from markdown.extensions import toc
-from mkdocs_macros import plugin as macros
-
-_CODE_ANNOTATION_MARKER: str = (
- r''
- r''
- r''
- r""
- r""
-)
-
-
-def _slugify(text: str) -> str:
- """Slugify a text.
-
- Args:
- text: The text to slugify.
-
- Returns:
- The slugified text.
- """
- return toc.slugify_unicode(text, "-")
-
-
-def _hook_macros_plugin(env: macros.MacrosPlugin) -> None:
- """Integrate the `mkdocs-macros` plugin into `mkdocstrings`.
-
- This is a temporary workaround to make `mkdocs-macros` work with
- `mkdocstrings` until a proper `mkdocs-macros` *pluglet* is available. See
- https://github.com/mkdocstrings/mkdocstrings/issues/615 for details.
-
- Args:
- env: The environment to hook the plugin into.
- """
- # get mkdocstrings' Python handler
- python_handler = env.conf["plugins"]["mkdocstrings"].get_handler("python")
-
- # get the `update_env` method of the Python handler
- update_env = python_handler.update_env
-
- # override the `update_env` method of the Python handler
- def patched_update_env(md: md.Markdown, config: dict[str, Any]) -> None:
- update_env(md=md, config=config)
-
- # get the `convert_markdown` filter of the env
- convert_markdown = python_handler.env.filters["convert_markdown"]
-
- # build a chimera made of macros+mkdocstrings
- def render_convert(markdown: str, *args: Any, **kwargs: Any) -> Any:
- return convert_markdown(env.render(markdown), *args, **kwargs)
-
- # patch the filter
- python_handler.env.filters["convert_markdown"] = render_convert
-
- # patch the method
- python_handler.update_env = patched_update_env
-
-
-def define_env(env: macros.MacrosPlugin) -> None:
- """Define the hook to create macro functions for use in Markdown.
-
- Args:
- env: The environment to define the macro functions in.
- """
- # A variable to easily show an example code annotation from mkdocs-material.
- # https://squidfunk.github.io/mkdocs-material/reference/code-blocks/#adding-annotations
- env.variables["code_annotation_marker"] = _CODE_ANNOTATION_MARKER
-
- # TODO(cookiecutter): Add any other macros, variables and filters here.
-
- # This hook needs to be done at the end of the `define_env` function.
- _hook_macros_plugin(env)
diff --git a/tests_golden/integration/test_cookiecutter_generation/actor/frequenz-actor-test/mkdocs.yml b/tests_golden/integration/test_cookiecutter_generation/actor/frequenz-actor-test/mkdocs.yml
index b15eefcd..95d90c78 100644
--- a/tests_golden/integration/test_cookiecutter_generation/actor/frequenz-actor-test/mkdocs.yml
+++ b/tests_golden/integration/test_cookiecutter_generation/actor/frequenz-actor-test/mkdocs.yml
@@ -124,10 +124,9 @@ plugins:
- https://frequenz-floss.github.io/frequenz-sdk-python/v1.0-pre/objects.inv
- https://typing-extensions.readthedocs.io/en/stable/objects.inv
# Note this plugin must be loaded after mkdocstrings to be able to use macros
- # inside docstrings. See the comment in `docs/_scripts/macros.py` for more
- # details
+ # inside docstrings.
- macros:
- module_name: docs/_scripts/macros
+ modules: ["frequenz.repo.config.mkdocs.mkdocstrings_macros"]
on_undefined: strict
on_error_fail: true
- search
diff --git a/tests_golden/integration/test_cookiecutter_generation/actor/frequenz-actor-test/pyproject.toml b/tests_golden/integration/test_cookiecutter_generation/actor/frequenz-actor-test/pyproject.toml
index 336868e5..5a6009b4 100644
--- a/tests_golden/integration/test_cookiecutter_generation/actor/frequenz-actor-test/pyproject.toml
+++ b/tests_golden/integration/test_cookiecutter_generation/actor/frequenz-actor-test/pyproject.toml
@@ -3,9 +3,9 @@
[build-system]
requires = [
- "setuptools == 75.5.0",
+ "setuptools == 75.8.0",
"setuptools_scm[toml] == 8.1.0",
- "frequenz-repo-config[actor] == 0.11.0",
+ "frequenz-repo-config[actor] == 0.12.0",
]
build-backend = "setuptools.build_meta"
@@ -32,7 +32,7 @@ dependencies = [
# Make sure to update the version for cross-referencing also in the
# mkdocs.yml file when changing the version here (look for the config key
# plugins.mkdocstrings.handlers.python.import)
- "frequenz-sdk >= 1.0.0rc1300, < 1.0.0rc1400",
+ "frequenz-sdk >= 1.0.0rc1500, < 1.0.0rc1600",
]
dynamic = ["version"]
@@ -46,31 +46,31 @@ dev-flake8 = [
"flake8 == 7.1.1",
"flake8-docstrings == 1.7.0",
"flake8-pyproject == 1.2.3", # For reading the flake8 config from pyproject.toml
- "pydoclint == 0.5.9",
+ "pydoclint == 0.6.0",
"pydocstyle == 6.3.0",
]
-dev-formatting = ["black == 24.10.0", "isort == 5.13.2"]
+dev-formatting = ["black == 25.1.0", "isort == 6.0.0"]
dev-mkdocs = [
"Markdown == 3.7",
- "black == 24.10.0",
+ "black == 25.1.0",
"mike == 2.1.3",
"mkdocs-gen-files == 0.5.0",
"mkdocs-literate-nav == 0.6.1",
"mkdocs-macros-plugin == 1.3.7",
- "mkdocs-material == 9.5.45",
+ "mkdocs-material == 9.6.2",
"mkdocstrings[python] == 0.28.0",
"mkdocstrings-python == 1.14.0",
- "frequenz-repo-config[actor] == 0.11.0",
+ "frequenz-repo-config[actor] == 0.12.0",
]
dev-mypy = [
"mypy == 1.9.0",
- "types-Markdown == 3.7.0.20240822",
+ "types-Markdown == 3.7.0.20241204",
# For checking the noxfile, docs/ script, and tests
"frequenz-actor-test[dev-mkdocs,dev-noxfile,dev-pytest]",
]
dev-noxfile = [
"nox == 2024.10.9",
- "frequenz-repo-config[actor] == 0.11.0",
+ "frequenz-repo-config[actor] == 0.12.0",
]
dev-pylint = [
# dev-pytest already defines a dependency to pylint because of the examples
@@ -78,12 +78,12 @@ dev-pylint = [
"frequenz-actor-test[dev-mkdocs,dev-noxfile,dev-pytest]",
]
dev-pytest = [
- "pytest == 8.3.3",
- "pylint == 3.3.1", # We need this to check for the examples
- "frequenz-repo-config[extra-lint-examples] == 0.11.0",
+ "pytest == 8.3.4",
+ "pylint == 3.3.4", # We need this to check for the examples
+ "frequenz-repo-config[extra-lint-examples] == 0.12.0",
"pytest-mock == 3.14.0",
- "pytest-asyncio == 0.24.0",
- "async-solipsism == 0.6",
+ "pytest-asyncio == 0.25.3",
+ "async-solipsism == 0.7",
]
dev = [
"frequenz-actor-test[dev-mkdocs,dev-flake8,dev-formatting,dev-mkdocs,dev-mypy,dev-noxfile,dev-pylint,dev-pytest]",
diff --git a/tests_golden/integration/test_cookiecutter_generation/api/cookiecutter-stdout.txt b/tests_golden/integration/test_cookiecutter_generation/api/cookiecutter-stdout.txt
index 2ec694d7..22c3da3e 100644
--- a/tests_golden/integration/test_cookiecutter_generation/api/cookiecutter-stdout.txt
+++ b/tests_golden/integration/test_cookiecutter_generation/api/cookiecutter-stdout.txt
@@ -12,7 +12,6 @@
./.github/workflows/release-notes-check.yml: # TODO(cookiecutter): Uncomment the following line for private repositories, otherwise remove it
./CODEOWNERS:# TODO(cookiecutter): Add more specific code-owners, check if the default is correct
./README.md:TODO(cookiecutter): Improve the README file
-./docs/_scripts/macros.py: # TODO(cookiecutter): Add any other macros, variables and filters here.
./mkdocs.yml: # TODO(cookiecutter): You might want to add other external references here
./mkdocs.yml: # TODO(cookiecutter): You might want to change the logo, the file is located in "docs/"
./mkdocs.yml: # TODO(cookiecutter): You probably want to update the social links
diff --git a/tests_golden/integration/test_cookiecutter_generation/api/frequenz-api-test/docs/_scripts/macros.py b/tests_golden/integration/test_cookiecutter_generation/api/frequenz-api-test/docs/_scripts/macros.py
deleted file mode 100644
index 2ae42657..00000000
--- a/tests_golden/integration/test_cookiecutter_generation/api/frequenz-api-test/docs/_scripts/macros.py
+++ /dev/null
@@ -1,80 +0,0 @@
-# License: MIT
-# Copyright © 2023 Frequenz Energy-as-a-Service GmbH
-
-"""This module defines macros for use in Markdown files."""
-
-from typing import Any
-
-import markdown as md
-from markdown.extensions import toc
-from mkdocs_macros import plugin as macros
-
-_CODE_ANNOTATION_MARKER: str = (
- r''
- r''
- r''
- r""
- r""
-)
-
-
-def _slugify(text: str) -> str:
- """Slugify a text.
-
- Args:
- text: The text to slugify.
-
- Returns:
- The slugified text.
- """
- return toc.slugify_unicode(text, "-")
-
-
-def _hook_macros_plugin(env: macros.MacrosPlugin) -> None:
- """Integrate the `mkdocs-macros` plugin into `mkdocstrings`.
-
- This is a temporary workaround to make `mkdocs-macros` work with
- `mkdocstrings` until a proper `mkdocs-macros` *pluglet* is available. See
- https://github.com/mkdocstrings/mkdocstrings/issues/615 for details.
-
- Args:
- env: The environment to hook the plugin into.
- """
- # get mkdocstrings' Python handler
- python_handler = env.conf["plugins"]["mkdocstrings"].get_handler("python")
-
- # get the `update_env` method of the Python handler
- update_env = python_handler.update_env
-
- # override the `update_env` method of the Python handler
- def patched_update_env(md: md.Markdown, config: dict[str, Any]) -> None:
- update_env(md=md, config=config)
-
- # get the `convert_markdown` filter of the env
- convert_markdown = python_handler.env.filters["convert_markdown"]
-
- # build a chimera made of macros+mkdocstrings
- def render_convert(markdown: str, *args: Any, **kwargs: Any) -> Any:
- return convert_markdown(env.render(markdown), *args, **kwargs)
-
- # patch the filter
- python_handler.env.filters["convert_markdown"] = render_convert
-
- # patch the method
- python_handler.update_env = patched_update_env
-
-
-def define_env(env: macros.MacrosPlugin) -> None:
- """Define the hook to create macro functions for use in Markdown.
-
- Args:
- env: The environment to define the macro functions in.
- """
- # A variable to easily show an example code annotation from mkdocs-material.
- # https://squidfunk.github.io/mkdocs-material/reference/code-blocks/#adding-annotations
- env.variables["code_annotation_marker"] = _CODE_ANNOTATION_MARKER
-
- # TODO(cookiecutter): Add any other macros, variables and filters here.
-
- # This hook needs to be done at the end of the `define_env` function.
- _hook_macros_plugin(env)
diff --git a/tests_golden/integration/test_cookiecutter_generation/api/frequenz-api-test/mkdocs.yml b/tests_golden/integration/test_cookiecutter_generation/api/frequenz-api-test/mkdocs.yml
index f02aa9d9..4c4196ab 100644
--- a/tests_golden/integration/test_cookiecutter_generation/api/frequenz-api-test/mkdocs.yml
+++ b/tests_golden/integration/test_cookiecutter_generation/api/frequenz-api-test/mkdocs.yml
@@ -124,10 +124,9 @@ plugins:
- https://grpc.github.io/grpc/python/objects.inv
- https://typing-extensions.readthedocs.io/en/stable/objects.inv
# Note this plugin must be loaded after mkdocstrings to be able to use macros
- # inside docstrings. See the comment in `docs/_scripts/macros.py` for more
- # details
+ # inside docstrings.
- macros:
- module_name: docs/_scripts/macros
+ modules: ["frequenz.repo.config.mkdocs.mkdocstrings_macros"]
on_undefined: strict
on_error_fail: true
- search
diff --git a/tests_golden/integration/test_cookiecutter_generation/api/frequenz-api-test/pyproject.toml b/tests_golden/integration/test_cookiecutter_generation/api/frequenz-api-test/pyproject.toml
index 577b2092..05c9e815 100644
--- a/tests_golden/integration/test_cookiecutter_generation/api/frequenz-api-test/pyproject.toml
+++ b/tests_golden/integration/test_cookiecutter_generation/api/frequenz-api-test/pyproject.toml
@@ -3,16 +3,16 @@
[build-system]
requires = [
- "setuptools == 75.5.0",
+ "setuptools == 75.8.0",
"setuptools_scm[toml] == 8.1.0",
- "frequenz-repo-config[api] == 0.11.0",
+ "frequenz-repo-config[api] == 0.12.0",
# We need to pin the protobuf, grpcio and grpcio-tools dependencies to make
# sure the code is generated using the minimum supported versions, as older
# versions can't work with code that was generated with newer versions.
# https://protobuf.dev/support/cross-version-runtime-guarantee/#backwards
- "protobuf == 5.28.0",
- "grpcio-tools == 1.66.1",
- "grpcio == 1.66.1",
+ "protobuf == 5.29.3",
+ "grpcio-tools == 1.70.0",
+ "grpcio == 1.70.0",
]
build-backend = "setuptools.build_meta"
@@ -35,15 +35,15 @@ classifiers = [
requires-python = ">= 3.11, < 4"
# TODO(cookiecutter): Remove and add more dependencies if appropriate
dependencies = [
- "frequenz-api-common >= 0.6.2, < 0.7.0",
+ "frequenz-api-common >= 0.6.3, < 0.7.0",
# We can't widen beyond the current value unless we bump the minimum
# requirements too because of protobuf cross-version runtime guarantees:
# https://protobuf.dev/support/cross-version-runtime-guarantee/#major
- "protobuf >= 5.28.0, < 7", # Do not widen beyond 7!
+ "protobuf >= 5.29.3, < 7", # Do not widen beyond 7!
# We couldn't find any document with a spec about the cross-version runtime
# guarantee for grpcio, so unless we find one in the future, we'll assume
# major version jumps are not compatible
- "grpcio >= 1.66.1, < 2", # Do not widen beyond 2!
+ "grpcio >= 1.70.0, < 2", # Do not widen beyond 2!
]
dynamic = ["version"]
@@ -57,32 +57,32 @@ dev-flake8 = [
"flake8 == 7.1.1",
"flake8-docstrings == 1.7.0",
"flake8-pyproject == 1.2.3", # For reading the flake8 config from pyproject.toml
- "pydoclint == 0.5.9",
+ "pydoclint == 0.6.0",
"pydocstyle == 6.3.0",
]
-dev-formatting = ["black == 24.10.0", "isort == 5.13.2"]
+dev-formatting = ["black == 25.1.0", "isort == 6.0.0"]
dev-mkdocs = [
"Markdown == 3.7",
- "black == 24.10.0",
+ "black == 25.1.0",
"mike == 2.1.3",
"mkdocs-gen-files == 0.5.0",
"mkdocs-literate-nav == 0.6.1",
"mkdocs-macros-plugin == 1.3.7",
- "mkdocs-material == 9.5.45",
+ "mkdocs-material == 9.6.2",
"mkdocstrings[python] == 0.28.0",
"mkdocstrings-python == 1.14.0",
- "frequenz-repo-config[api] == 0.11.0",
+ "frequenz-repo-config[api] == 0.12.0",
]
dev-mypy = [
"mypy == 1.9.0",
- "grpc-stubs == 1.53.0.2",
- "types-Markdown == 3.7.0.20240822",
+ "grpc-stubs == 1.53.0.5",
+ "types-Markdown == 3.7.0.20241204",
# For checking the noxfile, docs/ script, and tests
"frequenz-api-test[dev-mkdocs,dev-noxfile,dev-pytest]",
]
dev-noxfile = [
"nox == 2024.10.9",
- "frequenz-repo-config[api] == 0.11.0",
+ "frequenz-repo-config[api] == 0.12.0",
]
dev-pylint = [
# dev-pytest already defines a dependency to pylint because of the examples
@@ -90,9 +90,9 @@ dev-pylint = [
"frequenz-api-test[dev-mkdocs,dev-noxfile,dev-pytest]",
]
dev-pytest = [
- "pytest == 8.3.3",
- "pylint == 3.3.1", # We need this to check for the examples
- "frequenz-repo-config[extra-lint-examples] == 0.11.0",
+ "pytest == 8.3.4",
+ "pylint == 3.3.4", # We need this to check for the examples
+ "frequenz-repo-config[extra-lint-examples] == 0.12.0",
]
dev = [
"frequenz-api-test[dev-mkdocs,dev-flake8,dev-formatting,dev-mkdocs,dev-mypy,dev-noxfile,dev-pylint,dev-pytest]",
diff --git a/tests_golden/integration/test_cookiecutter_generation/app/cookiecutter-stdout.txt b/tests_golden/integration/test_cookiecutter_generation/app/cookiecutter-stdout.txt
index 8a5abb01..330fbba1 100644
--- a/tests_golden/integration/test_cookiecutter_generation/app/cookiecutter-stdout.txt
+++ b/tests_golden/integration/test_cookiecutter_generation/app/cookiecutter-stdout.txt
@@ -11,7 +11,6 @@
./.github/workflows/release-notes-check.yml: # TODO(cookiecutter): Uncomment the following line for private repositories, otherwise remove it
./CODEOWNERS:# TODO(cookiecutter): Add more specific code-owners, check if the default is correct
./README.md:TODO(cookiecutter): Improve the README file
-./docs/_scripts/macros.py: # TODO(cookiecutter): Add any other macros, variables and filters here.
./mkdocs.yml: # TODO(cookiecutter): You might want to add other external references here
./mkdocs.yml: # TODO(cookiecutter): You might want to change the logo, the file is located in "docs/"
./mkdocs.yml: # TODO(cookiecutter): You probably want to update the social links
diff --git a/tests_golden/integration/test_cookiecutter_generation/app/frequenz-app-test/docs/_scripts/macros.py b/tests_golden/integration/test_cookiecutter_generation/app/frequenz-app-test/docs/_scripts/macros.py
deleted file mode 100644
index 2ae42657..00000000
--- a/tests_golden/integration/test_cookiecutter_generation/app/frequenz-app-test/docs/_scripts/macros.py
+++ /dev/null
@@ -1,80 +0,0 @@
-# License: MIT
-# Copyright © 2023 Frequenz Energy-as-a-Service GmbH
-
-"""This module defines macros for use in Markdown files."""
-
-from typing import Any
-
-import markdown as md
-from markdown.extensions import toc
-from mkdocs_macros import plugin as macros
-
-_CODE_ANNOTATION_MARKER: str = (
- r''
- r''
- r''
- r""
- r""
-)
-
-
-def _slugify(text: str) -> str:
- """Slugify a text.
-
- Args:
- text: The text to slugify.
-
- Returns:
- The slugified text.
- """
- return toc.slugify_unicode(text, "-")
-
-
-def _hook_macros_plugin(env: macros.MacrosPlugin) -> None:
- """Integrate the `mkdocs-macros` plugin into `mkdocstrings`.
-
- This is a temporary workaround to make `mkdocs-macros` work with
- `mkdocstrings` until a proper `mkdocs-macros` *pluglet* is available. See
- https://github.com/mkdocstrings/mkdocstrings/issues/615 for details.
-
- Args:
- env: The environment to hook the plugin into.
- """
- # get mkdocstrings' Python handler
- python_handler = env.conf["plugins"]["mkdocstrings"].get_handler("python")
-
- # get the `update_env` method of the Python handler
- update_env = python_handler.update_env
-
- # override the `update_env` method of the Python handler
- def patched_update_env(md: md.Markdown, config: dict[str, Any]) -> None:
- update_env(md=md, config=config)
-
- # get the `convert_markdown` filter of the env
- convert_markdown = python_handler.env.filters["convert_markdown"]
-
- # build a chimera made of macros+mkdocstrings
- def render_convert(markdown: str, *args: Any, **kwargs: Any) -> Any:
- return convert_markdown(env.render(markdown), *args, **kwargs)
-
- # patch the filter
- python_handler.env.filters["convert_markdown"] = render_convert
-
- # patch the method
- python_handler.update_env = patched_update_env
-
-
-def define_env(env: macros.MacrosPlugin) -> None:
- """Define the hook to create macro functions for use in Markdown.
-
- Args:
- env: The environment to define the macro functions in.
- """
- # A variable to easily show an example code annotation from mkdocs-material.
- # https://squidfunk.github.io/mkdocs-material/reference/code-blocks/#adding-annotations
- env.variables["code_annotation_marker"] = _CODE_ANNOTATION_MARKER
-
- # TODO(cookiecutter): Add any other macros, variables and filters here.
-
- # This hook needs to be done at the end of the `define_env` function.
- _hook_macros_plugin(env)
diff --git a/tests_golden/integration/test_cookiecutter_generation/app/frequenz-app-test/mkdocs.yml b/tests_golden/integration/test_cookiecutter_generation/app/frequenz-app-test/mkdocs.yml
index c5bebc0b..ea2d972f 100644
--- a/tests_golden/integration/test_cookiecutter_generation/app/frequenz-app-test/mkdocs.yml
+++ b/tests_golden/integration/test_cookiecutter_generation/app/frequenz-app-test/mkdocs.yml
@@ -124,10 +124,9 @@ plugins:
- https://frequenz-floss.github.io/frequenz-sdk-python/v1.0-pre/objects.inv
- https://typing-extensions.readthedocs.io/en/stable/objects.inv
# Note this plugin must be loaded after mkdocstrings to be able to use macros
- # inside docstrings. See the comment in `docs/_scripts/macros.py` for more
- # details
+ # inside docstrings.
- macros:
- module_name: docs/_scripts/macros
+ modules: ["frequenz.repo.config.mkdocs.mkdocstrings_macros"]
on_undefined: strict
on_error_fail: true
- search
diff --git a/tests_golden/integration/test_cookiecutter_generation/app/frequenz-app-test/pyproject.toml b/tests_golden/integration/test_cookiecutter_generation/app/frequenz-app-test/pyproject.toml
index 831d049a..eca37134 100644
--- a/tests_golden/integration/test_cookiecutter_generation/app/frequenz-app-test/pyproject.toml
+++ b/tests_golden/integration/test_cookiecutter_generation/app/frequenz-app-test/pyproject.toml
@@ -3,9 +3,9 @@
[build-system]
requires = [
- "setuptools == 75.5.0",
+ "setuptools == 75.8.0",
"setuptools_scm[toml] == 8.1.0",
- "frequenz-repo-config[app] == 0.11.0",
+ "frequenz-repo-config[app] == 0.12.0",
]
build-backend = "setuptools.build_meta"
@@ -31,7 +31,7 @@ dependencies = [
# Make sure to update the version for cross-referencing also in the
# mkdocs.yml file when changing the version here (look for the config key
# plugins.mkdocstrings.handlers.python.import)
- "frequenz-sdk == 1.0.0rc1300",
+ "frequenz-sdk == 1.0.0rc1500",
]
dynamic = ["version"]
@@ -45,31 +45,31 @@ dev-flake8 = [
"flake8 == 7.1.1",
"flake8-docstrings == 1.7.0",
"flake8-pyproject == 1.2.3", # For reading the flake8 config from pyproject.toml
- "pydoclint == 0.5.9",
+ "pydoclint == 0.6.0",
"pydocstyle == 6.3.0",
]
-dev-formatting = ["black == 24.10.0", "isort == 5.13.2"]
+dev-formatting = ["black == 25.1.0", "isort == 6.0.0"]
dev-mkdocs = [
"Markdown == 3.7",
- "black == 24.10.0",
+ "black == 25.1.0",
"mike == 2.1.3",
"mkdocs-gen-files == 0.5.0",
"mkdocs-literate-nav == 0.6.1",
"mkdocs-macros-plugin == 1.3.7",
- "mkdocs-material == 9.5.45",
+ "mkdocs-material == 9.6.2",
"mkdocstrings[python] == 0.28.0",
"mkdocstrings-python == 1.14.0",
- "frequenz-repo-config[app] == 0.11.0",
+ "frequenz-repo-config[app] == 0.12.0",
]
dev-mypy = [
"mypy == 1.9.0",
- "types-Markdown == 3.7.0.20240822",
+ "types-Markdown == 3.7.0.20241204",
# For checking the noxfile, docs/ script, and tests
"frequenz-app-test[dev-mkdocs,dev-noxfile,dev-pytest]",
]
dev-noxfile = [
"nox == 2024.10.9",
- "frequenz-repo-config[app] == 0.11.0",
+ "frequenz-repo-config[app] == 0.12.0",
]
dev-pylint = [
# dev-pytest already defines a dependency to pylint because of the examples
@@ -77,12 +77,12 @@ dev-pylint = [
"frequenz-app-test[dev-mkdocs,dev-noxfile,dev-pytest]",
]
dev-pytest = [
- "pytest == 8.3.3",
- "pylint == 3.3.1", # We need this to check for the examples
- "frequenz-repo-config[extra-lint-examples] == 0.11.0",
+ "pytest == 8.3.4",
+ "pylint == 3.3.4", # We need this to check for the examples
+ "frequenz-repo-config[extra-lint-examples] == 0.12.0",
"pytest-mock == 3.14.0",
- "pytest-asyncio == 0.24.0",
- "async-solipsism == 0.6",
+ "pytest-asyncio == 0.25.3",
+ "async-solipsism == 0.7",
]
dev = [
"frequenz-app-test[dev-mkdocs,dev-flake8,dev-formatting,dev-mkdocs,dev-mypy,dev-noxfile,dev-pylint,dev-pytest]",
diff --git a/tests_golden/integration/test_cookiecutter_generation/lib/cookiecutter-stdout.txt b/tests_golden/integration/test_cookiecutter_generation/lib/cookiecutter-stdout.txt
index 77bc53b5..3cd7667c 100644
--- a/tests_golden/integration/test_cookiecutter_generation/lib/cookiecutter-stdout.txt
+++ b/tests_golden/integration/test_cookiecutter_generation/lib/cookiecutter-stdout.txt
@@ -11,7 +11,6 @@
./.github/workflows/release-notes-check.yml: # TODO(cookiecutter): Uncomment the following line for private repositories, otherwise remove it
./CODEOWNERS:# TODO(cookiecutter): Add more specific code-owners, check if the default is correct
./README.md:TODO(cookiecutter): Improve the README file
-./docs/_scripts/macros.py: # TODO(cookiecutter): Add any other macros, variables and filters here.
./mkdocs.yml: # TODO(cookiecutter): You might want to add other external references here
./mkdocs.yml: # TODO(cookiecutter): You might want to change the logo, the file is located in "docs/"
./mkdocs.yml: # TODO(cookiecutter): You probably want to update the social links
diff --git a/tests_golden/integration/test_cookiecutter_generation/lib/frequenz-test-python/docs/_scripts/macros.py b/tests_golden/integration/test_cookiecutter_generation/lib/frequenz-test-python/docs/_scripts/macros.py
deleted file mode 100644
index 2ae42657..00000000
--- a/tests_golden/integration/test_cookiecutter_generation/lib/frequenz-test-python/docs/_scripts/macros.py
+++ /dev/null
@@ -1,80 +0,0 @@
-# License: MIT
-# Copyright © 2023 Frequenz Energy-as-a-Service GmbH
-
-"""This module defines macros for use in Markdown files."""
-
-from typing import Any
-
-import markdown as md
-from markdown.extensions import toc
-from mkdocs_macros import plugin as macros
-
-_CODE_ANNOTATION_MARKER: str = (
- r''
- r''
- r''
- r""
- r""
-)
-
-
-def _slugify(text: str) -> str:
- """Slugify a text.
-
- Args:
- text: The text to slugify.
-
- Returns:
- The slugified text.
- """
- return toc.slugify_unicode(text, "-")
-
-
-def _hook_macros_plugin(env: macros.MacrosPlugin) -> None:
- """Integrate the `mkdocs-macros` plugin into `mkdocstrings`.
-
- This is a temporary workaround to make `mkdocs-macros` work with
- `mkdocstrings` until a proper `mkdocs-macros` *pluglet* is available. See
- https://github.com/mkdocstrings/mkdocstrings/issues/615 for details.
-
- Args:
- env: The environment to hook the plugin into.
- """
- # get mkdocstrings' Python handler
- python_handler = env.conf["plugins"]["mkdocstrings"].get_handler("python")
-
- # get the `update_env` method of the Python handler
- update_env = python_handler.update_env
-
- # override the `update_env` method of the Python handler
- def patched_update_env(md: md.Markdown, config: dict[str, Any]) -> None:
- update_env(md=md, config=config)
-
- # get the `convert_markdown` filter of the env
- convert_markdown = python_handler.env.filters["convert_markdown"]
-
- # build a chimera made of macros+mkdocstrings
- def render_convert(markdown: str, *args: Any, **kwargs: Any) -> Any:
- return convert_markdown(env.render(markdown), *args, **kwargs)
-
- # patch the filter
- python_handler.env.filters["convert_markdown"] = render_convert
-
- # patch the method
- python_handler.update_env = patched_update_env
-
-
-def define_env(env: macros.MacrosPlugin) -> None:
- """Define the hook to create macro functions for use in Markdown.
-
- Args:
- env: The environment to define the macro functions in.
- """
- # A variable to easily show an example code annotation from mkdocs-material.
- # https://squidfunk.github.io/mkdocs-material/reference/code-blocks/#adding-annotations
- env.variables["code_annotation_marker"] = _CODE_ANNOTATION_MARKER
-
- # TODO(cookiecutter): Add any other macros, variables and filters here.
-
- # This hook needs to be done at the end of the `define_env` function.
- _hook_macros_plugin(env)
diff --git a/tests_golden/integration/test_cookiecutter_generation/lib/frequenz-test-python/mkdocs.yml b/tests_golden/integration/test_cookiecutter_generation/lib/frequenz-test-python/mkdocs.yml
index 7e268f79..1d4c8edf 100644
--- a/tests_golden/integration/test_cookiecutter_generation/lib/frequenz-test-python/mkdocs.yml
+++ b/tests_golden/integration/test_cookiecutter_generation/lib/frequenz-test-python/mkdocs.yml
@@ -122,10 +122,9 @@ plugins:
- https://docs.python.org/3/objects.inv
- https://typing-extensions.readthedocs.io/en/stable/objects.inv
# Note this plugin must be loaded after mkdocstrings to be able to use macros
- # inside docstrings. See the comment in `docs/_scripts/macros.py` for more
- # details
+ # inside docstrings.
- macros:
- module_name: docs/_scripts/macros
+ modules: ["frequenz.repo.config.mkdocs.mkdocstrings_macros"]
on_undefined: strict
on_error_fail: true
- search
diff --git a/tests_golden/integration/test_cookiecutter_generation/lib/frequenz-test-python/pyproject.toml b/tests_golden/integration/test_cookiecutter_generation/lib/frequenz-test-python/pyproject.toml
index 9dfacc94..be44fd9a 100644
--- a/tests_golden/integration/test_cookiecutter_generation/lib/frequenz-test-python/pyproject.toml
+++ b/tests_golden/integration/test_cookiecutter_generation/lib/frequenz-test-python/pyproject.toml
@@ -3,9 +3,9 @@
[build-system]
requires = [
- "setuptools == 75.5.0",
+ "setuptools == 75.8.0",
"setuptools_scm[toml] == 8.1.0",
- "frequenz-repo-config[lib] == 0.11.0",
+ "frequenz-repo-config[lib] == 0.12.0",
]
build-backend = "setuptools.build_meta"
@@ -42,31 +42,31 @@ dev-flake8 = [
"flake8 == 7.1.1",
"flake8-docstrings == 1.7.0",
"flake8-pyproject == 1.2.3", # For reading the flake8 config from pyproject.toml
- "pydoclint == 0.5.9",
+ "pydoclint == 0.6.0",
"pydocstyle == 6.3.0",
]
-dev-formatting = ["black == 24.10.0", "isort == 5.13.2"]
+dev-formatting = ["black == 25.1.0", "isort == 6.0.0"]
dev-mkdocs = [
"Markdown == 3.7",
- "black == 24.10.0",
+ "black == 25.1.0",
"mike == 2.1.3",
"mkdocs-gen-files == 0.5.0",
"mkdocs-literate-nav == 0.6.1",
"mkdocs-macros-plugin == 1.3.7",
- "mkdocs-material == 9.5.45",
+ "mkdocs-material == 9.6.2",
"mkdocstrings[python] == 0.28.0",
"mkdocstrings-python == 1.14.0",
- "frequenz-repo-config[lib] == 0.11.0",
+ "frequenz-repo-config[lib] == 0.12.0",
]
dev-mypy = [
"mypy == 1.9.0",
- "types-Markdown == 3.7.0.20240822",
+ "types-Markdown == 3.7.0.20241204",
# For checking the noxfile, docs/ script, and tests
"frequenz-test[dev-mkdocs,dev-noxfile,dev-pytest]",
]
dev-noxfile = [
"nox == 2024.10.9",
- "frequenz-repo-config[lib] == 0.11.0",
+ "frequenz-repo-config[lib] == 0.12.0",
]
dev-pylint = [
# dev-pytest already defines a dependency to pylint because of the examples
@@ -74,12 +74,12 @@ dev-pylint = [
"frequenz-test[dev-mkdocs,dev-noxfile,dev-pytest]",
]
dev-pytest = [
- "pytest == 8.3.3",
- "pylint == 3.3.1", # We need this to check for the examples
- "frequenz-repo-config[extra-lint-examples] == 0.11.0",
+ "pytest == 8.3.4",
+ "pylint == 3.3.4", # We need this to check for the examples
+ "frequenz-repo-config[extra-lint-examples] == 0.12.0",
"pytest-mock == 3.14.0",
- "pytest-asyncio == 0.24.0",
- "async-solipsism == 0.6",
+ "pytest-asyncio == 0.25.3",
+ "async-solipsism == 0.7",
]
dev = [
"frequenz-test[dev-mkdocs,dev-flake8,dev-formatting,dev-mkdocs,dev-mypy,dev-noxfile,dev-pylint,dev-pytest]",
diff --git a/tests_golden/integration/test_cookiecutter_generation/model/cookiecutter-stdout.txt b/tests_golden/integration/test_cookiecutter_generation/model/cookiecutter-stdout.txt
index 0ba3358d..f48384c7 100644
--- a/tests_golden/integration/test_cookiecutter_generation/model/cookiecutter-stdout.txt
+++ b/tests_golden/integration/test_cookiecutter_generation/model/cookiecutter-stdout.txt
@@ -11,7 +11,6 @@
./.github/workflows/release-notes-check.yml: # TODO(cookiecutter): Uncomment the following line for private repositories, otherwise remove it
./CODEOWNERS:# TODO(cookiecutter): Add more specific code-owners, check if the default is correct
./README.md:TODO(cookiecutter): Improve the README file
-./docs/_scripts/macros.py: # TODO(cookiecutter): Add any other macros, variables and filters here.
./mkdocs.yml: # TODO(cookiecutter): You might want to add other external references here
./mkdocs.yml: # TODO(cookiecutter): You might want to change the logo, the file is located in "docs/"
./mkdocs.yml: # TODO(cookiecutter): You probably want to update the social links
diff --git a/tests_golden/integration/test_cookiecutter_generation/model/frequenz-model-test/docs/_scripts/macros.py b/tests_golden/integration/test_cookiecutter_generation/model/frequenz-model-test/docs/_scripts/macros.py
deleted file mode 100644
index 2ae42657..00000000
--- a/tests_golden/integration/test_cookiecutter_generation/model/frequenz-model-test/docs/_scripts/macros.py
+++ /dev/null
@@ -1,80 +0,0 @@
-# License: MIT
-# Copyright © 2023 Frequenz Energy-as-a-Service GmbH
-
-"""This module defines macros for use in Markdown files."""
-
-from typing import Any
-
-import markdown as md
-from markdown.extensions import toc
-from mkdocs_macros import plugin as macros
-
-_CODE_ANNOTATION_MARKER: str = (
- r''
- r''
- r''
- r""
- r""
-)
-
-
-def _slugify(text: str) -> str:
- """Slugify a text.
-
- Args:
- text: The text to slugify.
-
- Returns:
- The slugified text.
- """
- return toc.slugify_unicode(text, "-")
-
-
-def _hook_macros_plugin(env: macros.MacrosPlugin) -> None:
- """Integrate the `mkdocs-macros` plugin into `mkdocstrings`.
-
- This is a temporary workaround to make `mkdocs-macros` work with
- `mkdocstrings` until a proper `mkdocs-macros` *pluglet* is available. See
- https://github.com/mkdocstrings/mkdocstrings/issues/615 for details.
-
- Args:
- env: The environment to hook the plugin into.
- """
- # get mkdocstrings' Python handler
- python_handler = env.conf["plugins"]["mkdocstrings"].get_handler("python")
-
- # get the `update_env` method of the Python handler
- update_env = python_handler.update_env
-
- # override the `update_env` method of the Python handler
- def patched_update_env(md: md.Markdown, config: dict[str, Any]) -> None:
- update_env(md=md, config=config)
-
- # get the `convert_markdown` filter of the env
- convert_markdown = python_handler.env.filters["convert_markdown"]
-
- # build a chimera made of macros+mkdocstrings
- def render_convert(markdown: str, *args: Any, **kwargs: Any) -> Any:
- return convert_markdown(env.render(markdown), *args, **kwargs)
-
- # patch the filter
- python_handler.env.filters["convert_markdown"] = render_convert
-
- # patch the method
- python_handler.update_env = patched_update_env
-
-
-def define_env(env: macros.MacrosPlugin) -> None:
- """Define the hook to create macro functions for use in Markdown.
-
- Args:
- env: The environment to define the macro functions in.
- """
- # A variable to easily show an example code annotation from mkdocs-material.
- # https://squidfunk.github.io/mkdocs-material/reference/code-blocks/#adding-annotations
- env.variables["code_annotation_marker"] = _CODE_ANNOTATION_MARKER
-
- # TODO(cookiecutter): Add any other macros, variables and filters here.
-
- # This hook needs to be done at the end of the `define_env` function.
- _hook_macros_plugin(env)
diff --git a/tests_golden/integration/test_cookiecutter_generation/model/frequenz-model-test/mkdocs.yml b/tests_golden/integration/test_cookiecutter_generation/model/frequenz-model-test/mkdocs.yml
index d7d1a203..ade2d5ab 100644
--- a/tests_golden/integration/test_cookiecutter_generation/model/frequenz-model-test/mkdocs.yml
+++ b/tests_golden/integration/test_cookiecutter_generation/model/frequenz-model-test/mkdocs.yml
@@ -124,10 +124,9 @@ plugins:
- https://frequenz-floss.github.io/frequenz-sdk-python/v1.0-pre/objects.inv
- https://typing-extensions.readthedocs.io/en/stable/objects.inv
# Note this plugin must be loaded after mkdocstrings to be able to use macros
- # inside docstrings. See the comment in `docs/_scripts/macros.py` for more
- # details
+ # inside docstrings.
- macros:
- module_name: docs/_scripts/macros
+ modules: ["frequenz.repo.config.mkdocs.mkdocstrings_macros"]
on_undefined: strict
on_error_fail: true
- search
diff --git a/tests_golden/integration/test_cookiecutter_generation/model/frequenz-model-test/pyproject.toml b/tests_golden/integration/test_cookiecutter_generation/model/frequenz-model-test/pyproject.toml
index 3a5021d3..0f9ccb1f 100644
--- a/tests_golden/integration/test_cookiecutter_generation/model/frequenz-model-test/pyproject.toml
+++ b/tests_golden/integration/test_cookiecutter_generation/model/frequenz-model-test/pyproject.toml
@@ -3,9 +3,9 @@
[build-system]
requires = [
- "setuptools == 75.5.0",
+ "setuptools == 75.8.0",
"setuptools_scm[toml] == 8.1.0",
- "frequenz-repo-config[model] == 0.11.0",
+ "frequenz-repo-config[model] == 0.12.0",
]
build-backend = "setuptools.build_meta"
@@ -32,7 +32,7 @@ dependencies = [
# Make sure to update the version for cross-referencing also in the
# mkdocs.yml file when changing the version here (look for the config key
# plugins.mkdocstrings.handlers.python.import)
- "frequenz-sdk >= 1.0.0rc1300, < 1.0.0rc1400",
+ "frequenz-sdk >= 1.0.0rc1500, < 1.0.0rc1600",
]
dynamic = ["version"]
@@ -46,31 +46,31 @@ dev-flake8 = [
"flake8 == 7.1.1",
"flake8-docstrings == 1.7.0",
"flake8-pyproject == 1.2.3", # For reading the flake8 config from pyproject.toml
- "pydoclint == 0.5.9",
+ "pydoclint == 0.6.0",
"pydocstyle == 6.3.0",
]
-dev-formatting = ["black == 24.10.0", "isort == 5.13.2"]
+dev-formatting = ["black == 25.1.0", "isort == 6.0.0"]
dev-mkdocs = [
"Markdown == 3.7",
- "black == 24.10.0",
+ "black == 25.1.0",
"mike == 2.1.3",
"mkdocs-gen-files == 0.5.0",
"mkdocs-literate-nav == 0.6.1",
"mkdocs-macros-plugin == 1.3.7",
- "mkdocs-material == 9.5.45",
+ "mkdocs-material == 9.6.2",
"mkdocstrings[python] == 0.28.0",
"mkdocstrings-python == 1.14.0",
- "frequenz-repo-config[model] == 0.11.0",
+ "frequenz-repo-config[model] == 0.12.0",
]
dev-mypy = [
"mypy == 1.9.0",
- "types-Markdown == 3.7.0.20240822",
+ "types-Markdown == 3.7.0.20241204",
# For checking the noxfile, docs/ script, and tests
"frequenz-model-test[dev-mkdocs,dev-noxfile,dev-pytest]",
]
dev-noxfile = [
"nox == 2024.10.9",
- "frequenz-repo-config[model] == 0.11.0",
+ "frequenz-repo-config[model] == 0.12.0",
]
dev-pylint = [
# dev-pytest already defines a dependency to pylint because of the examples
@@ -78,12 +78,12 @@ dev-pylint = [
"frequenz-model-test[dev-mkdocs,dev-noxfile,dev-pytest]",
]
dev-pytest = [
- "pytest == 8.3.3",
- "pylint == 3.3.1", # We need this to check for the examples
- "frequenz-repo-config[extra-lint-examples] == 0.11.0",
+ "pytest == 8.3.4",
+ "pylint == 3.3.4", # We need this to check for the examples
+ "frequenz-repo-config[extra-lint-examples] == 0.12.0",
"pytest-mock == 3.14.0",
- "pytest-asyncio == 0.24.0",
- "async-solipsism == 0.6",
+ "pytest-asyncio == 0.25.3",
+ "async-solipsism == 0.7",
]
dev = [
"frequenz-model-test[dev-mkdocs,dev-flake8,dev-formatting,dev-mkdocs,dev-mypy,dev-noxfile,dev-pylint,dev-pytest]",