symfonyを1.0.11にupgradeしようとしたときのメモ
なんかすんなりupgradeできなかったのでメモっとく。
- 普通にPEARからupgradeしようとしたらエラー
$ sudo pear upgrade symfony/symfony downloading symfony-1.0.11.tgz ... Starting to download symfony-1.0.11.tgz (1,912,922 bytes) .....................................................done: 1,912,922 bytes Could not get contents of package "/tmp/pear/cache/symfony-1.0.11.tgz". Invalid tgz file. Download of "symfony/symfony" succeeded, but it is not a valid package archive Error: cannot download "symfony/symfony" Download failed upgrade failed
- grepでエラーメッセージの一部を探してみた
$ grep -R 'Invalid tgz file.' /usr/local/lib/php /usr/local/lib/php/PEAR/PackageFile.php: '. Invalid tgz file.');
- PackageFile.php(300〜323行目)
<?php $tar = new Archive_Tar($file); if ($this->_debug <= 1) { $tar->pushErrorHandling(PEAR_ERROR_RETURN); } $content = $tar->listContent(); if ($this->_debug <= 1) { $tar->popErrorHandling(); } if (!is_array($content)) { if (is_string($file) && strlen($file < 255) && (!file_exists($file) || !@is_file($file))) { $ret = PEAR::raiseError("could not open file \"$file\""); return $ret; } $file = realpath($file); $ret = PEAR::raiseError("Could not get contents of package \"$file\"". '. Invalid tgz file.'); return $ret; } else { if (!count($content) && !@is_file($file)) { $ret = PEAR::raiseError("could not open file \"$file\""); return $ret; } }
Archive_TarクラスのコンストラクタかlistContentメソッドがおかしいみたいなのでvar_dumpデバッグしてみる
- PackageFile.php(300〜304行目あたり)
<?php $tar = new Archive_Tar($file); if ($this->_debug <= 1) { $tar->pushErrorHandling(PEAR_ERROR_RETURN); } $content = $tar->listContent(); var_dump($tar); var_dump($content);
- var_dump結果
object(Archive_Tar)#1 (12) { ["_tarname"]=> string(34) "/tmp/pear/cache/symfony-1.0.11.tgz" ["_compress"]=> bool(true) ["_compress_type"]=> string(2) "gz" ["_separator"]=> string(1) " " ["_file"]=> int(0) ["_temp_tarname"]=> string(0) "" ["_debug"]=> bool(false) ["_default_error_mode"]=> NULL ["_default_error_options"]=> NULL ["_default_error_handler"]=> string(0) "" ["_error_class"]=> string(10) "PEAR_Error" ["_expected_errors"]=> array(0) { } } int(0)
listContent()をチェック
- Tar.php(215〜228行目)
<?php function listContent() { $v_list_detail = array(); if ($this->_openRead()) { if (!$this->_extractList('', $v_list_detail, "list", '', '')) { unset($v_list_detail); $v_list_detail = 0; } $this->_close(); } return $v_list_detail; }
_extractList()がfalseになってるのが元凶ぽい。とりあえず1430行目以降あたりからデバッグプリントを順番にしていこうと考える
- Tar.php(1390〜1408行目)
<?php while (strlen($v_binary_data = $this->_readBlock()) != 0) { $v_extract_file = FALSE; $v_extraction_stopped = 0; if (!$this->_readHeader($v_binary_data, $v_header)) { var_dump('debug'); return false; } if ($v_header['filename'] == '') { continue; } // ----- Look for long filename if ($v_header['typeflag'] == 'L') { if (!$this->_readLongHeader($v_header)) return false; }
var_dumpデバッグ1発目でヒットw _readHeader()をミスってる模様。
斜め読みすると、_readBlock()でgzファイルから512バイトずつ読んで、_readHeaderでヘッダーをチェックしてる処理。
だから、_readBlock()の結果を出力させてみた。
- _readBlock()出力結果の最後の方
string(512) "symfony-1.0.11/lib/vendor/propel-generator/classes/propel/phing/AbstractPropelDataModelTask.php100644 41 1751 45123 10745327731 26136 " string(512) "symfony-1.0.11/lib/vendor/propel-generator/classes/propel/phing/PropelOldSQLTask.php100644 41 1751 20716 10745327731 23717 " string(512) "symfony-1.0.11/lib/vendor/propel-generator/classes/propel/phing/PropelGraphvizTask.php100644 41 1751 10143 10745327731 24404 " string(512) "symfony-1.0.11/lib/vendor/propel-generator/classes/propel/phing/PropelSQLTask.php100644 41 1751 16357 10745327731 23266 " string(512) "symfony-1.0.11/lib/vendor/propel-generator/classes/propel/phing/PropelDataDumpTask.php100644 41 1751 24752 10745327731 24324 " string(512) "symfony-1.0.11/lib/vendor/propel-generator/classes/propel/engine/EngineException.php100644 41 1751 2624 10745327731 24016 " string(512) "././@LongLink000 144 0 4475 L" string(512) " @gzwrite($p_dest, $v_buffer, $v_read_size); $p_size -= $v_read_size; } } else if ($p_mode==3) { while ($p_size != 0) { $v_read_size = ($p_size < ARCHIVE_ZIP_READ_BLOCK_SIZE ? $p_size : ARCHIVE_ZIP_READ_BLOCK_SIZE); $v_buffer = @gzread($p_src, $v_read_size); @gzwrite($p_dest, $v_buffer, $v_read_size); $p_size -= $v_read_size; } } // ----- Return return $v_result; } // ------------------------"
明らかに最後がおかしい。。。tgzファイル内にいらない情報が混ざってるのか?
ちなみに他のtgzファイルの解凍は問題無くできているのでsymfonyのtgzファイルに問題がありそう。
シェル上からは普通にtgzファイルを解凍できるので、このエラーチェックをコメントアウトしてupgradeしてみた
- Tar.php(1435〜1437行目あたり)
// if (!$this->_readHeader($v_binary_data, $v_header)) {
// return false;
// }
$ sudo pear upgrade symfony/symfony downloading symfony-1.0.11.tgz ... Starting to download symfony-1.0.11.tgz (1,912,922 bytes) .....................................................done: 1,912,922 bytes upgrade ok: channel://pear.symfony-project.com/symfony-1.0.11
普通にupgradeできた。しかし根本的な原因解決になってない罠・・・orz