From 41edfebd8c606d036399cdea4ae237b32a1f4794 Mon Sep 17 00:00:00 2001 From: Leandro Lucarella Date: Tue, 4 Feb 2025 12:09:17 +0100 Subject: [PATCH 01/16] Add a new module for using numbered code annotations This module is basically documentation, but there is some relationship to macros as we'll provide the `CODE_ANNOTATION_MARKER` as a macro variable, so we take the opportunity to unify the documentation in one place. Signed-off-by: Leandro Lucarella --- .../repo/config/mkdocs/annotations.py | 80 +++++++++++++++++++ 1 file changed, 80 insertions(+) create mode 100644 src/frequenz/repo/config/mkdocs/annotations.py 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.""" From 7268922f1dbeb6064a81ee65697d658fb12c5a9e Mon Sep 17 00:00:00 2001 From: Leandro Lucarella Date: Tue, 4 Feb 2025 12:13:35 +0100 Subject: [PATCH 02/16] Add a module to hook mkdocstrings and macros This module provides the required hooking, so macros can be used inside docstrings properly when using `mkdocstrings`. Signed-off-by: Leandro Lucarella --- .../repo/config/mkdocs/mkdocstrings_macros.py | 116 ++++++++++++++++++ 1 file changed, 116 insertions(+) create mode 100644 src/frequenz/repo/config/mkdocs/mkdocstrings_macros.py 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..7fa780cc --- /dev/null +++ b/src/frequenz/repo/config/mkdocs/mkdocstrings_macros.py @@ -0,0 +1,116 @@ +# 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. + +To use this module, add the following configuration to your `mkdocs.yml`: + +```yaml title="mkdocs.yml" +plugins: + # Order is important! mkdocstrings must come before macros! + - mkdocstrings: + default_handler: python + # ... + - macros: + module_name: path/to/macros + on_undefined: strict + on_error_fail: true +``` + +Then you need to add the `path/to/macros.py` file. The contents will vary depending on +if you want to use use the convenience default hooking or not. + +# Basic usage + +A convenience [`define_env()`] function is provided to provide a [macros +extension](https://mkdocs-macros-plugin.readthedocs.io/en/latest/macros/) to do the +hooking and provide some useful variables and filters: + +* [`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). + +If you are happy with the defaults, your `path/to/macros.py` can look as simple as: + +```py title="path/to/macros.py" +from frequenz.repo.config.mkdocs.mkdocstrings_macros import define_env +``` + +# Advanced usage + +If you want to define your own macros, variables or filters, you'll need to provide your +own `define_env()` function, and call the hook to integrate with `mkdocstrings` 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) +``` +""" + + +from typing import Any + +import markdown as md +from mkdocs_macros import plugin as macros + +from .annotations import CODE_ANNOTATION_MARKER + + +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 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. + """ + env.variables.code_annotation_marker = CODE_ANNOTATION_MARKER + + # This hook needs to be done at the end of the `define_env` function. + hook_macros_plugin(env) From 10a10bddcaf72afce02a3990e2cf5722fbfa3ef4 Mon Sep 17 00:00:00 2001 From: Leandro Lucarella Date: Tue, 4 Feb 2025 12:14:11 +0100 Subject: [PATCH 03/16] Add a `slugify` function and filter Signed-off-by: Leandro Lucarella --- .../repo/config/mkdocs/mkdocstrings_macros.py | 26 ++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/src/frequenz/repo/config/mkdocs/mkdocstrings_macros.py b/src/frequenz/repo/config/mkdocs/mkdocstrings_macros.py index 7fa780cc..00025438 100644 --- a/src/frequenz/repo/config/mkdocs/mkdocstrings_macros.py +++ b/src/frequenz/repo/config/mkdocs/mkdocstrings_macros.py @@ -32,6 +32,8 @@ extension](https://mkdocs-macros-plugin.readthedocs.io/en/latest/macros/) to 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). @@ -51,10 +53,11 @@ 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 +from frequenz.repo.config.mkdocs.mkdocstrings_macros import hook_macros_plugin, slugify def define_env(env: macros.MacrosPlugin) -> None: env.variables.my_var = "Example" + env.filter(slugify, "slugify") # This hook needs to be done at the end of the `define_env` function. hook_macros_plugin(env) @@ -65,11 +68,31 @@ def define_env(env: macros.MacrosPlugin) -> None: from typing import Any import markdown as md +from markdown.extensions import toc from mkdocs_macros import plugin as macros from .annotations import CODE_ANNOTATION_MARKER +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 hook_macros_plugin(env: macros.MacrosPlugin) -> None: """Integrate the `mkdocs-macros` plugin into `mkdocstrings`. @@ -111,6 +134,7 @@ def define_env(env: macros.MacrosPlugin) -> None: env: The environment to define the macro functions in. """ env.variables.code_annotation_marker = CODE_ANNOTATION_MARKER + 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) From b92cf61d549faeca8dd3640579492856efb3fe26 Mon Sep 17 00:00:00 2001 From: Leandro Lucarella Date: Tue, 4 Feb 2025 12:45:44 +0100 Subject: [PATCH 04/16] Add and utility function and variables for getting version info This commit adds a new utility function to retrieve version information from the repository and expose it as a couple of macro variables. This function is also called from the convenience `define_env()` function, so the variables are provided by default. Signed-off-by: Leandro Lucarella --- .../repo/config/mkdocs/mkdocstrings_macros.py | 62 +++++++++++++++++++ 1 file changed, 62 insertions(+) diff --git a/src/frequenz/repo/config/mkdocs/mkdocstrings_macros.py b/src/frequenz/repo/config/mkdocs/mkdocstrings_macros.py index 00025438..c631e36a 100644 --- a/src/frequenz/repo/config/mkdocs/mkdocstrings_macros.py +++ b/src/frequenz/repo/config/mkdocs/mkdocstrings_macros.py @@ -37,6 +37,16 @@ * [`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 repository URL, please read the + [Advanced usage] section for more details. If you are happy with the defaults, your `path/to/macros.py` can look as simple as: @@ -57,6 +67,8 @@ def define_env(env: macros.MacrosPlugin) -> None: env.variables.my_var = "Example" + add_version_variables(env, "git+https://your-repo-url") + env.filter(slugify, "slugify") # This hook needs to be done at the end of the `define_env` function. @@ -65,14 +77,18 @@ def define_env(env: macros.MacrosPlugin) -> None: """ +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. @@ -93,6 +109,50 @@ def slugify(text: str) -> str: 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`. + + Args: + env: The environment to add the variables to. + repo_url: The URL of the repository to use in the `version_requirement` + variable. Only needed if you want to use the `version_requirement` variable + for branches. + """ + env.variables["version"] = None + env.variables["version_requirement"] = "" + 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}" + elif version_info.current_branch: + if repo_url is None: + _logger.warning( + "No repo_url provided, can't build the 'version_requirement' variable" + ) + else: + env.variables["version_requirement"] = ( + f" @ {repo_url}@{version_info.current_branch}" + ) + + def hook_macros_plugin(env: macros.MacrosPlugin) -> None: """Integrate the `mkdocs-macros` plugin into `mkdocstrings`. @@ -134,6 +194,8 @@ def define_env(env: macros.MacrosPlugin) -> None: env: The environment to define the macro functions in. """ env.variables.code_annotation_marker = CODE_ANNOTATION_MARKER + add_version_variables(env) + env.filter(slugify, "slugify") # type: ignore[no-untyped-call] # This hook needs to be done at the end of the `define_env` function. From 23804042c3b36c5c4d2fb6ac8a5b26f30e512a35 Mon Sep 17 00:00:00 2001 From: Leandro Lucarella Date: Tue, 4 Feb 2025 13:02:29 +0100 Subject: [PATCH 05/16] Add a function to get the default behaviour The new function `hook_env_with_everything()` will do all the default hooking, so it is easier to define a custom `define_env()` where only a few macros are added, but still gets all the variables macros and filters provided by this module. Signed-off-by: Leandro Lucarella --- .../repo/config/mkdocs/mkdocstrings_macros.py | 59 +++++++++++++++---- 1 file changed, 48 insertions(+), 11 deletions(-) diff --git a/src/frequenz/repo/config/mkdocs/mkdocstrings_macros.py b/src/frequenz/repo/config/mkdocs/mkdocstrings_macros.py index c631e36a..a4bcfb3e 100644 --- a/src/frequenz/repo/config/mkdocs/mkdocstrings_macros.py +++ b/src/frequenz/repo/config/mkdocs/mkdocstrings_macros.py @@ -54,22 +54,40 @@ from frequenz.repo.config.mkdocs.mkdocstrings_macros import define_env ``` -# Advanced usage +# 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 can define your own +`define_env()` function and call the [`hook_env_with_everything()`] function at the end. -If you want to define your own macros, variables or filters, you'll need to provide your -own `define_env()` function, and call the hook to integrate with `mkdocstrings` at the -end. +This function will add all the default variables and filters and call do the hooking as +described in [Basic usage]. You just need to be sure to call the function at the end. +You can also pass a `repo_url` in this case so the `version_requirement` variable can +work when the current version is a branch. 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, slugify +from frequenz.repo.config.mkdocs.mkdocstrings_macros import hook_env_with_everything def define_env(env: macros.MacrosPlugin) -> None: env.variables.my_var = "Example" - add_version_variables(env, "git+https://your-repo-url") + hook_env_with_everything(env, "git+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 call the hook to integrate with `mkdocstrings` at +the end. - env.filter(slugify, "slugify") +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) @@ -187,16 +205,35 @@ def render_convert(markdown: str, *args: Any, **kwargs: Any) -> Any: 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. +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 define the macro functions in. + env: The environment to hook. + repo_url: The URL of the repository to use in the `version_requirement` + variable. 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) + 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) From 30cc92a9d066c812089ab9abd6b80f61c2d8cb69 Mon Sep 17 00:00:00 2001 From: Leandro Lucarella Date: Tue, 4 Feb 2025 13:17:08 +0100 Subject: [PATCH 06/16] Update documentation with a simplified setup For the basic usage we can actually use the module itself as a *pluglet*: https://mkdocs-macros-plugin.readthedocs.io/en/latest/pluglets/ Signed-off-by: Leandro Lucarella --- .../repo/config/mkdocs/mkdocstrings_macros.py | 64 +++++++++++-------- 1 file changed, 38 insertions(+), 26 deletions(-) diff --git a/src/frequenz/repo/config/mkdocs/mkdocstrings_macros.py b/src/frequenz/repo/config/mkdocs/mkdocstrings_macros.py index a4bcfb3e..302cbdf5 100644 --- a/src/frequenz/repo/config/mkdocs/mkdocstrings_macros.py +++ b/src/frequenz/repo/config/mkdocs/mkdocstrings_macros.py @@ -5,11 +5,15 @@ # 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. +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. -To use this module, add the following configuration to your `mkdocs.yml`: + +# 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: @@ -18,19 +22,12 @@ default_handler: python # ... - macros: - module_name: path/to/macros + modules: ["frequenz.repo.config.mkdocs.mkdocstrings_macros"] on_undefined: strict on_error_fail: true ``` -Then you need to add the `path/to/macros.py` file. The contents will vary depending on -if you want to use use the convenience default hooking or not. - -# Basic usage - -A convenience [`define_env()`] function is provided to provide a [macros -extension](https://mkdocs-macros-plugin.readthedocs.io/en/latest/macros/) to do the -hooking and provide some useful variables and filters: +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. @@ -48,22 +45,33 @@ requirement for a branch, you need to provide a repository URL, please read the [Advanced usage] section for more details. -If you are happy with the defaults, your `path/to/macros.py` can look as simple as: - -```py title="path/to/macros.py" -from frequenz.repo.config.mkdocs.mkdocstrings_macros import define_env -``` # 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 can define your own -`define_env()` function and call the [`hook_env_with_everything()`] function at the end. +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: -This function will add all the default variables and filters and call do the hooking as -described in [Basic usage]. You just need to be sure to call the function at the end. -You can also pass a `repo_url` in this case so the `version_requirement` variable can -work when the current version is a branch. +```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. Here is an example of how to do it: @@ -72,14 +80,18 @@ 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, "git+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 call the hook to integrate with `mkdocstrings` at -the end. +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: From bc3b64e7d5fcd7a5fb98d3c33efdbe715ce4bf22 Mon Sep 17 00:00:00 2001 From: Leandro Lucarella Date: Tue, 4 Feb 2025 13:26:04 +0100 Subject: [PATCH 07/16] Fetch the `repo_url` from the `mkdocs.yaml` With this, there is no need for customization unless you want to define your own macros. Signed-off-by: Leandro Lucarella --- .../repo/config/mkdocs/mkdocstrings_macros.py | 37 +++++++++++-------- 1 file changed, 22 insertions(+), 15 deletions(-) diff --git a/src/frequenz/repo/config/mkdocs/mkdocstrings_macros.py b/src/frequenz/repo/config/mkdocs/mkdocstrings_macros.py index 302cbdf5..b345d4aa 100644 --- a/src/frequenz/repo/config/mkdocs/mkdocstrings_macros.py +++ b/src/frequenz/repo/config/mkdocs/mkdocstrings_macros.py @@ -42,8 +42,9 @@ 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 repository URL, please read the - [Advanced usage] section for more details. + 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 @@ -71,7 +72,8 @@ 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. +`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: @@ -82,7 +84,7 @@ 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, "git+https://your-repo-url") + hook_env_with_everything(env, "https://your-repo-url") ``` # Advanced usage @@ -154,16 +156,25 @@ def add_version_variables( 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`. + 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. Only needed if you want to use the `version_requirement` variable - for branches. + 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" + ) + try: version_info = get_repo_version_info() except Exception as exc: # pylint: disable=broad-except @@ -173,13 +184,9 @@ def add_version_variables( if version_info.current_tag: env.variables["version_requirement"] = f" == {version_info.current_tag}" elif version_info.current_branch: - if repo_url is None: - _logger.warning( - "No repo_url provided, can't build the 'version_requirement' variable" - ) - else: + if repo_url is not None: env.variables["version_requirement"] = ( - f" @ {repo_url}@{version_info.current_branch}" + f" @ git+{repo_url}@{version_info.current_branch}" ) @@ -230,8 +237,8 @@ def hook_env_with_everything( Args: env: The environment to hook. repo_url: The URL of the repository to use in the `version_requirement` - variable. Only needed if you want to use the `version_requirement` variable - for branches. + 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) From 831faf044159c0f9533d048f37113079d81af6f7 Mon Sep 17 00:00:00 2001 From: Leandro Lucarella Date: Tue, 4 Feb 2025 13:49:04 +0100 Subject: [PATCH 08/16] Add support for SHAs in `version_requirement` Signed-off-by: Leandro Lucarella --- src/frequenz/repo/config/mkdocs/mkdocstrings_macros.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/frequenz/repo/config/mkdocs/mkdocstrings_macros.py b/src/frequenz/repo/config/mkdocs/mkdocstrings_macros.py index b345d4aa..97fa4ee3 100644 --- a/src/frequenz/repo/config/mkdocs/mkdocstrings_macros.py +++ b/src/frequenz/repo/config/mkdocs/mkdocstrings_macros.py @@ -183,10 +183,10 @@ def add_version_variables( env.variables["version"] = version_info if version_info.current_tag: env.variables["version_requirement"] = f" == {version_info.current_tag}" - elif version_info.current_branch: + elif version_info.current_branch or version_info.sha: if repo_url is not None: env.variables["version_requirement"] = ( - f" @ git+{repo_url}@{version_info.current_branch}" + f" @ git+{repo_url}@{version_info.current_branch or version_info.sha}" ) From 6fde9506ad7ef093f9229e9f7599539468b599e0 Mon Sep 17 00:00:00 2001 From: Leandro Lucarella Date: Tue, 4 Feb 2025 14:07:18 +0100 Subject: [PATCH 09/16] Add `version_requirement` with the sha if we can get it from Git The macros plugin already offer easy access to git info, so we can do a last resort try of getting the current sha from there. Signed-off-by: Leandro Lucarella --- .../repo/config/mkdocs/mkdocstrings_macros.py | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/frequenz/repo/config/mkdocs/mkdocstrings_macros.py b/src/frequenz/repo/config/mkdocs/mkdocstrings_macros.py index 97fa4ee3..82e4f78f 100644 --- a/src/frequenz/repo/config/mkdocs/mkdocstrings_macros.py +++ b/src/frequenz/repo/config/mkdocs/mkdocstrings_macros.py @@ -175,6 +175,7 @@ def add_version_variables( "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 @@ -183,11 +184,13 @@ def add_version_variables( env.variables["version"] = version_info if version_info.current_tag: env.variables["version_requirement"] = f" == {version_info.current_tag}" - elif version_info.current_branch or version_info.sha: - if repo_url is not None: - env.variables["version_requirement"] = ( - f" @ git+{repo_url}@{version_info.current_branch or version_info.sha}" - ) + + 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: From af7ad872826d0386cce79ad7e32f2bd4e52f5d26 Mon Sep 17 00:00:00 2001 From: Leandro Lucarella Date: Tue, 4 Feb 2025 13:49:44 +0100 Subject: [PATCH 10/16] Add `RepoVersionInfo.__repr__()` Signed-off-by: Leandro Lucarella --- src/frequenz/repo/config/version.py | 7 +++++++ 1 file changed, 7 insertions(+) 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})" + ) From 147869a1b30b206106e03782448c275c0158a5a8 Mon Sep 17 00:00:00 2001 From: Leandro Lucarella Date: Tue, 4 Feb 2025 13:50:59 +0100 Subject: [PATCH 11/16] Use the new macros *pluglet* This completely removes the macros script. Signed-off-by: Leandro Lucarella --- docs/_scripts/macros.py | 108 ---------------------------------------- mkdocs.yml | 5 +- 2 files changed, 2 insertions(+), 111 deletions(-) delete mode 100644 docs/_scripts/macros.py 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 From bd5a72c580d86ccfa6e65e62a50ff14290c9c71b Mon Sep 17 00:00:00 2001 From: Leandro Lucarella Date: Tue, 4 Feb 2025 15:13:47 +0100 Subject: [PATCH 12/16] Bump template dependencies Signed-off-by: Leandro Lucarella --- .../pyproject.toml | 38 +++++++++---------- .../actor/frequenz-actor-test/pyproject.toml | 22 +++++------ .../api/frequenz-api-test/pyproject.toml | 30 +++++++-------- .../app/frequenz-app-test/pyproject.toml | 22 +++++------ .../lib/frequenz-test-python/pyproject.toml | 20 +++++----- .../model/frequenz-model-test/pyproject.toml | 22 +++++------ 6 files changed, 77 insertions(+), 77 deletions(-) diff --git a/cookiecutter/{{cookiecutter.github_repo_name}}/pyproject.toml b/cookiecutter/{{cookiecutter.github_repo_name}}/pyproject.toml index 4f95d637..c3060838 100644 --- a/cookiecutter/{{cookiecutter.github_repo_name}}/pyproject.toml +++ b/cookiecutter/{{cookiecutter.github_repo_name}}/pyproject.toml @@ -3,7 +3,7 @@ [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", {%- if cookiecutter.type == "api" %} @@ -11,9 +11,9 @@ requires = [ # 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,18 +87,18 @@ 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", @@ -106,9 +106,9 @@ dev-mkdocs = [ 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]", ] @@ -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 + "pytest == 8.3.4", + "pylint == 3.3.4", # We need this to check for the examples "frequenz-repo-config[extra-lint-examples] == 0.11.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/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..8d7bccb0 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,7 +3,7 @@ [build-system] requires = [ - "setuptools == 75.5.0", + "setuptools == 75.8.0", "setuptools_scm[toml] == 8.1.0", "frequenz-repo-config[actor] == 0.11.0", ] @@ -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,25 +46,25 @@ 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", ] 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]", ] @@ -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 + "pytest == 8.3.4", + "pylint == 3.3.4", # We need this to check for the examples "frequenz-repo-config[extra-lint-examples] == 0.11.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/frequenz-api-test/pyproject.toml b/tests_golden/integration/test_cookiecutter_generation/api/frequenz-api-test/pyproject.toml index 577b2092..70462bab 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", # 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,26 +57,26 @@ 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", ] 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]", ] @@ -90,8 +90,8 @@ 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 + "pytest == 8.3.4", + "pylint == 3.3.4", # We need this to check for the examples "frequenz-repo-config[extra-lint-examples] == 0.11.0", ] dev = [ 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..4ccbf051 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,7 +3,7 @@ [build-system] requires = [ - "setuptools == 75.5.0", + "setuptools == 75.8.0", "setuptools_scm[toml] == 8.1.0", "frequenz-repo-config[app] == 0.11.0", ] @@ -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,25 +45,25 @@ 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", ] 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]", ] @@ -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 + "pytest == 8.3.4", + "pylint == 3.3.4", # We need this to check for the examples "frequenz-repo-config[extra-lint-examples] == 0.11.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/frequenz-test-python/pyproject.toml b/tests_golden/integration/test_cookiecutter_generation/lib/frequenz-test-python/pyproject.toml index 9dfacc94..3666821e 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,7 +3,7 @@ [build-system] requires = [ - "setuptools == 75.5.0", + "setuptools == 75.8.0", "setuptools_scm[toml] == 8.1.0", "frequenz-repo-config[lib] == 0.11.0", ] @@ -42,25 +42,25 @@ 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", ] 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]", ] @@ -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 + "pytest == 8.3.4", + "pylint == 3.3.4", # We need this to check for the examples "frequenz-repo-config[extra-lint-examples] == 0.11.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/frequenz-model-test/pyproject.toml b/tests_golden/integration/test_cookiecutter_generation/model/frequenz-model-test/pyproject.toml index 3a5021d3..a7ea8e6b 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,7 +3,7 @@ [build-system] requires = [ - "setuptools == 75.5.0", + "setuptools == 75.8.0", "setuptools_scm[toml] == 8.1.0", "frequenz-repo-config[model] == 0.11.0", ] @@ -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,25 +46,25 @@ 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", ] 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]", ] @@ -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 + "pytest == 8.3.4", + "pylint == 3.3.4", # We need this to check for the examples "frequenz-repo-config[extra-lint-examples] == 0.11.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]", From dbe36d5770b5792d895ecaa2d7d5e174ce676933 Mon Sep 17 00:00:00 2001 From: Leandro Lucarella Date: Tue, 4 Feb 2025 15:14:35 +0100 Subject: [PATCH 13/16] Remove macros script from templates We now use the *pluglet* for templates too. Signed-off-by: Leandro Lucarella --- .../docs/_scripts/macros.py | 80 ------------------- .../mkdocs.yml | 5 +- .../actor/cookiecutter-stdout.txt | 1 - .../docs/_scripts/macros.py | 80 ------------------- .../actor/frequenz-actor-test/mkdocs.yml | 5 +- .../api/cookiecutter-stdout.txt | 1 - .../frequenz-api-test/docs/_scripts/macros.py | 80 ------------------- .../api/frequenz-api-test/mkdocs.yml | 5 +- .../app/cookiecutter-stdout.txt | 1 - .../frequenz-app-test/docs/_scripts/macros.py | 80 ------------------- .../app/frequenz-app-test/mkdocs.yml | 5 +- .../lib/cookiecutter-stdout.txt | 1 - .../docs/_scripts/macros.py | 80 ------------------- .../lib/frequenz-test-python/mkdocs.yml | 5 +- .../model/cookiecutter-stdout.txt | 1 - .../docs/_scripts/macros.py | 80 ------------------- .../model/frequenz-model-test/mkdocs.yml | 5 +- 17 files changed, 12 insertions(+), 503 deletions(-) delete mode 100644 cookiecutter/{{cookiecutter.github_repo_name}}/docs/_scripts/macros.py delete mode 100644 tests_golden/integration/test_cookiecutter_generation/actor/frequenz-actor-test/docs/_scripts/macros.py delete mode 100644 tests_golden/integration/test_cookiecutter_generation/api/frequenz-api-test/docs/_scripts/macros.py delete mode 100644 tests_golden/integration/test_cookiecutter_generation/app/frequenz-app-test/docs/_scripts/macros.py delete mode 100644 tests_golden/integration/test_cookiecutter_generation/lib/frequenz-test-python/docs/_scripts/macros.py delete mode 100644 tests_golden/integration/test_cookiecutter_generation/model/frequenz-model-test/docs/_scripts/macros.py 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/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/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/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/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/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 From 1019f6ae0b186496489430448e3cd06e6c928c7b Mon Sep 17 00:00:00 2001 From: Leandro Lucarella Date: Tue, 4 Feb 2025 15:15:20 +0100 Subject: [PATCH 14/16] Bump the repo-config version in templates in preparation for 0.12 Signed-off-by: Leandro Lucarella --- .../{{cookiecutter.github_repo_name}}/pyproject.toml | 8 ++++---- .../actor/frequenz-actor-test/pyproject.toml | 8 ++++---- .../api/frequenz-api-test/pyproject.toml | 8 ++++---- .../app/frequenz-app-test/pyproject.toml | 8 ++++---- .../lib/frequenz-test-python/pyproject.toml | 8 ++++---- .../model/frequenz-model-test/pyproject.toml | 8 ++++---- 6 files changed, 24 insertions(+), 24 deletions(-) diff --git a/cookiecutter/{{cookiecutter.github_repo_name}}/pyproject.toml b/cookiecutter/{{cookiecutter.github_repo_name}}/pyproject.toml index c3060838..7b254021 100644 --- a/cookiecutter/{{cookiecutter.github_repo_name}}/pyproject.toml +++ b/cookiecutter/{{cookiecutter.github_repo_name}}/pyproject.toml @@ -5,7 +5,7 @@ requires = [ "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 @@ -101,7 +101,7 @@ dev-mkdocs = [ "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", @@ -114,7 +114,7 @@ dev-mypy = [ ] 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 @@ -124,7 +124,7 @@ dev-pylint = [ dev-pytest = [ "pytest == 8.3.4", "pylint == 3.3.4", # We need this to check for the examples - "frequenz-repo-config[extra-lint-examples] == 0.11.0", + "frequenz-repo-config[extra-lint-examples] == 0.12.0", {%- if cookiecutter.type != "api" %} "pytest-mock == 3.14.0", "pytest-asyncio == 0.25.3", 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 8d7bccb0..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 @@ -5,7 +5,7 @@ requires = [ "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" @@ -60,7 +60,7 @@ dev-mkdocs = [ "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", @@ -70,7 +70,7 @@ dev-mypy = [ ] 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 @@ -80,7 +80,7 @@ dev-pylint = [ dev-pytest = [ "pytest == 8.3.4", "pylint == 3.3.4", # We need this to check for the examples - "frequenz-repo-config[extra-lint-examples] == 0.11.0", + "frequenz-repo-config[extra-lint-examples] == 0.12.0", "pytest-mock == 3.14.0", "pytest-asyncio == 0.25.3", "async-solipsism == 0.7", 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 70462bab..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 @@ -5,7 +5,7 @@ requires = [ "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. @@ -71,7 +71,7 @@ dev-mkdocs = [ "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", @@ -82,7 +82,7 @@ dev-mypy = [ ] 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 @@ -92,7 +92,7 @@ dev-pylint = [ dev-pytest = [ "pytest == 8.3.4", "pylint == 3.3.4", # We need this to check for the examples - "frequenz-repo-config[extra-lint-examples] == 0.11.0", + "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/frequenz-app-test/pyproject.toml b/tests_golden/integration/test_cookiecutter_generation/app/frequenz-app-test/pyproject.toml index 4ccbf051..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 @@ -5,7 +5,7 @@ requires = [ "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" @@ -59,7 +59,7 @@ dev-mkdocs = [ "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", @@ -69,7 +69,7 @@ dev-mypy = [ ] 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 @@ -79,7 +79,7 @@ dev-pylint = [ dev-pytest = [ "pytest == 8.3.4", "pylint == 3.3.4", # We need this to check for the examples - "frequenz-repo-config[extra-lint-examples] == 0.11.0", + "frequenz-repo-config[extra-lint-examples] == 0.12.0", "pytest-mock == 3.14.0", "pytest-asyncio == 0.25.3", "async-solipsism == 0.7", 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 3666821e..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 @@ -5,7 +5,7 @@ requires = [ "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" @@ -56,7 +56,7 @@ dev-mkdocs = [ "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", @@ -66,7 +66,7 @@ dev-mypy = [ ] 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 @@ -76,7 +76,7 @@ dev-pylint = [ dev-pytest = [ "pytest == 8.3.4", "pylint == 3.3.4", # We need this to check for the examples - "frequenz-repo-config[extra-lint-examples] == 0.11.0", + "frequenz-repo-config[extra-lint-examples] == 0.12.0", "pytest-mock == 3.14.0", "pytest-asyncio == 0.25.3", "async-solipsism == 0.7", 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 a7ea8e6b..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 @@ -5,7 +5,7 @@ requires = [ "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" @@ -60,7 +60,7 @@ dev-mkdocs = [ "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", @@ -70,7 +70,7 @@ dev-mypy = [ ] 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 @@ -80,7 +80,7 @@ dev-pylint = [ dev-pytest = [ "pytest == 8.3.4", "pylint == 3.3.4", # We need this to check for the examples - "frequenz-repo-config[extra-lint-examples] == 0.11.0", + "frequenz-repo-config[extra-lint-examples] == 0.12.0", "pytest-mock == 3.14.0", "pytest-asyncio == 0.25.3", "async-solipsism == 0.7", From 0c3bc4483f2ba4ab5e9cf5769cc351813babf49d Mon Sep 17 00:00:00 2001 From: Leandro Lucarella Date: Tue, 4 Feb 2025 15:40:45 +0100 Subject: [PATCH 15/16] Add mgration script Signed-off-by: Leandro Lucarella --- cookiecutter/migrate.py | 111 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 109 insertions(+), 2 deletions(-) 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() From d01b08eb27663992377f267cfd64123d1478c6f1 Mon Sep 17 00:00:00 2001 From: Leandro Lucarella Date: Tue, 4 Feb 2025 16:11:29 +0100 Subject: [PATCH 16/16] Update release notes Signed-off-by: Leandro Lucarella --- RELEASE_NOTES.md | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) 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.