Search in sources :

Example 51 with RootedPath

use of com.google.devtools.build.lib.vfs.RootedPath in project bazel by bazelbuild.

the class PackageFunction method compute.

@Override
public SkyValue compute(SkyKey key, Environment env) throws PackageFunctionException, InterruptedException {
    PackageIdentifier packageId = (PackageIdentifier) key.argument();
    SkyKey packageLookupKey = PackageLookupValue.key(packageId);
    PackageLookupValue packageLookupValue;
    try {
        packageLookupValue = (PackageLookupValue) env.getValueOrThrow(packageLookupKey, BuildFileNotFoundException.class, InconsistentFilesystemException.class);
    } catch (BuildFileNotFoundException e) {
        throw new PackageFunctionException(e, Transience.PERSISTENT);
    } catch (InconsistentFilesystemException e) {
        // This error is not transient from the perspective of the PackageFunction.
        throw new PackageFunctionException(new NoSuchPackageException(packageId, e.getMessage(), e), Transience.PERSISTENT);
    }
    if (packageLookupValue == null) {
        return null;
    }
    if (!packageLookupValue.packageExists()) {
        switch(packageLookupValue.getErrorReason()) {
            case NO_BUILD_FILE:
            case DELETED_PACKAGE:
                throw new PackageFunctionException(new BuildFileNotFoundException(packageId, packageLookupValue.getErrorMsg()), Transience.PERSISTENT);
            case INVALID_PACKAGE_NAME:
                throw new PackageFunctionException(new InvalidPackageNameException(packageId, packageLookupValue.getErrorMsg()), Transience.PERSISTENT);
            default:
                // We should never get here.
                throw new IllegalStateException();
        }
    }
    if (packageId.equals(Label.EXTERNAL_PACKAGE_IDENTIFIER)) {
        return getExternalPackage(env, packageLookupValue.getRoot());
    }
    WorkspaceNameValue workspaceNameValue = (WorkspaceNameValue) env.getValue(WorkspaceNameValue.key());
    if (workspaceNameValue == null) {
        return null;
    }
    String workspaceName = workspaceNameValue.maybeGetName();
    if (workspaceName == null) {
        throw new PackageFunctionException(new BuildFileContainsErrorsException(Label.EXTERNAL_PACKAGE_IDENTIFIER), Transience.PERSISTENT);
    }
    RootedPath buildFileRootedPath = packageLookupValue.getRootedPath(packageId);
    FileValue buildFileValue = null;
    Path buildFilePath = buildFileRootedPath.asPath();
    String replacementContents = null;
    if (!isDefaultsPackage(packageId)) {
        buildFileValue = getBuildFileValue(env, buildFileRootedPath);
        if (buildFileValue == null) {
            return null;
        }
    } else {
        replacementContents = PrecomputedValue.DEFAULTS_PACKAGE_CONTENTS.get(env);
        if (replacementContents == null) {
            return null;
        }
    }
    RuleVisibility defaultVisibility = PrecomputedValue.DEFAULT_VISIBILITY.get(env);
    if (defaultVisibility == null) {
        return null;
    }
    SkyKey astLookupKey = ASTFileLookupValue.key(preludeLabel);
    ASTFileLookupValue astLookupValue = null;
    try {
        astLookupValue = (ASTFileLookupValue) env.getValueOrThrow(astLookupKey, ErrorReadingSkylarkExtensionException.class, InconsistentFilesystemException.class);
    } catch (ErrorReadingSkylarkExtensionException | InconsistentFilesystemException e) {
        throw new PackageFunctionException(new NoSuchPackageException(packageId, "Error encountered while reading the prelude file: " + e.getMessage()), Transience.PERSISTENT);
    }
    if (astLookupValue == null) {
        return null;
    }
    // The prelude file doesn't have to exist. If not, we substitute an empty statement list.
    List<Statement> preludeStatements = astLookupValue.lookupSuccessful() ? astLookupValue.getAST().getStatements() : ImmutableList.<Statement>of();
    CacheEntryWithGlobDeps<Package.Builder> packageBuilderAndGlobDeps = loadPackage(workspaceName, replacementContents, packageId, buildFilePath, buildFileValue, defaultVisibility, preludeStatements, packageLookupValue.getRoot(), env);
    if (packageBuilderAndGlobDeps == null) {
        return null;
    }
    Package.Builder pkgBuilder = packageBuilderAndGlobDeps.value;
    pkgBuilder.buildPartial();
    try {
        // Since the Skyframe dependencies we request below in
        // markDependenciesAndPropagateFilesystemExceptions are requested independently of
        // the ones requested here in
        // handleLabelsCrossingSubpackagesAndPropagateInconsistentFilesystemExceptions, we don't
        // bother checking for missing values and instead piggyback on the env.missingValues() call
        // for the former. This avoids a Skyframe restart.
        handleLabelsCrossingSubpackagesAndPropagateInconsistentFilesystemExceptions(packageLookupValue.getRoot(), packageId, pkgBuilder, env);
    } catch (InternalInconsistentFilesystemException e) {
        packageFunctionCache.invalidate(packageId);
        throw new PackageFunctionException(e.toNoSuchPackageException(), e.isTransient() ? Transience.TRANSIENT : Transience.PERSISTENT);
    }
    Set<SkyKey> globKeys = packageBuilderAndGlobDeps.globDepKeys;
    Map<Label, Path> subincludes = pkgBuilder.getSubincludes();
    boolean packageShouldBeConsideredInError;
    try {
        packageShouldBeConsideredInError = markDependenciesAndPropagateFilesystemExceptions(env, globKeys, subincludes, packageId, pkgBuilder.containsErrors());
    } catch (InternalInconsistentFilesystemException e) {
        packageFunctionCache.invalidate(packageId);
        throw new PackageFunctionException(e.toNoSuchPackageException(), e.isTransient() ? Transience.TRANSIENT : Transience.PERSISTENT);
    }
    if (env.valuesMissing()) {
        return null;
    }
    Event.replayEventsOn(env.getListener(), pkgBuilder.getEvents());
    if (packageShouldBeConsideredInError) {
        pkgBuilder.setContainsErrors();
    }
    Package pkg = pkgBuilder.finishBuild();
    // We know this SkyFunction will not be called again, so we can remove the cache entry.
    packageFunctionCache.invalidate(packageId);
    packageFactory.afterDoneLoadingPackage(pkg);
    return new PackageValue(pkg);
}
Also used : BuildFileNotFoundException(com.google.devtools.build.lib.packages.BuildFileNotFoundException) InvalidPackageNameException(com.google.devtools.build.lib.packages.InvalidPackageNameException) Label(com.google.devtools.build.lib.cmdline.Label) RootedPath(com.google.devtools.build.lib.vfs.RootedPath) SkyKey(com.google.devtools.build.skyframe.SkyKey) RootedPath(com.google.devtools.build.lib.vfs.RootedPath) Path(com.google.devtools.build.lib.vfs.Path) BuildFileContainsErrorsException(com.google.devtools.build.lib.packages.BuildFileContainsErrorsException) Statement(com.google.devtools.build.lib.syntax.Statement) RuleVisibility(com.google.devtools.build.lib.packages.RuleVisibility) PackageIdentifier(com.google.devtools.build.lib.cmdline.PackageIdentifier) NoSuchPackageException(com.google.devtools.build.lib.packages.NoSuchPackageException) Package(com.google.devtools.build.lib.packages.Package)

