blob: 96a77454795082c77de1c2df4b5b6f9e298649ce [file] [log] [blame]
Damien Martin-Guillerezf88f4d82015-09-25 13:56:55 +00001// Copyright 2014 The Bazel Authors. All rights reserved.
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +01002//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15package com.google.devtools.build.lib.analysis;
16
tomluf2720dc2018-10-02 12:10:51 -070017import static java.util.stream.Collectors.toSet;
18
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010019import com.google.common.annotations.VisibleForTesting;
tomlua155b532017-11-08 20:12:47 +010020import com.google.common.base.Preconditions;
ulfjack06295192019-01-16 09:13:34 -080021import com.google.common.base.Supplier;
22import com.google.common.base.Suppliers;
Greg Estren7883bf12016-11-18 20:03:43 +000023import com.google.common.collect.ArrayListMultimap;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010024import com.google.common.collect.ImmutableList;
25import com.google.common.collect.ImmutableMap;
26import com.google.common.collect.ImmutableSet;
Greg Estren7883bf12016-11-18 20:03:43 +000027import com.google.common.collect.Multimap;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010028import com.google.common.collect.Sets;
29import com.google.common.eventbus.EventBus;
Rumou Duan33bab462016-04-25 17:55:12 +000030import com.google.devtools.build.lib.actions.ActionAnalysisMetadata;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010031import com.google.devtools.build.lib.actions.ActionGraph;
janakrefb3f152019-06-05 17:42:34 -070032import com.google.devtools.build.lib.actions.ActionLookupData;
janakr93e3eea2017-03-30 22:09:37 +000033import com.google.devtools.build.lib.actions.ActionLookupValue;
janakrefb3f152019-06-05 17:42:34 -070034import com.google.devtools.build.lib.actions.Actions;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010035import com.google.devtools.build.lib.actions.Artifact;
36import com.google.devtools.build.lib.actions.ArtifactFactory;
janakrae323982017-09-29 21:11:53 +020037import com.google.devtools.build.lib.actions.PackageRoots;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010038import com.google.devtools.build.lib.analysis.config.BuildConfiguration;
39import com.google.devtools.build.lib.analysis.config.BuildConfigurationCollection;
ulfjack36fbbde2018-08-02 05:16:00 -070040import com.google.devtools.build.lib.analysis.config.BuildOptions;
juliexxiab75e45302019-05-24 07:48:39 -070041import com.google.devtools.build.lib.analysis.config.ConfigurationResolver.TopLevelTargetsAndConfigsResult;
ulfjack36fbbde2018-08-02 05:16:00 -070042import com.google.devtools.build.lib.analysis.config.InvalidConfigurationException;
gregce45ae0962017-07-22 00:11:13 +020043import com.google.devtools.build.lib.analysis.constraints.TopLevelConstraintSemantics;
ulfjackab21d182017-08-10 15:36:14 +020044import com.google.devtools.build.lib.analysis.test.CoverageReportActionFactory;
45import com.google.devtools.build.lib.analysis.test.CoverageReportActionFactory.CoverageReportActionsWrapper;
cparsonsb83c5f82018-11-21 14:46:57 -080046import com.google.devtools.build.lib.analysis.test.InstrumentedFilesInfo;
Lukacs Berki6e91eb92015-09-21 09:12:37 +000047import com.google.devtools.build.lib.cmdline.Label;
Lukacs Berki6916be22015-02-19 13:36:06 +000048import com.google.devtools.build.lib.collect.nestedset.NestedSet;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010049import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010050import com.google.devtools.build.lib.concurrent.ThreadSafety.ThreadCompatible;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010051import com.google.devtools.build.lib.events.Event;
Klaus Aehlig777b30d2017-02-24 16:30:15 +000052import com.google.devtools.build.lib.events.ExtendedEventHandler;
Carmi Grushkodf9e5e12016-11-08 23:07:57 +000053import com.google.devtools.build.lib.packages.AspectClass;
Dmitry Lomov15756522016-12-16 16:52:37 +000054import com.google.devtools.build.lib.packages.AspectDescriptor;
Dmitry Lomovca9bfa42016-11-15 13:22:36 +000055import com.google.devtools.build.lib.packages.AspectParameters;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010056import com.google.devtools.build.lib.packages.Attribute;
Dmitry Lomov8ff06452015-10-21 19:16:30 +000057import com.google.devtools.build.lib.packages.NativeAspectClass;
Cal Peyser8a638d52017-03-24 15:44:24 +000058import com.google.devtools.build.lib.packages.NoSuchPackageException;
59import com.google.devtools.build.lib.packages.NoSuchTargetException;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010060import com.google.devtools.build.lib.packages.Rule;
61import com.google.devtools.build.lib.packages.Target;
62import com.google.devtools.build.lib.packages.TargetUtils;
nharmatac4335cf2017-07-18 21:39:13 +020063import com.google.devtools.build.lib.pkgcache.PackageManager.PackageManagerStatistics;
ulfjack36fbbde2018-08-02 05:16:00 -070064import com.google.devtools.build.lib.profiler.Profiler;
65import com.google.devtools.build.lib.profiler.SilentCloseable;
Dmitry Lomove2033b12015-08-19 16:57:49 +000066import com.google.devtools.build.lib.skyframe.AspectValue;
Carmi Grushkodf9e5e12016-11-08 23:07:57 +000067import com.google.devtools.build.lib.skyframe.AspectValue.AspectKey;
Dmitry Lomovc15ba2e2015-10-30 15:50:01 +000068import com.google.devtools.build.lib.skyframe.AspectValue.AspectValueKey;
ulfjack06295192019-01-16 09:13:34 -080069import com.google.devtools.build.lib.skyframe.BuildConfigurationValue;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010070import com.google.devtools.build.lib.skyframe.ConfiguredTargetKey;
71import com.google.devtools.build.lib.skyframe.CoverageReportValue;
ulfjack36fbbde2018-08-02 05:16:00 -070072import com.google.devtools.build.lib.skyframe.PrepareAnalysisPhaseValue;
Dmitry Lomove2033b12015-08-19 16:57:49 +000073import com.google.devtools.build.lib.skyframe.SkyframeAnalysisResult;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010074import com.google.devtools.build.lib.skyframe.SkyframeBuildView;
75import com.google.devtools.build.lib.skyframe.SkyframeExecutor;
ulfjack12bb59f52018-07-25 07:19:24 -070076import com.google.devtools.build.lib.skyframe.TargetPatternPhaseValue;
Dmitry Lomov51aafc12016-11-18 14:02:54 +000077import com.google.devtools.build.lib.syntax.SkylarkImport;
laurentlbc6c9b8e2019-04-15 11:26:26 -070078import com.google.devtools.build.lib.syntax.SkylarkImport.SkylarkImportSyntaxException;
Klaus Aehligc27b4da2017-09-01 10:33:22 +020079import com.google.devtools.build.lib.util.Pair;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010080import com.google.devtools.build.lib.util.RegexFilter;
Eric Fellheimer9c1e12f2015-08-06 20:23:55 +000081import com.google.devtools.build.skyframe.WalkableGraph;
Dmitry Lomove2033b12015-08-19 16:57:49 +000082import java.util.ArrayList;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010083import java.util.Collection;
ulfjack06295192019-01-16 09:13:34 -080084import java.util.HashMap;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010085import java.util.HashSet;
86import java.util.LinkedHashSet;
87import java.util.List;
ulfjack06295192019-01-16 09:13:34 -080088import java.util.Map;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010089import java.util.Set;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010090import java.util.logging.Logger;
mjhalupka7675dbd2018-01-29 12:46:58 -080091import java.util.stream.Collectors;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010092import javax.annotation.Nullable;
93
94/**
ulfjack865b6212018-06-14 03:41:55 -070095 * The BuildView presents a semantically-consistent and transitively-closed
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010096 * dependency graph for some set of packages.
97 *
98 * <h2>Package design</h2>
99 *
100 * <p>This package contains the Blaze dependency analysis framework (aka
101 * "analysis phase"). The goal of this code is to perform semantic analysis of
102 * all of the build targets required for a given build, to report
103 * errors/warnings for any problems in the input, and to construct an "action
104 * graph" (see {@code lib.actions} package) correctly representing the work to
105 * be done during the execution phase of the build.
106 *
107 * <p><b>Configurations</b> the inputs to a build come from two sources: the
108 * intrinsic inputs, specified in the BUILD file, are called <em>targets</em>.
109 * The environmental inputs, coming from the build tool, the command-line, or
110 * configuration files, are called the <em>configuration</em>. Only when a
111 * target and a configuration are combined is there sufficient information to
112 * perform a build. </p>
113 *
114 * <p>Targets are implemented by the {@link Target} hierarchy in the {@code
115 * lib.packages} code. Configurations are implemented by {@link
116 * BuildConfiguration}. The pair of these together is represented by an
117 * instance of class {@link ConfiguredTarget}; this is the root of a hierarchy
118 * with different implementations for each kind of target: source file, derived
119 * file, rules, etc.
120 *
121 * <p>The framework code in this package (as opposed to its subpackages) is
122 * responsible for constructing the {@code ConfiguredTarget} graph for a given
123 * target and configuration, taking care of such issues as:
124 * <ul>
125 * <li>caching common subgraphs.
126 * <li>detecting and reporting cycles.
127 * <li>correct propagation of errors through the graph.
128 * <li>reporting universal errors, such as dependencies from production code
129 * to tests, or to experimental branches.
130 * <li>capturing and replaying errors.
131 * <li>maintaining the graph from one build to the next to
132 * avoid unnecessary recomputation.
133 * <li>checking software licenses.
134 * </ul>
135 *
136 * <p>See also {@link ConfiguredTarget} which documents some important
137 * invariants.
138 */
139public class BuildView {
lberki998ec922017-09-05 10:08:25 +0200140 private static final Logger logger = Logger.getLogger(BuildView.class.getName());
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100141
142 private final BlazeDirectories directories;
143
144 private final SkyframeExecutor skyframeExecutor;
145 private final SkyframeBuildView skyframeBuildView;
146
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100147 private final ConfiguredRuleClassProvider ruleClassProvider;
148
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100149 /**
150 * A factory class to create the coverage report action. May be null.
151 */
152 @Nullable private final CoverageReportActionFactory coverageReportActionFactory;
153
Ulf Adams59dbf682015-09-17 11:36:43 +0000154 public BuildView(BlazeDirectories directories,
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100155 ConfiguredRuleClassProvider ruleClassProvider,
156 SkyframeExecutor skyframeExecutor,
Ulf Adams5a96d532015-09-26 09:00:57 +0000157 CoverageReportActionFactory coverageReportActionFactory) {
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100158 this.directories = directories;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100159 this.coverageReportActionFactory = coverageReportActionFactory;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100160 this.ruleClassProvider = ruleClassProvider;
161 this.skyframeExecutor = Preconditions.checkNotNull(skyframeExecutor);
Ulf Adams89eefd72015-09-23 08:00:43 +0000162 this.skyframeBuildView = skyframeExecutor.getSkyframeBuildView();
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100163 }
164
tomluf2720dc2018-10-02 12:10:51 -0700165 /** The number of configured targets freshly evaluated in the last analysis run. */
166 public int getTargetsConfigured() {
ulfjack865b6212018-06-14 03:41:55 -0700167 return skyframeBuildView.getEvaluatedTargetKeys().size();
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100168 }
169
tomluf2720dc2018-10-02 12:10:51 -0700170 /** The number of targets (not configured targets) loaded in the last analysis run. */
171 public int getTargetsLoaded() {
172 return skyframeBuildView.getEvaluatedTargetKeys().stream()
173 .map(key -> ((ConfiguredTargetKey) key).getLabel())
174 .collect(toSet())
175 .size();
176 }
177
tomlua0e8aae2018-06-19 15:07:26 -0700178 public int getActionsConstructed() {
179 return skyframeBuildView.getEvaluatedActionCount();
180 }
181
ulfjack865b6212018-06-14 03:41:55 -0700182 public PackageManagerStatistics getAndClearPkgManagerStatistics() {
183 return skyframeExecutor.getPackageManager().getAndClearStatistics();
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100184 }
185
ulfjack865b6212018-06-14 03:41:55 -0700186 private ArtifactFactory getArtifactFactory() {
Ulf Adams89eefd72015-09-23 08:00:43 +0000187 return skyframeBuildView.getArtifactFactory();
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100188 }
189
mjhalupka7675dbd2018-01-29 12:46:58 -0800190 /** Returns the collection of configured targets corresponding to any of the provided targets. */
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100191 @VisibleForTesting
mjhalupkae253f832018-06-13 14:19:26 -0700192 static LinkedHashSet<ConfiguredTarget> filterTestsByTargets(
ulfjack12bb59f52018-07-25 07:19:24 -0700193 Collection<ConfiguredTarget> targets, Set<Label> allowedTargetLabels) {
mjhalupka7675dbd2018-01-29 12:46:58 -0800194 return targets
195 .stream()
mjhalupkae253f832018-06-13 14:19:26 -0700196 .filter(ct -> allowedTargetLabels.contains(ct.getLabel()))
197 .collect(Collectors.toCollection(LinkedHashSet::new));
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100198 }
199
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100200 @ThreadCompatible
Dmitry Lomove2033b12015-08-19 16:57:49 +0000201 public AnalysisResult update(
ulfjack12bb59f52018-07-25 07:19:24 -0700202 TargetPatternPhaseValue loadingResult,
ulfjack36fbbde2018-08-02 05:16:00 -0700203 BuildOptions targetOptions,
204 Set<String> multiCpu,
Dmitry Lomove2033b12015-08-19 16:57:49 +0000205 List<String> aspects,
ulfjackb5daae32018-06-13 07:59:33 -0700206 AnalysisOptions viewOptions,
juliexxia8a2baea2017-12-18 14:33:45 -0800207 boolean keepGoing,
juliexxiaf8b57c52017-12-21 11:37:46 -0800208 int loadingPhaseThreads,
Dmitry Lomove2033b12015-08-19 16:57:49 +0000209 TopLevelArtifactContext topLevelOptions,
Klaus Aehlig777b30d2017-02-24 16:30:15 +0000210 ExtendedEventHandler eventHandler,
Ulf Adams8c4ae672016-03-30 11:20:41 +0000211 EventBus eventBus)
ulfjack36fbbde2018-08-02 05:16:00 -0700212 throws ViewCreationFailedException, InvalidConfigurationException, InterruptedException {
lberki998ec922017-09-05 10:08:25 +0200213 logger.info("Starting analysis");
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100214 pollInterruptedStatus();
215
216 skyframeBuildView.resetEvaluatedConfiguredTargetKeysSet();
tomlua0e8aae2018-06-19 15:07:26 -0700217 skyframeBuildView.resetEvaluationActionCount();
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100218
ulfjack12bb59f52018-07-25 07:19:24 -0700219 // TODO(ulfjack): Expensive. Maybe we don't actually need the targets, only the labels?
220 Collection<Target> targets =
221 loadingResult.getTargets(eventHandler, skyframeExecutor.getPackageManager());
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100222 eventBus.post(new AnalysisPhaseStartedEvent(targets));
223
ulfjack36fbbde2018-08-02 05:16:00 -0700224 // Prepare the analysis phase
225 BuildConfigurationCollection configurations;
juliexxiab75e45302019-05-24 07:48:39 -0700226 TopLevelTargetsAndConfigsResult topLevelTargetsWithConfigsResult;
ulfjack36fbbde2018-08-02 05:16:00 -0700227 if (viewOptions.skyframePrepareAnalysis) {
228 PrepareAnalysisPhaseValue prepareAnalysisPhaseValue;
229 try (SilentCloseable c = Profiler.instance().profile("Prepare analysis phase")) {
230 prepareAnalysisPhaseValue = skyframeExecutor.prepareAnalysisPhase(
231 eventHandler, targetOptions, multiCpu, loadingResult.getTargetLabels());
ulfjack06295192019-01-16 09:13:34 -0800232
ulfjack36fbbde2018-08-02 05:16:00 -0700233 // Determine the configurations
234 configurations =
235 prepareAnalysisPhaseValue.getConfigurations(eventHandler, skyframeExecutor);
juliexxiab75e45302019-05-24 07:48:39 -0700236 topLevelTargetsWithConfigsResult =
ulfjack36fbbde2018-08-02 05:16:00 -0700237 prepareAnalysisPhaseValue.getTopLevelCts(eventHandler, skyframeExecutor);
238 }
239 } else {
240 // Configuration creation.
241 // TODO(gregce): Consider dropping this phase and passing on-the-fly target / host configs as
242 // needed. This requires cleaning up the invalidation in SkyframeBuildView.setConfigurations.
243 try (SilentCloseable c = Profiler.instance().profile("createConfigurations")) {
244 configurations =
245 skyframeExecutor
246 .createConfigurations(
247 eventHandler,
248 targetOptions,
249 multiCpu,
250 keepGoing);
251 }
252 try (SilentCloseable c = Profiler.instance().profile("AnalysisUtils.getTargetsWithConfigs")) {
juliexxiab75e45302019-05-24 07:48:39 -0700253 topLevelTargetsWithConfigsResult =
ulfjack36fbbde2018-08-02 05:16:00 -0700254 AnalysisUtils.getTargetsWithConfigs(
255 configurations, targets, eventHandler, ruleClassProvider, skyframeExecutor);
ulfjack36fbbde2018-08-02 05:16:00 -0700256 }
257 }
258
mstaib6cf62782018-11-14 11:54:33 -0800259 skyframeBuildView.setConfigurations(
260 eventHandler, configurations, viewOptions.maxConfigChangesToShow);
Marian Lobur86bd4fd2015-09-16 10:01:38 +0000261
ulfjack36fbbde2018-08-02 05:16:00 -0700262 if (configurations.getTargetConfigurations().size() == 1) {
263 eventBus
264 .post(
265 new MakeEnvironmentEvent(
266 configurations.getTargetConfigurations().get(0).getMakeEnvironment()));
267 }
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100268
juliexxiab75e45302019-05-24 07:48:39 -0700269 Collection<TargetAndConfiguration> topLevelTargetsWithConfigs =
270 topLevelTargetsWithConfigsResult.getTargetsAndConfigs();
271
Klaus Aehlig71c993b2017-05-09 07:49:46 -0400272 // Report the generated association of targets to configurations
273 Multimap<Label, BuildConfiguration> byLabel =
274 ArrayListMultimap.<Label, BuildConfiguration>create();
275 for (TargetAndConfiguration pair : topLevelTargetsWithConfigs) {
276 byLabel.put(pair.getLabel(), pair.getConfiguration());
277 }
Klaus Aehlig2a92c902017-08-11 14:03:31 +0200278 for (Target target : targets) {
279 eventBus.post(new TargetConfiguredEvent(target, byLabel.get(target.getLabel())));
Klaus Aehlig71c993b2017-05-09 07:49:46 -0400280 }
281
janakr573807d2018-01-11 14:02:35 -0800282 List<ConfiguredTargetKey> topLevelCtKeys =
ulfjack36fbbde2018-08-02 05:16:00 -0700283 topLevelTargetsWithConfigs
284 .stream()
285 .map(node -> ConfiguredTargetKey.of(node.getLabel(), node.getConfiguration()))
286 .collect(Collectors.toList());
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100287
Klaus Aehligc27b4da2017-09-01 10:33:22 +0200288 Multimap<Pair<Label, String>, BuildConfiguration> aspectConfigurations =
289 ArrayListMultimap.create();
Klaus Aehlig71c993b2017-05-09 07:49:46 -0400290
Dmitry Lomovc15ba2e2015-10-30 15:50:01 +0000291 List<AspectValueKey> aspectKeys = new ArrayList<>();
Dmitry Lomove2033b12015-08-19 16:57:49 +0000292 for (String aspect : aspects) {
Dmitry Lomov0b832ce2015-10-20 10:03:14 +0000293 // Syntax: label%aspect
294 int delimiterPosition = aspect.indexOf('%');
295 if (delimiterPosition >= 0) {
John Fielda97e17f2015-11-13 02:19:52 +0000296 // TODO(jfield): For consistency with Skylark loads, the aspect should be specified
laurentlb940dbc52018-03-01 08:07:14 -0800297 // as an absolute label.
298 // We convert it for compatibility reasons (this will be removed in the future).
Dmitry Lomov51aafc12016-11-18 14:02:54 +0000299 String bzlFileLoadLikeString = aspect.substring(0, delimiterPosition);
300 if (!bzlFileLoadLikeString.startsWith("//") && !bzlFileLoadLikeString.startsWith("@")) {
301 // "Legacy" behavior of '--aspects' parameter.
laurentlb940dbc52018-03-01 08:07:14 -0800302 if (bzlFileLoadLikeString.startsWith("/")) {
303 bzlFileLoadLikeString = bzlFileLoadLikeString.substring(1);
304 }
305 int lastSlashPosition = bzlFileLoadLikeString.lastIndexOf('/');
306 if (lastSlashPosition >= 0) {
307 bzlFileLoadLikeString =
308 "//"
309 + bzlFileLoadLikeString.substring(0, lastSlashPosition)
310 + ":"
311 + bzlFileLoadLikeString.substring(lastSlashPosition + 1);
312 } else {
313 bzlFileLoadLikeString = "//:" + bzlFileLoadLikeString;
314 }
315 if (!bzlFileLoadLikeString.endsWith(".bzl")) {
316 bzlFileLoadLikeString = bzlFileLoadLikeString + ".bzl";
Dmitry Lomov51aafc12016-11-18 14:02:54 +0000317 }
318 }
319 SkylarkImport skylarkImport;
320 try {
dannarkf4b9ff42018-06-12 09:28:45 -0700321 skylarkImport =
laurentlbc6c9b8e2019-04-15 11:26:26 -0700322 SkylarkImport.create(
dannarkf4b9ff42018-06-12 09:28:45 -0700323 bzlFileLoadLikeString, /* repositoryMapping= */ ImmutableMap.of());
Dmitry Lomov51aafc12016-11-18 14:02:54 +0000324 } catch (SkylarkImportSyntaxException e) {
325 throw new ViewCreationFailedException(
326 String.format("Invalid aspect '%s': %s", aspect, e.getMessage()), e);
327 }
Dmitry Lomov0b832ce2015-10-20 10:03:14 +0000328
329 String skylarkFunctionName = aspect.substring(delimiterPosition + 1);
Dmitry Lomov01f85c02016-06-29 06:37:50 +0000330 for (TargetAndConfiguration targetSpec : topLevelTargetsWithConfigs) {
mstaib7c7a7012019-04-23 16:19:09 -0700331 if (targetSpec.getConfiguration() != null
332 && targetSpec.getConfiguration().trimConfigurationsRetroactively()) {
333 throw new ViewCreationFailedException(
334 "Aspects were requested, but are not supported in retroactive trimming mode.");
335 }
Klaus Aehligc27b4da2017-09-01 10:33:22 +0200336 aspectConfigurations.put(
337 Pair.of(targetSpec.getLabel(), aspect), targetSpec.getConfiguration());
Dmitry Lomove2033b12015-08-19 16:57:49 +0000338 aspectKeys.add(
Dmitry Lomov0b832ce2015-10-20 10:03:14 +0000339 AspectValue.createSkylarkAspectKey(
340 targetSpec.getLabel(),
Michael Staib04f6f242016-03-01 15:40:29 +0000341 // For invoking top-level aspects, use the top-level configuration for both the
342 // aspect and the base target while the top-level configuration is untrimmed.
343 targetSpec.getConfiguration(),
Dmitry Lomov0b832ce2015-10-20 10:03:14 +0000344 targetSpec.getConfiguration(),
Dmitry Lomov51aafc12016-11-18 14:02:54 +0000345 skylarkImport,
Dmitry Lomov0b832ce2015-10-20 10:03:14 +0000346 skylarkFunctionName));
Dmitry Lomove2033b12015-08-19 16:57:49 +0000347 }
348 } else {
Luis Fernando Pino Duquee82713d2016-04-26 16:22:38 +0000349 final NativeAspectClass aspectFactoryClass =
350 ruleClassProvider.getNativeAspectClassMap().get(aspect);
dslomov99ea6b42017-04-25 17:46:17 +0200351
Dmitry Lomov0b832ce2015-10-20 10:03:14 +0000352 if (aspectFactoryClass != null) {
Dmitry Lomov01f85c02016-06-29 06:37:50 +0000353 for (TargetAndConfiguration targetSpec : topLevelTargetsWithConfigs) {
mstaib7c7a7012019-04-23 16:19:09 -0700354 if (targetSpec.getConfiguration() != null
355 && targetSpec.getConfiguration().trimConfigurationsRetroactively()) {
356 throw new ViewCreationFailedException(
357 "Aspects were requested, but are not supported in retroactive trimming mode.");
358 }
Dmitry Lomovca9bfa42016-11-15 13:22:36 +0000359 // For invoking top-level aspects, use the top-level configuration for both the
360 // aspect and the base target while the top-level configuration is untrimmed.
361 BuildConfiguration configuration = targetSpec.getConfiguration();
Klaus Aehligc27b4da2017-09-01 10:33:22 +0200362 aspectConfigurations.put(Pair.of(targetSpec.getLabel(), aspect), configuration);
Dmitry Lomov0b832ce2015-10-20 10:03:14 +0000363 aspectKeys.add(
364 AspectValue.createAspectKey(
Dmitry Lomov8ff06452015-10-21 19:16:30 +0000365 targetSpec.getLabel(),
Dmitry Lomovca9bfa42016-11-15 13:22:36 +0000366 configuration,
dslomovfa50c3d2017-05-08 08:47:44 -0400367 new AspectDescriptor(aspectFactoryClass, AspectParameters.EMPTY),
Dmitry Lomovca9bfa42016-11-15 13:22:36 +0000368 configuration
369 ));
Dmitry Lomov0b832ce2015-10-20 10:03:14 +0000370 }
371 } else {
372 throw new ViewCreationFailedException("Aspect '" + aspect + "' is unknown");
373 }
Dmitry Lomove2033b12015-08-19 16:57:49 +0000374 }
375 }
376
Klaus Aehligc27b4da2017-09-01 10:33:22 +0200377 for (Pair<Label, String> target : aspectConfigurations.keys()) {
378 eventBus.post(
379 new AspectConfiguredEvent(
380 target.getFirst(), target.getSecond(), aspectConfigurations.get(target)));
381 }
382
janakr1f08d4c82018-09-15 16:33:35 -0700383 getArtifactFactory().noteAnalysisStarting();
Dmitry Lomove2033b12015-08-19 16:57:49 +0000384 SkyframeAnalysisResult skyframeAnalysisResult;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100385 try {
ulfjack06295192019-01-16 09:13:34 -0800386 Supplier<Map<BuildConfigurationValue.Key, BuildConfiguration>> configurationLookupSupplier =
387 () -> {
388 Map<BuildConfigurationValue.Key, BuildConfiguration> result = new HashMap<>();
389 for (TargetAndConfiguration node : topLevelTargetsWithConfigs) {
390 if (node.getConfiguration() != null) {
391 result.put(
392 BuildConfigurationValue.key(node.getConfiguration()), node.getConfiguration());
393 }
394 }
395 return result;
396 };
Dmitry Lomove2033b12015-08-19 16:57:49 +0000397 skyframeAnalysisResult =
398 skyframeBuildView.configureTargets(
ulfjack06295192019-01-16 09:13:34 -0800399 eventHandler,
400 topLevelCtKeys,
401 aspectKeys,
402 Suppliers.memoize(configurationLookupSupplier),
403 eventBus,
404 keepGoing,
405 loadingPhaseThreads);
Kristina Chodorow94e27422016-08-25 14:17:30 +0000406 setArtifactRoots(skyframeAnalysisResult.getPackageRoots());
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100407 } finally {
408 skyframeBuildView.clearInvalidatedConfiguredTargets();
409 }
410
Greg Estren7971e672016-06-01 23:22:48 +0000411 int numTargetsToAnalyze = topLevelTargetsWithConfigs.size();
Dmitry Lomove2033b12015-08-19 16:57:49 +0000412 int numSuccessful = skyframeAnalysisResult.getConfiguredTargets().size();
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100413 if (0 < numSuccessful && numSuccessful < numTargetsToAnalyze) {
414 String msg = String.format("Analysis succeeded for only %d of %d top-level targets",
415 numSuccessful, numTargetsToAnalyze);
416 eventHandler.handle(Event.info(msg));
lberki998ec922017-09-05 10:08:25 +0200417 logger.info(msg);
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100418 }
419
gregce45ae0962017-07-22 00:11:13 +0200420 Set<ConfiguredTarget> targetsToSkip =
janakr171a7eb2018-03-26 09:26:53 -0700421 new TopLevelConstraintSemantics(
422 skyframeExecutor.getPackageManager(),
423 input -> skyframeExecutor.getConfiguration(eventHandler, input),
424 eventHandler)
gregce21fdc482017-12-05 16:10:47 -0800425 .checkTargetEnvironmentRestrictions(skyframeAnalysisResult.getConfiguredTargets());
gregce45ae0962017-07-22 00:11:13 +0200426
Dmitry Lomove2033b12015-08-19 16:57:49 +0000427 AnalysisResult result =
428 createResult(
Ulf Adams5b9009b2015-09-24 09:52:53 +0000429 eventHandler,
ulfjackb2cb6402019-01-24 04:04:48 -0800430 eventBus,
Dmitry Lomove2033b12015-08-19 16:57:49 +0000431 loadingResult,
ulfjack940fbd72018-06-15 03:23:58 -0700432 configurations,
Dmitry Lomove2033b12015-08-19 16:57:49 +0000433 topLevelOptions,
434 viewOptions,
gregce45ae0962017-07-22 00:11:13 +0200435 skyframeAnalysisResult,
juliexxia693abdc2018-01-03 08:59:18 -0800436 targetsToSkip,
juliexxiab75e45302019-05-24 07:48:39 -0700437 topLevelTargetsWithConfigsResult);
lberki998ec922017-09-05 10:08:25 +0200438 logger.info("Finished analysis");
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100439 return result;
440 }
441
Dmitry Lomove2033b12015-08-19 16:57:49 +0000442 private AnalysisResult createResult(
Klaus Aehlig777b30d2017-02-24 16:30:15 +0000443 ExtendedEventHandler eventHandler,
ulfjackb2cb6402019-01-24 04:04:48 -0800444 EventBus eventBus,
ulfjack12bb59f52018-07-25 07:19:24 -0700445 TargetPatternPhaseValue loadingResult,
ulfjack940fbd72018-06-15 03:23:58 -0700446 BuildConfigurationCollection configurations,
Dmitry Lomove2033b12015-08-19 16:57:49 +0000447 TopLevelArtifactContext topLevelOptions,
ulfjackb5daae32018-06-13 07:59:33 -0700448 AnalysisOptions viewOptions,
gregce45ae0962017-07-22 00:11:13 +0200449 SkyframeAnalysisResult skyframeAnalysisResult,
juliexxia693abdc2018-01-03 08:59:18 -0800450 Set<ConfiguredTarget> targetsToSkip,
juliexxiab75e45302019-05-24 07:48:39 -0700451 TopLevelTargetsAndConfigsResult topLevelTargetsWithConfigs)
Klaus Aehlig777b30d2017-02-24 16:30:15 +0000452 throws InterruptedException {
ulfjack12bb59f52018-07-25 07:19:24 -0700453 Set<Label> testsToRun = loadingResult.getTestsToRunLabels();
gregce45ae0962017-07-22 00:11:13 +0200454 Set<ConfiguredTarget> configuredTargets =
455 Sets.newLinkedHashSet(skyframeAnalysisResult.getConfiguredTargets());
Googler92044992018-03-14 14:26:30 -0700456 ImmutableSet<AspectValue> aspects = ImmutableSet.copyOf(skyframeAnalysisResult.getAspects());
Dmitry Lomovcf6021a2016-08-09 16:49:32 +0000457
gregce45ae0962017-07-22 00:11:13 +0200458 Set<ConfiguredTarget> allTargetsToTest = null;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100459 if (testsToRun != null) {
460 // Determine the subset of configured targets that are meant to be run as tests.
mjhalupkae253f832018-06-13 14:19:26 -0700461 allTargetsToTest = filterTestsByTargets(configuredTargets, testsToRun);
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100462 }
463
janakrccb74562018-07-30 10:56:57 -0700464 ArtifactsToOwnerLabels.Builder artifactsToOwnerLabelsBuilder =
465 new ArtifactsToOwnerLabels.Builder();
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100466 Set<ConfiguredTarget> parallelTests = new HashSet<>();
467 Set<ConfiguredTarget> exclusiveTests = new HashSet<>();
Ulf Adamsfc154ae2015-08-31 12:32:14 +0000468
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100469 // build-info and build-changelist.
Ulf Adams5b9009b2015-09-24 09:52:53 +0000470 Collection<Artifact> buildInfoArtifacts =
471 skyframeExecutor.getWorkspaceStatusArtifacts(eventHandler);
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100472 Preconditions.checkState(buildInfoArtifacts.size() == 2, buildInfoArtifacts);
janakrccb74562018-07-30 10:56:57 -0700473 buildInfoArtifacts.forEach(artifactsToOwnerLabelsBuilder::addArtifact);
Ulf Adamsfc154ae2015-08-31 12:32:14 +0000474
475 // Extra actions
mjhalupka7675dbd2018-01-29 12:46:58 -0800476 addExtraActionsIfRequested(
janakrccb74562018-07-30 10:56:57 -0700477 viewOptions, configuredTargets, aspects, artifactsToOwnerLabelsBuilder, eventHandler);
Ulf Adamsfc154ae2015-08-31 12:32:14 +0000478
479 // Coverage
janakr75bc18a2018-07-13 00:52:17 -0700480 NestedSet<Artifact> baselineCoverageArtifacts =
janakrccb74562018-07-30 10:56:57 -0700481 getBaselineCoverageArtifacts(configuredTargets, artifactsToOwnerLabelsBuilder);
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100482 if (coverageReportActionFactory != null) {
Googlercdc90e92015-02-11 00:18:07 +0000483 CoverageReportActionsWrapper actionsWrapper;
janakr573807d2018-01-11 14:02:35 -0800484 actionsWrapper =
485 coverageReportActionFactory.createCoverageReportActionsWrapper(
486 eventHandler,
ulfjackb2cb6402019-01-24 04:04:48 -0800487 eventBus,
janakr573807d2018-01-11 14:02:35 -0800488 directories,
489 allTargetsToTest,
490 baselineCoverageArtifacts,
491 getArtifactFactory(),
janakrefb3f152019-06-05 17:42:34 -0700492 skyframeExecutor.getActionKeyContext(),
elenairina9438d102018-07-06 03:06:21 -0700493 CoverageReportValue.COVERAGE_REPORT_KEY,
494 loadingResult.getWorkspaceName());
Googlercdc90e92015-02-11 00:18:07 +0000495 if (actionsWrapper != null) {
janakrefb3f152019-06-05 17:42:34 -0700496 Actions.GeneratingActions actions = actionsWrapper.getActions();
Googlercdc90e92015-02-11 00:18:07 +0000497 skyframeExecutor.injectCoverageReportData(actions);
janakrccb74562018-07-30 10:56:57 -0700498 actionsWrapper.getCoverageOutputs().forEach(artifactsToOwnerLabelsBuilder::addArtifact);
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100499 }
500 }
501
Ulf Adamsfc154ae2015-08-31 12:32:14 +0000502 // Tests. This must come last, so that the exclusive tests are scheduled after everything else.
mjhalupka7675dbd2018-01-29 12:46:58 -0800503 scheduleTestsIfRequested(
504 parallelTests,
505 exclusiveTests,
506 topLevelOptions,
507 allTargetsToTest,
508 skyframeExecutor,
509 eventHandler);
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100510
juliexxiab75e45302019-05-24 07:48:39 -0700511 String error =
512 createErrorMessage(loadingResult, skyframeAnalysisResult, topLevelTargetsWithConfigs);
Eric Fellheimer9c1e12f2015-08-06 20:23:55 +0000513
Ulf Adams53abece2016-02-03 08:30:07 +0000514 final WalkableGraph graph = skyframeAnalysisResult.getWalkableGraph();
Janak Ramakrishnan3c0adb22016-08-15 21:54:55 +0000515 final ActionGraph actionGraph =
516 new ActionGraph() {
517 @Nullable
518 @Override
519 public ActionAnalysisMetadata getGeneratingAction(Artifact artifact) {
janakrefb3f152019-06-05 17:42:34 -0700520 if (artifact.isSourceArtifact()) {
521 return null;
Janak Ramakrishnan3c0adb22016-08-15 21:54:55 +0000522 }
janakrefb3f152019-06-05 17:42:34 -0700523 ActionLookupData generatingActionKey =
524 ((Artifact.DerivedArtifact) artifact).getGeneratingActionKey();
525 ActionLookupValue val;
526 try {
527 val = (ActionLookupValue) graph.getValue(generatingActionKey.getActionLookupKey());
528 } catch (InterruptedException e) {
529 throw new IllegalStateException(
530 "Interruption not expected from this graph: " + generatingActionKey, e);
531 }
532 if (val == null) {
533 return null;
534 }
535 int actionIndex = generatingActionKey.getActionIndex();
536 return val.isActionTemplate(actionIndex)
537 ? val.getActionTemplate(actionIndex)
538 : val.getAction(actionIndex);
Janak Ramakrishnan3c0adb22016-08-15 21:54:55 +0000539 }
540 };
Dmitry Lomove2033b12015-08-19 16:57:49 +0000541 return new AnalysisResult(
ulfjack940fbd72018-06-15 03:23:58 -0700542 configurations,
Dmitry Lomove2033b12015-08-19 16:57:49 +0000543 configuredTargets,
Dmitry Lomovcf6021a2016-08-09 16:49:32 +0000544 aspects,
Dmitry Lomove2033b12015-08-19 16:57:49 +0000545 allTargetsToTest,
gregce45ae0962017-07-22 00:11:13 +0200546 targetsToSkip,
Dmitry Lomove2033b12015-08-19 16:57:49 +0000547 error,
548 actionGraph,
janakrccb74562018-07-30 10:56:57 -0700549 artifactsToOwnerLabelsBuilder.build(),
Dmitry Lomove2033b12015-08-19 16:57:49 +0000550 parallelTests,
551 exclusiveTests,
Marian Lobur86bd4fd2015-09-16 10:01:38 +0000552 topLevelOptions,
Kristina Chodorow36a6c172016-07-22 15:18:07 +0000553 skyframeAnalysisResult.getPackageRoots(),
juliexxia693abdc2018-01-03 08:59:18 -0800554 loadingResult.getWorkspaceName(),
juliexxiab75e45302019-05-24 07:48:39 -0700555 topLevelTargetsWithConfigs.getTargetsAndConfigs());
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100556 }
557
juliexxiab75e45302019-05-24 07:48:39 -0700558 /**
559 * Check for errors in "chronological" order (acknowledge that loading and analysis are
560 * interleaved, but sequential on the single target scale).
561 */
Janak Ramakrishnan6f9d7d12016-08-09 08:45:34 +0000562 @Nullable
563 public static String createErrorMessage(
ulfjack12bb59f52018-07-25 07:19:24 -0700564 TargetPatternPhaseValue loadingResult,
juliexxiab75e45302019-05-24 07:48:39 -0700565 @Nullable SkyframeAnalysisResult skyframeAnalysisResult,
566 @Nullable TopLevelTargetsAndConfigsResult topLevelTargetsAndConfigs) {
567 if (loadingResult.hasError()) {
568 return "command succeeded, but there were errors parsing the target pattern";
569 }
570 if (loadingResult.hasPostExpansionError()
571 || (skyframeAnalysisResult != null && skyframeAnalysisResult.hasLoadingError())) {
572 return "command succeeded, but there were loading phase errors";
573 }
574 if (topLevelTargetsAndConfigs != null && topLevelTargetsAndConfigs.hasError()) {
575 return "command succeeded, but top level configurations could not be created";
576 }
577 if (skyframeAnalysisResult != null && skyframeAnalysisResult.hasAnalysisError()) {
578 return "command succeeded, but not all targets were analyzed";
579 }
580 return null;
Janak Ramakrishnan6f9d7d12016-08-09 08:45:34 +0000581 }
582
Lukacs Berki6916be22015-02-19 13:36:06 +0000583 private static NestedSet<Artifact> getBaselineCoverageArtifacts(
janakr75bc18a2018-07-13 00:52:17 -0700584 Collection<ConfiguredTarget> configuredTargets,
janakrccb74562018-07-30 10:56:57 -0700585 ArtifactsToOwnerLabels.Builder topLevelArtifactsToOwnerLabels) {
Lukacs Berki6916be22015-02-19 13:36:06 +0000586 NestedSetBuilder<Artifact> baselineCoverageArtifacts = NestedSetBuilder.stableOrder();
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100587 for (ConfiguredTarget target : configuredTargets) {
cparsonsb83c5f82018-11-21 14:46:57 -0800588 InstrumentedFilesInfo provider = target.get(InstrumentedFilesInfo.SKYLARK_CONSTRUCTOR);
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100589 if (provider != null) {
janakr75bc18a2018-07-13 00:52:17 -0700590 TopLevelArtifactHelper.addArtifactsWithOwnerLabel(
591 provider.getBaselineCoverageArtifacts(),
592 null,
593 target.getLabel(),
594 topLevelArtifactsToOwnerLabels);
Ulf Adamsfc154ae2015-08-31 12:32:14 +0000595 baselineCoverageArtifacts.addTransitive(provider.getBaselineCoverageArtifacts());
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100596 }
597 }
Lukacs Berki6916be22015-02-19 13:36:06 +0000598 return baselineCoverageArtifacts.build();
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100599 }
600
mjhalupka7675dbd2018-01-29 12:46:58 -0800601 private void addExtraActionsIfRequested(
ulfjackb5daae32018-06-13 07:59:33 -0700602 AnalysisOptions viewOptions,
Dmitry Lomovcf6021a2016-08-09 16:49:32 +0000603 Collection<ConfiguredTarget> configuredTargets,
604 Collection<AspectValue> aspects,
janakrccb74562018-07-30 10:56:57 -0700605 ArtifactsToOwnerLabels.Builder artifactsToTopLevelLabelsMap,
mjhalupka7675dbd2018-01-29 12:46:58 -0800606 ExtendedEventHandler eventHandler) {
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100607 RegexFilter filter = viewOptions.extraActionFilter;
Carmi Grushkodf9e5e12016-11-08 23:07:57 +0000608 for (ConfiguredTarget target : configuredTargets) {
609 ExtraActionArtifactsProvider provider =
610 target.getProvider(ExtraActionArtifactsProvider.class);
611 if (provider != null) {
612 if (viewOptions.extraActionTopLevelOnly) {
lberki9137a752017-06-09 12:49:10 +0200613 // Collect all aspect-classes that topLevel might inject.
614 Set<AspectClass> aspectClasses = new HashSet<>();
mjhalupka7675dbd2018-01-29 12:46:58 -0800615 Target actualTarget = null;
616 try {
617 actualTarget =
618 skyframeExecutor.getPackageManager().getTarget(eventHandler, target.getLabel());
619 } catch (NoSuchPackageException | NoSuchTargetException | InterruptedException e) {
620 eventHandler.handle(Event.error(""));
621 }
622 for (Attribute attr : actualTarget.getAssociatedRule().getAttributes()) {
lberki9137a752017-06-09 12:49:10 +0200623 aspectClasses.addAll(attr.getAspectClasses());
624 }
janakr75bc18a2018-07-13 00:52:17 -0700625 TopLevelArtifactHelper.addArtifactsWithOwnerLabel(
626 provider.getExtraActionArtifacts(),
627 filter,
628 target.getLabel(),
629 artifactsToTopLevelLabelsMap);
lberki9137a752017-06-09 12:49:10 +0200630 if (!aspectClasses.isEmpty()) {
janakr75bc18a2018-07-13 00:52:17 -0700631 TopLevelArtifactHelper.addArtifactsWithOwnerLabel(
632 filterTransitiveExtraActions(provider, aspectClasses),
633 filter,
634 target.getLabel(),
635 artifactsToTopLevelLabelsMap);
Carmi Grushkodf9e5e12016-11-08 23:07:57 +0000636 }
Carmi Grushkodf9e5e12016-11-08 23:07:57 +0000637 } else {
janakr75bc18a2018-07-13 00:52:17 -0700638 TopLevelArtifactHelper.addArtifactsWithOwnerLabel(
639 provider.getTransitiveExtraActionArtifacts(),
640 filter,
641 target.getLabel(),
642 artifactsToTopLevelLabelsMap);
Carmi Grushkodf9e5e12016-11-08 23:07:57 +0000643 }
644 }
645 }
janakr75bc18a2018-07-13 00:52:17 -0700646 for (AspectValue aspect : aspects) {
647 ExtraActionArtifactsProvider provider =
648 aspect.getConfiguredAspect().getProvider(ExtraActionArtifactsProvider.class);
649 if (provider != null) {
650 if (viewOptions.extraActionTopLevelOnly) {
651 TopLevelArtifactHelper.addArtifactsWithOwnerLabel(
652 provider.getExtraActionArtifacts(),
653 filter,
654 aspect.getLabel(),
655 artifactsToTopLevelLabelsMap);
656 } else {
657 TopLevelArtifactHelper.addArtifactsWithOwnerLabel(
658 provider.getTransitiveExtraActionArtifacts(),
659 filter,
660 aspect.getLabel(),
661 artifactsToTopLevelLabelsMap);
662 }
663 }
664 }
Carmi Grushkodf9e5e12016-11-08 23:07:57 +0000665 }
666
667 /**
janakr658d47f2019-05-29 11:11:30 -0700668 * Returns a list of artifacts from 'provider' that were registered by an aspect from
669 * 'aspectClasses'. All artifacts in 'provider' are considered - both direct and transitive.
Carmi Grushkodf9e5e12016-11-08 23:07:57 +0000670 */
671 private ImmutableList<Artifact> filterTransitiveExtraActions(
672 ExtraActionArtifactsProvider provider, Set<AspectClass> aspectClasses) {
673 ImmutableList.Builder<Artifact> artifacts = ImmutableList.builder();
674 // Add to 'artifacts' all extra-actions which were registered by aspects which 'topLevel'
675 // might have injected.
janakrefb3f152019-06-05 17:42:34 -0700676 for (Artifact.DerivedArtifact artifact : provider.getTransitiveExtraActionArtifacts()) {
677 ActionLookupValue.ActionLookupKey owner = artifact.getArtifactOwner();
Carmi Grushkobabd4852016-11-18 17:58:09 +0000678 if (owner instanceof AspectKey) {
679 if (aspectClasses.contains(((AspectKey) owner).getAspectClass())) {
680 artifacts.add(artifact);
Carmi Grushkodf9e5e12016-11-08 23:07:57 +0000681 }
682 }
683 }
684 return artifacts.build();
685 }
686
mjhalupka7675dbd2018-01-29 12:46:58 -0800687 private static void scheduleTestsIfRequested(
688 Collection<ConfiguredTarget> targetsToTest,
689 Collection<ConfiguredTarget> targetsToTestExclusive,
690 TopLevelArtifactContext topLevelOptions,
691 Collection<ConfiguredTarget> allTestTargets,
692 SkyframeExecutor skyframeExecutor,
693 ExtendedEventHandler eventHandler)
694 throws InterruptedException {
Lukacs Berki3f4d4e92015-02-24 10:28:26 +0000695 Set<String> outputGroups = topLevelOptions.outputGroups();
dslomov69c45f82017-12-14 11:15:43 -0500696 if (!outputGroups.contains(OutputGroupInfo.FILES_TO_COMPILE)
697 && !outputGroups.contains(OutputGroupInfo.COMPILATION_PREREQUISITES)
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100698 && allTestTargets != null) {
mjhalupka7675dbd2018-01-29 12:46:58 -0800699 scheduleTests(
700 targetsToTest,
701 targetsToTestExclusive,
702 allTestTargets,
703 topLevelOptions.runTestsExclusively(),
704 skyframeExecutor,
705 eventHandler);
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100706 }
707 }
708
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100709 /**
710 * Returns set of artifacts representing test results, writing into targetsToTest and
711 * targetsToTestExclusive.
712 */
mjhalupka7675dbd2018-01-29 12:46:58 -0800713 private static void scheduleTests(
714 Collection<ConfiguredTarget> targetsToTest,
715 Collection<ConfiguredTarget> targetsToTestExclusive,
716 Collection<ConfiguredTarget> allTestTargets,
717 boolean isExclusive,
718 SkyframeExecutor skyframeExecutor,
719 ExtendedEventHandler eventHandler)
720 throws InterruptedException {
721 for (ConfiguredTarget configuredTarget : allTestTargets) {
722 Target target = null;
723 try {
724 target =
725 skyframeExecutor
726 .getPackageManager()
727 .getTarget(eventHandler, configuredTarget.getLabel());
728 } catch (NoSuchTargetException | NoSuchPackageException e) {
729 eventHandler.handle(Event.error("Failed to get target when scheduling tests"));
730 continue;
731 }
732 if (target instanceof Rule) {
733 boolean exclusive = isExclusive || TargetUtils.isExclusiveTestRule((Rule) target);
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100734 Collection<ConfiguredTarget> testCollection = exclusive
735 ? targetsToTestExclusive
736 : targetsToTest;
mjhalupka7675dbd2018-01-29 12:46:58 -0800737 testCollection.add(configuredTarget);
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100738 }
739 }
740 }
741
Greg Estren7971e672016-06-01 23:22:48 +0000742 /**
Ulf Adamsa385d3e2015-09-28 13:21:45 +0000743 * Sets the possible artifact roots in the artifact factory. This allows the factory to resolve
744 * paths with unknown roots to artifacts.
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100745 */
ulfjack865b6212018-06-14 03:41:55 -0700746 private void setArtifactRoots(PackageRoots packageRoots) {
janakrae323982017-09-29 21:11:53 +0200747 getArtifactFactory().setPackageRoots(packageRoots.getPackageRootLookup());
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100748 }
749
750 /**
Ulf Adams9c505cb2015-09-28 13:38:14 +0000751 * Tests and clears the current thread's pending "interrupted" status, and
752 * throws InterruptedException iff it was set.
753 */
ulfjack865b6212018-06-14 03:41:55 -0700754 private final void pollInterruptedStatus() throws InterruptedException {
Ulf Adams9c505cb2015-09-28 13:38:14 +0000755 if (Thread.interrupted()) {
756 throw new InterruptedException();
757 }
758 }
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100759}