From 39481ad142469d3ed16d283694c76091b271d523 Mon Sep 17 00:00:00 2001 From: Fabian Meumertzheim Date: Fri, 23 Aug 2024 12:53:48 -0700 Subject: [PATCH] Let repo rule attributes reference extension apparent names Fixes #19055 RELNOTES: Repository rules instantiated in the same module extensions can now refer to each other by their extension-specified names in label attributes. Closes #23369. PiperOrigin-RevId: 666893202 Change-Id: Ib2eaa55fcb563adc86e16dc4a357ac808228ebda --- site/en/external/extension.md | 8 + .../lib/bazel/bzlmod/AttributeValues.java | 23 +-- ...uleExtensionEvalStarlarkThreadContext.java | 184 ++++++++++++------ ...leExtensionRepoMappingEntriesFunction.java | 2 + .../lib/bazel/bzlmod/ModuleFileFunction.java | 7 +- .../build/lib/bazel/bzlmod/ModuleKey.java | 8 + .../bzlmod/SingleExtensionEvalFunction.java | 13 +- .../lib/bazel/bzlmod/StarlarkBazelModule.java | 4 +- .../lib/bazel/bzlmod/TypeCheckedTag.java | 8 +- .../starlark/StarlarkRepositoryFunction.java | 1 + .../starlark/StarlarkRepositoryModule.java | 2 +- .../repository/ResolvedFileFunction.java | 3 +- .../BuildTopLevelAspectsDetailsFunction.java | 4 +- .../net/starlark/java/eval/EvalException.java | 26 ++- .../bzlmod/ModuleExtensionResolutionTest.java | 155 +++++++++++++-- .../lib/bazel/bzlmod/TypeCheckedTagTest.java | 26 ++- 16 files changed, 355 insertions(+), 119 deletions(-) diff --git a/site/en/external/extension.md b/site/en/external/extension.md index e0374f8b4bd175..5ba774961105ba 100644 --- a/site/en/external/extension.md +++ b/site/en/external/extension.md @@ -165,6 +165,14 @@ several repo visibility rules: the apparent name `foo`, and the extension generates a repo with the specified name `foo`, then for all repos generated by that extension `foo` refers to the former. +* Similarly, in a module extension's implementation function, repos created + by the extension can refer to each other by their apparent names in + attributes, regardless of the order in which they are created. + * In case of a conflict with a repository visible to the module, labels + passed to repository rule attributes can be wrapped in a call to + [`Label`](/rules/lib/toplevel/attr#label) to ensure that they refer to + the repo visible to the module instead of the extension-generated repo + of the same name. ## Best practices diff --git a/src/main/java/com/google/devtools/build/lib/bazel/bzlmod/AttributeValues.java b/src/main/java/com/google/devtools/build/lib/bazel/bzlmod/AttributeValues.java index 3cdbce47252caf..7c241e087896ca 100644 --- a/src/main/java/com/google/devtools/build/lib/bazel/bzlmod/AttributeValues.java +++ b/src/main/java/com/google/devtools/build/lib/bazel/bzlmod/AttributeValues.java @@ -45,14 +45,15 @@ public static AttributeValues create(Map attribs) { public abstract Dict attributes(); - public static void validateAttrs(AttributeValues attributes, String what) throws EvalException { + public static void validateAttrs(AttributeValues attributes, String where, String what) + throws EvalException { for (var entry : attributes.attributes().entrySet()) { - validateSingleAttr(entry.getKey(), entry.getValue(), what); + validateSingleAttr(entry.getKey(), entry.getValue(), where, what); } } - public static void validateSingleAttr(String attrName, Object attrValue, String what) - throws EvalException { + public static void validateSingleAttr( + String attrName, Object attrValue, String where, String what) throws EvalException { var maybeNonVisibleLabel = getFirstNonVisibleLabel(attrValue); if (maybeNonVisibleLabel.isEmpty()) { return; @@ -60,17 +61,9 @@ public static void validateSingleAttr(String attrName, Object attrValue, String Label label = maybeNonVisibleLabel.get(); String repoName = label.getRepository().getName(); throw Starlark.errorf( - "no repository visible as '@%s' to the %s, but referenced by label '@%s//%s:%s' in" - + " attribute '%s' of %s. Is the %s missing a bazel_dep or use_repo(..., \"%s\")?", - repoName, - label.getRepository().getOwnerRepoDisplayString(), - repoName, - label.getPackageName(), - label.getName(), - attrName, - what, - label.getRepository().getOwnerModuleDisplayString(), - repoName); + "no repository visible as '@%s' %s, but referenced by label '@%s//%s:%s' in" + + " attribute '%s' of %s.", + repoName, where, repoName, label.getPackageName(), label.getName(), attrName, what); } private static Optional