From bbeb87efbccfc70f19c2a9f37211b77dd95d42b6 Mon Sep 17 00:00:00 2001 From: Xdng Yng Date: Thu, 4 Jan 2024 15:27:19 -0800 Subject: [PATCH] Let module extensions track calls to `Label()` ... that use repo mapping. This is a rather obscure case of the lockfile being stale; if the `Label()` constructor is called in an extension impl function, and that call uses repo mapping of any form (i.e. the argument looks like `@foo//bar`), then we need to be ready to rerun the extension if `@foo` were to suddenly map to something else. I also did a minor refactoring in `SingleExtensionEvalFunction` around the logic to decide whether the locked extension is up-to-date. Right now we perform a "diff" between the locked extension and what we expect to be up-to-date, and if a "diff" is found *and* `--lockfile_mode=error`, we basically perform a diff again. We also don't short circuit; that is, if the transitive bzl digest has changed, there's no point in seeing whether any files have changed, but we do right now. A follow-up will be sent to fix the analogous bug for repo rules. Fixes #20721. Closes #20742. PiperOrigin-RevId: 595818144 Change-Id: Id660b7a659a7f2e4dde19c16784c2ab18a9ceb69 --- .../starlark/StarlarkRuleClassFunctions.java | 5 +- .../devtools/build/lib/bazel/bzlmod/BUILD | 1 + .../lib/bazel/bzlmod/BazelLockFileValue.java | 33 ---- .../lib/bazel/bzlmod/GsonTypeAdapterUtil.java | 84 ++++++++- .../bazel/bzlmod/LockFileModuleExtension.java | 11 +- .../bzlmod/SingleExtensionEvalFunction.java | 166 ++++++++++++++---- .../devtools/build/lib/cmdline/Label.java | 35 ++++ .../devtools/build/lib/cmdline/LabelTest.java | 37 ++++ .../py/bazel/bzlmod/bazel_lockfile_test.py | 80 +++++++++ 9 files changed, 378 insertions(+), 74 deletions(-) diff --git a/src/main/java/com/google/devtools/build/lib/analysis/starlark/StarlarkRuleClassFunctions.java b/src/main/java/com/google/devtools/build/lib/analysis/starlark/StarlarkRuleClassFunctions.java index 4d5d2ebfa57c8d..31488ce1f47a1c 100644 --- a/src/main/java/com/google/devtools/build/lib/analysis/starlark/StarlarkRuleClassFunctions.java +++ b/src/main/java/com/google/devtools/build/lib/analysis/starlark/StarlarkRuleClassFunctions.java @@ -1277,7 +1277,10 @@ public Label label(Object input, StarlarkThread thread) throws EvalException { // environment across .bzl files. Hence, we opt for stack inspection. BazelModuleContext moduleContext = BazelModuleContext.ofInnermostBzlOrFail(thread, "Label()"); try { - return Label.parseWithPackageContext((String) input, moduleContext.packageContext()); + return Label.parseWithPackageContext( + (String) input, + moduleContext.packageContext(), + thread.getThreadLocal(Label.RepoMappingRecorder.class)); } catch (LabelSyntaxException e) { throw Starlark.errorf("invalid label in Label(): %s", e.getMessage()); } diff --git a/src/main/java/com/google/devtools/build/lib/bazel/bzlmod/BUILD b/src/main/java/com/google/devtools/build/lib/bazel/bzlmod/BUILD index d97a0305b5ce2c..0083f8057b24ad 100644 --- a/src/main/java/com/google/devtools/build/lib/bazel/bzlmod/BUILD +++ b/src/main/java/com/google/devtools/build/lib/bazel/bzlmod/BUILD @@ -220,6 +220,7 @@ java_library( "//src/main/java/com/google/devtools/build/lib/skyframe:client_environment_function", "//src/main/java/com/google/devtools/build/lib/skyframe:client_environment_value", "//src/main/java/com/google/devtools/build/lib/skyframe:precomputed_value", + "//src/main/java/com/google/devtools/build/lib/skyframe:repository_mapping_value", "//src/main/java/com/google/devtools/build/lib/skyframe:skyframe_cluster", "//src/main/java/com/google/devtools/build/lib/util", "//src/main/java/com/google/devtools/build/lib/util:os", diff --git a/src/main/java/com/google/devtools/build/lib/bazel/bzlmod/BazelLockFileValue.java b/src/main/java/com/google/devtools/build/lib/bazel/bzlmod/BazelLockFileValue.java index 21b02c479b76e7..8ac7fb38e77d64 100644 --- a/src/main/java/com/google/devtools/build/lib/bazel/bzlmod/BazelLockFileValue.java +++ b/src/main/java/com/google/devtools/build/lib/bazel/bzlmod/BazelLockFileValue.java @@ -25,7 +25,6 @@ import com.google.devtools.build.skyframe.SkyKey; import com.google.devtools.build.skyframe.SkyValue; import com.ryanharter.auto.value.gson.GenerateTypeAdapter; -import java.util.Arrays; import java.util.Map; /** @@ -118,36 +117,4 @@ public ImmutableList getModuleAndFlagsDiff( } return moduleDiff.build(); } - - /** Returns the differences between an extension and its locked data */ - public ImmutableList getModuleExtensionDiff( - ModuleExtensionId extensionId, - LockFileModuleExtension lockedExtension, - byte[] transitiveDigest, - boolean filesChanged, - ImmutableMap envVariables, - ImmutableList> extensionUsages, - ImmutableList> lockedExtensionUsages) { - - ImmutableList.Builder extDiff = new ImmutableList.Builder<>(); - if (!Arrays.equals(transitiveDigest, lockedExtension.getBzlTransitiveDigest())) { - extDiff.add( - "The implementation of the extension '" - + extensionId - + "' or one of its transitive .bzl files has changed"); - } - if (filesChanged) { - extDiff.add("One or more files the extension '" + extensionId + "' is using have changed"); - } - if (!extensionUsages.equals(lockedExtensionUsages)) { - extDiff.add("The usages of the extension '" + extensionId + "' have changed"); - } - if (!envVariables.equals(lockedExtension.getEnvVariables())) { - extDiff.add( - "The environment variables the extension '" - + extensionId - + "' depends on (or their values) have changed"); - } - return extDiff.build(); - } } diff --git a/src/main/java/com/google/devtools/build/lib/bazel/bzlmod/GsonTypeAdapterUtil.java b/src/main/java/com/google/devtools/build/lib/bazel/bzlmod/GsonTypeAdapterUtil.java index 05a54e2e053cc7..8ef5920da28bed 100644 --- a/src/main/java/com/google/devtools/build/lib/bazel/bzlmod/GsonTypeAdapterUtil.java +++ b/src/main/java/com/google/devtools/build/lib/bazel/bzlmod/GsonTypeAdapterUtil.java @@ -23,9 +23,12 @@ import com.google.auto.value.AutoValue; import com.google.common.base.Preconditions; import com.google.common.base.Splitter; +import com.google.common.collect.ImmutableTable; +import com.google.common.collect.Table; import com.google.devtools.build.lib.bazel.bzlmod.Version.ParseException; import com.google.devtools.build.lib.cmdline.Label; import com.google.devtools.build.lib.cmdline.LabelSyntaxException; +import com.google.devtools.build.lib.cmdline.RepositoryName; import com.google.devtools.build.lib.vfs.Path; import com.google.gson.Gson; import com.google.gson.GsonBuilder; @@ -92,7 +95,7 @@ public ModuleKey read(JsonReader jsonReader) throws IOException { }; public static final TypeAdapter