Skip to content

Commit 64d9fb1

Browse files
aranguyencopybara-github
authored andcommitted
changing the structure of ScopeType to support custom exec behavior. The valid scopes are: universal, project, default, target, and values in the form of exec:<foo>. Here foo could be a specific value of the label to a flag that has the value we need.
PiperOrigin-RevId: 839954752 Change-Id: I8b9250041a40db0405ea8c757ceeaf350926a2ff
1 parent bde51f4 commit 64d9fb1

File tree

8 files changed

+58
-48
lines changed

8 files changed

+58
-48
lines changed

src/main/java/com/google/devtools/build/lib/analysis/config/BUILD

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -509,6 +509,7 @@ java_library(
509509
name = "scope",
510510
srcs = ["Scope.java"],
511511
deps = [
512+
"//src/main/java/com/google/devtools/build/lib/skyframe/serialization/autocodec",
512513
"//third_party:guava",
513514
"//third_party:jsr305",
514515
],

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ private static ImmutableMap<Label, Scope.ScopeType> convertScopesAttributes(
9090
.collect(
9191
toImmutableMap(
9292
e -> Label.parseCanonicalUnchecked(e.getKey()),
93-
e -> Scope.ScopeType.valueOfIgnoreCase(e.getValue())));
93+
e -> new Scope.ScopeType(e.getValue())));
9494
}
9595

