From 793b6826e567e20a256a6d4166031e75a185ef7a Mon Sep 17 00:00:00 2001 From: Jesse Glick Date: Wed, 9 Oct 2013 09:55:06 -0400 Subject: [PATCH] [FIXED JENKINS-19947] Restore historical undocumented behavior of a top-level entry in a ZIP. Noting that various DirScanner implementations handle this inconsistently. --- changelog.html | 3 +++ core/src/main/java/hudson/FilePath.java | 2 +- .../java/hudson/model/DirectoryBrowserSupport.java | 9 ++++++++- core/src/main/java/hudson/util/DirScanner.java | 10 +++++++++- .../java/hudson/model/DirectoryBrowserSupportTest.java | 2 +- 5 files changed, 22 insertions(+), 4 deletions(-) diff --git a/changelog.html b/changelog.html index 5ece4a56ac..e3c1b8d65d 100644 --- a/changelog.html +++ b/changelog.html @@ -58,6 +58,9 @@ Upcoming changes
  • RuntimeException if you try to save a config with a choice parameter that has no choices. (issue 18434) +
  • + 1.534 made ZIP downloads of artifacts work again, but missing a base directory inside the ZIP. + (issue 19947)
  • Upgrade Trilead SSH client library to version that does not cause connection loss when there is a lot of logging on the build slave and the performance improvements in diff --git a/core/src/main/java/hudson/FilePath.java b/core/src/main/java/hudson/FilePath.java index 15da9ead87..61bf466600 100644 --- a/core/src/main/java/hudson/FilePath.java +++ b/core/src/main/java/hudson/FilePath.java @@ -392,7 +392,7 @@ public final class FilePath implements Serializable { * * @param glob * Ant style glob, like "**/*.xml". If empty or null, this method - * works like {@link #createZipArchive(OutputStream)} + * works like {@link #createZipArchive(OutputStream)}, inserting a top-level directory into the ZIP. * * @since 1.315 */ diff --git a/core/src/main/java/hudson/model/DirectoryBrowserSupport.java b/core/src/main/java/hudson/model/DirectoryBrowserSupport.java index 09e07bed2d..7fd4dfd661 100644 --- a/core/src/main/java/hudson/model/DirectoryBrowserSupport.java +++ b/core/src/main/java/hudson/model/DirectoryBrowserSupport.java @@ -341,7 +341,14 @@ public final class DirectoryBrowserSupport implements HttpResponse { private static void zip(OutputStream outputStream, VirtualFile dir, String glob) throws IOException { ZipOutputStream zos = new ZipOutputStream(outputStream); for (String n : dir.list(glob.length() == 0 ? "**" : glob)) { - ZipEntry e = new ZipEntry(n); + String relativePath; + if (glob.length() == 0) { + // JENKINS-19947: traditional behavior is to prepend the directory name + relativePath = dir.getName() + '/' + n; + } else { + relativePath = n; + } + ZipEntry e = new ZipEntry(relativePath); VirtualFile f = dir.child(n); e.setTime(f.lastModified()); zos.putNextEntry(e); diff --git a/core/src/main/java/hudson/util/DirScanner.java b/core/src/main/java/hudson/util/DirScanner.java index 87c97fa326..a694c7c21b 100644 --- a/core/src/main/java/hudson/util/DirScanner.java +++ b/core/src/main/java/hudson/util/DirScanner.java @@ -51,6 +51,9 @@ public abstract class DirScanner implements Serializable { /** * Scans everything recursively. + *

    Note that all file paths are prefixed by the name of the root directory. + * For example, when scanning a directory {@code /tmp/dir} containing a file {@code file}, + * the {@code relativePath} sent to the {@link FileVisitor} will be {@code dir/file}. */ public static class Full extends DirScanner { private void scan(File f, String path, FileVisitor visitor) throws IOException { @@ -71,7 +74,8 @@ public abstract class DirScanner implements Serializable { } /** - * Scans by filtering things out from {@link FileFilter} + * Scans by filtering things out from {@link FileFilter}. + *

    An initial basename is prepended as with {@link Full}. */ public static class Filter extends Full { private final FileFilter filter; @@ -90,6 +94,10 @@ public abstract class DirScanner implements Serializable { /** * Scans by using Ant GLOB syntax. + *

    An initial basename is prepended as with {@link Full} if the includes and excludes are blank. + * Otherwise there is no prepended path. So for example when scanning a directory {@code /tmp/dir} containing a file {@code file}, + * the {@code relativePath} sent to the {@link FileVisitor} will be {@code dir/file} if {@code includes} is blank + * but {@code file} if it is {@code **}. (This anomaly is historical.) */ public static class Glob extends DirScanner { private final String includes, excludes; diff --git a/test/src/test/java/hudson/model/DirectoryBrowserSupportTest.java b/test/src/test/java/hudson/model/DirectoryBrowserSupportTest.java index 80b58d180c..2963d4d6df 100644 --- a/test/src/test/java/hudson/model/DirectoryBrowserSupportTest.java +++ b/test/src/test/java/hudson/model/DirectoryBrowserSupportTest.java @@ -159,7 +159,7 @@ public class DirectoryBrowserSupportTest { ZipFile readzip = new ZipFile(zipfile); - InputStream is = readzip.getInputStream(readzip.getEntry("artifact.out")); + InputStream is = readzip.getInputStream(readzip.getEntry("archive/artifact.out")); // ZipException in case of JENKINS-19752 assertFalse("Downloaded zip file must not be empty", is.read() == -1); -- GitLab