diff options
author | 2016-09-19 09:42:40 +0000 | |
---|---|---|
committer | 2016-09-19 13:02:15 +0000 | |
commit | 2f4d17a2fa632b05fcbeb8db5d6eb46af8ec341c (patch) | |
tree | 61966bda77c8e8e5b039adddaa9c1336251584fb /src/main/java/com/google/devtools/build/lib/vfs | |
parent | 96d396badb3a0d8caab35aa4bb181cf88700ab79 (diff) |
Also copy directories as output for sandbox.
--
MOS_MIGRATED_REVID=133564429
Diffstat (limited to 'src/main/java/com/google/devtools/build/lib/vfs')
-rw-r--r-- | src/main/java/com/google/devtools/build/lib/vfs/FileSystemUtils.java | 66 |
1 files changed, 66 insertions, 0 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 ee1af6cc97..c8d1f3c2c4 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 @@ -444,6 +444,41 @@ public class FileSystemUtils { } /** + * Moves the file from location "from" to location "to", while overwriting a + * potentially existing "to". File's last modified time, executable and + * writable bits are also preserved. + * + * <p>If no error occurs, the method returns normally. If a parent directory does + * not exist, a FileNotFoundException is thrown. An IOException is thrown when + * other erroneous situations occur. (e.g. read errors) + */ + @ThreadSafe // but not atomic + public static void moveFile(Path from, Path to) throws IOException { + long mtime = from.getLastModifiedTime(); + boolean writable = from.isWritable(); + boolean executable = from.isExecutable(); + + // We don't try-catch here for better performance. + to.delete(); + try { + from.renameTo(to); + } catch (IOException e) { + asByteSource(from).copyTo(asByteSink(to)); + if (!from.delete()) { + if (!to.delete()) { + throw new IOException("Unable to delete " + to); + } + throw new IOException("Unable to delete " + from); + } + } + to.setLastModifiedTime(mtime); // Preserve mtime. + if (!writable) { + to.setWritable(false); // Make file read-only if original was read-only. + } + to.setExecutable(executable); // Copy executable bit. + } + + /** * Copies a tool binary from one path to another, returning the target path. * The directory of the target path must already exist. The target copy's time * is set to match, as well as its read-only and executable flags. The @@ -569,6 +604,37 @@ public class FileSystemUtils { } /** + * Moves all dir trees under a given 'from' dir to location 'to', while overwriting + * all files in the potentially existing 'to'. Doesn't resolve symbolic links. + * + * <p>The source and the destination must be non-overlapping, otherwise an + * IllegalArgumentException will be thrown. This method cannot be used to copy + * a dir tree to a sub tree of itself. + * + * <p>If no error occurs, the method returns normally. If the given 'from' does + * not exist, a FileNotFoundException is thrown. An IOException is thrown when + * other erroneous situations occur. (e.g. read errors) + */ + @ThreadSafe + public static void moveTreesBelow(Path from , Path to) throws IOException { + if (to.startsWith(from)) { + throw new IllegalArgumentException(to + " is a subdirectory of " + from); + } + + Collection<Path> entries = from.getDirectoryEntries(); + for (Path entry : entries) { + if (entry.isDirectory(Symlinks.NOFOLLOW)) { + Path subDir = to.getChild(entry.getBaseName()); + subDir.createDirectory(); + moveTreesBelow(entry, subDir); + } else { + Path newEntry = to.getChild(entry.getBaseName()); + moveFile(entry, newEntry); + } + } + } + + /** * Attempts to create a directory with the name of the given path, creating * ancestors as necessary. * |