aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/main/java/com/google/devtools/build/lib
diff options
context:
space:
mode:
authorGravatar pcloudy <pcloudy@google.com>2018-06-13 00:18:43 -0700
committerGravatar Copybara-Service <copybara-piper@google.com>2018-06-13 00:20:20 -0700
commit053bedecdbf046c385b24a22bb708f095bebfd72 (patch)
tree1bdd4627110ee4bc45b4280ebc91591448a73d01 /src/main/java/com/google/devtools/build/lib
parentcb1af4ee0915fc294f61a97dc9ef84c4f246dd78 (diff)
Fix archive decompression with symlink on Windows
On Windows, extracting file symlink in an archive would be performed as copy. To ensure the copy will be successful, we defer all symlink creation after all regular files are extracted. Fix https://github.com/bazelbuild/bazel/issues/5367 RELNOTES: None. PiperOrigin-RevId: 200345463
Diffstat (limited to 'src/main/java/com/google/devtools/build/lib')
-rw-r--r--src/main/java/com/google/devtools/build/lib/bazel/repository/ZipDecompressor.java15
1 files changed, 12 insertions, 3 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/bazel/repository/ZipDecompressor.java b/src/main/java/com/google/devtools/build/lib/bazel/repository/ZipDecompressor.java
index 0f32e752b0..7af6b0631b 100644
--- a/src/main/java/com/google/devtools/build/lib/bazel/repository/ZipDecompressor.java
+++ b/src/main/java/com/google/devtools/build/lib/bazel/repository/ZipDecompressor.java
@@ -32,6 +32,9 @@ import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.StandardCopyOption;
import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+
import javax.annotation.Nullable;
/**
@@ -76,13 +79,18 @@ public class ZipDecompressor implements Decompressor {
boolean foundPrefix = false;
try (ZipReader reader = new ZipReader(descriptor.archivePath().getPathFile())) {
Collection<ZipFileEntry> entries = reader.entries();
+ // Store link, target info of symlinks, we create them after regular files are extracted.
+ Map<Path, PathFragment> symlinks = new HashMap<>();
for (ZipFileEntry entry : entries) {
StripPrefixedPath entryPath = StripPrefixedPath.maybeDeprefix(entry.getName(), prefix);
foundPrefix = foundPrefix || entryPath.foundPrefix();
if (entryPath.skip()) {
continue;
}
- extractZipEntry(reader, entry, destinationDirectory, entryPath.getPathFragment());
+ extractZipEntry(reader, entry, destinationDirectory, entryPath.getPathFragment(), symlinks);
+ }
+ for (Map.Entry<Path, PathFragment> symlink : symlinks.entrySet()) {
+ symlink.getKey().createSymbolicLink(symlink.getValue());
}
} catch (IOException e) {
throw new RepositoryFunctionException(new IOException(
@@ -104,7 +112,8 @@ public class ZipDecompressor implements Decompressor {
ZipReader reader,
ZipFileEntry entry,
Path destinationDirectory,
- PathFragment strippedRelativePath)
+ PathFragment strippedRelativePath,
+ Map<Path, PathFragment> symlinks)
throws IOException {
if (strippedRelativePath.isAbsolute()) {
throw new IOException(
@@ -137,7 +146,7 @@ public class ZipDecompressor implements Decompressor {
target = target.relativeTo("/");
target = destinationDirectory.getRelative(target).asFragment();
}
- outputPath.createSymbolicLink(target);
+ symlinks.put(outputPath, target);
} else {
// TODO(kchodorow): should be able to be removed when issue #236 is resolved, but for now
// this delete+rewrite is required or the build will error out if outputPath exists here.