aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--src/main/java/com/google/devtools/build/lib/bazel/repository/MavenServerFunction.java2
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/ExternalPackageUtil.java91
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/repository/RepositoryDelegatorFunction.java2
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/repository/RepositoryFunction.java8
-rw-r--r--src/test/java/com/google/devtools/build/lib/BUILD24
-rw-r--r--src/test/java/com/google/devtools/build/lib/rules/AliasTest.java11
-rw-r--r--src/test/java/com/google/devtools/build/lib/rules/ExternalPackageUtilTest.java301
-rw-r--r--src/test/java/com/google/devtools/build/lib/rules/ToolchainTypeTest.java7
8 files changed, 422 insertions, 24 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/bazel/repository/MavenServerFunction.java b/src/main/java/com/google/devtools/build/lib/bazel/repository/MavenServerFunction.java
index f76039afb9..dd9c51ced6 100644
--- a/src/main/java/com/google/devtools/build/lib/bazel/repository/MavenServerFunction.java
+++ b/src/main/java/com/google/devtools/build/lib/bazel/repository/MavenServerFunction.java
@@ -67,7 +67,7 @@ public class MavenServerFunction implements SkyFunction {
String repository = (String) skyKey.argument();
Rule repositoryRule = null;
try {
- repositoryRule = ExternalPackageUtil.getRule(repository, env);
+ repositoryRule = ExternalPackageUtil.getRuleByName(repository, env);
} catch (ExternalPackageUtil.ExternalRuleNotFoundException ex) {
// Ignored. We throw a new one below.
}
diff --git a/src/main/java/com/google/devtools/build/lib/rules/ExternalPackageUtil.java b/src/main/java/com/google/devtools/build/lib/rules/ExternalPackageUtil.java
index bf28790912..5e395c04aa 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/ExternalPackageUtil.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/ExternalPackageUtil.java
@@ -14,6 +14,10 @@
package com.google.devtools.build.lib.rules;
+import com.google.common.base.Function;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Iterables;
import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.cmdline.LabelSyntaxException;
import com.google.devtools.build.lib.cmdline.RepositoryName;
@@ -33,16 +37,25 @@ import com.google.devtools.build.skyframe.SkyFunctionException;
import com.google.devtools.build.skyframe.SkyFunctionException.Transience;
import com.google.devtools.build.skyframe.SkyKey;
import java.io.IOException;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
import javax.annotation.Nullable;
/** Utility class to centralize looking up rules from the external package. */
public class ExternalPackageUtil {
- /** Uses a rule name to fetch the corresponding Rule from the external package. */
+ /**
+ * Loads the external package and then calls the selector to find matching rules.
+ *
+ * @param env the environment to use for lookups
+ * @param returnFirst whether to return only the first rule found
+ * @param selector the function to call to load rules
+ */
@Nullable
- public static Rule getRule(String ruleName, Environment env)
+ private static Set<Rule> getRules(
+ Environment env, boolean returnFirst, Function<Package, Iterable<Rule>> selector)
throws ExternalPackageException, InterruptedException {
-
SkyKey packageLookupKey = PackageLookupValue.key(Label.EXTERNAL_PACKAGE_IDENTIFIER);
PackageLookupValue packageLookupValue = (PackageLookupValue) env.getValue(packageLookupKey);
if (packageLookupValue == null) {
@@ -50,6 +63,7 @@ public class ExternalPackageUtil {
}
RootedPath workspacePath = packageLookupValue.getRootedPath(Label.EXTERNAL_PACKAGE_IDENTIFIER);
+ Set<Rule> rules = new HashSet<>();
SkyKey workspaceKey = WorkspaceFileValue.key(workspacePath);
do {
WorkspaceFileValue value = (WorkspaceFileValue) env.getValue(workspaceKey);
@@ -64,20 +78,77 @@ public class ExternalPackageUtil {
Label.EXTERNAL_PACKAGE_IDENTIFIER, "Could not load //external package"),
Transience.PERSISTENT);
}
- Rule rule = externalPackage.getRule(ruleName);
- if (rule != null) {
- return rule;
+ Iterable<Rule> results = selector.apply(externalPackage);
+ if (results != null) {
+ Iterables.addAll(rules, results);
+ if (returnFirst && !rules.isEmpty()) {
+ return ImmutableSet.of(Iterables.getFirst(results, null));
+ }
}
workspaceKey = value.next();
} while (workspaceKey != null);
- throw new ExternalRuleNotFoundException(ruleName);
+
+ return rules;
+ }
+
+ /** Uses a rule name to fetch the corresponding Rule from the external package. */
+ @Nullable
+ public static List<Rule> getRuleByRuleClass(final String ruleClassName, Environment env)
+ throws ExternalPackageException, InterruptedException {
+
+ Set<Rule> rules =
+ getRules(
+ env,
+ false,
+ new Function<Package, Iterable<Rule>>() {
+ @Nullable
+ @Override
+ public Iterable<Rule> apply(Package externalPackage) {
+ return externalPackage.getRulesMatchingRuleClass(ruleClassName);
+ }
+ });
+
+ if (env.valuesMissing()) {
+ return null;
+ }
+ return ImmutableList.copyOf(rules);
+ }
+
+ /** Uses a rule name to fetch the corresponding Rule from the external package. */
+ @Nullable
+ public static Rule getRuleByName(final String ruleName, Environment env)
+ throws ExternalPackageException, InterruptedException {
+
+ Set<Rule> rules =
+ getRules(
+ env,
+ true,
+ new Function<Package, Iterable<Rule>>() {
+ @Nullable
+ @Override
+ public Iterable<Rule> apply(Package externalPackage) {
+ Rule rule = externalPackage.getRule(ruleName);
+ if (rule == null) {
+ return null;
+ }
+ return ImmutableList.of(rule);
+ }
+ });
+
+ if (env.valuesMissing()) {
+ return null;
+ }
+ if (rules == null || rules.isEmpty()) {
+ throw new ExternalRuleNotFoundException(ruleName);
+ }
+ return Iterables.getFirst(rules, null);
}
@Nullable
public static Rule getRule(String ruleName, @Nullable String ruleClassName, Environment env)
throws ExternalPackageException, InterruptedException {
try {
- return getRule(RepositoryName.create("@" + ruleName), ruleClassName, env);
+ return getRepository(RepositoryName.create("@" + ruleName), ruleClassName, env);
} catch (LabelSyntaxException e) {
throw new ExternalPackageException(
new IOException("Invalid rule name " + ruleName), Transience.PERSISTENT);
@@ -91,10 +162,10 @@ public class ExternalPackageUtil {
* name.
*/
@Nullable
- public static Rule getRule(
+ public static Rule getRepository(
RepositoryName repositoryName, @Nullable String ruleClassName, Environment env)
throws ExternalPackageException, InterruptedException {
- Rule rule = getRule(repositoryName.strippedName(), env);
+ Rule rule = getRuleByName(repositoryName.strippedName(), env);
Preconditions.checkState(
rule == null || ruleClassName == null || rule.getRuleClass().equals(ruleClassName),
"Got %s, was expecting a %s",
diff --git a/src/main/java/com/google/devtools/build/lib/rules/repository/RepositoryDelegatorFunction.java b/src/main/java/com/google/devtools/build/lib/rules/repository/RepositoryDelegatorFunction.java
index 80e0cdfe75..1ab88232c0 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/repository/RepositoryDelegatorFunction.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/repository/RepositoryDelegatorFunction.java
@@ -116,7 +116,7 @@ public final class RepositoryDelegatorFunction implements SkyFunction {
Rule rule;
try {
- rule = ExternalPackageUtil.getRule(repositoryName, null, env);
+ rule = ExternalPackageUtil.getRepository(repositoryName, null, env);
} catch (ExternalPackageUtil.ExternalRuleNotFoundException e) {
return RepositoryDirectoryValue.NO_SUCH_REPOSITORY_VALUE;
}
diff --git a/src/main/java/com/google/devtools/build/lib/rules/repository/RepositoryFunction.java b/src/main/java/com/google/devtools/build/lib/rules/repository/RepositoryFunction.java
index 036cd7b056..16c29673ba 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/repository/RepositoryFunction.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/repository/RepositoryFunction.java
@@ -394,9 +394,10 @@ public abstract class RepositoryFunction {
try {
// Add a dependency to the repository rule. RepositoryDirectoryValue does add this
- // dependency already but we want to catch RepositoryNotFoundException, so invoke #getRule
+ // dependency already but we want to catch RepositoryNotFoundException, so invoke
+ // #getRuleByName
// first.
- Rule rule = ExternalPackageUtil.getRule(repositoryName, env);
+ Rule rule = ExternalPackageUtil.getRuleByName(repositoryName, env);
if (rule == null) {
return;
}
@@ -421,7 +422,8 @@ public abstract class RepositoryFunction {
}
} catch (ExternalPackageUtil.ExternalRuleNotFoundException ex) {
// The repository we are looking for does not exist so we should depend on the whole
- // WORKSPACE file. In that case, the call to RepositoryFunction#getRule(String, Environment)
+ // WORKSPACE file. In that case, the call to RepositoryFunction#getRuleByName(String,
+ // Environment)
// already requested all repository functions from the WORKSPACE file from Skyframe as part
// of the resolution. Therefore we are safe to ignore that Exception.
return;
diff --git a/src/test/java/com/google/devtools/build/lib/BUILD b/src/test/java/com/google/devtools/build/lib/BUILD
index 92c9ee2429..7a6fa64457 100644
--- a/src/test/java/com/google/devtools/build/lib/BUILD
+++ b/src/test/java/com/google/devtools/build/lib/BUILD
@@ -1223,6 +1223,30 @@ java_test(
],
)
+java_test(
+ name = "rules-tests",
+ srcs = glob(["rules/*.java"]),
+ test_class = "com.google.devtools.build.lib.AllTests",
+ deps = [
+ ":actions_testutil",
+ ":analysis_testutil",
+ "//src/main/java/com/google/devtools/build/lib:build-base",
+ "//src/main/java/com/google/devtools/build/lib:collect",
+ "//src/main/java/com/google/devtools/build/lib:events",
+ "//src/main/java/com/google/devtools/build/lib:io",
+ "//src/main/java/com/google/devtools/build/lib:packages-internal",
+ "//src/main/java/com/google/devtools/build/lib:proto-rules",
+ "//src/main/java/com/google/devtools/build/lib/actions",
+ "//src/main/java/com/google/devtools/build/lib/rules/cpp",
+ "//src/main/java/com/google/devtools/build/skyframe",
+ "//src/main/java/com/google/devtools/build/skyframe:skyframe-objects",
+ "//third_party:auto_value",
+ "//third_party:guava",
+ "//third_party:junit4",
+ "//third_party:truth",
+ ],
+)
+
java_binary(
name = "MockSubprocess",
srcs = ["windows/MockSubprocess.java"],
diff --git a/src/test/java/com/google/devtools/build/lib/rules/AliasTest.java b/src/test/java/com/google/devtools/build/lib/rules/AliasTest.java
index 4b456a358c..029998968f 100644
--- a/src/test/java/com/google/devtools/build/lib/rules/AliasTest.java
+++ b/src/test/java/com/google/devtools/build/lib/rules/AliasTest.java
@@ -26,14 +26,13 @@ import com.google.devtools.build.lib.analysis.util.BuildViewTestCase;
import com.google.devtools.build.lib.collect.nestedset.NestedSet;
import com.google.devtools.build.lib.packages.License.LicenseType;
import com.google.devtools.build.lib.rules.cpp.CppCompilationContext;
-
-import org.junit.Test;
-
import java.util.Set;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
-/**
- * Unit tests for the <code>alias</code> rule.
- */
+/** Unit tests for the <code>alias</code> rule. */
+@RunWith(JUnit4.class)
public class AliasTest extends BuildViewTestCase {
@Test
public void smoke() throws Exception {
diff --git a/src/test/java/com/google/devtools/build/lib/rules/ExternalPackageUtilTest.java b/src/test/java/com/google/devtools/build/lib/rules/ExternalPackageUtilTest.java
new file mode 100644
index 0000000000..27c2e775c6
--- /dev/null
+++ b/src/test/java/com/google/devtools/build/lib/rules/ExternalPackageUtilTest.java
@@ -0,0 +1,301 @@
+// Copyright 2017 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.rules;
+
+import static com.google.common.truth.Truth.assertThat;
+import static com.google.devtools.build.skyframe.EvaluationResultSubjectFactory.assertThatEvaluationResult;
+
+import com.google.auto.value.AutoValue;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
+import com.google.devtools.build.lib.analysis.BlazeDirectories;
+import com.google.devtools.build.lib.analysis.util.AnalysisMock;
+import com.google.devtools.build.lib.analysis.util.BuildViewTestCase;
+import com.google.devtools.build.lib.cmdline.PackageIdentifier;
+import com.google.devtools.build.lib.events.NullEventHandler;
+import com.google.devtools.build.lib.packages.PackageFactory;
+import com.google.devtools.build.lib.packages.PackageFactory.EnvironmentExtension;
+import com.google.devtools.build.lib.packages.Rule;
+import com.google.devtools.build.lib.packages.RuleClassProvider;
+import com.google.devtools.build.lib.pkgcache.PathPackageLocator;
+import com.google.devtools.build.lib.skyframe.ExternalFilesHelper;
+import com.google.devtools.build.lib.skyframe.ExternalFilesHelper.ExternalFileAction;
+import com.google.devtools.build.lib.skyframe.ExternalPackageFunction;
+import com.google.devtools.build.lib.skyframe.FileFunction;
+import com.google.devtools.build.lib.skyframe.FileStateFunction;
+import com.google.devtools.build.lib.skyframe.LocalRepositoryLookupFunction;
+import com.google.devtools.build.lib.skyframe.PackageLookupFunction;
+import com.google.devtools.build.lib.skyframe.PackageLookupFunction.CrossRepositoryLabelViolationStrategy;
+import com.google.devtools.build.lib.skyframe.PackageLookupValue.BuildFileName;
+import com.google.devtools.build.lib.skyframe.PrecomputedValue;
+import com.google.devtools.build.lib.skyframe.SkyFunctions;
+import com.google.devtools.build.lib.skyframe.SkyframeExecutor;
+import com.google.devtools.build.lib.skyframe.WorkspaceASTFunction;
+import com.google.devtools.build.lib.skyframe.WorkspaceFileFunction;
+import com.google.devtools.build.lib.util.io.TimestampGranularityMonitor;
+import com.google.devtools.build.skyframe.EvaluationResult;
+import com.google.devtools.build.skyframe.InMemoryMemoizingEvaluator;
+import com.google.devtools.build.skyframe.LegacySkyKey;
+import com.google.devtools.build.skyframe.MemoizingEvaluator;
+import com.google.devtools.build.skyframe.RecordingDifferencer;
+import com.google.devtools.build.skyframe.SequentialBuildDriver;
+import com.google.devtools.build.skyframe.SkyFunction;
+import com.google.devtools.build.skyframe.SkyFunctionException;
+import com.google.devtools.build.skyframe.SkyFunctionName;
+import com.google.devtools.build.skyframe.SkyKey;
+import com.google.devtools.build.skyframe.SkyValue;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.atomic.AtomicReference;
+import javax.annotation.Nullable;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+/** Unit tests for {@link ExternalPackageUtil}. */
+@RunWith(JUnit4.class)
+public class ExternalPackageUtilTest extends BuildViewTestCase {
+
+ private SequentialBuildDriver driver;
+
+ @Before
+ public void createEnvironment() {
+ AnalysisMock analysisMock = AnalysisMock.get();
+ AtomicReference<PathPackageLocator> pkgLocator =
+ new AtomicReference<>(new PathPackageLocator(outputBase, ImmutableList.of(rootDirectory)));
+ AtomicReference<ImmutableSet<PackageIdentifier>> deletedPackages =
+ new AtomicReference<>(ImmutableSet.<PackageIdentifier>of());
+ BlazeDirectories directories =
+ new BlazeDirectories(
+ rootDirectory, outputBase, rootDirectory, analysisMock.getProductName());
+ ExternalFilesHelper externalFilesHelper =
+ new ExternalFilesHelper(
+ pkgLocator,
+ ExternalFileAction.DEPEND_ON_EXTERNAL_PKG_FOR_EXTERNAL_REPO_PATHS,
+ directories);
+
+ Map<SkyFunctionName, SkyFunction> skyFunctions = new HashMap<>();
+ skyFunctions.put(
+ SkyFunctions.PACKAGE_LOOKUP,
+ new PackageLookupFunction(
+ deletedPackages,
+ CrossRepositoryLabelViolationStrategy.ERROR,
+ ImmutableList.of(BuildFileName.BUILD_DOT_BAZEL, BuildFileName.BUILD)));
+ skyFunctions.put(
+ SkyFunctions.FILE_STATE,
+ new FileStateFunction(
+ new AtomicReference<TimestampGranularityMonitor>(), externalFilesHelper));
+ skyFunctions.put(SkyFunctions.FILE, new FileFunction(pkgLocator));
+ RuleClassProvider ruleClassProvider = analysisMock.createRuleClassProvider();
+ skyFunctions.put(SkyFunctions.WORKSPACE_AST, new WorkspaceASTFunction(ruleClassProvider));
+ skyFunctions.put(
+ SkyFunctions.WORKSPACE_FILE,
+ new WorkspaceFileFunction(
+ ruleClassProvider,
+ analysisMock
+ .getPackageFactoryBuilderForTesting()
+ .setEnvironmentExtensions(
+ ImmutableList.<EnvironmentExtension>of(
+ new PackageFactory.EmptyEnvironmentExtension()))
+ .build(ruleClassProvider, scratch.getFileSystem()),
+ directories));
+ skyFunctions.put(SkyFunctions.EXTERNAL_PACKAGE, new ExternalPackageFunction());
+ skyFunctions.put(SkyFunctions.LOCAL_REPOSITORY_LOOKUP, new LocalRepositoryLookupFunction());
+
+ // Helper Skyfunctions to call ExternalPackageUtil.
+ skyFunctions.put(GET_RULE_BY_NAME_FUNCTION, new GetRuleByNameFunction());
+ skyFunctions.put(GET_RULE_BY_RULE_CLASS_FUNCTION, new GetRuleByRuleClassFunction());
+
+ RecordingDifferencer differencer = new RecordingDifferencer();
+ MemoizingEvaluator evaluator = new InMemoryMemoizingEvaluator(skyFunctions, differencer);
+ driver = new SequentialBuildDriver(evaluator);
+ PrecomputedValue.PATH_PACKAGE_LOCATOR.set(differencer, pkgLocator.get());
+ }
+
+ @Test
+ public void getRuleByName() throws Exception {
+ scratch.overwriteFile("WORKSPACE", "http_archive(name = 'foo', url = 'http://foo')");
+ invalidatePackages(false);
+
+ SkyKey key = getRuleByNameKey("foo");
+ EvaluationResult<GetRuleByNameValue> result = getRuleByName(key);
+
+ assertThatEvaluationResult(result).hasNoError();
+
+ Rule rule = result.get(key).rule();
+ assertThat(rule).isNotNull();
+ assertThat(rule.getName()).isEqualTo("foo");
+ }
+
+ @Test
+ public void getRuleByName_missing() throws Exception {
+ scratch.overwriteFile("WORKSPACE", "http_archive(name = 'foo', url = 'http://foo')");
+ invalidatePackages(false);
+
+ SkyKey key = getRuleByNameKey("bar");
+ EvaluationResult<GetRuleByNameValue> result = getRuleByName(key);
+
+ assertThatEvaluationResult(result)
+ .hasErrorEntryForKeyThat(key)
+ .hasExceptionThat()
+ .hasMessageThat()
+ .contains("The rule named 'bar' could not be resolved");
+ }
+
+ @Test
+ public void getRuleByRuleClass() throws Exception {
+ scratch.overwriteFile(
+ "WORKSPACE",
+ "http_archive(name = 'foo', url = 'http://foo')",
+ "http_archive(name = 'bar', url = 'http://bar')");
+ invalidatePackages(false);
+
+ SkyKey key = getRuleByRuleClassKey("http_archive");
+ EvaluationResult<GetRuleByRuleClassValue> result = getRuleByRuleClass(key);
+
+ assertThatEvaluationResult(result).hasNoError();
+
+ List<Rule> rules = result.get(key).rules();
+ assertThat(rules).isNotNull();
+ assertThat(rules).hasSize(2);
+
+ Set<String> names = new HashSet<>();
+ for (Rule rule : rules) {
+ names.add(rule.getName());
+ }
+
+ assertThat(names).containsExactly("foo", "bar");
+ }
+
+ @Test
+ public void getRuleByRuleClass_none() throws Exception {
+ scratch.overwriteFile(
+ "WORKSPACE",
+ "http_archive(name = 'foo', url = 'http://foo')",
+ "http_archive(name = 'bar', url = 'http://bar')");
+ invalidatePackages(false);
+
+ SkyKey key = getRuleByRuleClassKey("new_git_repository");
+ EvaluationResult<GetRuleByRuleClassValue> result = getRuleByRuleClass(key);
+
+ assertThatEvaluationResult(result).hasNoError();
+
+ List<Rule> rules = result.get(key).rules();
+ assertThat(rules).isNotNull();
+ assertThat(rules).isEmpty();
+ }
+
+ // HELPER SKYFUNCTIONS
+
+ // GetRuleByName.
+ SkyKey getRuleByNameKey(String ruleName) {
+ return LegacySkyKey.create(GET_RULE_BY_NAME_FUNCTION, ruleName);
+ }
+
+ EvaluationResult<GetRuleByNameValue> getRuleByName(SkyKey key) throws InterruptedException {
+ return driver.<GetRuleByNameValue>evaluate(
+ ImmutableList.of(key),
+ false,
+ SkyframeExecutor.DEFAULT_THREAD_COUNT,
+ NullEventHandler.INSTANCE);
+ }
+
+ private static final SkyFunctionName GET_RULE_BY_NAME_FUNCTION =
+ SkyFunctionName.create("GET_RULE_BY_NAME");
+
+ @AutoValue
+ abstract static class GetRuleByNameValue implements SkyValue {
+ abstract Rule rule();
+
+ static GetRuleByNameValue create(Rule rule) {
+ return new AutoValue_ExternalPackageUtilTest_GetRuleByNameValue(rule);
+ }
+ }
+
+ private static final class GetRuleByNameFunction implements SkyFunction {
+
+ @Nullable
+ @Override
+ public SkyValue compute(SkyKey skyKey, Environment env)
+ throws SkyFunctionException, InterruptedException {
+ String ruleName = (String) skyKey.argument();
+
+ Rule rule = ExternalPackageUtil.getRuleByName(ruleName, env);
+ if (rule == null) {
+ return null;
+ }
+ return GetRuleByNameValue.create(rule);
+ }
+
+ @Nullable
+ @Override
+ public String extractTag(SkyKey skyKey) {
+ return null;
+ }
+ }
+
+ // GetRuleByRuleClass.
+ SkyKey getRuleByRuleClassKey(String ruleClass) {
+ return LegacySkyKey.create(GET_RULE_BY_RULE_CLASS_FUNCTION, ruleClass);
+ }
+
+ EvaluationResult<GetRuleByRuleClassValue> getRuleByRuleClass(SkyKey key)
+ throws InterruptedException {
+ return driver.<GetRuleByRuleClassValue>evaluate(
+ ImmutableList.of(key),
+ false,
+ SkyframeExecutor.DEFAULT_THREAD_COUNT,
+ NullEventHandler.INSTANCE);
+ }
+
+ private static final SkyFunctionName GET_RULE_BY_RULE_CLASS_FUNCTION =
+ SkyFunctionName.create("GET_RULE_BY_RULE_CLASS");
+
+ @AutoValue
+ abstract static class GetRuleByRuleClassValue implements SkyValue {
+ abstract ImmutableList<Rule> rules();
+
+ static GetRuleByRuleClassValue create(Iterable<Rule> rules) {
+ return new AutoValue_ExternalPackageUtilTest_GetRuleByRuleClassValue(
+ ImmutableList.copyOf(rules));
+ }
+ }
+
+ private static final class GetRuleByRuleClassFunction implements SkyFunction {
+
+ @Nullable
+ @Override
+ public SkyValue compute(SkyKey skyKey, Environment env)
+ throws SkyFunctionException, InterruptedException {
+ String ruleName = (String) skyKey.argument();
+
+ List<Rule> rules = ExternalPackageUtil.getRuleByRuleClass(ruleName, env);
+ if (rules == null) {
+ return null;
+ }
+ return GetRuleByRuleClassValue.create(rules);
+ }
+
+ @Nullable
+ @Override
+ public String extractTag(SkyKey skyKey) {
+ return null;
+ }
+ }
+}
diff --git a/src/test/java/com/google/devtools/build/lib/rules/ToolchainTypeTest.java b/src/test/java/com/google/devtools/build/lib/rules/ToolchainTypeTest.java
index e9cbf36307..a4990af350 100644
--- a/src/test/java/com/google/devtools/build/lib/rules/ToolchainTypeTest.java
+++ b/src/test/java/com/google/devtools/build/lib/rules/ToolchainTypeTest.java
@@ -18,10 +18,11 @@ import static com.google.common.truth.Truth.assertThat;
import com.google.devtools.build.lib.analysis.ConfiguredTarget;
import com.google.devtools.build.lib.analysis.util.BuildViewTestCase;
import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
-/**
- * Unit tests for the {@code toolchain_type} rule.
- */
+/** Unit tests for the {@code toolchain_type} rule. */
+@RunWith(JUnit4.class)
public class ToolchainTypeTest extends BuildViewTestCase {
@Test
public void testSmoke() throws Exception {