Skip to content

Commit 1745889

Browse files
Wyveraldbazel-io
authored andcommitted
Make repo marker files sensitive to repo mapping changes
Similar to the fix for bazelbuild#20721, we write recorded repo mapping entries into the marker file so that repo fetching is sensitive to any relevant repo mapping changes. Fixes bazelbuild#20722. Closes bazelbuild#21131. PiperOrigin-RevId: 603310262 Change-Id: I806f383e8579fed3533fac9b181efd8b75e76fcd
1 parent 548c171 commit 1745889

File tree

8 files changed

+317
-145
lines changed

8 files changed

+317
-145
lines changed

src/main/java/com/google/devtools/build/lib/bazel/repository/starlark/StarlarkRepositoryFunction.java

+15
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import com.google.common.collect.ImmutableList;
2121
import com.google.common.collect.ImmutableMap;
2222
import com.google.common.collect.ImmutableSet;
23+
import com.google.common.collect.Table;
2324
import com.google.devtools.build.lib.analysis.BlazeDirectories;
2425
import com.google.devtools.build.lib.analysis.RuleDefinition;
2526
import com.google.devtools.build.lib.bazel.repository.RepositoryResolvedEvent;
@@ -242,6 +243,10 @@ private RepositoryDirectoryValue.Builder fetchInternal(
242243
try (Mutability mu = Mutability.create("Starlark repository")) {
243244
StarlarkThread thread = new StarlarkThread(mu, starlarkSemantics);
244245
thread.setPrintHandler(Event.makeDebugPrintHandler(env.getListener()));
246+
var repoMappingRecorder = new Label.RepoMappingRecorder();
247+
repoMappingRecorder.mergeEntries(
248+
rule.getRuleClassObject().getRuleDefinitionEnvironmentRepoMappingEntries());
249+
thread.setThreadLocal(Label.RepoMappingRecorder.class, repoMappingRecorder);
245250

246251
new BazelStarlarkContext(
247252
BazelStarlarkContext.Phase.LOADING, // ("fetch")
@@ -330,6 +335,16 @@ private RepositoryDirectoryValue.Builder fetchInternal(
330335
markerData.put("ENV:" + envKey, clientEnvironment.get(envKey));
331336
}
332337

338+
for (Table.Cell<RepositoryName, String, RepositoryName> repoMappings :
339+
repoMappingRecorder.recordedEntries().cellSet()) {
340+
markerData.put(
341+
"REPO_MAPPING:"
342+
+ repoMappings.getRowKey().getName()
343+
+ ","
344+
+ repoMappings.getColumnKey(),
345+
repoMappings.getValue().getName());
346+
}
347+
333348
env.getListener().post(resolved);
334349
} catch (NeedsSkyframeRestartException e) {
335350
// A dependency is missing, cleanup and returns null

src/main/java/com/google/devtools/build/lib/bazel/repository/starlark/StarlarkRepositoryModule.java

+5
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,11 @@ public StarlarkCallable repositoryRule(
113113
BazelModuleContext moduleContext = BazelModuleContext.ofInnermostBzlOrThrow(thread);
114114
builder.setRuleDefinitionEnvironmentLabelAndDigest(
115115
moduleContext.label(), moduleContext.bzlTransitiveDigest());
116+
Label.RepoMappingRecorder repoMappingRecorder =
117+
thread.getThreadLocal(Label.RepoMappingRecorder.class);
118+
if (repoMappingRecorder != null) {
119+
builder.setRuleDefinitionEnvironmentRepoMappingEntries(repoMappingRecorder.recordedEntries());
120+
}
116121
builder.setWorkspaceOnly();
117122
return new RepositoryRuleFunction(
118123
builder,

src/main/java/com/google/devtools/build/lib/packages/RuleClass.java

+166-142
Large diffs are not rendered by default.

src/main/java/com/google/devtools/build/lib/rules/BUILD

+1
Original file line numberDiff line numberDiff line change
@@ -414,6 +414,7 @@ java_library(
414414
"//src/main/java/com/google/devtools/build/lib/skyframe:package_lookup_function",
415415
"//src/main/java/com/google/devtools/build/lib/skyframe:package_lookup_value",
416416
"//src/main/java/com/google/devtools/build/lib/skyframe:precomputed_value",
417+
"//src/main/java/com/google/devtools/build/lib/skyframe:repository_mapping_value",
417418
"//src/main/java/com/google/devtools/build/lib/skyframe:sky_functions",
418419
"//src/main/java/com/google/devtools/build/lib/skyframe:sky_value_dirtiness_checker",
419420
"//src/main/java/com/google/devtools/build/lib/util",

src/main/java/com/google/devtools/build/lib/rules/repository/RepositoryDelegatorFunction.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ public final class RepositoryDelegatorFunction implements SkyFunction {
8686

8787
// The marker file version is inject in the rule key digest so the rule key is always different
8888
// when we decide to update the format.
89-
private static final int MARKER_FILE_VERSION = 3;
89+
private static final int MARKER_FILE_VERSION = 4;
9090

9191
// Mapping of rule class name to RepositoryFunction.
9292
private final ImmutableMap<String, RepositoryFunction> handlers;

src/main/java/com/google/devtools/build/lib/rules/repository/RepositoryFunction.java

+39-2
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
package com.google.devtools.build.lib.rules.repository;
1616

1717
import static com.google.common.base.Preconditions.checkState;
18+
import static com.google.common.collect.ImmutableSet.toImmutableSet;
1819

1920
import com.google.common.annotations.VisibleForTesting;
2021
import com.google.common.base.Preconditions;
@@ -40,6 +41,7 @@
4041
import com.google.devtools.build.lib.skyframe.PackageLookupFunction;
4142
import com.google.devtools.build.lib.skyframe.PackageLookupValue;
4243
import com.google.devtools.build.lib.skyframe.PrecomputedValue;
44+
import com.google.devtools.build.lib.skyframe.RepositoryMappingValue;
4345
import com.google.devtools.build.lib.vfs.FileSystemUtils;
4446
import com.google.devtools.build.lib.vfs.Path;
4547
import com.google.devtools.build.lib.vfs.PathFragment;
@@ -50,6 +52,7 @@
5052
import com.google.devtools.build.skyframe.SkyFunctionException;
5153
import com.google.devtools.build.skyframe.SkyFunctionException.Transience;
5254
import com.google.devtools.build.skyframe.SkyKey;
55+
import com.google.devtools.build.skyframe.SkyframeLookupResult;
5356
import java.io.IOException;
5457
import java.util.Collection;
5558
import java.util.LinkedHashMap;
@@ -205,15 +208,49 @@ private static ImmutableSet<String> getEnviron(Rule rule) {
205208
public boolean verifyMarkerData(Rule rule, Map<String, String> markerData, Environment env)
206209
throws InterruptedException {
207210
return verifyEnvironMarkerData(markerData, env, getEnviron(rule))
208-
&& verifyMarkerDataForFiles(rule, markerData, env)
209-
&& verifySemanticsMarkerData(markerData, env);
211+
&& verifySemanticsMarkerData(markerData, env)
212+
&& verifyRepoMappingMarkerData(markerData, env)
213+
&& verifyMarkerDataForFiles(rule, markerData, env);
210214
}
211215

212216
protected boolean verifySemanticsMarkerData(Map<String, String> markerData, Environment env)
213217
throws InterruptedException {
214218
return true;
215219
}
216220

221+
private static boolean verifyRepoMappingMarkerData(
222+
Map<String, String> markerData, Environment env) throws InterruptedException {
223+
ImmutableSet<SkyKey> skyKeys =
224+
markerData.keySet().stream()
225+
.filter(k -> k.startsWith("REPO_MAPPING:"))
226+
// grab the part after the 'REPO_MAPPING:' and before the comma
227+
.map(k -> k.substring("REPO_MAPPING:".length(), k.indexOf(',')))
228+
.map(k -> RepositoryMappingValue.key(RepositoryName.createUnvalidated(k)))
229+
.collect(toImmutableSet());
230+
SkyframeLookupResult result = env.getValuesAndExceptions(skyKeys);
231+
if (env.valuesMissing()) {
232+
return false;
233+
}
234+
for (Map.Entry<String, String> entry : markerData.entrySet()) {
235+
if (!entry.getKey().startsWith("REPO_MAPPING:")) {
236+
continue;
237+
}
238+
int commaIndex = entry.getKey().indexOf(',');
239+
RepositoryName fromRepo =
240+
RepositoryName.createUnvalidated(
241+
entry.getKey().substring("REPO_MAPPING:".length(), commaIndex));
242+
String apparentRepoName = entry.getKey().substring(commaIndex + 1);
243+
RepositoryMappingValue repoMappingValue =
244+
(RepositoryMappingValue) result.get(RepositoryMappingValue.key(fromRepo));
245+
if (repoMappingValue == RepositoryMappingValue.NOT_FOUND_VALUE
246+
|| !RepositoryName.createUnvalidated(entry.getValue())
247+
.equals(repoMappingValue.getRepositoryMapping().get(apparentRepoName))) {
248+
return false;
249+
}
250+
}
251+
return true;
252+
}
253+
217254
private static boolean verifyLabelMarkerData(Rule rule, String key, String value, Environment env)
218255
throws InterruptedException {
219256
Preconditions.checkArgument(key.startsWith("FILE:"));

src/test/java/com/google/devtools/build/lib/packages/RuleClassTest.java

+1
Original file line numberDiff line numberDiff line change
@@ -1050,6 +1050,7 @@ private static RuleClass newRuleClass(
10501050
/* optionReferenceFunction= */ RuleClass.NO_OPTION_REFERENCE,
10511051
/* ruleDefinitionEnvironmentLabel= */ null,
10521052
/* ruleDefinitionEnvironmentDigest= */ null,
1053+
/* ruleDefinitionEnvironmentRepoMappingEntries= */ null,
10531054
new ConfigurationFragmentPolicy.Builder()
10541055
.requiresConfigurationFragments(allowedConfigurationFragments)
10551056
.build(),

src/test/shell/bazel/starlark_repository_test.sh

+89
Original file line numberDiff line numberDiff line change
@@ -2611,4 +2611,93 @@ EOF
26112611
assert_contains 'WORKSPACE' output
26122612
}
26132613

2614+
function test_repo_mapping_change_in_rule_impl() {
2615+
# regression test for #20722
2616+
create_new_workspace
2617+
cat > MODULE.bazel <<EOF
2618+
r = use_repo_rule("//:r.bzl", "r")
2619+
r(name = "r")
2620+
bazel_dep(name="foo", repo_name="data")
2621+
local_path_override(module_name="foo", path="foo")
2622+
bazel_dep(name="bar")
2623+
local_path_override(module_name="bar", path="bar")
2624+
EOF
2625+
touch BUILD
2626+
cat > r.bzl <<EOF
2627+
def _r(rctx):
2628+
print("I see: " + str(Label("@data")))
2629+
rctx.file("BUILD", "filegroup(name='r')")
2630+
r=repository_rule(_r)
2631+
EOF
2632+
mkdir foo
2633+
cat > foo/MODULE.bazel <<EOF
2634+
module(name="foo")
2635+
EOF
2636+
mkdir bar
2637+
cat > bar/MODULE.bazel <<EOF
2638+
module(name="bar")
2639+
EOF
2640+
2641+
bazel build @r >& $TEST_log || fail "expected bazel to succeed"
2642+
expect_log "I see: @@foo~override//:data"
2643+
2644+
# So far, so good. Now we make `@data` point to bar instead!
2645+
cat > MODULE.bazel <<EOF
2646+
r = use_repo_rule("//:r.bzl", "r")
2647+
r(name = "r")
2648+
bazel_dep(name="foo")
2649+
local_path_override(module_name="foo", path="foo")
2650+
bazel_dep(name="bar", repo_name="data")
2651+
local_path_override(module_name="bar", path="bar")
2652+
EOF
2653+
# for the repo `r`, nothing except the repo mapping has changed.
2654+
bazel build @r >& $TEST_log || fail "expected bazel to succeed"
2655+
expect_log "I see: @@bar~override//:data"
2656+
}
2657+
2658+
function test_repo_mapping_change_in_bzl_init() {
2659+
# same as above, but tests .bzl init time repo mapping usages
2660+
create_new_workspace
2661+
cat > MODULE.bazel <<EOF
2662+
r = use_repo_rule("//:r.bzl", "r")
2663+
r(name = "r")
2664+
bazel_dep(name="foo", repo_name="data")
2665+
local_path_override(module_name="foo", path="foo")
2666+
bazel_dep(name="bar")
2667+
local_path_override(module_name="bar", path="bar")
2668+
EOF
2669+
touch BUILD
2670+
cat > r.bzl <<EOF
2671+
CONSTANT = Label("@data")
2672+
def _r(rctx):
2673+
print("I see: " + str(CONSTANT))
2674+
rctx.file("BUILD", "filegroup(name='r')")
2675+
r=repository_rule(_r)
2676+
EOF
2677+
mkdir foo
2678+
cat > foo/MODULE.bazel <<EOF
2679+
module(name="foo")
2680+
EOF
2681+
mkdir bar
2682+
cat > bar/MODULE.bazel <<EOF
2683+
module(name="bar")
2684+
EOF
2685+
2686+
bazel build @r >& $TEST_log || fail "expected bazel to succeed"
2687+
expect_log "I see: @@foo~override//:data"
2688+
2689+
# So far, so good. Now we make `@data` point to bar instead!
2690+
cat > MODULE.bazel <<EOF
2691+
r = use_repo_rule("//:r.bzl", "r")
2692+
r(name = "r")
2693+
bazel_dep(name="foo")
2694+
local_path_override(module_name="foo", path="foo")
2695+
bazel_dep(name="bar", repo_name="data")
2696+
local_path_override(module_name="bar", path="bar")
2697+
EOF
2698+
# for the repo `r`, nothing except the repo mapping has changed.
2699+
bazel build @r >& $TEST_log || fail "expected bazel to succeed"
2700+
expect_log "I see: @@bar~override//:data"
2701+
}
2702+
26142703
run_suite "local repository tests"

0 commit comments

Comments
 (0)