Skip to content

feat: add local Needs exports to documentation bundles - #772

Merged
AlexanderLanin merged 2 commits into
eclipse-score:mainfrom
etas-contrib:pr/bundle-data-needs-sources
Sep 4, 2026
Merged

feat: add local Needs exports to documentation bundles#772
AlexanderLanin merged 2 commits into
eclipse-score:mainfrom
etas-contrib:pr/bundle-data-needs-sources

Conversation

@AlexanderLanin

@AlexanderLanin AlexanderLanin commented Aug 28, 2026

Copy link
Copy Markdown
Member

Why this matters

Source-bearing documentation bundles currently contribute content to composed documentation builds but do not expose a standalone Needs inventory for their own sources. That prevents each bundle from being validated or consumed independently and makes source ownership unclear at bundle boundaries.

This PR adds the local-export layer while preserving the project-wide needs_json target. Local exports intentionally remain self-contained: references to Needs owned outside the bundle are unresolved until cross-bundle propagation is added.

What changed

  • Generate <name>.__internal__.needs_local for every source-bearing docs_bundle and for the root bundle.
  • Build each local export from the bundle's direct documentation sources only, excluding nested bundle sources.
  • Reuse a bundle's checked-in conf.py for its local export, or generate a
    self-contained configuration when the bundle has no configuration.
  • Allow bundle-local Sphinx builds to receive the bundle's Python dependencies.
  • Centralize Needs-specific Sphinx options, per-setting define parameters, and private sphinx_build_binary creation in _needs_sphinx_docs.
  • Preserve source-link inputs and the existing project-wide needs_json behavior.
  • Keep project_url validation for normal host builds while leaving reusable local export metadata host-independent.
  • Model all low-level reference-integration components as explicit public docs_bundles and remove the redundant standalone_bundle fixture.
  • Add documentation and integration coverage for standalone and composed bundle Needs exports.

@github-actions

github-actions Bot commented Aug 28, 2026

Copy link
Copy Markdown
Contributor

License Check Results

🚀 The license check job ran with the Bazel command:

bazel run --lockfile_mode=error //src:license-check

Status: ⚠️ Needs Review

Click to expand output
[License Check Output]
Extracting Bazel installation...
Starting local Bazel server (8.6.0) and connecting to it...
INFO: Invocation ID: 8afcb2ee-913d-4584-abc8-9ae1d7d3d015
Computing main repo mapping: 
Loading: 
Loading: 0 packages loaded
Loading: 0 packages loaded
WARNING: Target pattern parsing failed.
ERROR: Skipping '//src:license-check': no such target '//src:license-check': target 'license-check' not declared in package 'src' defined by /home/runner/work/docs-as-code/docs-as-code/src/BUILD
ERROR: no such target '//src:license-check': target 'license-check' not declared in package 'src' defined by /home/runner/work/docs-as-code/docs-as-code/src/BUILD
INFO: Elapsed time: 6.987s
INFO: 0 processes.
ERROR: Build did NOT complete successfully
ERROR: Build failed. Not running target

@github-actions

Copy link
Copy Markdown
Contributor

Documentation preview for this pull request is available at:
pr-772: https://eclipse-score.github.io/docs-as-code/pr-772/

Comment thread docs.bzl Outdated

@MaximilianSoerenPollak MaximilianSoerenPollak left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

It seems alright to me.

I think it's hard to judge some edgecases and see if this covers all of the useages we might need.
Easiest to slowly test it in the modules that need it and see what is missing / not quiet right.
Great starting point though. 💯

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Adds reusable local and upward Needs exports for source-bearing documentation bundles.

Changes:

  • Adds upward_bundles hierarchy support and generated Needs targets.
  • Extends external Needs resolution for bundle exports.
  • Adds documentation and integration/unit coverage.

Reviewed changes

