From 9da772fa98322cd5bbb64b90bbac4ebbf40d2b6f Mon Sep 17 00:00:00 2001 From: kohsuke Date: Fri, 9 Mar 2007 06:57:24 +0000 Subject: [PATCH] supported downloading workspace and artifacts as a single zip file. git-svn-id: https://hudson.dev.java.net/svn/hudson/trunk/hudson/main@2383 71c3de6d-444a-0410-be80-ed276b4c234a --- core/src/main/java/hudson/FilePath.java | 45 +++++++++++++++++-- .../hudson/model/DirectoryBrowserSupport.java | 8 ++++ .../model/DirectoryBrowserSupport/dir.jelly | 10 +++++ 3 files changed, 60 insertions(+), 3 deletions(-) diff --git a/core/src/main/java/hudson/FilePath.java b/core/src/main/java/hudson/FilePath.java index 2f7e7ba8ec..c517b7548a 100644 --- a/core/src/main/java/hudson/FilePath.java +++ b/core/src/main/java/hudson/FilePath.java @@ -27,6 +27,8 @@ import java.io.Serializable; import java.io.Writer; import java.util.ArrayList; import java.util.List; +import java.util.zip.ZipOutputStream; +import java.util.zip.ZipEntry; import java.net.URI; /** @@ -144,6 +146,39 @@ public final class FilePath implements Serializable { return remote; } + /** + * Creates a zip file from this directory or a file and sends that to the given output stream. + */ + public void createZipArchive(OutputStream os) throws IOException, InterruptedException { + final OutputStream out = (channel!=null)?new RemoteOutputStream(os):os; + act(new FileCallable() { + private transient byte[] buf; + public Void invoke(File f, VirtualChannel channel) throws IOException { + buf = new byte[8192]; + + ZipOutputStream zip = new ZipOutputStream(out); + scan(f,zip,""); + zip.close(); + return null; + } + + private void scan(File f, ZipOutputStream zip, String path) throws IOException { + if(f.isDirectory()) { + for( File child : f.listFiles() ) + scan(child,zip,path+f.getName()+'/'); + } else { + zip.putNextEntry(new ZipEntry(path+f.getName())); + FileInputStream in = new FileInputStream(f); + int len; + while((len=in.read(buf))>0) + zip.write(buf,0,len); + in.close(); + zip.closeEntry(); + } + } + }); + } + /** * Code that gets executed on the machine where the {@link FilePath} is local. * Used to act on {@link FilePath}. @@ -260,15 +295,19 @@ public final class FilePath implements Serializable { * This method assumes that the file name is the same between local and remote. */ public String getName() { - int len = remote.length()-1; + String r = remote; + if(r.endsWith("\\") || r.endsWith("/")) + r = r.substring(0,r.length()-1); + + int len = r.length()-1; while(len>=0) { - char ch = remote.charAt(len); + char ch = r.charAt(len); if(ch=='\\' || ch=='/') break; len--; } - return remote.substring(len+1); + return r.substring(len+1); } /** diff --git a/core/src/main/java/hudson/model/DirectoryBrowserSupport.java b/core/src/main/java/hudson/model/DirectoryBrowserSupport.java index 3396254537..3664001e93 100644 --- a/core/src/main/java/hudson/model/DirectoryBrowserSupport.java +++ b/core/src/main/java/hudson/model/DirectoryBrowserSupport.java @@ -75,6 +75,13 @@ public final class DirectoryBrowserSupport { f = f.getParent(); isFingerprint = true; } + if(f.getParent().getName().equals("*zip*")) { + // the expected syntax is foo/bar/*zip*/bar.zip + // the last 'bar.zip' portion is to causes browses to set a good default file name + rsp.setContentType("application/zip"); + f.getParent().getParent().createZipArchive(rsp.getOutputStream()); + return; + } if(f.isDirectory()) { if(!req.getRequestURL().toString().endsWith("/")) { @@ -91,6 +98,7 @@ public final class DirectoryBrowserSupport { req.setAttribute("files", f.act(new ChildPathBuilder())); req.setAttribute("icon",icon); req.setAttribute("path",path); + req.setAttribute("dir",f); req.getView(this,"dir.jelly").forward(req,rsp); return; } else { diff --git a/core/src/main/resources/hudson/model/DirectoryBrowserSupport/dir.jelly b/core/src/main/resources/hudson/model/DirectoryBrowserSupport/dir.jelly index d506be035f..a2840bb49d 100644 --- a/core/src/main/resources/hudson/model/DirectoryBrowserSupport/dir.jelly +++ b/core/src/main/resources/hudson/model/DirectoryBrowserSupport/dir.jelly @@ -39,6 +39,16 @@ + + +
+ + + (all files in zip) + +
+ +