mirror of https://github.com/jenkinsci/jenkins.git
rolling back my earlier change that seems to be breaking tests. will revisit this change later
git-svn-id: https://hudson.dev.java.net/svn/hudson/trunk/hudson/main@19332 71c3de6d-444a-0410-be80-ed276b4c234a
This commit is contained in:
parent
b26cfc7b56
commit
b7a52ff7ba
|
|
@ -73,7 +73,6 @@ import java.io.OutputStream;
|
|||
import java.io.Serializable;
|
||||
import java.io.Writer;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.io.Closeable;
|
||||
import java.net.URI;
|
||||
import java.net.URL;
|
||||
import java.net.URLConnection;
|
||||
|
|
@ -247,31 +246,44 @@ public final class FilePath implements Serializable {
|
|||
* 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 {
|
||||
createZipArchive(os,(FileFilter)null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a zip file from this directory by using the specified filter,
|
||||
* and sends the result to the given output stream.
|
||||
*
|
||||
* @param filter
|
||||
* Must be serializable since it may be executed remotely. Can be null to add all files.
|
||||
*
|
||||
* @since 1.314
|
||||
*/
|
||||
public void createZipArchive(OutputStream os, final FileFilter filter) 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 {
|
||||
ZipWriter zw = new ZipWriter(out);
|
||||
try {
|
||||
accept(f,zw.with(filter));
|
||||
} finally {
|
||||
zw.close();
|
||||
}
|
||||
buf = new byte[8192];
|
||||
|
||||
ZipOutputStream zip = new ZipOutputStream(out);
|
||||
zip.setEncoding(System.getProperty("file.encoding"));
|
||||
scan(f,zip,"");
|
||||
zip.close();
|
||||
return null;
|
||||
}
|
||||
|
||||
private void scan(File f, ZipOutputStream zip, String path) throws IOException {
|
||||
// Bitmask indicating directories in 'external attributes' of a ZIP archive entry.
|
||||
final long BITMASK_IS_DIRECTORY = 1<<4;
|
||||
|
||||
if (f.canRead()) {
|
||||
if(f.isDirectory()) {
|
||||
ZipEntry dirZipEntry = new ZipEntry(path+f.getName()+'/');
|
||||
// Setting this bit explicitly is needed by some unzipping applications (see HUDSON-3294).
|
||||
dirZipEntry.setExternalAttributes(BITMASK_IS_DIRECTORY);
|
||||
zip.putNextEntry(dirZipEntry);
|
||||
zip.closeEntry();
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
});
|
||||
}
|
||||
|
|
@ -294,12 +306,24 @@ public final class FilePath implements Serializable {
|
|||
final OutputStream out = (channel!=null)?new RemoteOutputStream(os):os;
|
||||
act(new FileCallable<Void>() {
|
||||
public Void invoke(File dir, VirtualChannel channel) throws IOException {
|
||||
ZipWriter zw = new ZipWriter(out);
|
||||
try {
|
||||
accept(dir,glob,null,zw);
|
||||
} finally {
|
||||
zw.close();
|
||||
byte[] buf = new byte[8192];
|
||||
|
||||
ZipOutputStream zip = new ZipOutputStream(out);
|
||||
zip.setEncoding(System.getProperty("file.encoding"));
|
||||
for( String entry : glob(dir,glob) ) {
|
||||
File file = new File(dir,entry);
|
||||
if (file.canRead()) {
|
||||
zip.putNextEntry(new ZipEntry(dir.getName()+'/'+entry));
|
||||
FileInputStream in = new FileInputStream(file);
|
||||
int len;
|
||||
while((len=in.read(buf))>0)
|
||||
zip.write(buf,0,len);
|
||||
in.close();
|
||||
zip.closeEntry();
|
||||
}
|
||||
}
|
||||
|
||||
zip.close();
|
||||
return null;
|
||||
}
|
||||
|
||||
|
|
@ -1351,69 +1375,39 @@ public final class FilePath implements Serializable {
|
|||
}
|
||||
|
||||
/**
|
||||
* Visits files in a directory recursively.
|
||||
* Primarily used for building an archive with various filtering.
|
||||
* Writes to a tar stream and stores obtained files to the base dir.
|
||||
*
|
||||
* @return
|
||||
* number of files/directories that are written.
|
||||
*/
|
||||
private static abstract class FileVisitor {
|
||||
abstract void visit(File f, String relativePath) throws IOException;
|
||||
private Integer writeToTar(File baseDir, String fileMask, String excludes, OutputStream out) throws IOException {
|
||||
FileSet fs = Util.createFileSet(baseDir,fileMask,excludes);
|
||||
|
||||
/**
|
||||
* Decorates by a given filter.
|
||||
*/
|
||||
FileVisitor with(FileFilter f) {
|
||||
if(f==null) return this;
|
||||
return new FilterFileVisitor(f,this);
|
||||
}
|
||||
}
|
||||
byte[] buf = new byte[8192];
|
||||
|
||||
private static final class FilterFileVisitor extends FileVisitor implements Serializable {
|
||||
private final FileFilter filter;
|
||||
private final FileVisitor visitor;
|
||||
|
||||
private FilterFileVisitor(FileFilter filter, FileVisitor visitor) {
|
||||
this.filter = filter!=null ? filter : PASS_THROUGH;
|
||||
this.visitor = visitor;
|
||||
}
|
||||
|
||||
public void visit(File f, String relativePath) throws IOException {
|
||||
if(f.isDirectory() || filter.accept(f))
|
||||
visitor.visit(f,relativePath);
|
||||
}
|
||||
|
||||
private static final FileFilter PASS_THROUGH = new FileFilter() {
|
||||
public boolean accept(File pathname) {
|
||||
return true;
|
||||
TarOutputStream tar = new TarOutputStream(new BufferedOutputStream(out) {
|
||||
// TarOutputStream uses TarBuffer internally,
|
||||
// which flushes the stream for each block. this creates unnecessary
|
||||
// data stream fragmentation, and flush request to a remote, which slows things down.
|
||||
public void flush() throws IOException {
|
||||
// so don't do anything in flush
|
||||
}
|
||||
};
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@link FileVisitor} that creates a tar archive.
|
||||
*/
|
||||
private static final class TarWriter extends FileVisitor implements Closeable {
|
||||
private final byte[] buf = new byte[8192];
|
||||
private final TarOutputStream tar;
|
||||
int filesWritten=0;
|
||||
|
||||
private TarWriter(OutputStream out) {
|
||||
tar = new TarOutputStream(new BufferedOutputStream(out) {
|
||||
// TarOutputStream uses TarBuffer internally,
|
||||
// which flushes the stream for each block. this creates unnecessary
|
||||
// data stream fragmentation, and flush request to a remote, which slows things down.
|
||||
public void flush() throws IOException {
|
||||
// so don't do anything in flush
|
||||
}
|
||||
});
|
||||
tar.setLongFileMode(TarOutputStream.LONGFILE_GNU);
|
||||
});
|
||||
tar.setLongFileMode(TarOutputStream.LONGFILE_GNU);
|
||||
String[] files;
|
||||
if(baseDir.exists()) {
|
||||
DirectoryScanner ds = fs.getDirectoryScanner(new org.apache.tools.ant.Project());
|
||||
files = ds.getIncludedFiles();
|
||||
} else {
|
||||
files = new String[0];
|
||||
}
|
||||
|
||||
public void visit(File file, String relativePath) throws IOException {
|
||||
for( String f : files) {
|
||||
if(Functions.isWindows())
|
||||
relativePath = relativePath.replace('\\','/');
|
||||
f = f.replace('\\','/');
|
||||
|
||||
TarEntry te = new TarEntry(relativePath);
|
||||
File file = new File(baseDir, f);
|
||||
|
||||
TarEntry te = new TarEntry(f);
|
||||
te.setModTime(file.lastModified());
|
||||
if(!file.isDirectory())
|
||||
te.setSize(file.length());
|
||||
|
|
@ -1429,129 +1423,11 @@ public final class FilePath implements Serializable {
|
|||
}
|
||||
|
||||
tar.closeEntry();
|
||||
filesWritten++;
|
||||
}
|
||||
|
||||
public void close() throws IOException {
|
||||
tar.close();
|
||||
}
|
||||
}
|
||||
tar.close();
|
||||
|
||||
/**
|
||||
* {@link FileVisitor} that creates a zip archive.
|
||||
*/
|
||||
private static final class ZipWriter extends FileVisitor implements Closeable {
|
||||
private final byte[] buf = new byte[8192];
|
||||
private final ZipOutputStream zip;
|
||||
|
||||
private ZipWriter(OutputStream out) {
|
||||
zip = new ZipOutputStream(out);
|
||||
zip.setEncoding(System.getProperty("file.encoding"));
|
||||
}
|
||||
|
||||
public void visit(File f, String relativePath) throws IOException {
|
||||
if(f.isDirectory()) {
|
||||
ZipEntry dirZipEntry = new ZipEntry(relativePath+'/');
|
||||
// Setting this bit explicitly is needed by some unzipping applications (see HUDSON-3294).
|
||||
dirZipEntry.setExternalAttributes(BITMASK_IS_DIRECTORY);
|
||||
zip.putNextEntry(dirZipEntry);
|
||||
zip.closeEntry();
|
||||
} else {
|
||||
zip.putNextEntry(new ZipEntry(relativePath));
|
||||
FileInputStream in = new FileInputStream(f);
|
||||
int len;
|
||||
while((len=in.read(buf))>0)
|
||||
zip.write(buf,0,len);
|
||||
in.close();
|
||||
zip.closeEntry();
|
||||
}
|
||||
}
|
||||
|
||||
public void close() throws IOException {
|
||||
zip.close();
|
||||
}
|
||||
|
||||
// Bitmask indicating directories in 'external attributes' of a ZIP archive entry.
|
||||
private static final long BITMASK_IS_DIRECTORY = 1<<4;
|
||||
}
|
||||
|
||||
/**
|
||||
* Scans the given base directory with a GLOB and exclusion mask, and calls visitor.
|
||||
*/
|
||||
private void accept(File baseDir, String fileMask, String excludes, FileVisitor visitor) throws IOException {
|
||||
if(fileMask==null || excludes==null) {
|
||||
// optimization
|
||||
accept(baseDir,visitor);
|
||||
return;
|
||||
}
|
||||
|
||||
FileSet fs = Util.createFileSet(baseDir,fileMask,excludes);
|
||||
|
||||
if(baseDir.exists()) {
|
||||
DirectoryScanner ds = fs.getDirectoryScanner(new org.apache.tools.ant.Project());
|
||||
for( String f : ds.getIncludedFiles()) {
|
||||
File file = new File(baseDir, f);
|
||||
visitor.visit(file,f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Scans the given directory tree recursively and calls visitor.
|
||||
*/
|
||||
private void accept(final File baseDir, final FileVisitor visitor) throws IOException {
|
||||
class Scanner {
|
||||
public void run() throws IOException {
|
||||
scan(baseDir,"");
|
||||
}
|
||||
|
||||
private void scan(File f, String path) throws IOException {
|
||||
if (f.canRead()) {
|
||||
visitor.visit(f,path+f.getName());
|
||||
if(f.isDirectory()) {
|
||||
for( File child : f.listFiles() )
|
||||
scan(child,path+f.getName()+'/');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
new Scanner().run();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Writes files in 'this' directory to a tar stream.
|
||||
*
|
||||
* @param glob
|
||||
* Ant file pattern mask, like "**/*.java".
|
||||
*/
|
||||
public int tar(OutputStream out, final String glob) throws IOException, InterruptedException {
|
||||
final OutputStream o = new RemoteOutputStream(out);
|
||||
try {
|
||||
return act(new FileCallable<Integer>() {
|
||||
public Integer invoke(File f, VirtualChannel channel) throws IOException {
|
||||
return writeToTar(f,glob,null,o);
|
||||
}
|
||||
});
|
||||
} finally {
|
||||
out.close();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes to a tar stream and stores obtained files to the base dir.
|
||||
*
|
||||
* @return
|
||||
* number of files/directories that are written.
|
||||
*/
|
||||
private Integer writeToTar(File baseDir, String fileMask, String excludes, OutputStream out) throws IOException {
|
||||
TarWriter tw = new TarWriter(out);
|
||||
try {
|
||||
accept(baseDir,fileMask,excludes,tw);
|
||||
} finally {
|
||||
tw.close();
|
||||
}
|
||||
return tw.filesWritten;
|
||||
return files.length;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -49,6 +49,7 @@ import hudson.util.ArgumentListBuilder;
|
|||
import hudson.util.ForkOutputStream;
|
||||
import hudson.util.IOException2;
|
||||
import hudson.util.FormValidation;
|
||||
import hudson.util.AtomicFileWriter;
|
||||
import org.apache.commons.io.FileUtils;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.apache.tools.ant.BuildException;
|
||||
|
|
@ -1010,6 +1011,13 @@ public class CVSSCM extends SCM implements Serializable {
|
|||
|
||||
if(modified) {
|
||||
// write it back
|
||||
AtomicFileWriter w = new AtomicFileWriter(entries);
|
||||
try {
|
||||
w.write(newContents.toString());
|
||||
w.commit();
|
||||
} finally {
|
||||
w.abort();
|
||||
}
|
||||
File tmp = new File(f, "CVS/Entries.tmp");
|
||||
FileUtils.writeStringToFile(tmp,newContents.toString());
|
||||
entries.delete();
|
||||
|
|
|
|||
Loading…
Reference in New Issue