aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/main/java/com/google/devtools/build
diff options
context:
space:
mode:
authorGravatar juliexxia <juliexxia@google.com>2017-11-17 15:05:14 -0800
committerGravatar Copybara-Service <copybara-piper@google.com>2017-11-17 15:06:33 -0800
commit2af2bff08c2fab136ea0927242bd4f3fe05456bf (patch)
tree99d1a217f7d249c390a7bb8cf89949b9dad815c4 /src/main/java/com/google/devtools/build
parentc79c59c9e9cb7055d9b2446028a80eb2b40931be (diff)
Add --host_deps custom filtering to configuredtargetqueryenvironment.
Notable implementation details: - split the flag into --experimental_post_build_query and --experimental_query_options - allow --nohost_dep filtering to be applied to query targets configured in the host configuration (only returns deps also in the host configuration so allow deps as long as it never sees a transition from a host config to a non-host config) PiperOrigin-RevId: 176165870
Diffstat (limited to 'src/main/java/com/google/devtools/build')
-rw-r--r--src/main/java/com/google/devtools/build/lib/BUILD2
-rw-r--r--src/main/java/com/google/devtools/build/lib/buildtool/BuildRequestOptions.java8
-rw-r--r--src/main/java/com/google/devtools/build/lib/buildtool/BuildTool.java13
-rw-r--r--src/main/java/com/google/devtools/build/lib/query2/BUILD44
-rw-r--r--src/main/java/com/google/devtools/build/lib/query2/ConfiguredTargetQueryEnvironment.java119
5 files changed, 164 insertions, 22 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/BUILD b/src/main/java/com/google/devtools/build/lib/BUILD
index e5ac63d2c7..a84bae7a83 100644
--- a/src/main/java/com/google/devtools/build/lib/BUILD
+++ b/src/main/java/com/google/devtools/build/lib/BUILD
@@ -598,6 +598,7 @@ java_library(
"//src/main/java/com/google/devtools/build/lib:runtime",
"//src/main/java/com/google/devtools/build/lib:util",
"//src/main/java/com/google/devtools/build/lib/query2",
+ "//src/main/java/com/google/devtools/build/lib/query2:abstract-blaze-query-env",
"//src/main/java/com/google/devtools/build/lib/query2:query-engine",
"//src/main/java/com/google/devtools/common/options",
"//third_party:guava",
@@ -1014,6 +1015,7 @@ java_library(
"//src/main/java/com/google/devtools/build/lib/profiler:profiler-output",
"//src/main/java/com/google/devtools/build/lib/profiler/memory:allocationtracker",
"//src/main/java/com/google/devtools/build/lib/query2",
+ "//src/main/java/com/google/devtools/build/lib/query2:abstract-blaze-query-env",
"//src/main/java/com/google/devtools/build/lib/query2:query-engine",
"//src/main/java/com/google/devtools/build/lib/query2:query-output",
"//src/main/java/com/google/devtools/build/lib/shell",
diff --git a/src/main/java/com/google/devtools/build/lib/buildtool/BuildRequestOptions.java b/src/main/java/com/google/devtools/build/lib/buildtool/BuildRequestOptions.java
index a771237955..fc438aa1e1 100644
--- a/src/main/java/com/google/devtools/build/lib/buildtool/BuildRequestOptions.java
+++ b/src/main/java/com/google/devtools/build/lib/buildtool/BuildRequestOptions.java
@@ -210,6 +210,14 @@ public class BuildRequestOptions extends OptionsBase {
public String queryExpression;
@Option(
+ name = "experimental_query_options",
+ defaultValue = "null",
+ documentationCategory = OptionDocumentationCategory.LOGGING,
+ effectTags = {OptionEffectTag.UNKNOWN}
+ )
+ public String queryOptions;
+
+ @Option(
name = "analyze",
defaultValue = "true",
documentationCategory = OptionDocumentationCategory.UNDOCUMENTED,
diff --git a/src/main/java/com/google/devtools/build/lib/buildtool/BuildTool.java b/src/main/java/com/google/devtools/build/lib/buildtool/BuildTool.java
index d785f51ee6..7607c16f97 100644
--- a/src/main/java/com/google/devtools/build/lib/buildtool/BuildTool.java
+++ b/src/main/java/com/google/devtools/build/lib/buildtool/BuildTool.java
@@ -77,6 +77,7 @@ import com.google.devtools.build.skyframe.WalkableGraph;
import com.google.devtools.common.options.OptionsParsingException;
import java.io.IOException;
import java.util.Collection;
+import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;
@@ -422,6 +423,8 @@ public final class BuildTool {
runtime.getRuleClassProvider(),
env.getSkyframeExecutor());
+ String queryExpr = request.getBuildOptions().queryExpression;
+
// Currently, CTQE assumes that all top level targets take on the same default config and we
// don't have the ability to map multiple configs to multiple top level targets.
// So for now, we only allow multiple targets when they all carry the same config.
@@ -431,7 +434,7 @@ public final class BuildTool {
for (TargetAndConfiguration targAndConfig : topLevelTargetsWithConfigs) {
if (!targAndConfig.getConfiguration().equals(sampleConfig)) {
throw new QueryException(
- new TargetLiteral(request.getBuildOptions().queryExpression),
+ new TargetLiteral(queryExpr),
String.format(
"Top level targets %s and %s have different configurations (top level "
+ "targets with different configurations is not supported)",
@@ -441,6 +444,7 @@ public final class BuildTool {
WalkableGraph walkableGraph =
SkyframeExecutorWrappingWalkableGraph.of(env.getSkyframeExecutor());
+ String queryOptions = request.getBuildOptions().queryOptions;
ConfiguredTargetQueryEnvironment configuredTargetQueryEnvironment =
new ConfiguredTargetQueryEnvironment(
request.getViewOptions().keepGoing,
@@ -450,9 +454,12 @@ public final class BuildTool {
configurations.getHostConfiguration(),
env.newTargetPatternEvaluator().getOffset(),
env.getPackageManager().getPackagePath(),
- () -> walkableGraph);
+ () -> walkableGraph,
+ queryOptions == null
+ ? new HashSet<>()
+ : ConfiguredTargetQueryEnvironment.parseOptions(queryOptions).toSettings());
configuredTargetQueryEnvironment.evaluateQuery(
- request.getBuildOptions().queryExpression,
+ queryExpr,
new ThreadSafeOutputFormatterCallback<ConfiguredTarget>() {
@Override
public void processOutput(Iterable<ConfiguredTarget> partialResult)
diff --git a/src/main/java/com/google/devtools/build/lib/query2/BUILD b/src/main/java/com/google/devtools/build/lib/query2/BUILD
index 5637e6efcf..8f143033ba 100644
--- a/src/main/java/com/google/devtools/build/lib/query2/BUILD
+++ b/src/main/java/com/google/devtools/build/lib/query2/BUILD
@@ -8,9 +8,18 @@ filegroup(
java_library(
name = "query2",
- srcs = glob(["*.java"]),
+ srcs = glob(
+ ["*.java"],
+ exclude = [
+ "AbstractBlazeQueryEnvironment.java",
+ "FakeLoadTarget.java",
+ ],
+ ),
deps = [
+ ":abstract-blaze-query-env",
+ ":fake-load-target",
":query-engine",
+ ":query-output",
"//src/main/java/com/google/devtools/build/lib:build-base",
"//src/main/java/com/google/devtools/build/lib:events",
"//src/main/java/com/google/devtools/build/lib:packages-internal",
@@ -23,6 +32,7 @@ java_library(
"//src/main/java/com/google/devtools/build/lib/vfs",
"//src/main/java/com/google/devtools/build/skyframe",
"//src/main/java/com/google/devtools/build/skyframe:skyframe-objects",
+ "//src/main/java/com/google/devtools/common/options",
"//third_party:guava",
"//third_party:jsr305",
],
@@ -32,8 +42,9 @@ java_library(
name = "query-output",
srcs = glob(["output/*.java"]),
deps = [
+ ":abstract-blaze-query-env",
+ ":fake-load-target",
":query-engine",
- ":query2",
"//src/main/java/com/google/devtools/build/lib:events",
"//src/main/java/com/google/devtools/build/lib:packages-internal",
"//src/main/java/com/google/devtools/build/lib:util",
@@ -47,6 +58,35 @@ java_library(
],
)
+java_library(
+ name = "abstract-blaze-query-env",
+ srcs = [
+ "AbstractBlazeQueryEnvironment.java",
+ ],
+ deps = [
+ ":query-engine",
+ "//src/main/java/com/google/devtools/build/lib:events",
+ "//src/main/java/com/google/devtools/build/lib:packages-internal",
+ "//src/main/java/com/google/devtools/build/lib:util",
+ "//third_party:guava",
+ "//third_party:jsr305",
+ ],
+)
+
+java_library(
+ name = "fake-load-target",
+ srcs = [
+ "FakeLoadTarget.java",
+ ],
+ deps = [
+ "//src/main/java/com/google/devtools/build/lib:events",
+ "//src/main/java/com/google/devtools/build/lib:packages-internal",
+ "//src/main/java/com/google/devtools/build/lib:util",
+ "//third_party:guava",
+ "//third_party:jsr305",
+ ],
+)
+
# Query library.
java_library(
name = "query-engine",
diff --git a/src/main/java/com/google/devtools/build/lib/query2/ConfiguredTargetQueryEnvironment.java b/src/main/java/com/google/devtools/build/lib/query2/ConfiguredTargetQueryEnvironment.java
index 3628a76ad1..def3b9d4f3 100644
--- a/src/main/java/com/google/devtools/build/lib/query2/ConfiguredTargetQueryEnvironment.java
+++ b/src/main/java/com/google/devtools/build/lib/query2/ConfiguredTargetQueryEnvironment.java
@@ -23,13 +23,16 @@ import com.google.common.util.concurrent.MoreExecutors;
import com.google.devtools.build.lib.analysis.ConfiguredTarget;
import com.google.devtools.build.lib.analysis.LabelAndConfiguration;
import com.google.devtools.build.lib.analysis.config.BuildConfiguration;
+import com.google.devtools.build.lib.analysis.configuredtargets.RuleConfiguredTarget;
import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.cmdline.TargetParsingException;
import com.google.devtools.build.lib.cmdline.TargetPattern;
import com.google.devtools.build.lib.cmdline.TargetPattern.Type;
+import com.google.devtools.build.lib.collect.compacthashset.CompactHashSet;
import com.google.devtools.build.lib.concurrent.MultisetSemaphore;
import com.google.devtools.build.lib.events.Event;
import com.google.devtools.build.lib.events.ExtendedEventHandler;
+import com.google.devtools.build.lib.packages.DependencyFilter;
import com.google.devtools.build.lib.packages.Rule;
import com.google.devtools.build.lib.packages.Target;
import com.google.devtools.build.lib.pkgcache.FilteringPolicies;
@@ -48,6 +51,7 @@ import com.google.devtools.build.lib.query2.engine.QueryUtil.ThreadSafeMutableKe
import com.google.devtools.build.lib.query2.engine.QueryUtil.UniquifierImpl;
import com.google.devtools.build.lib.query2.engine.ThreadSafeOutputFormatterCallback;
import com.google.devtools.build.lib.query2.engine.Uniquifier;
+import com.google.devtools.build.lib.query2.output.QueryOptions;
import com.google.devtools.build.lib.skyframe.ConfiguredTargetKey;
import com.google.devtools.build.lib.skyframe.ConfiguredTargetValue;
import com.google.devtools.build.lib.skyframe.GraphBackedRecursivePackageProvider;
@@ -57,14 +61,18 @@ import com.google.devtools.build.lib.skyframe.TargetPatternValue;
import com.google.devtools.build.lib.skyframe.TargetPatternValue.TargetPatternKey;
import com.google.devtools.build.skyframe.SkyKey;
import com.google.devtools.build.skyframe.WalkableGraph;
+import com.google.devtools.common.options.OptionsParser;
+import com.google.devtools.common.options.OptionsParsingException;
import java.io.IOException;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Collection;
-import java.util.EnumSet;
+import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
+import java.util.Set;
import java.util.function.Function;
import java.util.function.Supplier;
import java.util.stream.Collectors;
@@ -132,15 +140,9 @@ public class ConfiguredTargetQueryEnvironment
BuildConfiguration hostConfiguration,
String parserPrefix,
PathPackageLocator pkgPath,
- Supplier<WalkableGraph> walkableGraphSupplier) {
- super(
- keepGoing,
- true,
- Rule.ALL_LABELS,
- eventHandler,
- // TODO(janakr): decide whether to support host and implicit dep filtering.
- EnumSet.noneOf(Setting.class),
- extraFunctions);
+ Supplier<WalkableGraph> walkableGraphSupplier,
+ Set<Setting> settings) {
+ super(keepGoing, true, Rule.ALL_LABELS, eventHandler, settings, extraFunctions);
this.defaultTargetConfiguration = defaultTargetConfiguration;
this.hostConfiguration = hostConfiguration;
this.parserPrefix = parserPrefix;
@@ -148,7 +150,7 @@ public class ConfiguredTargetQueryEnvironment
this.walkableGraphSupplier = walkableGraphSupplier;
}
- private void beforeEvaluateQuery() throws InterruptedException {
+ private void beforeEvaluateQuery() throws InterruptedException, QueryException {
graph = walkableGraphSupplier.get();
GraphBackedRecursivePackageProvider graphBackedRecursivePackageProvider =
new GraphBackedRecursivePackageProvider(graph, ALL_PATTERNS, pkgPath);
@@ -158,6 +160,20 @@ public class ConfiguredTargetQueryEnvironment
eventHandler,
FilteringPolicies.NO_FILTER,
MultisetSemaphore.unbounded());
+ checkSettings(settings);
+ }
+
+ // Check to make sure the settings requested are currently supported by this class
+ private void checkSettings(Set<Setting> settings) throws QueryException {
+ if (settings.contains(Setting.NO_HOST_DEPS)) {
+ settings = Sets.difference(settings, ImmutableSet.of(Setting.NO_HOST_DEPS));
+ }
+ if (!settings.isEmpty()) {
+ throw new QueryException(
+ String.format(
+ "The following filter(s) are not currently supported by configured query: %s",
+ settings.toString()));
+ }
}
@Nullable
@@ -257,6 +273,45 @@ public class ConfiguredTargetQueryEnvironment
return result;
}
+ private Collection<ConfiguredTarget> filterFwdDeps(
+ ConfiguredTarget configTarget, Collection<ConfiguredTarget> rawFwdDeps)
+ throws InterruptedException {
+ if (!(configTarget instanceof RuleConfiguredTarget) || settings.isEmpty()) {
+ return rawFwdDeps;
+ }
+ return getAllowedDeps(configTarget.getConfiguration(), rawFwdDeps);
+ }
+
+ /**
+ * Note: We should check which settings to filter on here but not doing that since we currently
+ * only support one setting (NO_HOST_DEPS) and should've already thrown an error by now if it's
+ * any other filter.
+ *
+ * @param currentConfig: the config of the source target. It's possible to query on a target
+ * that's configured in the host configuration. In those cases, if --nohost_deps is turned on,
+ * we only allow reachable targets that are ALSO in the host config. This is somewhat
+ * counterintuitive and subject to change in the future but seems like the best option right
+ * now.
+ * @param rawDeps: the next level of deps to filter
+ */
+ private Collection<ConfiguredTarget> getAllowedDeps(
+ BuildConfiguration currentConfig, Collection<ConfiguredTarget> rawDeps) {
+ if (currentConfig != null && currentConfig.isHostConfiguration()) {
+ return rawDeps
+ .stream()
+ .filter(
+ dep -> dep.getConfiguration() != null && dep.getConfiguration().isHostConfiguration())
+ .collect(Collectors.toList());
+ } else {
+ return rawDeps
+ .stream()
+ .filter(
+ dep ->
+ dep.getConfiguration() == null || !dep.getConfiguration().isHostConfiguration())
+ .collect(Collectors.toList());
+ }
+ }
+
@Override
public ThreadSafeMutableSet<ConfiguredTarget> getFwdDeps(Iterable<ConfiguredTarget> targets)
throws InterruptedException {
@@ -276,7 +331,29 @@ public class ConfiguredTargetQueryEnvironment
}
ThreadSafeMutableSet<ConfiguredTarget> result = createThreadSafeMutableSet();
for (Entry<SkyKey, Collection<ConfiguredTarget>> entry : directDeps.entrySet()) {
- result.addAll(entry.getValue());
+ result.addAll(filterFwdDeps(targetsByKey.get(entry.getKey()), entry.getValue()));
+ }
+ return result;
+ }
+
+ private Collection<ConfiguredTarget> filterReverseDeps(
+ Map<SkyKey, Collection<ConfiguredTarget>> rawReverseDeps) {
+ Set<ConfiguredTarget> result = CompactHashSet.create();
+ for (Map.Entry<SkyKey, Collection<ConfiguredTarget>> targetAndRdeps :
+ rawReverseDeps.entrySet()) {
+ ImmutableSet.Builder<ConfiguredTarget> ruleDeps = ImmutableSet.builder();
+ for (ConfiguredTarget parent : targetAndRdeps.getValue()) {
+ if (parent instanceof RuleConfiguredTarget
+ && dependencyFilter != DependencyFilter.ALL_DEPS) {
+ ruleDeps.add(parent);
+ } else {
+ result.add(parent);
+ }
+ }
+ result.addAll(
+ getAllowedDeps(
+ ((ConfiguredTargetKey) targetAndRdeps.getKey().argument()).getConfiguration(),
+ ruleDeps.build()));
}
return result;
}
@@ -298,11 +375,7 @@ public class ConfiguredTargetQueryEnvironment
.collect(Collectors.toList());
eventHandler.handle(Event.warn("Targets were missing from graph: " + missingTargets));
}
- ThreadSafeMutableSet<ConfiguredTarget> result = createThreadSafeMutableSet();
- for (Entry<SkyKey, Collection<ConfiguredTarget>> entry : reverseDeps.entrySet()) {
- result.addAll(entry.getValue());
- }
- return result;
+ return reverseDeps.isEmpty() ? Collections.emptyList() : filterReverseDeps(reverseDeps);
}
@Override
@@ -407,4 +480,16 @@ public class ConfiguredTargetQueryEnvironment
}
}
}
+
+ public static QueryOptions parseOptions(String rawOptions) throws QueryException {
+ List<String> options = new ArrayList<>(Arrays.asList(rawOptions.split(" ")));
+ OptionsParser parser = OptionsParser.newOptionsParser(QueryOptions.class);
+ parser.setAllowResidue(false);
+ try {
+ parser.parse(options);
+ } catch (OptionsParsingException e) {
+ throw new QueryException(e.getMessage());
+ }
+ return parser.getOptions(QueryOptions.class);
+ }
}