aboutsummaryrefslogtreecommitdiffstats
path: root/org.eclipse.jgit.pgm.test/tst
diff options
context:
space:
mode:
authorJonathan Nieder <jrn@google.com>2012-12-03 16:08:04 -0800
committerJonathan Nieder <jrn@google.com>2012-12-04 15:37:42 -0800
commit78009782cdabdba42841f2a71fbd5867f2ae683f (patch)
treea17f08bb0f076ba41fd019b731083ea7e4a5ae60 /org.eclipse.jgit.pgm.test/tst
parent345ab401ce27e9d4cb4002edd7f8e732b5e2e6fc (diff)
downloadjgit-78009782cdabdba42841f2a71fbd5867f2ae683f.tar.gz
jgit-78009782cdabdba42841f2a71fbd5867f2ae683f.zip
archive: Add tar support
Unlike ZIP files, tar files do not treat symlinks as ordinary files with a different mode, so tar support involves a little more code than would be ideal. Change-Id: Ica2568f4a0e443bf4b955ef0c029bc8eec62d369
Diffstat (limited to 'org.eclipse.jgit.pgm.test/tst')
-rw-r--r--org.eclipse.jgit.pgm.test/tst/org/eclipse/jgit/pgm/ArchiveTest.java167
1 files changed, 160 insertions, 7 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 cad379774e..bcf2728524 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
@@ -53,11 +53,15 @@ import java.io.FileOutputStream;
import java.io.InputStreamReader;
import java.io.IOException;
import java.io.OutputStream;
-
+import java.lang.Object;
import java.lang.String;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
+import java.util.concurrent.Callable;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Future;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
@@ -92,6 +96,13 @@ public class ArchiveTest extends CLIRepositoryTestCase {
}
@Test
+ public void testEmptyTar() throws Exception {
+ final byte[] result = CLIGitCommand.rawExecute( //
+ "git archive --format=tar " + emptyTree, db);
+ assertArrayEquals(new String[0], listTarEntries(result));
+ }
+
+ @Test
public void testArchiveWithFiles() throws Exception {
writeTrashFile("a", "a file with content!");
writeTrashFile("c", ""); // empty file
@@ -133,6 +144,32 @@ public class ArchiveTest extends CLIRepositoryTestCase {
}
@Test
+ public void testTarWithSubdir() throws Exception {
+ writeTrashFile("a", "a file with content!");
+ writeTrashFile("b.c", "before subdir in git sort order");
+ writeTrashFile("b0c", "after subdir in git sort order");
+ writeTrashFile("c", "");
+ git.add().addFilepattern("a").call();
+ git.add().addFilepattern("b.c").call();
+ git.add().addFilepattern("b0c").call();
+ git.add().addFilepattern("c").call();
+ git.commit().setMessage("populate toplevel").call();
+ writeTrashFile("b/b", "file in subdirectory");
+ writeTrashFile("b/a", "another file in subdirectory");
+ git.add().addFilepattern("b").call();
+ git.commit().setMessage("add subdir").call();
+
+ final byte[] result = CLIGitCommand.rawExecute( //
+ "git archive --format=tar master", db);
+ String[] expect = { "a", "b.c", "b0c", "b/a", "b/b", "c" };
+ String[] actual = listTarEntries(result);
+
+ Arrays.sort(expect);
+ Arrays.sort(actual);
+ assertArrayEquals(expect, actual);
+ }
+
+ @Test
public void testArchivePreservesMode() throws Exception {
writeTrashFile("plain", "a file with content");
writeTrashFile("executable", "an executable file");
@@ -159,6 +196,32 @@ public class ArchiveTest extends CLIRepositoryTestCase {
}
@Test
+ public void testTarPreservesMode() throws Exception {
+ writeTrashFile("plain", "a file with content");
+ writeTrashFile("executable", "an executable file");
+ writeTrashFile("symlink", "plain");
+ git.add().addFilepattern("plain").call();
+ git.add().addFilepattern("executable").call();
+ git.add().addFilepattern("symlink").call();
+
+ DirCache cache = db.lockDirCache();
+ cache.getEntry("executable").setFileMode(FileMode.EXECUTABLE_FILE);
+ cache.getEntry("symlink").setFileMode(FileMode.SYMLINK);
+ cache.write();
+ cache.commit();
+ cache.unlock();
+
+ git.commit().setMessage("three files with different modes").call();
+
+ final byte[] archive = CLIGitCommand.rawExecute( //
+ "git archive --format=tar master", db);
+ writeRaw("with-modes.tar", archive);
+ assertTarContainsEntry("with-modes.tar", "-rw-r--r--", "plain");
+ assertTarContainsEntry("with-modes.tar", "-rwxr-xr-x", "executable");
+ assertTarContainsEntry("with-modes.tar", "l", "symlink -> plain");
+ }
+
+ @Test
public void testArchivePreservesContent() throws Exception {
final String payload = "“The quick brown fox jumps over the lazy dog!”";
writeTrashFile("xyzzy", payload);
@@ -171,23 +234,45 @@ public class ArchiveTest extends CLIRepositoryTestCase {
zipEntryContent(result, "xyzzy"));
}
- private void assertContainsEntryWithMode(String zipFilename, String mode, String name) //
- throws Exception {
+ @Test
+ public void testTarPreservesContent() throws Exception {
+ final String payload = "“The quick brown fox jumps over the lazy dog!”";
+ writeTrashFile("xyzzy", payload);
+ git.add().addFilepattern("xyzzy").call();
+ git.commit().setMessage("add file with content").call();
+
+ final byte[] result = CLIGitCommand.rawExecute( //
+ "git archive --format=tar HEAD", db);
+ assertArrayEquals(new String[] { payload }, //
+ tarEntryContent(result, "xyzzy"));
+ }
+
+ private Process spawnAssumingCommandPresent(String... cmdline) {
final File cwd = db.getWorkTree();
- final ProcessBuilder procBuilder = new ProcessBuilder("zipinfo", zipFilename) //
+ final ProcessBuilder procBuilder = new ProcessBuilder(cmdline) //
.directory(cwd) //
.redirectErrorStream(true);
Process proc = null;
try {
proc = procBuilder.start();
} catch (IOException e) {
- // On machines without a "zipinfo" command, let the test pass.
+ // On machines without `cmdline[0]`, let the test pass.
assumeNoException(e);
}
- proc.getOutputStream().close();
- final BufferedReader reader = new BufferedReader( //
+ return proc;
+ }
+
+ private BufferedReader readFromProcess(Process proc) throws Exception {
+ return new BufferedReader( //
new InputStreamReader(proc.getInputStream(), "UTF-8"));
+ }
+
+ private void grepForEntry(String name, String mode, String... cmdline) //
+ throws Exception {
+ final Process proc = spawnAssumingCommandPresent(cmdline);
+ proc.getOutputStream().close();
+ final BufferedReader reader = readFromProcess(proc);
try {
String line;
while ((line = reader.readLine()) != null)
@@ -201,6 +286,16 @@ public class ArchiveTest extends CLIRepositoryTestCase {
}
}
+ private void assertContainsEntryWithMode(String zipFilename, String mode, String name) //
+ throws Exception {
+ grepForEntry(name, mode, "zipinfo", zipFilename);
+ }
+
+ private void assertTarContainsEntry(String tarfile, String mode, String name) //
+ throws Exception {
+ grepForEntry(name, mode, "tar", "tvf", tarfile);
+ }
+
private void writeRaw(String filename, byte[] data) //
throws IOException {
final File path = new File(db.getWorkTree(), filename);
@@ -224,6 +319,43 @@ public class ArchiveTest extends CLIRepositoryTestCase {
return l.toArray(new String[l.size()]);
}
+ private static Future<Object> writeAsync(final OutputStream stream, final byte[] data) {
+ final ExecutorService executor = Executors.newSingleThreadExecutor();
+
+ return executor.submit(new Callable<Object>() { //
+ public Object call() throws IOException {
+ try {
+ stream.write(data);
+ return null;
+ } finally {
+ stream.close();
+ }
+ }
+ });
+ }
+
+ private String[] listTarEntries(byte[] tarData) throws Exception {
+ final List<String> l = new ArrayList<String>();
+ final Process proc = spawnAssumingCommandPresent("tar", "tf", "-");
+ final BufferedReader reader = readFromProcess(proc);
+ final OutputStream out = proc.getOutputStream();
+
+ // Dump tarball to tar stdin in background
+ final Future<?> writing = writeAsync(out, tarData);
+
+ try {
+ String line;
+ while ((line = reader.readLine()) != null)
+ l.add(line);
+
+ return l.toArray(new String[l.size()]);
+ } finally {
+ writing.get();
+ reader.close();
+ proc.destroy();
+ }
+ }
+
private static String[] zipEntryContent(byte[] zipData, String path) //
throws IOException {
final ZipInputStream in = new ZipInputStream( //
@@ -246,4 +378,25 @@ public class ArchiveTest extends CLIRepositoryTestCase {
// not found
return null;
}
+
+ private String[] tarEntryContent(byte[] tarData, String path) //
+ throws Exception {
+ final List<String> l = new ArrayList<String>();
+ final Process proc = spawnAssumingCommandPresent("tar", "Oxf", "-", path);
+ final BufferedReader reader = readFromProcess(proc);
+ final OutputStream out = proc.getOutputStream();
+ final Future<?> writing = writeAsync(out, tarData);
+
+ try {
+ String line;
+ while ((line = reader.readLine()) != null)
+ l.add(line);
+
+ return l.toArray(new String[l.size()]);
+ } finally {
+ writing.get();
+ reader.close();
+ proc.destroy();
+ }
+ }
}