use of com.google.devtools.build.lib.vfs.RootedPath in project bazel by bazelbuild.
the class RecursiveFilesystemTraversalFunctionTest method testTraversalOfDanglingSymlinkInADirectory.
@Test
public void testTraversalOfDanglingSymlinkInADirectory() throws Exception {
Artifact dirArtifact = sourceArtifact("a");
RootedPath file = createFile(childOf(dirArtifact, "file.txt"));
RootedPath link = rootedPath(sourceArtifact("a/dangling.sym"));
PathFragment linkTarget = new PathFragment("non_existent");
parentOf(link).asPath().createDirectory();
link.asPath().createSymbolicLink(linkTarget);
traverseAndAssertFiles(fileLikeRoot(dirArtifact, DONT_CROSS), regularFileForTesting(file), danglingSymlinkForTesting(link, linkTarget));
}
use of com.google.devtools.build.lib.vfs.RootedPath in project bazel by bazelbuild.
the class PrepareDepsOfTargetsUnderDirectoryFunctionTest method testSubdirectoryExclusion.
@Test
public void testSubdirectoryExclusion() throws Exception {
// Given a package "a" with two packages below it, "a/b" and "a/c",
scratch.file("a/BUILD");
scratch.file("a/b/BUILD");
scratch.file("a/c/BUILD");
// When the top package is evaluated via PrepareDepsOfTargetsUnderDirectoryValue with "a/b"
// excluded,
PathFragment excludedPathFragment = new PathFragment("a/b");
SkyKey key = createPrepDepsKey(rootDirectory, new PathFragment("a"), ImmutableSet.of(excludedPathFragment));
SkyKey collectkey = createCollectPackagesKey(rootDirectory, new PathFragment("a"), ImmutableSet.of(excludedPathFragment));
EvaluationResult<?> evaluationResult = getEvaluationResult(key, collectkey);
CollectPackagesUnderDirectoryValue value = (CollectPackagesUnderDirectoryValue) evaluationResult.getWalkableGraph().getValue(createCollectPackagesKey(rootDirectory, new PathFragment("a"), ImmutableSet.of(excludedPathFragment)));
// Then the value reports that "a" is a package,
assertThat(value.isDirectoryPackage()).isTrue();
// And only the subdirectory corresponding to "a/c" is present in the result,
RootedPath onlySubdir = Iterables.getOnlyElement(value.getSubdirectoryTransitivelyContainsPackagesOrErrors().keySet());
assertThat(onlySubdir.getRelativePath()).isEqualTo(new PathFragment("a/c"));
// And the "a/c" subdirectory reports a package under it.
assertThat(value.getSubdirectoryTransitivelyContainsPackagesOrErrors().get(onlySubdir)).isTrue();
// Also, the computation graph does not contain a cached value for "a/b".
WalkableGraph graph = Preconditions.checkNotNull(evaluationResult.getWalkableGraph());
assertFalse(exists(createPrepDepsKey(rootDirectory, excludedPathFragment, ImmutableSet.<PathFragment>of()), graph));
// And the computation graph does contain a cached value for "a/c" with the empty set excluded,
// because that key was evaluated.
assertTrue(exists(createPrepDepsKey(rootDirectory, new PathFragment("a/c"), ImmutableSet.<PathFragment>of()), graph));
}
use of com.google.devtools.build.lib.vfs.RootedPath 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));
}
use of com.google.devtools.build.lib.vfs.RootedPath in project bazel by bazelbuild.
the class ASTFileLookupFunction method compute.
@Override
public SkyValue compute(SkyKey skyKey, Environment env) throws SkyFunctionException, InterruptedException {
Label fileLabel = (Label) skyKey.argument();
PathFragment filePathFragment = fileLabel.toPathFragment();
//
// Determine whether the package designated by fileLabel exists.
//
SkyKey pkgSkyKey = PackageLookupValue.key(fileLabel.getPackageIdentifier());
PackageLookupValue pkgLookupValue = null;
try {
pkgLookupValue = (PackageLookupValue) env.getValueOrThrow(pkgSkyKey, BuildFileNotFoundException.class, InconsistentFilesystemException.class);
} catch (BuildFileNotFoundException e) {
throw new ASTLookupFunctionException(new ErrorReadingSkylarkExtensionException(e), Transience.PERSISTENT);
} catch (InconsistentFilesystemException e) {
throw new ASTLookupFunctionException(e, Transience.PERSISTENT);
}
if (pkgLookupValue == null) {
return null;
}
if (!pkgLookupValue.packageExists()) {
return ASTFileLookupValue.forBadPackage(fileLabel, pkgLookupValue.getErrorMsg());
}
//
// Determine whether the file designated by fileLabel exists.
//
Path packageRoot = pkgLookupValue.getRoot();
RootedPath rootedPath = RootedPath.toRootedPath(packageRoot, filePathFragment);
SkyKey fileSkyKey = FileValue.key(rootedPath);
FileValue fileValue = null;
try {
fileValue = (FileValue) env.getValueOrThrow(fileSkyKey, IOException.class, FileSymlinkException.class, InconsistentFilesystemException.class);
} catch (IOException | FileSymlinkException e) {
throw new ASTLookupFunctionException(new ErrorReadingSkylarkExtensionException(e), Transience.PERSISTENT);
} catch (InconsistentFilesystemException e) {
throw new ASTLookupFunctionException(e, Transience.PERSISTENT);
}
if (fileValue == null) {
return null;
}
if (!fileValue.isFile()) {
return ASTFileLookupValue.forBadFile(fileLabel);
}
//
// Both the package and the file exist; load the file and parse it as an AST.
//
BuildFileAST ast = null;
Path path = rootedPath.asPath();
try {
long astFileSize = fileValue.getSize();
try (Mutability mutability = Mutability.create("validate")) {
ValidationEnvironment validationEnv = new ValidationEnvironment(ruleClassProvider.createSkylarkRuleClassEnvironment(fileLabel, mutability, env.getListener(), /*astFileContentHashCode=*/
null, /*importMap=*/
null).setupDynamic(Runtime.PKG_NAME, Runtime.NONE).setupDynamic(Runtime.REPOSITORY_NAME, Runtime.NONE));
ast = BuildFileAST.parseSkylarkFile(path, astFileSize, env.getListener());
ast = ast.validate(validationEnv, env.getListener());
}
} catch (IOException e) {
throw new ASTLookupFunctionException(new ErrorReadingSkylarkExtensionException(e), Transience.TRANSIENT);
}
return ASTFileLookupValue.withFile(ast);
}
use of com.google.devtools.build.lib.vfs.RootedPath in project bazel by bazelbuild.
the class FileFunction method resolveFromAncestors.
/**
* Returns the path and file state of {@code rootedPath}, accounting for ancestor symlinks, or
* {@code null} if there was a missing dep.
*/
@Nullable
private static Pair<RootedPath, FileStateValue> resolveFromAncestors(RootedPath rootedPath, Environment env) throws FileFunctionException, InterruptedException {
PathFragment relativePath = rootedPath.getRelativePath();
RootedPath realRootedPath = rootedPath;
FileValue parentFileValue = null;
if (!relativePath.equals(PathFragment.EMPTY_FRAGMENT)) {
RootedPath parentRootedPath = RootedPath.toRootedPath(rootedPath.getRoot(), relativePath.getParentDirectory());
parentFileValue = (FileValue) env.getValue(FileValue.key(parentRootedPath));
if (parentFileValue == null) {
return null;
}
PathFragment baseName = new PathFragment(relativePath.getBaseName());
RootedPath parentRealRootedPath = parentFileValue.realRootedPath();
realRootedPath = RootedPath.toRootedPath(parentRealRootedPath.getRoot(), parentRealRootedPath.getRelativePath().getRelative(baseName));
if (!parentFileValue.exists()) {
return Pair.<RootedPath, FileStateValue>of(realRootedPath, FileStateValue.NONEXISTENT_FILE_STATE_NODE);
}
}
FileStateValue realFileStateValue = (FileStateValue) env.getValue(FileStateValue.key(realRootedPath));
if (realFileStateValue == null) {
return null;
}
if (realFileStateValue.getType() != FileStateValue.Type.NONEXISTENT && parentFileValue != null && !parentFileValue.isDirectory()) {
String type = realFileStateValue.getType().toString().toLowerCase();
String message = type + " " + rootedPath.asPath() + " exists but its parent " + "path " + parentFileValue.realRootedPath().asPath() + " isn't an existing directory.";
throw new FileFunctionException(new InconsistentFilesystemException(message), Transience.TRANSIENT);
}
return Pair.of(realRootedPath, realFileStateValue);
}
Aggregations