blob: ff153030d6fbf703543e5f9c69b22d538584dcc4 [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
tomlua155b532017-11-08 20:12:47 +010017import static com.google.common.base.Preconditions.checkNotNull;
Jakob Buchgraberfb646092017-02-27 18:53:25 +000018
janakr75bc18a2018-07-13 00:52:17 -070019import com.google.common.annotations.VisibleForTesting;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010020import com.google.devtools.build.lib.actions.Artifact;
ulfjackab21d182017-08-10 15:36:14 +020021import com.google.devtools.build.lib.analysis.test.TestProvider;
janakr75bc18a2018-07-13 00:52:17 -070022import com.google.devtools.build.lib.cmdline.Label;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010023import com.google.devtools.build.lib.collect.nestedset.NestedSet;
24import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder;
Lukacs Berkic340a072015-02-18 13:16:53 +000025import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable;
janakrccb74562018-07-30 10:56:57 -070026import com.google.devtools.build.lib.profiler.AutoProfiler;
Dmitry Lomove2033b12015-08-19 16:57:49 +000027import com.google.devtools.build.lib.skyframe.AspectValue;
janakr75bc18a2018-07-13 00:52:17 -070028import com.google.devtools.build.lib.util.RegexFilter;
janakrccb74562018-07-30 10:56:57 -070029import java.util.logging.Logger;
Googler3ca7b782015-10-12 15:44:09 +000030import javax.annotation.Nullable;
31
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010032/**
33 * A small static class containing utility methods for handling the inclusion of
34 * extra top-level artifacts into the build.
35 */
36public final class TopLevelArtifactHelper {
janakrccb74562018-07-30 10:56:57 -070037 private static Logger logger = Logger.getLogger(TopLevelArtifactHelper.class.getName());
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010038
Jakob Buchgraberfb646092017-02-27 18:53:25 +000039 /** Set of {@link Artifact}s in an output group. */
40 @Immutable
41 public static final class ArtifactsInOutputGroup {
42 private final String outputGroup;
43 private final boolean important;
44 private final NestedSet<Artifact> artifacts;
45
46 private ArtifactsInOutputGroup(
47 String outputGroup, boolean important, NestedSet<Artifact> artifacts) {
48 this.outputGroup = checkNotNull(outputGroup);
49 this.important = important;
50 this.artifacts = checkNotNull(artifacts);
51 }
52
53 public String getOutputGroup() {
54 return outputGroup;
55 }
56
57 public NestedSet<Artifact> getArtifacts() {
58 return artifacts;
59 }
60
61 /** Returns {@code true} if the user should know about this output group. */
62 public boolean areImportant() {
63 return important;
64 }
65 }
66
67 /**
Lukacs Berkic340a072015-02-18 13:16:53 +000068 * The set of artifacts to build.
69 *
Lukacs Berki8af211f2015-02-19 15:42:57 +000070 * <p>There are two kinds: the ones that the user cares about (e.g. files to build) and the ones
hlopkoe1d9b582018-07-23 03:06:32 -070071 * they don't (e.g. baseline coverage artifacts). The latter type doesn't get reported on various
Jakob Buchgraberfb646092017-02-27 18:53:25 +000072 * outputs, e.g. on the console output listing the output artifacts of targets on the command
Lukacs Berki8af211f2015-02-19 15:42:57 +000073 * line.
Lukacs Berkic340a072015-02-18 13:16:53 +000074 */
75 @Immutable
76 public static final class ArtifactsToBuild {
Jakob Buchgraberfb646092017-02-27 18:53:25 +000077 private NestedSet<ArtifactsInOutputGroup> artifacts;
Lukacs Berkic340a072015-02-18 13:16:53 +000078
Jakob Buchgraberfb646092017-02-27 18:53:25 +000079 private ArtifactsToBuild(NestedSet<ArtifactsInOutputGroup> artifacts) {
80 this.artifacts = checkNotNull(artifacts);
Lukacs Berkic340a072015-02-18 13:16:53 +000081 }
82
83 /**
84 * Returns the artifacts that the user should know about.
85 */
86 public NestedSet<Artifact> getImportantArtifacts() {
Jakob Buchgraberfb646092017-02-27 18:53:25 +000087 NestedSetBuilder<Artifact> builder = new NestedSetBuilder<>(artifacts.getOrder());
88 for (ArtifactsInOutputGroup artifactsInOutputGroup : artifacts) {
89 if (artifactsInOutputGroup.areImportant()) {
90 builder.addTransitive(artifactsInOutputGroup.getArtifacts());
91 }
92 }
93 return builder.build();
Lukacs Berkic340a072015-02-18 13:16:53 +000094 }
95
96 /**
97 * Returns the actual set of artifacts that need to be built.
98 */
99 public NestedSet<Artifact> getAllArtifacts() {
Jakob Buchgraberfb646092017-02-27 18:53:25 +0000100 NestedSetBuilder<Artifact> builder = new NestedSetBuilder<>(artifacts.getOrder());
101 for (ArtifactsInOutputGroup artifactsInOutputGroup : artifacts) {
102 builder.addTransitive(artifactsInOutputGroup.getArtifacts());
103 }
104 return builder.build();
105 }
106
107 /**
108 * Returns the set of all {@link Artifact}s grouped by their corresponding output group.
109 *
110 * <p>If an {@link Artifact} belongs to two or more output groups, it appears once in each
111 * output group.
112 */
113 public NestedSet<ArtifactsInOutputGroup> getAllArtifactsByOutputGroup() {
114 return artifacts;
Lukacs Berkic340a072015-02-18 13:16:53 +0000115 }
116 }
117
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100118 private TopLevelArtifactHelper() {
119 // Prevent instantiation.
120 }
121
janakr75bc18a2018-07-13 00:52:17 -0700122 @VisibleForTesting
janakrccb74562018-07-30 10:56:57 -0700123 public static ArtifactsToOwnerLabels makeTopLevelArtifactsToOwnerLabels(
janakr75bc18a2018-07-13 00:52:17 -0700124 AnalysisResult analysisResult, Iterable<AspectValue> aspects) {
janakrccb74562018-07-30 10:56:57 -0700125 try (AutoProfiler ignored = AutoProfiler.logged("assigning owner labels", logger, 10)) {
126
127 ArtifactsToOwnerLabels.Builder artifactsToOwnerLabelsBuilder =
128 analysisResult.getTopLevelArtifactsToOwnerLabels().toBuilder();
janakr75bc18a2018-07-13 00:52:17 -0700129 TopLevelArtifactContext artifactContext = analysisResult.getTopLevelContext();
130 for (ConfiguredTarget target : analysisResult.getTargetsToBuild()) {
janakrccb74562018-07-30 10:56:57 -0700131 addArtifactsWithOwnerLabel(
132 getAllArtifactsToBuild(target, artifactContext).getAllArtifacts(),
133 null,
134 target.getLabel(),
135 artifactsToOwnerLabelsBuilder);
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100136 }
Dmitry Lomove2033b12015-08-19 16:57:49 +0000137 for (AspectValue aspect : aspects) {
janakrccb74562018-07-30 10:56:57 -0700138 addArtifactsWithOwnerLabel(
139 getAllArtifactsToBuild(aspect, artifactContext).getAllArtifacts(),
140 null,
141 aspect.getLabel(),
142 artifactsToOwnerLabelsBuilder);
Dmitry Lomove2033b12015-08-19 16:57:49 +0000143 }
janakr75bc18a2018-07-13 00:52:17 -0700144 if (analysisResult.getTargetsToTest() != null) {
145 for (ConfiguredTarget target : analysisResult.getTargetsToTest()) {
janakrccb74562018-07-30 10:56:57 -0700146 addArtifactsWithOwnerLabel(
147 TestProvider.getTestStatusArtifacts(target),
148 null,
149 target.getLabel(),
150 artifactsToOwnerLabelsBuilder);
janakr75bc18a2018-07-13 00:52:17 -0700151 }
152 }
janakrccb74562018-07-30 10:56:57 -0700153 // TODO(dslomov): Artifacts to test from aspects?
154 return artifactsToOwnerLabelsBuilder.build();
155 }
Dmitry Lomove2033b12015-08-19 16:57:49 +0000156 }
157
janakrccb74562018-07-30 10:56:57 -0700158 static void addArtifactsWithOwnerLabel(
janakr75bc18a2018-07-13 00:52:17 -0700159 Iterable<Artifact> artifacts,
160 @Nullable RegexFilter filter,
161 Label ownerLabel,
janakrccb74562018-07-30 10:56:57 -0700162 ArtifactsToOwnerLabels.Builder artifactsToOwnerLabelsBuilder) {
janakr75bc18a2018-07-13 00:52:17 -0700163 for (Artifact artifact : artifacts) {
164 if (filter == null || filter.isIncluded(artifact.getOwnerLabel().toString())) {
janakrccb74562018-07-30 10:56:57 -0700165 artifactsToOwnerLabelsBuilder.addArtifact(artifact, ownerLabel);
janakr75bc18a2018-07-13 00:52:17 -0700166 }
167 }
168 }
Dmitry Lomove2033b12015-08-19 16:57:49 +0000169
170 /**
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100171 * Returns all artifacts to build if this target is requested as a top-level target. The resulting
172 * set includes the temps and either the files to compile, if
Lukacs Berkic1f894e2015-02-17 13:00:26 +0000173 * {@code context.compileOnly() == true}, or the files to run.
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100174 *
175 * <p>Calls to this method should generally return quickly; however, the runfiles computation can
176 * be lazy, in which case it can be expensive on the first call. Subsequent calls may or may not
177 * return the same {@code Iterable} instance.
178 */
Lukacs Berkic340a072015-02-18 13:16:53 +0000179 public static ArtifactsToBuild getAllArtifactsToBuild(TransitiveInfoCollection target,
Lukacs Berkic1f894e2015-02-17 13:00:26 +0000180 TopLevelArtifactContext context) {
Googler3ca7b782015-10-12 15:44:09 +0000181 return getAllArtifactsToBuild(
dslomov69c45f82017-12-14 11:15:43 -0500182 OutputGroupInfo.get(target),
Googler3ca7b782015-10-12 15:44:09 +0000183 target.getProvider(FileProvider.class),
184 context
185 );
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100186 }
Dmitry Lomove2033b12015-08-19 16:57:49 +0000187
188 public static ArtifactsToBuild getAllArtifactsToBuild(
189 AspectValue aspectValue, TopLevelArtifactContext context) {
Dmitry Lomovb487ac62015-11-09 13:09:12 +0000190 ConfiguredAspect configuredAspect = aspectValue.getConfiguredAspect();
Googler3ca7b782015-10-12 15:44:09 +0000191 return getAllArtifactsToBuild(
dslomov69c45f82017-12-14 11:15:43 -0500192 OutputGroupInfo.get(configuredAspect),
Dmitry Lomovb487ac62015-11-09 13:09:12 +0000193 configuredAspect.getProvider(FileProvider.class),
194 context);
Googler3ca7b782015-10-12 15:44:09 +0000195 }
196
janakr75bc18a2018-07-13 00:52:17 -0700197 static ArtifactsToBuild getAllArtifactsToBuild(
dslomov69c45f82017-12-14 11:15:43 -0500198 @Nullable OutputGroupInfo outputGroupInfo,
Googler3ca7b782015-10-12 15:44:09 +0000199 @Nullable FileProvider fileProvider,
200 TopLevelArtifactContext context) {
Jakob Buchgraberfb646092017-02-27 18:53:25 +0000201 NestedSetBuilder<ArtifactsInOutputGroup> allBuilder = NestedSetBuilder.stableOrder();
Dmitry Lomove2033b12015-08-19 16:57:49 +0000202
Dmitry Lomove2033b12015-08-19 16:57:49 +0000203 for (String outputGroup : context.outputGroups()) {
204 NestedSetBuilder<Artifact> results = NestedSetBuilder.stableOrder();
205
dslomov69c45f82017-12-14 11:15:43 -0500206 if (outputGroup.equals(OutputGroupInfo.DEFAULT) && fileProvider != null) {
Jakob Buchgraberfb646092017-02-27 18:53:25 +0000207 results.addTransitive(fileProvider.getFilesToBuild());
Dmitry Lomove2033b12015-08-19 16:57:49 +0000208 }
209
dslomov69c45f82017-12-14 11:15:43 -0500210 if (outputGroupInfo != null) {
211 results.addTransitive(outputGroupInfo.getOutputGroup(outputGroup));
Dmitry Lomove2033b12015-08-19 16:57:49 +0000212 }
213
Jakob Buchgraberfb646092017-02-27 18:53:25 +0000214 // Ignore output groups that have no artifacts.
215 if (results.isEmpty()) {
216 continue;
Dmitry Lomove2033b12015-08-19 16:57:49 +0000217 }
Jakob Buchgraberfb646092017-02-27 18:53:25 +0000218
219 boolean isImportantGroup =
dslomov69c45f82017-12-14 11:15:43 -0500220 !outputGroup.startsWith(OutputGroupInfo.HIDDEN_OUTPUT_GROUP_PREFIX);
Jakob Buchgraberfb646092017-02-27 18:53:25 +0000221
222 ArtifactsInOutputGroup artifacts =
223 new ArtifactsInOutputGroup(outputGroup, isImportantGroup, results.build());
224
225 allBuilder.add(artifacts);
Dmitry Lomove2033b12015-08-19 16:57:49 +0000226 }
227
Jakob Buchgraberfb646092017-02-27 18:53:25 +0000228 return new ArtifactsToBuild(allBuilder.build());
Dmitry Lomove2033b12015-08-19 16:57:49 +0000229 }
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100230}