diff --git a/default_conf.py.tpl b/default_conf.py.tpl index 3c2426f27..d7455cbb2 100644 --- a/default_conf.py.tpl +++ b/default_conf.py.tpl @@ -18,4 +18,9 @@ project = {PROJECT} project_url = {PROJECT_URL} version = "0.0.0" +# Allow feature IDs that use the Bazel module name without its first +# underscore-separated prefix (for example, ``score_docs_as_code`` becomes +# ``docs_as_code``). A user-provided conf.py remains authoritative. +required_in_id = {REQUIRED_IN_ID} + extensions = ["score_sphinx_bundle"] diff --git a/docs.bzl b/docs.bzl index 6f902162e..eafe15481 100644 --- a/docs.bzl +++ b/docs.bzl @@ -61,6 +61,13 @@ load( "create_mounts_manifest", ) +def _module_name_without_prefix(): + """Return the current Bazel module name without its first prefix.""" + module_name = native.module_name() + if not module_name: + return "" + return module_name.split("_", 1)[-1] + def _generated_conf_impl(ctx): output = ctx.actions.declare_file(ctx.attr.output_path) ctx.actions.expand_template( @@ -69,6 +76,7 @@ def _generated_conf_impl(ctx): substitutions = { "{PROJECT}": repr(ctx.attr.project), "{PROJECT_URL}": repr(ctx.attr.project_url), + "{REQUIRED_IN_ID}": repr([ctx.attr.required_in_id]) if ctx.attr.required_in_id else "[]", }, ) return [DefaultInfo(files = depset([output]))] @@ -78,6 +86,7 @@ _generated_conf = rule( attrs = { "project": attr.string(mandatory = True), "project_url": attr.string(mandatory = True), + "required_in_id": attr.string(mandatory = True), "output_path": attr.string(mandatory = True), "template": attr.label( allow_single_file = True, @@ -238,6 +247,7 @@ def docs( name = "_docs_generated_config", project = project, project_url = project_url, + required_in_id = _module_name_without_prefix(), output_path = config_file_path, ) sphinx_config = ":_docs_generated_config" diff --git a/docs/reference/bazel_macros.rst b/docs/reference/bazel_macros.rst index adef0f43c..d3acbc6ac 100644 --- a/docs/reference/bazel_macros.rst +++ b/docs/reference/bazel_macros.rst @@ -56,8 +56,11 @@ Minimal example (root ``BUILD``) - ``project`` and ``project_url`` (strings, optional) Project name and canonical project URL. They are required when ``source_dir`` has no ``conf.py``; in that case ``docs()`` generates the Sphinx configuration - and supplies the Docs-as-Code baseline version and extensions. If a ``conf.py`` - exists, it remains authoritative and these values are not used. + and supplies the Docs-as-Code baseline version, extensions, and a + ``required_in_id`` entry derived from the Bazel module name. The first + underscore-separated prefix is removed (for example, + ``score_docs_as_code`` becomes ``docs_as_code``). If a ``conf.py`` exists, + it remains authoritative and these values are not used. - ``data`` (list of bazel labels) Extra runfiles / data targets that should be made available to the documentation targets. diff --git a/src/tests/docs_bzl/test_basic_docs.py b/src/tests/docs_bzl/test_basic_docs.py index cffda3ba0..ff92ffb1e 100644 --- a/src/tests/docs_bzl/test_basic_docs.py +++ b/src/tests/docs_bzl/test_basic_docs.py @@ -13,7 +13,7 @@ """Public docs() smoke scenario.""" -from src.tests.docs_bzl.helpers import load_needs_json, run_scenario +from src.tests.docs_bzl.helpers import built_output, load_needs_json, run_scenario def test_basic_docs_builds_html(): @@ -33,3 +33,8 @@ def test_basic_docs_builds_needs_without_conf_py(): assert result.artifacts is not None, f"expected artifacts: {result}" data = load_needs_json(result.artifacts["needs.json"]) assert data["current_version"], "current_version must be non-empty" + + generated_conf = built_output("scenarios/basic_docs", "docs/conf.py") + assert 'required_in_id = ["docs_as_code"]' in generated_conf.read_text( + encoding="utf-8" + )