Search in sources :

Example 36 with PackageIdentifier

use of com.google.devtools.build.lib.cmdline.PackageIdentifier in project bazel by bazelbuild.

the class SymlinkForest method plantSymlinkForest.

void plantSymlinkForest() throws IOException {
    deleteTreesBelowNotPrefixed(workspace, prefixes);
    // Create a sorted map of all dirs (packages and their ancestors) to sets of their roots.
    // Packages come from exactly one root, but their shared ancestors may come from more.
    // The map is maintained sorted lexicographically, so parents are before their children.
    Map<PackageIdentifier, Set<Path>> dirRootsMap = Maps.newTreeMap();
    for (Map.Entry<PackageIdentifier, Path> entry : packageRoots.entrySet()) {
        PackageIdentifier pkgId = entry.getKey();
        Path pkgRoot = entry.getValue();
        for (int i = 1; i <= pkgId.getPackageFragment().segmentCount(); i++) {
            if (pkgId.equals(Label.EXTERNAL_PACKAGE_IDENTIFIER)) {
                // This isn't a "real" package, don't add it to the symlink tree.
                continue;
            }
            PackageIdentifier dir = createInRepo(pkgId, pkgId.getPackageFragment().subFragment(0, i));
            Set<Path> roots = dirRootsMap.get(dir);
            if (roots == null) {
                roots = Sets.newHashSet();
                dirRootsMap.put(dir, roots);
            }
            roots.add(pkgRoot);
        }
    }
    // Now add in roots for all non-pkg dirs that are in between two packages, and missed above.
    for (Map.Entry<PackageIdentifier, Set<Path>> entry : dirRootsMap.entrySet()) {
        PackageIdentifier dir = entry.getKey();
        if (!packageRoots.containsKey(dir)) {
            PackageIdentifier pkgId = longestPathPrefix(dir, packageRoots.keySet());
            if (pkgId != null) {
                entry.getValue().add(packageRoots.get(pkgId));
            }
        }
    }
    // Create output dirs for all dirs that have more than one root and need to be split.
    for (Map.Entry<PackageIdentifier, Set<Path>> entry : dirRootsMap.entrySet()) {
        PackageIdentifier dir = entry.getKey();
        if (!dir.getRepository().isMain()) {
            FileSystemUtils.createDirectoryAndParents(workspace.getRelative(dir.getRepository().getPathUnderExecRoot()));
        }
        if (entry.getValue().size() > 1) {
            if (LOG_FINER) {
                LOG.finer("mkdir " + workspace.getRelative(dir.getPathUnderExecRoot()));
            }
            FileSystemUtils.createDirectoryAndParents(workspace.getRelative(dir.getPathUnderExecRoot()));
        }
    }
    // Make dir links for single rooted dirs.
    for (Map.Entry<PackageIdentifier, Set<Path>> entry : dirRootsMap.entrySet()) {
        PackageIdentifier dir = entry.getKey();
        Set<Path> roots = entry.getValue();
        // Simple case of one root for this dir.
        if (roots.size() == 1) {
            if (dir.getPackageFragment().segmentCount() > 1 && dirRootsMap.get(getParent(dir)).size() == 1) {
                // skip--an ancestor will link this one in from above
                continue;
            }
            // This is the top-most dir that can be linked to a single root. Make it so.
            // lone root in set
            Path root = roots.iterator().next();
            if (LOG_FINER) {
                LOG.finer("ln -s " + root.getRelative(dir.getSourceRoot()) + " " + workspace.getRelative(dir.getPathUnderExecRoot()));
            }
            workspace.getRelative(dir.getPathUnderExecRoot()).createSymbolicLink(root.getRelative(dir.getSourceRoot()));
        }
    }
    // Make links for dirs within packages, skip parent-only dirs.
    for (Map.Entry<PackageIdentifier, Set<Path>> entry : dirRootsMap.entrySet()) {
        PackageIdentifier dir = entry.getKey();
        if (entry.getValue().size() > 1) {
            // If this dir is at or below a package dir, link in its contents.
            PackageIdentifier pkgId = longestPathPrefix(dir, packageRoots.keySet());
            if (pkgId != null) {
                Path root = packageRoots.get(pkgId);
                try {
                    Path absdir = root.getRelative(dir.getSourceRoot());
                    if (absdir.isDirectory()) {
                        if (LOG_FINER) {
                            LOG.finer("ln -s " + absdir + "/* " + workspace.getRelative(dir.getSourceRoot()) + "/");
                        }
                        for (Path target : absdir.getDirectoryEntries()) {
                            PathFragment p = target.relativeTo(root);
                            if (!dirRootsMap.containsKey(createInRepo(pkgId, p))) {
                                //LOG.finest("ln -s " + target + " " + linkRoot.getRelative(p));
                                workspace.getRelative(p).createSymbolicLink(target);
                            }
                        }
                    } else {
                        LOG.fine("Symlink planting skipping dir '" + absdir + "'");
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            // Otherwise its just an otherwise empty common parent dir.
            }
        }
    }
    for (Map.Entry<PackageIdentifier, Path> entry : packageRoots.entrySet()) {
        PackageIdentifier pkgId = entry.getKey();
        if (!pkgId.getPackageFragment().equals(PathFragment.EMPTY_FRAGMENT)) {
            continue;
        }
        Path execrootDirectory = workspace.getRelative(pkgId.getPathUnderExecRoot());
        // If there were no subpackages, this directory might not exist yet.
        if (!execrootDirectory.exists()) {
            FileSystemUtils.createDirectoryAndParents(execrootDirectory);
        }
        // For the top-level directory, generate symlinks to everything in the directory instead of
        // the directory itself.
        Path sourceDirectory = entry.getValue().getRelative(pkgId.getSourceRoot());
        for (Path target : sourceDirectory.getDirectoryEntries()) {
            String baseName = target.getBaseName();
            Path execPath = execrootDirectory.getRelative(baseName);
            // Create any links that don't exist yet and don't start with bazel-.
            if (!baseName.startsWith(productName + "-") && !execPath.exists()) {
                execPath.createSymbolicLink(target);
            }
        }
    }
    symlinkCorrectWorkspaceName();
}
Also used : Path(com.google.devtools.build.lib.vfs.Path) ImmutableSet(com.google.common.collect.ImmutableSet) Set(java.util.Set) PackageIdentifier(com.google.devtools.build.lib.cmdline.PackageIdentifier) PathFragment(com.google.devtools.build.lib.vfs.PathFragment) IOException(java.io.IOException) ImmutableMap(com.google.common.collect.ImmutableMap) Map(java.util.Map)

Example 37 with PackageIdentifier

use of com.google.devtools.build.lib.cmdline.PackageIdentifier in project bazel by bazelbuild.

the class PreciseAspectResolver method computeBuildFileDependencies.

@Override
public Set<Label> computeBuildFileDependencies(Package pkg, BuildFileDependencyMode mode) throws InterruptedException {
    Set<Label> result = new LinkedHashSet<>();
    result.addAll(mode.getDependencies(pkg));
    Set<PackageIdentifier> dependentPackages = new LinkedHashSet<>();
    // Iterate over all rules...
    for (Target target : pkg.getTargets()) {
        if (!(target instanceof Rule)) {
            continue;
        }
        // ...figure out which direct dependencies can possibly have aspects attached to them...
        Multimap<Attribute, Label> depsWithPossibleAspects = ((Rule) target).getTransitions(new BinaryPredicate<Rule, Attribute>() {

            @Override
            public boolean apply(@Nullable Rule rule, Attribute attribute) {
                for (Aspect aspectWithParameters : attribute.getAspects(rule)) {
                    if (!aspectWithParameters.getDefinition().getAttributes().isEmpty()) {
                        return true;
                    }
                }
                return false;
            }
        });
        // ...and add the package of the aspect.
        for (Label depLabel : depsWithPossibleAspects.values()) {
            dependentPackages.add(depLabel.getPackageIdentifier());
        }
    }
    // Then add all the subinclude labels of the packages thus found to the result.
    for (PackageIdentifier packageIdentifier : dependentPackages) {
        try {
            result.add(Label.create(packageIdentifier, "BUILD"));
            Package dependentPackage = packageProvider.getPackage(eventHandler, packageIdentifier);
            result.addAll(mode.getDependencies(dependentPackage));
        } catch (NoSuchPackageException e) {
        // If the package is not found, just add its BUILD file, which is already done above.
        // Hopefully this error is not raised when there is a syntax error in a subincluded file
        // or something.
        } catch (LabelSyntaxException e) {
            throw new IllegalStateException(e);
        }
    }
    return result;
}
Also used : LinkedHashSet(java.util.LinkedHashSet) LabelSyntaxException(com.google.devtools.build.lib.cmdline.LabelSyntaxException) Attribute(com.google.devtools.build.lib.packages.Attribute) Label(com.google.devtools.build.lib.cmdline.Label) Aspect(com.google.devtools.build.lib.packages.Aspect) Target(com.google.devtools.build.lib.packages.Target) PackageIdentifier(com.google.devtools.build.lib.cmdline.PackageIdentifier) NoSuchPackageException(com.google.devtools.build.lib.packages.NoSuchPackageException) Rule(com.google.devtools.build.lib.packages.Rule) Package(com.google.devtools.build.lib.packages.Package)

Example 38 with PackageIdentifier

use of com.google.devtools.build.lib.cmdline.PackageIdentifier in project bazel by bazelbuild.

the class GenQuery method constructPackageMap.

/**
   * Precomputes the transitive closure of the scope. Returns two maps: one identifying the
   * successful packages, and the other identifying the valid targets. Breaks in the transitive
   * closure of the scope will cause the query to error out early.
   */
@Nullable
private static Pair<ImmutableMap<PackageIdentifier, Package>, ImmutableMap<Label, Target>> constructPackageMap(SkyFunction.Environment env, Collection<Target> scope) throws InterruptedException, BrokenQueryScopeException {
    // It is not necessary for correctness to construct intermediate NestedSets; we could iterate
    // over individual targets in scope immediately. However, creating a composite NestedSet first
    // saves us from iterating over the same sub-NestedSets multiple times.
    NestedSetBuilder<Label> validTargets = NestedSetBuilder.stableOrder();
    NestedSetBuilder<PackageIdentifier> successfulPackageNames = NestedSetBuilder.stableOrder();
    for (Target target : scope) {
        SkyKey key = TransitiveTargetValue.key(target.getLabel());
        TransitiveTargetValue transNode = (TransitiveTargetValue) env.getValue(key);
        if (transNode == null) {
            return null;
        }
        if (!transNode.getTransitiveUnsuccessfulPackages().isEmpty()) {
            // path, as otherwise this configured target would have failed earlier. See b/34132681.
            throw new BrokenQueryScopeException("errors were encountered while computing transitive closure of the scope.");
        }
        validTargets.addTransitive(transNode.getTransitiveTargets());
        successfulPackageNames.addTransitive(transNode.getTransitiveSuccessfulPackages());
    }
    // Construct the package id to package map for all successful packages.
    ImmutableMap.Builder<PackageIdentifier, Package> packageMapBuilder = ImmutableMap.builder();
    for (PackageIdentifier pkgId : successfulPackageNames.build()) {
        PackageValue pkg = (PackageValue) env.getValue(PackageValue.key(pkgId));
        Preconditions.checkNotNull(pkg, "package %s not preloaded", pkgId);
        Preconditions.checkState(!pkg.getPackage().containsErrors(), "package %s was found to both have and not have errors.", pkgId);
        packageMapBuilder.put(pkg.getPackage().getPackageIdentifier(), pkg.getPackage());
    }
    ImmutableMap<PackageIdentifier, Package> packageMap = packageMapBuilder.build();
    ImmutableMap.Builder<Label, Target> validTargetsMapBuilder = ImmutableMap.builder();
    for (Label label : validTargets.build()) {
        try {
            Target target = packageMap.get(label.getPackageIdentifier()).getTarget(label.getName());
            validTargetsMapBuilder.put(label, target);
        } catch (NoSuchTargetException e) {
            throw new IllegalStateException(e);
        }
    }
    return Pair.of(packageMap, validTargetsMapBuilder.build());
}
Also used : SkyKey(com.google.devtools.build.skyframe.SkyKey) Label(com.google.devtools.build.lib.cmdline.Label) PackageValue(com.google.devtools.build.lib.skyframe.PackageValue) ImmutableMap(com.google.common.collect.ImmutableMap) ConfiguredTarget(com.google.devtools.build.lib.analysis.ConfiguredTarget) Target(com.google.devtools.build.lib.packages.Target) PackageIdentifier(com.google.devtools.build.lib.cmdline.PackageIdentifier) NoSuchTargetException(com.google.devtools.build.lib.packages.NoSuchTargetException) Package(com.google.devtools.build.lib.packages.Package) TransitiveTargetValue(com.google.devtools.build.lib.skyframe.TransitiveTargetValue) Nullable(javax.annotation.Nullable)

Example 39 with PackageIdentifier

use of com.google.devtools.build.lib.cmdline.PackageIdentifier in project bazel by bazelbuild.

the class GenQuery method executeQuery.

@Nullable
private byte[] executeQuery(RuleContext ruleContext, QueryOptions queryOptions, Set<Target> scope, String query) throws InterruptedException {
    SkyFunction.Environment env = ruleContext.getAnalysisEnvironment().getSkyframeEnv();
    Pair<ImmutableMap<PackageIdentifier, Package>, ImmutableMap<Label, Target>> closureInfo;
    try {
        closureInfo = constructPackageMap(env, scope);
        if (closureInfo == null) {
            return null;
        }
    } catch (BrokenQueryScopeException e) {
        ruleContext.ruleError(e.getMessage());
        return null;
    }
    ImmutableMap<PackageIdentifier, Package> packageMap = closureInfo.first;
    ImmutableMap<Label, Target> validTargetsMap = closureInfo.second;
    PackageProvider packageProvider = new PreloadedMapPackageProvider(packageMap, validTargetsMap);
    TargetPatternEvaluator evaluator = new SkyframeEnvTargetPatternEvaluator(env);
    Predicate<Label> labelFilter = Predicates.in(validTargetsMap.keySet());
    return doQuery(queryOptions, packageProvider, labelFilter, evaluator, query, ruleContext);
}
Also used : TargetPatternEvaluator(com.google.devtools.build.lib.pkgcache.TargetPatternEvaluator) SkyFunction(com.google.devtools.build.skyframe.SkyFunction) Label(com.google.devtools.build.lib.cmdline.Label) ImmutableMap(com.google.common.collect.ImmutableMap) PackageProvider(com.google.devtools.build.lib.pkgcache.PackageProvider) ConfiguredTarget(com.google.devtools.build.lib.analysis.ConfiguredTarget) Target(com.google.devtools.build.lib.packages.Target) PackageIdentifier(com.google.devtools.build.lib.cmdline.PackageIdentifier) Package(com.google.devtools.build.lib.packages.Package) Nullable(javax.annotation.Nullable)

Example 40 with PackageIdentifier

use of com.google.devtools.build.lib.cmdline.PackageIdentifier in project bazel by bazelbuild.

the class ProcessPackageDirectory method getPackageExistenceAndSubdirDeps.

/**
   * Examines {@code rootedPath} to see if it is the location of a package, and to see if it has any
   * subdirectory children that should also be examined. Returns a {@link
   * ProcessPackageDirectoryResult}, or {@code null} if required dependencies were missing.
   */
@Nullable
ProcessPackageDirectoryResult getPackageExistenceAndSubdirDeps(RootedPath rootedPath, RepositoryName repositoryName, SkyFunction.Environment env, Set<PathFragment> excludedPaths) throws InterruptedException {
    PathFragment rootRelativePath = rootedPath.getRelativePath();
    SkyKey fileKey = FileValue.key(rootedPath);
    FileValue fileValue;
    try {
        fileValue = (FileValue) env.getValueOrThrow(fileKey, InconsistentFilesystemException.class, FileSymlinkException.class, IOException.class);
    } catch (InconsistentFilesystemException | FileSymlinkException | IOException e) {
        return reportErrorAndReturn("Failed to get information about path", e, rootRelativePath, env.getListener());
    }
    if (env.valuesMissing()) {
        return null;
    }
    if (!fileValue.isDirectory()) {
        return ProcessPackageDirectoryResult.EMPTY_RESULT;
    }
    PackageIdentifier packageId = PackageIdentifier.create(repositoryName, rootRelativePath);
    if ((packageId.getRepository().isDefault() || packageId.getRepository().isMain()) && fileValue.isSymlink() && fileValue.getUnresolvedLinkTarget().startsWith(directories.getOutputBase().asFragment())) {
        // somewhere in the directory tree manually.
        return ProcessPackageDirectoryResult.EMPTY_RESULT;
    }
    SkyKey pkgLookupKey = PackageLookupValue.key(packageId);
    SkyKey dirListingKey = DirectoryListingValue.key(rootedPath);
    Map<SkyKey, ValueOrException4<NoSuchPackageException, InconsistentFilesystemException, FileSymlinkException, IOException>> pkgLookupAndDirectoryListingDeps = env.getValuesOrThrow(ImmutableList.of(pkgLookupKey, dirListingKey), NoSuchPackageException.class, InconsistentFilesystemException.class, FileSymlinkException.class, IOException.class);
    if (env.valuesMissing()) {
        return null;
    }
    PackageLookupValue pkgLookupValue;
    try {
        pkgLookupValue = (PackageLookupValue) Preconditions.checkNotNull(pkgLookupAndDirectoryListingDeps.get(pkgLookupKey).get(), "%s %s %s", rootedPath, repositoryName, pkgLookupKey);
    } catch (NoSuchPackageException | InconsistentFilesystemException e) {
        return reportErrorAndReturn("Failed to load package", e, rootRelativePath, env.getListener());
    } catch (IOException | FileSymlinkException e) {
        throw new IllegalStateException(e);
    }
    DirectoryListingValue dirListingValue;
    try {
        dirListingValue = (DirectoryListingValue) Preconditions.checkNotNull(pkgLookupAndDirectoryListingDeps.get(dirListingKey).get(), "%s %s %s", rootedPath, repositoryName, dirListingKey);
    } catch (InconsistentFilesystemException | IOException e) {
        return reportErrorAndReturn("Failed to list directory contents", e, rootRelativePath, env.getListener());
    } catch (FileSymlinkException e) {
        // be able to avoid throwing there but throw here.
        throw new IllegalStateException("Symlink cycle found after not being found for \"" + rootedPath + "\"");
    } catch (NoSuchPackageException e) {
        throw new IllegalStateException(e);
    }
    return new ProcessPackageDirectoryResult(pkgLookupValue.packageExists() && pkgLookupValue.getRoot().equals(rootedPath.getRoot()), getSubdirDeps(dirListingValue, rootedPath, repositoryName, excludedPaths));
}
Also used : SkyKey(com.google.devtools.build.skyframe.SkyKey) ValueOrException4(com.google.devtools.build.skyframe.ValueOrException4) PathFragment(com.google.devtools.build.lib.vfs.PathFragment) IOException(java.io.IOException) PackageIdentifier(com.google.devtools.build.lib.cmdline.PackageIdentifier) NoSuchPackageException(com.google.devtools.build.lib.packages.NoSuchPackageException) Nullable(javax.annotation.Nullable)

Aggregations

PackageIdentifier (com.google.devtools.build.lib.cmdline.PackageIdentifier)49 SkyKey (com.google.devtools.build.skyframe.SkyKey)17 PathFragment (com.google.devtools.build.lib.vfs.PathFragment)16 Package (com.google.devtools.build.lib.packages.Package)14 Label (com.google.devtools.build.lib.cmdline.Label)12 Path (com.google.devtools.build.lib.vfs.Path)11 HashMap (java.util.HashMap)11 Test (org.junit.Test)11 ImmutableMap (com.google.common.collect.ImmutableMap)10 NoSuchPackageException (com.google.devtools.build.lib.packages.NoSuchPackageException)8 BuildFileNotFoundException (com.google.devtools.build.lib.packages.BuildFileNotFoundException)7 Target (com.google.devtools.build.lib.packages.Target)7 Nullable (javax.annotation.Nullable)7 NoSuchTargetException (com.google.devtools.build.lib.packages.NoSuchTargetException)6 LabelSyntaxException (com.google.devtools.build.lib.cmdline.LabelSyntaxException)5 Map (java.util.Map)5 RootedPath (com.google.devtools.build.lib.vfs.RootedPath)4 BlazeDirectories (com.google.devtools.build.lib.analysis.BlazeDirectories)3 ConfiguredTarget (com.google.devtools.build.lib.analysis.ConfiguredTarget)3 ResolvedTargets (com.google.devtools.build.lib.cmdline.ResolvedTargets)3