// Copyright 2014 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.cmdline.Label; import com.google.devtools.build.lib.cmdline.PackageIdentifier; import com.google.devtools.build.lib.cmdline.ResolvedTargets; import com.google.devtools.build.lib.cmdline.TargetParsingException; import com.google.devtools.build.lib.cmdline.TargetPattern; import com.google.devtools.build.lib.collect.compacthashset.CompactHashSet; import com.google.devtools.build.lib.concurrent.MultisetSemaphore; import com.google.devtools.build.lib.packages.Target; import com.google.devtools.build.lib.pkgcache.AbstractRecursivePackageProvider.MissingDepException; import com.google.devtools.build.lib.pkgcache.ParsingFailedEvent; import com.google.devtools.build.lib.util.BatchCallback; import com.google.devtools.build.lib.vfs.PathFragment; 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.Set; import javax.annotation.Nullable; /** * TargetPatternFunction translates a target pattern (eg, "foo/...") into a set of resolved * Targets. */ public class TargetPatternFunction implements SkyFunction { public TargetPatternFunction() { } @Override public SkyValue compute(SkyKey key, Environment env) throws TargetPatternFunctionException, InterruptedException { TargetPatternValue.TargetPatternKey patternKey = ((TargetPatternValue.TargetPatternKey) key.argument()); ResolvedTargets resolvedTargets; try { EnvironmentBackedRecursivePackageProvider provider = new EnvironmentBackedRecursivePackageProvider(env); RecursivePackageProviderBackedTargetPatternResolver resolver = new RecursivePackageProviderBackedTargetPatternResolver( provider, env.getListener(), patternKey.getPolicy(), MultisetSemaphore.unbounded()); TargetPattern parsedPattern = patternKey.getParsedPattern(); ImmutableSet excludedSubdirectories = patternKey.getExcludedSubdirectories(); final Set results = CompactHashSet.create(); BatchCallback callback = new BatchCallback() { @Override public void process(Iterable partialResult) { Iterables.addAll(results, partialResult); } }; parsedPattern.eval( resolver, /*blacklistedSubdirectories=*/ ImmutableSet.of(), excludedSubdirectories, callback, // The exception type here has to match the one on the BatchCallback. Since the callback // defined above never throws, the exact type here is not really relevant. RuntimeException.class); resolvedTargets = ResolvedTargets.builder().addAll(results).build(); } catch (TargetParsingException e) { env.getListener().post(new ParsingFailedEvent(patternKey.getPattern(), e.getMessage())); throw new TargetPatternFunctionException(e); } catch (MissingDepException e) { // The EnvironmentBackedRecursivePackageProvider constructed above might throw // MissingDepException to signal when it has a dependency on a missing Environment value. // Note that MissingDepException extends RuntimeException because the methods called // on EnvironmentBackedRecursivePackageProvider all belong to an interface shared with other // implementations that are unconcerned with MissingDepExceptions. return null; } Preconditions.checkNotNull(resolvedTargets, key); ResolvedTargets.Builder