Allow rule writers to create exec_group related exec transitions via config.exec(exec_group) and attach them to starlark dependency attrs.
PiperOrigin-RevId: 308290724
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/BUILD b/src/main/java/com/google/devtools/build/lib/analysis/BUILD
index 92efb5b..4de5d46 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/BUILD
+++ b/src/main/java/com/google/devtools/build/lib/analysis/BUILD
@@ -1557,9 +1557,11 @@
":config/transitions/patch_transition",
":config/transitions/transition_factory",
":platform_options",
+ ":toolchain_collection",
"//src/main/java/com/google/devtools/build/lib/cmdline",
"//src/main/java/com/google/devtools/build/lib/events",
"//src/main/java/com/google/devtools/build/lib/packages",
+ "//src/main/java/com/google/devtools/build/lib/skylarkbuildapi",
"//third_party:guava",
"//third_party:jsr305",
],
@@ -2035,6 +2037,7 @@
name = "skylark/starlark_config",
srcs = ["skylark/StarlarkConfig.java"],
deps = [
+ ":config/execution_transition_factory",
"//src/main/java/com/google/devtools/build/lib/packages",
"//src/main/java/com/google/devtools/build/lib/packages:type",
"//src/main/java/com/google/devtools/build/lib/skylarkbuildapi",
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/DependencyResolver.java b/src/main/java/com/google/devtools/build/lib/analysis/DependencyResolver.java
index 6dbb7f0..b84e2f9 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/DependencyResolver.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/DependencyResolver.java
@@ -22,6 +22,7 @@
import com.google.devtools.build.lib.analysis.AspectCollection.AspectCycleOnPathException;
import com.google.devtools.build.lib.analysis.config.BuildConfiguration;
import com.google.devtools.build.lib.analysis.config.ConfigMatchingProvider;
+import com.google.devtools.build.lib.analysis.config.ExecutionTransitionFactory;
import com.google.devtools.build.lib.analysis.config.Fragment;
import com.google.devtools.build.lib.analysis.config.HostTransition;
import com.google.devtools.build.lib.analysis.config.TransitionResolver;
@@ -291,7 +292,8 @@
@Nullable Rule fromRule,
ConfiguredAttributeMapper attributeMap,
@Nullable ToolchainCollection<ToolchainContext> toolchainContexts,
- Iterable<Aspect> aspects) {
+ Iterable<Aspect> aspects)
+ throws EvalException {
OrderedSetMultimap<DependencyKind, PartiallyResolvedDependency> partiallyResolvedDeps =
OrderedSetMultimap.create();
@@ -335,13 +337,28 @@
aspects, attribute.getName(), entry.getKey().getOwningAspect(), propagatingAspects);
Label executionPlatformLabel = null;
- // TODO(b/151742236): support transitions to other ({@link ExecGroup defined}) execution
- // platforms
- if (toolchainContexts != null
- && toolchainContexts.getDefaultToolchainContext().executionPlatform() != null) {
- executionPlatformLabel =
- toolchainContexts.getDefaultToolchainContext().executionPlatform().label();
+ if (toolchainContexts != null) {
+ if (attribute.getTransitionFactory() instanceof ExecutionTransitionFactory) {
+ String execGroup =
+ ((ExecutionTransitionFactory) attribute.getTransitionFactory()).getExecGroup();
+ if (!toolchainContexts.hasToolchainContext(execGroup)) {
+ String error =
+ String.format(
+ "Attr '%s' declares a transition for non-existent exec group '%s'",
+ attribute.getName(), execGroup);
+ if (fromRule != null) {
+ throw new EvalException(fromRule.getLocation(), error);
+ } else {
+ throw new EvalException(error);
+ }
+ }
+ if (toolchainContexts.getToolchainContext(execGroup).executionPlatform() != null) {
+ executionPlatformLabel =
+ toolchainContexts.getToolchainContext(execGroup).executionPlatform().label();
+ }
+ }
}
+
AttributeTransitionData attributeTransitionData =
AttributeTransitionData.builder()
.attributes(attributeMap)
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/ToolchainCollection.java b/src/main/java/com/google/devtools/build/lib/analysis/ToolchainCollection.java
index 2cbe240..206a8d6 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/ToolchainCollection.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/ToolchainCollection.java
@@ -24,7 +24,7 @@
import java.util.Map;
/**
- * A wrapper class for a map of exec_group names to their relevent ToolchainContext.
+ * A wrapper class for a map of exec_group names to their relevant ToolchainContext.
*
* @param <T> any class that extends ToolchainContext. This generic allows ToolchainCollection to be
* used, e.g., both before and after toolchain resolution.
@@ -73,6 +73,10 @@
return toolchainContexts.get(DEFAULT_EXEC_GROUP_NAME);
}
+ boolean hasToolchainContext(String execGroup) {
+ return toolchainContexts.containsKey(execGroup);
+ }
+
public T getToolchainContext(String execGroup) {
return toolchainContexts.get(execGroup);
}
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/config/ExecutionTransitionFactory.java b/src/main/java/com/google/devtools/build/lib/analysis/config/ExecutionTransitionFactory.java
index 643f6fb..28a5bf5 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/config/ExecutionTransitionFactory.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/config/ExecutionTransitionFactory.java
@@ -14,6 +14,8 @@
package com.google.devtools.build.lib.analysis.config;
+import static com.google.devtools.build.lib.analysis.ToolchainCollection.DEFAULT_EXEC_GROUP_NAME;
+
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
import com.google.devtools.build.lib.analysis.PlatformOptions;
@@ -22,6 +24,7 @@
import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.events.EventHandler;
import com.google.devtools.build.lib.packages.AttributeTransitionData;
+import com.google.devtools.build.lib.skylarkbuildapi.StarlarkConfigApi.ExecTransitionFactoryApi;
import javax.annotation.Nullable;
/**
@@ -29,26 +32,29 @@
* transition to a configuration suitable for building dependencies for the execution platform of
* the depending target.
*/
-public class ExecutionTransitionFactory implements TransitionFactory<AttributeTransitionData> {
+public class ExecutionTransitionFactory
+ implements TransitionFactory<AttributeTransitionData>, ExecTransitionFactoryApi {
- private ExecutionTransitionFactory() {}
+ private final String execGroup;
- /** Returns a new {@link ExecutionTransitionFactory}. */
- public static ExecutionTransitionFactory create() {
- return new ExecutionTransitionFactory();
+ private ExecutionTransitionFactory(String execGroup) {
+ this.execGroup = execGroup;
}
/**
- * Returns either a new {@link ExecutionTransitionFactory} or a factory for the {@link
- * HostTransition}, depending on the value of {@code enableExecutionTransition}.
+ * Returns a new {@link ExecutionTransitionFactory} for the default {@link
+ * com.google.devtools.build.lib.packages.ExecGroup}.
*/
- public static TransitionFactory<AttributeTransitionData> create(
- boolean enableExecutionTransition) {
- if (enableExecutionTransition) {
- return create();
- } else {
- return HostTransition.createFactory();
- }
+ public static ExecutionTransitionFactory create() {
+ return new ExecutionTransitionFactory(DEFAULT_EXEC_GROUP_NAME);
+ }
+
+ /**
+ * Returns a new {@link ExecutionTransitionFactory} for the given {@link
+ * com.google.devtools.build.lib.packages.ExecGroup}.
+ */
+ public static ExecutionTransitionFactory create(String execGroup) {
+ return new ExecutionTransitionFactory(execGroup);
}
@Override
@@ -56,6 +62,10 @@
return new ExecutionTransition(data.executionPlatform());
}
+ public String getExecGroup() {
+ return execGroup;
+ }
+
@Override
public boolean isHost() {
return false;
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/skylark/SkylarkAttr.java b/src/main/java/com/google/devtools/build/lib/analysis/skylark/SkylarkAttr.java
index 5fa7eb8..bfb7f3f 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/skylark/SkylarkAttr.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/skylark/SkylarkAttr.java
@@ -257,6 +257,8 @@
builder.cfg(HostTransition.createFactory());
} else if (trans.equals("exec")) {
builder.cfg(ExecutionTransitionFactory.create());
+ } else if (trans instanceof ExecutionTransitionFactory) {
+ builder.cfg((ExecutionTransitionFactory) trans);
} else if (trans instanceof SplitTransition) {
builder.cfg(TransitionFactories.of((SplitTransition) trans));
} else if (trans instanceof TransitionFactory) {
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/skylark/StarlarkConfig.java b/src/main/java/com/google/devtools/build/lib/analysis/skylark/StarlarkConfig.java
index d345023..5b197c6 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/skylark/StarlarkConfig.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/skylark/StarlarkConfig.java
@@ -19,9 +19,11 @@
import static com.google.devtools.build.lib.packages.Type.STRING;
import static com.google.devtools.build.lib.packages.Type.STRING_LIST;
+import com.google.devtools.build.lib.analysis.config.ExecutionTransitionFactory;
import com.google.devtools.build.lib.packages.BuildSetting;
import com.google.devtools.build.lib.skylarkbuildapi.StarlarkConfigApi;
import com.google.devtools.build.lib.syntax.Printer;
+import com.google.devtools.build.lib.syntax.Starlark;
/** Starlark namespace for creating build settings. */
// TODO(juliexxia): Consider adding more types of build settings, specifically other label types.
@@ -48,6 +50,13 @@
}
@Override
+ public ExecutionTransitionFactory exec(Object execGroupUnchecked) {
+ return execGroupUnchecked == Starlark.NONE
+ ? ExecutionTransitionFactory.create()
+ : ExecutionTransitionFactory.create((String) execGroupUnchecked);
+ }
+
+ @Override
public void repr(Printer printer) {
printer.append("<config>");
}
diff --git a/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/SkylarkAttrApi.java b/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/SkylarkAttrApi.java
index f0618e5..badbe68 100644
--- a/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/SkylarkAttrApi.java
+++ b/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/SkylarkAttrApi.java
@@ -89,7 +89,7 @@
+ "attribute.";
String CONFIGURATION_ARG = "cfg";
- // TODO(bazel-team): Update when new Starlark-based configuration framework is implemented.
+ // TODO(b/151742236): Update when new Starlark-based configuration framework is implemented.
String CONFIGURATION_DOC =
"<a href=\"../rules.$DOC_EXT#configurations\">Configuration</a> of the attribute. It can be "
+ "either <code>\"host\"</code> or <code>\"target\"</code>.";
diff --git a/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/StarlarkConfigApi.java b/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/StarlarkConfigApi.java
index e4c32e1..53a91b5 100644
--- a/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/StarlarkConfigApi.java
+++ b/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/StarlarkConfigApi.java
@@ -18,6 +18,7 @@
import com.google.devtools.build.lib.skylarkinterface.SkylarkCallable;
import com.google.devtools.build.lib.skylarkinterface.SkylarkModule;
import com.google.devtools.build.lib.skylarkinterface.SkylarkModuleCategory;
+import com.google.devtools.build.lib.syntax.StarlarkSemantics.FlagIdentifier;
import com.google.devtools.build.lib.syntax.StarlarkValue;
/**
@@ -116,4 +117,29 @@
+ "key-value map of settings like {'cpu': 'ppc', 'copt': '-DFoo'}, this describes a "
+ "single entry in that map.")
interface BuildSettingApi extends StarlarkValue {}
+
+ @SkylarkCallable(
+ name = "exec",
+ doc = "<i>experimental</i> Creates an execution transition.",
+ enableOnlyWithFlag = FlagIdentifier.EXPERIMENTAL_EXEC_GROUPS,
+ parameters = {
+ @Param(
+ name = "exec_group",
+ type = String.class,
+ named = true,
+ noneable = true,
+ defaultValue = "None",
+ doc =
+ "The name of the exec group whose execution platform this transition will use. If"
+ + " not provided, this exec transition will use the target's default execution"
+ + " platform.")
+ })
+ ExecTransitionFactoryApi exec(Object execGroupUnchecked);
+
+ /** The api for exec transitions. */
+ @SkylarkModule(
+ name = "ExecTransitionFactory",
+ category = SkylarkModuleCategory.BUILTIN,
+ doc = "<i>experimental</i> an execution transition.")
+ interface ExecTransitionFactoryApi extends StarlarkValue {}
}
diff --git a/src/main/java/com/google/devtools/build/skydoc/fakebuildapi/ConfigApiFakes.java b/src/main/java/com/google/devtools/build/skydoc/fakebuildapi/ConfigApiFakes.java
new file mode 100644
index 0000000..94547d4
--- /dev/null
+++ b/src/main/java/com/google/devtools/build/skydoc/fakebuildapi/ConfigApiFakes.java
@@ -0,0 +1,41 @@
+// Copyright 2018 The Bazel Authors. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.google.devtools.build.skydoc.fakebuildapi;
+
+import com.google.devtools.build.lib.skylarkbuildapi.StarlarkConfigApi.BuildSettingApi;
+import com.google.devtools.build.lib.skylarkbuildapi.StarlarkConfigApi.ExecTransitionFactoryApi;
+import com.google.devtools.build.lib.syntax.Printer;
+
+/**
+ * Fakes for callables under the {@link
+ * com.google.devtools.build.lib.skylarkbuildapi.StarlarkConfigApi} module.
+ */
+public class ConfigApiFakes {
+
+ private ConfigApiFakes() {}
+
+ /** Fake implementation of {@link BuildSettingApi}. */
+ public static class FakeBuildSettingDescriptor implements BuildSettingApi {
+
+ @Override
+ public void repr(Printer printer) {}
+ }
+
+ /** Fake implementation of ExecTransitionFactoryApi. */
+ public static class FakeExecTransitionFactory implements ExecTransitionFactoryApi {
+ @Override
+ public void repr(Printer printer) {}
+ }
+}
diff --git a/src/main/java/com/google/devtools/build/skydoc/fakebuildapi/FakeBuildSettingDescriptor.java b/src/main/java/com/google/devtools/build/skydoc/fakebuildapi/FakeBuildSettingDescriptor.java
deleted file mode 100644
index 3566ed2..0000000
--- a/src/main/java/com/google/devtools/build/skydoc/fakebuildapi/FakeBuildSettingDescriptor.java
+++ /dev/null
@@ -1,26 +0,0 @@
-// Copyright 2018 The Bazel Authors. All rights reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package com.google.devtools.build.skydoc.fakebuildapi;
-
-import com.google.devtools.build.lib.skylarkbuildapi.StarlarkConfigApi.BuildSettingApi;
-import com.google.devtools.build.lib.syntax.Printer;
-
-/**
- * Fake implementation of {@link BuildSettingApi}.
- */
-public class FakeBuildSettingDescriptor implements BuildSettingApi {
- @Override
- public void repr(Printer printer) {}
-}
diff --git a/src/main/java/com/google/devtools/build/skydoc/fakebuildapi/FakeConfigApi.java b/src/main/java/com/google/devtools/build/skydoc/fakebuildapi/FakeConfigApi.java
index 627129d..1b52ab9 100644
--- a/src/main/java/com/google/devtools/build/skydoc/fakebuildapi/FakeConfigApi.java
+++ b/src/main/java/com/google/devtools/build/skydoc/fakebuildapi/FakeConfigApi.java
@@ -16,6 +16,8 @@
import com.google.devtools.build.lib.skylarkbuildapi.StarlarkConfigApi;
import com.google.devtools.build.lib.syntax.Printer;
+import com.google.devtools.build.skydoc.fakebuildapi.ConfigApiFakes.FakeBuildSettingDescriptor;
+import com.google.devtools.build.skydoc.fakebuildapi.ConfigApiFakes.FakeExecTransitionFactory;
/** Fake implementation of {@link StarlarkConfigApi}. */
public class FakeConfigApi implements StarlarkConfigApi {
@@ -41,5 +43,10 @@
}
@Override
+ public ExecTransitionFactoryApi exec(Object execGroup) {
+ return new FakeExecTransitionFactory();
+ }
+
+ @Override
public void repr(Printer printer) {}
}
diff --git a/src/test/java/com/google/devtools/build/lib/analysis/StarlarkExecGroupTest.java b/src/test/java/com/google/devtools/build/lib/analysis/StarlarkExecGroupTest.java
new file mode 100644
index 0000000..6eeeb23
--- /dev/null
+++ b/src/test/java/com/google/devtools/build/lib/analysis/StarlarkExecGroupTest.java
@@ -0,0 +1,185 @@
+// Copyright 2015 The Bazel Authors. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.google.devtools.build.lib.analysis;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import com.google.common.collect.ImmutableMap;
+import com.google.devtools.build.lib.analysis.config.BuildConfiguration;
+import com.google.devtools.build.lib.analysis.util.BuildViewTestCase;
+import com.google.devtools.build.lib.cmdline.Label;
+import com.google.devtools.build.lib.packages.Provider;
+import com.google.devtools.build.lib.packages.StarlarkProvider;
+import com.google.devtools.build.lib.packages.StructImpl;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+/**
+ * Test for exec groups. Functionality related to rule context tested in {@link
+ * com.google.devtools.build.lib.skylark.SkylarkRuleContextTest}.
+ */
+@RunWith(JUnit4.class)
+public class StarlarkExecGroupTest extends BuildViewTestCase {
+
+ @Before
+ public final void setUp() throws Exception {
+ setStarlarkSemanticsOptions("--experimental_exec_groups");
+ }
+
+ /**
+ * Sets up two toolchains types, each with a single toolchain implementation and a single
+ * exec_compatible_with platform.
+ *
+ * <p>toolchain_type_1 -> foo_toolchain -> exec_compatible_with platform_1 toolchain_type_2 ->
+ * bar_toolchain -> exec_compatible_with platform_2
+ */
+ private void createToolchainsAndPlatforms() throws Exception {
+ scratch.file(
+ "rule/test_toolchain.bzl",
+ "def _impl(ctx):",
+ " return [platform_common.ToolchainInfo()]",
+ "test_toolchain = rule(",
+ " implementation = _impl,",
+ ")");
+ scratch.file(
+ "rule/BUILD",
+ "exports_files(['test_toolchain/bzl'])",
+ "toolchain_type(name = 'toolchain_type_1')",
+ "toolchain_type(name = 'toolchain_type_2')");
+ scratch.file(
+ "toolchain/BUILD",
+ "load('//rule:test_toolchain.bzl', 'test_toolchain')",
+ "test_toolchain(",
+ " name = 'foo',",
+ ")",
+ "toolchain(",
+ " name = 'foo_toolchain',",
+ " toolchain_type = '//rule:toolchain_type_1',",
+ " target_compatible_with = ['//platform:constraint_1'],",
+ " exec_compatible_with = ['//platform:constraint_1'],",
+ " toolchain = ':foo',",
+ ")",
+ "test_toolchain(",
+ " name = 'bar',",
+ ")",
+ "toolchain(",
+ " name = 'bar_toolchain',",
+ " toolchain_type = '//rule:toolchain_type_2',",
+ " target_compatible_with = ['//platform:constraint_1'],",
+ " exec_compatible_with = ['//platform:constraint_2'],",
+ " toolchain = ':bar',",
+ ")");
+
+ scratch.file(
+ "platform/BUILD",
+ "constraint_setting(name = 'setting')",
+ "constraint_value(",
+ " name = 'constraint_1',",
+ " constraint_setting = ':setting',",
+ ")",
+ "constraint_value(",
+ " name = 'constraint_2',",
+ " constraint_setting = ':setting',",
+ ")",
+ "platform(",
+ " name = 'platform_1',",
+ " constraint_values = [':constraint_1'],",
+ ")",
+ "platform(",
+ " name = 'platform_2',",
+ " constraint_values = [':constraint_2'],",
+ ")");
+ }
+
+ @Test
+ public void testExecGroupTransition() throws Exception {
+ createToolchainsAndPlatforms();
+ useConfiguration(
+ "--extra_toolchains=//toolchain:foo_toolchain,//toolchain:bar_toolchain",
+ "--platforms=//platform:platform_1",
+ "--extra_execution_platforms=//platform:platform_1,//platform:platform_2");
+
+ scratch.file(
+ "test/defs.bzl",
+ "MyInfo = provider()",
+ "def _impl(ctx):",
+ " return [MyInfo(dep = ctx.attr.dep, exec_group_dep = ctx.attr.exec_group_dep)]",
+ "with_transition = rule(",
+ " implementation = _impl,",
+ " attrs = {",
+ " 'exec_group_dep': attr.label(cfg = config.exec('watermelon')),",
+ " 'dep': attr.label(cfg = 'exec'),",
+ " },",
+ " exec_groups = {",
+ " 'watermelon': exec_group(toolchains = ['//rule:toolchain_type_2']),",
+ " },",
+ " toolchains = ['//rule:toolchain_type_1'],",
+ ")",
+ "def _impl2(ctx):",
+ " return []",
+ "simple_rule = rule(implementation = _impl2)");
+ scratch.file(
+ "test/BUILD",
+ "load('//test:defs.bzl', 'with_transition', 'simple_rule')",
+ "with_transition(name = 'parent', dep = ':child', exec_group_dep = ':other-child')",
+ "simple_rule(name = 'child')",
+ "simple_rule(name = 'other-child')");
+
+ ConfiguredTarget target = getConfiguredTarget("//test:parent");
+ Provider.Key key =
+ new StarlarkProvider.Key(
+ Label.parseAbsolute("//test:defs.bzl", ImmutableMap.of()), "MyInfo");
+ BuildConfiguration dep =
+ getConfiguration((ConfiguredTarget) ((StructImpl) target.get(key)).getValue("dep"));
+ BuildConfiguration execGroupDep =
+ getConfiguration(
+ (ConfiguredTarget) ((StructImpl) target.get(key)).getValue("exec_group_dep"));
+
+ assertThat(dep.getOptions().get(PlatformOptions.class).platforms)
+ .containsExactly(Label.parseAbsoluteUnchecked("//platform:platform_1"));
+ assertThat(execGroupDep.getOptions().get(PlatformOptions.class).platforms)
+ .containsExactly(Label.parseAbsoluteUnchecked("//platform:platform_2"));
+ }
+
+ @Test
+ public void testInvalidExecGroupTransition() throws Exception {
+ scratch.file(
+ "test/defs.bzl",
+ "MyInfo = provider()",
+ "def _impl(ctx):",
+ " return []",
+ "with_transition = rule(",
+ " implementation = _impl,",
+ " attrs = {",
+ " 'exec_group_dep': attr.label(cfg = config.exec('blueberry')),",
+ " },",
+ ")",
+ "def _impl2(ctx):",
+ " return []",
+ "simple_rule = rule(implementation = _impl2)");
+ scratch.file(
+ "test/BUILD",
+ "load('//test:defs.bzl', 'with_transition', 'simple_rule')",
+ "with_transition(name = 'parent', exec_group_dep = ':child')",
+ "simple_rule(name = 'child')");
+
+ reporter.removeHandler(failFastHandler);
+ getConfiguredTarget("//test:parent");
+ assertContainsEvent(
+ "Attr 'exec_group_dep' declares a transition for non-existent exec group 'blueberry'");
+ }
+}