Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 33 additions & 1 deletion docs.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,37 @@ def _merge_sourcelinks(name, sourcelinks):
tools = ["@score_docs_as_code//scripts_bazel:merge_sourcelinks"],
)

def _missing_requirements(deps):
"""Add Python hub dependencies if they are missing."""
found = []
missing = []
def _target_to_packagename(target):
return target.split("/")[-1].split(":")[0]
all_packages = [_target_to_packagename(pkg) for pkg in all_requirements]
def _find(pkg):
for dep in deps:
dep_pkg = _target_to_packagename(dep)
if dep_pkg == pkg:
return True
return False
for pkg in all_packages:
if _find(pkg):
found.append(pkg)
else:
missing.append(pkg)
if len(missing) == len(all_requirements):
#print("All docs-as-code dependencies are missing, adding all of them.")
Copy link
Contributor

@MaximilianSoerenPollak MaximilianSoerenPollak Mar 2, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm guessing these debug prints can be removed, or do we want to keep them?

return all_requirements
if len(missing) == 0:
#print("All docs-as-code dependencies are already included, no need to add any.")
return []
if len(found) > 0:
msg = "Some docs-as-code dependencies are in deps: " + ", ".join(found) + \
"\n ... but others are missing: " + ", ".join(missing) + \
"\nInconsistent deps for docs(): either include all dependencies or none of them."
fail(msg)
fail("This case should be unreachable?!")

def docs(source_dir = "docs", data = [], deps = [], scan_code = []):
"""Creates all targets related to documentation.

Expand All @@ -107,7 +138,8 @@ def docs(source_dir = "docs", data = [], deps = [], scan_code = []):
fail("docs() must be called from the root package. Current package: " + call_path)

module_deps = deps
deps = deps + all_requirements + [
deps = deps + _missing_requirements(deps)
deps = deps + [
"@score_docs_as_code//src:plantuml_for_python",
"@score_docs_as_code//src/extensions/score_sphinx_bundle:score_sphinx_bundle",
]
Expand Down
51 changes: 51 additions & 0 deletions docs/how-to/add_extensions.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
Add Extensions
===================

The docs-as-code module defines its own Python environment in ``MODULE.bazel``
and as a user you cannot extend that.
If you want to add Sphinx extensions,
you must duplicate the Python environment first.

Once you have your own Python environment,
supply all necessary packages to ``docs`` via the ``deps`` attribute.

.. code-block:: starlark
:caption: In your BUILD file

load("@your_python_env//:requirements.bzl", "all_requirements")

docs(
# ...other attributes...
deps = all_requirements
)

Inside ``docs()``, the docs-as-code module will check if you have supplied all necessary dependencies.

How to Create a Python Environment?
-----------------------------------

The general documentation is `in the rules_python documentation <https://rules-python.readthedocs.io/en/latest/toolchains.html>`_.

You can also peek into `this docs-as-code repo's MODULE.bazel file <https://github.com/eclipse-score/docs-as-code/blob/main/MODULE.bazel>`_
how ``docs_as_code_hub_env`` is defined and use it as a template for ``your_python_env``.

Recommendation:
Use `compile_pip_requirements <https://rules-python.readthedocs.io/en/latest/api/rules_python/python/pip.html#compile_pip_requirements>`_
because it is a solid practice anyways.
Next, get ``@score_docs_as_code//src:requirements.in`` as one of the inputs
to ensure you have all the necessary dependencies for docs-as-code.

.. code-block:: starlark
:caption: Example BUILD file snippet

load("@rules_python//python:pip.bzl", "compile_pip_requirements")

compile_pip_requirements(
name = "requirements",
srcs = [
"@score_docs_as_code//src:requirements.in",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this be the txt or the in?
I'm unsure here

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the in is better so compile-pip can detect conflicts.

"requirements.in",
],
requirements_txt = "requirements_lock.txt",
visibility = ["//visibility:public"],
)
1 change: 1 addition & 0 deletions docs/how-to/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,4 @@ Here you find practical guides on how to use docs-as-code.
other_modules
source_to_doc_links
test_to_doc_links
add_extensions
6 changes: 4 additions & 2 deletions docs/reference/bazel_macros.rst
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,10 @@ Minimal example (root ``BUILD``)

- ``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 packages or extension libraries the docs
build requires.
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).

Edge cases
----------
Expand Down
1 change: 1 addition & 0 deletions src/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ load("@score_tooling//:defs.bzl", "dash_license_checker")
exports_files(
[
"requirements.txt",
"requirements.in",
"incremental.py",
"dummy.py",
"generate_sourcelinks_cli.py",
Expand Down
Loading