Example 52 with RootedPath

use of com.google.devtools.build.lib.vfs.RootedPath in project bazel by bazelbuild.

the class PackageLookupFunction method computeExternalPackageLookupValue.

/**
   * Gets a PackageLookupValue from a different Bazel repository.
   *
   * <p>To do this, it looks up the "external" package and finds a path mapping for the repository
   * name.
   */
private PackageLookupValue computeExternalPackageLookupValue(SkyKey skyKey, Environment env, PackageIdentifier packageIdentifier) throws PackageLookupFunctionException, InterruptedException {
    PackageIdentifier id = (PackageIdentifier) skyKey.argument();
    SkyKey repositoryKey = RepositoryValue.key(id.getRepository());
    RepositoryValue repositoryValue;
    try {
        repositoryValue = (RepositoryValue) env.getValueOrThrow(repositoryKey, NoSuchPackageException.class, IOException.class, EvalException.class);
        if (repositoryValue == null) {
            return null;
        }
    } catch (NoSuchPackageException | IOException | EvalException e) {
        throw new PackageLookupFunctionException(new BuildFileNotFoundException(id, e.getMessage()), Transience.PERSISTENT);
    }
    // This checks for the build file names in the correct precedence order.
    for (BuildFileName buildFileName : buildFilesByPriority) {
        PathFragment buildFileFragment = id.getPackageFragment().getChild(buildFileName.getFilename());
        RootedPath buildFileRootedPath = RootedPath.toRootedPath(repositoryValue.getPath(), buildFileFragment);
        FileValue fileValue = getFileValue(buildFileRootedPath, env, packageIdentifier);
        if (fileValue == null) {
            return null;
        }
        if (fileValue.isFile()) {
            return PackageLookupValue.success(repositoryValue.getPath(), buildFileName);
        }
    }
    return PackageLookupValue.NO_BUILD_FILE_VALUE;
}
Also used : SkyKey(com.google.devtools.build.skyframe.SkyKey) BuildFileNotFoundException(com.google.devtools.build.lib.packages.BuildFileNotFoundException) PathFragment(com.google.devtools.build.lib.vfs.PathFragment) BuildFileName(com.google.devtools.build.lib.skyframe.PackageLookupValue.BuildFileName) IOException(java.io.IOException) EvalException(com.google.devtools.build.lib.syntax.EvalException) RootedPath(com.google.devtools.build.lib.vfs.RootedPath) PackageIdentifier(com.google.devtools.build.lib.cmdline.PackageIdentifier) NoSuchPackageException(com.google.devtools.build.lib.packages.NoSuchPackageException)

