Pick default archive format based on filename suffix
Introduce a setFilename() method for ArchiveCommand so callers can specify the intended filename of the produced archive. If the filename ends with .tar, the format will default to tar; if .zip, zip; if .tar.gz, gzip-compressed tar; and so on. This doesn't affect "jgit archive" because it doesn't support the --output=<file> option yet. A later patch might do that. Change-Id: Ic0236a70f7aa7f2271c3ef11083b21ee986b4df5
This commit is contained in:
parent
ebfe85d037
commit
56cb2d925c
|
@ -44,6 +44,9 @@
|
|||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.commons.compress.archivers.ArchiveOutputStream;
|
||||
import org.apache.commons.compress.archivers.tar.TarArchiveEntry;
|
||||
|
@ -57,6 +60,9 @@
|
|||
* Unix TAR format (ustar + some PAX extensions).
|
||||
*/
|
||||
public class TarFormat implements ArchiveCommand.Format<ArchiveOutputStream> {
|
||||
private static final List<String> SUFFIXES =
|
||||
Collections.unmodifiableList(Arrays.asList(".tar"));
|
||||
|
||||
public ArchiveOutputStream createArchiveOutputStream(OutputStream s) {
|
||||
TarArchiveOutputStream out = new TarArchiveOutputStream(s, "UTF-8"); //$NON-NLS-1$
|
||||
out.setLongFileMode(TarArchiveOutputStream.LONGFILE_POSIX);
|
||||
|
@ -90,4 +96,8 @@ public void putEntry(ArchiveOutputStream out,
|
|||
loader.copyTo(out);
|
||||
out.closeArchiveEntry();
|
||||
}
|
||||
|
||||
public Iterable<String> suffixes() {
|
||||
return SUFFIXES;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -44,6 +44,9 @@
|
|||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.commons.compress.archivers.ArchiveOutputStream;
|
||||
import org.apache.commons.compress.compressors.bzip2.BZip2CompressorOutputStream;
|
||||
|
@ -55,6 +58,10 @@
|
|||
* bzip2-compressed tarball (tar.bz2) format.
|
||||
*/
|
||||
public class Tbz2Format implements ArchiveCommand.Format<ArchiveOutputStream> {
|
||||
private static final List<String> SUFFIXES =
|
||||
Collections.unmodifiableList(Arrays.asList(
|
||||
".tar.bz2", ".tbz", ".tbz2"));
|
||||
|
||||
private final ArchiveCommand.Format<ArchiveOutputStream> tarFormat = new TarFormat();
|
||||
|
||||
public ArchiveOutputStream createArchiveOutputStream(OutputStream s)
|
||||
|
@ -68,4 +75,8 @@ public void putEntry(ArchiveOutputStream out,
|
|||
throws IOException {
|
||||
tarFormat.putEntry(out, path, mode, loader);
|
||||
}
|
||||
|
||||
public Iterable<String> suffixes() {
|
||||
return SUFFIXES;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -44,6 +44,9 @@
|
|||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.commons.compress.archivers.ArchiveOutputStream;
|
||||
import org.apache.commons.compress.compressors.gzip.GzipCompressorOutputStream;
|
||||
|
@ -55,6 +58,10 @@
|
|||
* gzip-compressed tarball (tar.gz) format.
|
||||
*/
|
||||
public class TgzFormat implements ArchiveCommand.Format<ArchiveOutputStream> {
|
||||
private static final List<String> SUFFIXES =
|
||||
Collections.unmodifiableList(Arrays.asList(
|
||||
".tar.gz", ".tgz"));
|
||||
|
||||
private final ArchiveCommand.Format<ArchiveOutputStream> tarFormat = new TarFormat();
|
||||
|
||||
public ArchiveOutputStream createArchiveOutputStream(OutputStream s)
|
||||
|
@ -68,4 +75,8 @@ public void putEntry(ArchiveOutputStream out,
|
|||
throws IOException {
|
||||
tarFormat.putEntry(out, path, mode, loader);
|
||||
}
|
||||
|
||||
public Iterable<String> suffixes() {
|
||||
return SUFFIXES;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -44,6 +44,9 @@
|
|||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.commons.compress.archivers.ArchiveOutputStream;
|
||||
import org.apache.commons.compress.compressors.xz.XZCompressorOutputStream;
|
||||
|
@ -55,6 +58,10 @@
|
|||
* Xz-compressed tar (tar.xz) format.
|
||||
*/
|
||||
public class TxzFormat implements ArchiveCommand.Format<ArchiveOutputStream> {
|
||||
private static final List<String> SUFFIXES =
|
||||
Collections.unmodifiableList(Arrays.asList(
|
||||
".tar.xz", ".txz"));
|
||||
|
||||
private final ArchiveCommand.Format<ArchiveOutputStream> tarFormat = new TarFormat();
|
||||
|
||||
public ArchiveOutputStream createArchiveOutputStream(OutputStream s)
|
||||
|
@ -68,4 +75,8 @@ public void putEntry(ArchiveOutputStream out,
|
|||
throws IOException {
|
||||
tarFormat.putEntry(out, path, mode, loader);
|
||||
}
|
||||
|
||||
public Iterable<String> suffixes() {
|
||||
return SUFFIXES;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -44,6 +44,9 @@
|
|||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.commons.compress.archivers.ArchiveOutputStream;
|
||||
import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
|
||||
|
@ -56,6 +59,9 @@
|
|||
* PKWARE's ZIP format.
|
||||
*/
|
||||
public class ZipFormat implements ArchiveCommand.Format<ArchiveOutputStream> {
|
||||
private static final List<String> SUFFIXES =
|
||||
Collections.unmodifiableList(Arrays.asList(".zip"));
|
||||
|
||||
public ArchiveOutputStream createArchiveOutputStream(OutputStream s) {
|
||||
return new ZipArchiveOutputStream(s);
|
||||
}
|
||||
|
@ -79,4 +85,8 @@ public void putEntry(ArchiveOutputStream out,
|
|||
loader.copyTo(out);
|
||||
out.closeArchiveEntry();
|
||||
}
|
||||
|
||||
public Iterable<String> suffixes() {
|
||||
return SUFFIXES;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -46,6 +46,8 @@
|
|||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.text.MessageFormat;
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
|
||||
|
@ -151,6 +153,18 @@ public static interface Format<T extends Closeable> {
|
|||
*/
|
||||
void putEntry(T out, String path, FileMode mode,
|
||||
ObjectLoader loader) throws IOException;
|
||||
|
||||
/**
|
||||
* Filename suffixes representing this format (e.g.,
|
||||
* { ".tar.gz", ".tgz" }).
|
||||
*
|
||||
* The behavior is undefined when suffixes overlap (if
|
||||
* one format claims suffix ".7z", no other format should
|
||||
* take ".tar.7z").
|
||||
*
|
||||
* @return this format's suffixes
|
||||
*/
|
||||
Iterable<String> suffixes();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -199,6 +213,8 @@ public String getFormat() {
|
|||
* An archival format with that name was already registered.
|
||||
*/
|
||||
public static void registerFormat(String name, Format<?> fmt) {
|
||||
// TODO(jrn): Check that suffixes don't overlap.
|
||||
|
||||
if (formats.putIfAbsent(name, fmt) != null)
|
||||
throw new JGitInternalException(MessageFormat.format(
|
||||
JGitText.get().archiveFormatAlreadyRegistered,
|
||||
|
@ -220,6 +236,16 @@ public static void unregisterFormat(String name) {
|
|||
name));
|
||||
}
|
||||
|
||||
private static Format<?> formatBySuffix(String filenameSuffix)
|
||||
throws UnsupportedFormatException {
|
||||
if (filenameSuffix != null)
|
||||
for (Format<?> fmt : formats.values())
|
||||
for (String sfx : fmt.suffixes())
|
||||
if (filenameSuffix.endsWith(sfx))
|
||||
return fmt;
|
||||
return lookupFormat("tar");
|
||||
}
|
||||
|
||||
private static Format<?> lookupFormat(String formatName) throws UnsupportedFormatException {
|
||||
Format<?> fmt = formats.get(formatName);
|
||||
if (fmt == null)
|
||||
|
@ -229,7 +255,10 @@ private static Format<?> lookupFormat(String formatName) throws UnsupportedForma
|
|||
|
||||
private OutputStream out;
|
||||
private ObjectId tree;
|
||||
private String format = "tar";
|
||||
private String format;
|
||||
|
||||
/** Filename suffix, for automatically choosing a format. */
|
||||
private String suffix;
|
||||
|
||||
/**
|
||||
* @param repo
|
||||
|
@ -282,7 +311,11 @@ private <T extends Closeable> OutputStream writeArchive(Format<T> fmt) {
|
|||
public OutputStream call() throws GitAPIException {
|
||||
checkCallable();
|
||||
|
||||
final Format<?> fmt = lookupFormat(format);
|
||||
final Format<?> fmt;
|
||||
if (format == null)
|
||||
fmt = formatBySuffix(suffix);
|
||||
else
|
||||
fmt = lookupFormat(format);
|
||||
return writeArchive(fmt);
|
||||
}
|
||||
|
||||
|
@ -300,6 +333,26 @@ public ArchiveCommand setTree(ObjectId tree) {
|
|||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the intended filename for the produced archive.
|
||||
* Currently the only effect is to determine the default
|
||||
* archive format when none is specified with
|
||||
* {@link #setFormat(String)}.
|
||||
*
|
||||
* @param filename
|
||||
* intended filename for the archive
|
||||
*/
|
||||
public ArchiveCommand setFilename(String filename) {
|
||||
int slash = filename.lastIndexOf('/');
|
||||
int dot = filename.indexOf('.', slash + 1);
|
||||
|
||||
if (dot == -1)
|
||||
this.suffix = "";
|
||||
else
|
||||
this.suffix = filename.substring(dot);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param out
|
||||
* the stream to which to write the archive
|
||||
|
@ -312,7 +365,9 @@ public ArchiveCommand setOutputStream(OutputStream out) {
|
|||
|
||||
/**
|
||||
* @param fmt
|
||||
* archive format (e.g., "tar" or "zip")
|
||||
* archive format (e.g., "tar" or "zip").
|
||||
* null means to choose automatically based on
|
||||
* the archive filename.
|
||||
* @return this
|
||||
*/
|
||||
public ArchiveCommand setFormat(String fmt) {
|
||||
|
|
Loading…
Reference in New Issue