From ff37283473571c017da78289879d8a612e35eb98 Mon Sep 17 00:00:00 2001 From: Andreas Zwinkau Date: Tue, 24 Mar 2026 13:48:37 +0100 Subject: [PATCH 1/4] Allow to configure a different metamodel Fixes https://github.com/eclipse-score/docs-as-code/issues/415 --- docs.bzl | 75 ++++++++++++++----- docs/how-to/setup.md | 6 +- docs/reference/bazel_macros.rst | 23 ++++++ src/extensions/score_metamodel/__init__.py | 5 +- .../tests/test_metamodel__init__.py | 65 ++++++++++++++++ .../tests/test_metamodel_load.py | 9 +++ src/extensions/score_metamodel/yaml_parser.py | 9 ++- src/incremental.py | 4 + 8 files changed, 174 insertions(+), 22 deletions(-) diff --git a/docs.bzl b/docs.bzl index 699c2370f..b0e01c226 100644 --- a/docs.bzl +++ b/docs.bzl @@ -125,7 +125,7 @@ def _missing_requirements(deps): fail(msg) fail("This case should be unreachable?!") -def docs(source_dir = "docs", data = [], deps = [], scan_code = [], known_good = None): +def docs(source_dir = "docs", data = [], deps = [], scan_code = [], known_good = None, metamodel = None): """Creates all targets related to documentation. By using this function, you'll get any and all updates for documentation targets in one place. @@ -135,6 +135,9 @@ def docs(source_dir = "docs", data = [], deps = [], scan_code = [], known_good = data: Additional data files to include in the documentation build. deps: Additional dependencies for the documentation build. scan_code: List of code targets to scan for source code links. + known_good: Optional label to a "known good" JSON file for source links. + metamodel: Optional label to a metamodel.yaml file. When set, the extension loads this + file instead of the default metamodel shipped with score_metamodel. """ call_path = native.package_name() @@ -142,6 +145,14 @@ def docs(source_dir = "docs", data = [], deps = [], scan_code = [], known_good = if call_path != "": fail("docs() must be called from the root package. Current package: " + call_path) + metamodel_data = [] + metamodel_env = {} + metamodel_opts = [] + if metamodel != None: + metamodel_data = [metamodel] + metamodel_env = {"SCORE_METAMODEL_YAML": "$(location " + str(metamodel) + ")"} + metamodel_opts = ["--define=score_metamodel_yaml=$(location " + str(metamodel) + ")"] + module_deps = deps deps = deps + _missing_requirements(deps) deps = deps + [ @@ -152,7 +163,7 @@ def docs(source_dir = "docs", data = [], deps = [], scan_code = [], known_good = sphinx_build_binary( name = "sphinx_build", visibility = ["//visibility:private"], - data = data, + data = data + metamodel_data, deps = deps, ) @@ -212,9 +223,14 @@ def docs(source_dir = "docs", data = [], deps = [], scan_code = [], known_good = name = "docs", tags = ["cli_help=Build documentation:\nbazel run //:docs"], srcs = ["@score_docs_as_code//src:incremental.py"], - data = docs_data, + data = data + [":sourcelinks_json"] + metamodel_data, deps = deps, - env = docs_env + env = { + "SOURCE_DIRECTORY": source_dir, + "DATA": str(data), + "ACTION": "incremental", + "SCORE_SOURCELINKS": "$(location :sourcelinks_json)", + } | metamodel_env, ) docs_sources_env["ACTION"] = "incremental" @@ -222,9 +238,14 @@ def docs(source_dir = "docs", data = [], deps = [], scan_code = [], known_good = name = "docs_combo", tags = ["cli_help=Build full documentation with all dependencies:\nbazel run //:docs_combo"], srcs = ["@score_docs_as_code//src:incremental.py"], - data = combo_data, + data = data_with_docs_sources + [":merged_sourcelinks"] + metamodel_data, deps = deps, - env = docs_sources_env + env = { + "SOURCE_DIRECTORY": source_dir, + "DATA": str(data_with_docs_sources), + "ACTION": "incremental", + "SCORE_SOURCELINKS": "$(location :merged_sourcelinks)", + } | metamodel_env, ) native.alias( @@ -238,9 +259,13 @@ def docs(source_dir = "docs", data = [], deps = [], scan_code = [], known_good = name = "docs_link_check", tags = ["cli_help=Verify Links inside Documentation:\nbazel run //:link_check\n (Note: this could take a long time)"], srcs = ["@score_docs_as_code//src:incremental.py"], - data = docs_data, + data = data + metamodel_data, deps = deps, - env = docs_env + env = { + "SOURCE_DIRECTORY": source_dir, + "DATA": str(data), + "ACTION": "linkcheck", + } | metamodel_env, ) docs_env["ACTION"] = "check" @@ -248,9 +273,14 @@ def docs(source_dir = "docs", data = [], deps = [], scan_code = [], known_good = name = "docs_check", tags = ["cli_help=Verify documentation:\nbazel run //:docs_check"], srcs = ["@score_docs_as_code//src:incremental.py"], - data = docs_data, + data = data + [":sourcelinks_json"] + metamodel_data, deps = deps, - env = docs_env + env = { + "SOURCE_DIRECTORY": source_dir, + "DATA": str(data), + "ACTION": "check", + "SCORE_SOURCELINKS": "$(location :sourcelinks_json)", + } | metamodel_env, ) docs_env["ACTION"] = "live_preview" @@ -258,9 +288,14 @@ def docs(source_dir = "docs", data = [], deps = [], scan_code = [], known_good = name = "live_preview", tags = ["cli_help=Live preview documentation in the browser:\nbazel run //:live_preview"], srcs = ["@score_docs_as_code//src:incremental.py"], - data = docs_data, + data = data + [":sourcelinks_json"] + metamodel_data, deps = deps, - env = docs_env + env = { + "SOURCE_DIRECTORY": source_dir, + "DATA": str(data), + "ACTION": "live_preview", + "SCORE_SOURCELINKS": "$(location :sourcelinks_json)", + } | metamodel_env, ) docs_sources_env["ACTION"] = "live_preview" @@ -268,9 +303,14 @@ def docs(source_dir = "docs", data = [], deps = [], scan_code = [], known_good = name = "live_preview_combo_experimental", tags = ["cli_help=Live preview full documentation with all dependencies in the browser:\nbazel run //:live_preview_combo_experimental"], srcs = ["@score_docs_as_code//src:incremental.py"], - data = combo_data, + data = data_with_docs_sources + [":merged_sourcelinks"] + metamodel_data, deps = deps, - env = docs_sources_env + env = { + "SOURCE_DIRECTORY": source_dir, + "DATA": str(data_with_docs_sources), + "ACTION": "live_preview", + "SCORE_SOURCELINKS": "$(location :merged_sourcelinks)", + } | metamodel_env, ) py_venv( @@ -278,7 +318,8 @@ def docs(source_dir = "docs", data = [], deps = [], scan_code = [], known_good = tags = ["cli_help=Create virtual environment (.venv_docs) for documentation support:\nbazel run //:ide_support"], venv_name = ".venv_docs", deps = deps, - data = data, + # Add dependencies to ide_support, so esbonio has access to them. + data = data + metamodel_data, package_collisions = "warning", ) @@ -293,10 +334,10 @@ def docs(source_dir = "docs", data = [], deps = [], scan_code = [], known_good = "--jobs", "auto", "--define=external_needs_source=" + str(data), - ], + ] + metamodel_opts, formats = ["needs"], sphinx = ":sphinx_build", - tools = data, + tools = data + metamodel_data, visibility = ["//visibility:public"], # Persistent workers cause stale symlinks after dependency version # changes, corrupting the Bazel cache. diff --git a/docs/how-to/setup.md b/docs/how-to/setup.md index 253f88116..a00096658 100644 --- a/docs/how-to/setup.md +++ b/docs/how-to/setup.md @@ -68,8 +68,10 @@ The `docs()` macro accepts the following arguments: | Parameter | Description | Required | |-----------|-------------|----------| | `source_dir` | Directory of documentation source files (RST, MD) | Yes | -| `data` | List of `needs_json` targets that should be included in the documentation| No | - +| `data` | List of `needs_json` targets that should be included in the documentation | No | +| `deps` | Additional Bazel Python dependencies | No | +| `scan_code` | Source code targets to scan for traceability tags | No | +| `metamodel` | Label to a custom `metamodel.yaml` that replaces the default metamodel | No | ### 4. Copy conf.py diff --git a/docs/reference/bazel_macros.rst b/docs/reference/bazel_macros.rst index 7118f83f8..a801c4af2 100644 --- a/docs/reference/bazel_macros.rst +++ b/docs/reference/bazel_macros.rst @@ -60,6 +60,29 @@ Minimal example (root ``BUILD``) If you don't provide the necessary Sphinx packages, this function adds its own (but checks for conflicts). +- ``scan_code`` (list of bazel labels) + Source code targets to scan for traceability tags (``req-Id:`` annotations). + Used to generate the source-code-link JSON that maps tags back to source files. + +- ``metamodel`` (bazel label, optional) + Path to a custom ``metamodel.yaml`` file. + When set, the ``score_metamodel`` extension loads **this file instead of** the default metamodel. + The label is automatically added to the ``data`` and ``tools`` of every generated target + so the file is available in the Bazel sandbox at build time. + + Example: + + .. code-block:: python + + docs( + source_dir = "docs", + metamodel = "//:my_metamodel.yaml", + ) + + The custom ``metamodel.yaml`` must follow the same schema as the default one + (see :doc:`score_metamodel `). + When ``metamodel`` is omitted the default metamodel is used unchanged. + Edge cases ---------- diff --git a/src/extensions/score_metamodel/__init__.py b/src/extensions/score_metamodel/__init__.py index f0b90c8ee..39be78f19 100644 --- a/src/extensions/score_metamodel/__init__.py +++ b/src/extensions/score_metamodel/__init__.py @@ -228,11 +228,14 @@ def postprocess_need_links(needs_types_list: list[ScoreNeedType]): def setup(app: Sphinx) -> dict[str, str | bool]: app.add_config_value("external_needs_source", "", rebuild="env") + app.add_config_value("score_metamodel_yaml", "", rebuild="env") config_setdefault(app.config, "needs_id_required", True) config_setdefault(app.config, "needs_id_regex", "^[A-Za-z0-9_-]{6,}") # load metamodel.yaml via ruamel.yaml - metamodel = load_metamodel_data() + raw_metamodel_path = app.config.score_metamodel_yaml + override_path = Path(raw_metamodel_path) if raw_metamodel_path else None + metamodel = load_metamodel_data(override_path) # Extend sphinx-needs config rather than overwriting app.config.needs_types += metamodel.needs_types diff --git a/src/extensions/score_metamodel/tests/test_metamodel__init__.py b/src/extensions/score_metamodel/tests/test_metamodel__init__.py index f7d36eae0..2199fa4cd 100644 --- a/src/extensions/score_metamodel/tests/test_metamodel__init__.py +++ b/src/extensions/score_metamodel/tests/test_metamodel__init__.py @@ -10,6 +10,10 @@ # # SPDX-License-Identifier: Apache-2.0 # ******************************************************************************* +import sys +from pathlib import Path +from unittest.mock import MagicMock, patch + import pytest from attribute_plugin import add_test_properties # type: ignore[import-untyped] from sphinx.application import Sphinx @@ -21,9 +25,15 @@ graph_checks, local_checks, parse_checks_filter, + setup, ) from src.extensions.score_metamodel.tests import need +# The module where setup() looks up load_metamodel_data at runtime. +# Using __globals__ avoids breakage when the same file is imported under +# two different names (e.g. "score_metamodel" and "src.extensions.score_metamodel"). +_setup_module = sys.modules[setup.__module__] + def dummy_local_check(app: Sphinx, need: NeedItem, log: CheckLogger) -> None: pass @@ -176,3 +186,58 @@ def test_combined_core_links_and_extras(self): assert n.get("output", []) == ["output_wp"] # Extra fields assert n.get("custom_attr") == "custom_value" + + +# ============================================================================= +# Tests for setup() — score_metamodel_yaml config value wiring +# ============================================================================= + + +def _make_mock_app(metamodel_yaml_value: str = "") -> MagicMock: + """Return a minimal mock Sphinx app suitable for calling setup().""" + app = MagicMock() + app.config.score_metamodel_yaml = metamodel_yaml_value + app.config.needs_types = [] + app.config.needs_extra_links = [] + app.config.needs_extra_options = [] + return app + + +def _mock_metamodel_return(): + return MagicMock( + needs_types=[], + needs_extra_links=[], + needs_extra_options=[], + needs_graph_check={}, + prohibited_words_checks=[], + ) + + +def test_setup_uses_default_path_when_config_empty(): + """setup() calls load_metamodel_data(None) when score_metamodel_yaml is empty.""" + app = _make_mock_app(metamodel_yaml_value="") + + with patch.object( + _setup_module, + "load_metamodel_data", + return_value=_mock_metamodel_return(), + ) as mock_load: + setup(app) + + mock_load.assert_called_once_with(None) + + +def test_setup_passes_path_when_config_set(tmp_path): + """setup() calls load_metamodel_data(Path(...)) when score_metamodel_yaml is set.""" + yaml_file = tmp_path / "custom_metamodel.yaml" + yaml_file.write_text("needs_types: {}\n") + app = _make_mock_app(metamodel_yaml_value=str(yaml_file)) + + with patch.object( + _setup_module, + "load_metamodel_data", + return_value=_mock_metamodel_return(), + ) as mock_load: + setup(app) + + mock_load.assert_called_once_with(Path(str(yaml_file))) diff --git a/src/extensions/score_metamodel/tests/test_metamodel_load.py b/src/extensions/score_metamodel/tests/test_metamodel_load.py index 9a660887a..f5676b870 100644 --- a/src/extensions/score_metamodel/tests/test_metamodel_load.py +++ b/src/extensions/score_metamodel/tests/test_metamodel_load.py @@ -25,6 +25,15 @@ def load_model_data(model_file: str) -> str: return f.read() +def test_load_metamodel_data_explicit_path(): + """When an explicit path is given, load_metamodel_data reads that file.""" + explicit_path = MODEL_DIR / "simple_model.yaml" + result = load_metamodel_data(yaml_path=explicit_path) + + assert len(result.needs_types) == 1 + assert result.needs_types[0]["directive"] == "type1" + + def test_load_metamodel_data(): model_data: str = load_model_data("simple_model.yaml") diff --git a/src/extensions/score_metamodel/yaml_parser.py b/src/extensions/score_metamodel/yaml_parser.py index f40556bbf..454a502c0 100644 --- a/src/extensions/score_metamodel/yaml_parser.py +++ b/src/extensions/score_metamodel/yaml_parser.py @@ -182,11 +182,16 @@ def _collect_all_custom_options( } -def load_metamodel_data() -> MetaModelData: +def load_metamodel_data(yaml_path: Path | None = None) -> MetaModelData: """ Load metamodel.yaml and prepare data fields as needed for sphinx-needs. + + Args: + yaml_path: Path to the metamodel YAML file. When None, the default + metamodel shipped with this extension is used. """ - yaml_path = Path(__file__).resolve().parent / "metamodel.yaml" + if yaml_path is None: + yaml_path = Path(__file__).resolve().parent / "metamodel.yaml" with open(yaml_path, encoding="utf-8") as f: data = cast(dict[str, Any], YAML().load(f)) diff --git a/src/incremental.py b/src/incremental.py index fa1c5abc2..3289865f0 100644 --- a/src/incremental.py +++ b/src/incremental.py @@ -84,6 +84,10 @@ def get_env(name: str) -> str: f"--define=external_needs_source={get_env('DATA')}", ] + metamodel_yaml = os.environ.get("SCORE_METAMODEL_YAML", "") + if metamodel_yaml: + base_arguments.append(f"--define=score_metamodel_yaml={metamodel_yaml}") + # configure sphinx build with GitHub user and repo from CLI if args.github_user and args.github_repo: base_arguments.append(f"-A=github_user={args.github_user}") From c134636f6bda382646c6464d87fe2dd2e9de1f60 Mon Sep 17 00:00:00 2001 From: Andreas Zwinkau Date: Wed, 29 Apr 2026 11:34:40 +0200 Subject: [PATCH 2/4] fix: simplify --- docs.bzl | 62 +++++++++++++++----------------------------------------- 1 file changed, 16 insertions(+), 46 deletions(-) diff --git a/docs.bzl b/docs.bzl index b0e01c226..5a4bd35ef 100644 --- a/docs.bzl +++ b/docs.bzl @@ -205,12 +205,12 @@ def docs(source_dir = "docs", data = [], deps = [], scan_code = [], known_good = "SOURCE_DIRECTORY": source_dir, "DATA": str(data), "SCORE_SOURCELINKS": "$(location :sourcelinks_json)", - } + } | metamodel_env docs_sources_env = { "SOURCE_DIRECTORY": source_dir, "DATA": str(data_with_docs_sources), "SCORE_SOURCELINKS": "$(location :merged_sourcelinks)", - } + } | metamodel_env if known_good: docs_env["KNOWN_GOOD_JSON"] = "$(location "+ known_good + ")" docs_sources_env["KNOWN_GOOD_JSON"] = "$(location "+ known_good + ")" @@ -223,14 +223,9 @@ def docs(source_dir = "docs", data = [], deps = [], scan_code = [], known_good = name = "docs", tags = ["cli_help=Build documentation:\nbazel run //:docs"], srcs = ["@score_docs_as_code//src:incremental.py"], - data = data + [":sourcelinks_json"] + metamodel_data, + data = docs_data, deps = deps, - env = { - "SOURCE_DIRECTORY": source_dir, - "DATA": str(data), - "ACTION": "incremental", - "SCORE_SOURCELINKS": "$(location :sourcelinks_json)", - } | metamodel_env, + env = docs_env ) docs_sources_env["ACTION"] = "incremental" @@ -238,14 +233,9 @@ def docs(source_dir = "docs", data = [], deps = [], scan_code = [], known_good = name = "docs_combo", tags = ["cli_help=Build full documentation with all dependencies:\nbazel run //:docs_combo"], srcs = ["@score_docs_as_code//src:incremental.py"], - data = data_with_docs_sources + [":merged_sourcelinks"] + metamodel_data, + data = combo_data, deps = deps, - env = { - "SOURCE_DIRECTORY": source_dir, - "DATA": str(data_with_docs_sources), - "ACTION": "incremental", - "SCORE_SOURCELINKS": "$(location :merged_sourcelinks)", - } | metamodel_env, + env = docs_sources_env ) native.alias( @@ -259,13 +249,9 @@ def docs(source_dir = "docs", data = [], deps = [], scan_code = [], known_good = name = "docs_link_check", tags = ["cli_help=Verify Links inside Documentation:\nbazel run //:link_check\n (Note: this could take a long time)"], srcs = ["@score_docs_as_code//src:incremental.py"], - data = data + metamodel_data, + data = docs_data, deps = deps, - env = { - "SOURCE_DIRECTORY": source_dir, - "DATA": str(data), - "ACTION": "linkcheck", - } | metamodel_env, + env = docs_env ) docs_env["ACTION"] = "check" @@ -273,14 +259,9 @@ def docs(source_dir = "docs", data = [], deps = [], scan_code = [], known_good = name = "docs_check", tags = ["cli_help=Verify documentation:\nbazel run //:docs_check"], srcs = ["@score_docs_as_code//src:incremental.py"], - data = data + [":sourcelinks_json"] + metamodel_data, + data = docs_data, deps = deps, - env = { - "SOURCE_DIRECTORY": source_dir, - "DATA": str(data), - "ACTION": "check", - "SCORE_SOURCELINKS": "$(location :sourcelinks_json)", - } | metamodel_env, + env = docs_env ) docs_env["ACTION"] = "live_preview" @@ -288,14 +269,9 @@ def docs(source_dir = "docs", data = [], deps = [], scan_code = [], known_good = name = "live_preview", tags = ["cli_help=Live preview documentation in the browser:\nbazel run //:live_preview"], srcs = ["@score_docs_as_code//src:incremental.py"], - data = data + [":sourcelinks_json"] + metamodel_data, + data = docs_data, deps = deps, - env = { - "SOURCE_DIRECTORY": source_dir, - "DATA": str(data), - "ACTION": "live_preview", - "SCORE_SOURCELINKS": "$(location :sourcelinks_json)", - } | metamodel_env, + env = docs_env ) docs_sources_env["ACTION"] = "live_preview" @@ -303,14 +279,9 @@ def docs(source_dir = "docs", data = [], deps = [], scan_code = [], known_good = name = "live_preview_combo_experimental", tags = ["cli_help=Live preview full documentation with all dependencies in the browser:\nbazel run //:live_preview_combo_experimental"], srcs = ["@score_docs_as_code//src:incremental.py"], - data = data_with_docs_sources + [":merged_sourcelinks"] + metamodel_data, + data = combo_data, deps = deps, - env = { - "SOURCE_DIRECTORY": source_dir, - "DATA": str(data_with_docs_sources), - "ACTION": "live_preview", - "SCORE_SOURCELINKS": "$(location :merged_sourcelinks)", - } | metamodel_env, + env = docs_sources_env ) py_venv( @@ -318,8 +289,7 @@ def docs(source_dir = "docs", data = [], deps = [], scan_code = [], known_good = tags = ["cli_help=Create virtual environment (.venv_docs) for documentation support:\nbazel run //:ide_support"], venv_name = ".venv_docs", deps = deps, - # Add dependencies to ide_support, so esbonio has access to them. - data = data + metamodel_data, + data = data, package_collisions = "warning", ) @@ -337,7 +307,7 @@ def docs(source_dir = "docs", data = [], deps = [], scan_code = [], known_good = ] + metamodel_opts, formats = ["needs"], sphinx = ":sphinx_build", - tools = data + metamodel_data, + tools = data, visibility = ["//visibility:public"], # Persistent workers cause stale symlinks after dependency version # changes, corrupting the Bazel cache. From 1ec83186e2f2501971db27c331519556b4459ba7 Mon Sep 17 00:00:00 2001 From: Andreas Zwinkau Date: Wed, 29 Apr 2026 12:53:45 +0200 Subject: [PATCH 3/4] test: Remove tests not worth the mocking efforts --- .../tests/test_metamodel__init__.py | 65 ------------------- 1 file changed, 65 deletions(-) diff --git a/src/extensions/score_metamodel/tests/test_metamodel__init__.py b/src/extensions/score_metamodel/tests/test_metamodel__init__.py index 2199fa4cd..f7d36eae0 100644 --- a/src/extensions/score_metamodel/tests/test_metamodel__init__.py +++ b/src/extensions/score_metamodel/tests/test_metamodel__init__.py @@ -10,10 +10,6 @@ # # SPDX-License-Identifier: Apache-2.0 # ******************************************************************************* -import sys -from pathlib import Path -from unittest.mock import MagicMock, patch - import pytest from attribute_plugin import add_test_properties # type: ignore[import-untyped] from sphinx.application import Sphinx @@ -25,15 +21,9 @@ graph_checks, local_checks, parse_checks_filter, - setup, ) from src.extensions.score_metamodel.tests import need -# The module where setup() looks up load_metamodel_data at runtime. -# Using __globals__ avoids breakage when the same file is imported under -# two different names (e.g. "score_metamodel" and "src.extensions.score_metamodel"). -_setup_module = sys.modules[setup.__module__] - def dummy_local_check(app: Sphinx, need: NeedItem, log: CheckLogger) -> None: pass @@ -186,58 +176,3 @@ def test_combined_core_links_and_extras(self): assert n.get("output", []) == ["output_wp"] # Extra fields assert n.get("custom_attr") == "custom_value" - - -# ============================================================================= -# Tests for setup() — score_metamodel_yaml config value wiring -# ============================================================================= - - -def _make_mock_app(metamodel_yaml_value: str = "") -> MagicMock: - """Return a minimal mock Sphinx app suitable for calling setup().""" - app = MagicMock() - app.config.score_metamodel_yaml = metamodel_yaml_value - app.config.needs_types = [] - app.config.needs_extra_links = [] - app.config.needs_extra_options = [] - return app - - -def _mock_metamodel_return(): - return MagicMock( - needs_types=[], - needs_extra_links=[], - needs_extra_options=[], - needs_graph_check={}, - prohibited_words_checks=[], - ) - - -def test_setup_uses_default_path_when_config_empty(): - """setup() calls load_metamodel_data(None) when score_metamodel_yaml is empty.""" - app = _make_mock_app(metamodel_yaml_value="") - - with patch.object( - _setup_module, - "load_metamodel_data", - return_value=_mock_metamodel_return(), - ) as mock_load: - setup(app) - - mock_load.assert_called_once_with(None) - - -def test_setup_passes_path_when_config_set(tmp_path): - """setup() calls load_metamodel_data(Path(...)) when score_metamodel_yaml is set.""" - yaml_file = tmp_path / "custom_metamodel.yaml" - yaml_file.write_text("needs_types: {}\n") - app = _make_mock_app(metamodel_yaml_value=str(yaml_file)) - - with patch.object( - _setup_module, - "load_metamodel_data", - return_value=_mock_metamodel_return(), - ) as mock_load: - setup(app) - - mock_load.assert_called_once_with(Path(str(yaml_file))) From 8981cf9b2be993a34c8697ae5b77261603211e06 Mon Sep 17 00:00:00 2001 From: Andreas Zwinkau Date: Thu, 30 Apr 2026 10:46:04 +0200 Subject: [PATCH 4/4] fix: review feedback --- docs.bzl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs.bzl b/docs.bzl index 5a4bd35ef..9a8f780e9 100644 --- a/docs.bzl +++ b/docs.bzl @@ -198,8 +198,8 @@ def docs(source_dir = "docs", data = [], deps = [], scan_code = [], known_good = data_with_docs_sources = _rewrite_needs_json_to_docs_sources(data) additional_combo_sourcelinks = _rewrite_needs_json_to_sourcelinks(data) _merge_sourcelinks(name = "merged_sourcelinks", sourcelinks = [":sourcelinks_json"] + additional_combo_sourcelinks, known_good = known_good) - docs_data = data + [":sourcelinks_json"] - combo_data = data_with_docs_sources + [":merged_sourcelinks"] + docs_data = data + metamodel_data + [":sourcelinks_json"] + combo_data = data_with_docs_sources + metamodel_data + [":merged_sourcelinks"] docs_env = { "SOURCE_DIRECTORY": source_dir, @@ -307,7 +307,7 @@ def docs(source_dir = "docs", data = [], deps = [], scan_code = [], known_good = ] + metamodel_opts, formats = ["needs"], sphinx = ":sphinx_build", - tools = data, + tools = data + metamodel_data, visibility = ["//visibility:public"], # Persistent workers cause stale symlinks after dependency version # changes, corrupting the Bazel cache.