Search in sources :

Example 1 with TraversalRequest

use of com.google.devtools.build.lib.skyframe.RecursiveFilesystemTraversalValue.TraversalRequest in project bazel by bazelbuild.

the class RecursiveFilesystemTraversalFunctionTest method assertTraverseSubpackages.

private void assertTraverseSubpackages(PackageBoundaryMode traverseSubpackages) throws Exception {
    Artifact pkgDirArtifact = sourceArtifact("pkg1/foo");
    Artifact subpkgDirArtifact = sourceArtifact("pkg1/foo/subdir/subpkg");
    RootedPath pkgBuildFile = childOf(pkgDirArtifact, "BUILD");
    RootedPath subpkgBuildFile = childOf(subpkgDirArtifact, "BUILD");
    scratch.dir(rootedPath(pkgDirArtifact).asPath().getPathString());
    scratch.dir(rootedPath(subpkgDirArtifact).asPath().getPathString());
    createFile(pkgBuildFile);
    createFile(subpkgBuildFile);
    TraversalRequest traversalRoot = pkgRoot(parentOf(pkgBuildFile), traverseSubpackages);
    ResolvedFile expected1 = regularFileForTesting(pkgBuildFile);
    ResolvedFile expected2 = regularFileForTesting(subpkgBuildFile);
    switch(traverseSubpackages) {
        case CROSS:
            traverseAndAssertFiles(traversalRoot, expected1, expected2);
            break;
        case DONT_CROSS:
            traverseAndAssertFiles(traversalRoot, expected1);
            break;
        case REPORT_ERROR:
            SkyKey key = rftvSkyKey(traversalRoot);
            EvaluationResult<SkyValue> result = eval(key);
            assertThat(result.hasError()).isTrue();
            assertThat(result.getError().getException().getMessage()).contains("crosses package boundary into package rooted at");
            break;
        default:
            throw new IllegalStateException(traverseSubpackages.toString());
    }
}
Also used : SkyKey(com.google.devtools.build.skyframe.SkyKey) SkyValue(com.google.devtools.build.skyframe.SkyValue) TraversalRequest(com.google.devtools.build.lib.skyframe.RecursiveFilesystemTraversalValue.TraversalRequest) ResolvedFile(com.google.devtools.build.lib.skyframe.RecursiveFilesystemTraversalValue.ResolvedFile) Artifact(com.google.devtools.build.lib.actions.Artifact) RootedPath(com.google.devtools.build.lib.vfs.RootedPath)

Example 2 with TraversalRequest

use of com.google.devtools.build.lib.skyframe.RecursiveFilesystemTraversalValue.TraversalRequest in project bazel by bazelbuild.

the class RecursiveFilesystemTraversalFunctionTest method assertTraversalOfDirectory.