Example 53 with RootedPath

use of com.google.devtools.build.lib.vfs.RootedPath in project bazel by bazelbuild.

the class PackageLookupFunction method getPackageLookupValue.

private PackageLookupValue getPackageLookupValue(Environment env, Path packagePathEntry, PackageIdentifier packageIdentifier, BuildFileName buildFileName) throws InterruptedException, PackageLookupFunctionException {
    PathFragment buildFileFragment = buildFileName.getBuildFileFragment(packageIdentifier);
    RootedPath buildFileRootedPath = RootedPath.toRootedPath(packagePathEntry, buildFileFragment);
    if (crossRepositoryLabelViolationStrategy == CrossRepositoryLabelViolationStrategy.ERROR) {
        // Is this path part of a local repository?
        RootedPath currentPath = RootedPath.toRootedPath(packagePathEntry, buildFileFragment.getParentDirectory());
        SkyKey repositoryLookupKey = LocalRepositoryLookupValue.key(currentPath);
        // TODO(jcater): Consider parallelizing these lookups.
        LocalRepositoryLookupValue localRepository;
        try {
            localRepository = (LocalRepositoryLookupValue) env.getValueOrThrow(repositoryLookupKey, ErrorDeterminingRepositoryException.class);
            if (localRepository == null) {
                return null;
            }
        } catch (ErrorDeterminingRepositoryException e) {
            // TODO(katre): Improve the error message given here.
            throw new PackageLookupFunctionException(new BuildFileNotFoundException(packageIdentifier, "Unable to determine the local repository for directory " + currentPath.asPath().getPathString()), Transience.PERSISTENT);
        }
        if (localRepository.exists() && !localRepository.getRepository().equals(packageIdentifier.getRepository())) {
            // TODO(jcater): Work out the correct package name for this error message.
            return PackageLookupValue.invalidPackageName("Package crosses into repository " + localRepository.getRepository().getName());
        }
    // There's no local repository, keep going.
    } else {
        // Future-proof against adding future values to CrossRepositoryLabelViolationStrategy.
        Preconditions.checkState(crossRepositoryLabelViolationStrategy == CrossRepositoryLabelViolationStrategy.IGNORE, crossRepositoryLabelViolationStrategy);
    }
    // Check for the existence of the build file.
    FileValue fileValue = getFileValue(buildFileRootedPath, env, packageIdentifier);
    if (fileValue == null) {
        return null;
    }
    if (fileValue.isFile()) {
        return PackageLookupValue.success(buildFileRootedPath.getRoot(), buildFileName);
    }
    return PackageLookupValue.NO_BUILD_FILE_VALUE;
}
Also used : SkyKey(com.google.devtools.build.skyframe.SkyKey) BuildFileNotFoundException(com.google.devtools.build.lib.packages.BuildFileNotFoundException) ErrorDeterminingRepositoryException(com.google.devtools.build.lib.packages.ErrorDeterminingRepositoryException) PathFragment(com.google.devtools.build.lib.vfs.PathFragment) RootedPath(com.google.devtools.build.lib.vfs.RootedPath)

