blob: acb8d9f10f1211b18bea7bd8de453448e52eae0f [file] [log] [blame]
// Copyright 2018 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.analysis.util;
import static com.google.common.collect.ImmutableList.toImmutableList;
import static com.google.common.collect.ImmutableMap.toImmutableMap;
import static com.google.devtools.build.lib.analysis.config.transitions.TransitionCollector.NULL_TRANSITION_COLLECTOR;
import static com.google.devtools.build.lib.skyframe.PrerequisiteProducer.getDependencyContext;
import com.google.common.base.Preconditions;
import com.google.common.collect.Collections2;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.MapDifference;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import com.google.common.eventbus.EventBus;
import com.google.devtools.build.lib.actions.ActionLookupKey;
import com.google.devtools.build.lib.actions.ArtifactFactory;
import com.google.devtools.build.lib.actions.BuildFailedException;
import com.google.devtools.build.lib.actions.PackageRoots;
import com.google.devtools.build.lib.actions.TestExecException;
import com.google.devtools.build.lib.analysis.AnalysisEnvironment;
import com.google.devtools.build.lib.analysis.AnalysisOptions;
import com.google.devtools.build.lib.analysis.AnalysisResult;
import com.google.devtools.build.lib.analysis.AnalysisUtils;
import com.google.devtools.build.lib.analysis.AspectValue;
import com.google.devtools.build.lib.analysis.BlazeDirectories;
import com.google.devtools.build.lib.analysis.BuildView;
import com.google.devtools.build.lib.analysis.CachingAnalysisEnvironment;
import com.google.devtools.build.lib.analysis.ConfiguredAspect;
import com.google.devtools.build.lib.analysis.ConfiguredRuleClassProvider;
import com.google.devtools.build.lib.analysis.ConfiguredTarget;
import com.google.devtools.build.lib.analysis.ConfiguredTargetFactory;
import com.google.devtools.build.lib.analysis.DependencyKey;
import com.google.devtools.build.lib.analysis.DependencyKind;
import com.google.devtools.build.lib.analysis.DependencyResolver;
import com.google.devtools.build.lib.analysis.DependencyResolver.DependencyLabels;
import com.google.devtools.build.lib.analysis.DuplicateException;
import com.google.devtools.build.lib.analysis.ExecGroupCollection.InvalidExecGroupException;
import com.google.devtools.build.lib.analysis.InconsistentAspectOrderException;
import com.google.devtools.build.lib.analysis.PartiallyResolvedDependency;
import com.google.devtools.build.lib.analysis.ResolvedToolchainContext;
import com.google.devtools.build.lib.analysis.RuleContext;
import com.google.devtools.build.lib.analysis.TargetAndConfiguration;
import com.google.devtools.build.lib.analysis.ToolchainCollection;
import com.google.devtools.build.lib.analysis.ToolchainContext;
import com.google.devtools.build.lib.analysis.TopLevelArtifactContext;
import com.google.devtools.build.lib.analysis.TransitiveDependencyState;
import com.google.devtools.build.lib.analysis.ViewCreationFailedException;
import com.google.devtools.build.lib.analysis.config.BuildConfigurationValue;
import com.google.devtools.build.lib.analysis.config.BuildOptions;
import com.google.devtools.build.lib.analysis.config.ConfigConditions;
import com.google.devtools.build.lib.analysis.config.ConfigMatchingProvider;
import com.google.devtools.build.lib.analysis.config.ConfigurationResolver;
import com.google.devtools.build.lib.analysis.config.DependencyEvaluationException;
import com.google.devtools.build.lib.analysis.config.InvalidConfigurationException;
import com.google.devtools.build.lib.analysis.configuredtargets.MergedConfiguredTarget;
import com.google.devtools.build.lib.analysis.constraints.IncompatibleTargetChecker.IncompatibleTargetException;
import com.google.devtools.build.lib.analysis.platform.ConstraintValueInfo;
import com.google.devtools.build.lib.analysis.platform.PlatformInfo;
import com.google.devtools.build.lib.analysis.producers.DependencyContext;
import com.google.devtools.build.lib.analysis.producers.PrerequisiteParameters;
import com.google.devtools.build.lib.analysis.starlark.StarlarkTransition;
import com.google.devtools.build.lib.analysis.test.CoverageReportActionFactory;
import com.google.devtools.build.lib.bugreport.BugReporter;
import com.google.devtools.build.lib.causes.Cause;
import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder;
import com.google.devtools.build.lib.collect.nestedset.Order;
import com.google.devtools.build.lib.concurrent.ThreadSafety.ThreadCompatible;
import com.google.devtools.build.lib.events.Event;
import com.google.devtools.build.lib.events.EventHandler;
import com.google.devtools.build.lib.events.ExtendedEventHandler;
import com.google.devtools.build.lib.events.StoredEventHandler;
import com.google.devtools.build.lib.packages.Attribute;
import com.google.devtools.build.lib.packages.BuildType;
import com.google.devtools.build.lib.packages.NoSuchPackageException;
import com.google.devtools.build.lib.packages.NoSuchTargetException;
import com.google.devtools.build.lib.packages.PackageSpecification;
import com.google.devtools.build.lib.packages.PackageSpecification.PackageGroupContents;
import com.google.devtools.build.lib.packages.RawAttributeMapper;
import com.google.devtools.build.lib.packages.Rule;
import com.google.devtools.build.lib.packages.Target;
import com.google.devtools.build.lib.runtime.QuiescingExecutorsImpl;
import com.google.devtools.build.lib.skyframe.AspectKeyCreator;
import com.google.devtools.build.lib.skyframe.AspectKeyCreator.AspectKey;
import com.google.devtools.build.lib.skyframe.ConfiguredTargetAndData;
import com.google.devtools.build.lib.skyframe.ConfiguredTargetKey;
import com.google.devtools.build.lib.skyframe.ConfiguredValueCreationException;
import com.google.devtools.build.lib.skyframe.PrerequisiteProducer;
import com.google.devtools.build.lib.skyframe.SkyFunctionEnvironmentForTesting;
import com.google.devtools.build.lib.skyframe.SkyframeBuildView;
import com.google.devtools.build.lib.skyframe.SkyframeExecutor;
import com.google.devtools.build.lib.skyframe.StarlarkBuiltinsValue;
import com.google.devtools.build.lib.skyframe.TargetPatternPhaseValue;
import com.google.devtools.build.lib.skyframe.toolchains.ToolchainException;
import com.google.devtools.build.lib.skyframe.toolchains.UnloadedToolchainContext;
import com.google.devtools.build.lib.util.AbruptExitException;
import com.google.devtools.build.lib.util.OrderedSetMultimap;
import com.google.devtools.build.skyframe.NodeEntry;
import com.google.devtools.build.skyframe.SkyFunction;
import com.google.devtools.build.skyframe.SkyKey;
import com.google.devtools.build.skyframe.Version;
import com.google.devtools.build.skyframe.WalkableGraph;
import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.annotation.Nullable;
import net.starlark.java.eval.Mutability;
/**
* A util class that contains all the helper stuff previously in BuildView that only exists to give
* tests access to Skyframe internals. The code largely predates the introduction of Skyframe, and
* mostly exists to avoid having to rewrite our tests to work with Skyframe natively.
*/
public class BuildViewForTesting {
private final BuildView buildView;
private final SkyframeExecutor skyframeExecutor;
private final SkyframeBuildView skyframeBuildView;
private final ConfiguredRuleClassProvider ruleClassProvider;
private ImmutableMap<ActionLookupKey, Version> currentActionLookupKeys = ImmutableMap.of();
public BuildViewForTesting(
BlazeDirectories directories,
ConfiguredRuleClassProvider ruleClassProvider,
SkyframeExecutor skyframeExecutor,
CoverageReportActionFactory coverageReportActionFactory) {
this.buildView =
new BuildView(
directories, ruleClassProvider, skyframeExecutor, coverageReportActionFactory);
this.ruleClassProvider = ruleClassProvider;
this.skyframeExecutor = Preconditions.checkNotNull(skyframeExecutor);
this.skyframeBuildView = skyframeExecutor.getSkyframeBuildView();
}
Set<ActionLookupKey> getSkyframeEvaluatedActionLookupKeyCountForTesting() {
Set<ActionLookupKey> actionLookupKeys = populateActionLookupKeyMapAndGetDiff();
Preconditions.checkState(
actionLookupKeys.size() == skyframeBuildView.getEvaluatedCounts().total(),
"Number of newly evaluated action lookup values %s does not agree with number that changed"
+ " in graph: %s. Keys: %s",
actionLookupKeys.size(),
skyframeBuildView.getEvaluatedCounts().total(),
actionLookupKeys);
return actionLookupKeys;
}
private Set<ActionLookupKey> populateActionLookupKeyMapAndGetDiff() {
ImmutableMap<ActionLookupKey, Version> newMap =
skyframeExecutor.getEvaluator().getInMemoryGraph().getAllNodeEntries().stream()
.filter(e -> e.getKey() instanceof ActionLookupKey)
.collect(toImmutableMap(e -> (ActionLookupKey) e.getKey(), NodeEntry::getVersion));
MapDifference<ActionLookupKey, Version> difference =
Maps.difference(newMap, currentActionLookupKeys);
currentActionLookupKeys = newMap;
return Sets.union(
difference.entriesDiffering().keySet(), difference.entriesOnlyOnLeft().keySet());
}
/** Returns whether the given configured target has errors. */
public boolean hasErrors(ConfiguredTarget configuredTarget) {
return configuredTarget == null;
}
@ThreadCompatible
public AnalysisResult update(
TargetPatternPhaseValue loadingResult,
BuildOptions targetOptions,
ImmutableSet<Label> explicitTargetPatterns,
List<String> aspects,
ImmutableMap<String, String> aspectsParameters,
AnalysisOptions viewOptions,
boolean keepGoing,
int loadingPhaseThreads,
TopLevelArtifactContext topLevelOptions,
ExtendedEventHandler eventHandler,
EventBus eventBus)
throws ViewCreationFailedException, InterruptedException, InvalidConfigurationException,
BuildFailedException, TestExecException, AbruptExitException {
populateActionLookupKeyMapAndGetDiff();
return buildView.update(
loadingResult,
targetOptions,
explicitTargetPatterns,
aspects,
aspectsParameters,
viewOptions,
keepGoing,
/* skipIncompatibleExplicitTargets= */ false,
/* checkForActionConflicts= */ true,
QuiescingExecutorsImpl.forTesting(),
topLevelOptions,
/* reportIncompatibleTargets= */ true,
eventHandler,
eventBus,
BugReporter.defaultInstance(),
/* includeExecutionPhase= */ false,
/* skymeldAnalysisOverlapPercentage= */ 0,
/* resourceManager= */ null,
/* buildResultListener= */ null,
/* executionSetupCallback= */ null,
/* buildConfigurationsCreatedCallback= */ null,
/* buildDriverKeyTestContext= */ null);
}
/** Sets the configuration. Not thread-safe. */
public void setConfigurationForTesting(
EventHandler eventHandler, BuildConfigurationValue configuration) {
skyframeBuildView.setConfiguration(eventHandler, configuration, /* maxDifferencesToShow= */ -1);
}
public ArtifactFactory getArtifactFactory() {
return skyframeBuildView.getArtifactFactory();
}
/**
* Gets a configuration for the given target.
*
* <p>Unconditionally includes all fragments.
*/
public BuildConfigurationValue getConfigurationForTesting(
Target target, BuildConfigurationValue config, ExtendedEventHandler eventHandler)
throws InvalidConfigurationException, InterruptedException {
List<TargetAndConfiguration> node =
ImmutableList.of(new TargetAndConfiguration(target, config));
Collection<TargetAndConfiguration> configs =
ConfigurationResolver.getConfigurationsFromExecutor(
node,
AnalysisUtils.targetsToDeps(new LinkedHashSet<>(node), ruleClassProvider),
eventHandler,
skyframeExecutor)
.getTargetsAndConfigs();
return configs.iterator().next().getConfiguration();
}
/**
* Sets the possible artifact roots in the artifact factory. This allows the factory to resolve
* paths with unknown roots to artifacts.
*/
public void setArtifactRoots(PackageRoots packageRoots) {
getArtifactFactory().setPackageRoots(packageRoots.getPackageRootLookup());
}
public Collection<ConfiguredTarget> getDirectPrerequisitesForTesting(
ExtendedEventHandler eventHandler, ConfiguredTarget ct)
throws InterruptedException,
DependencyResolver.Failure,
InvalidConfigurationException,
InconsistentAspectOrderException,
StarlarkTransition.TransitionException {
return Collections2.transform(
getConfiguredTargetAndDataDirectPrerequisitesForTesting(eventHandler, ct),
ConfiguredTargetAndData::getConfiguredTarget);
}
protected Collection<ConfiguredTargetAndData>
getConfiguredTargetAndDataDirectPrerequisitesForTesting(
ExtendedEventHandler eventHandler, ConfiguredTarget configuredTarget)
throws InterruptedException,
DependencyResolver.Failure,
InvalidConfigurationException,
InconsistentAspectOrderException,
StarlarkTransition.TransitionException {
return getPrerequisiteMapForTesting(
eventHandler,
configuredTarget,
prepareDependencyContext(eventHandler, configuredTarget))
.values();
}
// Helper method to find the aspects needed for a target and merge them.
protected static ConfiguredTargetAndData mergeAspects(
WalkableGraph graph, ConfiguredTargetAndData ctd, @Nullable DependencyKey dependencyKey) {
if (dependencyKey == null || dependencyKey.getAspects().getUsedAspects().isEmpty()) {
return ctd;
}
ConfiguredTargetKey ctKey =
ConfiguredTargetKey.builder()
.setLabel(dependencyKey.getLabel())
.setConfiguration(ctd.getConfiguration())
.build();
List<SkyKey> aspectKeys =
dependencyKey.getAspects().getUsedAspects().stream()
.map(aspect -> AspectKeyCreator.createAspectKey(aspect.getAspect(), ctKey))
.collect(toImmutableList());
try {
ImmutableList<ConfiguredAspect> configuredAspects =
graph.getSuccessfulValues(aspectKeys).values().stream()
.map(value -> (AspectValue) value)
.map(AspectValue::getConfiguredAspect)
.collect(toImmutableList());
return ctd.fromConfiguredTarget(
MergedConfiguredTarget.of(ctd.getConfiguredTarget(), configuredAspects));
} catch (InterruptedException | DuplicateException e) {
throw new IllegalStateException("Unexpected exception while finding prerequisites", e);
}
}
public OrderedSetMultimap<DependencyKind, PartiallyResolvedDependency>
getDirectPrerequisiteDependenciesForTesting(
final ExtendedEventHandler eventHandler,
final ConfiguredTarget ct,
@Nullable ToolchainCollection<ToolchainContext> toolchainContexts)
throws DependencyResolver.Failure,
InterruptedException,
InconsistentAspectOrderException,
StarlarkTransition.TransitionException,
InvalidConfigurationException {
Target target;
try {
target = skyframeExecutor.getPackageManager().getTarget(eventHandler, ct.getLabel());
} catch (NoSuchPackageException | NoSuchTargetException | InterruptedException e) {
eventHandler.handle(
Event.error("Failed to get target from package during prerequisite analysis." + e));
return OrderedSetMultimap.create();
}
if (!(target instanceof Rule)) {
return OrderedSetMultimap.create();
}
BuildConfigurationValue configuration =
skyframeExecutor.getConfiguration(eventHandler, ct.getConfigurationKey());
TargetAndConfiguration ctgNode = new TargetAndConfiguration(target, configuration);
DependencyLabels dependencyLabels =
DependencyResolver.computeDependencyLabels(
ctgNode,
/* aspects= */ ImmutableList.of(),
getConfigurableAttributeKeysForTesting(
eventHandler,
ctgNode,
toolchainContexts == null ? null : toolchainContexts.getTargetPlatform()),
toolchainContexts);
return DependencyResolver.partiallyResolveDependencies(
dependencyLabels.labels(),
target.getAssociatedRule(),
dependencyLabels.attributeMap(),
toolchainContexts,
/* aspects= */ ImmutableList.of(),
NULL_TRANSITION_COLLECTOR);
}
/**
* Returns ConfigMatchingProvider instances corresponding to the configurable attribute keys
* present in this rule's attributes.
*/
private ImmutableMap<Label, ConfigMatchingProvider> getConfigurableAttributeKeysForTesting(
ExtendedEventHandler eventHandler,
TargetAndConfiguration ctg,
@Nullable PlatformInfo platformInfo)
throws StarlarkTransition.TransitionException, InvalidConfigurationException,
InterruptedException {
if (!(ctg.getTarget() instanceof Rule)) {
return ImmutableMap.of();
}
Rule rule = (Rule) ctg.getTarget();
Map<Label, ConfigMatchingProvider> keys = new LinkedHashMap<>();
RawAttributeMapper mapper = RawAttributeMapper.of(rule);
for (Attribute attribute : rule.getAttributes()) {
for (Label label : mapper.getConfigurabilityKeys(attribute.getName(), attribute.getType())) {
if (BuildType.Selector.isDefaultConditionLabel(label)) {
continue;
}
ConfiguredTarget ct =
getConfiguredTargetForTesting(eventHandler, label, ctg.getConfiguration());
ConfigMatchingProvider matchProvider = ct.getProvider(ConfigMatchingProvider.class);
ConstraintValueInfo constraintValueInfo = ct.get(ConstraintValueInfo.PROVIDER);
if (matchProvider != null) {
keys.put(label, matchProvider);
} else if (constraintValueInfo != null && platformInfo != null) {
keys.put(label, constraintValueInfo.configMatchingProvider(platformInfo));
} else {
throw new InvalidConfigurationException(
String.format("%s isn't a valid select() condition", label));
}
}
}
return ImmutableMap.copyOf(keys);
}
private OrderedSetMultimap<DependencyKind, ConfiguredTargetAndData> getPrerequisiteMapForTesting(
final ExtendedEventHandler eventHandler,
ConfiguredTarget target,
PrerequisiteProducer.State state)
throws DependencyResolver.Failure,
InvalidConfigurationException,
InterruptedException,
InconsistentAspectOrderException,
StarlarkTransition.TransitionException {
DependencyContext dependencyContext = state.dependencyContext;
ToolchainCollection<ToolchainContext> toolchainContexts = dependencyContext.toolchainContexts();
DependencyLabels labels =
DependencyResolver.computeDependencyLabels(
state.targetAndConfiguration,
/* aspects= */ ImmutableList.of(),
dependencyContext.configConditions().asProviders(),
toolchainContexts);
var transitiveState = TransitiveDependencyState.createForTesting();
OrderedSetMultimap<DependencyKind, ConfiguredTargetAndData> result =
skyframeExecutor.getConfiguredTargetMapForTesting(
eventHandler,
new PrerequisiteParameters(
ConfiguredTargetKey.fromConfiguredTarget(target),
state.targetAndConfiguration.getTarget().getAssociatedRule(),
/* aspects= */ ImmutableList.of(),
skyframeBuildView.getStarlarkTransitionCache(),
toolchainContexts,
labels.attributeMap(),
transitiveState),
labels.labels());
if (!transitiveState.transitiveRootCauses().isEmpty()) {
throw new IllegalStateException(
"expected empty: " + transitiveState.transitiveRootCauses().build().toList());
}
return result;
}
/**
* Returns a configured target for the specified target and configuration. If the target in
* question has a top-level rule class transition, that transition is applied in the returned
* ConfiguredTarget.
*
* <p>Returns {@code null} if something goes wrong.
*/
public ConfiguredTarget getConfiguredTargetForTesting(
ExtendedEventHandler eventHandler, Label label, BuildConfigurationValue config)
throws InvalidConfigurationException, InterruptedException {
return skyframeExecutor.getConfiguredTargetForTesting(eventHandler, label, config);
}
ConfiguredTargetAndData getConfiguredTargetAndDataForTesting(
ExtendedEventHandler eventHandler, Label label, BuildConfigurationValue config)
throws InvalidConfigurationException, InterruptedException {
return skyframeExecutor.getConfiguredTargetAndDataForTesting(eventHandler, label, config);
}
/**
* Returns a RuleContext which is the same as the original RuleContext of the target parameter.
*/
public RuleContext getRuleContextForTesting(
ConfiguredTarget target, StoredEventHandler eventHandler)
throws DependencyResolver.Failure,
InvalidConfigurationException,
InterruptedException,
InconsistentAspectOrderException,
ToolchainException,
StarlarkTransition.TransitionException,
InvalidExecGroupException {
BuildConfigurationValue targetConfig =
skyframeExecutor.getConfiguration(eventHandler, target.getConfigurationKey());
SkyFunction.Environment skyframeEnv =
new SkyFunctionEnvironmentForTesting(eventHandler, skyframeExecutor);
StarlarkBuiltinsValue starlarkBuiltinsValue =
(StarlarkBuiltinsValue)
Preconditions.checkNotNull(skyframeEnv.getValue(StarlarkBuiltinsValue.key()));
CachingAnalysisEnvironment analysisEnv =
new CachingAnalysisEnvironment(
getArtifactFactory(),
skyframeExecutor.getActionKeyContext(),
ConfiguredTargetKey.builder()
.setLabel(target.getLabel())
.setConfiguration(targetConfig)
.build(),
targetConfig.extendedSanityChecks(),
targetConfig.allowAnalysisFailures(),
eventHandler,
skyframeEnv,
starlarkBuiltinsValue);
return getRuleContextForTesting(eventHandler, target, analysisEnv);
}
/**
* Creates and returns a rule context that is equivalent to the one that was used to create the
* given configured target.
*/
public RuleContext getRuleContextForTesting(
ExtendedEventHandler eventHandler, ConfiguredTarget configuredTarget, AnalysisEnvironment env)
throws DependencyResolver.Failure,
InvalidConfigurationException,
InterruptedException,
InconsistentAspectOrderException,
ToolchainException,
StarlarkTransition.TransitionException,
InvalidExecGroupException {
PrerequisiteProducer.State state = prepareDependencyContext(eventHandler, configuredTarget);
OrderedSetMultimap<DependencyKind, ConfiguredTargetAndData> prerequisiteMap =
getPrerequisiteMapForTesting(eventHandler, configuredTarget, state);
TargetAndConfiguration targetAndConfiguration = state.targetAndConfiguration;
Target target = targetAndConfiguration.getTarget();
String targetDescription = target.toString();
ToolchainCollection<UnloadedToolchainContext> unloadedToolchainCollection =
state.dependencyContext.unloadedToolchainContexts();
ToolchainCollection.Builder<ResolvedToolchainContext> resolvedToolchainContext =
ToolchainCollection.builder();
for (Map.Entry<String, UnloadedToolchainContext> unloadedToolchainContext :
unloadedToolchainCollection.getContextMap().entrySet()) {
ResolvedToolchainContext toolchainContext =
ResolvedToolchainContext.load(
unloadedToolchainContext.getValue(),
targetDescription,
ImmutableSet.copyOf(
prerequisiteMap.get(
DependencyKind.forExecGroup(unloadedToolchainContext.getKey()))));
resolvedToolchainContext.addContext(unloadedToolchainContext.getKey(), toolchainContext);
}
return new RuleContext.Builder(
env,
target,
/* aspects= */ ImmutableList.of(),
targetAndConfiguration.getConfiguration())
.setRuleClassProvider(ruleClassProvider)
.setConfigurationFragmentPolicy(
target.getAssociatedRule().getRuleClassObject().getConfigurationFragmentPolicy())
.setActionOwnerSymbol(ConfiguredTargetKey.fromConfiguredTarget(configuredTarget))
.setMutability(Mutability.create("configured target"))
.setVisibility(
NestedSetBuilder.create(
Order.STABLE_ORDER,
PackageGroupContents.create(ImmutableList.of(PackageSpecification.everything()))))
.setPrerequisites(ConfiguredTargetFactory.transformPrerequisiteMap(prerequisiteMap))
.setConfigConditions(ConfigConditions.EMPTY)
.setToolchainContexts(resolvedToolchainContext.build())
.setExecGroupCollectionBuilder(state.execGroupCollectionBuilder)
.unsafeBuild();
}
private PrerequisiteProducer.State prepareDependencyContext(
ExtendedEventHandler eventHandler, ConfiguredTarget configuredTarget)
throws InterruptedException {
// In production, the TargetAndConfiguration value is based on final configuration of the
// ConfiguredTarget after any rule transition is applied.
BuildConfigurationValue configuration =
skyframeExecutor.getConfiguration(eventHandler, configuredTarget.getConfigurationKey());
Target target;
try {
target =
skyframeExecutor.getPackageManager().getTarget(eventHandler, configuredTarget.getLabel());
} catch (NoSuchPackageException | NoSuchTargetException e) {
eventHandler.handle(
Event.error("Failed to get target when trying to get rule context for testing"));
throw new IllegalStateException(e);
}
SkyFunctionEnvironmentForTesting skyfunctionEnvironment =
new SkyFunctionEnvironmentForTesting(eventHandler, skyframeExecutor);
var state = new PrerequisiteProducer.State(/* storeTransitivePackages= */ false);
state.targetAndConfiguration =
new TargetAndConfiguration(target.getAssociatedRule(), configuration);
NestedSetBuilder<Cause> transitiveRootCauses = NestedSetBuilder.stableOrder();
try {
// Callers read this value from `state`.
var unused =
getDependencyContext(
state,
ConfiguredTargetKey.fromConfiguredTarget(configuredTarget),
ruleClassProvider,
skyfunctionEnvironment,
eventHandler);
} catch (ConfiguredValueCreationException
| IncompatibleTargetException
| ToolchainException
| DependencyEvaluationException e) {
throw new IllegalStateException(e);
}
if (!transitiveRootCauses.isEmpty()) {
throw new IllegalStateException("expected empty: " + transitiveRootCauses.build().toList());
}
return state;
}
/** Clears the analysis cache as in --discard_analysis_cache. */
void clearAnalysisCache(
ImmutableSet<ConfiguredTarget> topLevelTargets, ImmutableSet<AspectKey> topLevelAspects) {
skyframeBuildView.clearAnalysisCache(topLevelTargets, topLevelAspects);
}
}