blob: 38fe6dab12d753d65661219b751d053e431446ca [file] [log] [blame]
// Copyright 2021 The Bazel Authors. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package com.google.devtools.build.lib.skyframe;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
import com.google.devtools.build.lib.actions.ActionLookupKey;
import com.google.devtools.build.lib.actions.Artifact;
import com.google.devtools.build.lib.analysis.AspectValue;
import com.google.devtools.build.lib.analysis.ConfiguredTarget;
import com.google.devtools.build.lib.analysis.ConfiguredTargetValue;
import com.google.devtools.build.lib.analysis.ExtraActionArtifactsProvider;
import com.google.devtools.build.lib.analysis.TopLevelArtifactContext;
import com.google.devtools.build.lib.skyframe.AspectCompletionValue.AspectCompletionKey;
import com.google.devtools.build.lib.skyframe.ToplevelStarlarkAspectFunction.TopLevelAspectsValue;
import com.google.devtools.build.lib.util.RegexFilter;
import com.google.devtools.build.skyframe.SkyFunction;
import com.google.devtools.build.skyframe.SkyFunctionException;
import com.google.devtools.build.skyframe.SkyKey;
import com.google.devtools.build.skyframe.SkyValue;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import javax.annotation.Nullable;
/**
* Drives the analysis & execution of an ActionLookupKey, which is wrapped inside a BuildDriverKey.
*/
public class BuildDriverFunction implements SkyFunction {
/**
* From the ConfiguredTarget/Aspect keys, get the top-level artifacts. Then evaluate them together
* with the appropriate CompletionFunctions. This is the bridge between the conceptual analysis &
* execution phases.
*
* <p>TODO(b/199053098): implement build-info, build-changelist, coverage & exception handling.
*/
@Nullable
@Override
public SkyValue compute(SkyKey skyKey, Environment env)
throws SkyFunctionException, InterruptedException {
ActionLookupKey actionLookupKey = ((BuildDriverKey) skyKey).getActionLookupKey();
TopLevelArtifactContext topLevelArtifactContext =
((BuildDriverKey) skyKey).getTopLevelArtifactContext();
// Why SkyValue and not ActionLookupValue? The evaluation of some ActionLookupKey can result in
// classes that don't implement
// ActionLookupValue (e.g. ConfiguredTargetKey -> NonRuleConfiguredTargetValue).
SkyValue topLevelSkyValue = env.getValue(actionLookupKey);
if (env.valuesMissing()) {
return null;
}
ImmutableSet.Builder<Artifact> artifactsToBuild = ImmutableSet.builder();
Preconditions.checkState(
topLevelSkyValue instanceof ConfiguredTargetValue
|| topLevelSkyValue instanceof TopLevelAspectsValue);
if (topLevelSkyValue instanceof ConfiguredTargetValue) {
ConfiguredTarget configuredTarget =
((ConfiguredTargetValue) topLevelSkyValue).getConfiguredTarget();
addExtraActionsIfRequested(
configuredTarget.getProvider(ExtraActionArtifactsProvider.class), artifactsToBuild);
env.getValues(
Iterables.concat(
artifactsToBuild.build(),
Collections.singletonList(
TargetCompletionValue.key(
(ConfiguredTargetKey) actionLookupKey, topLevelArtifactContext, false))));
} else if (topLevelSkyValue instanceof TopLevelAspectsValue) {
List<SkyKey> aspectCompletionKeys = new ArrayList<>();
for (SkyValue aspectValue :
((TopLevelAspectsValue) topLevelSkyValue).getTopLevelAspectsValues()) {
addExtraActionsIfRequested(
((AspectValue) aspectValue)
.getConfiguredAspect()
.getProvider(ExtraActionArtifactsProvider.class),
artifactsToBuild);
aspectCompletionKeys.add(
AspectCompletionKey.create(
((AspectValue) aspectValue).getKey(), topLevelArtifactContext));
}
env.getValues(Iterables.concat(artifactsToBuild.build(), aspectCompletionKeys));
}
if (env.valuesMissing()) {
return null;
}
return new BuildDriverValue(topLevelSkyValue);
}
@Nullable
@Override
public String extractTag(SkyKey skyKey) {
return null;
}
private void addExtraActionsIfRequested(
ExtraActionArtifactsProvider provider, ImmutableSet.Builder<Artifact> artifactsToBuild) {
if (provider != null) {
addArtifactsToBuilder(
provider.getTransitiveExtraActionArtifacts().toList(), artifactsToBuild, null);
}
}
private static void addArtifactsToBuilder(
List<? extends Artifact> artifacts,
ImmutableSet.Builder<Artifact> builder,
RegexFilter filter) {
for (Artifact artifact : artifacts) {
if (filter.isIncluded(artifact.getOwnerLabel().toString())) {
builder.add(artifact);
}
}
}
}