mirror of
https://github.com/jenkinsci/jenkins.git
synced 2026-11-06 00:25:58 +00:00
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
This commit is contained in:
1 parent
dd79c8857c
commit
9da772fa98
3 files changed
+60
-3
No files matched your search
@@ -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<Void>() {
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -39,6 +39,16 @@
|
||||
</j:if>
|
||||
</tr>
|
||||
</j:forEach>
|
||||
<tr>
|
||||
<td style="text-align:right;" colspan="3">
|
||||
<div style="margin-top: 1em;">
|
||||
<a href="*zip*/${dir.name}.zip">
|
||||
<img src="${rootURL}/images/16x16/package.gif"/>
|
||||
(all files in zip)
|
||||
</a>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</l:main-panel>
|
||||
|
||||
Reference in new issue
Block a user