summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJonathan Nieder <jrn@google.com>2012-12-03 10:41:25 -0800
committerJonathan Nieder <jrn@google.com>2012-12-04 15:34:07 -0800
commit7123cbf470ea2fa39379a4d914f0933063bbbdfe (patch)
tree06201abf5ffdd5af283eec23d12983760912eb6c
parent72ee3280e08ef9d4a99466f0dbd29f419b5445b7 (diff)
downloadjgit-7123cbf470ea2fa39379a4d914f0933063bbbdfe.tar.gz
jgit-7123cbf470ea2fa39379a4d914f0933063bbbdfe.zip
archive: Record executable and symlink bits
Setting the mode for a zip entry is now as simple as "entry.setUnixMode(mode)", so do that. The test checks using the system's "zipinfo" command (from InfoZIP) that the mode has been recorded correctly on systems that happen to have a "zipinfo" command, using org.junit.Assume to distinguish them. Change-Id: I4236c102fd76f18d01b2dc926eeb9b9fa11a61b7
-rw-r--r--org.eclipse.jgit.pgm.test/tst/org/eclipse/jgit/pgm/ArchiveTest.java74
-rw-r--r--org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Archive.java14
2 files changed, 84 insertions, 4 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 583beefede..cad379774e 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
@@ -43,11 +43,16 @@
package org.eclipse.jgit.pgm;
import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.fail;
+import static org.junit.Assume.assumeNoException;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.FileOutputStream;
import java.io.InputStreamReader;
import java.io.IOException;
+import java.io.OutputStream;
import java.lang.String;
import java.util.ArrayList;
@@ -57,7 +62,9 @@ import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import org.eclipse.jgit.api.Git;
+import org.eclipse.jgit.dircache.DirCache;
import org.eclipse.jgit.lib.CLIRepositoryTestCase;
+import org.eclipse.jgit.lib.FileMode;
import org.eclipse.jgit.pgm.CLIGitCommand;
import org.junit.Before;
import org.junit.Ignore;
@@ -126,6 +133,32 @@ public class ArchiveTest extends CLIRepositoryTestCase {
}
@Test
+ public void testArchivePreservesMode() 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[] zipData = CLIGitCommand.rawExecute( //
+ "git archive master", db);
+ writeRaw("zip-with-modes.zip", zipData);
+ assertContainsEntryWithMode("zip-with-modes.zip", "-rw-", "plain");
+ assertContainsEntryWithMode("zip-with-modes.zip", "-rwx", "executable");
+ assertContainsEntryWithMode("zip-with-modes.zip", "l", "symlink");
+ }
+
+ @Test
public void testArchivePreservesContent() throws Exception {
final String payload = "“The quick brown fox jumps over the lazy dog!”";
writeTrashFile("xyzzy", payload);
@@ -138,6 +171,47 @@ public class ArchiveTest extends CLIRepositoryTestCase {
zipEntryContent(result, "xyzzy"));
}
+ private void assertContainsEntryWithMode(String zipFilename, String mode, String name) //
+ throws Exception {
+ final File cwd = db.getWorkTree();
+ final ProcessBuilder procBuilder = new ProcessBuilder("zipinfo", zipFilename) //
+ .directory(cwd) //
+ .redirectErrorStream(true);
+ Process proc = null;
+ try {
+ proc = procBuilder.start();
+ } catch (IOException e) {
+ // On machines without a "zipinfo" command, let the test pass.
+ assumeNoException(e);
+ }
+
+ proc.getOutputStream().close();
+ final BufferedReader reader = new BufferedReader( //
+ new InputStreamReader(proc.getInputStream(), "UTF-8"));
+ try {
+ String line;
+ while ((line = reader.readLine()) != null)
+ if (line.startsWith(mode) && line.endsWith(name))
+ // found it!
+ return;
+ fail("expected entry " + name + " with mode " + mode + " but found none");
+ } finally {
+ proc.getOutputStream().close();
+ proc.destroy();
+ }
+ }
+
+ private void writeRaw(String filename, byte[] data) //
+ throws IOException {
+ final File path = new File(db.getWorkTree(), filename);
+ final OutputStream out = new FileOutputStream(path);
+ try {
+ out.write(data);
+ } finally {
+ out.close();
+ }
+ }
+
private static String[] listZipEntries(byte[] zipData) throws IOException {
final List<String> l = new ArrayList<String>();
final ZipInputStream in = new ZipInputStream( //
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 ec937a3cc3..cc2f287b2a 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
@@ -90,14 +90,20 @@ class Archive extends TextBuiltin {
final ZipArchiveEntry entry = new ZipArchiveEntry(name);
final ObjectLoader loader = reader.open(idBuf);
entry.setSize(loader.getSize());
- out.putArchiveEntry(entry);
- loader.copyTo(out);
- out.closeArchiveEntry();
- if (mode != FileMode.REGULAR_FILE)
+ if (mode == FileMode.REGULAR_FILE)
+ ; // ok
+ else if (mode == FileMode.EXECUTABLE_FILE ||
+ mode == FileMode.SYMLINK)
+ entry.setUnixMode(mode.getBits());
+ else
System.err.println(MessageFormat.format( //
CLIText.get().archiveEntryModeIgnored, //
name));
+
+ out.putArchiveEntry(entry);
+ loader.copyTo(out);
+ out.closeArchiveEntry();
}
out.close();