aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/main/java/com/google/devtools/build/lib/vfs/FileSystemUtils.java
diff options
context:
space:
mode:
authorGravatar Kristina Chodorow <kchodorow@google.com>2016-06-16 20:30:57 +0000
committerGravatar Yue Gan <yueg@google.com>2016-06-17 09:26:21 +0000
commitbdfd58a8ca2ed5735d6aaa5b238fb0f689515724 (patch)
treefd40061fd63c6d4403d04e94af05d16ded2cab42 /src/main/java/com/google/devtools/build/lib/vfs/FileSystemUtils.java
parent3b62451a3c9e5eba3a892473d406cd02d84db5c3 (diff)
Make the execution root match the runfiles tree structure for external repositories
One interesting side effect of how this is implemented is that for external repositories, bin/ and genfiles/ are combined. External repo output is under bazel-out/local-fastbuild/repo_name for each repo. Fixes #1262. RELNOTES[INC]: Previously, an external repository would be symlinked into the execution root at execroot/local_repo/external/remote_repo. This changes it to be at execroot/remote_repo. This may break genrules/Skylark actions that hardcode execution root paths. If this causes breakages for you, ensure that genrules are using $(location :target) to access files and Skylark rules are using http://bazel.io/docs/skylark/lib/File.html's path, dirname, etc. functions. -- MOS_MIGRATED_REVID=125095799
Diffstat (limited to 'src/main/java/com/google/devtools/build/lib/vfs/FileSystemUtils.java')
-rw-r--r--src/main/java/com/google/devtools/build/lib/vfs/FileSystemUtils.java139
1 files changed, 0 insertions, 139 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/vfs/FileSystemUtils.java b/src/main/java/com/google/devtools/build/lib/vfs/FileSystemUtils.java
index 0facfefde1..aaac85007c 100644
--- a/src/main/java/com/google/devtools/build/lib/vfs/FileSystemUtils.java
+++ b/src/main/java/com/google/devtools/build/lib/vfs/FileSystemUtils.java
@@ -16,9 +16,6 @@ package com.google.devtools.build.lib.vfs;
import static java.nio.charset.StandardCharsets.ISO_8859_1;
import com.google.common.base.Predicate;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.Maps;
-import com.google.common.collect.Sets;
import com.google.common.io.ByteSink;
import com.google.common.io.ByteSource;
import com.google.common.io.ByteStreams;
@@ -35,10 +32,6 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.logging.Level;
-import java.util.logging.Logger;
/**
* Helper functions that implement often-used complex operations on file
@@ -47,9 +40,6 @@ import java.util.logging.Logger;
@ConditionallyThreadSafe // ThreadSafe except for deleteTree.
public class FileSystemUtils {
- static final Logger LOG = Logger.getLogger(FileSystemUtils.class.getName());
- static final boolean LOG_FINER = LOG.isLoggable(Level.FINER);
-
private FileSystemUtils() {}
/****************************************************************************
@@ -137,21 +127,6 @@ public class FileSystemUtils {
}
/**
- * Returns the longest prefix from a given set of 'prefixes' that are
- * contained in 'path'. I.e the closest ancestor directory containing path.
- * Returns null if none found.
- */
- static PathFragment longestPathPrefix(PathFragment path, Set<PathFragment> prefixes) {
- for (int i = path.segmentCount(); i >= 0; i--) {
- PathFragment prefix = path.subFragment(0, i);
- if (prefixes.contains(prefix)) {
- return prefix;
- }
- }
- return null;
- }
-
- /**
* Removes the shortest suffix beginning with '.' from the basename of the
* filename string. If the basename contains no '.', the filename is returned
* unchanged.
@@ -676,120 +651,6 @@ public class FileSystemUtils {
return true;
}
- /**
- * Takes a map of directory fragments to root paths, and creates a symlink
- * forest under an existing linkRoot to the corresponding source dirs or
- * files. Symlink are made at the highest dir possible, linking files directly
- * only when needed with nested packages.
- */
- public static void plantLinkForest(ImmutableMap<PathFragment, Path> packageRootMap,
- Path linkRoot, String productName)
- throws IOException {
- Path emptyPackagePath = null;
-
- // 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<PathFragment, Set<Path>> dirRootsMap = Maps.newTreeMap();
- for (Map.Entry<PathFragment, Path> entry : packageRootMap.entrySet()) {
- PathFragment pkgDir = entry.getKey();
- Path pkgRoot = entry.getValue();
- if (pkgDir.segmentCount() == 0) {
- emptyPackagePath = entry.getValue();
- }
- for (int i = 1; i <= pkgDir.segmentCount(); i++) {
- PathFragment dir = pkgDir.subFragment(0, i);
- Set<Path> roots = dirRootsMap.get(dir);
- if (roots == null) {
- roots = Sets.newHashSet();
- dirRootsMap.put(dir, roots);
- }
- roots.add(pkgRoot);
- }
- }
- // Now add in roots for all non-pkg dirs that are in between two packages, and missed above.
- for (Map.Entry<PathFragment, Set<Path>> entry : dirRootsMap.entrySet()) {
- PathFragment dir = entry.getKey();
- if (!packageRootMap.containsKey(dir)) {
- PathFragment pkgDir = longestPathPrefix(dir, packageRootMap.keySet());
- if (pkgDir != null) {
- entry.getValue().add(packageRootMap.get(pkgDir));
- }
- }
- }
- // Create output dirs for all dirs that have more than one root and need to be split.
- for (Map.Entry<PathFragment, Set<Path>> entry : dirRootsMap.entrySet()) {
- PathFragment dir = entry.getKey();
- if (entry.getValue().size() > 1) {
- if (LOG_FINER) {
- LOG.finer("mkdir " + linkRoot.getRelative(dir));
- }
- createDirectoryAndParents(linkRoot.getRelative(dir));
- }
- }
- // Make dir links for single rooted dirs.
- for (Map.Entry<PathFragment, Set<Path>> entry : dirRootsMap.entrySet()) {
- PathFragment dir = entry.getKey();
- Set<Path> roots = entry.getValue();
- // Simple case of one root for this dir.
- if (roots.size() == 1) {
- if (dir.segmentCount() > 1 && dirRootsMap.get(dir.getParentDirectory()).size() == 1) {
- 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
- if (LOG_FINER) {
- LOG.finer("ln -s " + root.getRelative(dir) + " " + linkRoot.getRelative(dir));
- }
- linkRoot.getRelative(dir).createSymbolicLink(root.getRelative(dir));
- }
- }
- // Make links for dirs within packages, skip parent-only dirs.
- for (Map.Entry<PathFragment, Set<Path>> entry : dirRootsMap.entrySet()) {
- PathFragment dir = entry.getKey();
- if (entry.getValue().size() > 1) {
- // If this dir is at or below a package dir, link in its contents.
- PathFragment pkgDir = longestPathPrefix(dir, packageRootMap.keySet());
- if (pkgDir != null) {
- Path root = packageRootMap.get(pkgDir);
- try {
- Path absdir = root.getRelative(dir);
- if (absdir.isDirectory()) {
- if (LOG_FINER) {
- LOG.finer("ln -s " + absdir + "/* " + linkRoot.getRelative(dir) + "/");
- }
- for (Path target : absdir.getDirectoryEntries()) {
- PathFragment p = target.relativeTo(root);
- if (!dirRootsMap.containsKey(p)) {
- //LOG.finest("ln -s " + target + " " + linkRoot.getRelative(p));
- linkRoot.getRelative(p).createSymbolicLink(target);
- }
- }
- } else {
- LOG.fine("Symlink planting skipping dir '" + absdir + "'");
- }
- } catch (IOException e) {
- e.printStackTrace();
- }
- // Otherwise its just an otherwise empty common parent dir.
- }
- }
- }
-
- if (emptyPackagePath != null) {
- // For the top-level directory, generate symlinks to everything in the directory instead of
- // the directory itself.
- for (Path target : emptyPackagePath.getDirectoryEntries()) {
- String baseName = target.getBaseName();
- // Create any links that don't exist yet and don't start with bazel-.
- if (!baseName.startsWith(productName + "-")
- && !linkRoot.getRelative(baseName).exists()) {
- linkRoot.getRelative(baseName).createSymbolicLink(target);
- }
- }
- }
- }
-
/****************************************************************************
* Whole-file I/O utilities for characters and bytes. These convenience
* methods are not efficient and should not be used for large amounts of data!