diff --git a/src/main/java/com/google/devtools/build/lib/actions/AbstractAction.java b/src/main/java/com/google/devtools/build/lib/actions/AbstractAction.java index 2bf6773d73d219..8bfcbf46e41a22 100644 --- a/src/main/java/com/google/devtools/build/lib/actions/AbstractAction.java +++ b/src/main/java/com/google/devtools/build/lib/actions/AbstractAction.java @@ -368,13 +368,9 @@ private String getProgressMessageChecked(@Nullable RepositoryMapping mainReposit private String replaceProgressMessagePlaceholders( String progressMessage, @Nullable RepositoryMapping mainRepositoryMapping) { if (progressMessage.contains("%{label}") && owner.getLabel() != null) { - String labelString; - if (mainRepositoryMapping != null) { - labelString = owner.getLabel().getDisplayForm(mainRepositoryMapping); - } else { - labelString = owner.getLabel().toString(); - } - progressMessage = progressMessage.replace("%{label}", labelString); + progressMessage = + progressMessage.replace( + "%{label}", owner.getLabel().getDisplayForm(mainRepositoryMapping)); } if (progressMessage.contains("%{output}") && getPrimaryOutput() != null) { progressMessage = diff --git a/src/main/java/com/google/devtools/build/lib/cmdline/BazelModuleContext.java b/src/main/java/com/google/devtools/build/lib/cmdline/BazelModuleContext.java index 9bd7dd45b30ef7..d5671835122135 100644 --- a/src/main/java/com/google/devtools/build/lib/cmdline/BazelModuleContext.java +++ b/src/main/java/com/google/devtools/build/lib/cmdline/BazelModuleContext.java @@ -44,6 +44,13 @@ public abstract class BazelModuleContext { /** The repository mapping applicable to the repo where the .bzl file is located in. */ public abstract RepositoryMapping repoMapping(); + /** + * The repository mapping applicable to the main repository, possibly without WORKSPACE repos or + * null. This is purely meant to support {@link Label#getDisplayFormForStarlark(StarlarkThread)}. + */ + @Nullable + public abstract RepositoryMapping bestEffortMainRepoMapping(); + /** Returns the name of the module's .bzl file, as provided to the parser. */ public abstract String filename(); @@ -160,11 +167,12 @@ public static BazelModuleContext ofInnermostBzlOrFail(StarlarkThread thread, Str public static BazelModuleContext create( Label label, RepositoryMapping repoMapping, + @Nullable RepositoryMapping bestEffortMainRepoMapping, String filename, ImmutableList loads, byte[] bzlTransitiveDigest) { return new AutoValue_BazelModuleContext( - label, repoMapping, filename, loads, bzlTransitiveDigest); + label, repoMapping, bestEffortMainRepoMapping, filename, loads, bzlTransitiveDigest); } public final Label.PackageContext packageContext() { diff --git a/src/main/java/com/google/devtools/build/lib/cmdline/Label.java b/src/main/java/com/google/devtools/build/lib/cmdline/Label.java index bae138baf4b81f..632fb4cdd578c8 100644 --- a/src/main/java/com/google/devtools/build/lib/cmdline/Label.java +++ b/src/main/java/com/google/devtools/build/lib/cmdline/Label.java @@ -442,10 +442,29 @@ public String getUnambiguousCanonicalForm() { * @param mainRepositoryMapping the {@link RepositoryMapping} of the main repository * @return analogous to {@link PackageIdentifier#getDisplayForm(RepositoryMapping)} */ - public String getDisplayForm(RepositoryMapping mainRepositoryMapping) { + public String getDisplayForm(@Nullable RepositoryMapping mainRepositoryMapping) { return packageIdentifier.getDisplayForm(mainRepositoryMapping) + ":" + name; } + @StarlarkMethod( + name = "to_display_form", + useStarlarkThread = true, + doc = + "Returns a string representation of this label that is optimized for human readability." + + " Use this to format a Label for use in BUILD files." + + "

The exact form of the return value is explicitly unspecified and subject to" + + " change." + + " The following properties are guaranteed for a Label l:" + + "

") + public String getDisplayFormForStarlark(StarlarkThread starlarkThread) throws EvalException { + checkRepoVisibilityForStarlark("to_display_form"); + return getDisplayForm( + BazelModuleContext.ofInnermostBzlOrThrow(starlarkThread).bestEffortMainRepoMapping()); + } + /** * Returns a shorthand label string that is suitable for display, i.e. in addition to simplifying * the repository part, labels of the form {@code [@repo]//foo/bar:bar} are simplified to the diff --git a/src/main/java/com/google/devtools/build/lib/cmdline/PackageIdentifier.java b/src/main/java/com/google/devtools/build/lib/cmdline/PackageIdentifier.java index 4271d0d6706489..4d062ca753add0 100644 --- a/src/main/java/com/google/devtools/build/lib/cmdline/PackageIdentifier.java +++ b/src/main/java/com/google/devtools/build/lib/cmdline/PackageIdentifier.java @@ -24,6 +24,8 @@ import com.google.devtools.build.skyframe.SkyFunctionName; import com.google.devtools.build.skyframe.SkyKey; import com.google.devtools.build.skyframe.SkyKey.SkyKeyInterner; + +import javax.annotation.Nullable; import javax.annotation.concurrent.Immutable; /** @@ -226,7 +228,7 @@ public String getUnambiguousCanonicalForm() { *
only with Bzlmod if the current package belongs to a repository that is not visible * from the main module */ - public String getDisplayForm(RepositoryMapping mainRepositoryMapping) { + public String getDisplayForm(@Nullable RepositoryMapping mainRepositoryMapping) { return repository.getDisplayForm(mainRepositoryMapping) + "//" + pkgName; } diff --git a/src/main/java/com/google/devtools/build/lib/cmdline/RepositoryName.java b/src/main/java/com/google/devtools/build/lib/cmdline/RepositoryName.java index d0b064512dd98d..984ba4ece2ac75 100644 --- a/src/main/java/com/google/devtools/build/lib/cmdline/RepositoryName.java +++ b/src/main/java/com/google/devtools/build/lib/cmdline/RepositoryName.java @@ -247,13 +247,15 @@ public String getCanonicalForm() { *
@protobuf *
if this repository is a WORKSPACE dependency and its name is "protobuf", * or if this repository is a Bzlmod dependency of the main module and its apparent name - * is "protobuf" + * is "protobuf" (in both cases only if mainRepositoryMapping is not null) *
@@protobuf~3.19.2 *
only with Bzlmod, if this a repository that is not visible from the main module */ - public String getDisplayForm(RepositoryMapping mainRepositoryMapping) { + public String getDisplayForm(@Nullable RepositoryMapping mainRepositoryMapping) { Preconditions.checkArgument( - mainRepositoryMapping.ownerRepo() == null || mainRepositoryMapping.ownerRepo().isMain()); + mainRepositoryMapping == null + || mainRepositoryMapping.ownerRepo() == null + || mainRepositoryMapping.ownerRepo().isMain()); if (!isVisible()) { return getNameWithAt(); } @@ -261,6 +263,9 @@ public String getDisplayForm(RepositoryMapping mainRepositoryMapping) { // Packages in the main repository can always use repo-relative form. return ""; } + if (mainRepositoryMapping == null) { + return getNameWithAt(); + } if (!mainRepositoryMapping.usesStrictDeps()) { // If the main repository mapping is not using strict visibility, then Bzlmod is certainly // disabled, which means that canonical and apparent names can be used interchangeably from diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/BzlLoadFunction.java b/src/main/java/com/google/devtools/build/lib/skyframe/BzlLoadFunction.java index 9c57bac68f819c..a9d14caa7e9502 100644 --- a/src/main/java/com/google/devtools/build/lib/skyframe/BzlLoadFunction.java +++ b/src/main/java/com/google/devtools/build/lib/skyframe/BzlLoadFunction.java @@ -66,6 +66,7 @@ import java.util.LinkedHashSet; import java.util.List; import java.util.Map; +import java.util.Optional; import java.util.concurrent.atomic.AtomicBoolean; import java.util.function.Consumer; import javax.annotation.Nullable; @@ -762,6 +763,11 @@ private BzlLoadValue computeInternalWithCompiledBzl( if (repoMapping == null) { return null; } + Optional mainRepoMapping = + getMainRepositoryMapping(key, builtins.starlarkSemantics, env); + if (mainRepoMapping == null) { + return null; + } Label.RepoMappingRecorder repoMappingRecorder = new Label.RepoMappingRecorder(); ImmutableList> programLoads = getLoadsFromProgram(prog); ImmutableList