Example 54 with RootedPath

use of com.google.devtools.build.lib.vfs.RootedPath in project bazel by bazelbuild.

the class ActionMetadataHandler method fileValueFromArtifact.

@VisibleForTesting
static FileValue fileValueFromArtifact(Artifact artifact, @Nullable FileStatusWithDigest statNoFollow, @Nullable TimestampGranularityMonitor tsgm) throws IOException {
    Path path = artifact.getPath();
    RootedPath rootedPath = RootedPath.toRootedPath(artifact.getRoot().getPath(), artifact.getRootRelativePath());
    if (statNoFollow == null) {
        statNoFollow = FileStatusWithDigestAdapter.adapt(path.statIfFound(Symlinks.NOFOLLOW));
        if (statNoFollow == null) {
            return FileValue.value(rootedPath, FileStateValue.NONEXISTENT_FILE_STATE_NODE, rootedPath, FileStateValue.NONEXISTENT_FILE_STATE_NODE);
        }
    }
    Path realPath = path;
    // done by the latter.
    if (statNoFollow.isSymbolicLink()) {
        realPath = path.resolveSymbolicLinks();
        // file that's not in a symlink cycle.
        if (realPath.equals(path)) {
            throw new IOException("symlink cycle");
        }
    }
    RootedPath realRootedPath = RootedPath.toRootedPathMaybeUnderRoot(realPath, ImmutableList.of(artifact.getRoot().getPath()));
    FileStateValue fileStateValue;
    FileStateValue realFileStateValue;
    try {
        fileStateValue = FileStateValue.createWithStatNoFollow(rootedPath, statNoFollow, tsgm);
        // TODO(bazel-team): consider avoiding a 'stat' here when the symlink target hasn't changed
        // and is a source file (since changes to those are checked separately).
        realFileStateValue = realPath.equals(path) ? fileStateValue : FileStateValue.create(realRootedPath, tsgm);
    } catch (InconsistentFilesystemException e) {
        throw new IOException(e);
    }
    return FileValue.value(rootedPath, fileStateValue, realRootedPath, realFileStateValue);
}
Also used : RootedPath(com.google.devtools.build.lib.vfs.RootedPath) Path(com.google.devtools.build.lib.vfs.Path) IOException(java.io.IOException) RootedPath(com.google.devtools.build.lib.vfs.RootedPath) VisibleForTesting(com.google.common.annotations.VisibleForTesting)

Example 55 with RootedPath

use of com.google.devtools.build.lib.vfs.RootedPath in project bazel by bazelbuild.

the class ProcessPackageDirectory method getSubdirDeps.

