summaryrefslogtreecommitdiffstatsabout
diff options
context:
space:
mode:
authorJonathan Nieder2013-05-23 21:08:35 (EDT)
committer Jonathan Nieder2013-05-23 21:08:35 (EDT)
commitd4932620e067a19a8cc22170fd133cc53aca2ddb (patch)
treeef54dafb37197c2b8c1c5f2d61448b44a6d09d1c
parentf7157a622179b195d9f2747fe13c341d57590d3b (diff)
downloadjgit-d4932620e067a19a8cc22170fd133cc53aca2ddb.zip
jgit-d4932620e067a19a8cc22170fd133cc53aca2ddb.tar.gz
jgit-d4932620e067a19a8cc22170fd133cc53aca2ddb.tar.bz2
ArchiveCommand: make archive formats non-inner classesrefs/changes/61/12561/7
First step toward making ArchiveCommand itself format-agnostic. Change-Id: I3cff5fce28fa7a19e34f8291cfb5b62f16429713
-rw-r--r--org.eclipse.jgit.pgm.test/tst/org/eclipse/jgit/pgm/ArchiveTest.java7
-rw-r--r--org.eclipse.jgit.pgm/resources/org/eclipse/jgit/pgm/internal/CLIText.properties1
-rw-r--r--org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Archive.java5
-rw-r--r--org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/archive/ArchiveCommand.java134
-rw-r--r--org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/archive/TarFormat.java85
-rw-r--r--org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/archive/ZipFormat.java77
-rw-r--r--org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/internal/CLIText.java1
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/api/errors/GitAPIException.java12
8 files changed, 239 insertions, 83 deletions
diff --git a/org.eclipse.jgit.pgm.test/tst/org/eclipse/jgit/pgm/ArchiveTest.java b/org.eclipse.jgit.pgm.test/tst/org/eclipse/jgit/pgm/ArchiveTest.java
index bcf2728..cb2a725 100644
--- a/org.eclipse.jgit.pgm.test/tst/org/eclipse/jgit/pgm/ArchiveTest.java
+++ b/org.eclipse.jgit.pgm.test/tst/org/eclipse/jgit/pgm/ArchiveTest.java
@@ -103,6 +103,13 @@ public class ArchiveTest extends CLIRepositoryTestCase {
}
@Test
+ public void testUnrecognizedFormat() throws Exception {
+ final String[] expect = new String[] { "fatal: Unknown archive format 'nonsense'" };
+ final String[] actual = execute("git archive --format=nonsense " + emptyTree);
+ assertArrayEquals(expect, actual);
+ }
+
+ @Test
public void testArchiveWithFiles() throws Exception {
writeTrashFile("a", "a file with content!");
writeTrashFile("c", ""); // empty file
diff --git a/org.eclipse.jgit.pgm/resources/org/eclipse/jgit/pgm/internal/CLIText.properties b/org.eclipse.jgit.pgm/resources/org/eclipse/jgit/pgm/internal/CLIText.properties
index cdf7123..3fa167e 100644
--- a/org.eclipse.jgit.pgm/resources/org/eclipse/jgit/pgm/internal/CLIText.properties
+++ b/org.eclipse.jgit.pgm/resources/org/eclipse/jgit/pgm/internal/CLIText.properties
@@ -173,6 +173,7 @@ tooManyRefsGiven=Too many refs given
unknownIoErrorStdout=An unknown I/O error occurred on standard output
unknownMergeStrategy=unknown merge strategy {0} specified
unmergedPaths=Unmerged paths:
+unsupportedArchiveFormat=Unknown archive format ''{0}''
unsupportedOperation=Unsupported operation: {0}
untrackedFiles=Untracked files:
updating=Updating {0}..{1}
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Archive.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Archive.java
index 815c96b..6d4f5aa 100644
--- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Archive.java
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Archive.java
@@ -43,6 +43,7 @@
package org.eclipse.jgit.pgm;
+import org.eclipse.jgit.api.errors.GitAPIException;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.pgm.TextBuiltin;
import org.eclipse.jgit.pgm.archive.ArchiveCommand;
@@ -56,7 +57,7 @@ class Archive extends TextBuiltin {
private ObjectId tree;
@Option(name = "--format", metaVar = "metaVar_archiveFormat", usage = "usage_archiveFormat")
- private ArchiveCommand.Format format = ArchiveCommand.Format.ZIP;
+ private String format = "zip";
@Override
protected void run() throws Exception {
@@ -68,6 +69,8 @@ class Archive extends TextBuiltin {
cmd.setTree(tree)
.setFormat(format)
.setOutputStream(outs).call();
+ } catch (GitAPIException e) {
+ throw die(e.getMessage());
} finally {
cmd.release();
}
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/archive/ArchiveCommand.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/archive/ArchiveCommand.java
index 1235d0a..ff5b0d0 100644
--- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/archive/ArchiveCommand.java
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/archive/ArchiveCommand.java
@@ -44,15 +44,11 @@ package org.eclipse.jgit.pgm.archive;
import java.io.IOException;
import java.io.OutputStream;
-import java.util.EnumMap;
-import java.util.Map;
+import java.text.MessageFormat;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
import org.apache.commons.compress.archivers.ArchiveOutputStream;
-import org.apache.commons.compress.archivers.tar.TarArchiveEntry;
-import org.apache.commons.compress.archivers.tar.TarArchiveOutputStream;
-import org.apache.commons.compress.archivers.tar.TarConstants;
-import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
-import org.apache.commons.compress.archivers.zip.ZipArchiveOutputStream;
import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.api.GitCommand;
import org.eclipse.jgit.api.errors.GitAPIException;
@@ -89,7 +85,7 @@ import org.eclipse.jgit.treewalk.TreeWalk;
* <pre>
* try {
* cmd.setTree(db.resolve(&quot;master&quot;))
- * .setFormat(ArchiveCommand.Format.ZIP)
+ * .setFormat("zip")
* .setOutputStream(out).call();
* } finally {
* cmd.release();
@@ -103,91 +99,69 @@ import org.eclipse.jgit.treewalk.TreeWalk;
*/
public class ArchiveCommand extends GitCommand<OutputStream> {
/**
- * Available archival formats (corresponding to values for
- * the --format= option)
+ * Archival format.
+ *
+ * Usage:
+ * Repository repo = git.getRepository();
+ * ArchiveOutputStream out = format.createArchiveOutputStream(System.out);
+ * try {
+ * for (...) {
+ * format.putEntry(path, mode, repo.open(objectId), out);
+ * }
+ * } finally {
+ * out.close();
+ * }
*/
- public static enum Format {
- /** Zip format */
- ZIP,
-
- /** Posix TAR-format */
- TAR
- }
-
- private static interface Archiver {
+ public static interface Format {
ArchiveOutputStream createArchiveOutputStream(OutputStream s);
void putEntry(String path, FileMode mode, //
ObjectLoader loader, ArchiveOutputStream out) //
throws IOException;
}
- private static final Map<Format, Archiver> formats;
+ /**
+ * Signals an attempt to use an archival format that ArchiveCommand
+ * doesn't know about (for example due to a typo).
+ */
+ public static class UnsupportedFormatException extends GitAPIException {
+ private static final long serialVersionUID = 1L;
- static {
- Map<Format, Archiver> fmts = new EnumMap<Format, Archiver>(Format.class);
- fmts.put(Format.ZIP, new Archiver() {
- public ArchiveOutputStream createArchiveOutputStream(OutputStream s) {
- return new ZipArchiveOutputStream(s);
- }
+ private final String format;
- public void putEntry(String path, FileMode mode, //
- ObjectLoader loader, ArchiveOutputStream out) //
- throws IOException {
- final ZipArchiveEntry entry = new ZipArchiveEntry(path);
+ /**
+ * @param format the problematic format name
+ */
+ public UnsupportedFormatException(String format) {
+ super(MessageFormat.format(CLIText.get().unsupportedArchiveFormat, format));
+ this.format = format;
+ }
- if (mode == FileMode.REGULAR_FILE) {
- // ok
- } else if (mode == FileMode.EXECUTABLE_FILE
- || mode == FileMode.SYMLINK) {
- entry.setUnixMode(mode.getBits());
- } else {
- // TODO(jrn): Let the caller know the tree contained
- // an entry with unsupported mode (e.g., a submodule).
- }
- entry.setSize(loader.getSize());
- out.putArchiveEntry(entry);
- loader.copyTo(out);
- out.closeArchiveEntry();
- }
- });
- fmts.put(Format.TAR, new Archiver() {
- public ArchiveOutputStream createArchiveOutputStream(OutputStream s) {
- return new TarArchiveOutputStream(s);
- }
+ /**
+ * @return the problematic format name
+ */
+ public String getFormat() {
+ return format;
+ }
+ }
- public void putEntry(String path, FileMode mode, //
- ObjectLoader loader, ArchiveOutputStream out) //
- throws IOException {
- if (mode == FileMode.SYMLINK) {
- final TarArchiveEntry entry = new TarArchiveEntry( //
- path, TarConstants.LF_SYMLINK);
- entry.setLinkName(new String( //
- loader.getCachedBytes(100), "UTF-8")); //$NON-NLS-1$
- out.putArchiveEntry(entry);
- out.closeArchiveEntry();
- return;
- }
+ private static final ConcurrentMap<String, Format> formats =
+ new ConcurrentHashMap<String, Format>();
- final TarArchiveEntry entry = new TarArchiveEntry(path);
- if (mode == FileMode.REGULAR_FILE ||
- mode == FileMode.EXECUTABLE_FILE) {
- entry.setMode(mode.getBits());
- } else {
- // TODO(jrn): Let the caller know the tree contained
- // an entry with unsupported mode (e.g., a submodule).
- }
- entry.setSize(loader.getSize());
- out.putArchiveEntry(entry);
- loader.copyTo(out);
- out.closeArchiveEntry();
- }
- });
- formats = fmts;
+ static {
+ formats.put("zip", new ZipFormat());
+ formats.put("tar", new TarFormat());
+ }
+
+ private static Format lookupFormat(String formatName) throws UnsupportedFormatException {
+ Format fmt = formats.get(formatName);
+ if (fmt == null)
+ throw new UnsupportedFormatException(formatName);
+ return fmt;
}
private OutputStream out;
private TreeWalk walk;
- private Format format = Format.TAR;
+ private String format = "tar";
/**
* @param repo
@@ -213,7 +187,7 @@ public class ArchiveCommand extends GitCommand<OutputStream> {
@Override
public OutputStream call() throws GitAPIException {
final MutableObjectId idBuf = new MutableObjectId();
- final Archiver fmt = formats.get(format);
+ final Format fmt = lookupFormat(format);
final ArchiveOutputStream outa = fmt.createArchiveOutputStream(out);
final ObjectReader reader = walk.getObjectReader();
@@ -268,10 +242,10 @@ public class ArchiveCommand extends GitCommand<OutputStream> {
/**
* @param fmt
- * archive format (e.g., Format.TAR)
+ * archive format (e.g., "tar" or "zip")
* @return this
*/
- public ArchiveCommand setFormat(Format fmt) {
+ public ArchiveCommand setFormat(String fmt) {
this.format = fmt;
return this;
}
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/archive/TarFormat.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/archive/TarFormat.java
new file mode 100644
index 0000000..c27fb35
--- /dev/null
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/archive/TarFormat.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2012 Google Inc.
+ * and other copyright owners as documented in the project's IP log.
+ *
+ * This program and the accompanying materials are made available
+ * under the terms of the Eclipse Distribution License v1.0 which
+ * accompanies this distribution, is reproduced below, and is
+ * available at http://www.eclipse.org/org/documents/edl-v10.php
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ *
+ * - Neither the name of the Eclipse Foundation, Inc. nor the
+ * names of its contributors may be used to endorse or promote
+ * products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.eclipse.jgit.pgm.archive;
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+import org.apache.commons.compress.archivers.ArchiveOutputStream;
+import org.apache.commons.compress.archivers.tar.TarArchiveEntry;
+import org.apache.commons.compress.archivers.tar.TarArchiveOutputStream;
+import org.apache.commons.compress.archivers.tar.TarConstants;
+import org.eclipse.jgit.lib.FileMode;
+import org.eclipse.jgit.lib.ObjectLoader;
+
+class TarFormat implements ArchiveCommand.Format {
+ public ArchiveOutputStream createArchiveOutputStream(OutputStream s) {
+ return new TarArchiveOutputStream(s);
+ }
+
+ public void putEntry(String path, FileMode mode, ObjectLoader loader,
+ ArchiveOutputStream out) throws IOException {
+ if (mode == FileMode.SYMLINK) {
+ final TarArchiveEntry entry = new TarArchiveEntry(
+ path, TarConstants.LF_SYMLINK);
+ entry.setLinkName(new String(
+ loader.getCachedBytes(100), "UTF-8")); //$NON-NLS-1$
+ out.putArchiveEntry(entry);
+ out.closeArchiveEntry();
+ return;
+ }
+
+ final TarArchiveEntry entry = new TarArchiveEntry(path);
+ if (mode == FileMode.REGULAR_FILE ||
+ mode == FileMode.EXECUTABLE_FILE) {
+ entry.setMode(mode.getBits());
+ } else {
+ // TODO(jrn): Let the caller know the tree contained
+ // an entry with unsupported mode (e.g., a submodule).
+ }
+ entry.setSize(loader.getSize());
+ out.putArchiveEntry(entry);
+ loader.copyTo(out);
+ out.closeArchiveEntry();
+ }
+}
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/archive/ZipFormat.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/archive/ZipFormat.java
new file mode 100644
index 0000000..d08428f
--- /dev/null
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/archive/ZipFormat.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2012 Google Inc.
+ * and other copyright owners as documented in the project's IP log.
+ *
+ * This program and the accompanying materials are made available
+ * under the terms of the Eclipse Distribution License v1.0 which
+ * accompanies this distribution, is reproduced below, and is
+ * available at http://www.eclipse.org/org/documents/edl-v10.php
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ *
+ * - Neither the name of the Eclipse Foundation, Inc. nor the
+ * names of its contributors may be used to endorse or promote
+ * products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.eclipse.jgit.pgm.archive;
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+import org.apache.commons.compress.archivers.ArchiveOutputStream;
+import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
+import org.apache.commons.compress.archivers.zip.ZipArchiveOutputStream;
+import org.eclipse.jgit.lib.FileMode;
+import org.eclipse.jgit.lib.ObjectLoader;
+
+class ZipFormat implements ArchiveCommand.Format {
+ public ArchiveOutputStream createArchiveOutputStream(OutputStream s) {
+ return new ZipArchiveOutputStream(s);
+ }
+
+ public void putEntry(String path, FileMode mode, ObjectLoader loader,
+ ArchiveOutputStream out) throws IOException {
+ final ZipArchiveEntry entry = new ZipArchiveEntry(path);
+
+ if (mode == FileMode.REGULAR_FILE) {
+ // ok
+ } else if (mode == FileMode.EXECUTABLE_FILE
+ || mode == FileMode.SYMLINK) {
+ entry.setUnixMode(mode.getBits());
+ } else {
+ // TODO(jrn): Let the caller know the tree contained
+ // an entry with unsupported mode (e.g., a submodule).
+ }
+ entry.setSize(loader.getSize());
+ out.putArchiveEntry(entry);
+ loader.copyTo(out);
+ out.closeArchiveEntry();
+ }
+}
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/internal/CLIText.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/internal/CLIText.java
index 62865d5..937707b 100644
--- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/internal/CLIText.java
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/internal/CLIText.java
@@ -236,6 +236,7 @@ public class CLIText extends TranslationBundle {
/***/ public char[] unknownIoErrorStdout;
/***/ public String unknownMergeStrategy;
/***/ public String unmergedPaths;
+ /***/ public String unsupportedArchiveFormat;
/***/ public String unsupportedOperation;
/***/ public String untrackedFiles;
/***/ public String updating;
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/errors/GitAPIException.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/errors/GitAPIException.java
index ba38529..92599ca 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/api/errors/GitAPIException.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/errors/GitAPIException.java
@@ -45,11 +45,19 @@ package org.eclipse.jgit.api.errors;
public abstract class GitAPIException extends Exception {
private static final long serialVersionUID = 1L;
- GitAPIException(String message, Throwable cause) {
+ /**
+ * Constructs a new exception with the specified detail
+ * message and cause.
+ */
+ protected GitAPIException(String message, Throwable cause) {
super(message, cause);
}
- GitAPIException(String message) {
+ /**
+ * Constructs a new exception with the specified detail
+ * message and no cause.
+ */
+ protected GitAPIException(String message) {
super(message);
}
}