blob: 749a8d02d2e4a1c4fc4be3218875addfff7ce64d [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
17import com.google.common.annotations.VisibleForTesting;
tomlua155b532017-11-08 20:12:47 +010018import com.google.common.base.Preconditions;
ulfjack06295192019-01-16 09:13:34 -080019import com.google.common.base.Supplier;
20import com.google.common.base.Suppliers;
Greg Estren7883bf12016-11-18 20:03:43 +000021import com.google.common.collect.ArrayListMultimap;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010022import com.google.common.collect.ImmutableList;
23import com.google.common.collect.ImmutableMap;
24import com.google.common.collect.ImmutableSet;
Greg Estren7883bf12016-11-18 20:03:43 +000025import com.google.common.collect.Multimap;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010026import com.google.common.collect.Sets;
27import com.google.common.eventbus.EventBus;
janakrdbd34bc2019-06-17 06:12:48 -070028import com.google.common.flogger.GoogleLogger;
Rumou Duan33bab462016-04-25 17:55:12 +000029import com.google.devtools.build.lib.actions.ActionAnalysisMetadata;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010030import com.google.devtools.build.lib.actions.ActionGraph;
janakrefb3f152019-06-05 17:42:34 -070031import com.google.devtools.build.lib.actions.ActionLookupData;
jhorvitz3daedc32020-07-22 18:33:55 -070032import com.google.devtools.build.lib.actions.ActionLookupKey;
janakr93e3eea2017-03-30 22:09:37 +000033import com.google.devtools.build.lib.actions.ActionLookupValue;
janakrefb3f152019-06-05 17:42:34 -070034import com.google.devtools.build.lib.actions.Actions;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010035import com.google.devtools.build.lib.actions.Artifact;
36import com.google.devtools.build.lib.actions.ArtifactFactory;
janakrae323982017-09-29 21:11:53 +020037import com.google.devtools.build.lib.actions.PackageRoots;
janakr6bbad592021-02-17 09:00:38 -080038import com.google.devtools.build.lib.actions.TotalAndConfiguredTargetOnlyMetric;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010039import com.google.devtools.build.lib.analysis.config.BuildConfigurationCollection;
jhorvitz33f76482021-10-28 10:13:26 -070040import com.google.devtools.build.lib.analysis.config.BuildConfigurationValue;
ulfjack36fbbde2018-08-02 05:16:00 -070041import com.google.devtools.build.lib.analysis.config.BuildOptions;
juliexxiab75e45302019-05-24 07:48:39 -070042import com.google.devtools.build.lib.analysis.config.ConfigurationResolver.TopLevelTargetsAndConfigsResult;
ulfjack36fbbde2018-08-02 05:16:00 -070043import com.google.devtools.build.lib.analysis.config.InvalidConfigurationException;
Philipp Schrader22b4dbc2020-10-27 07:17:41 -070044import com.google.devtools.build.lib.analysis.constraints.PlatformRestrictionsResult;
gregcec2ba0272021-01-12 09:44:03 -080045import com.google.devtools.build.lib.analysis.constraints.RuleContextConstraintSemantics;
gregce45ae0962017-07-22 00:11:13 +020046import com.google.devtools.build.lib.analysis.constraints.TopLevelConstraintSemantics;
ulfjackab21d182017-08-10 15:36:14 +020047import com.google.devtools.build.lib.analysis.test.CoverageReportActionFactory;
48import com.google.devtools.build.lib.analysis.test.CoverageReportActionFactory.CoverageReportActionsWrapper;
cparsonsb83c5f82018-11-21 14:46:57 -080049import com.google.devtools.build.lib.analysis.test.InstrumentedFilesInfo;
Lukacs Berki6e91eb92015-09-21 09:12:37 +000050import com.google.devtools.build.lib.cmdline.Label;
Googlerb2e1fe32019-09-20 14:00:39 -070051import com.google.devtools.build.lib.cmdline.LabelSyntaxException;
Lukacs Berki6916be22015-02-19 13:36:06 +000052import com.google.devtools.build.lib.collect.nestedset.NestedSet;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010053import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010054import com.google.devtools.build.lib.concurrent.ThreadSafety.ThreadCompatible;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010055import com.google.devtools.build.lib.events.Event;
Klaus Aehlig777b30d2017-02-24 16:30:15 +000056import com.google.devtools.build.lib.events.ExtendedEventHandler;
Carmi Grushkodf9e5e12016-11-08 23:07:57 +000057import com.google.devtools.build.lib.packages.AspectClass;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010058import com.google.devtools.build.lib.packages.Attribute;
Dmitry Lomov8ff06452015-10-21 19:16:30 +000059import com.google.devtools.build.lib.packages.NativeAspectClass;
Cal Peyser8a638d52017-03-24 15:44:24 +000060import com.google.devtools.build.lib.packages.NoSuchPackageException;
61import com.google.devtools.build.lib.packages.NoSuchTargetException;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010062import com.google.devtools.build.lib.packages.Rule;
messac4157da2021-08-06 11:17:19 -070063import com.google.devtools.build.lib.packages.StarlarkAspectClass;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010064import 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;
lebab52a1902021-09-23 01:35:13 -070075import com.google.devtools.build.lib.skyframe.AspectKeyCreator;
76import com.google.devtools.build.lib.skyframe.AspectKeyCreator.AspectKey;
77import com.google.devtools.build.lib.skyframe.AspectKeyCreator.TopLevelAspectsKey;
jhorvitz33f76482021-10-28 10:13:26 -070078import com.google.devtools.build.lib.skyframe.BuildConfigurationKey;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010079import com.google.devtools.build.lib.skyframe.ConfiguredTargetKey;
80import com.google.devtools.build.lib.skyframe.CoverageReportValue;
ulfjack36fbbde2018-08-02 05:16:00 -070081import com.google.devtools.build.lib.skyframe.PrepareAnalysisPhaseValue;
Dmitry Lomove2033b12015-08-19 16:57:49 +000082import com.google.devtools.build.lib.skyframe.SkyframeAnalysisResult;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010083import com.google.devtools.build.lib.skyframe.SkyframeBuildView;
84import com.google.devtools.build.lib.skyframe.SkyframeExecutor;
ulfjack12bb59f52018-07-25 07:19:24 -070085import com.google.devtools.build.lib.skyframe.TargetPatternPhaseValue;
Klaus Aehligc27b4da2017-09-01 10:33:22 +020086import com.google.devtools.build.lib.util.Pair;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010087import com.google.devtools.build.lib.util.RegexFilter;
Eric Fellheimer9c1e12f2015-08-06 20:23:55 +000088import com.google.devtools.build.skyframe.WalkableGraph;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010089import java.util.Collection;
ulfjack06295192019-01-16 09:13:34 -080090import java.util.HashMap;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010091import java.util.HashSet;
92import java.util.LinkedHashSet;
93import java.util.List;
ulfjack06295192019-01-16 09:13:34 -080094import java.util.Map;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010095import java.util.Set;
janakrdbd34bc2019-06-17 06:12:48 -070096import java.util.concurrent.TimeUnit;
janakr1a4066a2020-04-13 13:24:27 -070097import java.util.function.Predicate;
mjhalupka7675dbd2018-01-29 12:46:58 -080098import java.util.stream.Collectors;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010099import javax.annotation.Nullable;
100
101/**
jhorvitze362fc92021-04-22 16:04:44 -0700102 * The BuildView presents a semantically-consistent and transitively-closed dependency graph for
103 * some set of packages.
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100104 *
105 * <h2>Package design</h2>
106 *
jhorvitze362fc92021-04-22 16:04:44 -0700107 * <p>This package contains the Blaze dependency analysis framework (aka "analysis phase"). The goal
108 * of this code is to perform semantic analysis of all of the build targets required for a given
109 * build, to report errors/warnings for any problems in the input, and to construct an "action
110 * graph" (see {@code lib.actions} package) correctly representing the work to be done during the
111 * execution phase of the build.
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100112 *
jhorvitze362fc92021-04-22 16:04:44 -0700113 * <p><b>Configurations</b> the inputs to a build come from two sources: the intrinsic inputs,
114 * specified in the BUILD file, are called <em>targets</em>. The environmental inputs, coming from
115 * the build tool, the command-line, or configuration files, are called the <em>configuration</em>.
116 * Only when a target and a configuration are combined is there sufficient information to perform a
117 * build.
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100118 *
jhorvitze362fc92021-04-22 16:04:44 -0700119 * <p>Targets are implemented by the {@link Target} hierarchy in the {@code lib.packages} code.
jhorvitz33f76482021-10-28 10:13:26 -0700120 * Configurations are implemented by {@link BuildConfigurationValue}. The pair of these together is
jhorvitze362fc92021-04-22 16:04:44 -0700121 * represented by an instance of class {@link ConfiguredTarget}; this is the root of a hierarchy
122 * with different implementations for each kind of target: source file, derived file, rules, etc.
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100123 *
jhorvitze362fc92021-04-22 16:04:44 -0700124 * <p>The framework code in this package (as opposed to its subpackages) is responsible for
125 * constructing the {@code ConfiguredTarget} graph for a given target and configuration, taking care
126 * of such issues as:
127 *
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100128 * <ul>
129 * <li>caching common subgraphs.
130 * <li>detecting and reporting cycles.
131 * <li>correct propagation of errors through the graph.
jhorvitze362fc92021-04-22 16:04:44 -0700132 * <li>reporting universal errors, such as dependencies from production code to tests, or to
133 * experimental branches.
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100134 * <li>capturing and replaying errors.
jhorvitze362fc92021-04-22 16:04:44 -0700135 * <li>maintaining the graph from one build to the next to avoid unnecessary recomputation.
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100136 * <li>checking software licenses.
137 * </ul>
138 *
jhorvitze362fc92021-04-22 16:04:44 -0700139 * <p>See also {@link ConfiguredTarget} which documents some important invariants.
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100140 */
141public class BuildView {
janakrdbd34bc2019-06-17 06:12:48 -0700142 private static final GoogleLogger logger = GoogleLogger.forEnclosingClass();
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100143
144 private final BlazeDirectories directories;
145
146 private final SkyframeExecutor skyframeExecutor;
147 private final SkyframeBuildView skyframeBuildView;
148
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100149 private final ConfiguredRuleClassProvider ruleClassProvider;
150
jhorvitze362fc92021-04-22 16:04:44 -0700151 /** A factory class to create the coverage report action. May be null. */
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100152 @Nullable private final CoverageReportActionFactory coverageReportActionFactory;
153
jhorvitze362fc92021-04-22 16:04:44 -0700154 public BuildView(
155 BlazeDirectories directories,
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100156 ConfiguredRuleClassProvider ruleClassProvider,
157 SkyframeExecutor skyframeExecutor,
Ulf Adams5a96d532015-09-26 09:00:57 +0000158 CoverageReportActionFactory coverageReportActionFactory) {
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100159 this.directories = directories;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100160 this.coverageReportActionFactory = coverageReportActionFactory;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100161 this.ruleClassProvider = ruleClassProvider;
162 this.skyframeExecutor = Preconditions.checkNotNull(skyframeExecutor);
Ulf Adams89eefd72015-09-23 08:00:43 +0000163 this.skyframeBuildView = skyframeExecutor.getSkyframeBuildView();
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100164 }
165
janakr6bbad592021-02-17 09:00:38 -0800166 /** Returns the number of analyzed targets/aspects. */
167 public TotalAndConfiguredTargetOnlyMetric getEvaluatedCounts() {
168 return skyframeBuildView.getEvaluatedCounts();
tomluf2720dc2018-10-02 12:10:51 -0700169 }
170
janakr6bbad592021-02-17 09:00:38 -0800171 public TotalAndConfiguredTargetOnlyMetric getEvaluatedActionsCounts() {
172 return skyframeBuildView.getEvaluatedActionCounts();
tomlua0e8aae2018-06-19 15:07:26 -0700173 }
174
ulfjack865b6212018-06-14 03:41:55 -0700175 public PackageManagerStatistics getAndClearPkgManagerStatistics() {
176 return skyframeExecutor.getPackageManager().getAndClearStatistics();
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100177 }
178
ulfjack865b6212018-06-14 03:41:55 -0700179 private ArtifactFactory getArtifactFactory() {
Ulf Adams89eefd72015-09-23 08:00:43 +0000180 return skyframeBuildView.getArtifactFactory();
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100181 }
182
mjhalupka7675dbd2018-01-29 12:46:58 -0800183 /** Returns the collection of configured targets corresponding to any of the provided targets. */
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100184 @VisibleForTesting
mjhalupkae253f832018-06-13 14:19:26 -0700185 static LinkedHashSet<ConfiguredTarget> filterTestsByTargets(
ulfjack12bb59f52018-07-25 07:19:24 -0700186 Collection<ConfiguredTarget> targets, Set<Label> allowedTargetLabels) {
jhorvitze362fc92021-04-22 16:04:44 -0700187 return targets.stream()
mjhalupkae253f832018-06-13 14:19:26 -0700188 .filter(ct -> allowedTargetLabels.contains(ct.getLabel()))
189 .collect(Collectors.toCollection(LinkedHashSet::new));
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100190 }
191
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100192 @ThreadCompatible
Dmitry Lomove2033b12015-08-19 16:57:49 +0000193 public AnalysisResult update(
ulfjack12bb59f52018-07-25 07:19:24 -0700194 TargetPatternPhaseValue loadingResult,
ulfjack36fbbde2018-08-02 05:16:00 -0700195 BuildOptions targetOptions,
196 Set<String> multiCpu,
Philipp Schrader22b4dbc2020-10-27 07:17:41 -0700197 ImmutableSet<String> explicitTargetPatterns,
Dmitry Lomove2033b12015-08-19 16:57:49 +0000198 List<String> aspects,
ulfjackb5daae32018-06-13 07:59:33 -0700199 AnalysisOptions viewOptions,
juliexxia8a2baea2017-12-18 14:33:45 -0800200 boolean keepGoing,
jcateracdf1d32021-03-02 11:55:29 -0800201 boolean checkForActionConflicts,
juliexxiaf8b57c52017-12-21 11:37:46 -0800202 int loadingPhaseThreads,
Dmitry Lomove2033b12015-08-19 16:57:49 +0000203 TopLevelArtifactContext topLevelOptions,
Klaus Aehlig777b30d2017-02-24 16:30:15 +0000204 ExtendedEventHandler eventHandler,
leba94b810f2021-09-29 01:47:53 -0700205 EventBus eventBus,
leba1da8f4c2021-10-05 07:13:14 -0700206 boolean includeExecutionPhase,
207 int mergedPhasesExecutionJobsCount)
ulfjack36fbbde2018-08-02 05:16:00 -0700208 throws ViewCreationFailedException, InvalidConfigurationException, InterruptedException {
janakrdbd34bc2019-06-17 06:12:48 -0700209 logger.atInfo().log("Starting analysis");
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100210 pollInterruptedStatus();
211
Laszlo Csomor2bef7782020-01-07 01:15:16 -0800212 skyframeBuildView.resetProgressReceiver();
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100213
ulfjack12bb59f52018-07-25 07:19:24 -0700214 // TODO(ulfjack): Expensive. Maybe we don't actually need the targets, only the labels?
215 Collection<Target> targets =
216 loadingResult.getTargets(eventHandler, skyframeExecutor.getPackageManager());
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100217 eventBus.post(new AnalysisPhaseStartedEvent(targets));
218
ulfjack36fbbde2018-08-02 05:16:00 -0700219 // Prepare the analysis phase
220 BuildConfigurationCollection configurations;
juliexxiab75e45302019-05-24 07:48:39 -0700221 TopLevelTargetsAndConfigsResult topLevelTargetsWithConfigsResult;
ulfjack36fbbde2018-08-02 05:16:00 -0700222 if (viewOptions.skyframePrepareAnalysis) {
223 PrepareAnalysisPhaseValue prepareAnalysisPhaseValue;
224 try (SilentCloseable c = Profiler.instance().profile("Prepare analysis phase")) {
jhorvitze362fc92021-04-22 16:04:44 -0700225 prepareAnalysisPhaseValue =
226 skyframeExecutor.prepareAnalysisPhase(
227 eventHandler, targetOptions, multiCpu, loadingResult.getTargetLabels());
ulfjack06295192019-01-16 09:13:34 -0800228
ulfjack36fbbde2018-08-02 05:16:00 -0700229 // Determine the configurations
230 configurations =
231 prepareAnalysisPhaseValue.getConfigurations(eventHandler, skyframeExecutor);
juliexxiab75e45302019-05-24 07:48:39 -0700232 topLevelTargetsWithConfigsResult =
ulfjack36fbbde2018-08-02 05:16:00 -0700233 prepareAnalysisPhaseValue.getTopLevelCts(eventHandler, skyframeExecutor);
234 }
235 } else {
236 // Configuration creation.
237 // TODO(gregce): Consider dropping this phase and passing on-the-fly target / host configs as
238 // needed. This requires cleaning up the invalidation in SkyframeBuildView.setConfigurations.
239 try (SilentCloseable c = Profiler.instance().profile("createConfigurations")) {
240 configurations =
jhorvitze362fc92021-04-22 16:04:44 -0700241 skyframeExecutor.createConfigurations(eventHandler, targetOptions, multiCpu, keepGoing);
ulfjack36fbbde2018-08-02 05:16:00 -0700242 }
243 try (SilentCloseable c = Profiler.instance().profile("AnalysisUtils.getTargetsWithConfigs")) {
juliexxiab75e45302019-05-24 07:48:39 -0700244 topLevelTargetsWithConfigsResult =
ulfjack36fbbde2018-08-02 05:16:00 -0700245 AnalysisUtils.getTargetsWithConfigs(
246 configurations, targets, eventHandler, ruleClassProvider, skyframeExecutor);
247 }
248 }
249
mstaib6cf62782018-11-14 11:54:33 -0800250 skyframeBuildView.setConfigurations(
251 eventHandler, configurations, viewOptions.maxConfigChangesToShow);
Marian Lobur86bd4fd2015-09-16 10:01:38 +0000252
ulfjack36fbbde2018-08-02 05:16:00 -0700253 if (configurations.getTargetConfigurations().size() == 1) {
jhorvitze362fc92021-04-22 16:04:44 -0700254 eventBus.post(
255 new MakeEnvironmentEvent(
256 configurations.getTargetConfigurations().get(0).getMakeEnvironment()));
ulfjack36fbbde2018-08-02 05:16:00 -0700257 }
jhorvitz33f76482021-10-28 10:13:26 -0700258 for (BuildConfigurationValue targetConfig : configurations.getTargetConfigurations()) {
felly392e3e42019-08-05 15:16:29 -0700259 eventBus.post(targetConfig.toBuildEvent());
260 }
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100261
juliexxiab75e45302019-05-24 07:48:39 -0700262 Collection<TargetAndConfiguration> topLevelTargetsWithConfigs =
263 topLevelTargetsWithConfigsResult.getTargetsAndConfigs();
264
Klaus Aehlig71c993b2017-05-09 07:49:46 -0400265 // Report the generated association of targets to configurations
jhorvitz33f76482021-10-28 10:13:26 -0700266 Multimap<Label, BuildConfigurationValue> byLabel = ArrayListMultimap.create();
Klaus Aehlig71c993b2017-05-09 07:49:46 -0400267 for (TargetAndConfiguration pair : topLevelTargetsWithConfigs) {
268 byLabel.put(pair.getLabel(), pair.getConfiguration());
269 }
Klaus Aehlig2a92c902017-08-11 14:03:31 +0200270 for (Target target : targets) {
271 eventBus.post(new TargetConfiguredEvent(target, byLabel.get(target.getLabel())));
Klaus Aehlig71c993b2017-05-09 07:49:46 -0400272 }
273
janakr573807d2018-01-11 14:02:35 -0800274 List<ConfiguredTargetKey> topLevelCtKeys =
jcater83221e32020-05-28 11:37:39 -0700275 topLevelTargetsWithConfigs.stream()
jcaterb2dcba52021-09-16 05:17:47 -0700276 .map(BuildView::getConfiguredTargetKey)
ulfjack36fbbde2018-08-02 05:16:00 -0700277 .collect(Collectors.toList());
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100278
messac4157da2021-08-06 11:17:19 -0700279 ImmutableList.Builder<AspectClass> aspectClassesBuilder = ImmutableList.builder();
Dmitry Lomove2033b12015-08-19 16:57:49 +0000280 for (String aspect : aspects) {
Dmitry Lomov0b832ce2015-10-20 10:03:14 +0000281 // Syntax: label%aspect
282 int delimiterPosition = aspect.indexOf('%');
283 if (delimiterPosition >= 0) {
gregceca48e9a2020-04-14 08:54:38 -0700284 // TODO(jfield): For consistency with Starlark loads, the aspect should be specified
laurentlb940dbc52018-03-01 08:07:14 -0800285 // as an absolute label.
286 // We convert it for compatibility reasons (this will be removed in the future).
Dmitry Lomov51aafc12016-11-18 14:02:54 +0000287 String bzlFileLoadLikeString = aspect.substring(0, delimiterPosition);
288 if (!bzlFileLoadLikeString.startsWith("//") && !bzlFileLoadLikeString.startsWith("@")) {
289 // "Legacy" behavior of '--aspects' parameter.
laurentlb940dbc52018-03-01 08:07:14 -0800290 if (bzlFileLoadLikeString.startsWith("/")) {
291 bzlFileLoadLikeString = bzlFileLoadLikeString.substring(1);
292 }
293 int lastSlashPosition = bzlFileLoadLikeString.lastIndexOf('/');
294 if (lastSlashPosition >= 0) {
295 bzlFileLoadLikeString =
296 "//"
297 + bzlFileLoadLikeString.substring(0, lastSlashPosition)
298 + ":"
299 + bzlFileLoadLikeString.substring(lastSlashPosition + 1);
300 } else {
301 bzlFileLoadLikeString = "//:" + bzlFileLoadLikeString;
302 }
303 if (!bzlFileLoadLikeString.endsWith(".bzl")) {
304 bzlFileLoadLikeString = bzlFileLoadLikeString + ".bzl";
Dmitry Lomov51aafc12016-11-18 14:02:54 +0000305 }
306 }
gregce773b95f2020-05-19 09:51:09 -0700307 Label starlarkFileLabel;
Dmitry Lomov51aafc12016-11-18 14:02:54 +0000308 try {
gregce773b95f2020-05-19 09:51:09 -0700309 starlarkFileLabel =
Googlerb2e1fe32019-09-20 14:00:39 -0700310 Label.parseAbsolute(
dannarkf4b9ff42018-06-12 09:28:45 -0700311 bzlFileLoadLikeString, /* repositoryMapping= */ ImmutableMap.of());
Googlerb2e1fe32019-09-20 14:00:39 -0700312 } catch (LabelSyntaxException e) {
mschaller859c9ac2020-09-25 16:09:19 -0700313 String errorMessage = String.format("Invalid aspect '%s': %s", aspect, e.getMessage());
Dmitry Lomov51aafc12016-11-18 14:02:54 +0000314 throw new ViewCreationFailedException(
mschaller859c9ac2020-09-25 16:09:19 -0700315 errorMessage,
316 createFailureDetail(errorMessage, Analysis.Code.ASPECT_LABEL_SYNTAX_ERROR),
317 e);
Dmitry Lomov51aafc12016-11-18 14:02:54 +0000318 }
gregce773b95f2020-05-19 09:51:09 -0700319 String starlarkFunctionName = aspect.substring(delimiterPosition + 1);
messac4157da2021-08-06 11:17:19 -0700320 aspectClassesBuilder.add(new StarlarkAspectClass(starlarkFileLabel, starlarkFunctionName));
Dmitry Lomove2033b12015-08-19 16:57:49 +0000321 } else {
Luis Fernando Pino Duquee82713d2016-04-26 16:22:38 +0000322 final NativeAspectClass aspectFactoryClass =
323 ruleClassProvider.getNativeAspectClassMap().get(aspect);
dslomov99ea6b42017-04-25 17:46:17 +0200324
Dmitry Lomov0b832ce2015-10-20 10:03:14 +0000325 if (aspectFactoryClass != null) {
messac4157da2021-08-06 11:17:19 -0700326 aspectClassesBuilder.add(aspectFactoryClass);
Dmitry Lomov0b832ce2015-10-20 10:03:14 +0000327 } else {
mschaller859c9ac2020-09-25 16:09:19 -0700328 String errorMessage = "Aspect '" + aspect + "' is unknown";
329 throw new ViewCreationFailedException(
330 errorMessage, createFailureDetail(errorMessage, Analysis.Code.ASPECT_NOT_FOUND));
Dmitry Lomov0b832ce2015-10-20 10:03:14 +0000331 }
Dmitry Lomove2033b12015-08-19 16:57:49 +0000332 }
333 }
334
jhorvitz33f76482021-10-28 10:13:26 -0700335 Multimap<Pair<Label, String>, BuildConfigurationValue> aspectConfigurations =
messac4157da2021-08-06 11:17:19 -0700336 ArrayListMultimap.create();
337 ImmutableList<AspectClass> aspectClasses = aspectClassesBuilder.build();
338 ImmutableList.Builder<TopLevelAspectsKey> aspectsKeys = ImmutableList.builder();
339 for (TargetAndConfiguration targetSpec : topLevelTargetsWithConfigs) {
jhorvitz33f76482021-10-28 10:13:26 -0700340 BuildConfigurationValue configuration = targetSpec.getConfiguration();
messac4157da2021-08-06 11:17:19 -0700341 for (AspectClass aspectClass : aspectClasses) {
342 aspectConfigurations.put(
343 Pair.of(targetSpec.getLabel(), aspectClass.getName()), configuration);
344 }
345 // For invoking top-level aspects, use the top-level configuration for both the
346 // aspect and the base target while the top-level configuration is untrimmed.
347 if (!aspectClasses.isEmpty()) {
348 aspectsKeys.add(
lebab52a1902021-09-23 01:35:13 -0700349 AspectKeyCreator.createTopLevelAspectsKey(
messac4157da2021-08-06 11:17:19 -0700350 aspectClasses, targetSpec.getLabel(), configuration));
351 }
352 }
353
Klaus Aehligc27b4da2017-09-01 10:33:22 +0200354 for (Pair<Label, String> target : aspectConfigurations.keys()) {
355 eventBus.post(
356 new AspectConfiguredEvent(
357 target.getFirst(), target.getSecond(), aspectConfigurations.get(target)));
358 }
359
janakr1f08d4c82018-09-15 16:33:35 -0700360 getArtifactFactory().noteAnalysisStarting();
Dmitry Lomove2033b12015-08-19 16:57:49 +0000361 SkyframeAnalysisResult skyframeAnalysisResult;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100362 try {
jhorvitz33f76482021-10-28 10:13:26 -0700363 Supplier<Map<BuildConfigurationKey, BuildConfigurationValue>> configurationLookupSupplier =
ulfjack06295192019-01-16 09:13:34 -0800364 () -> {
jhorvitz33f76482021-10-28 10:13:26 -0700365 Map<BuildConfigurationKey, BuildConfigurationValue> result = new HashMap<>();
ulfjack06295192019-01-16 09:13:34 -0800366 for (TargetAndConfiguration node : topLevelTargetsWithConfigs) {
367 if (node.getConfiguration() != null) {
jhorvitz33f76482021-10-28 10:13:26 -0700368 result.put(node.getConfiguration().getKey(), node.getConfiguration());
ulfjack06295192019-01-16 09:13:34 -0800369 }
370 }
371 return result;
372 };
leba94b810f2021-09-29 01:47:53 -0700373 if (!includeExecutionPhase) {
374 skyframeAnalysisResult =
375 skyframeBuildView.configureTargets(
376 eventHandler,
377 topLevelCtKeys,
378 aspectsKeys.build(),
379 Suppliers.memoize(configurationLookupSupplier),
380 topLevelOptions,
381 eventBus,
382 keepGoing,
383 loadingPhaseThreads,
384 viewOptions.strictConflictChecks,
385 checkForActionConflicts,
386 viewOptions.cpuHeavySkyKeysThreadPoolSize);
387 setArtifactRoots(skyframeAnalysisResult.getPackageRoots());
388 } else {
389 skyframeAnalysisResult =
390 skyframeBuildView.analyzeAndExecuteTargets(
391 eventHandler,
392 topLevelCtKeys,
393 aspectsKeys.build(),
394 topLevelOptions,
395 keepGoing,
396 loadingPhaseThreads,
leba1da8f4c2021-10-05 07:13:14 -0700397 viewOptions.cpuHeavySkyKeysThreadPoolSize,
398 mergedPhasesExecutionJobsCount);
leba94b810f2021-09-29 01:47:53 -0700399 }
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100400 } finally {
janakr6bbad592021-02-17 09:00:38 -0800401 skyframeBuildView.clearInvalidatedActionLookupKeys();
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100402 }
403
Greg Estren7971e672016-06-01 23:22:48 +0000404 int numTargetsToAnalyze = topLevelTargetsWithConfigs.size();
Dmitry Lomove2033b12015-08-19 16:57:49 +0000405 int numSuccessful = skyframeAnalysisResult.getConfiguredTargets().size();
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100406 if (0 < numSuccessful && numSuccessful < numTargetsToAnalyze) {
jhorvitze362fc92021-04-22 16:04:44 -0700407 String msg =
408 String.format(
409 "Analysis succeeded for only %d of %d top-level targets",
410 numSuccessful, numTargetsToAnalyze);
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100411 eventHandler.handle(Event.info(msg));
janakrdbd34bc2019-06-17 06:12:48 -0700412 logger.atInfo().log(msg);
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100413 }
414
leba94b810f2021-09-29 01:47:53 -0700415 AnalysisResult result;
416 if (includeExecutionPhase) {
417 // TODO(b/199053098): Also consider targets with errors like below.
418 result =
419 createResult(
420 eventHandler,
421 eventBus,
422 loadingResult,
423 configurations,
424 topLevelOptions,
425 viewOptions,
426 skyframeAnalysisResult,
427 /*targetsToSkip=*/ ImmutableSet.of(),
428 topLevelTargetsWithConfigsResult,
429 /*includeExecutionPhase=*/ true);
430 } else {
431 TopLevelConstraintSemantics topLevelConstraintSemantics =
432 new TopLevelConstraintSemantics(
433 (RuleContextConstraintSemantics) ruleClassProvider.getConstraintSemantics(),
434 skyframeExecutor.getPackageManager(),
435 input -> skyframeExecutor.getConfiguration(eventHandler, input),
436 eventHandler);
gregce45ae0962017-07-22 00:11:13 +0200437
leba94b810f2021-09-29 01:47:53 -0700438 PlatformRestrictionsResult platformRestrictions =
439 topLevelConstraintSemantics.checkPlatformRestrictions(
440 skyframeAnalysisResult.getConfiguredTargets(), explicitTargetPatterns, keepGoing);
441
442 if (!platformRestrictions.targetsWithErrors().isEmpty()) {
443 // If there are any errored targets (e.g. incompatible targets that are explicitly specified
444 // on the command line), remove them from the list of targets to be built.
445 skyframeAnalysisResult =
446 skyframeAnalysisResult.withAdditionalErroredTargets(
447 platformRestrictions.targetsWithErrors());
448 }
449
450 Set<ConfiguredTarget> targetsToSkip =
451 Sets.union(
452 topLevelConstraintSemantics.checkTargetEnvironmentRestrictions(
453 skyframeAnalysisResult.getConfiguredTargets()),
454 platformRestrictions.targetsToSkip())
455 .immutableCopy();
456
457 result =
458 createResult(
459 eventHandler,
460 eventBus,
461 loadingResult,
462 configurations,
463 topLevelOptions,
464 viewOptions,
465 skyframeAnalysisResult,
466 targetsToSkip,
467 topLevelTargetsWithConfigsResult,
468 /*includeExecutionPhase=*/ false);
469 }
janakrdbd34bc2019-06-17 06:12:48 -0700470 logger.atInfo().log("Finished analysis");
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100471 return result;
472 }
473
jcaterb2dcba52021-09-16 05:17:47 -0700474 private static ConfiguredTargetKey getConfiguredTargetKey(
475 TargetAndConfiguration targetAndConfiguration) {
476 return ConfiguredTargetKey.builder()
477 .setLabel(targetAndConfiguration.getLabel())
478 .setConfiguration(targetAndConfiguration.getConfiguration())
479 .build();
480 }
481
Dmitry Lomove2033b12015-08-19 16:57:49 +0000482 private AnalysisResult createResult(
Klaus Aehlig777b30d2017-02-24 16:30:15 +0000483 ExtendedEventHandler eventHandler,
ulfjackb2cb6402019-01-24 04:04:48 -0800484 EventBus eventBus,
ulfjack12bb59f52018-07-25 07:19:24 -0700485 TargetPatternPhaseValue loadingResult,
ulfjack940fbd72018-06-15 03:23:58 -0700486 BuildConfigurationCollection configurations,
Dmitry Lomove2033b12015-08-19 16:57:49 +0000487 TopLevelArtifactContext topLevelOptions,
ulfjackb5daae32018-06-13 07:59:33 -0700488 AnalysisOptions viewOptions,
gregce45ae0962017-07-22 00:11:13 +0200489 SkyframeAnalysisResult skyframeAnalysisResult,
juliexxia693abdc2018-01-03 08:59:18 -0800490 Set<ConfiguredTarget> targetsToSkip,
leba94b810f2021-09-29 01:47:53 -0700491 TopLevelTargetsAndConfigsResult topLevelTargetsWithConfigs,
492 boolean includeExecutionPhase)
Klaus Aehlig777b30d2017-02-24 16:30:15 +0000493 throws InterruptedException {
ulfjack12bb59f52018-07-25 07:19:24 -0700494 Set<Label> testsToRun = loadingResult.getTestsToRunLabels();
gregce45ae0962017-07-22 00:11:13 +0200495 Set<ConfiguredTarget> configuredTargets =
496 Sets.newLinkedHashSet(skyframeAnalysisResult.getConfiguredTargets());
janakrf15d08d2020-04-22 12:53:03 -0700497 ImmutableMap<AspectKey, ConfiguredAspect> aspects = skyframeAnalysisResult.getAspects();
Dmitry Lomovcf6021a2016-08-09 16:49:32 +0000498
gregce45ae0962017-07-22 00:11:13 +0200499 Set<ConfiguredTarget> allTargetsToTest = null;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100500 if (testsToRun != null) {
501 // Determine the subset of configured targets that are meant to be run as tests.
mjhalupkae253f832018-06-13 14:19:26 -0700502 allTargetsToTest = filterTestsByTargets(configuredTargets, testsToRun);
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100503 }
504
jhorvitzcd477f22021-05-05 10:18:22 -0700505 ImmutableSet.Builder<Artifact> artifactsToBuild = ImmutableSet.builder();
Ulf Adamsfc154ae2015-08-31 12:32:14 +0000506
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100507 // build-info and build-changelist.
Ulf Adams5b9009b2015-09-24 09:52:53 +0000508 Collection<Artifact> buildInfoArtifacts =
509 skyframeExecutor.getWorkspaceStatusArtifacts(eventHandler);
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100510 Preconditions.checkState(buildInfoArtifacts.size() == 2, buildInfoArtifacts);
Ulf Adamsfc154ae2015-08-31 12:32:14 +0000511
512 // Extra actions
mjhalupka7675dbd2018-01-29 12:46:58 -0800513 addExtraActionsIfRequested(
jhorvitzcd477f22021-05-05 10:18:22 -0700514 viewOptions, configuredTargets, aspects, artifactsToBuild, eventHandler);
Ulf Adamsfc154ae2015-08-31 12:32:14 +0000515
516 // Coverage
janakr75bc18a2018-07-13 00:52:17 -0700517 NestedSet<Artifact> baselineCoverageArtifacts =
jhorvitzcd477f22021-05-05 10:18:22 -0700518 getBaselineCoverageArtifacts(configuredTargets, artifactsToBuild);
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100519 if (coverageReportActionFactory != null) {
Googlercdc90e92015-02-11 00:18:07 +0000520 CoverageReportActionsWrapper actionsWrapper;
janakr573807d2018-01-11 14:02:35 -0800521 actionsWrapper =
522 coverageReportActionFactory.createCoverageReportActionsWrapper(
523 eventHandler,
ulfjackb2cb6402019-01-24 04:04:48 -0800524 eventBus,
janakr573807d2018-01-11 14:02:35 -0800525 directories,
526 allTargetsToTest,
527 baselineCoverageArtifacts,
528 getArtifactFactory(),
janakrefb3f152019-06-05 17:42:34 -0700529 skyframeExecutor.getActionKeyContext(),
elenairina9438d102018-07-06 03:06:21 -0700530 CoverageReportValue.COVERAGE_REPORT_KEY,
531 loadingResult.getWorkspaceName());
Googlercdc90e92015-02-11 00:18:07 +0000532 if (actionsWrapper != null) {
janakrefb3f152019-06-05 17:42:34 -0700533 Actions.GeneratingActions actions = actionsWrapper.getActions();
Googlercdc90e92015-02-11 00:18:07 +0000534 skyframeExecutor.injectCoverageReportData(actions);
jhorvitzcd477f22021-05-05 10:18:22 -0700535 actionsWrapper.getCoverageOutputs().forEach(artifactsToBuild::add);
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100536 }
537 }
janakr1a4066a2020-04-13 13:24:27 -0700538 // TODO(cparsons): If extra actions are ever removed, this filtering step can probably be
539 // removed as well: the only concern would be action conflicts involving coverage artifacts,
540 // which seems far-fetched.
541 if (skyframeAnalysisResult.hasActionConflicts()) {
janakr1a4066a2020-04-13 13:24:27 -0700542 // We don't remove the (hopefully unnecessary) guard in SkyframeBuildView that enables/
543 // disables analysis, since no new targets should actually be analyzed.
jhorvitzcd477f22021-05-05 10:18:22 -0700544 ImmutableSet<Artifact> artifacts = artifactsToBuild.build();
janakr1a4066a2020-04-13 13:24:27 -0700545 Predicate<Artifact> errorFreeArtifacts =
546 skyframeExecutor.filterActionConflictsForTopLevelArtifacts(eventHandler, artifacts);
jhorvitzcd477f22021-05-05 10:18:22 -0700547
548 artifactsToBuild = ImmutableSet.builder();
549 artifacts.stream().filter(errorFreeArtifacts).forEach(artifactsToBuild::add);
janakr1a4066a2020-04-13 13:24:27 -0700550 }
551 // Build-info artifacts are always conflict-free, and can't be checked easily.
jhorvitzcd477f22021-05-05 10:18:22 -0700552 buildInfoArtifacts.forEach(artifactsToBuild::add);
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100553
laszlocsomord237db72020-01-09 08:15:07 -0800554 // Tests.
555 Pair<ImmutableSet<ConfiguredTarget>, ImmutableSet<ConfiguredTarget>> testsPair =
556 collectTests(
557 topLevelOptions, allTargetsToTest, skyframeExecutor.getPackageManager(), eventHandler);
558 ImmutableSet<ConfiguredTarget> parallelTests = testsPair.first;
559 ImmutableSet<ConfiguredTarget> exclusiveTests = testsPair.second;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100560
leba94b810f2021-09-29 01:47:53 -0700561 if (includeExecutionPhase) {
562 return new AnalysisAndExecutionResult(
563 configurations,
564 ImmutableSet.copyOf(configuredTargets),
565 aspects,
566 allTargetsToTest == null ? null : ImmutableList.copyOf(allTargetsToTest),
567 ImmutableSet.copyOf(targetsToSkip),
568 artifactsToBuild.build(),
569 parallelTests,
570 exclusiveTests,
571 topLevelOptions,
572 loadingResult.getWorkspaceName(),
573 topLevelTargetsWithConfigs.getTargetsAndConfigs(),
574 loadingResult.getNotSymlinkedInExecrootDirectories());
575 }
576
mschaller75216c72020-06-25 16:04:29 -0700577 FailureDetail failureDetail =
578 createFailureDetail(loadingResult, skyframeAnalysisResult, topLevelTargetsWithConfigs);
Eric Fellheimer9c1e12f2015-08-06 20:23:55 +0000579
jhorvitzcd477f22021-05-05 10:18:22 -0700580 WalkableGraph graph = skyframeAnalysisResult.getWalkableGraph();
581 ActionGraph actionGraph =
Janak Ramakrishnan3c0adb22016-08-15 21:54:55 +0000582 new ActionGraph() {
583 @Nullable
584 @Override
585 public ActionAnalysisMetadata getGeneratingAction(Artifact artifact) {
janakrefb3f152019-06-05 17:42:34 -0700586 if (artifact.isSourceArtifact()) {
587 return null;
Janak Ramakrishnan3c0adb22016-08-15 21:54:55 +0000588 }
janakrefb3f152019-06-05 17:42:34 -0700589 ActionLookupData generatingActionKey =
590 ((Artifact.DerivedArtifact) artifact).getGeneratingActionKey();
591 ActionLookupValue val;
592 try {
593 val = (ActionLookupValue) graph.getValue(generatingActionKey.getActionLookupKey());
594 } catch (InterruptedException e) {
595 throw new IllegalStateException(
596 "Interruption not expected from this graph: " + generatingActionKey, e);
597 }
598 if (val == null) {
janakrdbd34bc2019-06-17 06:12:48 -0700599 logger.atWarning().atMostEvery(1, TimeUnit.SECONDS).log(
600 "Missing generating action for %s (%s)", artifact, generatingActionKey);
janakrefb3f152019-06-05 17:42:34 -0700601 return null;
602 }
Googler2714b882019-08-01 12:30:08 -0700603 return val.getActions().get(generatingActionKey.getActionIndex());
Janak Ramakrishnan3c0adb22016-08-15 21:54:55 +0000604 }
605 };
Dmitry Lomove2033b12015-08-19 16:57:49 +0000606 return new AnalysisResult(
ulfjack940fbd72018-06-15 03:23:58 -0700607 configurations,
laszlocsomor3c8883d2019-12-19 05:19:28 -0800608 ImmutableSet.copyOf(configuredTargets),
Dmitry Lomovcf6021a2016-08-09 16:49:32 +0000609 aspects,
laszlocsomor3c8883d2019-12-19 05:19:28 -0800610 allTargetsToTest == null ? null : ImmutableList.copyOf(allTargetsToTest),
611 ImmutableSet.copyOf(targetsToSkip),
mschaller75216c72020-06-25 16:04:29 -0700612 failureDetail,
Dmitry Lomove2033b12015-08-19 16:57:49 +0000613 actionGraph,
jhorvitzcd477f22021-05-05 10:18:22 -0700614 artifactsToBuild.build(),
laszlocsomord237db72020-01-09 08:15:07 -0800615 parallelTests,
616 exclusiveTests,
Marian Lobur86bd4fd2015-09-16 10:01:38 +0000617 topLevelOptions,
Kristina Chodorow36a6c172016-07-22 15:18:07 +0000618 skyframeAnalysisResult.getPackageRoots(),
juliexxia693abdc2018-01-03 08:59:18 -0800619 loadingResult.getWorkspaceName(),
ichern121933e2020-01-27 02:08:19 -0800620 topLevelTargetsWithConfigs.getTargetsAndConfigs(),
621 loadingResult.getNotSymlinkedInExecrootDirectories());
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100622 }
623
juliexxiab75e45302019-05-24 07:48:39 -0700624 /**
625 * Check for errors in "chronological" order (acknowledge that loading and analysis are
626 * interleaved, but sequential on the single target scale).
627 */
Janak Ramakrishnan6f9d7d12016-08-09 08:45:34 +0000628 @Nullable
mschaller75216c72020-06-25 16:04:29 -0700629 public static FailureDetail createFailureDetail(
ulfjack12bb59f52018-07-25 07:19:24 -0700630 TargetPatternPhaseValue loadingResult,
juliexxiab75e45302019-05-24 07:48:39 -0700631 @Nullable SkyframeAnalysisResult skyframeAnalysisResult,
632 @Nullable TopLevelTargetsAndConfigsResult topLevelTargetsAndConfigs) {
633 if (loadingResult.hasError()) {
mschaller75216c72020-06-25 16:04:29 -0700634 return FailureDetail.newBuilder()
635 .setMessage("command succeeded, but there were errors parsing the target pattern")
636 .setTargetPatterns(TargetPatterns.newBuilder().setCode(Code.TARGET_PATTERN_PARSE_FAILURE))
637 .build();
juliexxiab75e45302019-05-24 07:48:39 -0700638 }
639 if (loadingResult.hasPostExpansionError()
640 || (skyframeAnalysisResult != null && skyframeAnalysisResult.hasLoadingError())) {
mschaller75216c72020-06-25 16:04:29 -0700641 return FailureDetail.newBuilder()
642 .setMessage("command succeeded, but there were loading phase errors")
643 .setAnalysis(Analysis.newBuilder().setCode(Analysis.Code.GENERIC_LOADING_PHASE_FAILURE))
644 .build();
juliexxiab75e45302019-05-24 07:48:39 -0700645 }
646 if (topLevelTargetsAndConfigs != null && topLevelTargetsAndConfigs.hasError()) {
mschaller75216c72020-06-25 16:04:29 -0700647 return FailureDetail.newBuilder()
648 .setMessage("command succeeded, but top level configurations could not be created")
649 .setBuildConfiguration(
650 FailureDetails.BuildConfiguration.newBuilder()
651 .setCode(
652 FailureDetails.BuildConfiguration.Code
653 .TOP_LEVEL_CONFIGURATION_CREATION_FAILURE))
654 .build();
juliexxiab75e45302019-05-24 07:48:39 -0700655 }
656 if (skyframeAnalysisResult != null && skyframeAnalysisResult.hasAnalysisError()) {
mschaller75216c72020-06-25 16:04:29 -0700657 return FailureDetail.newBuilder()
658 .setMessage("command succeeded, but not all targets were analyzed")
659 .setAnalysis(Analysis.newBuilder().setCode(Analysis.Code.NOT_ALL_TARGETS_ANALYZED))
660 .build();
juliexxiab75e45302019-05-24 07:48:39 -0700661 }
662 return null;
Janak Ramakrishnan6f9d7d12016-08-09 08:45:34 +0000663 }
664
mschaller859c9ac2020-09-25 16:09:19 -0700665 private static FailureDetail createFailureDetail(String errorMessage, Analysis.Code code) {
666 return FailureDetail.newBuilder()
667 .setMessage(errorMessage)
668 .setAnalysis(Analysis.newBuilder().setCode(code))
669 .build();
670 }
671
Lukacs Berki6916be22015-02-19 13:36:06 +0000672 private static NestedSet<Artifact> getBaselineCoverageArtifacts(
janakr75bc18a2018-07-13 00:52:17 -0700673 Collection<ConfiguredTarget> configuredTargets,
jhorvitzcd477f22021-05-05 10:18:22 -0700674 ImmutableSet.Builder<Artifact> artifactsToBuild) {
Lukacs Berki6916be22015-02-19 13:36:06 +0000675 NestedSetBuilder<Artifact> baselineCoverageArtifacts = NestedSetBuilder.stableOrder();
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100676 for (ConfiguredTarget target : configuredTargets) {
gregceff941232020-04-21 08:03:32 -0700677 InstrumentedFilesInfo provider = target.get(InstrumentedFilesInfo.STARLARK_CONSTRUCTOR);
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100678 if (provider != null) {
jhorvitzcd477f22021-05-05 10:18:22 -0700679 artifactsToBuild.addAll(provider.getBaselineCoverageArtifacts().toList());
Ulf Adamsfc154ae2015-08-31 12:32:14 +0000680 baselineCoverageArtifacts.addTransitive(provider.getBaselineCoverageArtifacts());
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100681 }
682 }
Lukacs Berki6916be22015-02-19 13:36:06 +0000683 return baselineCoverageArtifacts.build();
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100684 }
685
mjhalupka7675dbd2018-01-29 12:46:58 -0800686 private void addExtraActionsIfRequested(
ulfjackb5daae32018-06-13 07:59:33 -0700687 AnalysisOptions viewOptions,
Dmitry Lomovcf6021a2016-08-09 16:49:32 +0000688 Collection<ConfiguredTarget> configuredTargets,
janakrf15d08d2020-04-22 12:53:03 -0700689 ImmutableMap<AspectKey, ConfiguredAspect> aspects,
jhorvitzcd477f22021-05-05 10:18:22 -0700690 ImmutableSet.Builder<Artifact> artifactsToBuild,
mjhalupka7675dbd2018-01-29 12:46:58 -0800691 ExtendedEventHandler eventHandler) {
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100692 RegexFilter filter = viewOptions.extraActionFilter;
Carmi Grushkodf9e5e12016-11-08 23:07:57 +0000693 for (ConfiguredTarget target : configuredTargets) {
694 ExtraActionArtifactsProvider provider =
695 target.getProvider(ExtraActionArtifactsProvider.class);
696 if (provider != null) {
697 if (viewOptions.extraActionTopLevelOnly) {
lberki9137a752017-06-09 12:49:10 +0200698 // Collect all aspect-classes that topLevel might inject.
699 Set<AspectClass> aspectClasses = new HashSet<>();
mjhalupka7675dbd2018-01-29 12:46:58 -0800700 Target actualTarget = null;
701 try {
702 actualTarget =
703 skyframeExecutor.getPackageManager().getTarget(eventHandler, target.getLabel());
704 } catch (NoSuchPackageException | NoSuchTargetException | InterruptedException e) {
705 eventHandler.handle(Event.error(""));
706 }
707 for (Attribute attr : actualTarget.getAssociatedRule().getAttributes()) {
lberki9137a752017-06-09 12:49:10 +0200708 aspectClasses.addAll(attr.getAspectClasses());
709 }
jhorvitzcd477f22021-05-05 10:18:22 -0700710 addArtifactsToBuilder(
711 provider.getExtraActionArtifacts().toList(), artifactsToBuild, filter);
lberki9137a752017-06-09 12:49:10 +0200712 if (!aspectClasses.isEmpty()) {
jhorvitzcd477f22021-05-05 10:18:22 -0700713 addArtifactsToBuilder(
714 filterTransitiveExtraActions(provider, aspectClasses), artifactsToBuild, filter);
Carmi Grushkodf9e5e12016-11-08 23:07:57 +0000715 }
Carmi Grushkodf9e5e12016-11-08 23:07:57 +0000716 } else {
jhorvitzcd477f22021-05-05 10:18:22 -0700717 addArtifactsToBuilder(
718 provider.getTransitiveExtraActionArtifacts().toList(), artifactsToBuild, filter);
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) {
jhorvitzcd477f22021-05-05 10:18:22 -0700727 addArtifactsToBuilder(
728 provider.getExtraActionArtifacts().toList(), artifactsToBuild, filter);
janakr75bc18a2018-07-13 00:52:17 -0700729 } else {
jhorvitzcd477f22021-05-05 10:18:22 -0700730 addArtifactsToBuilder(
731 provider.getTransitiveExtraActionArtifacts().toList(), artifactsToBuild, filter);
janakr75bc18a2018-07-13 00:52:17 -0700732 }
733 }
734 }
Carmi Grushkodf9e5e12016-11-08 23:07:57 +0000735 }
736
jhorvitzcd477f22021-05-05 10:18:22 -0700737 private static void addArtifactsToBuilder(
738 List<? extends Artifact> artifacts,
739 ImmutableSet.Builder<Artifact> builder,
740 RegexFilter filter) {
741 for (Artifact artifact : artifacts) {
742 if (filter.isIncluded(artifact.getOwnerLabel().toString())) {
743 builder.add(artifact);
744 }
745 }
746 }
747
Carmi Grushkodf9e5e12016-11-08 23:07:57 +0000748 /**
janakr658d47f2019-05-29 11:11:30 -0700749 * Returns a list of artifacts from 'provider' that were registered by an aspect from
750 * 'aspectClasses'. All artifacts in 'provider' are considered - both direct and transitive.
Carmi Grushkodf9e5e12016-11-08 23:07:57 +0000751 */
laszlocsomord237db72020-01-09 08:15:07 -0800752 private static ImmutableList<Artifact> filterTransitiveExtraActions(
Carmi Grushkodf9e5e12016-11-08 23:07:57 +0000753 ExtraActionArtifactsProvider provider, Set<AspectClass> aspectClasses) {
754 ImmutableList.Builder<Artifact> artifacts = ImmutableList.builder();
755 // Add to 'artifacts' all extra-actions which were registered by aspects which 'topLevel'
756 // might have injected.
ulfjack61216fd2019-12-18 12:31:03 -0800757 for (Artifact.DerivedArtifact artifact :
758 provider.getTransitiveExtraActionArtifacts().toList()) {
jhorvitz3daedc32020-07-22 18:33:55 -0700759 ActionLookupKey owner = artifact.getArtifactOwner();
Carmi Grushkobabd4852016-11-18 17:58:09 +0000760 if (owner instanceof AspectKey) {
761 if (aspectClasses.contains(((AspectKey) owner).getAspectClass())) {
762 artifacts.add(artifact);
Carmi Grushkodf9e5e12016-11-08 23:07:57 +0000763 }
764 }
765 }
766 return artifacts.build();
767 }
768
laszlocsomord237db72020-01-09 08:15:07 -0800769 private static Pair<ImmutableSet<ConfiguredTarget>, ImmutableSet<ConfiguredTarget>> collectTests(
mjhalupka7675dbd2018-01-29 12:46:58 -0800770 TopLevelArtifactContext topLevelOptions,
laszlocsomord237db72020-01-09 08:15:07 -0800771 @Nullable Iterable<ConfiguredTarget> allTestTargets,
772 PackageManager packageManager,
mjhalupka7675dbd2018-01-29 12:46:58 -0800773 ExtendedEventHandler eventHandler)
774 throws InterruptedException {
Lukacs Berki3f4d4e92015-02-24 10:28:26 +0000775 Set<String> outputGroups = topLevelOptions.outputGroups();
dslomov69c45f82017-12-14 11:15:43 -0500776 if (!outputGroups.contains(OutputGroupInfo.FILES_TO_COMPILE)
777 && !outputGroups.contains(OutputGroupInfo.COMPILATION_PREREQUISITES)
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100778 && allTestTargets != null) {
laszlocsomord237db72020-01-09 08:15:07 -0800779 final boolean isExclusive = topLevelOptions.runTestsExclusively();
780 ImmutableSet.Builder<ConfiguredTarget> targetsToTest = ImmutableSet.builder();
781 ImmutableSet.Builder<ConfiguredTarget> targetsToTestExclusive = ImmutableSet.builder();
782 for (ConfiguredTarget configuredTarget : allTestTargets) {
jhorvitze362fc92021-04-22 16:04:44 -0700783 Target target;
laszlocsomord237db72020-01-09 08:15:07 -0800784 try {
785 target = packageManager.getTarget(eventHandler, configuredTarget.getLabel());
786 } catch (NoSuchTargetException | NoSuchPackageException e) {
787 eventHandler.handle(Event.error("Failed to get target when scheduling tests"));
788 continue;
789 }
790 if (target instanceof Rule) {
791 if (isExclusive || TargetUtils.isExclusiveTestRule((Rule) target)) {
792 targetsToTestExclusive.add(configuredTarget);
793 } else {
794 targetsToTest.add(configuredTarget);
795 }
796 }
mjhalupka7675dbd2018-01-29 12:46:58 -0800797 }
laszlocsomord237db72020-01-09 08:15:07 -0800798 return Pair.of(targetsToTest.build(), targetsToTestExclusive.build());
799 } else {
800 return Pair.of(ImmutableSet.of(), ImmutableSet.of());
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100801 }
802 }
803
Greg Estren7971e672016-06-01 23:22:48 +0000804 /**
Ulf Adamsa385d3e2015-09-28 13:21:45 +0000805 * Sets the possible artifact roots in the artifact factory. This allows the factory to resolve
806 * paths with unknown roots to artifacts.
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100807 */
ulfjack865b6212018-06-14 03:41:55 -0700808 private void setArtifactRoots(PackageRoots packageRoots) {
janakrae323982017-09-29 21:11:53 +0200809 getArtifactFactory().setPackageRoots(packageRoots.getPackageRootLookup());
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100810 }
811
812 /**
jhorvitze362fc92021-04-22 16:04:44 -0700813 * Tests and clears the current thread's pending "interrupted" status, and throws
814 * InterruptedException iff it was set.
Ulf Adams9c505cb2015-09-28 13:38:14 +0000815 */
jhorvitze362fc92021-04-22 16:04:44 -0700816 private static void pollInterruptedStatus() throws InterruptedException {
Ulf Adams9c505cb2015-09-28 13:38:14 +0000817 if (Thread.interrupted()) {
818 throw new InterruptedException();
819 }
820 }
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100821}