Skip to content

Add Bazel extension to expose transitive dependencies via setup.bzl #110

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 5 commits into
base: main
Choose a base branch
from
Draft
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
16 changes: 16 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,22 @@ Docs-as-code tooling for Eclipse S-CORE

The S-CORE docs Sphinx configuration and build code.

## Usage

### Using the module in your Bazel project

To use `score_docs_as_code` in your Bazel project, add the following to your `MODULE.bazel`:

```starlark
bazel_dep(name = "score_docs_as_code", version = "...")

# Use the setup extension to access transitive dependencies
use_extension("@score_docs_as_code//setup:setup.bzl", "setup")
use_repo(setup, "score_python_basics")
```

This pattern allows you to use the `docs()` macro and other utilities without manually declaring all transitive dependencies like `score_python_basics` in your own `MODULE.bazel`.

## Building documentation

#### Run a documentation build:
Expand Down
81 changes: 81 additions & 0 deletions VERIFICATION.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
# Verification Steps for Setup Extension

This document outlines how to verify that the setup extension works correctly.

## Manual Testing Steps

### 1. Create a test downstream project

Create a new directory with the following structure:

```
test-downstream-project/
├── MODULE.bazel
├── BUILD
└── test.py
```

### 2. Add MODULE.bazel content

```starlark
module(name = "test_downstream", version = "1.0.0")

bazel_dep(name = "score_docs_as_code", version = "0.4.0")

# Use the setup extension to access transitive dependencies
use_extension("@score_docs_as_code//setup:setup.bzl", "setup")
use_repo(setup, "score_python_basics")
```

### 3. Add BUILD content

```starlark
load("@score_python_basics//:defs.bzl", "score_py_pytest")

score_py_pytest(
name = "test",
srcs = ["test.py"],
)
```

### 4. Add test.py content

```python
def test_works():
assert True
```

### 5. Verify the build works

Run: `bazel test //:test`

If successful, this confirms that:
- The setup extension properly exposes score_python_basics
- Downstream projects don't need to manually declare score_python_basics
- The transitive dependency resolution works correctly

### 6. Verify documentation macro usage

Create a docs example in the test project:

```starlark
load("@score_docs_as_code//:docs.bzl", "docs")

docs(
conf_dir = "docs",
source_dir = "docs",
docs_targets = [{"suffix": ""}],
source_files_to_scan_for_needs_links = [],
)
```

Run: `bazel run //:ide_support`

This should work without any additional dependencies since score_python_basics is available via the extension.

## Expected Behavior

- ✅ Projects can use the docs() macro without manually declaring score_python_basics
- ✅ Projects can use score_py_pytest and other utilities from score_python_basics
- ✅ Projects can use score_virtualenv for IDE support
- ✅ The extension follows Bazel best practices for modular dependencies
Binary file added bazelisk
Binary file not shown.
19 changes: 19 additions & 0 deletions examples/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ These examples show how to use the 'docs' macro in order to build without outgoi
| `simple` | Build documentation without links to another sphinx documentations |
| `linking-latest` | Build documentation with links to another documentation via URL |
| `linking-release` | Build documentation with links to another documentation via MODULE import |
| `test-extension` | Example showing how to use the setup extension for transitive dependencies |

---
In order to enable linking against an imported Modules needs make sure you have imported it into the MODULE.bazel via
Expand Down Expand Up @@ -60,6 +61,24 @@ docs(

The `external_needs_info` is based on external needs, which can be explored more in detail [here](https://sphinx-needs.readthedocs.io/en/latest/configuration.html#needs-external-needs)

## Using the Setup Extension for Transitive Dependencies

The `score_docs_as_code` module provides a setup extension that allows downstream consumers to access transitive dependencies without explicitly declaring them. This follows Bazel best practices for modular, reusable modules.

In your downstream project's `MODULE.bazel`:

```starlark
module(name = "my_project", version = "1.0.0")

bazel_dep(name = "score_docs_as_code", version = "0.4.0")

# Use the setup extension to access transitive dependencies
use_extension("@score_docs_as_code//setup:setup.bzl", "setup")
use_repo(setup, "score_python_basics")
```

This makes `@score_python_basics` available in your BUILD files without needing to add `bazel_dep(name = "score_python_basics")` to your MODULE.bazel. You can then use utilities like `score_py_pytest` and `score_virtualenv` from the `score_python_basics` module.

---

The targets available in the examples are
Expand Down
27 changes: 27 additions & 0 deletions examples/test-extension/BUILD
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/**
* This example demonstrates how to use the setup extension to access
* transitive dependencies like score_python_basics.
*
* In a real downstream project, you would have a MODULE.bazel like this:
*
* ```starlark
* module(name = "my_project", version = "1.0.0")
*
* bazel_dep(name = "score_docs_as_code", version = "0.4.0")
*
* # Use the setup extension to access transitive dependencies
* use_extension("@score_docs_as_code//setup:setup.bzl", "setup")
* use_repo(setup, "score_python_basics")
* ```
*
* Then in your BUILD file, you can use score_python_basics utilities:
*/

load("@score_python_basics//:defs.bzl", "score_py_pytest")

# This demonstrates that score_python_basics is available
# without explicitly declaring it as a bazel_dep
score_py_pytest(
name = "test_extension_example",
srcs = ["test_extension.py"],
)
5 changes: 5 additions & 0 deletions examples/test-extension/test_extension.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
"""Test file to demonstrate the extension usage."""

def test_extension_works():
"""Simple test to verify the extension setup works."""
assert True, "Extension test passes"
15 changes: 15 additions & 0 deletions setup/BUILD
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# *******************************************************************************
# Copyright (c) 2025 Contributors to the Eclipse Foundation
#
# See the NOTICE file(s) distributed with this work for additional
# information regarding copyright ownership.
#
# This program and the accompanying materials are made available under the
# terms of the Apache License Version 2.0 which is available at
# https://www.apache.org/licenses/LICENSE-2.0
#
# SPDX-License-Identifier: Apache-2.0
# *******************************************************************************

# This package contains the setup extension for exposing transitive dependencies
exports_files(["setup.bzl"])
42 changes: 42 additions & 0 deletions setup/setup.bzl
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# *******************************************************************************
# Copyright (c) 2025 Contributors to the Eclipse Foundation
#
# See the NOTICE file(s) distributed with this work for additional
# information regarding copyright ownership.
#
# This program and the accompanying materials are made available under the
# terms of the Apache License Version 2.0 which is available at
# https://www.apache.org/licenses/LICENSE-2.0
#
# SPDX-License-Identifier: Apache-2.0
# *******************************************************************************

"""Bazel extension to expose transitive dependencies for score_docs_as_code."""

def _setup_impl(module_ctx):
"""Module extension implementation that exposes transitive dependencies.

This extension allows downstream modules to access transitive dependencies
like score_python_basics without explicitly declaring them in their MODULE.bazel.

The key insight is that this module already depends on score_python_basics,
so the dependency is available transitively. This extension just provides
a way for downstream consumers to access it via use_repo().

Usage in downstream MODULE.bazel:
use_extension("@score_docs_as_code//setup:setup.bzl", "setup")
use_repo(setup, "score_python_basics")

Note: This follows the standard Bazel module extension pattern. The
pattern suggested in the issue description with setup.setup_dependencies()
is not how Bazel module extensions work in practice.
"""
# The extension implementation doesn't need to create or modify repositories.
# It just needs to exist so that downstream consumers can use use_repo()
# to access the transitive dependencies that this module provides.
pass

# Define the module extension named "setup"
setup = module_extension(
implementation = _setup_impl,
)