aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/main/java/com/google/devtools/build/lib/skyframe/PrepareDepsOfPatternsFunction.java
diff options
context:
space:
mode:
authorGravatar Mark Schaller <mschaller@google.com>2015-03-30 14:37:36 +0000
committerGravatar Laurent Le Brun <laurentlb@google.com>2015-03-31 13:57:25 +0000
commitf7cb668fd78fc1f70647db928cec4d9a67039ac8 (patch)
treefa08430ef2eef69b22adb18d1e7971a0482bd9ee /src/main/java/com/google/devtools/build/lib/skyframe/PrepareDepsOfPatternsFunction.java
parent31ac6ce8fe4756e8e1788f3763f07a0ca1627776 (diff)
Add PrepareDepsOfPatternsFunction, use before query
This introduces a single SkyFunction that has the desired side effect of loading matching targets and their transitive dependencies in the graph. It replaces the two calls to buildDriver.evaluate that made sure the graph loaded the necessary values before query evaluation with just one call. -- MOS_MIGRATED_REVID=89864338
Diffstat (limited to 'src/main/java/com/google/devtools/build/lib/skyframe/PrepareDepsOfPatternsFunction.java')
-rw-r--r--src/main/java/com/google/devtools/build/lib/skyframe/PrepareDepsOfPatternsFunction.java120
1 files changed, 120 insertions, 0 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/PrepareDepsOfPatternsFunction.java b/src/main/java/com/google/devtools/build/lib/skyframe/PrepareDepsOfPatternsFunction.java
new file mode 100644
index 0000000000..fe90910c63
--- /dev/null
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/PrepareDepsOfPatternsFunction.java
@@ -0,0 +1,120 @@
+// Copyright 2015 Google Inc. 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.skyframe;
+
+import com.google.common.base.Preconditions;
+import com.google.common.base.Predicates;
+import com.google.devtools.build.lib.cmdline.ResolvedTargets;
+import com.google.devtools.build.lib.cmdline.TargetParsingException;
+import com.google.devtools.build.lib.events.Event;
+import com.google.devtools.build.lib.events.EventHandler;
+import com.google.devtools.build.lib.packages.NoSuchPackageException;
+import com.google.devtools.build.lib.packages.NoSuchTargetException;
+import com.google.devtools.build.lib.packages.Target;
+import com.google.devtools.build.lib.pkgcache.ParseFailureListener;
+import com.google.devtools.build.lib.skyframe.PrepareDepsOfPatternsValue.TargetPatternSequence;
+import com.google.devtools.build.skyframe.SkyFunction;
+import com.google.devtools.build.skyframe.SkyKey;
+import com.google.devtools.build.skyframe.SkyValue;
+import com.google.devtools.build.skyframe.ValueOrException;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import javax.annotation.Nullable;
+
+/**
+ * PrepareDepsOfPatternsFunction ensures the graph loads targets matching the pattern sequence and
+ * their transitive dependencies.
+ */
+public class PrepareDepsOfPatternsFunction implements SkyFunction {
+
+ /**
+ * Given a {@link SkyKey} that contains a sequence of target patterns, when this function returns
+ * {@link PrepareDepsOfPatternsValue}, then all targets matching that sequence, and those targets'
+ * transitive dependencies, have been loaded.
+ */
+ @Nullable
+ @Override
+ public SkyValue compute(SkyKey skyKey, Environment env) throws InterruptedException {
+ TargetPatternSequence targetPatternSequence = (TargetPatternSequence) skyKey.argument();
+ Iterable<SkyKey> patternSkyKeys = TargetPatternValue.keys(targetPatternSequence.getPatterns(),
+ targetPatternSequence.getPolicy(), targetPatternSequence.getOffset());
+ Map<SkyKey, ValueOrException<TargetParsingException>> targetPatternValuesByKey =
+ env.getValuesOrThrow(patternSkyKeys, TargetParsingException.class);
+ if (env.valuesMissing()) {
+ return null;
+ }
+
+ EventHandler eventHandler = env.getListener();
+ boolean handlerIsParseFailureListener = eventHandler instanceof ParseFailureListener;
+
+ ResolvedTargets.Builder<Target> builder = ResolvedTargets.builder();
+ for (SkyKey key : patternSkyKeys) {
+ try {
+ // The only exception type throwable by TargetPatternFunction is TargetParsingException.
+ // Therefore all ValueOrException values in the map will either be non-null or throw
+ // TargetParsingException when get is called.
+ TargetPatternValue resultValue = Preconditions.checkNotNull(
+ (TargetPatternValue) targetPatternValuesByKey.get(key).get());
+ ResolvedTargets<Target> results = resultValue.getTargets();
+ if (((TargetPatternValue.TargetPattern) key.argument()).isNegative()) {
+ builder.filter(Predicates.not(Predicates.in(results.getTargets())));
+ } else {
+ builder.merge(results);
+ }
+ } catch (TargetParsingException e) {
+ // If a target pattern can't be evaluated, notify the user of the problem and keep going.
+ handleTargetParsingException(eventHandler, handlerIsParseFailureListener, key, e);
+ }
+ }
+ ResolvedTargets<Target> resolvedTargets = builder.build();
+
+ List<SkyKey> targetKeys = new ArrayList<>();
+ for (Target target : resolvedTargets.getTargets()) {
+ targetKeys.add(TransitiveTargetValue.key(target.getLabel()));
+ }
+
+ // TransitiveTargetFunction can produce exceptions of types NoSuchPackageException and
+ // NoSuchTargetException. However, PrepareDepsOfPatternsFunction doesn't care about any errors
+ // found during transitive target loading--it just wants the graph to have loaded whatever
+ // transitive target values are available.
+ env.getValuesOrThrow(targetKeys, NoSuchPackageException.class, NoSuchTargetException.class);
+ if (env.valuesMissing()) {
+ return null;
+ }
+
+ return PrepareDepsOfPatternsValue.INSTANCE;
+ }
+
+ private static void handleTargetParsingException(EventHandler eventHandler,
+ boolean handlerIsParseFailureListener, SkyKey key, TargetParsingException e) {
+ TargetPatternValue.TargetPattern pattern = (TargetPatternValue.TargetPattern) key.argument();
+ String rawPattern = pattern.getPattern();
+ String errorMessage = e.getMessage();
+ eventHandler.handle(Event.error("Skipping '" + rawPattern + "': " + errorMessage));
+ if (handlerIsParseFailureListener) {
+ ParseFailureListener parseListener = (ParseFailureListener) eventHandler;
+ parseListener.parsingError(rawPattern, errorMessage);
+ }
+ }
+
+ @Nullable
+ @Override
+ public String extractTag(SkyKey skyKey) {
+ return null;
+ }
+
+}