private void assertTraversalOfDirectory(Artifact directoryArtifact) throws Exception {
    // Create files under the directory.
    // Use the root + root-relative path of the rootArtifact to create these files, rather than
    // using the rootDirectory + execpath of the rootArtifact. The resulting paths are the same
    // but the RootedPaths are different:
    // in the 1st case, it is: RootedPath(/root/execroot, relative), in the second it is
    // in the 2nd case, it is: RootedPath(/root, execroot/relative).
    // Creating the files will also create the parent directories.
    RootedPath file1 = createFile(childOf(directoryArtifact, "bar.txt"));
    RootedPath file2 = createFile(childOf(directoryArtifact, "baz/qux.txt"));
    TraversalRequest traversalRoot = fileLikeRoot(directoryArtifact, DONT_CROSS);
    // Assert that the SkyValue is built and looks right.
    ResolvedFile expected1 = regularFileForTesting(file1);
    ResolvedFile expected2 = regularFileForTesting(file2);
    RecursiveFilesystemTraversalValue v1 = traverseAndAssertFiles(traversalRoot, expected1, expected2);
    assertThat(progressReceiver.invalidations).isEmpty();
    assertThat(progressReceiver.evaluations).contains(v1);
    progressReceiver.clear();
    // Add a new file to the directory and see that the value is rebuilt.
    RootedPath file3 = createFile(childOf(directoryArtifact, "foo.txt"));
    invalidateDirectory(directoryArtifact);
    ResolvedFile expected3 = regularFileForTesting(file3);
    RecursiveFilesystemTraversalValue v2 = traverseAndAssertFiles(traversalRoot, expected1, expected2, expected3);
    assertThat(progressReceiver.invalidations).contains(rftvSkyKey(traversalRoot));
    assertThat(progressReceiver.evaluations).contains(v2);
    // Directories always have the same hash code, but that is fine because their contents are also
    // part of the RecursiveFilesystemTraversalValue, so v1 and v2 are unequal.
    assertThat(v2).isNotEqualTo(v1);
    assertTraversalRootHashesAreEqual(v1, v2);
    progressReceiver.clear();
    // Edit a file in the directory and see that the value is rebuilt.
    appendToFile(file1, "bar");
    RecursiveFilesystemTraversalValue v3 = traverseAndAssertFiles(traversalRoot, expected1, expected2, expected3);
    assertThat(progressReceiver.invalidations).contains(rftvSkyKey(traversalRoot));
    assertThat(progressReceiver.evaluations).contains(v3);
    assertThat(v3).isNotEqualTo(v2);
    // Directories always have the same hash code, but that is fine because their contents are also
    // part of the RecursiveFilesystemTraversalValue, so v2 and v3 are unequal.
    assertTraversalRootHashesAreEqual(v2, v3);
    progressReceiver.clear();
    // Add a new file *outside* of the directory and see that the value is *not* rebuilt.
    Artifact someFile = sourceArtifact("somewhere/else/a.file");
    createFile(someFile, "new file");
    appendToFile(someFile, "not all changes are treated equal");
    RecursiveFilesystemTraversalValue v4 = traverseAndAssertFiles(traversalRoot, expected1, expected2, expected3);
    assertThat(v4).isEqualTo(v3);
    assertTraversalRootHashesAreEqual(v3, v4);
    assertThat(progressReceiver.invalidations).doesNotContain(rftvSkyKey(traversalRoot));
}
Also used : TraversalRequest(com.google.devtools.build.lib.skyframe.RecursiveFilesystemTraversalValue.TraversalRequest) ResolvedFile(com.google.devtools.build.lib.skyframe.RecursiveFilesystemTraversalValue.ResolvedFile) RootedPath(com.google.devtools.build.lib.vfs.RootedPath) Artifact(com.google.devtools.build.lib.actions.Artifact)

Example 3 with TraversalRequest

use of com.google.devtools.build.lib.skyframe.RecursiveFilesystemTraversalValue.TraversalRequest in project bazel by bazelbuild.

the class RecursiveFilesystemTraversalFunction method compute.

@Override
public SkyValue compute(SkyKey skyKey, Environment env) throws RecursiveFilesystemTraversalFunctionException, InterruptedException {
    TraversalRequest traversal = (TraversalRequest) skyKey.argument();
    try {
        // Stat the traversal root.
        FileInfo rootInfo = lookUpFileInfo(env, traversal);
        if (!rootInfo.type.exists()) {
            // May be a dangling symlink or a non-existent file. Handle gracefully.
            if (rootInfo.type.isSymlink()) {
                return resultForDanglingSymlink(traversal.path, rootInfo);
            } else {
                return RecursiveFilesystemTraversalValue.EMPTY;
            }
        }
        if (rootInfo.type.isFile()) {
            if (traversal.pattern == null || traversal.pattern.matcher(rootInfo.realPath.getRelativePath().getPathString()).matches()) {
                // The root is a file or a symlink to one.
                return resultForFileRoot(traversal.path, rootInfo);
            } else {
                return RecursiveFilesystemTraversalValue.EMPTY;
            }
        }
        // Otherwise the root is a directory or a symlink to one.
        PkgLookupResult pkgLookupResult = checkIfPackage(env, traversal, rootInfo);
        traversal = pkgLookupResult.traversal;
        if (pkgLookupResult.isConflicting()) {
            // with a source package. We can't handle that, bail out.
            throw new RecursiveFilesystemTraversalFunctionException(new GeneratedPathConflictException(traversal));
        } else if (pkgLookupResult.isPackage() && !traversal.skipTestingForSubpackage) {
            // The traversal was requested for a directory that defines a package.
            String msg = traversal.errorInfo + " crosses package boundary into package rooted at " + traversal.path.getRelativePath().getPathString();
            switch(traversal.crossPkgBoundaries) {
                case CROSS:
                    // We are free to traverse the subpackage but we need to display a warning.
                    env.getListener().handle(Event.warn(null, msg));
                    break;
                case DONT_CROSS:
                    // We cannot traverse the subpackage and should skip it silently. Return empty results.
                    return RecursiveFilesystemTraversalValue.EMPTY;
                case REPORT_ERROR:
                    // We cannot traverse the subpackage and should complain loudly (display an error).
                    throw new RecursiveFilesystemTraversalFunctionException(new CannotCrossPackageBoundaryException(msg));
                default:
                    throw new IllegalStateException(traversal.toString());
            }
        }
        // We are free to traverse this directory.
        Collection<SkyKey> dependentKeys = createRecursiveTraversalKeys(env, traversal);
        return resultForDirectory(traversal, rootInfo, traverseChildren(env, dependentKeys));
    } catch (MissingDepException e) {
        return null;
    }
}
Also used : SkyKey(com.google.devtools.build.skyframe.SkyKey) TraversalRequest(com.google.devtools.build.lib.skyframe.RecursiveFilesystemTraversalValue.TraversalRequest)

