blob: f5df8ce94da515a2f2016920d263bae67d8e311d [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;
Philipp Schrader22b4dbc2020-10-27 07:17:41 -070045import com.google.devtools.build.lib.analysis.constraints.PlatformRestrictionsResult;
gregcec2ba0272021-01-12 09:44:03 -080046import com.google.devtools.build.lib.analysis.constraints.RuleContextConstraintSemantics;
gregce45ae0962017-07-22 00:11:13 +020047import com.google.devtools.build.lib.analysis.constraints.TopLevelConstraintSemantics;
ulfjackab21d182017-08-10 15:36:14 +020048import com.google.devtools.build.lib.analysis.test.CoverageReportActionFactory;
49import com.google.devtools.build.lib.analysis.test.CoverageReportActionFactory.CoverageReportActionsWrapper;
cparsonsb83c5f82018-11-21 14:46:57 -080050import com.google.devtools.build.lib.analysis.test.InstrumentedFilesInfo;
Lukacs Berki6e91eb92015-09-21 09:12:37 +000051import com.google.devtools.build.lib.cmdline.Label;
Googlerb2e1fe32019-09-20 14:00:39 -070052import com.google.devtools.build.lib.cmdline.LabelSyntaxException;
Lukacs Berki6916be22015-02-19 13:36:06 +000053import com.google.devtools.build.lib.collect.nestedset.NestedSet;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010054import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010055import com.google.devtools.build.lib.concurrent.ThreadSafety.ThreadCompatible;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010056import com.google.devtools.build.lib.events.Event;
Klaus Aehlig777b30d2017-02-24 16:30:15 +000057import com.google.devtools.build.lib.events.ExtendedEventHandler;
Carmi Grushkodf9e5e12016-11-08 23:07:57 +000058import com.google.devtools.build.lib.packages.AspectClass;
Dmitry Lomov15756522016-12-16 16:52:37 +000059import com.google.devtools.build.lib.packages.AspectDescriptor;
Dmitry Lomovca9bfa42016-11-15 13:22:36 +000060import com.google.devtools.build.lib.packages.AspectParameters;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010061import com.google.devtools.build.lib.packages.Attribute;
Dmitry Lomov8ff06452015-10-21 19:16:30 +000062import com.google.devtools.build.lib.packages.NativeAspectClass;
Cal Peyser8a638d52017-03-24 15:44:24 +000063import com.google.devtools.build.lib.packages.NoSuchPackageException;
64import com.google.devtools.build.lib.packages.NoSuchTargetException;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010065import com.google.devtools.build.lib.packages.Rule;
66import com.google.devtools.build.lib.packages.Target;
67import com.google.devtools.build.lib.packages.TargetUtils;
laszlocsomord237db72020-01-09 08:15:07 -080068import com.google.devtools.build.lib.pkgcache.PackageManager;
nharmatac4335cf2017-07-18 21:39:13 +020069import com.google.devtools.build.lib.pkgcache.PackageManager.PackageManagerStatistics;
ulfjack36fbbde2018-08-02 05:16:00 -070070import com.google.devtools.build.lib.profiler.Profiler;
71import com.google.devtools.build.lib.profiler.SilentCloseable;
mschaller75216c72020-06-25 16:04:29 -070072import com.google.devtools.build.lib.server.FailureDetails;
73import com.google.devtools.build.lib.server.FailureDetails.Analysis;
74import com.google.devtools.build.lib.server.FailureDetails.FailureDetail;
75import com.google.devtools.build.lib.server.FailureDetails.TargetPatterns;
76import com.google.devtools.build.lib.server.FailureDetails.TargetPatterns.Code;
jcater40549e72020-04-16 10:52:40 -070077import com.google.devtools.build.lib.skyframe.AspectValueKey;
78import com.google.devtools.build.lib.skyframe.AspectValueKey.AspectKey;
ulfjack06295192019-01-16 09:13:34 -080079import com.google.devtools.build.lib.skyframe.BuildConfigurationValue;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010080import com.google.devtools.build.lib.skyframe.ConfiguredTargetKey;
81import com.google.devtools.build.lib.skyframe.CoverageReportValue;
ulfjack36fbbde2018-08-02 05:16:00 -070082import com.google.devtools.build.lib.skyframe.PrepareAnalysisPhaseValue;
Dmitry Lomove2033b12015-08-19 16:57:49 +000083import com.google.devtools.build.lib.skyframe.SkyframeAnalysisResult;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010084import com.google.devtools.build.lib.skyframe.SkyframeBuildView;
85import com.google.devtools.build.lib.skyframe.SkyframeExecutor;
ulfjack12bb59f52018-07-25 07:19:24 -070086import com.google.devtools.build.lib.skyframe.TargetPatternPhaseValue;
Klaus Aehligc27b4da2017-09-01 10:33:22 +020087import com.google.devtools.build.lib.util.Pair;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010088import com.google.devtools.build.lib.util.RegexFilter;
Laszlo Csomor2bef7782020-01-07 01:15:16 -080089import com.google.devtools.build.skyframe.SkyKey;
Eric Fellheimer9c1e12f2015-08-06 20:23:55 +000090import com.google.devtools.build.skyframe.WalkableGraph;
Dmitry Lomove2033b12015-08-19 16:57:49 +000091import java.util.ArrayList;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010092import java.util.Collection;
ulfjack06295192019-01-16 09:13:34 -080093import java.util.HashMap;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010094import java.util.HashSet;
95import java.util.LinkedHashSet;
96import java.util.List;
ulfjack06295192019-01-16 09:13:34 -080097import java.util.Map;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010098import java.util.Set;
janakrdbd34bc2019-06-17 06:12:48 -070099import java.util.concurrent.TimeUnit;
janakr1a4066a2020-04-13 13:24:27 -0700100import java.util.function.Predicate;
mjhalupka7675dbd2018-01-29 12:46:58 -0800101import java.util.stream.Collectors;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100102import javax.annotation.Nullable;
103
104/**
ulfjack865b6212018-06-14 03:41:55 -0700105 * The BuildView presents a semantically-consistent and transitively-closed
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100106 * dependency graph for some set of packages.
107 *
108 * <h2>Package design</h2>
109 *
110 * <p>This package contains the Blaze dependency analysis framework (aka
111 * "analysis phase"). The goal of this code is to perform semantic analysis of
112 * all of the build targets required for a given build, to report
113 * errors/warnings for any problems in the input, and to construct an "action
114 * graph" (see {@code lib.actions} package) correctly representing the work to
115 * be done during the execution phase of the build.
116 *
117 * <p><b>Configurations</b> the inputs to a build come from two sources: the
118 * intrinsic inputs, specified in the BUILD file, are called <em>targets</em>.
119 * The environmental inputs, coming from the build tool, the command-line, or
120 * configuration files, are called the <em>configuration</em>. Only when a
121 * target and a configuration are combined is there sufficient information to
122 * perform a build. </p>
123 *
124 * <p>Targets are implemented by the {@link Target} hierarchy in the {@code
125 * lib.packages} code. Configurations are implemented by {@link
126 * BuildConfiguration}. The pair of these together is represented by an
127 * instance of class {@link ConfiguredTarget}; this is the root of a hierarchy
128 * with different implementations for each kind of target: source file, derived
129 * file, rules, etc.
130 *
131 * <p>The framework code in this package (as opposed to its subpackages) is
132 * responsible for constructing the {@code ConfiguredTarget} graph for a given
133 * target and configuration, taking care of such issues as:
134 * <ul>
135 * <li>caching common subgraphs.
136 * <li>detecting and reporting cycles.
137 * <li>correct propagation of errors through the graph.
138 * <li>reporting universal errors, such as dependencies from production code
139 * to tests, or to experimental branches.
140 * <li>capturing and replaying errors.
141 * <li>maintaining the graph from one build to the next to
142 * avoid unnecessary recomputation.
143 * <li>checking software licenses.
144 * </ul>
145 *
146 * <p>See also {@link ConfiguredTarget} which documents some important
147 * invariants.
148 */
149public class BuildView {
janakrdbd34bc2019-06-17 06:12:48 -0700150 private static final GoogleLogger logger = GoogleLogger.forEnclosingClass();
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100151
152 private final BlazeDirectories directories;
153
154 private final SkyframeExecutor skyframeExecutor;
155 private final SkyframeBuildView skyframeBuildView;
156
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100157 private final ConfiguredRuleClassProvider ruleClassProvider;
158
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100159 /**
160 * A factory class to create the coverage report action. May be null.
161 */
162 @Nullable private final CoverageReportActionFactory coverageReportActionFactory;
163
Ulf Adams59dbf682015-09-17 11:36:43 +0000164 public BuildView(BlazeDirectories directories,
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100165 ConfiguredRuleClassProvider ruleClassProvider,
166 SkyframeExecutor skyframeExecutor,
Ulf Adams5a96d532015-09-26 09:00:57 +0000167 CoverageReportActionFactory coverageReportActionFactory) {
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100168 this.directories = directories;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100169 this.coverageReportActionFactory = coverageReportActionFactory;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100170 this.ruleClassProvider = ruleClassProvider;
171 this.skyframeExecutor = Preconditions.checkNotNull(skyframeExecutor);
Ulf Adams89eefd72015-09-23 08:00:43 +0000172 this.skyframeBuildView = skyframeExecutor.getSkyframeBuildView();
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100173 }
174
Laszlo Csomor2bef7782020-01-07 01:15:16 -0800175 /**
176 * Returns two numbers: number of analyzed and number of loaded targets.
177 *
178 * <p>The first number: configured targets freshly evaluated in the last analysis run.
179 *
180 * <p>The second number: targets (not configured targets) loaded in the last analysis run.
181 */
182 public Pair<Integer, Integer> getTargetsConfiguredAndLoaded() {
183 ImmutableSet<SkyKey> keys = skyframeBuildView.getEvaluatedTargetKeys();
184 int targetsConfigured = keys.size();
185 int targetsLoaded =
186 keys.stream().map(key -> ((ConfiguredTargetKey) key).getLabel()).collect(toSet()).size();
187 return Pair.of(targetsConfigured, targetsLoaded);
tomluf2720dc2018-10-02 12:10:51 -0700188 }
189
tomlua0e8aae2018-06-19 15:07:26 -0700190 public int getActionsConstructed() {
191 return skyframeBuildView.getEvaluatedActionCount();
192 }
193
ulfjack865b6212018-06-14 03:41:55 -0700194 public PackageManagerStatistics getAndClearPkgManagerStatistics() {
195 return skyframeExecutor.getPackageManager().getAndClearStatistics();
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100196 }
197
ulfjack865b6212018-06-14 03:41:55 -0700198 private ArtifactFactory getArtifactFactory() {
Ulf Adams89eefd72015-09-23 08:00:43 +0000199 return skyframeBuildView.getArtifactFactory();
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100200 }
201
mjhalupka7675dbd2018-01-29 12:46:58 -0800202 /** Returns the collection of configured targets corresponding to any of the provided targets. */
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100203 @VisibleForTesting
mjhalupkae253f832018-06-13 14:19:26 -0700204 static LinkedHashSet<ConfiguredTarget> filterTestsByTargets(
ulfjack12bb59f52018-07-25 07:19:24 -0700205 Collection<ConfiguredTarget> targets, Set<Label> allowedTargetLabels) {
mjhalupka7675dbd2018-01-29 12:46:58 -0800206 return targets
207 .stream()
mjhalupkae253f832018-06-13 14:19:26 -0700208 .filter(ct -> allowedTargetLabels.contains(ct.getLabel()))
209 .collect(Collectors.toCollection(LinkedHashSet::new));
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100210 }
211
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100212 @ThreadCompatible
Dmitry Lomove2033b12015-08-19 16:57:49 +0000213 public AnalysisResult update(
ulfjack12bb59f52018-07-25 07:19:24 -0700214 TargetPatternPhaseValue loadingResult,
ulfjack36fbbde2018-08-02 05:16:00 -0700215 BuildOptions targetOptions,
216 Set<String> multiCpu,
Philipp Schrader22b4dbc2020-10-27 07:17:41 -0700217 ImmutableSet<String> explicitTargetPatterns,
Dmitry Lomove2033b12015-08-19 16:57:49 +0000218 List<String> aspects,
ulfjackb5daae32018-06-13 07:59:33 -0700219 AnalysisOptions viewOptions,
juliexxia8a2baea2017-12-18 14:33:45 -0800220 boolean keepGoing,
juliexxiaf8b57c52017-12-21 11:37:46 -0800221 int loadingPhaseThreads,
Dmitry Lomove2033b12015-08-19 16:57:49 +0000222 TopLevelArtifactContext topLevelOptions,
Klaus Aehlig777b30d2017-02-24 16:30:15 +0000223 ExtendedEventHandler eventHandler,
Ulf Adams8c4ae672016-03-30 11:20:41 +0000224 EventBus eventBus)
ulfjack36fbbde2018-08-02 05:16:00 -0700225 throws ViewCreationFailedException, InvalidConfigurationException, InterruptedException {
janakrdbd34bc2019-06-17 06:12:48 -0700226 logger.atInfo().log("Starting analysis");
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100227 pollInterruptedStatus();
228
Laszlo Csomor2bef7782020-01-07 01:15:16 -0800229 skyframeBuildView.resetProgressReceiver();
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100230
ulfjack12bb59f52018-07-25 07:19:24 -0700231 // TODO(ulfjack): Expensive. Maybe we don't actually need the targets, only the labels?
232 Collection<Target> targets =
233 loadingResult.getTargets(eventHandler, skyframeExecutor.getPackageManager());
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100234 eventBus.post(new AnalysisPhaseStartedEvent(targets));
235
ulfjack36fbbde2018-08-02 05:16:00 -0700236 // Prepare the analysis phase
237 BuildConfigurationCollection configurations;
juliexxiab75e45302019-05-24 07:48:39 -0700238 TopLevelTargetsAndConfigsResult topLevelTargetsWithConfigsResult;
ulfjack36fbbde2018-08-02 05:16:00 -0700239 if (viewOptions.skyframePrepareAnalysis) {
240 PrepareAnalysisPhaseValue prepareAnalysisPhaseValue;
241 try (SilentCloseable c = Profiler.instance().profile("Prepare analysis phase")) {
242 prepareAnalysisPhaseValue = skyframeExecutor.prepareAnalysisPhase(
243 eventHandler, targetOptions, multiCpu, loadingResult.getTargetLabels());
ulfjack06295192019-01-16 09:13:34 -0800244
ulfjack36fbbde2018-08-02 05:16:00 -0700245 // Determine the configurations
246 configurations =
247 prepareAnalysisPhaseValue.getConfigurations(eventHandler, skyframeExecutor);
juliexxiab75e45302019-05-24 07:48:39 -0700248 topLevelTargetsWithConfigsResult =
ulfjack36fbbde2018-08-02 05:16:00 -0700249 prepareAnalysisPhaseValue.getTopLevelCts(eventHandler, skyframeExecutor);
250 }
251 } else {
252 // Configuration creation.
253 // TODO(gregce): Consider dropping this phase and passing on-the-fly target / host configs as
254 // needed. This requires cleaning up the invalidation in SkyframeBuildView.setConfigurations.
255 try (SilentCloseable c = Profiler.instance().profile("createConfigurations")) {
256 configurations =
257 skyframeExecutor
258 .createConfigurations(
259 eventHandler,
260 targetOptions,
261 multiCpu,
262 keepGoing);
263 }
264 try (SilentCloseable c = Profiler.instance().profile("AnalysisUtils.getTargetsWithConfigs")) {
juliexxiab75e45302019-05-24 07:48:39 -0700265 topLevelTargetsWithConfigsResult =
ulfjack36fbbde2018-08-02 05:16:00 -0700266 AnalysisUtils.getTargetsWithConfigs(
267 configurations, targets, eventHandler, ruleClassProvider, skyframeExecutor);
268 }
269 }
270
mstaib6cf62782018-11-14 11:54:33 -0800271 skyframeBuildView.setConfigurations(
272 eventHandler, configurations, viewOptions.maxConfigChangesToShow);
Marian Lobur86bd4fd2015-09-16 10:01:38 +0000273
ulfjack36fbbde2018-08-02 05:16:00 -0700274 if (configurations.getTargetConfigurations().size() == 1) {
275 eventBus
276 .post(
277 new MakeEnvironmentEvent(
278 configurations.getTargetConfigurations().get(0).getMakeEnvironment()));
279 }
felly392e3e42019-08-05 15:16:29 -0700280 for (BuildConfiguration targetConfig : configurations.getTargetConfigurations()) {
281 eventBus.post(targetConfig.toBuildEvent());
282 }
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100283
juliexxiab75e45302019-05-24 07:48:39 -0700284 Collection<TargetAndConfiguration> topLevelTargetsWithConfigs =
285 topLevelTargetsWithConfigsResult.getTargetsAndConfigs();
286
Klaus Aehlig71c993b2017-05-09 07:49:46 -0400287 // Report the generated association of targets to configurations
288 Multimap<Label, BuildConfiguration> byLabel =
289 ArrayListMultimap.<Label, BuildConfiguration>create();
290 for (TargetAndConfiguration pair : topLevelTargetsWithConfigs) {
291 byLabel.put(pair.getLabel(), pair.getConfiguration());
292 }
Klaus Aehlig2a92c902017-08-11 14:03:31 +0200293 for (Target target : targets) {
294 eventBus.post(new TargetConfiguredEvent(target, byLabel.get(target.getLabel())));
Klaus Aehlig71c993b2017-05-09 07:49:46 -0400295 }
296
janakr573807d2018-01-11 14:02:35 -0800297 List<ConfiguredTargetKey> topLevelCtKeys =
jcater83221e32020-05-28 11:37:39 -0700298 topLevelTargetsWithConfigs.stream()
jcater4488f0c2020-05-28 12:47:40 -0700299 .map(TargetAndConfiguration::getConfiguredTargetKey)
ulfjack36fbbde2018-08-02 05:16:00 -0700300 .collect(Collectors.toList());
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100301
Klaus Aehligc27b4da2017-09-01 10:33:22 +0200302 Multimap<Pair<Label, String>, BuildConfiguration> aspectConfigurations =
303 ArrayListMultimap.create();
Klaus Aehlig71c993b2017-05-09 07:49:46 -0400304
Dmitry Lomovc15ba2e2015-10-30 15:50:01 +0000305 List<AspectValueKey> aspectKeys = new ArrayList<>();
Dmitry Lomove2033b12015-08-19 16:57:49 +0000306 for (String aspect : aspects) {
Dmitry Lomov0b832ce2015-10-20 10:03:14 +0000307 // Syntax: label%aspect
308 int delimiterPosition = aspect.indexOf('%');
309 if (delimiterPosition >= 0) {
gregceca48e9a2020-04-14 08:54:38 -0700310 // TODO(jfield): For consistency with Starlark loads, the aspect should be specified
laurentlb940dbc52018-03-01 08:07:14 -0800311 // as an absolute label.
312 // We convert it for compatibility reasons (this will be removed in the future).
Dmitry Lomov51aafc12016-11-18 14:02:54 +0000313 String bzlFileLoadLikeString = aspect.substring(0, delimiterPosition);
314 if (!bzlFileLoadLikeString.startsWith("//") && !bzlFileLoadLikeString.startsWith("@")) {
315 // "Legacy" behavior of '--aspects' parameter.
laurentlb940dbc52018-03-01 08:07:14 -0800316 if (bzlFileLoadLikeString.startsWith("/")) {
317 bzlFileLoadLikeString = bzlFileLoadLikeString.substring(1);
318 }
319 int lastSlashPosition = bzlFileLoadLikeString.lastIndexOf('/');
320 if (lastSlashPosition >= 0) {
321 bzlFileLoadLikeString =
322 "//"
323 + bzlFileLoadLikeString.substring(0, lastSlashPosition)
324 + ":"
325 + bzlFileLoadLikeString.substring(lastSlashPosition + 1);
326 } else {
327 bzlFileLoadLikeString = "//:" + bzlFileLoadLikeString;
328 }
329 if (!bzlFileLoadLikeString.endsWith(".bzl")) {
330 bzlFileLoadLikeString = bzlFileLoadLikeString + ".bzl";
Dmitry Lomov51aafc12016-11-18 14:02:54 +0000331 }
332 }
gregce773b95f2020-05-19 09:51:09 -0700333 Label starlarkFileLabel;
Dmitry Lomov51aafc12016-11-18 14:02:54 +0000334 try {
gregce773b95f2020-05-19 09:51:09 -0700335 starlarkFileLabel =
Googlerb2e1fe32019-09-20 14:00:39 -0700336 Label.parseAbsolute(
dannarkf4b9ff42018-06-12 09:28:45 -0700337 bzlFileLoadLikeString, /* repositoryMapping= */ ImmutableMap.of());
Googlerb2e1fe32019-09-20 14:00:39 -0700338 } catch (LabelSyntaxException e) {
mschaller859c9ac2020-09-25 16:09:19 -0700339 String errorMessage = String.format("Invalid aspect '%s': %s", aspect, e.getMessage());
Dmitry Lomov51aafc12016-11-18 14:02:54 +0000340 throw new ViewCreationFailedException(
mschaller859c9ac2020-09-25 16:09:19 -0700341 errorMessage,
342 createFailureDetail(errorMessage, Analysis.Code.ASPECT_LABEL_SYNTAX_ERROR),
343 e);
Dmitry Lomov51aafc12016-11-18 14:02:54 +0000344 }
Dmitry Lomov0b832ce2015-10-20 10:03:14 +0000345
gregce773b95f2020-05-19 09:51:09 -0700346 String starlarkFunctionName = aspect.substring(delimiterPosition + 1);
Dmitry Lomov01f85c02016-06-29 06:37:50 +0000347 for (TargetAndConfiguration targetSpec : topLevelTargetsWithConfigs) {
mstaib7c7a7012019-04-23 16:19:09 -0700348 if (targetSpec.getConfiguration() != null
349 && targetSpec.getConfiguration().trimConfigurationsRetroactively()) {
mschaller859c9ac2020-09-25 16:09:19 -0700350 String errorMessage =
351 "Aspects were requested, but are not supported in retroactive trimming mode.";
mstaib7c7a7012019-04-23 16:19:09 -0700352 throw new ViewCreationFailedException(
mschaller859c9ac2020-09-25 16:09:19 -0700353 errorMessage, createFailureDetail(errorMessage, Analysis.Code.ASPECT_PREREQ_UNMET));
mstaib7c7a7012019-04-23 16:19:09 -0700354 }
Klaus Aehligc27b4da2017-09-01 10:33:22 +0200355 aspectConfigurations.put(
356 Pair.of(targetSpec.getLabel(), aspect), targetSpec.getConfiguration());
Dmitry Lomove2033b12015-08-19 16:57:49 +0000357 aspectKeys.add(
gregce5c8a5f52020-05-13 10:35:36 -0700358 AspectValueKey.createStarlarkAspectKey(
Dmitry Lomov0b832ce2015-10-20 10:03:14 +0000359 targetSpec.getLabel(),
Michael Staib04f6f242016-03-01 15:40:29 +0000360 // For invoking top-level aspects, use the top-level configuration for both the
361 // aspect and the base target while the top-level configuration is untrimmed.
362 targetSpec.getConfiguration(),
Dmitry Lomov0b832ce2015-10-20 10:03:14 +0000363 targetSpec.getConfiguration(),
gregce773b95f2020-05-19 09:51:09 -0700364 starlarkFileLabel,
365 starlarkFunctionName));
Dmitry Lomove2033b12015-08-19 16:57:49 +0000366 }
367 } else {
Luis Fernando Pino Duquee82713d2016-04-26 16:22:38 +0000368 final NativeAspectClass aspectFactoryClass =
369 ruleClassProvider.getNativeAspectClassMap().get(aspect);
dslomov99ea6b42017-04-25 17:46:17 +0200370
Dmitry Lomov0b832ce2015-10-20 10:03:14 +0000371 if (aspectFactoryClass != null) {
Dmitry Lomov01f85c02016-06-29 06:37:50 +0000372 for (TargetAndConfiguration targetSpec : topLevelTargetsWithConfigs) {
mstaib7c7a7012019-04-23 16:19:09 -0700373 if (targetSpec.getConfiguration() != null
374 && targetSpec.getConfiguration().trimConfigurationsRetroactively()) {
mschaller859c9ac2020-09-25 16:09:19 -0700375 String errorMessage =
376 "Aspects were requested, but are not supported in retroactive trimming mode.";
mstaib7c7a7012019-04-23 16:19:09 -0700377 throw new ViewCreationFailedException(
mschaller859c9ac2020-09-25 16:09:19 -0700378 errorMessage,
379 createFailureDetail(errorMessage, Analysis.Code.ASPECT_PREREQ_UNMET));
mstaib7c7a7012019-04-23 16:19:09 -0700380 }
Dmitry Lomovca9bfa42016-11-15 13:22:36 +0000381 // For invoking top-level aspects, use the top-level configuration for both the
382 // aspect and the base target while the top-level configuration is untrimmed.
383 BuildConfiguration configuration = targetSpec.getConfiguration();
Klaus Aehligc27b4da2017-09-01 10:33:22 +0200384 aspectConfigurations.put(Pair.of(targetSpec.getLabel(), aspect), configuration);
Dmitry Lomov0b832ce2015-10-20 10:03:14 +0000385 aspectKeys.add(
jcater40549e72020-04-16 10:52:40 -0700386 AspectValueKey.createAspectKey(
Dmitry Lomov8ff06452015-10-21 19:16:30 +0000387 targetSpec.getLabel(),
Dmitry Lomovca9bfa42016-11-15 13:22:36 +0000388 configuration,
dslomovfa50c3d2017-05-08 08:47:44 -0400389 new AspectDescriptor(aspectFactoryClass, AspectParameters.EMPTY),
jcater40549e72020-04-16 10:52:40 -0700390 configuration));
Dmitry Lomov0b832ce2015-10-20 10:03:14 +0000391 }
392 } else {
mschaller859c9ac2020-09-25 16:09:19 -0700393 String errorMessage = "Aspect '" + aspect + "' is unknown";
394 throw new ViewCreationFailedException(
395 errorMessage, createFailureDetail(errorMessage, Analysis.Code.ASPECT_NOT_FOUND));
Dmitry Lomov0b832ce2015-10-20 10:03:14 +0000396 }
Dmitry Lomove2033b12015-08-19 16:57:49 +0000397 }
398 }
399
Klaus Aehligc27b4da2017-09-01 10:33:22 +0200400 for (Pair<Label, String> target : aspectConfigurations.keys()) {
401 eventBus.post(
402 new AspectConfiguredEvent(
403 target.getFirst(), target.getSecond(), aspectConfigurations.get(target)));
404 }
405
janakr1f08d4c82018-09-15 16:33:35 -0700406 getArtifactFactory().noteAnalysisStarting();
Dmitry Lomove2033b12015-08-19 16:57:49 +0000407 SkyframeAnalysisResult skyframeAnalysisResult;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100408 try {
ulfjack06295192019-01-16 09:13:34 -0800409 Supplier<Map<BuildConfigurationValue.Key, BuildConfiguration>> configurationLookupSupplier =
410 () -> {
411 Map<BuildConfigurationValue.Key, BuildConfiguration> result = new HashMap<>();
412 for (TargetAndConfiguration node : topLevelTargetsWithConfigs) {
413 if (node.getConfiguration() != null) {
414 result.put(
415 BuildConfigurationValue.key(node.getConfiguration()), node.getConfiguration());
416 }
417 }
418 return result;
419 };
Dmitry Lomove2033b12015-08-19 16:57:49 +0000420 skyframeAnalysisResult =
421 skyframeBuildView.configureTargets(
ulfjack06295192019-01-16 09:13:34 -0800422 eventHandler,
423 topLevelCtKeys,
424 aspectKeys,
425 Suppliers.memoize(configurationLookupSupplier),
janakr6d185b82020-03-30 14:08:01 -0700426 topLevelOptions,
ulfjack06295192019-01-16 09:13:34 -0800427 eventBus,
428 keepGoing,
janakr1a4066a2020-04-13 13:24:27 -0700429 loadingPhaseThreads,
430 viewOptions.strictConflictChecks);
Kristina Chodorow94e27422016-08-25 14:17:30 +0000431 setArtifactRoots(skyframeAnalysisResult.getPackageRoots());
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100432 } finally {
433 skyframeBuildView.clearInvalidatedConfiguredTargets();
434 }
435
Philipp Schrader22b4dbc2020-10-27 07:17:41 -0700436 TopLevelConstraintSemantics topLevelConstraintSemantics =
437 new TopLevelConstraintSemantics(
gregcec2ba0272021-01-12 09:44:03 -0800438 (RuleContextConstraintSemantics) ruleClassProvider.getConstraintSemantics(),
Philipp Schrader22b4dbc2020-10-27 07:17:41 -0700439 skyframeExecutor.getPackageManager(),
440 input -> skyframeExecutor.getConfiguration(eventHandler, input),
441 eventHandler);
442
443 PlatformRestrictionsResult platformRestrictions =
444 topLevelConstraintSemantics.checkPlatformRestrictions(
445 skyframeAnalysisResult.getConfiguredTargets(), explicitTargetPatterns, keepGoing);
446
447 if (!platformRestrictions.targetsWithErrors().isEmpty()) {
448 // If there are any errored targets (e.g. incompatible targets that are explicitly specified
449 // on the command line), remove them from the list of targets to be built.
450 skyframeAnalysisResult =
451 skyframeAnalysisResult.withAdditionalErroredTargets(
452 ImmutableSet.copyOf(platformRestrictions.targetsWithErrors()));
453 }
454
Greg Estren7971e672016-06-01 23:22:48 +0000455 int numTargetsToAnalyze = topLevelTargetsWithConfigs.size();
Dmitry Lomove2033b12015-08-19 16:57:49 +0000456 int numSuccessful = skyframeAnalysisResult.getConfiguredTargets().size();
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100457 if (0 < numSuccessful && numSuccessful < numTargetsToAnalyze) {
458 String msg = String.format("Analysis succeeded for only %d of %d top-level targets",
459 numSuccessful, numTargetsToAnalyze);
460 eventHandler.handle(Event.info(msg));
janakrdbd34bc2019-06-17 06:12:48 -0700461 logger.atInfo().log(msg);
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100462 }
463
gregce45ae0962017-07-22 00:11:13 +0200464 Set<ConfiguredTarget> targetsToSkip =
Philipp Schrader22b4dbc2020-10-27 07:17:41 -0700465 Sets.union(
466 topLevelConstraintSemantics.checkTargetEnvironmentRestrictions(
467 skyframeAnalysisResult.getConfiguredTargets()),
468 platformRestrictions.targetsToSkip())
469 .immutableCopy();
gregce45ae0962017-07-22 00:11:13 +0200470
Dmitry Lomove2033b12015-08-19 16:57:49 +0000471 AnalysisResult result =
472 createResult(
Ulf Adams5b9009b2015-09-24 09:52:53 +0000473 eventHandler,
ulfjackb2cb6402019-01-24 04:04:48 -0800474 eventBus,
Dmitry Lomove2033b12015-08-19 16:57:49 +0000475 loadingResult,
ulfjack940fbd72018-06-15 03:23:58 -0700476 configurations,
Dmitry Lomove2033b12015-08-19 16:57:49 +0000477 topLevelOptions,
478 viewOptions,
gregce45ae0962017-07-22 00:11:13 +0200479 skyframeAnalysisResult,
juliexxia693abdc2018-01-03 08:59:18 -0800480 targetsToSkip,
juliexxiab75e45302019-05-24 07:48:39 -0700481 topLevelTargetsWithConfigsResult);
janakrdbd34bc2019-06-17 06:12:48 -0700482 logger.atInfo().log("Finished analysis");
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100483 return result;
484 }
485
Dmitry Lomove2033b12015-08-19 16:57:49 +0000486 private AnalysisResult createResult(
Klaus Aehlig777b30d2017-02-24 16:30:15 +0000487 ExtendedEventHandler eventHandler,
ulfjackb2cb6402019-01-24 04:04:48 -0800488 EventBus eventBus,
ulfjack12bb59f52018-07-25 07:19:24 -0700489 TargetPatternPhaseValue loadingResult,
ulfjack940fbd72018-06-15 03:23:58 -0700490 BuildConfigurationCollection configurations,
Dmitry Lomove2033b12015-08-19 16:57:49 +0000491 TopLevelArtifactContext topLevelOptions,
ulfjackb5daae32018-06-13 07:59:33 -0700492 AnalysisOptions viewOptions,
gregce45ae0962017-07-22 00:11:13 +0200493 SkyframeAnalysisResult skyframeAnalysisResult,
juliexxia693abdc2018-01-03 08:59:18 -0800494 Set<ConfiguredTarget> targetsToSkip,
juliexxiab75e45302019-05-24 07:48:39 -0700495 TopLevelTargetsAndConfigsResult topLevelTargetsWithConfigs)
Klaus Aehlig777b30d2017-02-24 16:30:15 +0000496 throws InterruptedException {
ulfjack12bb59f52018-07-25 07:19:24 -0700497 Set<Label> testsToRun = loadingResult.getTestsToRunLabels();
gregce45ae0962017-07-22 00:11:13 +0200498 Set<ConfiguredTarget> configuredTargets =
499 Sets.newLinkedHashSet(skyframeAnalysisResult.getConfiguredTargets());
janakrf15d08d2020-04-22 12:53:03 -0700500 ImmutableMap<AspectKey, ConfiguredAspect> aspects = skyframeAnalysisResult.getAspects();
Dmitry Lomovcf6021a2016-08-09 16:49:32 +0000501
gregce45ae0962017-07-22 00:11:13 +0200502 Set<ConfiguredTarget> allTargetsToTest = null;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100503 if (testsToRun != null) {
504 // Determine the subset of configured targets that are meant to be run as tests.
mjhalupkae253f832018-06-13 14:19:26 -0700505 allTargetsToTest = filterTestsByTargets(configuredTargets, testsToRun);
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100506 }
507
janakrccb74562018-07-30 10:56:57 -0700508 ArtifactsToOwnerLabels.Builder artifactsToOwnerLabelsBuilder =
509 new ArtifactsToOwnerLabels.Builder();
Ulf Adamsfc154ae2015-08-31 12:32:14 +0000510
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100511 // build-info and build-changelist.
Ulf Adams5b9009b2015-09-24 09:52:53 +0000512 Collection<Artifact> buildInfoArtifacts =
513 skyframeExecutor.getWorkspaceStatusArtifacts(eventHandler);
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100514 Preconditions.checkState(buildInfoArtifacts.size() == 2, buildInfoArtifacts);
Ulf Adamsfc154ae2015-08-31 12:32:14 +0000515
516 // Extra actions
mjhalupka7675dbd2018-01-29 12:46:58 -0800517 addExtraActionsIfRequested(
janakrccb74562018-07-30 10:56:57 -0700518 viewOptions, configuredTargets, aspects, artifactsToOwnerLabelsBuilder, eventHandler);
Ulf Adamsfc154ae2015-08-31 12:32:14 +0000519
520 // Coverage
janakr75bc18a2018-07-13 00:52:17 -0700521 NestedSet<Artifact> baselineCoverageArtifacts =
janakrccb74562018-07-30 10:56:57 -0700522 getBaselineCoverageArtifacts(configuredTargets, artifactsToOwnerLabelsBuilder);
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100523 if (coverageReportActionFactory != null) {
Googlercdc90e92015-02-11 00:18:07 +0000524 CoverageReportActionsWrapper actionsWrapper;
janakr573807d2018-01-11 14:02:35 -0800525 actionsWrapper =
526 coverageReportActionFactory.createCoverageReportActionsWrapper(
527 eventHandler,
ulfjackb2cb6402019-01-24 04:04:48 -0800528 eventBus,
janakr573807d2018-01-11 14:02:35 -0800529 directories,
530 allTargetsToTest,
531 baselineCoverageArtifacts,
532 getArtifactFactory(),
janakrefb3f152019-06-05 17:42:34 -0700533 skyframeExecutor.getActionKeyContext(),
elenairina9438d102018-07-06 03:06:21 -0700534 CoverageReportValue.COVERAGE_REPORT_KEY,
535 loadingResult.getWorkspaceName());
Googlercdc90e92015-02-11 00:18:07 +0000536 if (actionsWrapper != null) {
janakrefb3f152019-06-05 17:42:34 -0700537 Actions.GeneratingActions actions = actionsWrapper.getActions();
Googlercdc90e92015-02-11 00:18:07 +0000538 skyframeExecutor.injectCoverageReportData(actions);
janakrccb74562018-07-30 10:56:57 -0700539 actionsWrapper.getCoverageOutputs().forEach(artifactsToOwnerLabelsBuilder::addArtifact);
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100540 }
541 }
janakr1a4066a2020-04-13 13:24:27 -0700542 // TODO(cparsons): If extra actions are ever removed, this filtering step can probably be
543 // removed as well: the only concern would be action conflicts involving coverage artifacts,
544 // which seems far-fetched.
545 if (skyframeAnalysisResult.hasActionConflicts()) {
546 ArtifactsToOwnerLabels tempOwners = artifactsToOwnerLabelsBuilder.build();
547 // We don't remove the (hopefully unnecessary) guard in SkyframeBuildView that enables/
548 // disables analysis, since no new targets should actually be analyzed.
549 Set<Artifact> artifacts = tempOwners.getArtifacts();
550 Predicate<Artifact> errorFreeArtifacts =
551 skyframeExecutor.filterActionConflictsForTopLevelArtifacts(eventHandler, artifacts);
552 artifactsToOwnerLabelsBuilder = tempOwners.toBuilder().filterArtifacts(errorFreeArtifacts);
553 }
554 // Build-info artifacts are always conflict-free, and can't be checked easily.
555 buildInfoArtifacts.forEach(artifactsToOwnerLabelsBuilder::addArtifact);
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100556
laszlocsomord237db72020-01-09 08:15:07 -0800557 // Tests.
558 Pair<ImmutableSet<ConfiguredTarget>, ImmutableSet<ConfiguredTarget>> testsPair =
559 collectTests(
560 topLevelOptions, allTargetsToTest, skyframeExecutor.getPackageManager(), eventHandler);
561 ImmutableSet<ConfiguredTarget> parallelTests = testsPair.first;
562 ImmutableSet<ConfiguredTarget> exclusiveTests = testsPair.second;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100563
mschaller75216c72020-06-25 16:04:29 -0700564 FailureDetail failureDetail =
565 createFailureDetail(loadingResult, skyframeAnalysisResult, topLevelTargetsWithConfigs);
Eric Fellheimer9c1e12f2015-08-06 20:23:55 +0000566
Ulf Adams53abece2016-02-03 08:30:07 +0000567 final WalkableGraph graph = skyframeAnalysisResult.getWalkableGraph();
Janak Ramakrishnan3c0adb22016-08-15 21:54:55 +0000568 final ActionGraph actionGraph =
569 new ActionGraph() {
570 @Nullable
571 @Override
572 public ActionAnalysisMetadata getGeneratingAction(Artifact artifact) {
janakrefb3f152019-06-05 17:42:34 -0700573 if (artifact.isSourceArtifact()) {
574 return null;
Janak Ramakrishnan3c0adb22016-08-15 21:54:55 +0000575 }
janakrefb3f152019-06-05 17:42:34 -0700576 ActionLookupData generatingActionKey =
577 ((Artifact.DerivedArtifact) artifact).getGeneratingActionKey();
578 ActionLookupValue val;
579 try {
580 val = (ActionLookupValue) graph.getValue(generatingActionKey.getActionLookupKey());
581 } catch (InterruptedException e) {
582 throw new IllegalStateException(
583 "Interruption not expected from this graph: " + generatingActionKey, e);
584 }
585 if (val == null) {
janakrdbd34bc2019-06-17 06:12:48 -0700586 logger.atWarning().atMostEvery(1, TimeUnit.SECONDS).log(
587 "Missing generating action for %s (%s)", artifact, generatingActionKey);
janakrefb3f152019-06-05 17:42:34 -0700588 return null;
589 }
Googler2714b882019-08-01 12:30:08 -0700590 return val.getActions().get(generatingActionKey.getActionIndex());
Janak Ramakrishnan3c0adb22016-08-15 21:54:55 +0000591 }
592 };
Dmitry Lomove2033b12015-08-19 16:57:49 +0000593 return new AnalysisResult(
ulfjack940fbd72018-06-15 03:23:58 -0700594 configurations,
laszlocsomor3c8883d2019-12-19 05:19:28 -0800595 ImmutableSet.copyOf(configuredTargets),
Dmitry Lomovcf6021a2016-08-09 16:49:32 +0000596 aspects,
laszlocsomor3c8883d2019-12-19 05:19:28 -0800597 allTargetsToTest == null ? null : ImmutableList.copyOf(allTargetsToTest),
598 ImmutableSet.copyOf(targetsToSkip),
mschaller75216c72020-06-25 16:04:29 -0700599 failureDetail,
Dmitry Lomove2033b12015-08-19 16:57:49 +0000600 actionGraph,
janakrccb74562018-07-30 10:56:57 -0700601 artifactsToOwnerLabelsBuilder.build(),
laszlocsomord237db72020-01-09 08:15:07 -0800602 parallelTests,
603 exclusiveTests,
Marian Lobur86bd4fd2015-09-16 10:01:38 +0000604 topLevelOptions,
Kristina Chodorow36a6c172016-07-22 15:18:07 +0000605 skyframeAnalysisResult.getPackageRoots(),
juliexxia693abdc2018-01-03 08:59:18 -0800606 loadingResult.getWorkspaceName(),
ichern121933e2020-01-27 02:08:19 -0800607 topLevelTargetsWithConfigs.getTargetsAndConfigs(),
608 loadingResult.getNotSymlinkedInExecrootDirectories());
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100609 }
610
juliexxiab75e45302019-05-24 07:48:39 -0700611 /**
612 * Check for errors in "chronological" order (acknowledge that loading and analysis are
613 * interleaved, but sequential on the single target scale).
614 */
Janak Ramakrishnan6f9d7d12016-08-09 08:45:34 +0000615 @Nullable
mschaller75216c72020-06-25 16:04:29 -0700616 public static FailureDetail createFailureDetail(
ulfjack12bb59f52018-07-25 07:19:24 -0700617 TargetPatternPhaseValue loadingResult,
juliexxiab75e45302019-05-24 07:48:39 -0700618 @Nullable SkyframeAnalysisResult skyframeAnalysisResult,
619 @Nullable TopLevelTargetsAndConfigsResult topLevelTargetsAndConfigs) {
620 if (loadingResult.hasError()) {
mschaller75216c72020-06-25 16:04:29 -0700621 return FailureDetail.newBuilder()
622 .setMessage("command succeeded, but there were errors parsing the target pattern")
623 .setTargetPatterns(TargetPatterns.newBuilder().setCode(Code.TARGET_PATTERN_PARSE_FAILURE))
624 .build();
juliexxiab75e45302019-05-24 07:48:39 -0700625 }
626 if (loadingResult.hasPostExpansionError()
627 || (skyframeAnalysisResult != null && skyframeAnalysisResult.hasLoadingError())) {
mschaller75216c72020-06-25 16:04:29 -0700628 return FailureDetail.newBuilder()
629 .setMessage("command succeeded, but there were loading phase errors")
630 .setAnalysis(Analysis.newBuilder().setCode(Analysis.Code.GENERIC_LOADING_PHASE_FAILURE))
631 .build();
juliexxiab75e45302019-05-24 07:48:39 -0700632 }
633 if (topLevelTargetsAndConfigs != null && topLevelTargetsAndConfigs.hasError()) {
mschaller75216c72020-06-25 16:04:29 -0700634 return FailureDetail.newBuilder()
635 .setMessage("command succeeded, but top level configurations could not be created")
636 .setBuildConfiguration(
637 FailureDetails.BuildConfiguration.newBuilder()
638 .setCode(
639 FailureDetails.BuildConfiguration.Code
640 .TOP_LEVEL_CONFIGURATION_CREATION_FAILURE))
641 .build();
juliexxiab75e45302019-05-24 07:48:39 -0700642 }
643 if (skyframeAnalysisResult != null && skyframeAnalysisResult.hasAnalysisError()) {
mschaller75216c72020-06-25 16:04:29 -0700644 return FailureDetail.newBuilder()
645 .setMessage("command succeeded, but not all targets were analyzed")
646 .setAnalysis(Analysis.newBuilder().setCode(Analysis.Code.NOT_ALL_TARGETS_ANALYZED))
647 .build();
juliexxiab75e45302019-05-24 07:48:39 -0700648 }
649 return null;
Janak Ramakrishnan6f9d7d12016-08-09 08:45:34 +0000650 }
651
mschaller859c9ac2020-09-25 16:09:19 -0700652 private static FailureDetail createFailureDetail(String errorMessage, Analysis.Code code) {
653 return FailureDetail.newBuilder()
654 .setMessage(errorMessage)
655 .setAnalysis(Analysis.newBuilder().setCode(code))
656 .build();
657 }
658
Lukacs Berki6916be22015-02-19 13:36:06 +0000659 private static NestedSet<Artifact> getBaselineCoverageArtifacts(
janakr75bc18a2018-07-13 00:52:17 -0700660 Collection<ConfiguredTarget> configuredTargets,
janakrccb74562018-07-30 10:56:57 -0700661 ArtifactsToOwnerLabels.Builder topLevelArtifactsToOwnerLabels) {
Lukacs Berki6916be22015-02-19 13:36:06 +0000662 NestedSetBuilder<Artifact> baselineCoverageArtifacts = NestedSetBuilder.stableOrder();
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100663 for (ConfiguredTarget target : configuredTargets) {
gregceff941232020-04-21 08:03:32 -0700664 InstrumentedFilesInfo provider = target.get(InstrumentedFilesInfo.STARLARK_CONSTRUCTOR);
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100665 if (provider != null) {
janakr75bc18a2018-07-13 00:52:17 -0700666 TopLevelArtifactHelper.addArtifactsWithOwnerLabel(
667 provider.getBaselineCoverageArtifacts(),
668 null,
669 target.getLabel(),
670 topLevelArtifactsToOwnerLabels);
Ulf Adamsfc154ae2015-08-31 12:32:14 +0000671 baselineCoverageArtifacts.addTransitive(provider.getBaselineCoverageArtifacts());
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100672 }
673 }
Lukacs Berki6916be22015-02-19 13:36:06 +0000674 return baselineCoverageArtifacts.build();
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100675 }
676
mjhalupka7675dbd2018-01-29 12:46:58 -0800677 private void addExtraActionsIfRequested(
ulfjackb5daae32018-06-13 07:59:33 -0700678 AnalysisOptions viewOptions,
Dmitry Lomovcf6021a2016-08-09 16:49:32 +0000679 Collection<ConfiguredTarget> configuredTargets,
janakrf15d08d2020-04-22 12:53:03 -0700680 ImmutableMap<AspectKey, ConfiguredAspect> aspects,
janakrccb74562018-07-30 10:56:57 -0700681 ArtifactsToOwnerLabels.Builder artifactsToTopLevelLabelsMap,
mjhalupka7675dbd2018-01-29 12:46:58 -0800682 ExtendedEventHandler eventHandler) {
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100683 RegexFilter filter = viewOptions.extraActionFilter;
Carmi Grushkodf9e5e12016-11-08 23:07:57 +0000684 for (ConfiguredTarget target : configuredTargets) {
685 ExtraActionArtifactsProvider provider =
686 target.getProvider(ExtraActionArtifactsProvider.class);
687 if (provider != null) {
688 if (viewOptions.extraActionTopLevelOnly) {
lberki9137a752017-06-09 12:49:10 +0200689 // Collect all aspect-classes that topLevel might inject.
690 Set<AspectClass> aspectClasses = new HashSet<>();
mjhalupka7675dbd2018-01-29 12:46:58 -0800691 Target actualTarget = null;
692 try {
693 actualTarget =
694 skyframeExecutor.getPackageManager().getTarget(eventHandler, target.getLabel());
695 } catch (NoSuchPackageException | NoSuchTargetException | InterruptedException e) {
696 eventHandler.handle(Event.error(""));
697 }
698 for (Attribute attr : actualTarget.getAssociatedRule().getAttributes()) {
lberki9137a752017-06-09 12:49:10 +0200699 aspectClasses.addAll(attr.getAspectClasses());
700 }
janakr75bc18a2018-07-13 00:52:17 -0700701 TopLevelArtifactHelper.addArtifactsWithOwnerLabel(
702 provider.getExtraActionArtifacts(),
703 filter,
704 target.getLabel(),
705 artifactsToTopLevelLabelsMap);
lberki9137a752017-06-09 12:49:10 +0200706 if (!aspectClasses.isEmpty()) {
janakr75bc18a2018-07-13 00:52:17 -0700707 TopLevelArtifactHelper.addArtifactsWithOwnerLabel(
708 filterTransitiveExtraActions(provider, aspectClasses),
709 filter,
710 target.getLabel(),
711 artifactsToTopLevelLabelsMap);
Carmi Grushkodf9e5e12016-11-08 23:07:57 +0000712 }
Carmi Grushkodf9e5e12016-11-08 23:07:57 +0000713 } else {
janakr75bc18a2018-07-13 00:52:17 -0700714 TopLevelArtifactHelper.addArtifactsWithOwnerLabel(
715 provider.getTransitiveExtraActionArtifacts(),
716 filter,
717 target.getLabel(),
718 artifactsToTopLevelLabelsMap);
Carmi Grushkodf9e5e12016-11-08 23:07:57 +0000719 }
720 }
721 }
janakrf15d08d2020-04-22 12:53:03 -0700722 for (Map.Entry<AspectKey, ConfiguredAspect> aspectEntry : aspects.entrySet()) {
janakr75bc18a2018-07-13 00:52:17 -0700723 ExtraActionArtifactsProvider provider =
janakrf15d08d2020-04-22 12:53:03 -0700724 aspectEntry.getValue().getProvider(ExtraActionArtifactsProvider.class);
janakr75bc18a2018-07-13 00:52:17 -0700725 if (provider != null) {
726 if (viewOptions.extraActionTopLevelOnly) {
727 TopLevelArtifactHelper.addArtifactsWithOwnerLabel(
728 provider.getExtraActionArtifacts(),
729 filter,
janakrf15d08d2020-04-22 12:53:03 -0700730 aspectEntry.getKey().getLabel(),
janakr75bc18a2018-07-13 00:52:17 -0700731 artifactsToTopLevelLabelsMap);
732 } else {
733 TopLevelArtifactHelper.addArtifactsWithOwnerLabel(
734 provider.getTransitiveExtraActionArtifacts(),
735 filter,
janakrf15d08d2020-04-22 12:53:03 -0700736 aspectEntry.getKey().getLabel(),
janakr75bc18a2018-07-13 00:52:17 -0700737 artifactsToTopLevelLabelsMap);
738 }
739 }
740 }
Carmi Grushkodf9e5e12016-11-08 23:07:57 +0000741 }
742
743 /**
janakr658d47f2019-05-29 11:11:30 -0700744 * Returns a list of artifacts from 'provider' that were registered by an aspect from
745 * 'aspectClasses'. All artifacts in 'provider' are considered - both direct and transitive.
Carmi Grushkodf9e5e12016-11-08 23:07:57 +0000746 */
laszlocsomord237db72020-01-09 08:15:07 -0800747 private static ImmutableList<Artifact> filterTransitiveExtraActions(
Carmi Grushkodf9e5e12016-11-08 23:07:57 +0000748 ExtraActionArtifactsProvider provider, Set<AspectClass> aspectClasses) {
749 ImmutableList.Builder<Artifact> artifacts = ImmutableList.builder();
750 // Add to 'artifacts' all extra-actions which were registered by aspects which 'topLevel'
751 // might have injected.
ulfjack61216fd2019-12-18 12:31:03 -0800752 for (Artifact.DerivedArtifact artifact :
753 provider.getTransitiveExtraActionArtifacts().toList()) {
jhorvitz3daedc32020-07-22 18:33:55 -0700754 ActionLookupKey owner = artifact.getArtifactOwner();
Carmi Grushkobabd4852016-11-18 17:58:09 +0000755 if (owner instanceof AspectKey) {
756 if (aspectClasses.contains(((AspectKey) owner).getAspectClass())) {
757 artifacts.add(artifact);
Carmi Grushkodf9e5e12016-11-08 23:07:57 +0000758 }
759 }
760 }
761 return artifacts.build();
762 }
763
laszlocsomord237db72020-01-09 08:15:07 -0800764 private static Pair<ImmutableSet<ConfiguredTarget>, ImmutableSet<ConfiguredTarget>> collectTests(
mjhalupka7675dbd2018-01-29 12:46:58 -0800765 TopLevelArtifactContext topLevelOptions,
laszlocsomord237db72020-01-09 08:15:07 -0800766 @Nullable Iterable<ConfiguredTarget> allTestTargets,
767 PackageManager packageManager,
mjhalupka7675dbd2018-01-29 12:46:58 -0800768 ExtendedEventHandler eventHandler)
769 throws InterruptedException {
Lukacs Berki3f4d4e92015-02-24 10:28:26 +0000770 Set<String> outputGroups = topLevelOptions.outputGroups();
dslomov69c45f82017-12-14 11:15:43 -0500771 if (!outputGroups.contains(OutputGroupInfo.FILES_TO_COMPILE)
772 && !outputGroups.contains(OutputGroupInfo.COMPILATION_PREREQUISITES)
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100773 && allTestTargets != null) {
laszlocsomord237db72020-01-09 08:15:07 -0800774 final boolean isExclusive = topLevelOptions.runTestsExclusively();
775 ImmutableSet.Builder<ConfiguredTarget> targetsToTest = ImmutableSet.builder();
776 ImmutableSet.Builder<ConfiguredTarget> targetsToTestExclusive = ImmutableSet.builder();
777 for (ConfiguredTarget configuredTarget : allTestTargets) {
778 Target target = null;
779 try {
780 target = packageManager.getTarget(eventHandler, configuredTarget.getLabel());
781 } catch (NoSuchTargetException | NoSuchPackageException e) {
782 eventHandler.handle(Event.error("Failed to get target when scheduling tests"));
783 continue;
784 }
785 if (target instanceof Rule) {
786 if (isExclusive || TargetUtils.isExclusiveTestRule((Rule) target)) {
787 targetsToTestExclusive.add(configuredTarget);
788 } else {
789 targetsToTest.add(configuredTarget);
790 }
791 }
mjhalupka7675dbd2018-01-29 12:46:58 -0800792 }
laszlocsomord237db72020-01-09 08:15:07 -0800793 return Pair.of(targetsToTest.build(), targetsToTestExclusive.build());
794 } else {
795 return Pair.of(ImmutableSet.of(), ImmutableSet.of());
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100796 }
797 }
798
Greg Estren7971e672016-06-01 23:22:48 +0000799 /**
Ulf Adamsa385d3e2015-09-28 13:21:45 +0000800 * Sets the possible artifact roots in the artifact factory. This allows the factory to resolve
801 * paths with unknown roots to artifacts.
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100802 */
ulfjack865b6212018-06-14 03:41:55 -0700803 private void setArtifactRoots(PackageRoots packageRoots) {
janakrae323982017-09-29 21:11:53 +0200804 getArtifactFactory().setPackageRoots(packageRoots.getPackageRootLookup());
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100805 }
806
807 /**
Ulf Adams9c505cb2015-09-28 13:38:14 +0000808 * Tests and clears the current thread's pending "interrupted" status, and
809 * throws InterruptedException iff it was set.
810 */
ulfjack865b6212018-06-14 03:41:55 -0700811 private final void pollInterruptedStatus() throws InterruptedException {
Ulf Adams9c505cb2015-09-28 13:38:14 +0000812 if (Thread.interrupted()) {
813 throw new InterruptedException();
814 }
815 }
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100816}