🐘

[PHP] フレームワークの最新バージョンに対応したライブラリをフレームワークのリリース前から開発する方法

3 min read

  • illuminate/contracts:^9.0 に依存している
  • しかし Laravel 9.0 系は まだリリースされていない

このとき composer.json をこうする↓

{
    // ...
    "require": {
        "illuminate/contracts": "^9.0",
	// ...
    },

    // ...
    "minimum-stability": "dev",
    "prefer-stable": true
}

解説

用語やスタビリティ解決の詳細に関しては以下のドキュメント等を参考にしてください。

minimum-stabilityprefer-stable について

用語の意味
用語 意味 デフォルト値
minimum-stability インストール可能な最小の安定性 "stable"
prefer-stable 可能な範囲で安定バージョンを選ぶ false
バージョン表現とスタビリティの対応
安定度 スタビリティ 例(タグ) 例(ブランチ)
5 stable v1.0.0
4 RC v1.0.0-rc1
3 beta v1.0.0-beta
2 alpha v1.0.0-alpha
1 dev v1.x-dev
dev-master
  • バージョン番号っぽいブランチは -dev サフィックスが自動付与されて解釈される
    • バージョン番号っぽいブランチは,その系統の最新バージョンとみなすことができます。
      例えば v1.0.0 v1.x-dev は両方とも ^1.0 の対象になります。
  • それ以外のブランチは dev- プレフィクスが自動付与されて解釈される
組み合わせと動作
minimum-stability prefer-stable 動作
A "stable"
(デフォルト)
- stable しか選択できない
B "dev" false
(デフォルト)
全てインストール可能で,できるだけ最新版を使う
C "dev" true 全てインストール可能で,できるだけ安定版を使う
  • (A) 既定の動作で,アプリケーション開発者は基本的にこのままでよいでしょう。
  • (B) 🔥🔥🔥 全ライブラリ master ブランチの内容が降ってきます 🔥🔥🔥
  • (C) ライブラリ開発向けです。基本安定に寄せますが,一部リリース前のものも指定できるようになります。

前提条件と branch-alias

  • インストールしたい将来のバージョンに対応する「バージョン番号っぽいブランチ」がある
  • minimum-stability"dev" になっている

この2つの要件を満たしていれば,最初の例に示したような composer.json の設定で,まだリリースされていないバージョンのフレームワークをインストールすることが可能になります。しかし,ブランチ名がこの規則に従っておらず,仮に master という名前だったらどうしましょうか? Composer ではこれに対応する仕組みが用意されています。

フレームワーク側で解決

branch-alias という機能を使用すると,ブランチに別名を付けられます。

// フレームワーク側の composer.json

{
    "extra": {
        "branch-alias": {
            "dev-master": "9.x-dev"
        }
    }
}

Laravel はこちらの方法を採用し, master ブランチを次のバージョンの dev 版として用意しています。

ライブラリ開発側で解決

もしフレームワーク側での用意がない場合は,インラインエイリアスを使うとよいでしょう。

// ライブラリ開発側の composer.json

{
    "require": {
        "illuminate/contracts": "dev-master as 9.x-dev"
    }
}

但し, Composer 公式ページ の最後にも書いてあるとおり,ルートパッケージでしかこの機能は使用できません。つまり,誰かがこのライブラリをインストールする際にエイリアスは有効になりません。 この状態では一切リリースできないので,ライブラリとしての使い方は限定的になります。この状態でのパッケージ公開は避けましょう。

スタビリティフラグではダメなのか?

一見

{
    "require": {
        "illuminate/contracts": "^9.0"
    },
    "minimum-stability": "dev",
    "prefer-stable": true
}

の代わりに,スタビリティフラグという機能を使用して

{
    "require": {
        "illuminate/contracts": "^9.0@dev"
    }
}

でも問題なさそうな気がしてしまいますが, illuminate/contracts:9.x-dev が他の illuminate/xxxxx:9.x-dev に依存している場合に対応できません。「依存先の依存先」までスタビリティを制御する必要がある場合は,必ず全体に対して設定を行ってください。

Discussion

ログインするとコメントできます