Bazel macro: docs#
The docs macro defined in docs.bzl is a convenience wrapper
that creates a small set of Bazel targets
to build, verify and preview the project’s Sphinx documentation,
and to create a Python virtual environment for IDE support (Esbonio).
See commands for the targets/commands it creates.
The macro must be called from the repository root package.
Minimal example (root BUILD)#
load("//:docs.bzl", "docs")
docs(
source_dir = "docs",
project = "My Project",
project_url = "https://github.com/eclipse-score/my-project",
data = [
# labels to any extra tools or data you want included
# e.g. "//:needs_json" or other tool targets
],
bundles = [
# dicts describing bundles to mount into this project
# e.g. {"bundle": "@score_process//:docs_bundle", "mount_at": "process"}
],
deps = [
# additional bazel labels providing Python deps or other runfiles
],
)
source_dir(string, default:"docs") Path (relative to repository root) to your Sphinx source directory. This is the folder that contains the top-level ReST/markdown sources. Aconf.pyis optional.projectandproject_url(strings, optional) Project name and canonical project URL. They are required whensource_dirhas noconf.py; in that casedocs()generates the Sphinx configuration and supplies the Docs-as-Code baseline version and extensions. If aconf.pyexists, 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. The items indataare added to the py_binaries and to the Sphinx tooling so they are available at build time.Note
To pull in another module’s needs for cross-referencing, add its
:needs_jsontarget here.bundles(list of placement dicts) Documentation bundles to overlay into this project’s documentation tree, each with its placement (mount_at). See Mount docs bundles for the full reference.deps(list of bazel labels) Additional Bazel dependencies to add to the Python binaries and the virtual environment target. Use this to add project-specific Python modules.If you don’t provide the necessary Sphinx packages, this function adds its own (but checks for conflicts).
code_targets(list of Bazel labels) Implementation targets or filegroups to scan for traceability tags (req-Id:annotations). Implementation targetsrcs,hdrs, andtextual_hdrsare collected through theirdepsrecursively; filegroups expand to their files. Each documentation bundle produces one cache for its declared targets; Bazel reuses that cache while its inputs are unchanged. The generated JSON is supplied tolive_previewjust like a normal documentation build.scan_code(list of Bazel labels, deprecated) Explicit source files or filegroups to scan. Usecode_targetsfor implementation targets; it follows their dependencies automatically.external_needs(list of bazel labels) External:needs_json_filetargets from other modules/repositories for referencing their needs. Do not use:needs_jsontargets.metamodel(bazel label, optional) Path to a custommetamodel.yamlfile. When set, thescore_metamodelextension loads this file instead of the default metamodel. The label is automatically added to thedataandtoolsof every generated target so the file is available in the Bazel sandbox at build time.Example:
docs( source_dir = "docs", metamodel = "//:my_metamodel.yaml", )
The custom
metamodel.yamlmust follow the same schema as the default one (see score_metamodel). You may use@score_docs_as_code//src/extensions/score_metamodel:metamodel_yamlfor extension processing. Whenmetamodelis omitted the default metamodel is used unchanged.
Bazel macro: docs_bundle#
docs_bundle (also from docs.bzl) declares a mountable documentation
bundle: a chunk of RST/Markdown content that can be overlaid into a host
documentation project. A bundle carries only content — it has no placement of its
own. Where it appears is decided by whoever mounts it (a composing
docs_bundle or the docs(bundles=[…]) call
site).
load("//:docs.bzl", "docs_bundle")
docs_bundle(
name = "docs_dir",
source_dir = "docs",
entry_doc = "index",
metamodel = "//:my_metamodel.yaml",
bundles = [],
upward_bundles = [],
visibility = ["//visibility:public"],
)
Signature: docs_bundle(name, source_dir = None, entry_doc = "index", metamodel = None, bundles = [], upward_bundles = [], scan_code = [], code_targets = [], deps = [], visibility = None).
source_dir(string, optional) Directory holding the bundle’s own doc sources. It is globbed the same way asdocs()(RST, Markdown, images, and the other doc file kinds). Thesource_diritself is the mount root, so the files mount relative to it (soconcept/index.rstwithsource_dir = "concept"becomesindex.rst). The bundle exposes those files as a Bazel depset (via theDocsBundleInfoprovider) and records thesource_dirpath; sphinx-mounts walks that original directory directly — no copy is made. Leave it unset for a pure aggregator that only composesbundles.entry_doc(string, optional) Bundle-relative docname used as the canonical navigation entry. It defaults toindex. Every mount attaches this entry to the parentindextoctree by default; a placement’sattach_tomay override that host document.metamodel(Bazel label, optional) Metamodel used when processing Needs owned by this bundle. If omitted, the built-in SCORE metamodel is selected. The metamodel belongs to the bundle and is an input to the bundle-local Needs export.bundles(list of composition dicts, optional) Nested bundles to compose into this one, so a bundle can aggregate other bundles transitively. Each entry is a dict:bundle— label of anotherdocs_bundletarget.mount_at— the docname prefix at which the child bundle appears inside this bundle.attach_to(optional) — a docname (relative to this bundle) whose toctree receives the child’s bundle-defined entry document. When omitted, the parentindexdocument receives it.
A child’s
mount_at/attach_toprefix-stack with the placement this bundle later receives, so composition is fully transitive. The same underlying bundle resolving to two different finalmount_atvalues is a hard build error. See Mount docs bundles for a worked example and Documentation bundles and mounts for the composition and transitivity semantics.upward_bundles(list of labels, optional)Explicit documentation-hierarchy dependencies above this bundle. A source bundle may declare one or more ancestor bundles; both the direct declarations and their transitive closure are propagated through
DocsBundleInfofor the per-bundle Needs export. A source-less aggregator may also declare them to provide a named hierarchy group for consumers. Dependencies are declared explicitly and are not inferred from Need links.If
source_dircontains documentation sources, the macro creates<name>_needs_localfor the bundle’s own Needs and<name>_needs_upwardfor an importable JSON export. The latter merges the bundle’s own Needs with the exports of its directupward_bundles; those exports already contain their own ancestors. The public file target therefore exposes the complete declared upward interface without assigning ownership of ancestor Needs to the child.
The top-level docs() macro also accepts upward_bundles. Those labels are
attached to the generated :docs_source_bundle target, so the module’s own
Needs can refer to an ancestor bundle while mounted descendants continue to use
the module source bundle as their upward parent. The older
:_docs_source_bundle label remains available for compatibility, but new
consumers should use the stable :docs_source_bundle name.
Note
A bundle is placement-free: its mount_at and attach_to are assigned
by the mounter, while its entry_doc belongs to the bundle. This lets the
same bundle be mounted at different locations by different consumers without
changing its canonical entry page.
code_targets(list of Bazel labels, optional)Implementation targets or filegroups to scan for requirement tags. Implementation target
srcs,hdrs, andtextual_hdrsare collected recursively from theirdeps; filegroups expand to their files. The bundle owns one cached scan result; Bazel only regenerates it when its collected source inputs change.
deps(list of Bazel labels, optional)Additional Python dependencies used by the bundle-local Sphinx/Needs action.
scan_code(list of Bazel labels, deprecated)Explicit source files or filegroups to scan. Prefer
code_targetsfor implementation targets.
Edge cases#
If your Sphinx
conf.pyexpects files generated by other Bazel targets, make sure those targets are included in thedatalist so they are available to the build driver.