Example 4 with TraversalRequest

use of com.google.devtools.build.lib.skyframe.RecursiveFilesystemTraversalValue.TraversalRequest in project bazel by bazelbuild.

the class RecursiveFilesystemTraversalFunction method createRecursiveTraversalKeys.

/**
   * List the directory and create {@code SkyKey}s to request contents of its children recursively.
   *
   * <p>The returned keys are of type {@link SkyFunctions#RECURSIVE_FILESYSTEM_TRAVERSAL}.
   */
private static Collection<SkyKey> createRecursiveTraversalKeys(Environment env, TraversalRequest traversal) throws MissingDepException, InterruptedException {
    // Use the traversal's path, even if it's a symlink. The contents of the directory, as listed
    // in the result, must be relative to it.
    DirectoryListingValue dirListing = (DirectoryListingValue) getDependentSkyValue(env, DirectoryListingValue.key(traversal.path));
    List<SkyKey> result = new ArrayList<>();
    for (Dirent dirent : dirListing.getDirents()) {
        RootedPath childPath = RootedPath.toRootedPath(traversal.path.getRoot(), traversal.path.getRelativePath().getRelative(dirent.getName()));
        TraversalRequest childTraversal = traversal.forChildEntry(childPath);
        result.add(RecursiveFilesystemTraversalValue.key(childTraversal));
    }
    return result;
}
Also used : SkyKey(com.google.devtools.build.skyframe.SkyKey) TraversalRequest(com.google.devtools.build.lib.skyframe.RecursiveFilesystemTraversalValue.TraversalRequest) ArrayList(java.util.ArrayList) Dirent(com.google.devtools.build.lib.vfs.Dirent) RootedPath(com.google.devtools.build.lib.vfs.RootedPath)

Example 5 with TraversalRequest

use of com.google.devtools.build.lib.skyframe.RecursiveFilesystemTraversalValue.TraversalRequest in project bazel by bazelbuild.

the class RecursiveFilesystemTraversalFunctionTest method testRegexp.

@Test
public void testRegexp() throws Exception {
    Artifact wantedArtifact = sourceArtifact("foo/bar/baz.txt");
    Artifact unwantedArtifact = sourceArtifact("foo/boo/baztxt.bak");
    RootedPath wantedPath = rootedPath(wantedArtifact);
    createFile(wantedPath, "hello");
    createFile(unwantedArtifact, "nope");
    Artifact pkgDirArtifact = sourceArtifact("foo");
    RootedPath dir = rootedPath(pkgDirArtifact);
    scratch.dir(dir.asPath().getPathString());
    TraversalRequest traversalRoot = new TraversalRequest(dir, false, PackageBoundaryMode.REPORT_ERROR, true, null, Pattern.compile(".*\\.txt"));
    ResolvedFile expected = regularFileForTesting(wantedPath);
    traverseAndAssertFiles(traversalRoot, expected);
}
Also used : TraversalRequest(com.google.devtools.build.lib.skyframe.RecursiveFilesystemTraversalValue.TraversalRequest) ResolvedFile(com.google.devtools.build.lib.skyframe.RecursiveFilesystemTraversalValue.ResolvedFile) Artifact(com.google.devtools.build.lib.actions.Artifact) RootedPath(com.google.devtools.build.lib.vfs.RootedPath) Test(org.junit.Test)

Aggregations

TraversalRequest (com.google.devtools.build.lib.skyframe.RecursiveFilesystemTraversalValue.TraversalRequest)10 RootedPath (com.google.devtools.build.lib.vfs.RootedPath)9 ResolvedFile (com.google.devtools.build.lib.skyframe.RecursiveFilesystemTraversalValue.ResolvedFile)8 Artifact (com.google.devtools.build.lib.actions.Artifact)7 Test (org.junit.Test)5 SkyKey (com.google.devtools.build.skyframe.SkyKey)3 PathFragment (com.google.devtools.build.lib.vfs.PathFragment)2 Dirent (com.google.devtools.build.lib.vfs.Dirent)1 SkyValue (com.google.devtools.build.skyframe.SkyValue)1 ArrayList (java.util.ArrayList)1