【問題】依存パッケージをcomposerがインストールしてくれない
Laravelで自作パッケージを開発し、他アプリから使用できるかどうか確認をしている際に、自作パッケージの依存パッケージがインストールされない、という問題がありました。
作成したパッケージのcomposer.jsonには、以下のように記述しています。ここでは、作成したパッケージではFeedsパッケージが必要であるため、以下の様に記述しました。
dev-master
というのは、masterブランチのパッケージを使用するという意味です。
"require": {
"willvincent/feeds": "dev-master"
},
これで、作成したパッケージを使用する親アプリのルートディレクトリでcomposer update
を実行すれば、作成したパッケージが追加されるときに、Feedsパッケージも追加されるようになるはずです。…なるはずなのですが、なぜか追加されません
【原因】Composerのスタビリティの設定
Composerにはパッケージを追加する際に、そのパッケージのスタビリティ(そのバージョンが開発版なのか安定版なのか)を判断してダウンロードする仕組みがあります。
例えば、-dev
は開発中、-rc
は公開前、-stable
は安定版、というようなキーワードをブランチ名(タグ名)に付けることで、そのバージョンの状態を判断することができます。
※バージョンの例
3.0-dev
2.0-alpha
1.8
1.7
composer.jsonで追加するパッケージのバージョン指定に@dev
などのスタビリティフラグを付けることで、例えば「安定版じゃないけど最新のβバージョンが欲しい」というようなときに対応することができます。
"require": {
"vendor/foo": "1.0@beta"
}
そして今回の状況ですが、作成したパッケージであるルートパッケージがdev-master
を要求していて、 それがさらに他のパッケージを要求していました。それぞれの関係を矢印で表すとこのような感じです。
作成したパッケージ→Feedsパッケージ(dev-master)→SimplePieパッケージ
dev-masterはmasterブランチを指定しており、dev-master@dev
というスタビリティフラグを持っているのですが、今回作成したパッケージを追加しようとしている親アプリではスタビリティをstable
に指定していました。つまり安定版のパッケージを追加するようになっていたのです。
そのため、dev-master@stable
を参照しようとして見つからず、その結果追加されないという現象が起きていたようでした。
【解決】スタビリティフラグをホワイトリストとして使用する
親アプリのcomposer.jsonに以下のように記述します。
"require": {
"allabout/fbn-citrus-core": "dev-r26790_create_rss_validator",
"willvincent/feeds": "@dev",
ここではFeedsパッケージのバージョン指定はせずに、@dev
のみとします。
作成したパッケージのcomposer.jsonは変わらずそのままパッケージのバージョン指定をするように記述します。
"require": {
"willvincent/feeds": "dev-master"
},
これにより、無事に作成したパッケージの依存パッケージもダウンロードされるようになりました!
Composerのスタビリティについて大変勉強になりました。
参考にした記事
Composerがパッケージのstabilityを解決するしくみ
http://kohkimakimoto.hatenablog.com/entry/2014/04/04/102125