blob: 21f3a1bf9d64b4d62fa92bd4185ac3a6423d33a7 [file] [log] [blame]
# Copyright 2023 The Bazel Authors. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Skylib module containing utilities for Bazel modules and module extensions."""
def _as_extension(macro, doc = None):
"""Wraps a WORKSPACE dependency macro into a module extension.
Example:
```starlark
def rules_foo_deps(optional_arg = True):
some_repo_rule(name = "foobar")
http_archive(name = "bazqux")
rules_foo_deps_ext = modules.as_extension(rules_foo_deps)
```
Args:
macro: A [WORKSPACE dependency macro](https://bazel.build/rules/deploying#dependencies), i.e.,
a function with no required parameters that instantiates one or more repository rules.
doc: A description of the module extension that can be extracted by documentation generating
tools.
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`.
"""
def _ext_impl(module_ctx):
macro()
return _use_all_repos(module_ctx)
return module_extension(
implementation = _ext_impl,
doc = doc,
)
def _use_all_repos(module_ctx):
"""Return from a module extension that should have all its repositories imported via `use_repo`.
Example:
```starlark
def _ext_impl(module_ctx):
some_repo_rule(name = "foobar")
http_archive(name = "bazqux")
return modules.use_all_repos(module_ctx)
ext = module_extension(_ext_impl)
```
Args:
module_ctx: The [`module_ctx`](https://bazel.build/rules/lib/builtins/module_ctx) object
passed to the module extension's implementation function.
Returns:
An [`extension_metadata`](https://bazel.build/rules/lib/builtins/extension_metadata.html)
object that, when returned from a module extension implementation function, specifies that all
repositories generated by this extension should be imported via `use_repo`. If the current
version of Bazel doesn't support `extension_metadata`, returns `None` instead, which can
safely be returned from a module extension implementation function in all versions of Bazel.
"""
# module_ctx.extension_metadata is available in Bazel 6.2.0 and later.
# If not available, returning None from a module extension is equivalent to not returning
# anything.
extension_metadata = getattr(module_ctx, "extension_metadata", None)
if not extension_metadata:
return None
# module_ctx.root_module_has_non_dev_dependency is available in Bazel 6.3.0 and later.
root_module_has_non_dev_dependency = getattr(
module_ctx,
"root_module_has_non_dev_dependency",
None,
)
if root_module_has_non_dev_dependency == None:
return None
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",
)
modules = struct(
as_extension = _as_extension,
use_all_repos = _use_all_repos,
)