blob: 74f0b84b62a85fa4ebe9df472bdae64b49ad001b [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;
janakrdbd34bc2019-06-17 06:12:48 -070030import com.google.common.flogger.GoogleLogger;
Rumou Duan33bab462016-04-25 17:55:12 +000031import com.google.devtools.build.lib.actions.ActionAnalysisMetadata;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010032import com.google.devtools.build.lib.actions.ActionGraph;
janakrefb3f152019-06-05 17:42:34 -070033import com.google.devtools.build.lib.actions.ActionLookupData;
jhorvitz3daedc32020-07-22 18:33:55 -070034import com.google.devtools.build.lib.actions.ActionLookupKey;
janakr93e3eea2017-03-30 22:09:37 +000035import com.google.devtools.build.lib.actions.ActionLookupValue;
janakrefb3f152019-06-05 17:42:34 -070036import com.google.devtools.build.lib.actions.Actions;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010037import com.google.devtools.build.lib.actions.Artifact;
38import com.google.devtools.build.lib.actions.ArtifactFactory;
janakrae323982017-09-29 21:11:53 +020039import com.google.devtools.build.lib.actions.PackageRoots;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010040import com.google.devtools.build.lib.analysis.config.BuildConfiguration;
41import com.google.devtools.build.lib.analysis.config.BuildConfigurationCollection;
ulfjack36fbbde2018-08-02 05:16:00 -070042import com.google.devtools.build.lib.analysis.config.BuildOptions;
juliexxiab75e45302019-05-24 07:48:39 -070043import com.google.devtools.build.lib.analysis.config.ConfigurationResolver.TopLevelTargetsAndConfigsResult;
ulfjack36fbbde2018-08-02 05:16:00 -070044import com.google.devtools.build.lib.analysis.config.InvalidConfigurationException;
gregce45ae0962017-07-22 00:11:13 +020045import com.google.devtools.build.lib.analysis.constraints.TopLevelConstraintSemantics;
ulfjackab21d182017-08-10 15:36:14 +020046import com.google.devtools.build.lib.analysis.test.CoverageReportActionFactory;
47import com.google.devtools.build.lib.analysis.test.CoverageReportActionFactory.CoverageReportActionsWrapper;
cparsonsb83c5f82018-11-21 14:46:57 -080048import com.google.devtools.build.lib.analysis.test.InstrumentedFilesInfo;
Lukacs Berki6e91eb92015-09-21 09:12:37 +000049import com.google.devtools.build.lib.cmdline.Label;
Googlerb2e1fe32019-09-20 14:00:39 -070050import com.google.devtools.build.lib.cmdline.LabelSyntaxException;
Lukacs Berki6916be22015-02-19 13:36:06 +000051import com.google.devtools.build.lib.collect.nestedset.NestedSet;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010052import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010053import com.google.devtools.build.lib.concurrent.ThreadSafety.ThreadCompatible;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010054import com.google.devtools.build.lib.events.Event;
Klaus Aehlig777b30d2017-02-24 16:30:15 +000055import com.google.devtools.build.lib.events.ExtendedEventHandler;
Carmi Grushkodf9e5e12016-11-08 23:07:57 +000056import com.google.devtools.build.lib.packages.AspectClass;
Dmitry Lomov15756522016-12-16 16:52:37 +000057import com.google.devtools.build.lib.packages.AspectDescriptor;
Dmitry Lomovca9bfa42016-11-15 13:22:36 +000058import com.google.devtools.build.lib.packages.AspectParameters;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010059import com.google.devtools.build.lib.packages.Attribute;
Dmitry Lomov8ff06452015-10-21 19:16:30 +000060import com.google.devtools.build.lib.packages.NativeAspectClass;
Cal Peyser8a638d52017-03-24 15:44:24 +000061import com.google.devtools.build.lib.packages.NoSuchPackageException;
62import com.google.devtools.build.lib.packages.NoSuchTargetException;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010063import com.google.devtools.build.lib.packages.Rule;
64import com.google.devtools.build.lib.packages.Target;
65import com.google.devtools.build.lib.packages.TargetUtils;
laszlocsomord237db72020-01-09 08:15:07 -080066import com.google.devtools.build.lib.pkgcache.PackageManager;
nharmatac4335cf2017-07-18 21:39:13 +020067import com.google.devtools.build.lib.pkgcache.PackageManager.PackageManagerStatistics;
ulfjack36fbbde2018-08-02 05:16:00 -070068import com.google.devtools.build.lib.profiler.Profiler;
69import com.google.devtools.build.lib.profiler.SilentCloseable;
mschaller75216c72020-06-25 16:04:29 -070070import com.google.devtools.build.lib.server.FailureDetails;
71import com.google.devtools.build.lib.server.FailureDetails.Analysis;
72import com.google.devtools.build.lib.server.FailureDetails.FailureDetail;
73import com.google.devtools.build.lib.server.FailureDetails.TargetPatterns;
74import com.google.devtools.build.lib.server.FailureDetails.TargetPatterns.Code;
jcater40549e72020-04-16 10:52:40 -070075import com.google.devtools.build.lib.skyframe.AspectValueKey;
76import com.google.devtools.build.lib.skyframe.AspectValueKey.AspectKey;
ulfjack06295192019-01-16 09:13:34 -080077import com.google.devtools.build.lib.skyframe.BuildConfigurationValue;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010078import com.google.devtools.build.lib.skyframe.ConfiguredTargetKey;
79import com.google.devtools.build.lib.skyframe.CoverageReportValue;
ulfjack36fbbde2018-08-02 05:16:00 -070080import com.google.devtools.build.lib.skyframe.PrepareAnalysisPhaseValue;
Dmitry Lomove2033b12015-08-19 16:57:49 +000081import com.google.devtools.build.lib.skyframe.SkyframeAnalysisResult;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010082import com.google.devtools.build.lib.skyframe.SkyframeBuildView;
83import com.google.devtools.build.lib.skyframe.SkyframeExecutor;
ulfjack12bb59f52018-07-25 07:19:24 -070084import com.google.devtools.build.lib.skyframe.TargetPatternPhaseValue;
Klaus Aehligc27b4da2017-09-01 10:33:22 +020085import com.google.devtools.build.lib.util.Pair;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010086import com.google.devtools.build.lib.util.RegexFilter;
Laszlo Csomor2bef7782020-01-07 01:15:16 -080087import com.google.devtools.build.skyframe.SkyKey;
Eric Fellheimer9c1e12f2015-08-06 20:23:55 +000088import com.google.devtools.build.skyframe.WalkableGraph;
Dmitry Lomove2033b12015-08-19 16:57:49 +000089import java.util.ArrayList;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010090import java.util.Collection;
ulfjack06295192019-01-16 09:13:34 -080091import java.util.HashMap;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010092import java.util.HashSet;
93import java.util.LinkedHashSet;
94import java.util.List;
ulfjack06295192019-01-16 09:13:34 -080095import java.util.Map;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010096import java.util.Set;
janakrdbd34bc2019-06-17 06:12:48 -070097import java.util.concurrent.TimeUnit;
janakr1a4066a2020-04-13 13:24:27 -070098import java.util.function.Predicate;
mjhalupka7675dbd2018-01-29 12:46:58 -080099import java.util.stream.Collectors;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100100import javax.annotation.Nullable;
101
102/**
ulfjack865b6212018-06-14 03:41:55 -0700103 * The BuildView presents a semantically-consistent and transitively-closed
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100104 * dependency graph for some set of packages.
105 *
106 * <h2>Package design</h2>
107 *
108 * <p>This package contains the Blaze dependency analysis framework (aka
109 * "analysis phase"). The goal of this code is to perform semantic analysis of
110 * all of the build targets required for a given build, to report
111 * errors/warnings for any problems in the input, and to construct an "action
112 * graph" (see {@code lib.actions} package) correctly representing the work to
113 * be done during the execution phase of the build.
114 *
115 * <p><b>Configurations</b> the inputs to a build come from two sources: the
116 * intrinsic inputs, specified in the BUILD file, are called <em>targets</em>.
117 * The environmental inputs, coming from the build tool, the command-line, or
118 * configuration files, are called the <em>configuration</em>. Only when a
119 * target and a configuration are combined is there sufficient information to
120 * perform a build. </p>
121 *
122 * <p>Targets are implemented by the {@link Target} hierarchy in the {@code
123 * lib.packages} code. Configurations are implemented by {@link
124 * BuildConfiguration}. The pair of these together is represented by an
125 * instance of class {@link ConfiguredTarget}; this is the root of a hierarchy
126 * with different implementations for each kind of target: source file, derived
127 * file, rules, etc.
128 *
129 * <p>The framework code in this package (as opposed to its subpackages) is
130 * responsible for constructing the {@code ConfiguredTarget} graph for a given
131 * target and configuration, taking care of such issues as:
132 * <ul>
133 * <li>caching common subgraphs.
134 * <li>detecting and reporting cycles.
135 * <li>correct propagation of errors through the graph.
136 * <li>reporting universal errors, such as dependencies from production code
137 * to tests, or to experimental branches.
138 * <li>capturing and replaying errors.
139 * <li>maintaining the graph from one build to the next to
140 * avoid unnecessary recomputation.
141 * <li>checking software licenses.
142 * </ul>
143 *
144 * <p>See also {@link ConfiguredTarget} which documents some important
145 * invariants.
146 */
147public class BuildView {
janakrdbd34bc2019-06-17 06:12:48 -0700148 private static final GoogleLogger logger = GoogleLogger.forEnclosingClass();
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100149
150 private final BlazeDirectories directories;
151
152 private final SkyframeExecutor skyframeExecutor;
153 private final SkyframeBuildView skyframeBuildView;
154
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100155 private final ConfiguredRuleClassProvider ruleClassProvider;
156
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100157 /**
158 * A factory class to create the coverage report action. May be null.
159 */
160 @Nullable private final CoverageReportActionFactory coverageReportActionFactory;
161
Ulf Adams59dbf682015-09-17 11:36:43 +0000162 public BuildView(BlazeDirectories directories,
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100163 ConfiguredRuleClassProvider ruleClassProvider,
164 SkyframeExecutor skyframeExecutor,
Ulf Adams5a96d532015-09-26 09:00:57 +0000165 CoverageReportActionFactory coverageReportActionFactory) {
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100166 this.directories = directories;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100167 this.coverageReportActionFactory = coverageReportActionFactory;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100168 this.ruleClassProvider = ruleClassProvider;
169 this.skyframeExecutor = Preconditions.checkNotNull(skyframeExecutor);
Ulf Adams89eefd72015-09-23 08:00:43 +0000170 this.skyframeBuildView = skyframeExecutor.getSkyframeBuildView();
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100171 }
172
Laszlo Csomor2bef7782020-01-07 01:15:16 -0800173 /**
174 * Returns two numbers: number of analyzed and number of loaded targets.
175 *
176 * <p>The first number: configured targets freshly evaluated in the last analysis run.
177 *
178 * <p>The second number: targets (not configured targets) loaded in the last analysis run.
179 */
180 public Pair<Integer, Integer> getTargetsConfiguredAndLoaded() {
181 ImmutableSet<SkyKey> keys = skyframeBuildView.getEvaluatedTargetKeys();
182 int targetsConfigured = keys.size();
183 int targetsLoaded =
184 keys.stream().map(key -> ((ConfiguredTargetKey) key).getLabel()).collect(toSet()).size();
185 return Pair.of(targetsConfigured, targetsLoaded);
tomluf2720dc2018-10-02 12:10:51 -0700186 }
187
tomlua0e8aae2018-06-19 15:07:26 -0700188 public int getActionsConstructed() {
189 return skyframeBuildView.getEvaluatedActionCount();
190 }
191
ulfjack865b6212018-06-14 03:41:55 -0700192 public PackageManagerStatistics getAndClearPkgManagerStatistics() {
193 return skyframeExecutor.getPackageManager().getAndClearStatistics();
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100194 }
195
ulfjack865b6212018-06-14 03:41:55 -0700196 private ArtifactFactory getArtifactFactory() {
Ulf Adams89eefd72015-09-23 08:00:43 +0000197 return skyframeBuildView.getArtifactFactory();
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100198 }
199
mjhalupka7675dbd2018-01-29 12:46:58 -0800200 /** Returns the collection of configured targets corresponding to any of the provided targets. */
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100201 @VisibleForTesting
mjhalupkae253f832018-06-13 14:19:26 -0700202 static LinkedHashSet<ConfiguredTarget> filterTestsByTargets(
ulfjack12bb59f52018-07-25 07:19:24 -0700203 Collection<ConfiguredTarget> targets, Set<Label> allowedTargetLabels) {
mjhalupka7675dbd2018-01-29 12:46:58 -0800204 return targets
205 .stream()
mjhalupkae253f832018-06-13 14:19:26 -0700206 .filter(ct -> allowedTargetLabels.contains(ct.getLabel()))
207 .collect(Collectors.toCollection(LinkedHashSet::new));
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100208 }
209
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100210 @ThreadCompatible
Dmitry Lomove2033b12015-08-19 16:57:49 +0000211 public AnalysisResult update(
ulfjack12bb59f52018-07-25 07:19:24 -0700212 TargetPatternPhaseValue loadingResult,
ulfjack36fbbde2018-08-02 05:16:00 -0700213 BuildOptions targetOptions,
214 Set<String> multiCpu,
Dmitry Lomove2033b12015-08-19 16:57:49 +0000215 List<String> aspects,
ulfjackb5daae32018-06-13 07:59:33 -0700216 AnalysisOptions viewOptions,
juliexxia8a2baea2017-12-18 14:33:45 -0800217 boolean keepGoing,
juliexxiaf8b57c52017-12-21 11:37:46 -0800218 int loadingPhaseThreads,
Dmitry Lomove2033b12015-08-19 16:57:49 +0000219 TopLevelArtifactContext topLevelOptions,
Klaus Aehlig777b30d2017-02-24 16:30:15 +0000220 ExtendedEventHandler eventHandler,
Ulf Adams8c4ae672016-03-30 11:20:41 +0000221 EventBus eventBus)
ulfjack36fbbde2018-08-02 05:16:00 -0700222 throws ViewCreationFailedException, InvalidConfigurationException, InterruptedException {
janakrdbd34bc2019-06-17 06:12:48 -0700223 logger.atInfo().log("Starting analysis");
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100224 pollInterruptedStatus();
225
Laszlo Csomor2bef7782020-01-07 01:15:16 -0800226 skyframeBuildView.resetProgressReceiver();
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100227
ulfjack12bb59f52018-07-25 07:19:24 -0700228 // TODO(ulfjack): Expensive. Maybe we don't actually need the targets, only the labels?
229 Collection<Target> targets =
230 loadingResult.getTargets(eventHandler, skyframeExecutor.getPackageManager());
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100231 eventBus.post(new AnalysisPhaseStartedEvent(targets));
232
ulfjack36fbbde2018-08-02 05:16:00 -0700233 // Prepare the analysis phase
234 BuildConfigurationCollection configurations;
juliexxiab75e45302019-05-24 07:48:39 -0700235 TopLevelTargetsAndConfigsResult topLevelTargetsWithConfigsResult;
ulfjack36fbbde2018-08-02 05:16:00 -0700236 if (viewOptions.skyframePrepareAnalysis) {
237 PrepareAnalysisPhaseValue prepareAnalysisPhaseValue;
238 try (SilentCloseable c = Profiler.instance().profile("Prepare analysis phase")) {
239 prepareAnalysisPhaseValue = skyframeExecutor.prepareAnalysisPhase(
240 eventHandler, targetOptions, multiCpu, loadingResult.getTargetLabels());
ulfjack06295192019-01-16 09:13:34 -0800241
ulfjack36fbbde2018-08-02 05:16:00 -0700242 // Determine the configurations
243 configurations =
244 prepareAnalysisPhaseValue.getConfigurations(eventHandler, skyframeExecutor);
juliexxiab75e45302019-05-24 07:48:39 -0700245 topLevelTargetsWithConfigsResult =
ulfjack36fbbde2018-08-02 05:16:00 -0700246 prepareAnalysisPhaseValue.getTopLevelCts(eventHandler, skyframeExecutor);
247 }
248 } else {
249 // Configuration creation.
250 // TODO(gregce): Consider dropping this phase and passing on-the-fly target / host configs as
251 // needed. This requires cleaning up the invalidation in SkyframeBuildView.setConfigurations.
252 try (SilentCloseable c = Profiler.instance().profile("createConfigurations")) {
253 configurations =
254 skyframeExecutor
255 .createConfigurations(
256 eventHandler,
257 targetOptions,
258 multiCpu,
259 keepGoing);
260 }
261 try (SilentCloseable c = Profiler.instance().profile("AnalysisUtils.getTargetsWithConfigs")) {
juliexxiab75e45302019-05-24 07:48:39 -0700262 topLevelTargetsWithConfigsResult =
ulfjack36fbbde2018-08-02 05:16:00 -0700263 AnalysisUtils.getTargetsWithConfigs(
264 configurations, targets, eventHandler, ruleClassProvider, skyframeExecutor);
265 }
266 }
267
mstaib6cf62782018-11-14 11:54:33 -0800268 skyframeBuildView.setConfigurations(
269 eventHandler, configurations, viewOptions.maxConfigChangesToShow);
Marian Lobur86bd4fd2015-09-16 10:01:38 +0000270
ulfjack36fbbde2018-08-02 05:16:00 -0700271 if (configurations.getTargetConfigurations().size() == 1) {
272 eventBus
273 .post(
274 new MakeEnvironmentEvent(
275 configurations.getTargetConfigurations().get(0).getMakeEnvironment()));
276 }
felly392e3e42019-08-05 15:16:29 -0700277 for (BuildConfiguration targetConfig : configurations.getTargetConfigurations()) {
278 eventBus.post(targetConfig.toBuildEvent());
279 }
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100280
juliexxiab75e45302019-05-24 07:48:39 -0700281 Collection<TargetAndConfiguration> topLevelTargetsWithConfigs =
282 topLevelTargetsWithConfigsResult.getTargetsAndConfigs();
283
Klaus Aehlig71c993b2017-05-09 07:49:46 -0400284 // Report the generated association of targets to configurations
285 Multimap<Label, BuildConfiguration> byLabel =
286 ArrayListMultimap.<Label, BuildConfiguration>create();
287 for (TargetAndConfiguration pair : topLevelTargetsWithConfigs) {
288 byLabel.put(pair.getLabel(), pair.getConfiguration());
289 }
Klaus Aehlig2a92c902017-08-11 14:03:31 +0200290 for (Target target : targets) {
291 eventBus.post(new TargetConfiguredEvent(target, byLabel.get(target.getLabel())));
Klaus Aehlig71c993b2017-05-09 07:49:46 -0400292 }
293
janakr573807d2018-01-11 14:02:35 -0800294 List<ConfiguredTargetKey> topLevelCtKeys =
jcater83221e32020-05-28 11:37:39 -0700295 topLevelTargetsWithConfigs.stream()
jcater4488f0c2020-05-28 12:47:40 -0700296 .map(TargetAndConfiguration::getConfiguredTargetKey)
ulfjack36fbbde2018-08-02 05:16:00 -0700297 .collect(Collectors.toList());
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100298
Klaus Aehligc27b4da2017-09-01 10:33:22 +0200299 Multimap<Pair<Label, String>, BuildConfiguration> aspectConfigurations =
300 ArrayListMultimap.create();
Klaus Aehlig71c993b2017-05-09 07:49:46 -0400301
Dmitry Lomovc15ba2e2015-10-30 15:50:01 +0000302 List<AspectValueKey> aspectKeys = new ArrayList<>();
Dmitry Lomove2033b12015-08-19 16:57:49 +0000303 for (String aspect : aspects) {
Dmitry Lomov0b832ce2015-10-20 10:03:14 +0000304 // Syntax: label%aspect
305 int delimiterPosition = aspect.indexOf('%');
306 if (delimiterPosition >= 0) {
gregceca48e9a2020-04-14 08:54:38 -0700307 // TODO(jfield): For consistency with Starlark loads, the aspect should be specified
laurentlb940dbc52018-03-01 08:07:14 -0800308 // as an absolute label.
309 // We convert it for compatibility reasons (this will be removed in the future).
Dmitry Lomov51aafc12016-11-18 14:02:54 +0000310 String bzlFileLoadLikeString = aspect.substring(0, delimiterPosition);
311 if (!bzlFileLoadLikeString.startsWith("//") && !bzlFileLoadLikeString.startsWith("@")) {
312 // "Legacy" behavior of '--aspects' parameter.
laurentlb940dbc52018-03-01 08:07:14 -0800313 if (bzlFileLoadLikeString.startsWith("/")) {
314 bzlFileLoadLikeString = bzlFileLoadLikeString.substring(1);
315 }
316 int lastSlashPosition = bzlFileLoadLikeString.lastIndexOf('/');
317 if (lastSlashPosition >= 0) {
318 bzlFileLoadLikeString =
319 "//"
320 + bzlFileLoadLikeString.substring(0, lastSlashPosition)
321 + ":"
322 + bzlFileLoadLikeString.substring(lastSlashPosition + 1);
323 } else {
324 bzlFileLoadLikeString = "//:" + bzlFileLoadLikeString;
325 }
326 if (!bzlFileLoadLikeString.endsWith(".bzl")) {
327 bzlFileLoadLikeString = bzlFileLoadLikeString + ".bzl";
Dmitry Lomov51aafc12016-11-18 14:02:54 +0000328 }
329 }
gregce773b95f2020-05-19 09:51:09 -0700330 Label starlarkFileLabel;
Dmitry Lomov51aafc12016-11-18 14:02:54 +0000331 try {
gregce773b95f2020-05-19 09:51:09 -0700332 starlarkFileLabel =
Googlerb2e1fe32019-09-20 14:00:39 -0700333 Label.parseAbsolute(
dannarkf4b9ff42018-06-12 09:28:45 -0700334 bzlFileLoadLikeString, /* repositoryMapping= */ ImmutableMap.of());
Googlerb2e1fe32019-09-20 14:00:39 -0700335 } catch (LabelSyntaxException e) {
Dmitry Lomov51aafc12016-11-18 14:02:54 +0000336 throw new ViewCreationFailedException(
337 String.format("Invalid aspect '%s': %s", aspect, e.getMessage()), e);
338 }
Dmitry Lomov0b832ce2015-10-20 10:03:14 +0000339
gregce773b95f2020-05-19 09:51:09 -0700340 String starlarkFunctionName = aspect.substring(delimiterPosition + 1);
Dmitry Lomov01f85c02016-06-29 06:37:50 +0000341 for (TargetAndConfiguration targetSpec : topLevelTargetsWithConfigs) {
mstaib7c7a7012019-04-23 16:19:09 -0700342 if (targetSpec.getConfiguration() != null
343 && targetSpec.getConfiguration().trimConfigurationsRetroactively()) {
344 throw new ViewCreationFailedException(
345 "Aspects were requested, but are not supported in retroactive trimming mode.");
346 }
Klaus Aehligc27b4da2017-09-01 10:33:22 +0200347 aspectConfigurations.put(
348 Pair.of(targetSpec.getLabel(), aspect), targetSpec.getConfiguration());
Dmitry Lomove2033b12015-08-19 16:57:49 +0000349 aspectKeys.add(
gregce5c8a5f52020-05-13 10:35:36 -0700350 AspectValueKey.createStarlarkAspectKey(
Dmitry Lomov0b832ce2015-10-20 10:03:14 +0000351 targetSpec.getLabel(),
Michael Staib04f6f242016-03-01 15:40:29 +0000352 // For invoking top-level aspects, use the top-level configuration for both the
353 // aspect and the base target while the top-level configuration is untrimmed.
354 targetSpec.getConfiguration(),
Dmitry Lomov0b832ce2015-10-20 10:03:14 +0000355 targetSpec.getConfiguration(),
gregce773b95f2020-05-19 09:51:09 -0700356 starlarkFileLabel,
357 starlarkFunctionName));
Dmitry Lomove2033b12015-08-19 16:57:49 +0000358 }
359 } else {
Luis Fernando Pino Duquee82713d2016-04-26 16:22:38 +0000360 final NativeAspectClass aspectFactoryClass =
361 ruleClassProvider.getNativeAspectClassMap().get(aspect);
dslomov99ea6b42017-04-25 17:46:17 +0200362
Dmitry Lomov0b832ce2015-10-20 10:03:14 +0000363 if (aspectFactoryClass != null) {
Dmitry Lomov01f85c02016-06-29 06:37:50 +0000364 for (TargetAndConfiguration targetSpec : topLevelTargetsWithConfigs) {
mstaib7c7a7012019-04-23 16:19:09 -0700365 if (targetSpec.getConfiguration() != null
366 && targetSpec.getConfiguration().trimConfigurationsRetroactively()) {
367 throw new ViewCreationFailedException(
368 "Aspects were requested, but are not supported in retroactive trimming mode.");
369 }
Dmitry Lomovca9bfa42016-11-15 13:22:36 +0000370 // For invoking top-level aspects, use the top-level configuration for both the
371 // aspect and the base target while the top-level configuration is untrimmed.
372 BuildConfiguration configuration = targetSpec.getConfiguration();
Klaus Aehligc27b4da2017-09-01 10:33:22 +0200373 aspectConfigurations.put(Pair.of(targetSpec.getLabel(), aspect), configuration);
Dmitry Lomov0b832ce2015-10-20 10:03:14 +0000374 aspectKeys.add(
jcater40549e72020-04-16 10:52:40 -0700375 AspectValueKey.createAspectKey(
Dmitry Lomov8ff06452015-10-21 19:16:30 +0000376 targetSpec.getLabel(),
Dmitry Lomovca9bfa42016-11-15 13:22:36 +0000377 configuration,
dslomovfa50c3d2017-05-08 08:47:44 -0400378 new AspectDescriptor(aspectFactoryClass, AspectParameters.EMPTY),
jcater40549e72020-04-16 10:52:40 -0700379 configuration));
Dmitry Lomov0b832ce2015-10-20 10:03:14 +0000380 }
381 } else {
382 throw new ViewCreationFailedException("Aspect '" + aspect + "' is unknown");
383 }
Dmitry Lomove2033b12015-08-19 16:57:49 +0000384 }
385 }
386
Klaus Aehligc27b4da2017-09-01 10:33:22 +0200387 for (Pair<Label, String> target : aspectConfigurations.keys()) {
388 eventBus.post(
389 new AspectConfiguredEvent(
390 target.getFirst(), target.getSecond(), aspectConfigurations.get(target)));
391 }
392
janakr1f08d4c82018-09-15 16:33:35 -0700393 getArtifactFactory().noteAnalysisStarting();
Dmitry Lomove2033b12015-08-19 16:57:49 +0000394 SkyframeAnalysisResult skyframeAnalysisResult;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100395 try {
ulfjack06295192019-01-16 09:13:34 -0800396 Supplier<Map<BuildConfigurationValue.Key, BuildConfiguration>> configurationLookupSupplier =
397 () -> {
398 Map<BuildConfigurationValue.Key, BuildConfiguration> result = new HashMap<>();
399 for (TargetAndConfiguration node : topLevelTargetsWithConfigs) {
400 if (node.getConfiguration() != null) {
401 result.put(
402 BuildConfigurationValue.key(node.getConfiguration()), node.getConfiguration());
403 }
404 }
405 return result;
406 };
Dmitry Lomove2033b12015-08-19 16:57:49 +0000407 skyframeAnalysisResult =
408 skyframeBuildView.configureTargets(
ulfjack06295192019-01-16 09:13:34 -0800409 eventHandler,
410 topLevelCtKeys,
411 aspectKeys,
412 Suppliers.memoize(configurationLookupSupplier),
janakr6d185b82020-03-30 14:08:01 -0700413 topLevelOptions,
ulfjack06295192019-01-16 09:13:34 -0800414 eventBus,
415 keepGoing,
janakr1a4066a2020-04-13 13:24:27 -0700416 loadingPhaseThreads,
417 viewOptions.strictConflictChecks);
Kristina Chodorow94e27422016-08-25 14:17:30 +0000418 setArtifactRoots(skyframeAnalysisResult.getPackageRoots());
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100419 } finally {
420 skyframeBuildView.clearInvalidatedConfiguredTargets();
421 }
422
Greg Estren7971e672016-06-01 23:22:48 +0000423 int numTargetsToAnalyze = topLevelTargetsWithConfigs.size();
Dmitry Lomove2033b12015-08-19 16:57:49 +0000424 int numSuccessful = skyframeAnalysisResult.getConfiguredTargets().size();
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100425 if (0 < numSuccessful && numSuccessful < numTargetsToAnalyze) {
426 String msg = String.format("Analysis succeeded for only %d of %d top-level targets",
427 numSuccessful, numTargetsToAnalyze);
428 eventHandler.handle(Event.info(msg));
janakrdbd34bc2019-06-17 06:12:48 -0700429 logger.atInfo().log(msg);
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100430 }
431
gregce45ae0962017-07-22 00:11:13 +0200432 Set<ConfiguredTarget> targetsToSkip =
janakr171a7eb2018-03-26 09:26:53 -0700433 new TopLevelConstraintSemantics(
434 skyframeExecutor.getPackageManager(),
435 input -> skyframeExecutor.getConfiguration(eventHandler, input),
436 eventHandler)
gregce21fdc482017-12-05 16:10:47 -0800437 .checkTargetEnvironmentRestrictions(skyframeAnalysisResult.getConfiguredTargets());
gregce45ae0962017-07-22 00:11:13 +0200438
Dmitry Lomove2033b12015-08-19 16:57:49 +0000439 AnalysisResult result =
440 createResult(
Ulf Adams5b9009b2015-09-24 09:52:53 +0000441 eventHandler,
ulfjackb2cb6402019-01-24 04:04:48 -0800442 eventBus,
Dmitry Lomove2033b12015-08-19 16:57:49 +0000443 loadingResult,
ulfjack940fbd72018-06-15 03:23:58 -0700444 configurations,
Dmitry Lomove2033b12015-08-19 16:57:49 +0000445 topLevelOptions,
446 viewOptions,
gregce45ae0962017-07-22 00:11:13 +0200447 skyframeAnalysisResult,
juliexxia693abdc2018-01-03 08:59:18 -0800448 targetsToSkip,
juliexxiab75e45302019-05-24 07:48:39 -0700449 topLevelTargetsWithConfigsResult);
janakrdbd34bc2019-06-17 06:12:48 -0700450 logger.atInfo().log("Finished analysis");
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100451 return result;
452 }
453
Dmitry Lomove2033b12015-08-19 16:57:49 +0000454 private AnalysisResult createResult(
Klaus Aehlig777b30d2017-02-24 16:30:15 +0000455 ExtendedEventHandler eventHandler,
ulfjackb2cb6402019-01-24 04:04:48 -0800456 EventBus eventBus,
ulfjack12bb59f52018-07-25 07:19:24 -0700457 TargetPatternPhaseValue loadingResult,
ulfjack940fbd72018-06-15 03:23:58 -0700458 BuildConfigurationCollection configurations,
Dmitry Lomove2033b12015-08-19 16:57:49 +0000459 TopLevelArtifactContext topLevelOptions,
ulfjackb5daae32018-06-13 07:59:33 -0700460 AnalysisOptions viewOptions,
gregce45ae0962017-07-22 00:11:13 +0200461 SkyframeAnalysisResult skyframeAnalysisResult,
juliexxia693abdc2018-01-03 08:59:18 -0800462 Set<ConfiguredTarget> targetsToSkip,
juliexxiab75e45302019-05-24 07:48:39 -0700463 TopLevelTargetsAndConfigsResult topLevelTargetsWithConfigs)
Klaus Aehlig777b30d2017-02-24 16:30:15 +0000464 throws InterruptedException {
ulfjack12bb59f52018-07-25 07:19:24 -0700465 Set<Label> testsToRun = loadingResult.getTestsToRunLabels();
gregce45ae0962017-07-22 00:11:13 +0200466 Set<ConfiguredTarget> configuredTargets =
467 Sets.newLinkedHashSet(skyframeAnalysisResult.getConfiguredTargets());
janakrf15d08d2020-04-22 12:53:03 -0700468 ImmutableMap<AspectKey, ConfiguredAspect> aspects = skyframeAnalysisResult.getAspects();
Dmitry Lomovcf6021a2016-08-09 16:49:32 +0000469
gregce45ae0962017-07-22 00:11:13 +0200470 Set<ConfiguredTarget> allTargetsToTest = null;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100471 if (testsToRun != null) {
472 // Determine the subset of configured targets that are meant to be run as tests.
mjhalupkae253f832018-06-13 14:19:26 -0700473 allTargetsToTest = filterTestsByTargets(configuredTargets, testsToRun);
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100474 }
475
janakrccb74562018-07-30 10:56:57 -0700476 ArtifactsToOwnerLabels.Builder artifactsToOwnerLabelsBuilder =
477 new ArtifactsToOwnerLabels.Builder();
Ulf Adamsfc154ae2015-08-31 12:32:14 +0000478
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100479 // build-info and build-changelist.
Ulf Adams5b9009b2015-09-24 09:52:53 +0000480 Collection<Artifact> buildInfoArtifacts =
481 skyframeExecutor.getWorkspaceStatusArtifacts(eventHandler);
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100482 Preconditions.checkState(buildInfoArtifacts.size() == 2, buildInfoArtifacts);
Ulf Adamsfc154ae2015-08-31 12:32:14 +0000483
484 // Extra actions
mjhalupka7675dbd2018-01-29 12:46:58 -0800485 addExtraActionsIfRequested(
janakrccb74562018-07-30 10:56:57 -0700486 viewOptions, configuredTargets, aspects, artifactsToOwnerLabelsBuilder, eventHandler);
Ulf Adamsfc154ae2015-08-31 12:32:14 +0000487
488 // Coverage
janakr75bc18a2018-07-13 00:52:17 -0700489 NestedSet<Artifact> baselineCoverageArtifacts =
janakrccb74562018-07-30 10:56:57 -0700490 getBaselineCoverageArtifacts(configuredTargets, artifactsToOwnerLabelsBuilder);
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100491 if (coverageReportActionFactory != null) {
Googlercdc90e92015-02-11 00:18:07 +0000492 CoverageReportActionsWrapper actionsWrapper;
janakr573807d2018-01-11 14:02:35 -0800493 actionsWrapper =
494 coverageReportActionFactory.createCoverageReportActionsWrapper(
495 eventHandler,
ulfjackb2cb6402019-01-24 04:04:48 -0800496 eventBus,
janakr573807d2018-01-11 14:02:35 -0800497 directories,
498 allTargetsToTest,
499 baselineCoverageArtifacts,
500 getArtifactFactory(),
janakrefb3f152019-06-05 17:42:34 -0700501 skyframeExecutor.getActionKeyContext(),
elenairina9438d102018-07-06 03:06:21 -0700502 CoverageReportValue.COVERAGE_REPORT_KEY,
503 loadingResult.getWorkspaceName());
Googlercdc90e92015-02-11 00:18:07 +0000504 if (actionsWrapper != null) {
janakrefb3f152019-06-05 17:42:34 -0700505 Actions.GeneratingActions actions = actionsWrapper.getActions();
Googlercdc90e92015-02-11 00:18:07 +0000506 skyframeExecutor.injectCoverageReportData(actions);
janakrccb74562018-07-30 10:56:57 -0700507 actionsWrapper.getCoverageOutputs().forEach(artifactsToOwnerLabelsBuilder::addArtifact);
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100508 }
509 }
janakr1a4066a2020-04-13 13:24:27 -0700510 // TODO(cparsons): If extra actions are ever removed, this filtering step can probably be
511 // removed as well: the only concern would be action conflicts involving coverage artifacts,
512 // which seems far-fetched.
513 if (skyframeAnalysisResult.hasActionConflicts()) {
514 ArtifactsToOwnerLabels tempOwners = artifactsToOwnerLabelsBuilder.build();
515 // We don't remove the (hopefully unnecessary) guard in SkyframeBuildView that enables/
516 // disables analysis, since no new targets should actually be analyzed.
517 Set<Artifact> artifacts = tempOwners.getArtifacts();
518 Predicate<Artifact> errorFreeArtifacts =
519 skyframeExecutor.filterActionConflictsForTopLevelArtifacts(eventHandler, artifacts);
520 artifactsToOwnerLabelsBuilder = tempOwners.toBuilder().filterArtifacts(errorFreeArtifacts);
521 }
522 // Build-info artifacts are always conflict-free, and can't be checked easily.
523 buildInfoArtifacts.forEach(artifactsToOwnerLabelsBuilder::addArtifact);
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100524
laszlocsomord237db72020-01-09 08:15:07 -0800525 // Tests.
526 Pair<ImmutableSet<ConfiguredTarget>, ImmutableSet<ConfiguredTarget>> testsPair =
527 collectTests(
528 topLevelOptions, allTargetsToTest, skyframeExecutor.getPackageManager(), eventHandler);
529 ImmutableSet<ConfiguredTarget> parallelTests = testsPair.first;
530 ImmutableSet<ConfiguredTarget> exclusiveTests = testsPair.second;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100531
mschaller75216c72020-06-25 16:04:29 -0700532 FailureDetail failureDetail =
533 createFailureDetail(loadingResult, skyframeAnalysisResult, topLevelTargetsWithConfigs);
Eric Fellheimer9c1e12f2015-08-06 20:23:55 +0000534
Ulf Adams53abece2016-02-03 08:30:07 +0000535 final WalkableGraph graph = skyframeAnalysisResult.getWalkableGraph();
Janak Ramakrishnan3c0adb22016-08-15 21:54:55 +0000536 final ActionGraph actionGraph =
537 new ActionGraph() {
538 @Nullable
539 @Override
540 public ActionAnalysisMetadata getGeneratingAction(Artifact artifact) {
janakrefb3f152019-06-05 17:42:34 -0700541 if (artifact.isSourceArtifact()) {
542 return null;
Janak Ramakrishnan3c0adb22016-08-15 21:54:55 +0000543 }
janakrefb3f152019-06-05 17:42:34 -0700544 ActionLookupData generatingActionKey =
545 ((Artifact.DerivedArtifact) artifact).getGeneratingActionKey();
546 ActionLookupValue val;
547 try {
548 val = (ActionLookupValue) graph.getValue(generatingActionKey.getActionLookupKey());
549 } catch (InterruptedException e) {
550 throw new IllegalStateException(
551 "Interruption not expected from this graph: " + generatingActionKey, e);
552 }
553 if (val == null) {
janakrdbd34bc2019-06-17 06:12:48 -0700554 logger.atWarning().atMostEvery(1, TimeUnit.SECONDS).log(
555 "Missing generating action for %s (%s)", artifact, generatingActionKey);
janakrefb3f152019-06-05 17:42:34 -0700556 return null;
557 }
Googler2714b882019-08-01 12:30:08 -0700558 return val.getActions().get(generatingActionKey.getActionIndex());
Janak Ramakrishnan3c0adb22016-08-15 21:54:55 +0000559 }
560 };
Dmitry Lomove2033b12015-08-19 16:57:49 +0000561 return new AnalysisResult(
ulfjack940fbd72018-06-15 03:23:58 -0700562 configurations,
laszlocsomor3c8883d2019-12-19 05:19:28 -0800563 ImmutableSet.copyOf(configuredTargets),
Dmitry Lomovcf6021a2016-08-09 16:49:32 +0000564 aspects,
laszlocsomor3c8883d2019-12-19 05:19:28 -0800565 allTargetsToTest == null ? null : ImmutableList.copyOf(allTargetsToTest),
566 ImmutableSet.copyOf(targetsToSkip),
mschaller75216c72020-06-25 16:04:29 -0700567 failureDetail,
Dmitry Lomove2033b12015-08-19 16:57:49 +0000568 actionGraph,
janakrccb74562018-07-30 10:56:57 -0700569 artifactsToOwnerLabelsBuilder.build(),
laszlocsomord237db72020-01-09 08:15:07 -0800570 parallelTests,
571 exclusiveTests,
Marian Lobur86bd4fd2015-09-16 10:01:38 +0000572 topLevelOptions,
Kristina Chodorow36a6c172016-07-22 15:18:07 +0000573 skyframeAnalysisResult.getPackageRoots(),
juliexxia693abdc2018-01-03 08:59:18 -0800574 loadingResult.getWorkspaceName(),
ichern121933e2020-01-27 02:08:19 -0800575 topLevelTargetsWithConfigs.getTargetsAndConfigs(),
576 loadingResult.getNotSymlinkedInExecrootDirectories());
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100577 }
578
juliexxiab75e45302019-05-24 07:48:39 -0700579 /**
580 * Check for errors in "chronological" order (acknowledge that loading and analysis are
581 * interleaved, but sequential on the single target scale).
582 */
Janak Ramakrishnan6f9d7d12016-08-09 08:45:34 +0000583 @Nullable
mschaller75216c72020-06-25 16:04:29 -0700584 public static FailureDetail createFailureDetail(
ulfjack12bb59f52018-07-25 07:19:24 -0700585 TargetPatternPhaseValue loadingResult,
juliexxiab75e45302019-05-24 07:48:39 -0700586 @Nullable SkyframeAnalysisResult skyframeAnalysisResult,
587 @Nullable TopLevelTargetsAndConfigsResult topLevelTargetsAndConfigs) {
588 if (loadingResult.hasError()) {
mschaller75216c72020-06-25 16:04:29 -0700589 return FailureDetail.newBuilder()
590 .setMessage("command succeeded, but there were errors parsing the target pattern")
591 .setTargetPatterns(TargetPatterns.newBuilder().setCode(Code.TARGET_PATTERN_PARSE_FAILURE))
592 .build();
juliexxiab75e45302019-05-24 07:48:39 -0700593 }
594 if (loadingResult.hasPostExpansionError()
595 || (skyframeAnalysisResult != null && skyframeAnalysisResult.hasLoadingError())) {
mschaller75216c72020-06-25 16:04:29 -0700596 return FailureDetail.newBuilder()
597 .setMessage("command succeeded, but there were loading phase errors")
598 .setAnalysis(Analysis.newBuilder().setCode(Analysis.Code.GENERIC_LOADING_PHASE_FAILURE))
599 .build();
juliexxiab75e45302019-05-24 07:48:39 -0700600 }
601 if (topLevelTargetsAndConfigs != null && topLevelTargetsAndConfigs.hasError()) {
mschaller75216c72020-06-25 16:04:29 -0700602 return FailureDetail.newBuilder()
603 .setMessage("command succeeded, but top level configurations could not be created")
604 .setBuildConfiguration(
605 FailureDetails.BuildConfiguration.newBuilder()
606 .setCode(
607 FailureDetails.BuildConfiguration.Code
608 .TOP_LEVEL_CONFIGURATION_CREATION_FAILURE))
609 .build();
juliexxiab75e45302019-05-24 07:48:39 -0700610 }
611 if (skyframeAnalysisResult != null && skyframeAnalysisResult.hasAnalysisError()) {
mschaller75216c72020-06-25 16:04:29 -0700612 return FailureDetail.newBuilder()
613 .setMessage("command succeeded, but not all targets were analyzed")
614 .setAnalysis(Analysis.newBuilder().setCode(Analysis.Code.NOT_ALL_TARGETS_ANALYZED))
615 .build();
juliexxiab75e45302019-05-24 07:48:39 -0700616 }
617 return null;
Janak Ramakrishnan6f9d7d12016-08-09 08:45:34 +0000618 }
619
Lukacs Berki6916be22015-02-19 13:36:06 +0000620 private static NestedSet<Artifact> getBaselineCoverageArtifacts(
janakr75bc18a2018-07-13 00:52:17 -0700621 Collection<ConfiguredTarget> configuredTargets,
janakrccb74562018-07-30 10:56:57 -0700622 ArtifactsToOwnerLabels.Builder topLevelArtifactsToOwnerLabels) {
Lukacs Berki6916be22015-02-19 13:36:06 +0000623 NestedSetBuilder<Artifact> baselineCoverageArtifacts = NestedSetBuilder.stableOrder();
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100624 for (ConfiguredTarget target : configuredTargets) {
gregceff941232020-04-21 08:03:32 -0700625 InstrumentedFilesInfo provider = target.get(InstrumentedFilesInfo.STARLARK_CONSTRUCTOR);
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100626 if (provider != null) {
janakr75bc18a2018-07-13 00:52:17 -0700627 TopLevelArtifactHelper.addArtifactsWithOwnerLabel(
628 provider.getBaselineCoverageArtifacts(),
629 null,
630 target.getLabel(),
631 topLevelArtifactsToOwnerLabels);
Ulf Adamsfc154ae2015-08-31 12:32:14 +0000632 baselineCoverageArtifacts.addTransitive(provider.getBaselineCoverageArtifacts());
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100633 }
634 }
Lukacs Berki6916be22015-02-19 13:36:06 +0000635 return baselineCoverageArtifacts.build();
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100636 }
637
mjhalupka7675dbd2018-01-29 12:46:58 -0800638 private void addExtraActionsIfRequested(
ulfjackb5daae32018-06-13 07:59:33 -0700639 AnalysisOptions viewOptions,
Dmitry Lomovcf6021a2016-08-09 16:49:32 +0000640 Collection<ConfiguredTarget> configuredTargets,
janakrf15d08d2020-04-22 12:53:03 -0700641 ImmutableMap<AspectKey, ConfiguredAspect> aspects,
janakrccb74562018-07-30 10:56:57 -0700642 ArtifactsToOwnerLabels.Builder artifactsToTopLevelLabelsMap,
mjhalupka7675dbd2018-01-29 12:46:58 -0800643 ExtendedEventHandler eventHandler) {
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100644 RegexFilter filter = viewOptions.extraActionFilter;
Carmi Grushkodf9e5e12016-11-08 23:07:57 +0000645 for (ConfiguredTarget target : configuredTargets) {
646 ExtraActionArtifactsProvider provider =
647 target.getProvider(ExtraActionArtifactsProvider.class);
648 if (provider != null) {
649 if (viewOptions.extraActionTopLevelOnly) {
lberki9137a752017-06-09 12:49:10 +0200650 // Collect all aspect-classes that topLevel might inject.
651 Set<AspectClass> aspectClasses = new HashSet<>();
mjhalupka7675dbd2018-01-29 12:46:58 -0800652 Target actualTarget = null;
653 try {
654 actualTarget =
655 skyframeExecutor.getPackageManager().getTarget(eventHandler, target.getLabel());
656 } catch (NoSuchPackageException | NoSuchTargetException | InterruptedException e) {
657 eventHandler.handle(Event.error(""));
658 }
659 for (Attribute attr : actualTarget.getAssociatedRule().getAttributes()) {
lberki9137a752017-06-09 12:49:10 +0200660 aspectClasses.addAll(attr.getAspectClasses());
661 }
janakr75bc18a2018-07-13 00:52:17 -0700662 TopLevelArtifactHelper.addArtifactsWithOwnerLabel(
663 provider.getExtraActionArtifacts(),
664 filter,
665 target.getLabel(),
666 artifactsToTopLevelLabelsMap);
lberki9137a752017-06-09 12:49:10 +0200667 if (!aspectClasses.isEmpty()) {
janakr75bc18a2018-07-13 00:52:17 -0700668 TopLevelArtifactHelper.addArtifactsWithOwnerLabel(
669 filterTransitiveExtraActions(provider, aspectClasses),
670 filter,
671 target.getLabel(),
672 artifactsToTopLevelLabelsMap);
Carmi Grushkodf9e5e12016-11-08 23:07:57 +0000673 }
Carmi Grushkodf9e5e12016-11-08 23:07:57 +0000674 } else {
janakr75bc18a2018-07-13 00:52:17 -0700675 TopLevelArtifactHelper.addArtifactsWithOwnerLabel(
676 provider.getTransitiveExtraActionArtifacts(),
677 filter,
678 target.getLabel(),
679 artifactsToTopLevelLabelsMap);
Carmi Grushkodf9e5e12016-11-08 23:07:57 +0000680 }
681 }
682 }
janakrf15d08d2020-04-22 12:53:03 -0700683 for (Map.Entry<AspectKey, ConfiguredAspect> aspectEntry : aspects.entrySet()) {
janakr75bc18a2018-07-13 00:52:17 -0700684 ExtraActionArtifactsProvider provider =
janakrf15d08d2020-04-22 12:53:03 -0700685 aspectEntry.getValue().getProvider(ExtraActionArtifactsProvider.class);
janakr75bc18a2018-07-13 00:52:17 -0700686 if (provider != null) {
687 if (viewOptions.extraActionTopLevelOnly) {
688 TopLevelArtifactHelper.addArtifactsWithOwnerLabel(
689 provider.getExtraActionArtifacts(),
690 filter,
janakrf15d08d2020-04-22 12:53:03 -0700691 aspectEntry.getKey().getLabel(),
janakr75bc18a2018-07-13 00:52:17 -0700692 artifactsToTopLevelLabelsMap);
693 } else {
694 TopLevelArtifactHelper.addArtifactsWithOwnerLabel(
695 provider.getTransitiveExtraActionArtifacts(),
696 filter,
janakrf15d08d2020-04-22 12:53:03 -0700697 aspectEntry.getKey().getLabel(),
janakr75bc18a2018-07-13 00:52:17 -0700698 artifactsToTopLevelLabelsMap);
699 }
700 }
701 }
Carmi Grushkodf9e5e12016-11-08 23:07:57 +0000702 }
703
704 /**
janakr658d47f2019-05-29 11:11:30 -0700705 * Returns a list of artifacts from 'provider' that were registered by an aspect from
706 * 'aspectClasses'. All artifacts in 'provider' are considered - both direct and transitive.
Carmi Grushkodf9e5e12016-11-08 23:07:57 +0000707 */
laszlocsomord237db72020-01-09 08:15:07 -0800708 private static ImmutableList<Artifact> filterTransitiveExtraActions(
Carmi Grushkodf9e5e12016-11-08 23:07:57 +0000709 ExtraActionArtifactsProvider provider, Set<AspectClass> aspectClasses) {
710 ImmutableList.Builder<Artifact> artifacts = ImmutableList.builder();
711 // Add to 'artifacts' all extra-actions which were registered by aspects which 'topLevel'
712 // might have injected.
ulfjack61216fd2019-12-18 12:31:03 -0800713 for (Artifact.DerivedArtifact artifact :
714 provider.getTransitiveExtraActionArtifacts().toList()) {
jhorvitz3daedc32020-07-22 18:33:55 -0700715 ActionLookupKey owner = artifact.getArtifactOwner();
Carmi Grushkobabd4852016-11-18 17:58:09 +0000716 if (owner instanceof AspectKey) {
717 if (aspectClasses.contains(((AspectKey) owner).getAspectClass())) {
718 artifacts.add(artifact);
Carmi Grushkodf9e5e12016-11-08 23:07:57 +0000719 }
720 }
721 }
722 return artifacts.build();
723 }
724
laszlocsomord237db72020-01-09 08:15:07 -0800725 private static Pair<ImmutableSet<ConfiguredTarget>, ImmutableSet<ConfiguredTarget>> collectTests(
mjhalupka7675dbd2018-01-29 12:46:58 -0800726 TopLevelArtifactContext topLevelOptions,
laszlocsomord237db72020-01-09 08:15:07 -0800727 @Nullable Iterable<ConfiguredTarget> allTestTargets,
728 PackageManager packageManager,
mjhalupka7675dbd2018-01-29 12:46:58 -0800729 ExtendedEventHandler eventHandler)
730 throws InterruptedException {
Lukacs Berki3f4d4e92015-02-24 10:28:26 +0000731 Set<String> outputGroups = topLevelOptions.outputGroups();
dslomov69c45f82017-12-14 11:15:43 -0500732 if (!outputGroups.contains(OutputGroupInfo.FILES_TO_COMPILE)
733 && !outputGroups.contains(OutputGroupInfo.COMPILATION_PREREQUISITES)
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100734 && allTestTargets != null) {
laszlocsomord237db72020-01-09 08:15:07 -0800735 final boolean isExclusive = topLevelOptions.runTestsExclusively();
736 ImmutableSet.Builder<ConfiguredTarget> targetsToTest = ImmutableSet.builder();
737 ImmutableSet.Builder<ConfiguredTarget> targetsToTestExclusive = ImmutableSet.builder();
738 for (ConfiguredTarget configuredTarget : allTestTargets) {
739 Target target = null;
740 try {
741 target = packageManager.getTarget(eventHandler, configuredTarget.getLabel());
742 } catch (NoSuchTargetException | NoSuchPackageException e) {
743 eventHandler.handle(Event.error("Failed to get target when scheduling tests"));
744 continue;
745 }
746 if (target instanceof Rule) {
747 if (isExclusive || TargetUtils.isExclusiveTestRule((Rule) target)) {
748 targetsToTestExclusive.add(configuredTarget);
749 } else {
750 targetsToTest.add(configuredTarget);
751 }
752 }
mjhalupka7675dbd2018-01-29 12:46:58 -0800753 }
laszlocsomord237db72020-01-09 08:15:07 -0800754 return Pair.of(targetsToTest.build(), targetsToTestExclusive.build());
755 } else {
756 return Pair.of(ImmutableSet.of(), ImmutableSet.of());
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100757 }
758 }
759
Greg Estren7971e672016-06-01 23:22:48 +0000760 /**
Ulf Adamsa385d3e2015-09-28 13:21:45 +0000761 * Sets the possible artifact roots in the artifact factory. This allows the factory to resolve
762 * paths with unknown roots to artifacts.
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100763 */
ulfjack865b6212018-06-14 03:41:55 -0700764 private void setArtifactRoots(PackageRoots packageRoots) {
janakrae323982017-09-29 21:11:53 +0200765 getArtifactFactory().setPackageRoots(packageRoots.getPackageRootLookup());
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100766 }
767
768 /**
Ulf Adams9c505cb2015-09-28 13:38:14 +0000769 * Tests and clears the current thread's pending "interrupted" status, and
770 * throws InterruptedException iff it was set.
771 */
ulfjack865b6212018-06-14 03:41:55 -0700772 private final void pollInterruptedStatus() throws InterruptedException {
Ulf Adams9c505cb2015-09-28 13:38:14 +0000773 if (Thread.interrupted()) {
774 throw new InterruptedException();
775 }
776 }
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100777}