diff --git a/NEWS.mdtext b/NEWS.mdtext
index 86f5190..e16f211 100644
--- a/NEWS.mdtext
+++ b/NEWS.mdtext
@@ -4,6 +4,8 @@
## Bugfixes
+- monotone zip archive entries now all carry the revision date as mtime (issue 645)
+
## Documentation
## Translations
diff --git a/phpunit.xml b/phpunit.xml
index 00db39e..21fb44e 100644
--- a/phpunit.xml
+++ b/phpunit.xml
@@ -12,4 +12,16 @@
test/IDF/
+
+
+
+ src/IDF
+
+ src/IDF/Tests
+ src/IDF/conf
+ src/IDF/version.php
+
+
+
+
diff --git a/run-tests b/run-tests
new file mode 100755
index 0000000..bc166f6
--- /dev/null
+++ b/run-tests
@@ -0,0 +1,14 @@
+#!/usr/bin/env php
+>> code coverage %s/%s (%s%%)'."\n",
+ $xml->project->metrics['coveredstatements'],
+ $xml->project->metrics['statements'],
+ round(($xml->project->metrics['coveredstatements']/(float)$xml->project->metrics['statements']) * 100.0, 2)
+);
+
diff --git a/src/IDF/Scm/Monotone/ZipRender.php b/src/IDF/Scm/Monotone/ZipRender.php
index eddc4fc..093725f 100644
--- a/src/IDF/Scm/Monotone/ZipRender.php
+++ b/src/IDF/Scm/Monotone/ZipRender.php
@@ -60,6 +60,26 @@ class IDF_Scm_Monotone_ZipRender extends Pluf_HTTP_Response
$this->outputHeaders();
if ($output_body) {
+ $certs = $this->stdio->exec(array('certs', $this->revision));
+ $stanzas = IDF_Scm_Monotone_BasicIO::parse($certs);
+
+ // use the revision's date (if there is one) as timestamp
+ // for all file entries
+ $timestamp = time();
+ foreach ($stanzas as $stanza) {
+ $next_is_date = false;
+ foreach ($stanza as $line) {
+ if ($line['key'] == 'name' && $line['values'][0] == 'date') {
+ $next_is_date = true;
+ continue;
+ }
+ if ($next_is_date && $line['key'] == 'value') {
+ $timestamp = strtotime($line['values'][0]);
+ break;
+ }
+ }
+ }
+
$manifest = $this->stdio->exec(array('get_manifest_of', $this->revision));
$stanzas = IDF_Scm_Monotone_BasicIO::parse($manifest);
@@ -69,7 +89,11 @@ class IDF_Scm_Monotone_ZipRender extends Pluf_HTTP_Response
if ($stanza[0]['key'] != 'file')
continue;
$content = $this->stdio->exec(array('get_file', $stanza[1]['hash']));
- $zip->add_file($stanza[0]['values'][0], $content);
+ $zip->add_file(
+ $stanza[0]['values'][0],
+ $content,
+ array('time' => $timestamp)
+ );
}
$zip->finish();
diff --git a/test/IDF/Scm/Monotone/ZipRenderTest.php b/test/IDF/Scm/Monotone/ZipRenderTest.php
new file mode 100644
index 0000000..5200b68
--- /dev/null
+++ b/test/IDF/Scm/Monotone/ZipRenderTest.php
@@ -0,0 +1,140 @@
+render(true);
+ $zipcontents = ob_get_contents();
+ ob_end_clean();
+
+ // for this version php needs to be compiled with --enable-zip
+ if (function_exists('zip_open')) {
+ // yes, I'd rather have used php://memory here, but ZipArchive::open()
+ // complained that it could not open the stream in question
+ $filename = tempnam(Pluf::f('tmp_folder', '/tmp'), __CLASS__.'.');
+ file_put_contents($filename, $zipcontents);
+
+ $za = new ZipArchive();
+ $za->open($filename);
+ $this->assertEquals(2, $za->numFiles);
+
+ // 2009-07-06T22:06:27 - one second
+ // (don't ask me why, seems to be some quirk in zipstream)
+ $mtime = 1246910787 - 1;
+
+ // foo
+ $data = $za->statIndex(0);
+ $this->assertEquals('foo', $data['name']);
+ $this->assertEquals(12, $data['size']);
+ $this->assertEquals($mtime, $data['mtime']);
+
+ // bar/baz
+ $data = $za->statIndex(1);
+ $this->assertEquals('bar/baz', $data['name']);
+ $this->assertEquals(12, $data['size']);
+ $this->assertEquals($mtime, $data['mtime']);
+
+ $za->close();
+ unlink($filename);
+ }
+ else {
+ $wrapped_act = wordwrap(
+ base64_encode($zipcontents),
+ 32, "\n", true
+ );
+ $wrapped_exp = wordwrap(
+ base64_encode(file_get_contents(DATADIR . '/' . __CLASS__ . '/data.zip')),
+ 32, "\n", true
+ );
+
+ $this->assertEquals($wrapped_exp, $wrapped_act);
+ }
+ }
+}
diff --git a/test/bootstrap.php b/test/bootstrap.php
index df766f4..c72e63a 100644
--- a/test/bootstrap.php
+++ b/test/bootstrap.php
@@ -22,7 +22,6 @@ passthru('php ' . PLUF_PATH . '/migrate.php --conf=' . TESTDIR . '/config.php -a
echo ">>> setting up web application...\n";
require 'Pluf.php';
-// for some reason this is nowhere done in Pluf.php
+// for PHPUnit 3.5 and beyond this is needed, since it comes with its own class loader
spl_autoload_register('__autoload');
Pluf::start(TESTDIR . '/config.php');
-
diff --git a/test/data/IDF_Scm_Monotone_ZipRenderTest/data.zip b/test/data/IDF_Scm_Monotone_ZipRenderTest/data.zip
new file mode 100644
index 0000000..9d25ecb
Binary files /dev/null and b/test/data/IDF_Scm_Monotone_ZipRenderTest/data.zip differ