diff options
Diffstat (limited to 'src/main/java/com/google')
58 files changed, 566 insertions, 326 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/actions/AbstractAction.java b/src/main/java/com/google/devtools/build/lib/actions/AbstractAction.java index faa6db0025..8e470fa033 100644 --- a/src/main/java/com/google/devtools/build/lib/actions/AbstractAction.java +++ b/src/main/java/com/google/devtools/build/lib/actions/AbstractAction.java @@ -40,6 +40,7 @@ import com.google.devtools.build.lib.syntax.SkylarkNestedSet; import com.google.devtools.build.lib.vfs.FileSystem; import com.google.devtools.build.lib.vfs.FileSystemUtils; import com.google.devtools.build.lib.vfs.Path; +import com.google.devtools.build.lib.vfs.Root; import com.google.devtools.build.lib.vfs.Symlinks; import com.google.devtools.build.skyframe.SkyFunction; import java.io.IOException; @@ -399,13 +400,13 @@ public abstract class AbstractAction implements Action, SkylarkValue { if (output.getRoot() == null) { throw e; } - String outputRootDir = output.getRoot().getPath().getPathString(); - if (!path.getPathString().startsWith(outputRootDir)) { + Root outputRoot = output.getRoot().getRoot(); + if (!outputRoot.contains(path)) { throw e; } Path parentDir = path.getParentDirectory(); - if (!parentDir.isWritable() && parentDir.getPathString().startsWith(outputRootDir)) { + if (!parentDir.isWritable() && outputRoot.contains(parentDir)) { // Retry deleting after making the parent writable. parentDir.setWritable(true); deleteOutput(fileSystem, output); diff --git a/src/main/java/com/google/devtools/build/lib/actions/Artifact.java b/src/main/java/com/google/devtools/build/lib/actions/Artifact.java index a72c77daf2..82594e7d0e 100644 --- a/src/main/java/com/google/devtools/build/lib/actions/Artifact.java +++ b/src/main/java/com/google/devtools/build/lib/actions/Artifact.java @@ -190,7 +190,7 @@ public class Artifact */ @VisibleForTesting public Artifact(Path path, ArtifactRoot root, PathFragment execPath, ArtifactOwner owner) { - if (root == null || !path.startsWith(root.getPath())) { + if (root == null || !root.getRoot().contains(path)) { throw new IllegalArgumentException(root + ": illegal root for " + path + " (execPath: " + execPath + ")"); } @@ -209,7 +209,7 @@ public class Artifact // These two lines establish the invariant that // execPath == rootRelativePath <=> execPath.equals(rootRelativePath) // This is important for isSourceArtifact. - PathFragment rootRel = path.relativeTo(root.getPath()); + PathFragment rootRel = root.getRoot().relativize(path); if (!execPath.endsWith(rootRel)) { throw new IllegalArgumentException(execPath + ": illegal execPath doesn't end with " + rootRel + " at " + path + " with root " + root); @@ -245,15 +245,21 @@ public class Artifact */ @VisibleForTesting // Only exists for testing. public Artifact(Path path, ArtifactRoot root) { - this(path, root, root.getExecPath().getRelative(path.relativeTo(root.getPath())), + this( + path, + root, + root.getExecPath().getRelative(root.getRoot().relativize(path)), ArtifactOwner.NULL_OWNER); } /** Constructs a source or derived Artifact for the specified root-relative path and root. */ @VisibleForTesting // Only exists for testing. public Artifact(PathFragment rootRelativePath, ArtifactRoot root) { - this(root.getPath().getRelative(rootRelativePath), root, - root.getExecPath().getRelative(rootRelativePath), ArtifactOwner.NULL_OWNER); + this( + root.getRoot().getRelative(rootRelativePath), + root, + root.getExecPath().getRelative(rootRelativePath), + ArtifactOwner.NULL_OWNER); } public final Path getPath() { @@ -665,7 +671,11 @@ public class Artifact } else { // Derived Artifact: path and root are under execRoot PathFragment execRoot = trimTail(path.asFragment(), execPath); - return "[[" + execRoot + "]" + root.getPath().asFragment().relativeTo(execRoot) + "]" + return "[[" + + execRoot + + "]" + + root.getRoot().asPath().asFragment().relativeTo(execRoot) + + "]" + rootRelativePath; } } diff --git a/src/main/java/com/google/devtools/build/lib/actions/ArtifactFactory.java b/src/main/java/com/google/devtools/build/lib/actions/ArtifactFactory.java index 26d97f7d9a..c6330d0808 100644 --- a/src/main/java/com/google/devtools/build/lib/actions/ArtifactFactory.java +++ b/src/main/java/com/google/devtools/build/lib/actions/ArtifactFactory.java @@ -149,7 +149,7 @@ public class ArtifactFactory implements ArtifactResolver { Preconditions.checkArgument(!execPath.isAbsolute(), "%s %s %s", execPath, root, owner); Preconditions.checkNotNull(owner, "%s %s", execPath, root); execPath = execPath.normalize(); - return getArtifact(root.getPath().getRelative(execPath), root, execPath, owner, null); + return getArtifact(root.getRoot().getRelative(execPath), root, execPath, owner, null); } @Override @@ -161,10 +161,10 @@ public class ArtifactFactory implements ArtifactResolver { Preconditions.checkArgument(!root.isSourceRoot()); Preconditions.checkArgument(!rootRelativePath.isAbsolute(), rootRelativePath); Preconditions.checkArgument(rootRelativePath.isNormalized(), rootRelativePath); - Preconditions.checkArgument(root.getPath().startsWith(execRootParent), "%s %s", root, - execRootParent); - Preconditions.checkArgument(!root.getPath().equals(execRootParent), "%s %s", root, - execRootParent); + Preconditions.checkArgument( + root.getRoot().asPath().startsWith(execRootParent), "%s %s", root, execRootParent); + Preconditions.checkArgument( + !root.getRoot().asPath().equals(execRootParent), "%s %s", root, execRootParent); // TODO(bazel-team): this should only accept roots from derivedRoots. //Preconditions.checkArgument(derivedRoots.contains(root), "%s not in %s", root, derivedRoots); } @@ -180,7 +180,7 @@ public class ArtifactFactory implements ArtifactResolver { public Artifact getDerivedArtifact( PathFragment rootRelativePath, ArtifactRoot root, ArtifactOwner owner) { validatePath(rootRelativePath, root); - Path path = root.getPath().getRelative(rootRelativePath); + Path path = root.getRoot().getRelative(rootRelativePath); return getArtifact(path, root, path.relativeTo(root.getExecRoot()), owner, null); } @@ -195,7 +195,7 @@ public class ArtifactFactory implements ArtifactResolver { public Artifact getFilesetArtifact( PathFragment rootRelativePath, ArtifactRoot root, ArtifactOwner owner) { validatePath(rootRelativePath, root); - Path path = root.getPath().getRelative(rootRelativePath); + Path path = root.getRoot().getRelative(rootRelativePath); return getArtifact( path, root, path.relativeTo(root.getExecRoot()), owner, SpecialArtifactType.FILESET); } @@ -210,7 +210,7 @@ public class ArtifactFactory implements ArtifactResolver { public Artifact getTreeArtifact( PathFragment rootRelativePath, ArtifactRoot root, ArtifactOwner owner) { validatePath(rootRelativePath, root); - Path path = root.getPath().getRelative(rootRelativePath); + Path path = root.getRoot().getRelative(rootRelativePath); return getArtifact( path, root, path.relativeTo(root.getExecRoot()), owner, SpecialArtifactType.TREE); } @@ -218,7 +218,7 @@ public class ArtifactFactory implements ArtifactResolver { public Artifact getConstantMetadataArtifact( PathFragment rootRelativePath, ArtifactRoot root, ArtifactOwner owner) { validatePath(rootRelativePath, root); - Path path = root.getPath().getRelative(rootRelativePath); + Path path = root.getRoot().getRelative(rootRelativePath); return getArtifact( path, root, path.relativeTo(root.getExecRoot()), owner, SpecialArtifactType.CONSTANT_METADATA); @@ -395,7 +395,7 @@ public class ArtifactFactory implements ArtifactResolver { ArtifactRoot sourceRoot = packageRoots.getRootForPackage(PackageIdentifier.create(RepositoryName.MAIN, execPath)); if (sourceRoot != null) { - return sourceRoot.getPath().getRelative(execPath); + return sourceRoot.getRoot().getRelative(execPath); } return execRoot.getRelative(execPath); } diff --git a/src/main/java/com/google/devtools/build/lib/actions/ArtifactRoot.java b/src/main/java/com/google/devtools/build/lib/actions/ArtifactRoot.java index 47b3c5e68c..8f2480de70 100644 --- a/src/main/java/com/google/devtools/build/lib/actions/ArtifactRoot.java +++ b/src/main/java/com/google/devtools/build/lib/actions/ArtifactRoot.java @@ -24,6 +24,7 @@ import com.google.devtools.build.lib.skylarkinterface.SkylarkPrinter; import com.google.devtools.build.lib.skylarkinterface.SkylarkValue; import com.google.devtools.build.lib.vfs.Path; import com.google.devtools.build.lib.vfs.PathFragment; +import com.google.devtools.build.lib.vfs.Root; import java.io.Serializable; import java.util.Objects; import javax.annotation.Nullable; @@ -56,21 +57,21 @@ public final class ArtifactRoot implements Comparable<ArtifactRoot>, Serializabl // This must always be consistent with Package.getSourceRoot; otherwise computing source roots // from exec paths does not work, which can break the action cache for input-discovering actions. - public static ArtifactRoot computeSourceRoot(Path packageRoot, RepositoryName repository) { + public static ArtifactRoot computeSourceRoot(Root packageRoot, RepositoryName repository) { if (repository.isMain()) { return asSourceRoot(packageRoot); } else { - Path actualRoot = packageRoot; + Path actualRootPath = packageRoot.asPath(); for (int i = 0; i < repository.getSourceRoot().segmentCount(); i++) { - actualRoot = actualRoot.getParentDirectory(); + actualRootPath = actualRootPath.getParentDirectory(); } - return asSourceRoot(actualRoot); + return asSourceRoot(Root.fromPath(actualRootPath)); } } /** Returns the given path as a source root. The path may not be {@code null}. */ - public static ArtifactRoot asSourceRoot(Path path) { - return new ArtifactRoot(null, path); + public static ArtifactRoot asSourceRoot(Root path) { + return new ArtifactRoot(null, PathFragment.EMPTY_FRAGMENT, path); } /** @@ -83,34 +84,37 @@ public final class ArtifactRoot implements Comparable<ArtifactRoot>, Serializabl public static ArtifactRoot asDerivedRoot(Path execRoot, Path root) { Preconditions.checkArgument(root.startsWith(execRoot)); Preconditions.checkArgument(!root.equals(execRoot)); - return new ArtifactRoot(execRoot, root); + PathFragment execPath = root.relativeTo(execRoot); + return new ArtifactRoot(execRoot, execPath, Root.fromPath(root)); } public static ArtifactRoot middlemanRoot(Path execRoot, Path outputDir) { Path root = outputDir.getRelative("internal"); Preconditions.checkArgument(root.startsWith(execRoot)); Preconditions.checkArgument(!root.equals(execRoot)); - return new ArtifactRoot(execRoot, root, true); + PathFragment execPath = root.relativeTo(execRoot); + return new ArtifactRoot(execRoot, execPath, Root.fromPath(root), true); } @Nullable private final Path execRoot; - private final Path path; + private final Root root; private final boolean isMiddlemanRoot; private final PathFragment execPath; - private ArtifactRoot(@Nullable Path execRoot, Path path, boolean isMiddlemanRoot) { + private ArtifactRoot( + @Nullable Path execRoot, PathFragment execPath, Root root, boolean isMiddlemanRoot) { this.execRoot = execRoot; - this.path = Preconditions.checkNotNull(path); + this.root = Preconditions.checkNotNull(root); this.isMiddlemanRoot = isMiddlemanRoot; - this.execPath = isSourceRoot() ? PathFragment.EMPTY_FRAGMENT : path.relativeTo(execRoot); + this.execPath = execPath; } - private ArtifactRoot(@Nullable Path execRoot, Path path) { - this(execRoot, path, false); + private ArtifactRoot(@Nullable Path execRoot, PathFragment execPath, Root root) { + this(execRoot, execPath, root, false); } - public Path getPath() { - return path; + public Root getRoot() { + return root; } /** @@ -142,12 +146,12 @@ public final class ArtifactRoot implements Comparable<ArtifactRoot>, Serializabl @Override public int compareTo(ArtifactRoot o) { - return path.compareTo(o.path); + return root.compareTo(o.root); } @Override public int hashCode() { - return Objects.hash(execRoot, path.hashCode()); + return Objects.hash(execRoot, root.hashCode()); } @Override @@ -159,12 +163,12 @@ public final class ArtifactRoot implements Comparable<ArtifactRoot>, Serializabl return false; } ArtifactRoot r = (ArtifactRoot) o; - return path.equals(r.path) && Objects.equals(execRoot, r.execRoot); + return root.equals(r.root) && Objects.equals(execRoot, r.execRoot); } @Override public String toString() { - return path + (isSourceRoot() ? "[source]" : "[derived]"); + return root + (isSourceRoot() ? "[source]" : "[derived]"); } @Override diff --git a/src/main/java/com/google/devtools/build/lib/actions/FilesetTraversalParams.java b/src/main/java/com/google/devtools/build/lib/actions/FilesetTraversalParams.java index 3a9e211860..75e0da2423 100644 --- a/src/main/java/com/google/devtools/build/lib/actions/FilesetTraversalParams.java +++ b/src/main/java/com/google/devtools/build/lib/actions/FilesetTraversalParams.java @@ -19,8 +19,8 @@ import com.google.common.base.Optional; import com.google.common.collect.ImmutableList; import com.google.devtools.build.lib.cmdline.Label; import com.google.devtools.build.lib.util.Fingerprint; -import com.google.devtools.build.lib.vfs.Path; import com.google.devtools.build.lib.vfs.PathFragment; +import com.google.devtools.build.lib.vfs.Root; import com.google.devtools.build.lib.vfs.RootedPath; import java.util.Set; @@ -75,7 +75,7 @@ public interface FilesetTraversalParams { * * <p>This is typically the workspace root or some output tree's root (e.g. genfiles, binfiles). */ - public abstract Path getRootPart(); + public abstract Root getRootPart(); /** * Returns the {@link #getRootPart() root}-relative part of the path. @@ -96,12 +96,12 @@ public interface FilesetTraversalParams { static DirectTraversalRoot forPackage(Artifact buildFile) { return new AutoValue_FilesetTraversalParams_DirectTraversalRoot( - buildFile.getRoot().getPath(), buildFile.getRootRelativePath().getParentDirectory()); + buildFile.getRoot().getRoot(), buildFile.getRootRelativePath().getParentDirectory()); } static DirectTraversalRoot forFileOrDirectory(Artifact fileOrDirectory) { return new AutoValue_FilesetTraversalParams_DirectTraversalRoot( - fileOrDirectory.getRoot().getPath(), fileOrDirectory.getRootRelativePath()); + fileOrDirectory.getRoot().getRoot(), fileOrDirectory.getRootRelativePath()); } } diff --git a/src/main/java/com/google/devtools/build/lib/actions/PackageRoots.java b/src/main/java/com/google/devtools/build/lib/actions/PackageRoots.java index 9275e3f15f..aff94304b2 100644 --- a/src/main/java/com/google/devtools/build/lib/actions/PackageRoots.java +++ b/src/main/java/com/google/devtools/build/lib/actions/PackageRoots.java @@ -17,6 +17,7 @@ package com.google.devtools.build.lib.actions; import com.google.common.collect.ImmutableMap; import com.google.devtools.build.lib.cmdline.PackageIdentifier; import com.google.devtools.build.lib.vfs.Path; +import com.google.devtools.build.lib.vfs.Root; import java.util.Optional; import javax.annotation.Nullable; @@ -32,7 +33,7 @@ public interface PackageRoots { * this build are present in the map. Should only be needed for planting the symlink forest. If it * is absent, planting the symlink forest is not necessary. */ - Optional<ImmutableMap<PackageIdentifier, Path>> getPackageRootsMap(); + Optional<ImmutableMap<PackageIdentifier, Root>> getPackageRootsMap(); PackageRootLookup getPackageRootLookup(); diff --git a/src/main/java/com/google/devtools/build/lib/analysis/skylark/SkylarkRuleContext.java b/src/main/java/com/google/devtools/build/lib/analysis/skylark/SkylarkRuleContext.java index de2bd4673d..506ff64543 100644 --- a/src/main/java/com/google/devtools/build/lib/analysis/skylark/SkylarkRuleContext.java +++ b/src/main/java/com/google/devtools/build/lib/analysis/skylark/SkylarkRuleContext.java @@ -1008,6 +1008,6 @@ public final class SkylarkRuleContext implements SkylarkValue { public String getBuildFileRelativePath() throws EvalException { checkMutable("build_file_path"); Package pkg = ruleContext.getRule().getPackage(); - return pkg.getBuildFile().getPath().relativeTo(pkg.getSourceRoot()).getPathString(); + return pkg.getSourceRoot().relativize(pkg.getBuildFile().getPath()).getPathString(); } } diff --git a/src/main/java/com/google/devtools/build/lib/bazel/repository/MavenServerFunction.java b/src/main/java/com/google/devtools/build/lib/bazel/repository/MavenServerFunction.java index c0c522d697..566e52b072 100644 --- a/src/main/java/com/google/devtools/build/lib/bazel/repository/MavenServerFunction.java +++ b/src/main/java/com/google/devtools/build/lib/bazel/repository/MavenServerFunction.java @@ -30,6 +30,7 @@ import com.google.devtools.build.lib.syntax.Type; import com.google.devtools.build.lib.util.Fingerprint; import com.google.devtools.build.lib.vfs.Path; import com.google.devtools.build.lib.vfs.PathFragment; +import com.google.devtools.build.lib.vfs.Root; import com.google.devtools.build.lib.vfs.RootedPath; import com.google.devtools.build.skyframe.SkyFunction; import com.google.devtools.build.skyframe.SkyFunctionException.Transience; @@ -102,9 +103,10 @@ public class MavenServerFunction implements SkyFunction { } else { PathFragment settingsFilePath = PathFragment.create(mapper.get("settings_file", Type.STRING)); - RootedPath settingsPath = RootedPath.toRootedPath( - directories.getWorkspace().getRelative(settingsFilePath), - PathFragment.EMPTY_FRAGMENT); + RootedPath settingsPath = + RootedPath.toRootedPath( + Root.fromPath(directories.getWorkspace().getRelative(settingsFilePath)), + PathFragment.EMPTY_FRAGMENT); FileValue fileValue = (FileValue) env.getValue(FileValue.key(settingsPath)); if (fileValue == null) { return null; @@ -187,9 +189,11 @@ public class MavenServerFunction implements SkyFunction { if (m2Home != null) { PathFragment mavenInstallSettings = PathFragment.create(m2Home).getRelative("conf/settings.xml"); - systemKey = FileValue.key( - RootedPath.toRootedPath(directories.getWorkspace().getRelative(mavenInstallSettings), - PathFragment.EMPTY_FRAGMENT)); + systemKey = + FileValue.key( + RootedPath.toRootedPath( + Root.fromPath(directories.getWorkspace().getRelative(mavenInstallSettings)), + PathFragment.EMPTY_FRAGMENT)); settingsFilesBuilder.add(systemKey); } @@ -198,9 +202,11 @@ public class MavenServerFunction implements SkyFunction { SkyKey userKey = null; if (userHome != null) { PathFragment userSettings = PathFragment.create(userHome).getRelative(".m2/settings.xml"); - userKey = FileValue.key(RootedPath.toRootedPath( - directories.getWorkspace().getRelative(userSettings), - PathFragment.EMPTY_FRAGMENT)); + userKey = + FileValue.key( + RootedPath.toRootedPath( + Root.fromPath(directories.getWorkspace().getRelative(userSettings)), + PathFragment.EMPTY_FRAGMENT)); settingsFilesBuilder.add(userKey); } diff --git a/src/main/java/com/google/devtools/build/lib/bazel/rules/android/AndroidNdkRepositoryFunction.java b/src/main/java/com/google/devtools/build/lib/bazel/rules/android/AndroidNdkRepositoryFunction.java index 26b63c7e74..1e4e9b4e82 100644 --- a/src/main/java/com/google/devtools/build/lib/bazel/rules/android/AndroidNdkRepositoryFunction.java +++ b/src/main/java/com/google/devtools/build/lib/bazel/rules/android/AndroidNdkRepositoryFunction.java @@ -39,6 +39,7 @@ import com.google.devtools.build.lib.util.ResourceFileLoader; import com.google.devtools.build.lib.vfs.FileSystemUtils; import com.google.devtools.build.lib.vfs.Path; import com.google.devtools.build.lib.vfs.PathFragment; +import com.google.devtools.build.lib.vfs.Root; import com.google.devtools.build.lib.vfs.RootedPath; import com.google.devtools.build.lib.view.config.crosstool.CrosstoolConfig.CToolchain; import com.google.devtools.build.lib.view.config.crosstool.CrosstoolConfig.CrosstoolRelease; @@ -358,7 +359,8 @@ public class AndroidNdkRepositoryFunction extends AndroidRepositoryFunction { releaseFilePath = directory.getRelative("RELEASE.TXT"); } - SkyKey releaseFileKey = FileValue.key(RootedPath.toRootedPath(directory, releaseFilePath)); + SkyKey releaseFileKey = + FileValue.key(RootedPath.toRootedPath(Root.fromPath(directory), releaseFilePath)); String releaseFileContent = ""; try { diff --git a/src/main/java/com/google/devtools/build/lib/bazel/rules/android/AndroidRepositoryFunction.java b/src/main/java/com/google/devtools/build/lib/bazel/rules/android/AndroidRepositoryFunction.java index 846653a0c4..ccf3d53346 100644 --- a/src/main/java/com/google/devtools/build/lib/bazel/rules/android/AndroidRepositoryFunction.java +++ b/src/main/java/com/google/devtools/build/lib/bazel/rules/android/AndroidRepositoryFunction.java @@ -22,6 +22,7 @@ import com.google.devtools.build.lib.skyframe.InconsistentFilesystemException; import com.google.devtools.build.lib.vfs.Dirent; import com.google.devtools.build.lib.vfs.Path; import com.google.devtools.build.lib.vfs.PathFragment; +import com.google.devtools.build.lib.vfs.Root; import com.google.devtools.build.lib.vfs.RootedPath; import com.google.devtools.build.skyframe.SkyFunction.Environment; import com.google.devtools.build.skyframe.SkyFunctionException.Transience; @@ -49,7 +50,7 @@ abstract class AndroidRepositoryFunction extends RepositoryFunction { */ final DirectoryListingValue getDirectoryListing(Path root, PathFragment dirPath, Environment env) throws RepositoryFunctionException, InterruptedException { - RootedPath rootedPath = RootedPath.toRootedPath(root, dirPath); + RootedPath rootedPath = RootedPath.toRootedPath(Root.fromPath(root), dirPath); try { FileValue dirFileValue = (FileValue) env.getValueOrThrow(FileValue.key(rootedPath), IOException.class); @@ -66,7 +67,7 @@ abstract class AndroidRepositoryFunction extends RepositoryFunction { } return (DirectoryListingValue) env.getValueOrThrow( - DirectoryListingValue.key(RootedPath.toRootedPath(root, dirPath)), + DirectoryListingValue.key(RootedPath.toRootedPath(Root.fromPath(root), dirPath)), InconsistentFilesystemException.class); } catch (IOException e) { throw new RepositoryFunctionException(e, Transience.PERSISTENT); diff --git a/src/main/java/com/google/devtools/build/lib/bazel/rules/android/AndroidSdkRepositoryFunction.java b/src/main/java/com/google/devtools/build/lib/bazel/rules/android/AndroidSdkRepositoryFunction.java index e888f73933..b7f1dbe52d 100644 --- a/src/main/java/com/google/devtools/build/lib/bazel/rules/android/AndroidSdkRepositoryFunction.java +++ b/src/main/java/com/google/devtools/build/lib/bazel/rules/android/AndroidSdkRepositoryFunction.java @@ -38,6 +38,7 @@ import com.google.devtools.build.lib.vfs.Dirent; import com.google.devtools.build.lib.vfs.FileSystem; import com.google.devtools.build.lib.vfs.Path; import com.google.devtools.build.lib.vfs.PathFragment; +import com.google.devtools.build.lib.vfs.Root; import com.google.devtools.build.lib.vfs.RootedPath; import com.google.devtools.build.skyframe.SkyFunction.Environment; import com.google.devtools.build.skyframe.SkyFunctionException.Transience; @@ -303,8 +304,8 @@ public class AndroidSdkRepositoryFunction extends AndroidRepositoryFunction { Path sourcePropertiesFilePath = directory.getRelative( "build-tools/" + buildToolsDirectory + "/source.properties"); - SkyKey releaseFileKey = FileValue.key( - RootedPath.toRootedPath(directory, sourcePropertiesFilePath)); + SkyKey releaseFileKey = + FileValue.key(RootedPath.toRootedPath(Root.fromPath(directory), sourcePropertiesFilePath)); try { env.getValueOrThrow(releaseFileKey, IOException.class); @@ -401,7 +402,8 @@ public class AndroidSdkRepositoryFunction extends AndroidRepositoryFunction { input -> DirectoryListingValue.key( RootedPath.toRootedPath( - root, root.getRelative(path).getRelative(input.getName()))))); + Root.fromPath(root), + root.getRelative(path).getRelative(input.getName()))))); Map<SkyKey, ValueOrException<InconsistentFilesystemException>> values = env.getValuesOrThrow( diff --git a/src/main/java/com/google/devtools/build/lib/buildtool/ExecutionTool.java b/src/main/java/com/google/devtools/build/lib/buildtool/ExecutionTool.java index ea4c801fc5..2b607d8a56 100644 --- a/src/main/java/com/google/devtools/build/lib/buildtool/ExecutionTool.java +++ b/src/main/java/com/google/devtools/build/lib/buildtool/ExecutionTool.java @@ -96,6 +96,7 @@ import com.google.devtools.build.lib.vfs.FileSystemUtils; import com.google.devtools.build.lib.vfs.ModifiedFileSet; import com.google.devtools.build.lib.vfs.Path; import com.google.devtools.build.lib.vfs.PathFragment; +import com.google.devtools.build.lib.vfs.Root; import java.io.IOException; import java.io.OutputStream; import java.io.OutputStreamWriter; @@ -518,7 +519,7 @@ public class ExecutionTool { } private void prepare(PackageRoots packageRoots) throws ExecutorInitException { - Optional<ImmutableMap<PackageIdentifier, Path>> packageRootMap = + Optional<ImmutableMap<PackageIdentifier, Root>> packageRootMap = packageRoots.getPackageRootsMap(); if (!packageRootMap.isPresent()) { return; diff --git a/src/main/java/com/google/devtools/build/lib/buildtool/OutputDirectoryLinksUtils.java b/src/main/java/com/google/devtools/build/lib/buildtool/OutputDirectoryLinksUtils.java index 5c16e7941f..2cfd532b8a 100644 --- a/src/main/java/com/google/devtools/build/lib/buildtool/OutputDirectoryLinksUtils.java +++ b/src/main/java/com/google/devtools/build/lib/buildtool/OutputDirectoryLinksUtils.java @@ -26,6 +26,7 @@ import com.google.devtools.build.lib.events.EventHandler; import com.google.devtools.build.lib.vfs.FileSystemUtils; import com.google.devtools.build.lib.vfs.Path; import com.google.devtools.build.lib.vfs.PathFragment; +import com.google.devtools.build.lib.vfs.Root; import java.io.IOException; import java.util.ArrayList; import java.util.List; @@ -98,7 +99,8 @@ public class OutputDirectoryLinksUtils { Set<Path> binPaths = targetConfigs .stream() - .map(targetConfig -> targetConfig.getBinDirectory(repositoryName).getPath()) + .map(targetConfig -> targetConfig.getBinDirectory(repositoryName).getRoot()) + .map(Root::asPath) .distinct() .collect(toImmutableSet()); if (binPaths.size() == 1) { @@ -109,7 +111,8 @@ public class OutputDirectoryLinksUtils { Set<Path> testLogsPaths = targetConfigs .stream() - .map(targetConfig -> targetConfig.getTestLogsDirectory(repositoryName).getPath()) + .map(targetConfig -> targetConfig.getTestLogsDirectory(repositoryName).getRoot()) + .map(Root::asPath) .distinct() .collect(toImmutableSet()); if (testLogsPaths.size() == 1) { @@ -124,7 +127,8 @@ public class OutputDirectoryLinksUtils { Set<Path> genfilesPaths = targetConfigs .stream() - .map(targetConfig -> targetConfig.getGenfilesDirectory(repositoryName).getPath()) + .map(targetConfig -> targetConfig.getGenfilesDirectory(repositoryName).getRoot()) + .map(Root::asPath) .distinct() .collect(toImmutableSet()); if (genfilesPaths.size() == 1) { diff --git a/src/main/java/com/google/devtools/build/lib/buildtool/SymlinkForest.java b/src/main/java/com/google/devtools/build/lib/buildtool/SymlinkForest.java index 948090c55b..4b4f7cc5c4 100644 --- a/src/main/java/com/google/devtools/build/lib/buildtool/SymlinkForest.java +++ b/src/main/java/com/google/devtools/build/lib/buildtool/SymlinkForest.java @@ -26,6 +26,7 @@ import com.google.devtools.build.lib.concurrent.ThreadSafety; import com.google.devtools.build.lib.vfs.FileSystemUtils; import com.google.devtools.build.lib.vfs.Path; import com.google.devtools.build.lib.vfs.PathFragment; +import com.google.devtools.build.lib.vfs.Root; import java.io.IOException; import java.util.Map; import java.util.Set; @@ -40,14 +41,16 @@ class SymlinkForest { private static final Logger logger = Logger.getLogger(SymlinkForest.class.getName()); private static final boolean LOG_FINER = logger.isLoggable(Level.FINER); - private final ImmutableMap<PackageIdentifier, Path> packageRoots; + private final ImmutableMap<PackageIdentifier, Root> packageRoots; private final Path execroot; private final String workspaceName; private final String productName; private final String[] prefixes; SymlinkForest( - ImmutableMap<PackageIdentifier, Path> packageRoots, Path execroot, String productName, + ImmutableMap<PackageIdentifier, Root> packageRoots, + Path execroot, + String productName, String workspaceName) { this.packageRoots = packageRoots; this.execroot = execroot; @@ -112,22 +115,22 @@ class SymlinkForest { // 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()) { + Map<PackageIdentifier, Set<Root>> dirRootsMap = Maps.newTreeMap(); + for (Map.Entry<PackageIdentifier, Root> entry : packageRoots.entrySet()) { PackageIdentifier pkgId = entry.getKey(); - Path pkgRoot = entry.getValue(); + Root 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.computeIfAbsent(dir, k -> Sets.newHashSet()); + Set<Root> roots = dirRootsMap.computeIfAbsent(dir, k -> Sets.newHashSet()); 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()) { + for (Map.Entry<PackageIdentifier, Set<Root>> entry : dirRootsMap.entrySet()) { PackageIdentifier dir = entry.getKey(); if (!packageRoots.containsKey(dir)) { PackageIdentifier pkgId = longestPathPrefix(dir, packageRoots.keySet()); @@ -137,7 +140,7 @@ class SymlinkForest { } } // 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()) { + for (Map.Entry<PackageIdentifier, Set<Root>> entry : dirRootsMap.entrySet()) { PackageIdentifier dir = entry.getKey(); if (!dir.getRepository().isMain()) { FileSystemUtils.createDirectoryAndParents( @@ -153,9 +156,9 @@ class SymlinkForest { } // Make dir links for single rooted dirs. - for (Map.Entry<PackageIdentifier, Set<Path>> entry : dirRootsMap.entrySet()) { + for (Map.Entry<PackageIdentifier, Set<Root>> entry : dirRootsMap.entrySet()) { PackageIdentifier dir = entry.getKey(); - Set<Path> roots = entry.getValue(); + Set<Root> roots = entry.getValue(); // Simple case of one root for this dir. if (roots.size() == 1) { if (dir.getPackageFragment().segmentCount() > 1 @@ -163,7 +166,7 @@ class SymlinkForest { continue; // skip--an ancestor will link this one in from above } // This is the top-most dir that can be linked to a single root. Make it so. - Path root = roots.iterator().next(); // lone root in set + Root root = roots.iterator().next(); // lone root in set if (LOG_FINER) { logger.finer( "ln -s " @@ -176,13 +179,13 @@ class SymlinkForest { } } // Make links for dirs within packages, skip parent-only dirs. - for (Map.Entry<PackageIdentifier, Set<Path>> entry : dirRootsMap.entrySet()) { + for (Map.Entry<PackageIdentifier, Set<Root>> 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); + Root root = packageRoots.get(pkgId); try { Path absdir = root.getRelative(dir.getSourceRoot()); if (absdir.isDirectory()) { @@ -191,7 +194,7 @@ class SymlinkForest { "ln -s " + absdir + "/* " + execroot.getRelative(dir.getSourceRoot()) + "/"); } for (Path target : absdir.getDirectoryEntries()) { - PathFragment p = target.relativeTo(root); + PathFragment p = root.relativize(target); if (!dirRootsMap.containsKey(createInRepo(pkgId, p))) { //LOG.finest("ln -s " + target + " " + linkRoot.getRelative(p)); execroot.getRelative(p).createSymbolicLink(target); @@ -208,7 +211,7 @@ class SymlinkForest { } } - for (Map.Entry<PackageIdentifier, Path> entry : packageRoots.entrySet()) { + for (Map.Entry<PackageIdentifier, Root> entry : packageRoots.entrySet()) { PackageIdentifier pkgId = entry.getKey(); if (!pkgId.getPackageFragment().equals(PathFragment.EMPTY_FRAGMENT)) { continue; diff --git a/src/main/java/com/google/devtools/build/lib/packages/Package.java b/src/main/java/com/google/devtools/build/lib/packages/Package.java index 9f1daa7dd5..ca12997e90 100644 --- a/src/main/java/com/google/devtools/build/lib/packages/Package.java +++ b/src/main/java/com/google/devtools/build/lib/packages/Package.java @@ -42,6 +42,7 @@ import com.google.devtools.build.lib.util.SpellChecker; import com.google.devtools.build.lib.vfs.Canonicalizer; import com.google.devtools.build.lib.vfs.Path; import com.google.devtools.build.lib.vfs.PathFragment; +import com.google.devtools.build.lib.vfs.Root; import com.google.protobuf.CodedInputStream; import com.google.protobuf.CodedOutputStream; import java.io.IOException; @@ -112,10 +113,10 @@ public class Package { protected String workspaceName; /** - * The root of the source tree in which this package was found. It is an invariant that - * {@code sourceRoot.getRelative(packageId.getSourceRoot()).equals(packageDirectory)}. + * The root of the source tree in which this package was found. It is an invariant that {@code + * sourceRoot.getRelative(packageId.getSourceRoot()).equals(packageDirectory)}. */ - private Path sourceRoot; + private Root sourceRoot; /** * The "Make" environment of this package, containing package-local @@ -273,22 +274,22 @@ public class Package { /** * Returns the source root (a directory) beneath which this package's BUILD file was found. * - * <p> Assumes invariant: - * {@code getSourceRoot().getRelative(packageId.getSourceRoot()).equals(getPackageDirectory())} + * <p>Assumes invariant: {@code + * getSourceRoot().getRelative(packageId.getSourceRoot()).equals(getPackageDirectory())} */ - public Path getSourceRoot() { + public Root getSourceRoot() { return sourceRoot; } // This must always be consistent with Root.computeSourceRoot; otherwise computing source roots // from exec paths does not work, which can break the action cache for input-discovering actions. - private static Path getSourceRoot(Path buildFile, PathFragment packageFragment) { + private static Root getSourceRoot(Path buildFile, PathFragment packageFragment) { Path current = buildFile.getParentDirectory(); for (int i = 0, len = packageFragment.segmentCount(); i < len && !packageFragment.equals(PathFragment.EMPTY_FRAGMENT); i++) { current = current.getParentDirectory(); } - return current; + return Root.fromPath(current); } /** diff --git a/src/main/java/com/google/devtools/build/lib/pkgcache/LoadingPhaseRunner.java b/src/main/java/com/google/devtools/build/lib/pkgcache/LoadingPhaseRunner.java index 39397513f0..af09f1ab5a 100644 --- a/src/main/java/com/google/devtools/build/lib/pkgcache/LoadingPhaseRunner.java +++ b/src/main/java/com/google/devtools/build/lib/pkgcache/LoadingPhaseRunner.java @@ -24,8 +24,8 @@ import com.google.devtools.build.lib.packages.Package; import com.google.devtools.build.lib.packages.Rule; import com.google.devtools.build.lib.packages.Target; import com.google.devtools.build.lib.syntax.Type; -import com.google.devtools.build.lib.vfs.Path; import com.google.devtools.build.lib.vfs.PathFragment; +import com.google.devtools.build.lib.vfs.Root; import java.util.Collection; import java.util.List; import javax.annotation.Nullable; @@ -57,13 +57,11 @@ public abstract class LoadingPhaseRunner { @Nullable LoadingCallback callback) throws TargetParsingException, LoadingFailedException, InterruptedException; - /** - * Returns a map of collected package names to root paths. - */ - public static ImmutableMap<PackageIdentifier, Path> collectPackageRoots( + /** Returns a map of collected package names to root paths. */ + public static ImmutableMap<PackageIdentifier, Root> collectPackageRoots( Collection<Package> packages) { // Make a map of the package names to their root paths. - ImmutableMap.Builder<PackageIdentifier, Path> packageRoots = ImmutableMap.builder(); + ImmutableMap.Builder<PackageIdentifier, Root> packageRoots = ImmutableMap.builder(); for (Package pkg : packages) { packageRoots.put(pkg.getPackageIdentifier(), pkg.getSourceRoot()); } diff --git a/src/main/java/com/google/devtools/build/lib/pkgcache/PathPackageLocator.java b/src/main/java/com/google/devtools/build/lib/pkgcache/PathPackageLocator.java index 94694c1335..b0c780b956 100644 --- a/src/main/java/com/google/devtools/build/lib/pkgcache/PathPackageLocator.java +++ b/src/main/java/com/google/devtools/build/lib/pkgcache/PathPackageLocator.java @@ -27,6 +27,7 @@ import com.google.devtools.build.lib.packages.NoSuchPackageException; import com.google.devtools.build.lib.vfs.FileStatus; import com.google.devtools.build.lib.vfs.Path; import com.google.devtools.build.lib.vfs.PathFragment; +import com.google.devtools.build.lib.vfs.Root; import com.google.devtools.build.lib.vfs.Symlinks; import com.google.devtools.build.lib.vfs.UnixGlob; import java.io.IOException; @@ -47,7 +48,7 @@ import java.util.concurrent.atomic.AtomicReference; public class PathPackageLocator implements Serializable { private static final String WORKSPACE_WILDCARD = "%workspace%"; - private final ImmutableList<Path> pathEntries; + private final ImmutableList<Root> pathEntries; // Transient because this is an injected value in Skyframe, and as such, its serialized // representation is used as a key. We want a change to output base not to invalidate things. private final transient Path outputBase; @@ -56,7 +57,7 @@ public class PathPackageLocator implements Serializable { @VisibleForTesting public PathPackageLocator( - Path outputBase, List<Path> pathEntries, List<BuildFileName> buildFilesByPriority) { + Path outputBase, List<Root> pathEntries, List<BuildFileName> buildFilesByPriority) { this.outputBase = outputBase; this.pathEntries = ImmutableList.copyOf(pathEntries); this.buildFilesByPriority = ImmutableList.copyOf(buildFilesByPriority); @@ -133,11 +134,8 @@ public class PathPackageLocator implements Serializable { return null; } - - /** - * Returns an immutable ordered list of the directories on the package path. - */ - public ImmutableList<Path> getPathEntries() { + /** Returns an immutable ordered list of the directories on the package path. */ + public ImmutableList<Root> getPathEntries() { return pathEntries; } @@ -187,38 +185,18 @@ public class PathPackageLocator implements Serializable { } /** - * A factory of PathPackageLocators from a list of path elements. Elements may contain - * "%workspace%", indicating the workspace. + * A factory of PathPackageLocators from a list of path elements. * * @param outputBase the output base. Can be null if remote repositories are not in use. - * @param pathElements Each element must be an absolute path, relative path, or some string - * "%workspace%" + relative, where relative is itself a relative path. The special symbol - * "%workspace%" means to interpret the path relative to the nearest enclosing workspace. - * Relative paths are interpreted relative to the client's working directory, which may be - * below the workspace. - * @param eventHandler The eventHandler. - * @param workspace The nearest enclosing package root directory. - * @param clientWorkingDirectory The client's working directory. + * @param pathElements Each element must be a {@link Root} object. * @param buildFilesByPriority The ordered collection of {@link BuildFileName}s to check in each * potential package directory. * @return a {@link PathPackageLocator} that uses the {@code outputBase} and {@code pathElements} * provided. */ public static PathPackageLocator createWithoutExistenceCheck( - Path outputBase, - List<String> pathElements, - EventHandler eventHandler, - Path workspace, - Path clientWorkingDirectory, - List<BuildFileName> buildFilesByPriority) { - return createInternal( - outputBase, - pathElements, - eventHandler, - workspace, - clientWorkingDirectory, - buildFilesByPriority, - false); + Path outputBase, List<Root> pathElements, List<BuildFileName> buildFilesByPriority) { + return new PathPackageLocator(outputBase, pathElements, buildFilesByPriority); } private static PathPackageLocator createInternal( @@ -229,7 +207,7 @@ public class PathPackageLocator implements Serializable { Path clientWorkingDirectory, List<BuildFileName> buildFilesByPriority, boolean checkExistence) { - List<Path> resolvedPaths = new ArrayList<>(); + List<Root> resolvedPaths = new ArrayList<>(); for (String pathElement : pathElements) { // Replace "%workspace%" with the path of the enclosing workspace directory. @@ -254,7 +232,7 @@ public class PathPackageLocator implements Serializable { } if (!checkExistence || rootPath.exists()) { - resolvedPaths.add(rootPath); + resolvedPaths.add(Root.fromPath(rootPath)); } } @@ -276,7 +254,7 @@ public class PathPackageLocator implements Serializable { private Path getFilePath(PathFragment suffix, AtomicReference<? extends UnixGlob.FilesystemCalls> cache) { - for (Path pathEntry : pathEntries) { + for (Root pathEntry : pathEntries) { Path buildFile = pathEntry.getRelative(suffix); try { FileStatus stat = cache.get().statIfFound(buildFile, Symlinks.FOLLOW); diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcIncLibrary.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcIncLibrary.java index a459e42ac1..ad05f41707 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcIncLibrary.java +++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcIncLibrary.java @@ -93,7 +93,7 @@ public abstract class CcIncLibrary implements RuleConfiguredTargetFactory { .getRelative(packageFragment) .getRelative(includeDirectory); Path includeRoot = - configIncludeDirectory.getPath().getRelative(packageFragment).getRelative(includeDirectory); + configIncludeDirectory.getRoot().getRelative(packageFragment).getRelative(includeDirectory); // For every source artifact, we compute a virtual artifact that is below the include directory. // These are used for include checking. diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CppCompileAction.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CppCompileAction.java index 8f2a0c63b5..7bede6cf39 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CppCompileAction.java +++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CppCompileAction.java @@ -64,6 +64,7 @@ import com.google.devtools.build.lib.util.ShellEscaper; import com.google.devtools.build.lib.vfs.FileSystemUtils; import com.google.devtools.build.lib.vfs.Path; import com.google.devtools.build.lib.vfs.PathFragment; +import com.google.devtools.build.lib.vfs.Root; import com.google.devtools.build.skyframe.SkyFunction; import com.google.devtools.build.skyframe.SkyKey; import com.google.devtools.build.skyframe.SkyValue; @@ -904,16 +905,16 @@ public class CppCompileAction extends AbstractAction } } // Still not found: see if it is in a subdir of a declared package. - Path root = input.getRoot().getPath(); + Root root = input.getRoot().getRoot(); for (Path dir = input.getPath().getParentDirectory();;) { if (dir.getRelative(BUILD_PATH_FRAGMENT).exists()) { return false; // Bad: this is a sub-package, not a subdir of a declared package. } dir = dir.getParentDirectory(); - if (dir.equals(root)) { + if (dir.equals(root.asPath())) { return false; // Bad: at the top, give up. } - if (declaredIncludeDirs.contains(dir.relativeTo(root))) { + if (declaredIncludeDirs.contains(root.relativize(dir))) { return true; // OK: found under a declared dir. } } diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/FdoSupport.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/FdoSupport.java index 8edc2d9cc5..40d80302a4 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/cpp/FdoSupport.java +++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/FdoSupport.java @@ -38,6 +38,7 @@ import com.google.devtools.build.lib.skyframe.PrecomputedValue; import com.google.devtools.build.lib.vfs.FileSystemUtils; import com.google.devtools.build.lib.vfs.Path; import com.google.devtools.build.lib.vfs.PathFragment; +import com.google.devtools.build.lib.vfs.Root; import com.google.devtools.build.lib.vfs.RootedPath; import com.google.devtools.build.lib.view.config.crosstool.CrosstoolConfig.LipoMode; import com.google.devtools.build.skyframe.SkyFunction; @@ -304,8 +305,10 @@ public class FdoSupport { PrecomputedValue.dependOnBuildId(env); } else { Path path = fdoMode == FdoMode.AUTO_FDO ? getAutoFdoImportsPath(fdoProfile) : fdoProfile; - env.getValue(FileValue.key(RootedPath.toRootedPathMaybeUnderRoot(path, - ImmutableList.of(execRoot)))); + env.getValue( + FileValue.key( + RootedPath.toRootedPathMaybeUnderRoot( + path, ImmutableList.of(Root.fromPath(execRoot))))); } } diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/IncludeScanner.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/IncludeScanner.java index b07f75e86f..6ad546cec3 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/cpp/IncludeScanner.java +++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/IncludeScanner.java @@ -155,7 +155,7 @@ public interface IncludeScanner { for (Artifact included : includes) { // Check for absolute includes -- we assign the file system root as // the root path for such includes - if (included.getRoot().getPath().isRootDirectory()) { + if (included.getRoot().getRoot().isRootDirectory()) { if (FileSystemUtils.startsWithAny( included.getPath().asFragment(), absoluteBuiltInIncludeDirs)) { // Skip include files found in absolute include directories. diff --git a/src/main/java/com/google/devtools/build/lib/rules/repository/NewLocalRepositoryFunction.java b/src/main/java/com/google/devtools/build/lib/rules/repository/NewLocalRepositoryFunction.java index 9811287cb9..9021546d65 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/repository/NewLocalRepositoryFunction.java +++ b/src/main/java/com/google/devtools/build/lib/rules/repository/NewLocalRepositoryFunction.java @@ -23,6 +23,7 @@ import com.google.devtools.build.lib.skyframe.InconsistentFilesystemException; import com.google.devtools.build.lib.vfs.FileSystem; import com.google.devtools.build.lib.vfs.Path; import com.google.devtools.build.lib.vfs.PathFragment; +import com.google.devtools.build.lib.vfs.Root; import com.google.devtools.build.lib.vfs.RootedPath; import com.google.devtools.build.skyframe.SkyFunction.Environment; import com.google.devtools.build.skyframe.SkyFunctionException; @@ -56,7 +57,7 @@ public class NewLocalRepositoryFunction extends RepositoryFunction { FileSystem fs = directories.getOutputBase().getFileSystem(); Path path = fs.getPath(pathFragment); - RootedPath dirPath = RootedPath.toRootedPath(fs.getRootDirectory(), path); + RootedPath dirPath = RootedPath.toRootedPath(Root.fromFileSystemRoot(fs), path); try { FileValue dirFileValue = diff --git a/src/main/java/com/google/devtools/build/lib/rules/repository/NewRepositoryFileHandler.java b/src/main/java/com/google/devtools/build/lib/rules/repository/NewRepositoryFileHandler.java index 7d93da6f98..14efd5e10b 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/repository/NewRepositoryFileHandler.java +++ b/src/main/java/com/google/devtools/build/lib/rules/repository/NewRepositoryFileHandler.java @@ -25,6 +25,7 @@ import com.google.devtools.build.lib.syntax.EvalException; import com.google.devtools.build.lib.syntax.Type; import com.google.devtools.build.lib.vfs.Path; import com.google.devtools.build.lib.vfs.PathFragment; +import com.google.devtools.build.lib.vfs.Root; import com.google.devtools.build.lib.vfs.RootedPath; import com.google.devtools.build.skyframe.SkyFunction.Environment; import com.google.devtools.build.skyframe.SkyFunctionException.Transience; @@ -216,7 +217,7 @@ public class NewRepositoryFileHandler { } // And now for the file - Path packageRoot = pkgLookupValue.getRoot(); + Root packageRoot = pkgLookupValue.getRoot(); rootedFile = RootedPath.toRootedPath(packageRoot, label.toPathFragment()); } else { // TODO(dmarting): deprecate using a path for the workspace_file attribute. @@ -236,9 +237,10 @@ public class NewRepositoryFileHandler { if (file.isAbsolute()) { rootedFile = RootedPath.toRootedPath( - fileTarget.getParentDirectory(), PathFragment.create(fileTarget.getBaseName())); + Root.fromPath(fileTarget.getParentDirectory()), + PathFragment.create(fileTarget.getBaseName())); } else { - rootedFile = RootedPath.toRootedPath(workspacePath, file); + rootedFile = RootedPath.toRootedPath(Root.fromPath(workspacePath), file); } } SkyKey fileKey = FileValue.key(rootedFile); diff --git a/src/main/java/com/google/devtools/build/lib/rules/repository/RepositoryFunction.java b/src/main/java/com/google/devtools/build/lib/rules/repository/RepositoryFunction.java index 0cf44e6edd..024287deb3 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/repository/RepositoryFunction.java +++ b/src/main/java/com/google/devtools/build/lib/rules/repository/RepositoryFunction.java @@ -42,6 +42,7 @@ import com.google.devtools.build.lib.syntax.Type; import com.google.devtools.build.lib.vfs.FileSystemUtils; import com.google.devtools.build.lib.vfs.Path; import com.google.devtools.build.lib.vfs.PathFragment; +import com.google.devtools.build.lib.vfs.Root; import com.google.devtools.build.lib.vfs.RootedPath; import com.google.devtools.build.lib.vfs.Symlinks; import com.google.devtools.build.skyframe.SkyFunction.Environment; @@ -212,7 +213,7 @@ public abstract class RepositoryFunction { Path file = rule.getPackage().getPackageDirectory().getRelative(filePathFragment); rootedPath = RootedPath.toRootedPath( - file.getParentDirectory(), PathFragment.create(file.getBaseName())); + Root.fromPath(file.getParentDirectory()), PathFragment.create(file.getBaseName())); } SkyKey fileSkyKey = FileValue.key(rootedPath); @@ -281,7 +282,7 @@ public abstract class RepositoryFunction { } // And now for the file - Path packageRoot = pkgLookupValue.getRoot(); + Root packageRoot = pkgLookupValue.getRoot(); return RootedPath.toRootedPath(packageRoot, label.toPathFragment()); } @@ -473,8 +474,10 @@ public abstract class RepositoryFunction { @Nullable protected static FileValue getRepositoryDirectory(Path repositoryDirectory, Environment env) throws RepositoryFunctionException, InterruptedException { - SkyKey outputDirectoryKey = FileValue.key(RootedPath.toRootedPath( - repositoryDirectory, PathFragment.EMPTY_FRAGMENT)); + SkyKey outputDirectoryKey = + FileValue.key( + RootedPath.toRootedPath( + Root.fromPath(repositoryDirectory), PathFragment.EMPTY_FRAGMENT)); FileValue value; try { value = (FileValue) env.getValueOrThrow(outputDirectoryKey, IOException.class); diff --git a/src/main/java/com/google/devtools/build/lib/rules/repository/RepositoryLoaderFunction.java b/src/main/java/com/google/devtools/build/lib/rules/repository/RepositoryLoaderFunction.java index ad0e5abb15..f2cda7aa7d 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/repository/RepositoryLoaderFunction.java +++ b/src/main/java/com/google/devtools/build/lib/rules/repository/RepositoryLoaderFunction.java @@ -23,6 +23,7 @@ import com.google.devtools.build.lib.skyframe.RepositoryValue; import com.google.devtools.build.lib.skyframe.WorkspaceFileValue; import com.google.devtools.build.lib.vfs.Path; import com.google.devtools.build.lib.vfs.PathFragment; +import com.google.devtools.build.lib.vfs.Root; import com.google.devtools.build.lib.vfs.RootedPath; import com.google.devtools.build.skyframe.SkyFunction; import com.google.devtools.build.skyframe.SkyFunctionException; @@ -54,7 +55,8 @@ public class RepositoryLoaderFunction implements SkyFunction { SkyKey workspaceKey = WorkspaceFileValue.key( - RootedPath.toRootedPath(repository.getPath(), PathFragment.create("WORKSPACE"))); + RootedPath.toRootedPath( + Root.fromPath(repository.getPath()), PathFragment.create("WORKSPACE"))); WorkspaceFileValue workspacePackage = (WorkspaceFileValue) env.getValue(workspaceKey); if (workspacePackage == null) { return null; diff --git a/src/main/java/com/google/devtools/build/lib/runtime/ProjectFile.java b/src/main/java/com/google/devtools/build/lib/runtime/ProjectFile.java index 59c0a23294..30760ecd1d 100644 --- a/src/main/java/com/google/devtools/build/lib/runtime/ProjectFile.java +++ b/src/main/java/com/google/devtools/build/lib/runtime/ProjectFile.java @@ -16,6 +16,7 @@ package com.google.devtools.build.lib.runtime; import com.google.devtools.build.lib.vfs.Path; import com.google.devtools.build.lib.vfs.PathFragment; +import com.google.devtools.build.lib.vfs.Root; import com.google.devtools.common.options.OptionsParsingException; import java.util.List; @@ -38,7 +39,7 @@ public interface ProjectFile { * Returns an (optionally cached) project file instance. If there is no such file, or if the * file cannot be parsed, then it throws an exception. */ - ProjectFile getProjectFile(Path workingDirectory, List<Path> packagePath, PathFragment path) + ProjectFile getProjectFile(Path workingDirectory, List<Root> packagePath, PathFragment path) throws OptionsParsingException; } diff --git a/src/main/java/com/google/devtools/build/lib/runtime/commands/InfoItem.java b/src/main/java/com/google/devtools/build/lib/runtime/commands/InfoItem.java index 0badadd258..7d5e05f045 100644 --- a/src/main/java/com/google/devtools/build/lib/runtime/commands/InfoItem.java +++ b/src/main/java/com/google/devtools/build/lib/runtime/commands/InfoItem.java @@ -224,7 +224,7 @@ public abstract class InfoItem { public byte[] get(Supplier<BuildConfiguration> configurationSupplier, CommandEnvironment env) throws AbruptExitException { checkNotNull(configurationSupplier); - return print(configurationSupplier.get().getBinDirectory(RepositoryName.MAIN).getPath()); + return print(configurationSupplier.get().getBinDirectory(RepositoryName.MAIN).getRoot()); } } @@ -245,8 +245,7 @@ public abstract class InfoItem { public byte[] get(Supplier<BuildConfiguration> configurationSupplier, CommandEnvironment env) throws AbruptExitException { checkNotNull(configurationSupplier); - return print( - configurationSupplier.get().getGenfilesDirectory(RepositoryName.MAIN).getPath()); + return print(configurationSupplier.get().getGenfilesDirectory(RepositoryName.MAIN).getRoot()); } } @@ -267,8 +266,7 @@ public abstract class InfoItem { public byte[] get(Supplier<BuildConfiguration> configurationSupplier, CommandEnvironment env) throws AbruptExitException { checkNotNull(configurationSupplier); - return print( - configurationSupplier.get().getTestLogsDirectory(RepositoryName.MAIN).getPath()); + return print(configurationSupplier.get().getTestLogsDirectory(RepositoryName.MAIN).getRoot()); } } diff --git a/src/main/java/com/google/devtools/build/lib/runtime/commands/ProjectFileSupport.java b/src/main/java/com/google/devtools/build/lib/runtime/commands/ProjectFileSupport.java index ffb81648f6..a14ff5a23c 100644 --- a/src/main/java/com/google/devtools/build/lib/runtime/commands/ProjectFileSupport.java +++ b/src/main/java/com/google/devtools/build/lib/runtime/commands/ProjectFileSupport.java @@ -23,6 +23,7 @@ import com.google.devtools.build.lib.runtime.ProjectFile; import com.google.devtools.build.lib.skyframe.BazelSkyframeExecutorConstants; import com.google.devtools.build.lib.vfs.Path; import com.google.devtools.build.lib.vfs.PathFragment; +import com.google.devtools.build.lib.vfs.Root; import com.google.devtools.common.options.OptionPriority.PriorityCategory; import com.google.devtools.common.options.OptionsParser; import com.google.devtools.common.options.OptionsParsingException; @@ -60,7 +61,7 @@ public final class ProjectFileSupport { // cwd is a subdirectory of the workspace, that will be surprising, and we should interpret it // relative to the cwd instead. PathFragment projectFilePath = PathFragment.create(targets.get(0).substring(1)); - List<Path> packagePath = + List<Root> packagePath = PathPackageLocator.create( // We only need a non-null outputBase for the PathPackageLocator if we support // external diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/ASTFileLookupFunction.java b/src/main/java/com/google/devtools/build/lib/skyframe/ASTFileLookupFunction.java index 2fcbfbe1fc..b1f816d87a 100644 --- a/src/main/java/com/google/devtools/build/lib/skyframe/ASTFileLookupFunction.java +++ b/src/main/java/com/google/devtools/build/lib/skyframe/ASTFileLookupFunction.java @@ -24,6 +24,7 @@ import com.google.devtools.build.lib.syntax.SkylarkSemantics; import com.google.devtools.build.lib.vfs.FileSystemUtils; import com.google.devtools.build.lib.vfs.Path; import com.google.devtools.build.lib.vfs.PathFragment; +import com.google.devtools.build.lib.vfs.Root; import com.google.devtools.build.lib.vfs.RootedPath; import com.google.devtools.build.skyframe.SkyFunction; import com.google.devtools.build.skyframe.SkyFunctionException; @@ -79,7 +80,7 @@ public class ASTFileLookupFunction implements SkyFunction { // // Determine whether the file designated by fileLabel exists. // - Path packageRoot = pkgLookupValue.getRoot(); + Root packageRoot = pkgLookupValue.getRoot(); RootedPath rootedPath = RootedPath.toRootedPath(packageRoot, filePathFragment); SkyKey fileSkyKey = FileValue.key(rootedPath); FileValue fileValue = null; diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/ActionMetadataHandler.java b/src/main/java/com/google/devtools/build/lib/skyframe/ActionMetadataHandler.java index d060835c46..bf635c9e1d 100644 --- a/src/main/java/com/google/devtools/build/lib/skyframe/ActionMetadataHandler.java +++ b/src/main/java/com/google/devtools/build/lib/skyframe/ActionMetadataHandler.java @@ -554,7 +554,7 @@ public class ActionMetadataHandler implements MetadataHandler { throws IOException { Path path = artifact.getPath(); RootedPath rootedPath = - RootedPath.toRootedPath(artifact.getRoot().getPath(), artifact.getRootRelativePath()); + RootedPath.toRootedPath(artifact.getRoot().getRoot(), artifact.getRootRelativePath()); if (statNoFollow == null) { statNoFollow = FileStatusWithDigestAdapter.adapt(path.statIfFound(Symlinks.NOFOLLOW)); if (statNoFollow == null) { @@ -573,8 +573,9 @@ public class ActionMetadataHandler implements MetadataHandler { throw new IOException("symlink cycle"); } } - RootedPath realRootedPath = RootedPath.toRootedPathMaybeUnderRoot(realPath, - ImmutableList.of(artifact.getRoot().getPath())); + RootedPath realRootedPath = + RootedPath.toRootedPathMaybeUnderRoot( + realPath, ImmutableList.of(artifact.getRoot().getRoot())); FileStateValue fileStateValue = FileStateValue.createWithStatNoFollow(rootedPath, statNoFollow, tsgm); // TODO(bazel-team): consider avoiding a 'stat' here when the symlink target hasn't changed diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/ArtifactFunction.java b/src/main/java/com/google/devtools/build/lib/skyframe/ArtifactFunction.java index e607b195af..627184df44 100644 --- a/src/main/java/com/google/devtools/build/lib/skyframe/ArtifactFunction.java +++ b/src/main/java/com/google/devtools/build/lib/skyframe/ArtifactFunction.java @@ -214,8 +214,8 @@ class ArtifactFunction implements SkyFunction { private FileArtifactValue createSourceValue(Artifact artifact, boolean mandatory, Environment env) throws MissingInputFileException, InterruptedException { - SkyKey fileSkyKey = FileValue.key(RootedPath.toRootedPath(artifact.getRoot().getPath(), - artifact.getPath())); + SkyKey fileSkyKey = + FileValue.key(RootedPath.toRootedPath(artifact.getRoot().getRoot(), artifact.getPath())); FileValue fileValue; try { fileValue = (FileValue) env.getValueOrThrow(fileSkyKey, IOException.class); diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/BlacklistedPackagePrefixesFunction.java b/src/main/java/com/google/devtools/build/lib/skyframe/BlacklistedPackagePrefixesFunction.java index 713022c7e5..8d96dd3d40 100644 --- a/src/main/java/com/google/devtools/build/lib/skyframe/BlacklistedPackagePrefixesFunction.java +++ b/src/main/java/com/google/devtools/build/lib/skyframe/BlacklistedPackagePrefixesFunction.java @@ -17,8 +17,8 @@ import com.google.common.collect.ImmutableSet; import com.google.common.io.CharStreams; import com.google.common.io.LineProcessor; import com.google.devtools.build.lib.pkgcache.PathPackageLocator; -import com.google.devtools.build.lib.vfs.Path; import com.google.devtools.build.lib.vfs.PathFragment; +import com.google.devtools.build.lib.vfs.Root; import com.google.devtools.build.lib.vfs.RootedPath; import com.google.devtools.build.skyframe.SkyFunction; import com.google.devtools.build.skyframe.SkyFunctionException; @@ -58,7 +58,7 @@ public class BlacklistedPackagePrefixesFunction implements SkyFunction { return null; } - for (Path packagePathEntry : pkgLocator.getPathEntries()) { + for (Root packagePathEntry : pkgLocator.getPathEntries()) { RootedPath rootedPatternFile = RootedPath.toRootedPath(packagePathEntry, additionalBlacklistedPackagePrefixesFile); FileValue patternFileValue = (FileValue) env.getValue(FileValue.key(rootedPatternFile)); diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/ContainingPackageLookupValue.java b/src/main/java/com/google/devtools/build/lib/skyframe/ContainingPackageLookupValue.java index e2edd9dcfe..491275ceef 100644 --- a/src/main/java/com/google/devtools/build/lib/skyframe/ContainingPackageLookupValue.java +++ b/src/main/java/com/google/devtools/build/lib/skyframe/ContainingPackageLookupValue.java @@ -15,7 +15,7 @@ package com.google.devtools.build.lib.skyframe; import com.google.common.base.Preconditions; import com.google.devtools.build.lib.cmdline.PackageIdentifier; -import com.google.devtools.build.lib.vfs.Path; +import com.google.devtools.build.lib.vfs.Root; import com.google.devtools.build.skyframe.LegacySkyKey; import com.google.devtools.build.skyframe.SkyKey; import com.google.devtools.build.skyframe.SkyValue; @@ -36,7 +36,7 @@ public abstract class ContainingPackageLookupValue implements SkyValue { public abstract PackageIdentifier getContainingPackageName(); /** If there is a containing package, returns its package root */ - public abstract Path getContainingPackageRoot(); + public abstract Root getContainingPackageRoot(); public static SkyKey key(PackageIdentifier id) { Preconditions.checkArgument(!id.getPackageFragment().isAbsolute(), id); @@ -44,7 +44,7 @@ public abstract class ContainingPackageLookupValue implements SkyValue { return LegacySkyKey.create(SkyFunctions.CONTAINING_PACKAGE_LOOKUP, id); } - public static ContainingPackage withContainingPackage(PackageIdentifier pkgId, Path root) { + public static ContainingPackage withContainingPackage(PackageIdentifier pkgId, Root root) { return new ContainingPackage(pkgId, root); } @@ -64,7 +64,7 @@ public abstract class ContainingPackageLookupValue implements SkyValue { } @Override - public Path getContainingPackageRoot() { + public Root getContainingPackageRoot() { throw new IllegalStateException(); } } @@ -72,9 +72,9 @@ public abstract class ContainingPackageLookupValue implements SkyValue { /** A successful lookup value. */ public static class ContainingPackage extends ContainingPackageLookupValue { private final PackageIdentifier containingPackage; - private final Path containingPackageRoot; + private final Root containingPackageRoot; - private ContainingPackage(PackageIdentifier pkgId, Path containingPackageRoot) { + private ContainingPackage(PackageIdentifier pkgId, Root containingPackageRoot) { this.containingPackage = pkgId; this.containingPackageRoot = containingPackageRoot; } @@ -90,7 +90,7 @@ public abstract class ContainingPackageLookupValue implements SkyValue { } @Override - public Path getContainingPackageRoot() { + public Root getContainingPackageRoot() { return containingPackageRoot; } diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/DiffAwareness.java b/src/main/java/com/google/devtools/build/lib/skyframe/DiffAwareness.java index 64c90338d0..507a49f403 100644 --- a/src/main/java/com/google/devtools/build/lib/skyframe/DiffAwareness.java +++ b/src/main/java/com/google/devtools/build/lib/skyframe/DiffAwareness.java @@ -14,7 +14,7 @@ package com.google.devtools.build.lib.skyframe; import com.google.devtools.build.lib.vfs.ModifiedFileSet; -import com.google.devtools.build.lib.vfs.Path; +import com.google.devtools.build.lib.vfs.Root; import com.google.devtools.common.options.OptionsClassProvider; import java.io.Closeable; import javax.annotation.Nullable; @@ -36,11 +36,11 @@ public interface DiffAwareness extends Closeable { * Returns a {@link DiffAwareness} instance suitable for managing changes to files under the * given package path entry, or {@code null} if this factory cannot create such an instance. * - * <p> Skyframe has a collection of factories, and will create a {@link DiffAwareness} instance + * <p>Skyframe has a collection of factories, and will create a {@link DiffAwareness} instance * per package path entry using one of the factories that returns a non-null value. */ @Nullable - DiffAwareness maybeCreate(Path pathEntry); + DiffAwareness maybeCreate(Root pathEntry); } /** Opaque view of the filesystem under a package path entry at a specific point in time. */ diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/DiffAwarenessManager.java b/src/main/java/com/google/devtools/build/lib/skyframe/DiffAwarenessManager.java index 8c9ffb7426..7bd831b1df 100644 --- a/src/main/java/com/google/devtools/build/lib/skyframe/DiffAwarenessManager.java +++ b/src/main/java/com/google/devtools/build/lib/skyframe/DiffAwarenessManager.java @@ -19,7 +19,7 @@ import com.google.devtools.build.lib.events.Event; import com.google.devtools.build.lib.events.EventHandler; import com.google.devtools.build.lib.skyframe.DiffAwareness.View; import com.google.devtools.build.lib.vfs.ModifiedFileSet; -import com.google.devtools.build.lib.vfs.Path; +import com.google.devtools.build.lib.vfs.Root; import com.google.devtools.common.options.OptionsClassProvider; import java.util.Map; import java.util.logging.Logger; @@ -36,7 +36,7 @@ public final class DiffAwarenessManager { // The manager attempts to instantiate these in the order in which they are passed to the // constructor; this is critical in the case where a factory always succeeds. private final ImmutableList<? extends DiffAwareness.Factory> diffAwarenessFactories; - private Map<Path, DiffAwarenessState> currentDiffAwarenessStates = Maps.newHashMap(); + private Map<Root, DiffAwarenessState> currentDiffAwarenessStates = Maps.newHashMap(); public DiffAwarenessManager(Iterable<? extends DiffAwareness.Factory> diffAwarenessFactories) { this.diffAwarenessFactories = ImmutableList.copyOf(diffAwarenessFactories); @@ -77,11 +77,11 @@ public final class DiffAwarenessManager { } /** - * Gets the set of changed files since the last call with this path entry, or - * {@code ModifiedFileSet.EVERYTHING_MODIFIED} if this is the first such call. + * Gets the set of changed files since the last call with this path entry, or {@code + * ModifiedFileSet.EVERYTHING_MODIFIED} if this is the first such call. */ public ProcessableModifiedFileSet getDiff( - EventHandler eventHandler, Path pathEntry, OptionsClassProvider options) { + EventHandler eventHandler, Root pathEntry, OptionsClassProvider options) { DiffAwarenessState diffAwarenessState = maybeGetDiffAwarenessState(pathEntry); if (diffAwarenessState == null) { return BrokenProcessableModifiedFileSet.INSTANCE; @@ -120,7 +120,7 @@ public final class DiffAwarenessManager { } private void handleBrokenDiffAwareness( - EventHandler eventHandler, Path pathEntry, BrokenDiffAwarenessException e) { + EventHandler eventHandler, Root pathEntry, BrokenDiffAwarenessException e) { currentDiffAwarenessStates.remove(pathEntry); logger.info("Broken diff awareness for " + pathEntry + ": " + e); eventHandler.handle(Event.warn(e.getMessage() + "... temporarily falling back to manually " @@ -132,7 +132,7 @@ public final class DiffAwarenessManager { * current one, or otherwise {@code null} if no factory could make a fresh one. */ @Nullable - private DiffAwarenessState maybeGetDiffAwarenessState(Path pathEntry) { + private DiffAwarenessState maybeGetDiffAwarenessState(Root pathEntry) { DiffAwarenessState diffAwarenessState = currentDiffAwarenessStates.get(pathEntry); if (diffAwarenessState != null) { return diffAwarenessState; @@ -153,15 +153,15 @@ public final class DiffAwarenessManager { private class ProcessableModifiedFileSetImpl implements ProcessableModifiedFileSet { private final ModifiedFileSet modifiedFileSet; - private final Path pathEntry; + private final Root pathEntry; /** * The {@link View} that should be the baseline on the next {@link #getDiff} call after * {@link #markProcessed} is called. */ private final View nextView; - private ProcessableModifiedFileSetImpl(ModifiedFileSet modifiedFileSet, Path pathEntry, - View nextView) { + private ProcessableModifiedFileSetImpl( + ModifiedFileSet modifiedFileSet, Root pathEntry, View nextView) { this.modifiedFileSet = modifiedFileSet; this.pathEntry = pathEntry; this.nextView = nextView; diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/DirtinessCheckerUtils.java b/src/main/java/com/google/devtools/build/lib/skyframe/DirtinessCheckerUtils.java index eae3b0ce8d..94a1a3b1d2 100644 --- a/src/main/java/com/google/devtools/build/lib/skyframe/DirtinessCheckerUtils.java +++ b/src/main/java/com/google/devtools/build/lib/skyframe/DirtinessCheckerUtils.java @@ -21,7 +21,7 @@ import com.google.common.base.Preconditions; import com.google.common.collect.ImmutableList; import com.google.devtools.build.lib.skyframe.ExternalFilesHelper.FileType; import com.google.devtools.build.lib.util.io.TimestampGranularityMonitor; -import com.google.devtools.build.lib.vfs.Path; +import com.google.devtools.build.lib.vfs.Root; import com.google.devtools.build.lib.vfs.RootedPath; import com.google.devtools.build.skyframe.SkyKey; import com.google.devtools.build.skyframe.SkyValue; @@ -92,9 +92,9 @@ public class DirtinessCheckerUtils { } static final class MissingDiffDirtinessChecker extends BasicFilesystemDirtinessChecker { - private final Set<Path> missingDiffPackageRoots; + private final Set<Root> missingDiffPackageRoots; - MissingDiffDirtinessChecker(final Set<Path> missingDiffPackageRoots) { + MissingDiffDirtinessChecker(final Set<Root> missingDiffPackageRoots) { this.missingDiffPackageRoots = missingDiffPackageRoots; } diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/EnvironmentBackedRecursivePackageProvider.java b/src/main/java/com/google/devtools/build/lib/skyframe/EnvironmentBackedRecursivePackageProvider.java index 9dc0b1c3f0..ccbc126098 100644 --- a/src/main/java/com/google/devtools/build/lib/skyframe/EnvironmentBackedRecursivePackageProvider.java +++ b/src/main/java/com/google/devtools/build/lib/skyframe/EnvironmentBackedRecursivePackageProvider.java @@ -33,6 +33,7 @@ import com.google.devtools.build.lib.pkgcache.RecursivePackageProvider; import com.google.devtools.build.lib.rules.repository.RepositoryDirectoryValue; import com.google.devtools.build.lib.vfs.Path; import com.google.devtools.build.lib.vfs.PathFragment; +import com.google.devtools.build.lib.vfs.Root; import com.google.devtools.build.lib.vfs.RootedPath; import com.google.devtools.build.skyframe.SkyFunction.Environment; import com.google.devtools.build.skyframe.SkyKey; @@ -135,7 +136,7 @@ public final class EnvironmentBackedRecursivePackageProvider implements Recursiv throw new MissingDepException(); } - List<Path> roots = new ArrayList<>(); + List<Root> roots = new ArrayList<>(); if (repository.isMain()) { roots.addAll(packageLocator.getPathEntries()); } else { @@ -149,7 +150,7 @@ public final class EnvironmentBackedRecursivePackageProvider implements Recursiv eventHandler.handle(Event.error(String.format("No such repository '%s'", repository))); return ImmutableList.of(); } - roots.add(repositoryValue.getPath()); + roots.add(Root.fromPath(repositoryValue.getPath())); } if (blacklistedSubdirectories.contains(directory)) { @@ -158,7 +159,7 @@ public final class EnvironmentBackedRecursivePackageProvider implements Recursiv PathFragment.checkAllPathsAreUnder(blacklistedSubdirectories, directory); LinkedHashSet<PathFragment> packageNames = new LinkedHashSet<>(); - for (Path root : roots) { + for (Root root : roots) { RecursivePkgValue lookup = (RecursivePkgValue) env.getValue(RecursivePkgValue.key( repository, RootedPath.toRootedPath(root, directory), blacklistedSubdirectories)); if (lookup == null) { diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/GlobDescriptor.java b/src/main/java/com/google/devtools/build/lib/skyframe/GlobDescriptor.java index e3b15f6b72..53c1aadc67 100644 --- a/src/main/java/com/google/devtools/build/lib/skyframe/GlobDescriptor.java +++ b/src/main/java/com/google/devtools/build/lib/skyframe/GlobDescriptor.java @@ -23,9 +23,8 @@ import com.google.devtools.build.lib.skyframe.serialization.ObjectCodec; import com.google.devtools.build.lib.skyframe.serialization.SerializationException; import com.google.devtools.build.lib.skyframe.serialization.strings.StringCodecs; import com.google.devtools.build.lib.util.StringCanonicalizer; -import com.google.devtools.build.lib.vfs.Path; -import com.google.devtools.build.lib.vfs.PathCodec; import com.google.devtools.build.lib.vfs.PathFragment; +import com.google.devtools.build.lib.vfs.Root; import com.google.devtools.build.skyframe.SkyFunctionName; import com.google.devtools.build.skyframe.SkyKey; import com.google.protobuf.CodedInputStream; @@ -45,8 +44,8 @@ public final class GlobDescriptor implements SkyKey { private static final Interner<GlobDescriptor> interner = BlazeInterners.newWeakInterner(); /** Creates and returns a new {@link ObjectCodec} for {@link GlobDescriptor}s. */ - public static ObjectCodec<GlobDescriptor> getCodec(PathCodec pathCodec) { - return new GlobDescriptorCodec(pathCodec); + public static ObjectCodec<GlobDescriptor> getCodec(ObjectCodec<Root> rootCodec) { + return new GlobDescriptorCodec(rootCodec); } /** @@ -55,14 +54,13 @@ public final class GlobDescriptor implements SkyKey { * @param packageId the name of the owner package (must be an existing package) * @param packageRoot the package root of {@code packageId} * @param subdir the subdirectory being looked at (must exist and must be a directory. It's - * assumed that there are no other packages between {@code packageName} and - * {@code subdir}. + * assumed that there are no other packages between {@code packageName} and {@code subdir}. * @param pattern a valid glob pattern * @param excludeDirs true if directories should be excluded from results */ public static GlobDescriptor create( PackageIdentifier packageId, - Path packageRoot, + Root packageRoot, PathFragment subdir, String pattern, boolean excludeDirs) { @@ -72,13 +70,17 @@ public final class GlobDescriptor implements SkyKey { } private final PackageIdentifier packageId; - private final Path packageRoot; + private final Root packageRoot; private final PathFragment subdir; private final String pattern; private final boolean excludeDirs; - private GlobDescriptor(PackageIdentifier packageId, Path packageRoot, PathFragment subdir, - String pattern, boolean excludeDirs) { + private GlobDescriptor( + PackageIdentifier packageId, + Root packageRoot, + PathFragment subdir, + String pattern, + boolean excludeDirs) { this.packageId = Preconditions.checkNotNull(packageId); this.packageRoot = Preconditions.checkNotNull(packageRoot); this.subdir = Preconditions.checkNotNull(subdir); @@ -102,10 +104,8 @@ public final class GlobDescriptor implements SkyKey { return packageId; } - /** - * Returns the package root of {@code getPackageId()}. - */ - public Path getPackageRoot() { + /** Returns the package root of {@code getPackageId()}. */ + public Root getPackageRoot() { return packageRoot; } @@ -168,11 +168,11 @@ public final class GlobDescriptor implements SkyKey { private static class GlobDescriptorCodec implements ObjectCodec<GlobDescriptor> { private final PackageIdentifierCodec packageIdCodec = new PackageIdentifierCodec(); - private final PathCodec pathCodec; + private final ObjectCodec<Root> rootCodec; private final ObjectCodec<String> stringCodec = StringCodecs.asciiOptimized(); - private GlobDescriptorCodec(PathCodec pathCodec) { - this.pathCodec = pathCodec; + private GlobDescriptorCodec(ObjectCodec<Root> rootCodec) { + this.rootCodec = rootCodec; } @Override @@ -184,7 +184,7 @@ public final class GlobDescriptor implements SkyKey { public void serialize(GlobDescriptor globDesc, CodedOutputStream codedOut) throws IOException, SerializationException { packageIdCodec.serialize(globDesc.getPackageId(), codedOut); - pathCodec.serialize(globDesc.getPackageRoot(), codedOut); + rootCodec.serialize(globDesc.getPackageRoot(), codedOut); PathFragment.CODEC.serialize(globDesc.getSubdir(), codedOut); stringCodec.serialize(globDesc.getPattern(), codedOut); codedOut.writeBoolNoTag(globDesc.excludeDirs()); @@ -194,7 +194,7 @@ public final class GlobDescriptor implements SkyKey { public GlobDescriptor deserialize(CodedInputStream codedIn) throws SerializationException, IOException { PackageIdentifier packageId = packageIdCodec.deserialize(codedIn); - Path packageRoot = pathCodec.deserialize(codedIn); + Root packageRoot = rootCodec.deserialize(codedIn); PathFragment pathFragment = PathFragment.CODEC.deserialize(codedIn); String pattern = stringCodec.deserialize(codedIn); boolean excludeDirs = codedIn.readBool(); diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/GlobValue.java b/src/main/java/com/google/devtools/build/lib/skyframe/GlobValue.java index eb00cb9f20..e268135627 100644 --- a/src/main/java/com/google/devtools/build/lib/skyframe/GlobValue.java +++ b/src/main/java/com/google/devtools/build/lib/skyframe/GlobValue.java @@ -20,8 +20,8 @@ import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder; import com.google.devtools.build.lib.collect.nestedset.Order; import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable; import com.google.devtools.build.lib.concurrent.ThreadSafety.ThreadSafe; -import com.google.devtools.build.lib.vfs.Path; import com.google.devtools.build.lib.vfs.PathFragment; +import com.google.devtools.build.lib.vfs.Root; import com.google.devtools.build.lib.vfs.UnixGlob; import com.google.devtools.build.skyframe.SkyKey; import com.google.devtools.build.skyframe.SkyValue; @@ -75,14 +75,19 @@ public final class GlobValue implements SkyValue { } /** - * Constructs a {@link SkyKey} for a glob lookup. {@code packageName} is assumed to be an - * existing package. Trying to glob into a non-package is undefined behavior. + * Constructs a {@link SkyKey} for a glob lookup. {@code packageName} is assumed to be an existing + * package. Trying to glob into a non-package is undefined behavior. * * @throws InvalidGlobPatternException if the pattern is not valid. */ @ThreadSafe - public static SkyKey key(PackageIdentifier packageId, Path packageRoot, String pattern, - boolean excludeDirs, PathFragment subdir) throws InvalidGlobPatternException { + public static SkyKey key( + PackageIdentifier packageId, + Root packageRoot, + String pattern, + boolean excludeDirs, + PathFragment subdir) + throws InvalidGlobPatternException { if (pattern.indexOf('?') != -1) { throw new InvalidGlobPatternException(pattern, "wildcard ? forbidden"); } @@ -101,8 +106,12 @@ public final class GlobValue implements SkyValue { * <p>Do not use outside {@code GlobFunction}. */ @ThreadSafe - static SkyKey internalKey(PackageIdentifier packageId, Path packageRoot, PathFragment subdir, - String pattern, boolean excludeDirs) { + static SkyKey internalKey( + PackageIdentifier packageId, + Root packageRoot, + PathFragment subdir, + String pattern, + boolean excludeDirs) { return GlobDescriptor.create(packageId, packageRoot, subdir, pattern, excludeDirs); } diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/GraphBackedRecursivePackageProvider.java b/src/main/java/com/google/devtools/build/lib/skyframe/GraphBackedRecursivePackageProvider.java index d7e74ffae5..f73ac247f1 100644 --- a/src/main/java/com/google/devtools/build/lib/skyframe/GraphBackedRecursivePackageProvider.java +++ b/src/main/java/com/google/devtools/build/lib/skyframe/GraphBackedRecursivePackageProvider.java @@ -43,6 +43,7 @@ import com.google.devtools.build.lib.rules.repository.RepositoryDirectoryValue; import com.google.devtools.build.lib.skyframe.TargetPatternValue.TargetPatternKey; import com.google.devtools.build.lib.vfs.Path; import com.google.devtools.build.lib.vfs.PathFragment; +import com.google.devtools.build.lib.vfs.Root; import com.google.devtools.build.lib.vfs.RootedPath; import com.google.devtools.build.skyframe.SkyKey; import com.google.devtools.build.skyframe.SkyValue; @@ -201,7 +202,7 @@ public final class GraphBackedRecursivePackageProvider implements RecursivePacka return ImmutableList.of(); } - List<Path> roots = new ArrayList<>(); + List<Root> roots = new ArrayList<>(); if (repository.isMain()) { roots.addAll(pkgPath.getPathEntries()); } else { @@ -212,14 +213,14 @@ public final class GraphBackedRecursivePackageProvider implements RecursivePacka // "nothing". return ImmutableList.of(); } - roots.add(repositoryValue.getPath()); + roots.add(Root.fromPath(repositoryValue.getPath())); } // If we found a TargetsBelowDirectory pattern in the universe that contains this directory, // then we can look for packages in and under it in the graph. If we didn't find one, then the // directory wasn't in the universe, so return an empty list. ImmutableList.Builder<PathFragment> builder = ImmutableList.builder(); - for (Path root : roots) { + for (Root root : roots) { RootedPath rootedDir = RootedPath.toRootedPath(root, directory); TraversalInfo info = new TraversalInfo(rootedDir, blacklistedSubdirectories, excludedSubdirectories); diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/LocalDiffAwareness.java b/src/main/java/com/google/devtools/build/lib/skyframe/LocalDiffAwareness.java index 897a8e0afa..76cfd37d8b 100644 --- a/src/main/java/com/google/devtools/build/lib/skyframe/LocalDiffAwareness.java +++ b/src/main/java/com/google/devtools/build/lib/skyframe/LocalDiffAwareness.java @@ -23,6 +23,7 @@ import com.google.common.collect.Iterables; import com.google.devtools.build.lib.util.OS; import com.google.devtools.build.lib.vfs.ModifiedFileSet; import com.google.devtools.build.lib.vfs.PathFragment; +import com.google.devtools.build.lib.vfs.Root; import com.google.devtools.common.options.Option; import com.google.devtools.common.options.OptionDocumentationCategory; import com.google.devtools.common.options.OptionEffectTag; @@ -73,10 +74,10 @@ public abstract class LocalDiffAwareness implements DiffAwareness { } @Override - public DiffAwareness maybeCreate(com.google.devtools.build.lib.vfs.Path pathEntry) { + public DiffAwareness maybeCreate(Root pathEntry) { com.google.devtools.build.lib.vfs.Path resolvedPathEntry; try { - resolvedPathEntry = pathEntry.resolveSymbolicLinks(); + resolvedPathEntry = pathEntry.asPath().resolveSymbolicLinks(); } catch (IOException e) { return null; } diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/MapAsPackageRoots.java b/src/main/java/com/google/devtools/build/lib/skyframe/MapAsPackageRoots.java index f4ac69ffe0..e3d2baae2f 100644 --- a/src/main/java/com/google/devtools/build/lib/skyframe/MapAsPackageRoots.java +++ b/src/main/java/com/google/devtools/build/lib/skyframe/MapAsPackageRoots.java @@ -18,7 +18,7 @@ import com.google.common.collect.ImmutableMap; import com.google.devtools.build.lib.actions.ArtifactRoot; import com.google.devtools.build.lib.actions.PackageRoots; import com.google.devtools.build.lib.cmdline.PackageIdentifier; -import com.google.devtools.build.lib.vfs.Path; +import com.google.devtools.build.lib.vfs.Root; import java.util.HashMap; import java.util.Map; import java.util.Optional; @@ -28,22 +28,22 @@ import java.util.Optional; * planted for execution. */ public class MapAsPackageRoots implements PackageRoots { - private final ImmutableMap<PackageIdentifier, Path> packageRootsMap; + private final ImmutableMap<PackageIdentifier, Root> packageRootsMap; - MapAsPackageRoots(ImmutableMap<PackageIdentifier, Path> packageRootsMap) { + MapAsPackageRoots(ImmutableMap<PackageIdentifier, Root> packageRootsMap) { this.packageRootsMap = packageRootsMap; } @Override - public Optional<ImmutableMap<PackageIdentifier, Path>> getPackageRootsMap() { + public Optional<ImmutableMap<PackageIdentifier, Root>> getPackageRootsMap() { return Optional.of(packageRootsMap); } @Override public PackageRootLookup getPackageRootLookup() { - Map<Path, ArtifactRoot> rootMap = new HashMap<>(); + Map<Root, ArtifactRoot> rootMap = new HashMap<>(); Map<PackageIdentifier, ArtifactRoot> realPackageRoots = new HashMap<>(); - for (Map.Entry<PackageIdentifier, Path> entry : packageRootsMap.entrySet()) { + for (Map.Entry<PackageIdentifier, Root> entry : packageRootsMap.entrySet()) { ArtifactRoot root = rootMap.get(entry.getValue()); if (root == null) { root = ArtifactRoot.asSourceRoot(entry.getValue()); diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/PackageFunction.java b/src/main/java/com/google/devtools/build/lib/skyframe/PackageFunction.java index b10ab4b952..6da94fd90b 100644 --- a/src/main/java/com/google/devtools/build/lib/skyframe/PackageFunction.java +++ b/src/main/java/com/google/devtools/build/lib/skyframe/PackageFunction.java @@ -60,6 +60,7 @@ import com.google.devtools.build.lib.util.Pair; import com.google.devtools.build.lib.vfs.FileSystemUtils; import com.google.devtools.build.lib.vfs.Path; import com.google.devtools.build.lib.vfs.PathFragment; +import com.google.devtools.build.lib.vfs.Root; import com.google.devtools.build.lib.vfs.RootedPath; import com.google.devtools.build.skyframe.SkyFunction; import com.google.devtools.build.skyframe.SkyFunctionException; @@ -433,7 +434,7 @@ public class PackageFunction implements SkyFunction { * @throws PackageFunctionException if there is an error computing the workspace file or adding * its rules to the //external package. */ - private SkyValue getExternalPackage(Environment env, Path packageLookupPath) + private SkyValue getExternalPackage(Environment env, Root packageLookupPath) throws PackageFunctionException, InterruptedException { SkylarkSemantics skylarkSemantics = PrecomputedValue.SKYLARK_SEMANTICS.get(env); if (skylarkSemantics == null) { @@ -808,7 +809,7 @@ public class PackageFunction implements SkyFunction { } private static void handleLabelsCrossingSubpackagesAndPropagateInconsistentFilesystemExceptions( - Path pkgRoot, PackageIdentifier pkgId, Package.Builder pkgBuilder, Environment env) + Root pkgRoot, PackageIdentifier pkgId, Package.Builder pkgBuilder, Environment env) throws InternalInconsistentFilesystemException, InterruptedException { Set<SkyKey> containingPkgLookupKeys = Sets.newHashSet(); Map<Target, SkyKey> targetToKey = new HashMap<>(); @@ -887,7 +888,10 @@ public class PackageFunction implements SkyFunction { } private static boolean maybeAddEventAboutLabelCrossingSubpackage( - Package.Builder pkgBuilder, Path pkgRoot, Label label, @Nullable Location location, + Package.Builder pkgBuilder, + Root pkgRoot, + Label label, + @Nullable Location location, @Nullable ContainingPackageLookupValue containingPkgLookupValue) { if (containingPkgLookupValue == null) { return true; @@ -914,7 +918,7 @@ public class PackageFunction implements SkyFunction { PathFragment labelNameFragment = PathFragment.create(label.getName()); String message = String.format("Label '%s' crosses boundary of subpackage '%s'", label, containingPkg); - Path containingRoot = containingPkgLookupValue.getContainingPackageRoot(); + Root containingRoot = containingPkgLookupValue.getContainingPackageRoot(); if (pkgRoot.equals(containingRoot)) { PathFragment labelNameInContainingPackage = labelNameFragment.subFragment( containingPkg.getPackageFragment().segmentCount() @@ -993,12 +997,15 @@ public class PackageFunction implements SkyFunction { */ private static class SkyframeHybridGlobber implements GlobberWithSkyframeGlobDeps { private final PackageIdentifier packageId; - private final Path packageRoot; + private final Root packageRoot; private final Environment env; private final LegacyGlobber legacyGlobber; private final Set<SkyKey> globDepsRequested = Sets.newConcurrentHashSet(); - private SkyframeHybridGlobber(PackageIdentifier packageId, Path packageRoot, Environment env, + private SkyframeHybridGlobber( + PackageIdentifier packageId, + Root packageRoot, + Environment env, LegacyGlobber legacyGlobber) { this.packageId = packageId; this.packageRoot = packageRoot; @@ -1225,7 +1232,7 @@ public class PackageFunction implements SkyFunction { private GlobberWithSkyframeGlobDeps makeGlobber( Path buildFilePath, PackageIdentifier packageId, - Path packageRoot, + Root packageRoot, SkyFunction.Environment env) { LegacyGlobber legacyGlobber = packageFactory.createLegacyGlobber( buildFilePath.getParentDirectory(), packageId, packageLocator); @@ -1243,15 +1250,14 @@ public class PackageFunction implements SkyFunction { } /** - * Constructs a {@link Package} object for the given package using legacy package loading. - * Note that the returned package may be in error. + * Constructs a {@link Package} object for the given package using legacy package loading. Note + * that the returned package may be in error. * * <p>May return null if the computation has to be restarted. * - * <p>Exactly one of {@code replacementContents} and {@code buildFileValue} will be - * non-{@code null}. The former indicates that we have a faux BUILD file with the given contents - * and the latter indicates that we have a legitimate BUILD file and should actually read its - * contents. + * <p>Exactly one of {@code replacementContents} and {@code buildFileValue} will be non-{@code + * null}. The former indicates that we have a faux BUILD file with the given contents and the + * latter indicates that we have a legitimate BUILD file and should actually read its contents. */ @Nullable private BuilderAndGlobDeps loadPackage( @@ -1263,7 +1269,7 @@ public class PackageFunction implements SkyFunction { RuleVisibility defaultVisibility, SkylarkSemantics skylarkSemantics, List<Statement> preludeStatements, - Path packageRoot, + Root packageRoot, Environment env) throws InterruptedException, PackageFunctionException { BuilderAndGlobDeps builderAndGlobDeps = packageFunctionCache.getIfPresent(packageId); diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/PackageLookupFunction.java b/src/main/java/com/google/devtools/build/lib/skyframe/PackageLookupFunction.java index 00d0c34f19..780b4d8733 100644 --- a/src/main/java/com/google/devtools/build/lib/skyframe/PackageLookupFunction.java +++ b/src/main/java/com/google/devtools/build/lib/skyframe/PackageLookupFunction.java @@ -25,8 +25,8 @@ import com.google.devtools.build.lib.packages.ErrorDeterminingRepositoryExceptio import com.google.devtools.build.lib.packages.NoSuchPackageException; import com.google.devtools.build.lib.pkgcache.PathPackageLocator; import com.google.devtools.build.lib.syntax.EvalException; -import com.google.devtools.build.lib.vfs.Path; import com.google.devtools.build.lib.vfs.PathFragment; +import com.google.devtools.build.lib.vfs.Root; import com.google.devtools.build.lib.vfs.RootedPath; import com.google.devtools.build.skyframe.SkyFunction; import com.google.devtools.build.skyframe.SkyFunctionException; @@ -120,7 +120,7 @@ public class PackageLookupFunction implements SkyFunction { // to having restart the SkyFunction after every new dependency. However, if we try to batch // the missing value keys, more dependencies than necessary will be declared. This wart can be // fixed once we have nicer continuation support [skyframe-loading] - for (Path packagePathEntry : pkgLocator.getPathEntries()) { + for (Root packagePathEntry : pkgLocator.getPathEntries()) { // This checks for the build file names in the correct precedence order. for (BuildFileName buildFileName : buildFilesByPriority) { @@ -168,7 +168,7 @@ public class PackageLookupFunction implements SkyFunction { private PackageLookupValue getPackageLookupValue( Environment env, - ImmutableList<Path> packagePathEntries, + ImmutableList<Root> packagePathEntries, PackageIdentifier packageIdentifier, BuildFileName buildFileName) throws PackageLookupFunctionException, InterruptedException { @@ -177,7 +177,7 @@ public class PackageLookupFunction implements SkyFunction { // to having restart the SkyFunction after every new dependency. However, if we try to batch // the missing value keys, more dependencies than necessary will be declared. This wart can be // fixed once we have nicer continuation support [skyframe-loading] - for (Path packagePathEntry : packagePathEntries) { + for (Root packagePathEntry : packagePathEntries) { PackageLookupValue result = getPackageLookupValue(env, packagePathEntry, packageIdentifier, buildFileName); if (result == null) { @@ -192,7 +192,7 @@ public class PackageLookupFunction implements SkyFunction { private PackageLookupValue getPackageLookupValue( Environment env, - Path packagePathEntry, + Root packagePathEntry, PackageIdentifier packageIdentifier, BuildFileName buildFileName) throws InterruptedException, PackageLookupFunctionException { @@ -235,7 +235,7 @@ public class PackageLookupFunction implements SkyFunction { if (localRepositoryPath.isAbsolute()) { // We need the package path to also be absolute. pathToRequestedPackage = - packagePathEntry.asFragment().getRelative(pathToRequestedPackage); + packagePathEntry.getRelative(pathToRequestedPackage).asFragment(); } PathFragment remainingPath = pathToRequestedPackage.relativeTo(localRepositoryPath); PackageIdentifier correctPackage = @@ -264,7 +264,7 @@ public class PackageLookupFunction implements SkyFunction { } private PackageLookupValue computeWorkspacePackageLookupValue( - Environment env, ImmutableList<Path> packagePathEntries) + Environment env, ImmutableList<Root> packagePathEntries) throws PackageLookupFunctionException, InterruptedException { PackageLookupValue result = getPackageLookupValue( @@ -281,7 +281,7 @@ public class PackageLookupFunction implements SkyFunction { if (packagePathEntries.isEmpty()) { return PackageLookupValue.NO_BUILD_FILE_VALUE; } - Path lastPackagePath = packagePathEntries.get(packagePathEntries.size() - 1); + Root lastPackagePath = packagePathEntries.get(packagePathEntries.size() - 1); FileValue lastPackagePackagePathFileValue = getFileValue( RootedPath.toRootedPath(lastPackagePath, PathFragment.EMPTY_FRAGMENT), env, @@ -326,14 +326,14 @@ public class PackageLookupFunction implements SkyFunction { PathFragment buildFileFragment = id.getPackageFragment().getRelative(buildFileName.getFilenameFragment()); RootedPath buildFileRootedPath = - RootedPath.toRootedPath(repositoryValue.getPath(), buildFileFragment); + RootedPath.toRootedPath(Root.fromPath(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.success(Root.fromPath(repositoryValue.getPath()), buildFileName); } } diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/PackageLookupValue.java b/src/main/java/com/google/devtools/build/lib/skyframe/PackageLookupValue.java index 50bccd5343..408bc2753f 100644 --- a/src/main/java/com/google/devtools/build/lib/skyframe/PackageLookupValue.java +++ b/src/main/java/com/google/devtools/build/lib/skyframe/PackageLookupValue.java @@ -17,8 +17,8 @@ import com.google.common.base.Objects; import com.google.common.base.Preconditions; import com.google.devtools.build.lib.cmdline.PackageIdentifier; import com.google.devtools.build.lib.packages.BuildFileName; -import com.google.devtools.build.lib.vfs.Path; import com.google.devtools.build.lib.vfs.PathFragment; +import com.google.devtools.build.lib.vfs.Root; import com.google.devtools.build.lib.vfs.RootedPath; import com.google.devtools.build.skyframe.LegacySkyKey; import com.google.devtools.build.skyframe.SkyKey; @@ -61,7 +61,7 @@ public abstract class PackageLookupValue implements SkyValue { protected PackageLookupValue() { } - public static PackageLookupValue success(Path root, BuildFileName buildFileName) { + public static PackageLookupValue success(Root root, BuildFileName buildFileName) { return new SuccessfulPackageLookupValue(root, buildFileName); } @@ -75,10 +75,10 @@ public abstract class PackageLookupValue implements SkyValue { } /** - * For a successful package lookup, returns the root (package path entry) that the package - * resides in. + * For a successful package lookup, returns the root (package path entry) that the package resides + * in. */ - public abstract Path getRoot(); + public abstract Root getRoot(); /** For a successful package lookup, returns the build file name that the package uses. */ public abstract BuildFileName getBuildFileName(); @@ -120,10 +120,10 @@ public abstract class PackageLookupValue implements SkyValue { /** Successful lookup value. */ public static class SuccessfulPackageLookupValue extends PackageLookupValue { - private final Path root; + private final Root root; private final BuildFileName buildFileName; - private SuccessfulPackageLookupValue(Path root, BuildFileName buildFileName) { + private SuccessfulPackageLookupValue(Root root, BuildFileName buildFileName) { this.root = root; this.buildFileName = buildFileName; } @@ -134,7 +134,7 @@ public abstract class PackageLookupValue implements SkyValue { } @Override - public Path getRoot() { + public Root getRoot() { return root; } @@ -176,7 +176,7 @@ public abstract class PackageLookupValue implements SkyValue { } @Override - public Path getRoot() { + public Root getRoot() { throw new IllegalStateException(); } diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/PackageRootsNoSymlinkCreation.java b/src/main/java/com/google/devtools/build/lib/skyframe/PackageRootsNoSymlinkCreation.java index 16f03e715e..68dacda9b6 100644 --- a/src/main/java/com/google/devtools/build/lib/skyframe/PackageRootsNoSymlinkCreation.java +++ b/src/main/java/com/google/devtools/build/lib/skyframe/PackageRootsNoSymlinkCreation.java @@ -19,7 +19,7 @@ import com.google.common.collect.ImmutableMap; import com.google.devtools.build.lib.actions.ArtifactRoot; import com.google.devtools.build.lib.actions.PackageRoots; import com.google.devtools.build.lib.cmdline.PackageIdentifier; -import com.google.devtools.build.lib.vfs.Path; +import com.google.devtools.build.lib.vfs.Root; import java.util.Optional; /** @@ -30,12 +30,12 @@ public class PackageRootsNoSymlinkCreation implements PackageRoots { private final ArtifactRoot sourceRoot; @VisibleForTesting - public PackageRootsNoSymlinkCreation(Path sourcePath) { + public PackageRootsNoSymlinkCreation(Root sourcePath) { this.sourceRoot = ArtifactRoot.asSourceRoot(sourcePath); } @Override - public Optional<ImmutableMap<PackageIdentifier, Path>> getPackageRootsMap() { + public Optional<ImmutableMap<PackageIdentifier, Root>> getPackageRootsMap() { return Optional.empty(); } diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/PrepareDepsOfPatternFunction.java b/src/main/java/com/google/devtools/build/lib/skyframe/PrepareDepsOfPatternFunction.java index fd0f08fc44..0eab83286b 100644 --- a/src/main/java/com/google/devtools/build/lib/skyframe/PrepareDepsOfPatternFunction.java +++ b/src/main/java/com/google/devtools/build/lib/skyframe/PrepareDepsOfPatternFunction.java @@ -37,8 +37,8 @@ import com.google.devtools.build.lib.rules.repository.RepositoryDirectoryValue; import com.google.devtools.build.lib.skyframe.EnvironmentBackedRecursivePackageProvider.MissingDepException; import com.google.devtools.build.lib.util.BatchCallback; import com.google.devtools.build.lib.util.BatchCallback.NullCallback; -import com.google.devtools.build.lib.vfs.Path; import com.google.devtools.build.lib.vfs.PathFragment; +import com.google.devtools.build.lib.vfs.Root; import com.google.devtools.build.lib.vfs.RootedPath; import com.google.devtools.build.skyframe.SkyFunction; import com.google.devtools.build.skyframe.SkyFunctionException; @@ -246,7 +246,7 @@ public class PrepareDepsOfPatternFunction implements SkyFunction { Preconditions.checkArgument(excludedSubdirectories.isEmpty(), excludedSubdirectories); FilteringPolicy policy = rulesOnly ? FilteringPolicies.RULES_ONLY : FilteringPolicies.NO_FILTER; - List<Path> roots = new ArrayList<>(); + List<Root> roots = new ArrayList<>(); if (repository.isMain()) { roots.addAll(pkgPath.getPathEntries()); } else { @@ -261,10 +261,10 @@ public class PrepareDepsOfPatternFunction implements SkyFunction { // already checked for its existence. throw new IllegalStateException(String.format("No such repository '%s'", repository)); } - roots.add(repositoryValue.getPath()); + roots.add(Root.fromPath(repositoryValue.getPath())); } - for (Path root : roots) { + for (Root root : roots) { RootedPath rootedPath = RootedPath.toRootedPath(root, directoryPathFragment); env.getValues( ImmutableList.of( diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/ProcessPackageDirectory.java b/src/main/java/com/google/devtools/build/lib/skyframe/ProcessPackageDirectory.java index e46f4f2b74..d4fba1a2e3 100644 --- a/src/main/java/com/google/devtools/build/lib/skyframe/ProcessPackageDirectory.java +++ b/src/main/java/com/google/devtools/build/lib/skyframe/ProcessPackageDirectory.java @@ -25,8 +25,8 @@ import com.google.devtools.build.lib.events.EventHandler; import com.google.devtools.build.lib.packages.NoSuchPackageException; import com.google.devtools.build.lib.vfs.Dirent; import com.google.devtools.build.lib.vfs.Dirent.Type; -import com.google.devtools.build.lib.vfs.Path; import com.google.devtools.build.lib.vfs.PathFragment; +import com.google.devtools.build.lib.vfs.Root; import com.google.devtools.build.lib.vfs.RootedPath; import com.google.devtools.build.skyframe.SkyFunction; import com.google.devtools.build.skyframe.SkyKey; @@ -167,7 +167,7 @@ public class ProcessPackageDirectory { RootedPath rootedPath, RepositoryName repositoryName, Set<PathFragment> excludedPaths) { - Path root = rootedPath.getRoot(); + Root root = rootedPath.getRoot(); PathFragment rootRelativePath = rootedPath.getRelativePath(); boolean followSymlinks = shouldFollowSymlinksWhenTraversing(dirListingValue.getDirents()); List<SkyKey> childDeps = new ArrayList<>(); diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/RecursiveFilesystemTraversalFunction.java b/src/main/java/com/google/devtools/build/lib/skyframe/RecursiveFilesystemTraversalFunction.java index 5b0549f3be..d8e569eea3 100644 --- a/src/main/java/com/google/devtools/build/lib/skyframe/RecursiveFilesystemTraversalFunction.java +++ b/src/main/java/com/google/devtools/build/lib/skyframe/RecursiveFilesystemTraversalFunction.java @@ -24,8 +24,8 @@ import com.google.devtools.build.lib.skyframe.RecursiveFilesystemTraversalValue. import com.google.devtools.build.lib.skyframe.RecursiveFilesystemTraversalValue.ResolvedFileFactory; import com.google.devtools.build.lib.skyframe.RecursiveFilesystemTraversalValue.TraversalRequest; import com.google.devtools.build.lib.vfs.Dirent; -import com.google.devtools.build.lib.vfs.Path; import com.google.devtools.build.lib.vfs.PathFragment; +import com.google.devtools.build.lib.vfs.Root; import com.google.devtools.build.lib.vfs.RootedPath; import com.google.devtools.build.skyframe.SkyFunction; import com.google.devtools.build.skyframe.SkyFunctionException; @@ -308,7 +308,7 @@ public final class RecursiveFilesystemTraversalFunction implements SkyFunction { return PkgLookupResult.conflict(traversal, rootInfo); } else { // The traversal's root was a source directory and it defines a package. - Path pkgRoot = pkgLookup.getRoot(); + Root pkgRoot = pkgLookup.getRoot(); if (!pkgRoot.equals(traversal.path.getRoot())) { // However the root of this package is different from what we expected. stat() the real // BUILD file of that package. diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/RecursiveFilesystemTraversalValue.java b/src/main/java/com/google/devtools/build/lib/skyframe/RecursiveFilesystemTraversalValue.java index c37dfc41c1..d3bbc160f7 100644 --- a/src/main/java/com/google/devtools/build/lib/skyframe/RecursiveFilesystemTraversalValue.java +++ b/src/main/java/com/google/devtools/build/lib/skyframe/RecursiveFilesystemTraversalValue.java @@ -23,8 +23,8 @@ import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder; import com.google.devtools.build.lib.collect.nestedset.Order; import com.google.devtools.build.lib.skyframe.RecursiveFilesystemTraversalFunction.DanglingSymlinkException; import com.google.devtools.build.lib.skyframe.RecursiveFilesystemTraversalFunction.FileType; -import com.google.devtools.build.lib.vfs.Path; import com.google.devtools.build.lib.vfs.PathFragment; +import com.google.devtools.build.lib.vfs.Root; import com.google.devtools.build.lib.vfs.RootedPath; import com.google.devtools.build.skyframe.LegacySkyKey; import com.google.devtools.build.skyframe.SkyKey; @@ -167,7 +167,7 @@ public final class RecursiveFilesystemTraversalValue implements SkyValue { * <p>This method can be used when a package is found out to be under a different root path than * originally assumed. */ - TraversalRequest forChangedRootPath(Path newRoot) { + TraversalRequest forChangedRootPath(Root newRoot) { return duplicate(RootedPath.toRootedPath(newRoot, path.getRelativePath()), skipTestingForSubpackage); } diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/SequencedSkyframeExecutor.java b/src/main/java/com/google/devtools/build/lib/skyframe/SequencedSkyframeExecutor.java index 0313d477d8..c9f87fad3b 100644 --- a/src/main/java/com/google/devtools/build/lib/skyframe/SequencedSkyframeExecutor.java +++ b/src/main/java/com/google/devtools/build/lib/skyframe/SequencedSkyframeExecutor.java @@ -66,6 +66,7 @@ import com.google.devtools.build.lib.vfs.FileSystem; import com.google.devtools.build.lib.vfs.ModifiedFileSet; import com.google.devtools.build.lib.vfs.Path; import com.google.devtools.build.lib.vfs.PathFragment; +import com.google.devtools.build.lib.vfs.Root; import com.google.devtools.build.skyframe.BuildDriver; import com.google.devtools.build.skyframe.Differencer; import com.google.devtools.build.skyframe.InMemoryMemoizingEvaluator; @@ -312,11 +313,11 @@ public final class SequencedSkyframeExecutor extends SkyframeExecutor { } TimestampGranularityMonitor tsgm = this.tsgm.get(); modifiedFiles = 0; - Map<Path, DiffAwarenessManager.ProcessableModifiedFileSet> modifiedFilesByPathEntry = + Map<Root, DiffAwarenessManager.ProcessableModifiedFileSet> modifiedFilesByPathEntry = Maps.newHashMap(); - Set<Pair<Path, DiffAwarenessManager.ProcessableModifiedFileSet>> + Set<Pair<Root, DiffAwarenessManager.ProcessableModifiedFileSet>> pathEntriesWithoutDiffInformation = Sets.newHashSet(); - for (Path pathEntry : pkgLocator.get().getPathEntries()) { + for (Root pathEntry : pkgLocator.get().getPathEntries()) { DiffAwarenessManager.ProcessableModifiedFileSet modifiedFileSet = diffAwarenessManager.getDiff(eventHandler, pathEntry, options); if (modifiedFileSet.getModifiedFileSet().treatEverythingAsModified()) { @@ -359,10 +360,11 @@ public final class SequencedSkyframeExecutor extends SkyframeExecutor { * diff. Removes entries from the given map as they are processed. All of the files need to be * invalidated, so the map should be empty upon completion of this function. */ - private void handleDiffsWithCompleteDiffInformation(TimestampGranularityMonitor tsgm, - Map<Path, DiffAwarenessManager.ProcessableModifiedFileSet> modifiedFilesByPathEntry) - throws InterruptedException { - for (Path pathEntry : ImmutableSet.copyOf(modifiedFilesByPathEntry.keySet())) { + private void handleDiffsWithCompleteDiffInformation( + TimestampGranularityMonitor tsgm, + Map<Root, DiffAwarenessManager.ProcessableModifiedFileSet> modifiedFilesByPathEntry) + throws InterruptedException { + for (Root pathEntry : ImmutableSet.copyOf(modifiedFilesByPathEntry.keySet())) { DiffAwarenessManager.ProcessableModifiedFileSet processableModifiedFileSet = modifiedFilesByPathEntry.get(pathEntry); ModifiedFileSet modifiedFileSet = processableModifiedFileSet.getModifiedFileSet(); @@ -380,7 +382,7 @@ public final class SequencedSkyframeExecutor extends SkyframeExecutor { private void handleDiffsWithMissingDiffInformation( ExtendedEventHandler eventHandler, TimestampGranularityMonitor tsgm, - Set<Pair<Path, DiffAwarenessManager.ProcessableModifiedFileSet>> + Set<Pair<Root, DiffAwarenessManager.ProcessableModifiedFileSet>> pathEntriesWithoutDiffInformation, boolean checkOutputFiles) throws InterruptedException { @@ -406,8 +408,8 @@ public final class SequencedSkyframeExecutor extends SkyframeExecutor { // system values under package roots for which we don't have diff information. If at least // one path entry doesn't have diff information, then we're going to have to iterate over // the skyframe values at least once no matter what. - Set<Path> diffPackageRootsUnderWhichToCheck = new HashSet<>(); - for (Pair<Path, DiffAwarenessManager.ProcessableModifiedFileSet> pair : + Set<Root> diffPackageRootsUnderWhichToCheck = new HashSet<>(); + for (Pair<Root, DiffAwarenessManager.ProcessableModifiedFileSet> pair : pathEntriesWithoutDiffInformation) { diffPackageRootsUnderWhichToCheck.add(pair.getFirst()); } @@ -438,7 +440,7 @@ public final class SequencedSkyframeExecutor extends SkyframeExecutor { new MissingDiffDirtinessChecker(diffPackageRootsUnderWhichToCheck))))); handleChangedFiles(diffPackageRootsUnderWhichToCheck, diff); - for (Pair<Path, DiffAwarenessManager.ProcessableModifiedFileSet> pair : + for (Pair<Root, DiffAwarenessManager.ProcessableModifiedFileSet> pair : pathEntriesWithoutDiffInformation) { pair.getSecond().markProcessed(); } @@ -450,7 +452,7 @@ public final class SequencedSkyframeExecutor extends SkyframeExecutor { } private void handleChangedFiles( - Collection<Path> diffPackageRootsUnderWhichToCheck, Differencer.Diff diff) { + Collection<Root> diffPackageRootsUnderWhichToCheck, Differencer.Diff diff) { Collection<SkyKey> changedKeysWithoutNewValues = diff.changedKeysWithoutNewValues(); Map<SkyKey, SkyValue> changedKeysWithNewValues = diff.changedKeysWithNewValues(); @@ -467,9 +469,10 @@ public final class SequencedSkyframeExecutor extends SkyframeExecutor { private static final int MAX_NUMBER_OF_CHANGED_KEYS_TO_LOG = 10; - private static void logDiffInfo(Iterable<Path> pathEntries, - Collection<SkyKey> changedWithoutNewValue, - Map<SkyKey, ? extends SkyValue> changedWithNewValue) { + private static void logDiffInfo( + Iterable<Root> pathEntries, + Collection<SkyKey> changedWithoutNewValue, + Map<SkyKey, ? extends SkyValue> changedWithNewValue) { int numModified = changedWithNewValue.size() + changedWithoutNewValue.size(); StringBuilder result = new StringBuilder("DiffAwareness found ") .append(numModified) @@ -564,7 +567,7 @@ public final class SequencedSkyframeExecutor extends SkyframeExecutor { @Override public void invalidateFilesUnderPathForTesting( - ExtendedEventHandler eventHandler, ModifiedFileSet modifiedFileSet, Path pathEntry) + ExtendedEventHandler eventHandler, ModifiedFileSet modifiedFileSet, Root pathEntry) throws InterruptedException { if (lastAnalysisDiscarded) { // Values were cleared last build, but they couldn't be deleted because they were needed for diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/SkyframeBuildView.java b/src/main/java/com/google/devtools/build/lib/skyframe/SkyframeBuildView.java index 81159c3ce8..d724a9093a 100644 --- a/src/main/java/com/google/devtools/build/lib/skyframe/SkyframeBuildView.java +++ b/src/main/java/com/google/devtools/build/lib/skyframe/SkyframeBuildView.java @@ -64,7 +64,7 @@ import com.google.devtools.build.lib.skyframe.ConfiguredTargetFunction.Configure import com.google.devtools.build.lib.skyframe.SkyframeActionExecutor.ConflictException; import com.google.devtools.build.lib.skyframe.SkylarkImportLookupFunction.SkylarkImportFailedException; import com.google.devtools.build.lib.util.OrderedSetMultimap; -import com.google.devtools.build.lib.vfs.Path; +import com.google.devtools.build.lib.vfs.Root; import com.google.devtools.build.skyframe.CycleInfo; import com.google.devtools.build.skyframe.ErrorInfo; import com.google.devtools.build.skyframe.EvaluationProgressReceiver; @@ -216,7 +216,7 @@ public final class SkyframeBuildView { skyframeExecutor.findArtifactConflicts(); Collection<AspectValue> goodAspects = Lists.newArrayListWithCapacity(values.size()); - Path singleSourceRoot = skyframeExecutor.getForcedSingleSourceRootIfNoExecrootSymlinkCreation(); + Root singleSourceRoot = skyframeExecutor.getForcedSingleSourceRootIfNoExecrootSymlinkCreation(); NestedSetBuilder<Package> packages = singleSourceRoot == null ? NestedSetBuilder.stableOrder() : null; for (AspectValueKey aspectKey : aspectKeys) { diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/SkyframeExecutor.java b/src/main/java/com/google/devtools/build/lib/skyframe/SkyframeExecutor.java index d5519db499..29cb592369 100644 --- a/src/main/java/com/google/devtools/build/lib/skyframe/SkyframeExecutor.java +++ b/src/main/java/com/google/devtools/build/lib/skyframe/SkyframeExecutor.java @@ -130,6 +130,7 @@ import com.google.devtools.build.lib.vfs.FileSystem; import com.google.devtools.build.lib.vfs.ModifiedFileSet; import com.google.devtools.build.lib.vfs.Path; import com.google.devtools.build.lib.vfs.PathFragment; +import com.google.devtools.build.lib.vfs.Root; import com.google.devtools.build.lib.vfs.RootedPath; import com.google.devtools.build.lib.vfs.UnixGlob; import com.google.devtools.build.skyframe.BuildDriver; @@ -715,7 +716,7 @@ public abstract class SkyframeExecutor implements WalkableGraphFactory { * need to track all loaded packages. */ @Nullable - protected Path getForcedSingleSourceRootIfNoExecrootSymlinkCreation() { + protected Root getForcedSingleSourceRootIfNoExecrootSymlinkCreation() { return null; } @@ -910,7 +911,7 @@ public abstract class SkyframeExecutor implements WalkableGraphFactory { } @VisibleForTesting - ImmutableList<Path> getPathEntries() { + ImmutableList<Root> getPathEntries() { return pkgLocator.get().getPathEntries(); } @@ -923,9 +924,11 @@ public abstract class SkyframeExecutor implements WalkableGraphFactory { || (oldType.equals(Dirent.Type.SYMLINK) && newType.equals(FileStateType.SYMLINK)); } - protected Differencer.Diff getDiff(TimestampGranularityMonitor tsgm, - Iterable<PathFragment> modifiedSourceFiles, final Path pathEntry) - throws InterruptedException { + protected Differencer.Diff getDiff( + TimestampGranularityMonitor tsgm, + Iterable<PathFragment> modifiedSourceFiles, + final Root pathEntry) + throws InterruptedException { if (Iterables.isEmpty(modifiedSourceFiles)) { return new ImmutableDiff(ImmutableList.<SkyKey>of(), ImmutableMap.<SkyKey, SkyValue>of()); } @@ -1626,7 +1629,7 @@ public abstract class SkyframeExecutor implements WalkableGraphFactory { */ @VisibleForTesting public abstract void invalidateFilesUnderPathForTesting( - ExtendedEventHandler eventHandler, ModifiedFileSet modifiedFileSet, Path pathEntry) + ExtendedEventHandler eventHandler, ModifiedFileSet modifiedFileSet, Root pathEntry) throws InterruptedException; /** diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/packages/AbstractPackageLoader.java b/src/main/java/com/google/devtools/build/lib/skyframe/packages/AbstractPackageLoader.java index 7fee331968..e995c5cd4b 100644 --- a/src/main/java/com/google/devtools/build/lib/skyframe/packages/AbstractPackageLoader.java +++ b/src/main/java/com/google/devtools/build/lib/skyframe/packages/AbstractPackageLoader.java @@ -69,6 +69,7 @@ import com.google.devtools.build.lib.syntax.SkylarkSemantics; import com.google.devtools.build.lib.util.io.TimestampGranularityMonitor; import com.google.devtools.build.lib.vfs.Path; import com.google.devtools.build.lib.vfs.PathFragment; +import com.google.devtools.build.lib.vfs.Root; import com.google.devtools.build.skyframe.BuildDriver; import com.google.devtools.build.skyframe.Differencer; import com.google.devtools.build.skyframe.ErrorInfo; @@ -215,7 +216,7 @@ public abstract class AbstractPackageLoader implements PackageLoader { PathPackageLocator pkgLocator = new PathPackageLocator( null, - ImmutableList.of(workspaceDir), + ImmutableList.of(Root.fromPath(workspaceDir)), BazelSkyframeExecutorConstants.BUILD_FILES_BY_PRIORITY); this.ruleClassProvider = builder.ruleClassProvider; this.skylarkSemantics = builder.skylarkSemantics; diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/serialization/testutils/FsUtils.java b/src/main/java/com/google/devtools/build/lib/skyframe/serialization/testutils/FsUtils.java index 4a8858c194..53962ba122 100644 --- a/src/main/java/com/google/devtools/build/lib/skyframe/serialization/testutils/FsUtils.java +++ b/src/main/java/com/google/devtools/build/lib/skyframe/serialization/testutils/FsUtils.java @@ -17,6 +17,7 @@ package com.google.devtools.build.lib.skyframe.serialization.testutils; import com.google.devtools.build.lib.vfs.FileSystem; import com.google.devtools.build.lib.vfs.FileSystemProvider; import com.google.devtools.build.lib.vfs.PathFragment; +import com.google.devtools.build.lib.vfs.Root; import com.google.devtools.build.lib.vfs.RootedPath; import com.google.devtools.build.lib.vfs.inmemoryfs.InMemoryFileSystem; @@ -29,7 +30,7 @@ public class FsUtils { public static final RootedPath TEST_ROOT = RootedPath.toRootedPath( - TEST_FILESYSTEM.getPath(PathFragment.create("/anywhere/at/all")), + Root.fromPath(TEST_FILESYSTEM.getPath(PathFragment.create("/anywhere/at/all"))), PathFragment.create("all/at/anywhere")); private FsUtils() {} diff --git a/src/main/java/com/google/devtools/build/lib/vfs/FileSystem.java b/src/main/java/com/google/devtools/build/lib/vfs/FileSystem.java index e914663695..a469f20a4d 100644 --- a/src/main/java/com/google/devtools/build/lib/vfs/FileSystem.java +++ b/src/main/java/com/google/devtools/build/lib/vfs/FileSystem.java @@ -113,7 +113,9 @@ public abstract class FileSystem { } /** Lazy-initialized on first access, always use {@link FileSystem#getRootDirectory} */ - private Path rootPath; + private volatile Path rootPath; + + private volatile Root root; /** Returns filesystem-specific path factory. */ protected PathFactory getPathFactory() { @@ -159,6 +161,17 @@ public abstract class FileSystem { return rootPath; } + final Root getRoot() { + if (root == null) { + synchronized (this) { + if (root == null) { + root = new Root.PathRoot(getRootDirectory()); + } + } + } + return root; + } + /** * Returns whether or not the FileSystem supports modifications of files and file entries. * diff --git a/src/main/java/com/google/devtools/build/lib/vfs/Root.java b/src/main/java/com/google/devtools/build/lib/vfs/Root.java new file mode 100644 index 0000000000..41f65de8c9 --- /dev/null +++ b/src/main/java/com/google/devtools/build/lib/vfs/Root.java @@ -0,0 +1,179 @@ +// Copyright 2018 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.vfs; + +import com.google.common.base.Preconditions; +import com.google.devtools.build.lib.skyframe.serialization.ObjectCodec; +import com.google.devtools.build.lib.skyframe.serialization.SerializationException; +import com.google.protobuf.CodedInputStream; +import com.google.protobuf.CodedOutputStream; +import java.io.IOException; +import java.io.Serializable; + +/** + * A root path used in {@link RootedPath} and in artifact roots. + * + * <p>A typical root could be the exec path, a package root, or an output root specific to some + * configuration. + */ +public interface Root extends Comparable<Root>, Serializable { + + static ObjectCodec<Root> getCodec(PathCodec pathCodec) { + return new RootCodec(pathCodec); + } + + /** Constructs a root from a path. */ + static Root fromPath(Path path) { + return new PathRoot(path); + } + + /** Returns a root from the file system's root directory. */ + static Root fromFileSystemRoot(FileSystem fileSystem) { + return fileSystem.getRoot(); + } + + /** Returns a path by concatenating the root and the root-relative path. */ + Path getRelative(PathFragment relativePath); + + /** Returns a path by concatenating the root and the root-relative path. */ + Path getRelative(String relativePath); + + /** Returns the relative path between the root and the given path. */ + PathFragment relativize(Path path); + + @Deprecated + PathFragment relativize(PathFragment relativePath); + + /** Returns whether the given path is under this root. */ + boolean contains(Path path); + + @Deprecated + boolean contains(PathFragment relativePath); + + /** + * Returns the underlying path. Please avoid using this method. Roots may eventually not be + * directly backed by paths. + */ + Path asPath(); + + @Deprecated + boolean isRootDirectory(); + + /** Implementation of Root that is backed by a {@link Path}. */ + final class PathRoot implements Root { + private final Path path; + + PathRoot(Path path) { + this.path = path; + } + + @Override + public Path getRelative(PathFragment relativePath) { + return path.getRelative(relativePath); + } + + @Override + public Path getRelative(String relativePath) { + return path.getRelative(relativePath); + } + + @Override + public PathFragment relativize(Path path) { + return path.relativeTo(this.path); + } + + @Override + public PathFragment relativize(PathFragment relativePath) { + Preconditions.checkArgument(relativePath.isAbsolute()); + return relativePath.relativeTo(path.asFragment()); + } + + @Override + public boolean contains(Path path) { + return path.startsWith(this.path); + } + + @Override + public boolean contains(PathFragment relativePath) { + return relativePath.isAbsolute() && relativePath.startsWith(path.asFragment()); + } + + @Override + public Path asPath() { + return path; + } + + @Override + public boolean isRootDirectory() { + return path.isRootDirectory(); + } + + @Override + public String toString() { + return path.toString(); + } + + @Override + public int compareTo(Root o) { + return path.compareTo(((PathRoot) o).path); + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + PathRoot pathRoot = (PathRoot) o; + return path.equals(pathRoot.path); + } + + @Override + public int hashCode() { + return path.hashCode(); + } + } + + /** Codec to serialize {@link Root}s. */ + class RootCodec implements ObjectCodec<Root> { + private final PathCodec pathCodec; + + private RootCodec(PathCodec pathCodec) { + this.pathCodec = pathCodec; + } + + @Override + public Class<Root> getEncodedClass() { + return Root.class; + } + + @Override + public void serialize(Root obj, CodedOutputStream codedOut) + throws SerializationException, IOException { + if (obj instanceof PathRoot) { + pathCodec.serialize(((PathRoot) obj).path, codedOut); + } else { + throw new AssertionError("Unknown Root subclass: " + obj.getClass().getName()); + } + } + + @Override + public Root deserialize(CodedInputStream codedIn) throws SerializationException, IOException { + Path path = pathCodec.deserialize(codedIn); + return new PathRoot(path); + } + } +} diff --git a/src/main/java/com/google/devtools/build/lib/vfs/RootedPath.java b/src/main/java/com/google/devtools/build/lib/vfs/RootedPath.java index a704b37b73..415e0ac80d 100644 --- a/src/main/java/com/google/devtools/build/lib/vfs/RootedPath.java +++ b/src/main/java/com/google/devtools/build/lib/vfs/RootedPath.java @@ -23,25 +23,24 @@ import java.io.Serializable; import java.util.Objects; /** - * A {@link PathFragment} relative to a root, which is an absolute {@link Path}. Typically the root - * will be a package path entry. + * A {@link PathFragment} relative to a {@link Root}. Typically the root will be a package path + * entry. * - * Two {@link RootedPath}s are considered equal iff they have equal roots and equal relative paths. + * <p>Two {@link RootedPath}s are considered equal iff they have equal roots and equal relative + * paths. * - * TODO(bazel-team): refactor Artifact to use this instead of Root. - * TODO(bazel-team): use an opaque root representation so as to not expose the absolute path to - * clients via #asPath or #getRoot. + * <p>TODO(bazel-team): refactor Artifact to use this instead of Root. TODO(bazel-team): use an + * opaque root representation so as to not expose the absolute path to clients via #asPath or + * #getRoot. */ public class RootedPath implements Serializable { - private final Path root; + private final Root root; private final PathFragment relativePath; private final Path path; - /** - * Constructs a {@link RootedPath} from an absolute root path and a non-absolute relative path. - */ - private RootedPath(Path root, PathFragment relativePath) { + /** Constructs a {@link RootedPath} from a {@link Root} and path fragment relative to the root. */ + private RootedPath(Root root, PathFragment relativePath) { Preconditions.checkState(!relativePath.isAbsolute(), "relativePath: %s root: %s", relativePath, root); this.root = root; @@ -49,32 +48,29 @@ public class RootedPath implements Serializable { this.path = root.getRelative(this.relativePath); } - /** - * Returns a rooted path representing {@code relativePath} relative to {@code root}. - */ - public static RootedPath toRootedPath(Path root, PathFragment relativePath) { + /** Returns a rooted path representing {@code relativePath} relative to {@code root}. */ + public static RootedPath toRootedPath(Root root, PathFragment relativePath) { if (relativePath.isAbsolute()) { if (root.isRootDirectory()) { return new RootedPath( - root.getRelative(relativePath.windowsVolume()), relativePath.toRelative()); + Root.fromPath(root.getRelative(relativePath.windowsVolume())), + relativePath.toRelative()); } else { Preconditions.checkArgument( - relativePath.startsWith(root.asFragment()), + root.contains(relativePath), "relativePath '%s' is absolute, but it's not under root '%s'", relativePath, root); - return new RootedPath(root, relativePath.relativeTo(root.asFragment())); + return new RootedPath(root, root.relativize(relativePath)); } } else { return new RootedPath(root, relativePath); } } - /** - * Returns a rooted path representing {@code path} under the root {@code root}. - */ - public static RootedPath toRootedPath(Path root, Path path) { - Preconditions.checkState(path.startsWith(root), "path: %s root: %s", path, root); + /** Returns a rooted path representing {@code path} under the root {@code root}. */ + public static RootedPath toRootedPath(Root root, Path path) { + Preconditions.checkState(root.contains(path), "path: %s root: %s", path, root); return toRootedPath(root, path.asFragment()); } @@ -82,13 +78,13 @@ public class RootedPath implements Serializable { * Returns a rooted path representing {@code path} under one of the package roots, or under the * filesystem root if it's not under any package root. */ - public static RootedPath toRootedPathMaybeUnderRoot(Path path, Iterable<Path> packagePathRoots) { - for (Path root : packagePathRoots) { - if (path.startsWith(root)) { + public static RootedPath toRootedPathMaybeUnderRoot(Path path, Iterable<Root> packagePathRoots) { + for (Root root : packagePathRoots) { + if (root.contains(path)) { return toRootedPath(root, path); } } - return toRootedPath(path.getFileSystem().getRootDirectory(), path); + return toRootedPath(Root.fromFileSystemRoot(path.getFileSystem()), path); } public Path asPath() { @@ -99,7 +95,7 @@ public class RootedPath implements Serializable { return path; } - public Path getRoot() { + public Root getRoot() { return root; } @@ -135,11 +131,11 @@ public class RootedPath implements Serializable { /** Custom serialization for {@link RootedPath}s. */ public static class RootedPathCodec implements ObjectCodec<RootedPath> { - private final PathCodec pathCodec; + private final ObjectCodec<Root> rootCodec; /** Create an instance which will deserialize RootedPaths on {@code fileSystem}. */ public RootedPathCodec(FileSystem fileSystem) { - this.pathCodec = new PathCodec(fileSystem); + this.rootCodec = Root.getCodec(new PathCodec(fileSystem)); } @Override @@ -150,14 +146,14 @@ public class RootedPath implements Serializable { @Override public void serialize(RootedPath rootedPath, CodedOutputStream codedOut) throws IOException, SerializationException { - pathCodec.serialize(rootedPath.getRoot(), codedOut); + rootCodec.serialize(rootedPath.getRoot(), codedOut); PathFragment.CODEC.serialize(rootedPath.getRelativePath(), codedOut); } @Override public RootedPath deserialize(CodedInputStream codedIn) throws IOException, SerializationException { - Path root = pathCodec.deserialize(codedIn); + Root root = rootCodec.deserialize(codedIn); PathFragment relativePath = PathFragment.CODEC.deserialize(codedIn); return toRootedPath(root, relativePath); } |