private Iterable<SkyKey> getSubdirDeps(DirectoryListingValue dirListingValue, RootedPath rootedPath, RepositoryName repositoryName, Set<PathFragment> excludedPaths) {
    Path root = rootedPath.getRoot();
    PathFragment rootRelativePath = rootedPath.getRelativePath();
    boolean followSymlinks = shouldFollowSymlinksWhenTraversing(dirListingValue.getDirents());
    List<SkyKey> childDeps = new ArrayList<>();
    for (Dirent dirent : dirListingValue.getDirents()) {
        Type type = dirent.getType();
        if (type != Type.DIRECTORY && (type != Type.SYMLINK || !followSymlinks)) {
            // rise to infinite directory trees are diagnosed by FileValue.
            continue;
        }
        String basename = dirent.getName();
        if (rootRelativePath.equals(PathFragment.EMPTY_FRAGMENT) && PathPackageLocator.DEFAULT_TOP_LEVEL_EXCLUDES.contains(basename)) {
            continue;
        }
        PathFragment subdirectory = rootRelativePath.getRelative(basename);
        // If this subdirectory is one of the excluded paths, don't recurse into it.
        if (excludedPaths.contains(subdirectory)) {
            continue;
        }
        // If we have an excluded path that isn't below this subdirectory, we shouldn't pass that
        // excluded path to our evaluation of the subdirectory, because the exclusion can't
        // possibly match anything beneath the subdirectory.
        //
        // For example, if we're currently evaluating directory "a", are looking at its subdirectory
        // "a/b", and we have an excluded path "a/c/d", there's no need to pass the excluded path
        // "a/c/d" to our evaluation of "a/b".
        //
        // This strategy should help to get more skyframe sharing. Consider the example above. A
        // subsequent request of "a/b/...", without any excluded paths, will be a cache hit.
        //
        // TODO(bazel-team): Replace the excludedPaths set with a trie or a SortedSet for better
        // efficiency.
        ImmutableSet<PathFragment> excludedSubdirectoriesBeneathThisSubdirectory = PathFragment.filterPathsStartingWith(excludedPaths, subdirectory);
        RootedPath subdirectoryRootedPath = RootedPath.toRootedPath(root, subdirectory);
        childDeps.add(skyKeyTransformer.makeSkyKey(repositoryName, subdirectoryRootedPath, excludedSubdirectoriesBeneathThisSubdirectory));
    }
    return childDeps;
}
Also used : RootedPath(com.google.devtools.build.lib.vfs.RootedPath) Path(com.google.devtools.build.lib.vfs.Path) SkyKey(com.google.devtools.build.skyframe.SkyKey) Type(com.google.devtools.build.lib.vfs.Dirent.Type) PathFragment(com.google.devtools.build.lib.vfs.PathFragment) ArrayList(java.util.ArrayList) Dirent(com.google.devtools.build.lib.vfs.Dirent) RootedPath(com.google.devtools.build.lib.vfs.RootedPath)

Aggregations

RootedPath (com.google.devtools.build.lib.vfs.RootedPath)84 PathFragment (com.google.devtools.build.lib.vfs.PathFragment)43 SkyKey (com.google.devtools.build.skyframe.SkyKey)41 Test (org.junit.Test)33 Path (com.google.devtools.build.lib.vfs.Path)28 Artifact (com.google.devtools.build.lib.actions.Artifact)21 IOException (java.io.IOException)15 Package (com.google.devtools.build.lib.packages.Package)13 SkyValue (com.google.devtools.build.skyframe.SkyValue)11 TraversalRequest (com.google.devtools.build.lib.skyframe.RecursiveFilesystemTraversalValue.TraversalRequest)9 ResolvedFile (com.google.devtools.build.lib.skyframe.RecursiveFilesystemTraversalValue.ResolvedFile)8 FilesetTraversalParams (com.google.devtools.build.lib.actions.FilesetTraversalParams)7 EvalException (com.google.devtools.build.lib.syntax.EvalException)7 ErrorInfo (com.google.devtools.build.skyframe.ErrorInfo)7 Dirent (com.google.devtools.build.lib.vfs.Dirent)6 LabelSyntaxException (com.google.devtools.build.lib.cmdline.LabelSyntaxException)5 BuildFileNotFoundException (com.google.devtools.build.lib.packages.BuildFileNotFoundException)5 NoSuchPackageException (com.google.devtools.build.lib.packages.NoSuchPackageException)5 FileValue (com.google.devtools.build.lib.skyframe.FileValue)5 Map (java.util.Map)5