[Mac]netatalkの.AppleDoubleでsymfonyコマンドがつまずく時がある

タイトルでもわかるとおり、非常に限定的な環境でsymfonyを使ったときにハマってしまったので、今後、私と同じようなマニアックな環境でハマってしまった人がググってくれることを期待して備忘録を残します。

さて、私はMac OS X上にVMware Fusion 2を導入していて、会社での開発をVM上のCentOS 5で行っています。開発ではMacのCocoaに対応したEclipse 3.5を主にしようしています。EclipseでVM上のファイルを直接読み書きするため、netatalkというMac版sambaとも言えるソフトウェアをCentOSに導入して、MacとLinux間の共有を行っています。ここら辺のお話は、以前3回に渡って書いたnetatalk導入のブログの記事を参照してもらえればと思います。

Mac OS Xでで外部ストレージ(NFS)などを用いるとき、ファイルのメタ情報を保存するために、netatalkでは.AppleDoubleというフォルダを各フォルダごとに生成し、そのフォルダの中に元ファイル名と同名のファイル名でメタ情報を格納します。※WikipediaのAppleSingleにAppleDoubleについて記載があります。netatalkではnoadoubleというオプションがあり、「必要なければ.AppleDoubleを作らない」という設定にすることができるのですが、必要ある場合は当然作成されてしまいます。例えば、Eclipseからアクセスして保存とかをすると、.AppleDoubleが作られてしまうような気がします。

CentOS上にsymfonyを展開してMacからターミナルで操ろうとしたとき、基本的にはsymfonyのあの深いフォルダ階層のすべてに.AppleDoubleが生成されてしまうということです。そこでこまったのがsymfonyコマンド。propel:build-xxxとかやろうとすると、どうも.AppleDoubleのせいでうまくいかないことがあります。

例えばpropel:build-model
[shcode]
[ueno@localhost project]$ ./symfony propel:build-model
Unable to parse file “/path/to/project/config/.AppleDouble/schema.yml”: Unable to parse line 1 (
[/shcode]
なぜか.AppleDoubleフォルダ内のshema.ymlがパースできないと言われてしまいます。前述の通り、.AppleDoubleフォルダの中に元ファイル名と同名のメタファイルを生成しますので、もしかしたらschema.ymlという名前に反応してしまったのかもしれません。一応propel:build-modelのヘルプを見てみましょう。
[shcode]
[ueno@localhost project]$ ./symfony help propel:build-model
Usage:
symfony propel:build-model [–phing-arg=”…”]

Aliases: propel-build-model

Options:
–phing-arg Arbitrary phing argument (multiple values allowed)

Description:
The propel:build-model task creates model classes from the schema:

./symfony propel:build-model

The task read the schema information in config/*schema.xml and/or
config/*schema.yml from the project and all installed plugins.

You mix and match YML and XML schema files. The task will convert
YML ones to XML before calling the Propel task.

The model classes files are created in lib/model.

This task never overrides custom classes in lib/model.
It only replaces files in lib/model/om and lib/model/map.
[/shcode]
検索条件はconfig/*schema.ymlと書いてありますので、フォルダも引っかかってしまうようです。

で解決策はどうするのか?propel:build-xxx系のコマンドなどでは、symfonyライブラリの中に含まれるsfFinder.class.phpというユーティリティを利用しています。この中に、指定されたルールに基づいて、ファイルやディレクトリを検索するというin()メソッドがあるのですが、この中で、バージョン管理ソフトのディレクトリを無視するようなプログラムの掛かれば部分があります。symfony 1.2.8のlib/symfony/util/sfFinder.class.phpの341行目付近です。
[phpcode]
/**
* Searches files and directories which match defined rules.
*
* @return array list of files and directories
*/
public function in()
{
$files = array();
$here_dir = getcwd();

$finder = clone $this;

if ($this->ignore_version_control)
{
$ignores = array(‘.svn’, ‘_svn’, ‘CVS’, ‘_darcs’, ‘.arch-params’, ‘.monotone’, ‘.bzr’, ‘.git’, ‘.hg’);

$finder->discard($ignores)->prune($ignores);
}
[/phpcode]
svnやらcvsやらgitやらのメタ情報を保存するフォルダの除外指定が列挙されています。ならばここにAppleDoubleをいれればいいんでないか?ということで、修正多野がこちら
[phpcode]
if ($this->ignore_version_control)
{
$ignores = array(‘.svn’, ‘_svn’, ‘CVS’, ‘_darcs’, ‘.arch-params’, ‘.monotone’, ‘.bzr’, ‘.git’, ‘.hg’, ‘.AppleDouble’);

$finder->discard($ignores)->prune($ignores);
}
[/phpcode]
symfonyのコアを書き換えるのはどうかと思ったのですが、この設定を付け加えるだけでnetatalk環境でのsymfonyコマンドが問題なく使えるようになったので開発が進みそうです。

まぁ、こんな環境でsymfony使う人はなかなか居ないと思いますが。。。

About: uechoco