An open API service indexing awesome lists of open source software.

https://github.com/aherrmann/repro-bzlmod-module-extension-cycle


https://github.com/aherrmann/repro-bzlmod-module-extension-cycle

Last synced: 3 months ago
JSON representation

Awesome Lists containing this project

README

          

# Undetected cyclic dependency between module extensions

This repository illustrates an issue where Bazel does not detect a cyclic
dependency between imported module extensions and instead silently disregards
tags on the affected extension.

## Expected behavior

You can observe the expected behavior with the following command:

```
$ (cd module_b; bazel fetch @extension_2//:defs.bzl)
DEBUG: .../module_a~override/extension_1.bzl:7:18: MODULE module_b TAG module_b_tag_1
DEBUG: .../module_a~override/extension_1.bzl:7:18: MODULE module_b TAG module_b_tag_2
DEBUG: .../module_a~override/extension_1.bzl:7:18: MODULE module_a TAG module_a_tag_1
DEBUG: .../module_a~override/extension_1.bzl:7:18: MODULE module_a TAG module_a_tag_2
DEBUG: .../module_a~override/extension_2.bzl:5:10: extension_2 found hello from extension_1, 4 tags
```

Note that 4 tags of `extension_1` are reported.

## Faulty behavior

You can observe the faulty behavior by changing the extension imports in
`module_b` as follows:

```diff
diff --git a/module_b/MODULE.bazel b/module_b/MODULE.bazel
index 16a8f90..8f57311 100644
--- a/module_b/MODULE.bazel
+++ b/module_b/MODULE.bazel
@@ -3,15 +3,15 @@ module(name = "module_b")
bazel_dep(name = "module_a")
local_path_override(module_name = "module_a", path = "../module_a")

-# extension_1 = use_extension("@module_a//:extensions.bzl", "extension_1")
-# extension_2 = use_extension("@module_a//:extensions.bzl", "extension_2")
+extension_1 = use_extension("@module_a//:extensions.bzl", "extension_1")
+extension_2 = use_extension("@module_a//:extensions.bzl", "extension_2")
# $ (cd module_b; bazel fetch @extension_2//:defs.bzl)
# DEBUG: .../module_a~override/extension_1.bzl:7:18: MODULE module_a TAG module_a_tag_1
# DEBUG: .../module_a~override/extension_1.bzl:7:18: MODULE module_a TAG module_a_tag_2
# DEBUG: .../module_a~override/extension_2.bzl:5:10: extension_2 found hello from extension_1, 2 tags

-extension_1 = use_extension("@module_a//:extension_1.bzl", "extension_1")
-extension_2 = use_extension("@module_a//:extension_2.bzl", "extension_2")
+# extension_1 = use_extension("@module_a//:extension_1.bzl", "extension_1")
+# extension_2 = use_extension("@module_a//:extension_2.bzl", "extension_2")
# $ (cd module_b; bazel fetch @extension_2//:defs.bzl)
# DEBUG: .../module_a~override/extension_1.bzl:7:18: MODULE module_b TAG module_b_tag_1
# DEBUG: .../module_a~override/extension_1.bzl:7:18: MODULE module_b TAG module_b_tag_2
```

And then executing the following command:

```
$ (cd module_b; bazel fetch @extension_2//:defs.bzl)
DEBUG: .../module_a~override/extension_1.bzl:7:18: MODULE module_a TAG module_a_tag_1
DEBUG: .../module_a~override/extension_1.bzl:7:18: MODULE module_a TAG module_a_tag_2
DEBUG: .../module_a~override/extension_2.bzl:5:10: extension_2 found hello from extension_1, 2 tags
```

Note that no only 2 tags of `extension_1` are reported. The tags defined in
`module_b` are lost.

## For reference

Bazel does detect the cyclic dependency from the context of `module_a` which
defines the module extensions `extension_1` and `extension_2`.

First modify the imports in `module_a` as follows:

```diff
diff --git a/module_a/MODULE.bazel b/module_a/MODULE.bazel
index 5ff4cb7..11259b0 100644
--- a/module_a/MODULE.bazel
+++ b/module_a/MODULE.bazel
@@ -1,6 +1,6 @@
module(name = "module_a")

-# extension_1 = use_extension("//:extensions.bzl", "extension_1")
+extension_1 = use_extension("//:extensions.bzl", "extension_1")
# ```
# $ (cd module_a; bazel fetch @extension_1//:defs.bzl)
# ERROR: Circular definition of repositories generated by module extensions and/or .bzl files:
@@ -13,7 +13,7 @@ module(name = "module_a")
# ERROR: cycles detected during target parsing
# ```

-extension_1 = use_extension("//:extension_1.bzl", "extension_1")
+# extension_1 = use_extension("//:extension_1.bzl", "extension_1")

extension_1.tag(name = "module_a_tag_1")
extension_1.tag(name = "module_a_tag_2")
```

Then execute the following command to trigger the error:

```
$ (cd module_a; bazel fetch @extension_1//:defs.bzl)
ERROR: Circular definition of repositories generated by module extensions and/or .bzl files:
.-> @_main~extension_1~extension_1
| extension 'extension_1' defined in //:extensions.bzl
| //:extensions.bzl
| //:extension_2.bzl
| @_main~extension_1~extension_1//:defs.bzl
`-- @_main~extension_1~extension_1
ERROR: cycles detected during target parsing
```