Skip to content

Commit 463e8c8

Browse files
Wyveraldcopybara-github
authored andcommitted
Fix Label() behavior when called with '@repo' parts
The Label() constructor reads its repo mapping from BazelStarlarkContext, which is constructed when the thread is created. This is wrong because the repo mapping it needs is actually the one of the repo where the .bzl file lives. So we do that by having BazelModuleContext store the repo mapping (similar to how it stores the label right now) and return that. Callers who want the repo mapping (not just Label()) now get it from the topmost stack frame rather than from the BazelStarlarkContext, which no longer carries a repo mapping. This coincidentally also fixes Label() behavior when called from a Bzlmod environment (either extension impl functions, or repo rules; see #13316), because we simply don't have a BazelStarlarkContext in those cases. Fixes #12963. PiperOrigin-RevId: 401732211
1 parent 7cf0c34 commit 463e8c8

File tree

17 files changed

+116
-69
lines changed

17 files changed

+116
-69
lines changed

src/main/java/com/google/devtools/build/lib/analysis/ConfiguredRuleClassProvider.java

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,6 @@
4444
import com.google.devtools.build.lib.analysis.starlark.StarlarkModules;
4545
import com.google.devtools.build.lib.cmdline.Label;
4646
import com.google.devtools.build.lib.cmdline.LabelSyntaxException;
47-
import com.google.devtools.build.lib.cmdline.RepositoryMapping;
4847
import com.google.devtools.build.lib.graph.Digraph;
4948
import com.google.devtools.build.lib.graph.Node;
5049
import com.google.devtools.build.lib.packages.BazelStarlarkContext;
@@ -860,13 +859,11 @@ public ImmutableMap<String, Object> getEnvironment() {
860859
}
861860

862861
@Override
863-
public void setStarlarkThreadContext(
864-
StarlarkThread thread, Label fileLabel, RepositoryMapping repoMapping) {
862+
public void setStarlarkThreadContext(StarlarkThread thread, Label fileLabel) {
865863
new BazelStarlarkContext(
866864
BazelStarlarkContext.Phase.LOADING,
867865
toolsRepository,
868866
configurationFragmentMap,
869-
repoMapping,
870867
/*convertedLabelsInPackage=*/ new HashMap<>(),
871868
new SymbolGenerator<>(fileLabel),
872869
/*analysisRuleLabel=*/ null,

src/main/java/com/google/devtools/build/lib/analysis/RuleContext.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1127,7 +1127,6 @@ private StarlarkThread createStarlarkThread(Mutability mutability) {
11271127
BazelStarlarkContext.Phase.ANALYSIS,
11281128
ruleClassProvider.getToolsRepository(),
11291129
/*fragmentNameToClass=*/ null,
1130-
getTarget().getPackage().getRepositoryMapping(),
11311130
/*convertedLabelsInPackage=*/ new HashMap<>(),
11321131
getSymbolGenerator(),
11331132
getLabel(),

src/main/java/com/google/devtools/build/lib/analysis/config/StarlarkDefinedConfigTransition.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -205,10 +205,10 @@ public static StarlarkDefinedConfigTransition newRegularTransition(
205205
StarlarkSemantics semantics,
206206
Label parentLabel,
207207
Location location,
208-
BazelStarlarkContext starlarkContext)
208+
RepositoryMapping repoMapping)
209209
throws EvalException {
210210
return new RegularTransition(
211-
impl, inputs, outputs, semantics, parentLabel, location, starlarkContext.getRepoMapping());
211+
impl, inputs, outputs, semantics, parentLabel, location, repoMapping);
212212
}
213213

214214
public static StarlarkDefinedConfigTransition newAnalysisTestTransition(
@@ -350,7 +350,6 @@ public ImmutableMap<String, Map<String, Object>> evaluate(
350350
Phase.ANALYSIS,
351351
/*toolsRepository=*/ null,
352352
/*fragmentNameToClass=*/ null,
353-
repoMapping,
354353
/*convertedLabelsInPackage=*/ new HashMap<>(),
355354
dummySymbolGenerator,
356355
parentLabel,

src/main/java/com/google/devtools/build/lib/analysis/starlark/StarlarkAttrModule.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@
4545
import com.google.devtools.build.lib.starlarkbuildapi.StarlarkAttrModuleApi;
4646
import com.google.devtools.build.lib.util.FileType;
4747
import com.google.devtools.build.lib.util.FileTypeSet;
48+
import java.util.HashMap;
4849
import java.util.List;
4950
import java.util.Map;
5051
import javax.annotation.Nullable;
@@ -137,13 +138,12 @@ private static Attribute.Builder<?> createAttribute(
137138
} else if (defaultValue instanceof StarlarkLateBoundDefault) {
138139
builder.value((StarlarkLateBoundDefault) defaultValue); // unchecked cast
139140
} else {
140-
BazelStarlarkContext bazelStarlarkContext = BazelStarlarkContext.from(thread);
141+
BazelModuleContext moduleContext =
142+
BazelModuleContext.of(Module.ofInnermostEnclosingStarlarkFunction(thread));
141143
builder.defaultValue(
142144
defaultValue,
143145
new BuildType.LabelConversionContext(
144-
BazelModuleContext.of(Module.ofInnermostEnclosingStarlarkFunction(thread)).label(),
145-
bazelStarlarkContext.getRepoMapping(),
146-
bazelStarlarkContext.getConvertedLabelsInPackage()),
146+
moduleContext.label(), moduleContext.repoMapping(), new HashMap<>()),
147147
DEFAULT_ARG);
148148
}
149149
}

src/main/java/com/google/devtools/build/lib/analysis/starlark/StarlarkRuleClassFunctions.java

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -557,10 +557,12 @@ private static ImmutableList<Label> parseLabels(
557557
Iterable<String> inputs, StarlarkThread thread, String adjective) throws EvalException {
558558
ImmutableList.Builder<Label> parsedLabels = new ImmutableList.Builder<>();
559559
BazelStarlarkContext bazelStarlarkContext = BazelStarlarkContext.from(thread);
560+
BazelModuleContext moduleContext =
561+
BazelModuleContext.of(Module.ofInnermostEnclosingStarlarkFunction(thread));
560562
LabelConversionContext context =
561563
new LabelConversionContext(
562-
BazelModuleContext.of(Module.ofInnermostEnclosingStarlarkFunction(thread)).label(),
563-
bazelStarlarkContext.getRepoMapping(),
564+
moduleContext.label(),
565+
moduleContext.repoMapping(),
564566
bazelStarlarkContext.getConvertedLabelsInPackage());
565567
for (String input : inputs) {
566568
try {
@@ -958,8 +960,6 @@ public boolean isImmutable() {
958960

959961
@Override
960962
public Label label(String labelString, StarlarkThread thread) throws EvalException {
961-
BazelStarlarkContext context = BazelStarlarkContext.from(thread);
962-
963963
// This function is surprisingly complex.
964964
//
965965
// - The logic to find the "current repo" is rather magical, using dynamic scope:
@@ -984,16 +984,14 @@ public Label label(String labelString, StarlarkThread thread) throws EvalExcepti
984984
// and cache without needing four allocations (parseAbsoluteLabel,
985985
// getRelativeWithRemapping, getUnambiguousCanonicalForm, parseAbsoluteLabel
986986
// in labelCache)
987-
988-
// This is the label of the innermost BUILD/.bzl file on the current call stack.
989-
Label parentLabel =
990-
BazelModuleContext.of(Module.ofInnermostEnclosingStarlarkFunction(thread)).label();
991-
987+
BazelModuleContext moduleContext =
988+
BazelModuleContext.of(Module.ofInnermostEnclosingStarlarkFunction(thread));
992989
try {
993990
LabelValidator.parseAbsoluteLabel(labelString);
994991
labelString =
995-
parentLabel
996-
.getRelativeWithRemapping(labelString, context.getRepoMapping())
992+
moduleContext
993+
.label()
994+
.getRelativeWithRemapping(labelString, moduleContext.repoMapping())
997995
.getUnambiguousCanonicalForm();
998996
return labelCache.get(labelString);
999997
} catch (LabelValidator.BadLabelException | LabelSyntaxException e) {

src/main/java/com/google/devtools/build/lib/analysis/starlark/StarlarkToolchainContext.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -89,11 +89,12 @@ private Label transformKey(StarlarkThread starlarkThread, Object key) throws Eva
8989
} else if (key instanceof String) {
9090
try {
9191
BazelStarlarkContext bazelStarlarkContext = BazelStarlarkContext.from(starlarkThread);
92+
BazelModuleContext moduleContext =
93+
BazelModuleContext.of(Module.ofInnermostEnclosingStarlarkFunction(starlarkThread));
9294
LabelConversionContext context =
9395
new LabelConversionContext(
94-
BazelModuleContext.of(Module.ofInnermostEnclosingStarlarkFunction(starlarkThread))
95-
.label(),
96-
bazelStarlarkContext.getRepoMapping(),
96+
moduleContext.label(),
97+
moduleContext.repoMapping(),
9798
bazelStarlarkContext.getConvertedLabelsInPackage());
9899
return context.convert((String) key);
99100
} catch (LabelSyntaxException e) {

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

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,6 @@ public RepositoryDirectoryValue.Builder fetch(
158158
BazelStarlarkContext.Phase.LOADING, // ("fetch")
159159
/*toolsRepository=*/ null,
160160
/*fragmentNameToClass=*/ null,
161-
rule.getPackage().getRepositoryMapping(),
162161
/*convertedLabelsInPackage=*/ new HashMap<>(),
163162
new SymbolGenerator<>(key),
164163
/*analysisRuleLabel=*/ null,

src/main/java/com/google/devtools/build/lib/cmdline/Label.java

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -548,17 +548,19 @@ public Label getLocalTargetLabel(String targetName) throws LabelSyntaxException
548548
useStarlarkThread = true)
549549
public Label getRelative(String relName, StarlarkThread thread) throws LabelSyntaxException {
550550
HasRepoMapping hrm = thread.getThreadLocal(HasRepoMapping.class);
551-
return getRelativeWithRemapping(relName, hrm.getRepoMapping());
551+
return getRelativeWithRemapping(relName, hrm.getRepoMappingForCurrentBzlFile(thread));
552552
}
553553

554554
/**
555-
* An interface for retrieving a repository mapping.
555+
* An interface for retrieving a repository mapping that's applicable for the repo containing the
556+
* current .bzl file (more precisely, the .bzl file where the function at the innermost Starlark
557+
* stack frame lives).
556558
*
557559
* <p>This has only a single implementation, {@code BazelStarlarkContext}, but we can't mention
558560
* that type here because logically it belongs in Bazel, above this package.
559561
*/
560562
public interface HasRepoMapping {
561-
RepositoryMapping getRepoMapping();
563+
RepositoryMapping getRepoMappingForCurrentBzlFile(StarlarkThread thread);
562564
}
563565

564566
/**

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

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
import com.google.auto.value.AutoValue;
1818
import com.google.common.collect.ImmutableMap;
1919
import com.google.devtools.build.lib.cmdline.Label;
20+
import com.google.devtools.build.lib.cmdline.RepositoryMapping;
2021
import net.starlark.java.eval.Module;
2122

2223
/**
@@ -28,6 +29,9 @@ public abstract class BazelModuleContext {
2829
/** Label associated with the Starlark {@link net.starlark.java.eval.Module}. */
2930
public abstract Label label();
3031

32+
/** The repository mapping applicable to the repo where the .bzl file is located in. */
33+
public abstract RepositoryMapping repoMapping();
34+
3135
/** Returns the name of the module's .bzl file, as provided to the parser. */
3236
public abstract String filename();
3337

@@ -64,9 +68,11 @@ public static BazelModuleContext of(Module m) {
6468

6569
public static BazelModuleContext create(
6670
Label label,
71+
RepositoryMapping repoMapping,
6772
String filename,
6873
ImmutableMap<String, Module> loads,
6974
byte[] bzlTransitiveDigest) {
70-
return new AutoValue_BazelModuleContext(label, filename, loads, bzlTransitiveDigest);
75+
return new AutoValue_BazelModuleContext(
76+
label, repoMapping, filename, loads, bzlTransitiveDigest);
7177
}
7278
}

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

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
import java.util.Optional;
2626
import javax.annotation.Nullable;
2727
import net.starlark.java.eval.EvalException;
28+
import net.starlark.java.eval.Module;
2829
import net.starlark.java.eval.Starlark;
2930
import net.starlark.java.eval.StarlarkThread;
3031

@@ -63,7 +64,6 @@ public void storeInThread(StarlarkThread thread) {
6364
@Nullable private final String toolsRepository;
6465
// Only necessary for loading phase threads to construct configuration_field.
6566
@Nullable private final ImmutableMap<String, Class<?>> fragmentNameToClass;
66-
private final RepositoryMapping repoMapping;
6767
private final HashMap<String, Label> convertedLabelsInPackage;
6868
private final SymbolGenerator<?> symbolGenerator;
6969
@Nullable private final Label analysisRuleLabel;
@@ -77,7 +77,6 @@ public void storeInThread(StarlarkThread thread) {
7777
* @param fragmentNameToClass a map from configuration fragment name to configuration fragment
7878
* class, such as "apple" to AppleConfiguration.class for loading phase threads, null for
7979
* other threads.
80-
* @param repoMapping a map from RepositoryName to RepositoryName to be used for external
8180
* @param convertedLabelsInPackage a mutable map from String to Label, used during package loading
8281
* of a single package.
8382
* @param symbolGenerator a {@link SymbolGenerator} to be used when creating objects to be
@@ -90,22 +89,19 @@ public void storeInThread(StarlarkThread thread) {
9089
// separate structs, exactly one of which is populated (plus the common fields). And eliminate
9190
// StarlarkUtils.Phase.
9291
// TODO(adonovan): move PackageFactory.PackageContext in here, for loading-phase threads.
93-
// TODO(adonovan): add a PackageIdentifier here, for use by the Starlark Label function.
9492
// TODO(adonovan): is there any reason not to put the entire RuleContext in this thread, for
9593
// analysis threads?
9694
public BazelStarlarkContext(
9795
Phase phase,
9896
@Nullable String toolsRepository,
9997
@Nullable ImmutableMap<String, Class<?>> fragmentNameToClass,
100-
RepositoryMapping repoMapping,
10198
HashMap<String, Label> convertedLabelsInPackage,
10299
SymbolGenerator<?> symbolGenerator,
103100
@Nullable Label analysisRuleLabel,
104101
@Nullable Label networkAllowlistForTests) {
105102
this.phase = Preconditions.checkNotNull(phase);
106103
this.toolsRepository = toolsRepository;
107104
this.fragmentNameToClass = fragmentNameToClass;
108-
this.repoMapping = repoMapping;
109105
this.convertedLabelsInPackage = convertedLabelsInPackage;
110106
this.symbolGenerator = Preconditions.checkNotNull(symbolGenerator);
111107
this.analysisRuleLabel = analysisRuleLabel;
@@ -130,8 +126,11 @@ public ImmutableMap<String, Class<?>> getFragmentNameToClass() {
130126
* in the BUILD files and the values are new repository names chosen by the main repository.
131127
*/
132128
@Override
133-
public RepositoryMapping getRepoMapping() {
134-
return repoMapping;
129+
public RepositoryMapping getRepoMappingForCurrentBzlFile(StarlarkThread thread) {
130+
// TODO(b/200024947): Find a better place for this. We don't want Label to have to depend on
131+
// StarlarkModuleContext, but having the logic in BazelStarlarkContext is purely a historical
132+
// misstep.
133+
return BazelModuleContext.of(Module.ofInnermostEnclosingStarlarkFunction(thread)).repoMapping();
135134
}
136135

137136
/**

0 commit comments

Comments
 (0)