From 30900f71965875be18c08cbba0cf548b26b34c53 Mon Sep 17 00:00:00 2001 From: Thomas Keller Date: Thu, 24 Mar 2011 23:54:52 +0100 Subject: [PATCH] monotone zip archive entries now all carry the revision date as mtime (issue 645); add a test case for the zip render response that works with and without PHP's zip extension --- NEWS.mdtext | 2 + src/IDF/Scm/Monotone/ZipRender.php | 26 +++- test/IDF/Scm/Monotone/ZipRenderTest.php | 140 ++++++++++++++++++ .../IDF_Scm_Monotone_ZipRenderTest/data.zip | Bin 0 -> 218 bytes 4 files changed, 167 insertions(+), 1 deletion(-) create mode 100644 test/IDF/Scm/Monotone/ZipRenderTest.php create mode 100644 test/data/IDF_Scm_Monotone_ZipRenderTest/data.zip diff --git a/NEWS.mdtext b/NEWS.mdtext index e7533ff..101c430 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/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/data/IDF_Scm_Monotone_ZipRenderTest/data.zip b/test/data/IDF_Scm_Monotone_ZipRenderTest/data.zip new file mode 100644 index 0000000000000000000000000000000000000000..9d25ecb152d95d4b43cd29bf710d9b8c4016f86a GIT binary patch literal 218 zcmWIWW@ce#V_@K5IJ@DQ)zVbUCLRU`1`uWj;