Copilot reviewed 12 out of 12 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
docs.bzl Generates local and upward Needs exports.
bzl/bundle_rules.bzl Propagates hierarchy metadata.
default_conf.py.tpl Supports bundle entry documents.
docs/reference/bazel_macros.rst Documents the new API and flow.
src/extensions/score_metamodel/external_needs.py Resolves upward exports from runfiles.
src/extensions/score_metamodel/tests/test_external_needs.py Tests bundle export resolution.
src/tests/docs_bzl/test_upward_bundles.py Tests bundle export behavior.
src/tests/docs_bzl/README.md Registers the new scenario.
src/tests/docs_bzl/scenarios/upward_bundles/BUILD Defines the hierarchy fixture.
src/tests/docs_bzl/scenarios/upward_bundles/platform/index.rst Provides ancestor Needs.
src/tests/docs_bzl/scenarios/upward_bundles/component/index.rst Provides dependent Needs.
src/tests/docs_bzl/scenarios/data_files_runfiles/BUILD Documents data-only behavior.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread docs.bzl Outdated
Comment thread docs.bzl Outdated
Comment thread src/extensions/score_metamodel/external_needs.py Outdated
Comment thread src/tests/docs_bzl/test_upward_bundles.py Outdated
Comment thread src/extensions/score_metamodel/external_needs.py Outdated
Comment thread src/tests/docs_bzl/scenarios/data_files_runfiles/BUILD Outdated

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 15 out of 15 changed files in this pull request and generated 3 comments.

Comment thread src/extensions/score_metamodel/external_needs.py Outdated
Comment thread docs.bzl Outdated
Comment thread docs.bzl Outdated
# Label() directly would resolve them relative to the repository containing
# this .bzl file, which is wrong when the macro is loaded by another module.
bundle_string = str(native.package_relative_label(bundle))
return Label(bundle_string + ".__internal__.needs_local")

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

I am intentionally not applying the suggested change. upward_bundles is defined as an explicit direct-dependency list; resolving needs_upward here would import the ancestor chain implicitly and violate the no-transitive-dependencies contract. Source-less hierarchy groups are now rejected explicitly with an analysis-time error (1d33c85), and consumers must list the source-bearing ancestors they need directly. Leaving this thread open because the proposed behavior conflicts with that contract.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 15 out of 15 changed files in this pull request and generated 2 comments.

Comment thread bzl/bundle_rules.bzl Outdated
Comment thread docs.bzl Outdated
@AlexanderLanin
AlexanderLanin force-pushed the pr/bundle-data-needs-sources branch from 2aa2764 to 93ebfb9 Compare September 2, 2026 22:57
@AlexanderLanin AlexanderLanin changed the title Add source bundle upward Needs exports Add upward Needs exports for source-bearing bundles Sep 2, 2026
@AlexanderLanin
AlexanderLanin marked this pull request as draft September 2, 2026 22:57
@AlexanderLanin
AlexanderLanin force-pushed the pr/bundle-data-needs-sources branch from 93ebfb9 to 2dbb70b Compare September 2, 2026 23:24
@AlexanderLanin AlexanderLanin changed the title Add upward Needs exports for source-bearing bundles Add local Needs exports for documentation bundles Sep 2, 2026
@AlexanderLanin
AlexanderLanin force-pushed the pr/bundle-data-needs-sources branch 2 times, most recently from 8a8ab62 to 6205415 Compare September 3, 2026 05:59
@AlexanderLanin AlexanderLanin changed the title Add local Needs exports for documentation bundles [PR3] Add local Needs exports for documentation bundles Sep 3, 2026
@AlexanderLanin
AlexanderLanin force-pushed the pr/bundle-data-needs-sources branch 2 times, most recently from 0fe3bed to eee8166 Compare September 3, 2026 08:28
@AlexanderLanin
AlexanderLanin force-pushed the pr/bundle-data-needs-sources branch 10 times, most recently from 3ded8d7 to 8d00c04 Compare September 4, 2026 11:01
@AlexanderLanin AlexanderLanin changed the title [PR3] Add local Needs exports for documentation bundles [PR3] Add local Needs exports and centralize Sphinx setup Sep 4, 2026
@AlexanderLanin AlexanderLanin changed the title [PR3] Add local Needs exports and centralize Sphinx setup feat: add local_needs to docs_bundle Sep 4, 2026
@AlexanderLanin
AlexanderLanin requested a balanced review from Copilot September 4, 2026 13:07

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟡 Changes recommended

Local exports break checked-in configurations and explicit-source layouts, while project URL validation regresses globally.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Review details
  • Files reviewed: 14/14 changed files
  • Comments generated: 5
  • Review effort level: Balanced

