Ethna 2.3.7とEthna 2.5.0preview5を共存させるとethnaコマンドがバグる
先日のEthna_Plugin_Debugtoolbarのインストールで、すでにインストールしてるEthna 2.3.7はそのままにしてEthna 2.5.0preview5をインストールしたらethnaコマンドがちゃんと動かなった。
再現手順
再現手順は以下のとおり。
以降長いので略記。
2.3.7な環境で、
$ ethna -v Ethna 2.3.7
プロジェクトを作成して、
$ ethna add-project sample
そのプロジェクトに2.5.0p5をインストール。
$ cd sample $ ethna pear-local channel-discover pear.ethna.jp $ ethna pear-local install -a http://pear.ethna.jp/pear/Ethna-2.5.2009062201.tgz $ bin/ethna -v Ethna 2.5.0-preview5 (using PHP 5.2.6-3ubuntu4.1)
インストールした2.5.0p5のethnaコマンドを引数なしで実行すると、
$ bin/ethna Fatal error: Cannot redeclare class Ethna_Plugin_Handle_AddAction in /usr/share/php/Ethna/class/Plugin/Handle/Ethna_Plugin_Handle_AddAction.php on line 143 Call Stack: 0.0037 89304 1. {main}() /home/okonomi/public_html/blog/sample/lib/Ethna/bin/ethna_handle.php:0 0.1453 3294016 2. Ethna_Plugin_Handle_Help->perform() /home/okonomi/public_html/blog/sample/lib/Ethna/bin/ethna_handle.php:66 0.1457 3294864 3. Ethna_Handle->getHandlerList() /home/okonomi/public_html/blog/sample/lib/Ethna/class/Plugin/Handle/Help.php:38 0.1457 3294864 4. Ethna_Plugin->getPluginList() /home/okonomi/public_html/blog/sample/lib/Ethna/class/Ethna_Handle.php:80 0.2917 6312800 5. Ethna_Plugin->getPlugin() /home/okonomi/public_html/blog/sample/lib/Ethna/class/Ethna_Plugin.php:115 0.2917 6312800 6. Ethna_Plugin->_getPlugin() /home/okonomi/public_html/blog/sample/lib/Ethna/class/Ethna_Plugin.php:93 0.2917 6312800 7. Ethna_Plugin->_loadPlugin() /home/okonomi/public_html/blog/sample/lib/Ethna/class/Ethna_Plugin.php:145 0.2918 6312800 8. Ethna_Plugin->_includePluginSrc() /home/okonomi/public_html/blog/sample/lib/Ethna/class/Ethna_Plugin.php:176
ずぎゃーん。
原因を探る
どうやらプラグインをリストアップするときに何か失敗してるみたい。ソースを追いかけてみる。
Ethna_PluginクラスのgetPluginList()では、$src_registryの内容を元にgetPlugin()を呼んでプラグインをロードしてる。
試しに$src_registryの値をprint_rしてみると、
<?php Array ( [Handle] => Array ( [Help] => Array ( [0] => Ethna_Plugin_Handle_Help [1] => /home/okonomi/public_html/blog/sample/lib/Ethna/class/Plugin/Handle [2] => Help.php ) [AddAction] => Array ( [0] => Ethna_Plugin_Handle_AddAction [1] => /home/okonomi/public_html/blog/sample/lib/Ethna/class/Plugin/Handle [2] => AddAction.php ) [AddActionTest] => Array ( [0] => Ethna_Plugin_Handle_AddActionTest [1] => /home/okonomi/public_html/blog/sample/lib/Ethna/class/Plugin/Handle [2] => AddActionTest.php ) [AddAppManager] => Array ( [0] => Ethna_Plugin_Handle_AddAppManager [1] => /home/okonomi/public_html/blog/sample/lib/Ethna/class/Plugin/Handle [2] => AddAppManager.php ) [AddAppObject] => Array ( [0] => Ethna_Plugin_Handle_AddAppObject [1] => /home/okonomi/public_html/blog/sample/lib/Ethna/class/Plugin/Handle [2] => AddAppObject.php ) [AddEntryPoint] => Array ( [0] => Ethna_Plugin_Handle_AddEntryPoint [1] => /home/okonomi/public_html/blog/sample/lib/Ethna/class/Plugin/Handle [2] => AddEntryPoint.php ) [AddProject] => Array ( [0] => Ethna_Plugin_Handle_AddProject [1] => /home/okonomi/public_html/blog/sample/lib/Ethna/class/Plugin/Handle [2] => AddProject.php ) [AddTemplate] => Array ( [0] => Ethna_Plugin_Handle_AddTemplate [1] => /home/okonomi/public_html/blog/sample/lib/Ethna/class/Plugin/Handle [2] => AddTemplate.php ) [AddTest] => Array ( [0] => Ethna_Plugin_Handle_AddTest [1] => /home/okonomi/public_html/blog/sample/lib/Ethna/class/Plugin/Handle [2] => AddTest.php ) [AddView] => Array ( [0] => Ethna_Plugin_Handle_AddView [1] => /home/okonomi/public_html/blog/sample/lib/Ethna/class/Plugin/Handle [2] => AddView.php ) [AddViewTest] => Array ( [0] => Ethna_Plugin_Handle_AddViewTest [1] => /home/okonomi/public_html/blog/sample/lib/Ethna/class/Plugin/Handle [2] => AddViewTest.php ) [ClearCache] => Array ( [0] => Ethna_Plugin_Handle_ClearCache [1] => /home/okonomi/public_html/blog/sample/lib/Ethna/class/Plugin/Handle [2] => ClearCache.php ) [CreatePlugin] => Array ( [0] => Ethna_Plugin_Handle_CreatePlugin [1] => /home/okonomi/public_html/blog/sample/lib/Ethna/class/Plugin/Handle [2] => CreatePlugin.php ) [I18n] => Array ( [0] => Ethna_Plugin_Handle_I18n [1] => /home/okonomi/public_html/blog/sample/lib/Ethna/class/Plugin/Handle [2] => I18n.php ) [MakePluginPackage] => Array ( [0] => Ethna_Plugin_Handle_MakePluginPackage [1] => /home/okonomi/public_html/blog/sample/lib/Ethna/class/Plugin/Handle [2] => MakePluginPackage.php ) [PearLocal] => Array ( [0] => Ethna_Plugin_Handle_PearLocal [1] => /home/okonomi/public_html/blog/sample/lib/Ethna/class/Plugin/Handle [2] => PearLocal.php ) [Ethna_Plugin_Handle_AddAction] => Array ( [0] => Ethna_Plugin_Handle_Ethna_Plugin_Handle_AddAction [1] => /usr/share/php/Ethna/class/Plugin/Handle [2] => Ethna_Plugin_Handle_AddAction.php ) [Ethna_Plugin_Handle_AddActionTest] => Array ( [0] => Ethna_Plugin_Handle_Ethna_Plugin_Handle_AddActionTest [1] => /usr/share/php/Ethna/class/Plugin/Handle [2] => Ethna_Plugin_Handle_AddActionTest.php ) [Ethna_Plugin_Handle_AddAppManager] => Array ( [0] => Ethna_Plugin_Handle_Ethna_Plugin_Handle_AddAppManager [1] => /usr/share/php/Ethna/class/Plugin/Handle [2] => Ethna_Plugin_Handle_AddAppManager.php ) [Ethna_Plugin_Handle_AddAppObject] => Array ( [0] => Ethna_Plugin_Handle_Ethna_Plugin_Handle_AddAppObject [1] => /usr/share/php/Ethna/class/Plugin/Handle [2] => Ethna_Plugin_Handle_AddAppObject.php ) [Ethna_Plugin_Handle_AddEntryPoint] => Array ( [0] => Ethna_Plugin_Handle_Ethna_Plugin_Handle_AddEntryPoint [1] => /usr/share/php/Ethna/class/Plugin/Handle [2] => Ethna_Plugin_Handle_AddEntryPoint.php ) [Ethna_Plugin_Handle_AddProject] => Array ( [0] => Ethna_Plugin_Handle_Ethna_Plugin_Handle_AddProject [1] => /usr/share/php/Ethna/class/Plugin/Handle [2] => Ethna_Plugin_Handle_AddProject.php ) [Ethna_Plugin_Handle_AddTemplate] => Array ( [0] => Ethna_Plugin_Handle_Ethna_Plugin_Handle_AddTemplate [1] => /usr/share/php/Ethna/class/Plugin/Handle [2] => Ethna_Plugin_Handle_AddTemplate.php ) [Ethna_Plugin_Handle_AddTest] => Array ( [0] => Ethna_Plugin_Handle_Ethna_Plugin_Handle_AddTest [1] => /usr/share/php/Ethna/class/Plugin/Handle [2] => Ethna_Plugin_Handle_AddTest.php ) [Ethna_Plugin_Handle_AddView] => Array ( [0] => Ethna_Plugin_Handle_Ethna_Plugin_Handle_AddView [1] => /usr/share/php/Ethna/class/Plugin/Handle [2] => Ethna_Plugin_Handle_AddView.php ) [Ethna_Plugin_Handle_AddViewTest] => Array ( [0] => Ethna_Plugin_Handle_Ethna_Plugin_Handle_AddViewTest [1] => /usr/share/php/Ethna/class/Plugin/Handle [2] => Ethna_Plugin_Handle_AddViewTest.php ) [Ethna_Plugin_Handle_ChannelUpdate] => Array ( [0] => Ethna_Plugin_Handle_Ethna_Plugin_Handle_ChannelUpdate [1] => /usr/share/php/Ethna/class/Plugin/Handle [2] => Ethna_Plugin_Handle_ChannelUpdate.php ) [Ethna_Plugin_Handle_ClearCache] => Array ( [0] => Ethna_Plugin_Handle_Ethna_Plugin_Handle_ClearCache [1] => /usr/share/php/Ethna/class/Plugin/Handle [2] => Ethna_Plugin_Handle_ClearCache.php ) [Ethna_Plugin_Handle_InfoPlugin] => Array ( [0] => Ethna_Plugin_Handle_Ethna_Plugin_Handle_InfoPlugin [1] => /usr/share/php/Ethna/class/Plugin/Handle [2] => Ethna_Plugin_Handle_InfoPlugin.php ) [Ethna_Plugin_Handle_InstallPlugin] => Array ( [0] => Ethna_Plugin_Handle_Ethna_Plugin_Handle_InstallPlugin [1] => /usr/share/php/Ethna/class/Plugin/Handle [2] => Ethna_Plugin_Handle_InstallPlugin.php ) [Ethna_Plugin_Handle_ListPlugin] => Array ( [0] => Ethna_Plugin_Handle_Ethna_Plugin_Handle_ListPlugin [1] => /usr/share/php/Ethna/class/Plugin/Handle [2] => Ethna_Plugin_Handle_ListPlugin.php ) [Ethna_Plugin_Handle_MakePluginPackage] => Array ( [0] => Ethna_Plugin_Handle_Ethna_Plugin_Handle_MakePluginPackage [1] => /usr/share/php/Ethna/class/Plugin/Handle [2] => Ethna_Plugin_Handle_MakePluginPackage.php ) [Ethna_Plugin_Handle_PearLocal] => Array ( [0] => Ethna_Plugin_Handle_Ethna_Plugin_Handle_PearLocal [1] => /usr/share/php/Ethna/class/Plugin/Handle [2] => Ethna_Plugin_Handle_PearLocal.php ) [Ethna_Plugin_Handle_UninstallPlugin] => Array ( [0] => Ethna_Plugin_Handle_Ethna_Plugin_Handle_UninstallPlugin [1] => /usr/share/php/Ethna/class/Plugin/Handle [2] => Ethna_Plugin_Handle_UninstallPlugin.php ) [Ethna_Plugin_Handle_UpgradePlugin] => Array ( [0] => Ethna_Plugin_Handle_Ethna_Plugin_Handle_UpgradePlugin [1] => /usr/share/php/Ethna/class/Plugin/Handle [2] => Ethna_Plugin_Handle_UpgradePlugin.php ) ) )
なんかクラス名とか重複してる?
$src_registryを組み立ててるのはsearchAllPluginSrc()から呼ばれてる_searchPluginSrc()で、引数の$typeと$nameが$src_registryの配列のキーになってる。で、$nameはプラグインのファイル名からつくられてる。
そういえばプラグインのファイル名の命名規則が変更されたんだった。そのあたりに原因が?
命名規則の変更を吸収するようなコードを1行追加してみた。
<?php /** * 指定された $type のプラグイン (のソース) をすべて検索する * * @access public * @param string $type プラグインの種類 */ function searchAllPluginSrc($type) { // 後で見付かったもので上書きするので $this->appid_list の逆順とする $name_list = array(); $ext = $this->ctl->getExt('php'); foreach($this->_dirlist as $dir) { $files = glob($dir . DIRECTORY_SEPARATOR . $type . DIRECTORY_SEPARATOR . "/*." . $ext); if (!$files) { $this->logger->log(LOG_DEBUG, 'cannot open plugin directory: [%s/%s]', $dir, $type); continue; } $this->logger->log(LOG_DEBUG, 'plugin directory opened: [%s]', $dir); foreach ($files as $plugin_file) { $plugin_name = substr(basename($plugin_file), 0, - strlen($ext) - 1); + $plugin_name = preg_replace("/^[A-Z]+_Plugin_{$type}_(.+)/i", '$1', $plugin_name); $name_list[$plugin_name] = 0; } } foreach (array_keys($name_list) as $name) { // 冗長だがもう一度探しなおす $this->_searchPluginSrc($type, $name); } } // }}}
で、実行。
$ bin/ethna usage: ethna [option] [command] [args...] available options are as follows: -v, --version show version and exit available commands are as follows: add-action add-action-test add-app-manager add-app-object add-entry-point add-project add-template add-test add-view add-view-test clear-cache create-plugin help i18n make-plugin-package pear-local
おお、うまくいった!
さて
今回の対応が正しいのかよく分からないですが、起こった問題と対応方法を書いてみました。
こういうのってチケット投げた方がいいのかなー…?