From 1969278310726555b9870824c3fa21f2c67acfe8 Mon Sep 17 00:00:00 2001 From: Fabian Meumertzheim Date: Wed, 24 Apr 2024 23:26:33 +0200 Subject: [PATCH] Mark `modules.as_extension` as `reproducible` (#497) WORKSPACE macros are fully deterministic and thus a prime example of a `reproducible` module extension. This reduces clutter in `MODULE.bazel.lock`. --- docs/modules_doc.md | 6 ++++-- lib/modules.bzl | 23 ++++++++++++++++++++--- 2 files changed, 24 insertions(+), 5 deletions(-) diff --git a/docs/modules_doc.md b/docs/modules_doc.md index 1b8a049..96b200b 100755 --- a/docs/modules_doc.md +++ b/docs/modules_doc.md @@ -34,7 +34,8 @@ rules_foo_deps_ext = modules.as_extension(rules_foo_deps) A module extension that generates the repositories instantiated by the given macro and also uses [`use_all_repos`](#use_all_repos) to indicate that all of those repositories should be -imported via `use_repo`. +imported via `use_repo`. The extension is marked as reproducible if supported by the current +version of Bazel and thus doesn't result in a lockfile entry. @@ -42,7 +43,7 @@ imported via `use_repo`. ## modules.use_all_repos
-modules.use_all_repos(module_ctx)
+modules.use_all_repos(module_ctx, reproducible)
 
Return from a module extension that should have all its repositories imported via `use_repo`. @@ -64,6 +65,7 @@ ext = module_extension(_ext_impl) | Name | Description | Default Value | | :------------- | :------------- | :------------- | | module_ctx | The [module_ctx](https://bazel.build/rules/lib/builtins/module_ctx) object passed to the module extension's implementation function. | none | +| reproducible | The value of the reproducible parameter to pass to the [extension_metadata](https://bazel.build/rules/lib/builtins/extension_metadata.html) object returned by this function. This is safe to set with Bazel versions that don't support this parameter and will be ignored in that case. | False | **RETURNS** diff --git a/lib/modules.bzl b/lib/modules.bzl index 21f3a1b..e1ba56f 100644 --- a/lib/modules.bzl +++ b/lib/modules.bzl @@ -35,19 +35,23 @@ def _as_extension(macro, doc = None): Returns: A module extension that generates the repositories instantiated by the given macro and also uses [`use_all_repos`](#use_all_repos) to indicate that all of those repositories should be - imported via `use_repo`. + imported via `use_repo`. The extension is marked as reproducible if supported by the current + version of Bazel and thus doesn't result in a lockfile entry. """ def _ext_impl(module_ctx): macro() - return _use_all_repos(module_ctx) + + # Setting `reproducible` is safe since `macro`, as a function without parameters, must be + # deterministic. + return _use_all_repos(module_ctx, reproducible = True) return module_extension( implementation = _ext_impl, doc = doc, ) -def _use_all_repos(module_ctx): +def _use_all_repos(module_ctx, reproducible = False): """Return from a module extension that should have all its repositories imported via `use_repo`. Example: @@ -63,6 +67,10 @@ def _use_all_repos(module_ctx): Args: module_ctx: The [`module_ctx`](https://bazel.build/rules/lib/builtins/module_ctx) object passed to the module extension's implementation function. + reproducible: The value of the `reproducible` parameter to pass to the + [`extension_metadata`](https://bazel.build/rules/lib/builtins/extension_metadata.html) + object returned by this function. This is safe to set with Bazel versions that don't + support this parameter and will be ignored in that case. Returns: An [`extension_metadata`](https://bazel.build/rules/lib/builtins/extension_metadata.html) @@ -88,9 +96,18 @@ def _use_all_repos(module_ctx): if root_module_has_non_dev_dependency == None: return None + # module_ctx.extension_metadata has the paramater `reproducible` as of Bazel 7.1.0. We can't + # test for it directly and would ideally use bazel_features to check for it, but adding a + # dependency on it would require complicating the WORKSPACE setup for skylib. Thus, test for + # it by checking the availability of another feature introduced in 7.1.0. + extension_metadata_kwargs = {} + if hasattr(module_ctx, "watch"): + extension_metadata_kwargs["reproducible"] = reproducible + return extension_metadata( root_module_direct_deps = "all" if root_module_has_non_dev_dependency else [], root_module_direct_dev_deps = [] if root_module_has_non_dev_dependency else "all", + **extension_metadata_kwargs ) modules = struct(