Comment thread docs.bzl Outdated
Comment on lines +347 to +350
if config == None:
# Sphinx expects conf.py below the source root. Bundle-local Needs
# exports always use a generated config so the bundle stays
# self-contained and does not depend on a caller-provided conf.py.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Valid. Local exports now reuse a checked-in conf.py when present and generate a unique fallback config otherwise. The bundle deps are also passed to the private Sphinx binary so custom configuration extensions remain available.

Comment thread docs.bzl Outdated
else:
needs_config = config

source_strip_prefix = _bundle_sphinx_strip_prefix(source_dir)

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Valid. Explicit source bundles now expose a Sphinx library whose strip prefix is derived from the actual source paths, including generated outputs. This stages the bundle entry document at the local Sphinx root.

Comment thread docs.bzl Outdated
Comment on lines +384 to +388
score_sourcelinks_json = "$(location " + str(sourcelinks_json) + ")" if sourcelinks_json else None,
# ``sphinxdocs`` removes this string literally from short_path.
# Keep the separator so a source_dir/conf.py is relocated as
# conf.py rather than /conf.py.
strip_prefix = source_strip_prefix,

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Valid. Added a successful build of the legacy component needs_local target and asserted its exported source_code_link, covering the local source-link path.

@@ -141,12 +141,6 @@ def extend_needs_json_exporter(config: Config, params: list[str]) -> None:
# This is wrong. But good enough.
config.add(p, default="", rebuild="env", types=(), description="")

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Valid. The earlier change had removed normal project_url validation. Bundle-export mode is now an explicit config value: only local exports suppress the missing-value diagnostic and serialize an empty reusable-export URL; host builds retain the validation.

Comment on lines +278 to +287
def test_build_combined_file_without_source_links_uses_empty_input(
tmp_path: Path, monkeypatch: pytest.MonkeyPatch
):
"""Standalone builds may legitimately have no source-link input."""
monkeypatch.delenv("SCORE_SOURCELINKS", raising=False)

build_and_save_combined_file(tmp_path)

combined_file = tmp_path / "score_scl_grouped_cache.json"
assert json.loads(combined_file.read_text(encoding="utf-8")) == []

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Valid. Removed the duplicate no-source-links test and kept the existing test as the single authoritative coverage for that behavior.

@AlexanderLanin
AlexanderLanin force-pushed the pr/bundle-data-needs-sources branch from 880f54d to 30eca23 Compare September 4, 2026 13:16
@AlexanderLanin AlexanderLanin changed the title feat: add local_needs to docs_bundle feat: add local Needs exports to documentation bundles Sep 4, 2026

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟡 Changes recommended

Local exports omit bundle data, can include nested same-package sources, and mishandle explicit-source configurations.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Review details
  • Files reviewed: 15/15 changed files
  • Comments generated: 3
  • Review effort level: Balanced

Comment thread docs.bzl
Comment on lines +343 to +350
# ``bundle_sphinx_source_files`` is important here: using the complete bundle
# would also feed nested child sources into this Sphinx invocation and
# export their Needs under the parent's local target. Ownership stays
# one-way: every source-bearing bundle exports only its own sources.
own_sources = bundle_sphinx_source_files(
name = _bundle_internal_target(name, "needs_sources"),
bundle = ":" + name,
visibility = visibility,

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

will be covered by future PRs

Comment thread docs.bzl Outdated
Comment thread docs.bzl
needs_local = _bundle_internal_target(name, "needs_local")
_needs_sphinx_docs(
name = needs_local,
deps = [own_sources],

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

will be covered by future PRs

@MaximilianSoerenPollak MaximilianSoerenPollak left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Talked about in a call.

It's a temp solution that is okay and will be worked on further.

@AlexanderLanin
AlexanderLanin marked this pull request as ready for review September 4, 2026 15:58
@AlexanderLanin
AlexanderLanin merged commit 1084124 into eclipse-score:main Sep 4, 2026
18 of 20 checks passed
@AlexanderLanin
AlexanderLanin deleted the pr/bundle-data-needs-sources branch September 4, 2026 15:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Development

Successfully merging this pull request may close these issues.

3 participants