diff options
author | 2018-06-13 00:18:43 -0700 | |
---|---|---|
committer | 2018-06-13 00:20:20 -0700 | |
commit | 053bedecdbf046c385b24a22bb708f095bebfd72 (patch) | |
tree | 1bdd4627110ee4bc45b4280ebc91591448a73d01 /src/main/java/com/google/devtools/build/lib | |
parent | cb1af4ee0915fc294f61a97dc9ef84c4f246dd78 (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.java | 15 |
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. |