9696
public static BuildOptions getDefaultBuildOptionsForFragments(

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

Lines changed: 25 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,10 @@
1313
// limitations under the License.
1414
package com.google.devtools.build.lib.analysis.config;
1515

16-
import static com.google.common.collect.ImmutableList.toImmutableList;
17-
import static java.util.Arrays.stream;
18-
1916
import com.google.common.base.MoreObjects;
2017
import com.google.common.collect.ImmutableList;
2118
import com.google.common.collect.ImmutableSet;
22-
import java.util.Locale;
19+
import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec;
2320
import javax.annotation.Nullable;
2421

2522
/**
@@ -28,27 +25,34 @@
2825
*/
2926
public class Scope {
3027
/** Type of supported scopes. */
31-
public enum ScopeType {
32-
/** The flag's value never changes except explicitly by a configuraiton transition. * */
33-
UNIVERSAL,
34-
/** The flag's value resets on exec transitions. * */
35-
TARGET,
36-
/** The flag resets on targets outside the flag's project. See PROJECT.scl. * */
37-
PROJECT,
38-
/** Placeholder for flags that don't explicitly specify scope. Shouldn't be set directly. * */
39-
DEFAULT;
40-
41-
/** Returns the enum of a {@code scope = "<string>"} value. */
42-
public static ScopeType valueOfIgnoreCase(String scopeType) throws IllegalArgumentException {
43-
return ScopeType.valueOf(scopeType.toUpperCase(Locale.ROOT));
28+
@AutoCodec
29+
public record ScopeType(String scopeType) {
30+
/** The flag's value never changes except explicitly by a configuration transition. */
31+
public static final String UNIVERSAL = "universal";
32+
33+
/** The flag's value resets on exec transitions. */
34+
public static final String TARGET = "target";
35+
36+
/** The flag resets on targets outside the flag's project. See PROJECT.scl. */
37+
public static final String PROJECT = "project";
38+
39+
/** Placeholder for flags that don't explicitly specify scope. Shouldn't be set directly. */
40+
public static final String DEFAULT = "default";
41+
42+
public ScopeType {
43+
if (!(scopeType.equals(DEFAULT)
44+
|| scopeType.equals(UNIVERSAL)
45+
|| scopeType.equals(TARGET)
46+
|| scopeType.equals(PROJECT)
47+
|| scopeType.startsWith("exec:"))) {
48+
// TODO: don't let blaze crash for an invalid scope type.
49+
throw new IllegalArgumentException("Invalid scope type: " + scopeType);
50+
}
4451
}
4552

4653
/** Which values can a rule's {@code scope} attribute have? */
4754
public static ImmutableList<String> allowedAttributeValues() {
48-
return stream(ScopeType.values())
49-
.map(e -> e.name().toLowerCase(Locale.ROOT))
50-
.filter(e -> !e.equals("default")) // "default" is an internal value for unset attributes.
51-
.collect(toImmutableList());
55+
return ImmutableList.of(UNIVERSAL, TARGET, PROJECT);
5256
}
5357
}
5458

src/main/java/com/google/devtools/build/lib/analysis/producers/BuildConfigurationKeyProducer.java

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -183,7 +183,7 @@ private StateMachine findBuildOptionsScopes(Tasks tasks) {
183183
this.postPlatformProcessedOptions.getScopeTypeMap().get(entry.getKey());
184184
// scope is null is applicable for cases where a transition applies starlark flags that are
185185
// not already part of the baseline configuration.
186-
if (scopeType == null || scopeType == Scope.ScopeType.PROJECT) {
186+
if (scopeType == null || scopeType.scopeType().equals(Scope.ScopeType.PROJECT)) {
187187
flagsWithIncompleteScopeInfo.add(entry.getKey());
188188
}
189189
}
@@ -275,7 +275,7 @@ private StateMachine possiblyApplyScopes(Tasks tasks) {
275275

276276
boolean shouldApplyScopes =
277277
buildOptionsScopeValue.getFullyResolvedScopes().values().stream()
278-
.anyMatch(scope -> scope.getScopeType() == Scope.ScopeType.PROJECT);
278+
.anyMatch(scope -> scope.getScopeType().scopeType().equals(Scope.ScopeType.PROJECT));
279279

280280
if (!shouldApplyScopes) {
281281
return finishConfigurationKeyProcessing(
@@ -342,9 +342,12 @@ private static BuildOptions resetFlags(
342342
Scope scope = buildOptionsScopeValue.getFullyResolvedScopes().get(flagLabel);
343343
if (scope == null) {
344344
Verify.verify(
345-
transitionedOptionsWithScopeType.getScopeTypeMap().get(flagLabel)
346-
!= Scope.ScopeType.PROJECT);
347-
} else if (scope.getScopeType() == Scope.ScopeType.PROJECT) {
345+
!transitionedOptionsWithScopeType
346+
.getScopeTypeMap()
347+
.get(flagLabel)
348+
.scopeType()
349+
.equals(Scope.ScopeType.PROJECT));
350+
} else if (scope.getScopeType().scopeType().equals(Scope.ScopeType.PROJECT)) {
348351
Object flagValue = flagEntry.getValue();
349352
Object baselineValue = baselineConfiguration.getStarlarkOptions().get(flagLabel);
350353
if (flagValue != baselineValue && !isInScope(label, scope.getScopeDefinition())) {

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

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -236,9 +236,11 @@ private static ImmutableMap<Label, Object> getExecPropagatingStarlarkFlags(
236236
// setting "scope = 'target'".
237237
return starlarkOptions.entrySet().stream()
238238
.filter(
239-
entry ->
240-
options.getScopeTypeMap().get(entry.getKey()) == Scope.ScopeType.UNIVERSAL
241-
|| options.getScopeTypeMap().get(entry.getKey()) == Scope.ScopeType.DEFAULT)
239+
entry -> {
240+
String scopeType = options.getScopeTypeMap().get(entry.getKey()).scopeType();
241+
return scopeType.equals(Scope.ScopeType.UNIVERSAL)
242+
|| scopeType.equals(Scope.ScopeType.DEFAULT);
243+
})
242244
.collect(ImmutableMap.toImmutableMap(Map.Entry::getKey, Map.Entry::getValue));
243245
}
244246

@@ -256,9 +258,10 @@ private static ImmutableMap<Label, Object> getExecPropagatingStarlarkFlags(
256258

257259
ImmutableMap.Builder<Label, Object> ans = ImmutableMap.builder();
258260
for (Map.Entry<Label, Object> entry : starlarkOptions.entrySet()) {
259-
if (options.getScopeTypeMap().get(entry.getKey()) == Scope.ScopeType.UNIVERSAL) {
261+
String scopeType = options.getScopeTypeMap().get(entry.getKey()).scopeType();
262+
if (scopeType.equals(Scope.ScopeType.UNIVERSAL)) {
260263
ans.put(entry);
261-
} else if (options.getScopeTypeMap().get(entry.getKey()) == Scope.ScopeType.TARGET) {
264+
} else if (scopeType.equals(Scope.ScopeType.TARGET)) {
262265
// Don't propagate this flag.
263266
} else if (customPropagatingFlags.contains(entry.getKey().getUnambiguousCanonicalForm())) {
264267
ans.put(entry);

src/main/java/com/google/devtools/build/lib/skyframe/BuildOptionsScopeFunction.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@ private ImmutableMultimap<Label, Label> findProjectFiles(
134134

135135
Map<Label, ProjectFilesLookupValue.Key> targetsToSkyKeys = new HashMap<>();
136136
for (Label starlarkOption : scopes.keySet()) {
137-
if (scopes.get(starlarkOption).getScopeType() == Scope.ScopeType.PROJECT) {
137+
if (scopes.get(starlarkOption).getScopeType().scopeType().equals(Scope.ScopeType.PROJECT)) {
138138
targetsToSkyKeys.put(
139139
starlarkOption, ProjectFilesLookupValue.key(starlarkOption.getPackageIdentifier()));
140140
}
@@ -184,9 +184,9 @@ private Scope.ScopeType getScopeType(
184184
// value when --incompatible_exclude_starlark_flags_from_exec_config is stably enabled
185185
// and existing rules like skylib's have updated to TARGET.
186186
|| !attrs.isAttributeValueExplicitlySpecified("scope")) {
187-
return Scope.ScopeType.DEFAULT;
187+
return new Scope.ScopeType(Scope.ScopeType.DEFAULT);
188188
}
189-
return Scope.ScopeType.valueOfIgnoreCase(attrs.get("scope", Type.STRING));
189+
return new Scope.ScopeType(attrs.get("scope", Type.STRING));
190190
}
191191

192192
/**

src/test/java/com/google/devtools/build/lib/analysis/producers/BuildConfigurationKeyProducerTest.java

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -552,9 +552,9 @@ public void createKey_withScopedBuildOptions_outOfScopeFlag_flagNotSetInTheBasel
552552
ImmutableMap<Label, Scope.ScopeType> expectedScopeTypeMap =
553553
ImmutableMap.of(
554554
Label.parseCanonicalUnchecked("//flag:foo"),
555-
Scope.ScopeType.PROJECT,
555+
new Scope.ScopeType(Scope.ScopeType.PROJECT),
556556
Label.parseCanonicalUnchecked("//flag:bar"),
557-
Scope.ScopeType.UNIVERSAL);
557+
new Scope.ScopeType(Scope.ScopeType.UNIVERSAL));
558558
assertThat(result.getOptions().getScopeTypeMap())
559559
.containsExactlyEntriesIn(expectedScopeTypeMap);
560560
}
@@ -660,11 +660,11 @@ public void createKey_withScopedBuildOptions_outOfScopeFlag_flagSetInTheBaseline
660660
ImmutableMap<Label, Scope.ScopeType> expectedScopeTypeMap =
661661
ImmutableMap.of(
662662
Label.parseCanonicalUnchecked("//flag:foo"),
663-
Scope.ScopeType.PROJECT,
663+
new Scope.ScopeType(Scope.ScopeType.PROJECT),
664664
Label.parseCanonicalUnchecked("//flag:bar"),
665-
Scope.ScopeType.UNIVERSAL,
665+
new Scope.ScopeType(Scope.ScopeType.UNIVERSAL),
666666
Label.parseCanonicalUnchecked("//out_of_scope_flag:baz"),
667-
Scope.ScopeType.PROJECT);
667+
new Scope.ScopeType(Scope.ScopeType.PROJECT));
668668
assertThat(result.getOptions().getScopeTypeMap())
669669
.containsExactlyEntriesIn(expectedScopeTypeMap);
670670
}
@@ -698,9 +698,9 @@ public void checkFinalizeBuildOptions_haveCorrectScopeTypeMap_noScopingApplied()
698698
ImmutableMap<Label, Scope.ScopeType> expectedScopeTypeMap =
699699
ImmutableMap.of(
700700
Label.parseCanonicalUnchecked("//flag:foo"),
701-
Scope.ScopeType.UNIVERSAL,
701+
new Scope.ScopeType(Scope.ScopeType.UNIVERSAL),
702702
Label.parseCanonicalUnchecked("//flag:bar"),
703-
Scope.ScopeType.UNIVERSAL);
703+
new Scope.ScopeType(Scope.ScopeType.UNIVERSAL));
704704
assertThat(result.getOptions().getScopeTypeMap())
705705
.containsExactlyEntriesIn(expectedScopeTypeMap);
706706
}

src/test/java/com/google/devtools/build/lib/skyframe/BuildOptionsScopeFunctionTest.java

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@
2525
import com.google.devtools.build.lib.analysis.config.FragmentOptions;
2626
import com.google.devtools.build.lib.analysis.config.InvalidConfigurationException;
2727
import com.google.devtools.build.lib.analysis.config.Scope;
28-
import com.google.devtools.build.lib.analysis.config.Scope.ScopeType;
2928
import com.google.devtools.build.lib.analysis.util.AnalysisMock;
3029
import com.google.devtools.build.lib.analysis.util.BuildViewTestCase;
3130
import com.google.devtools.build.lib.cmdline.Label;
@@ -170,19 +169,19 @@ public void buildOptionsScopesFunction_returnsCorrectScope() throws Exception {
170169
ImmutableMap.of(
171170
Label.parseCanonical("//test_flags:foo"),
172171
new Scope(
173-
Scope.ScopeType.PROJECT,
172+
new Scope.ScopeType(Scope.ScopeType.PROJECT),
174173
new Scope.ScopeDefinition(ImmutableSet.of("//my_project/"))),
175174
Label.parseCanonical("//test_flags:bar"),
176-
new Scope(ScopeType.UNIVERSAL, null))));
175+
new Scope(new Scope.ScopeType(Scope.ScopeType.UNIVERSAL), null))));
177176

178177
// verify that the BuildOptionsScopeValue.getResolvedBuildOptionsWithScopeTypes() has the
179178
// correct ScopeType map for all flags.
180179
assertThat(buildOptionsScopeValue.getResolvedBuildOptionsWithScopeTypes().getScopeTypeMap())
181180
.containsExactly(
182181
Label.parseCanonical("//test_flags:foo"),
183-
Scope.ScopeType.PROJECT,
182+
new Scope.ScopeType(Scope.ScopeType.PROJECT),
184183
Label.parseCanonical("//test_flags:bar"),
185-
Scope.ScopeType.UNIVERSAL);
184+
new Scope.ScopeType(Scope.ScopeType.UNIVERSAL));
186185
}
187186

188187
@Test
@@ -223,7 +222,7 @@ public void buildOptionsScopesFunction_doesNotErrorOut_whenNoProjectFile() throw
223222
.equals(
224223
ImmutableMap.of(
225224
Label.parseCanonical("//test_flags:foo"),
226-
new Scope(Scope.ScopeType.PROJECT, null))));
225+
new Scope(new Scope.ScopeType(Scope.ScopeType.PROJECT), null))));
227226
}
228227

229228
private BuildOptionsScopeValue executeFunction(BuildOptionsScopeValue.Key key) throws Exception {

0 commit comments

Comments
 (0)