ウェブサイト検索

PHP: Composerパッケージに独自のパッチを適用する方法


サードパーティ製パッケージを使用することで、プロジェクトの開発を加速できます。時には、追加機能を加えたり、重要なバグを修正したりする必要があるかもしれません。ここでは、ComposerでインストールされたPHPパッケージにパッチを適用する方法を説明します。

パッケージをパッチする時

まず、プロジェクト内でパッチを作成することが適切かどうかを考えます。パッチは常に小さな変更であるべきです。広範な新機能を追加する必要がある場合は、パッケージに対して問題をオープンするか、自分でフォークするべきです。こうすることで、パッケージの進化に伴う対立を避けることができます。

あなたが求めている変更が本当にあなたのプロジェクトに特有であるかどうか、慎重に考えるべきです。依存関係のパッチは通常、コードの数行にのみ影響を与えます。それらは、パッケージを使用することを妨げるバグや問題に対処しています。ほとんどのパッチは短期的な性質を持っています。後で、パッケージのコードベース内でのソース修正に置き換えられるべきです。

最終的には、あなたの意図を測る必要があります。あなたは、パッケージに関する即時の問題に対処しているのか、それともコードベースに合わせてパッケージの機能を拡張しているのか?後者であれば、パッケージに貢献するか、またはプロジェクトの第一級市民となる追加のクラスや関数でラップすることを検討すべきです。

コンポーザーパッチの作成

パッチを作成することを決めたら、プロジェクトの準備を始めることができます。Composerにはパッチの組み込みサポートがないため、人気のあるsimplify/vendor-patchesプロジェクトを使用して追加します。これにより、直感的なインターフェースが提供されます。

cweagans/composer-patches

新しいパッチを作成するのを手伝うために。

composer require --dev symplify/vendor-patches

修正が必要なパッケージがプロジェクトにインストールされていることを確認してください。

composer require example/broken-package

次に、問題のあるファイルをコードエディタで開いてください。vendor ディレクトリ内にあります。例として、vendor/example/broken-package/src/Broken.php を編集する必要があります:

<?php

class Broken {

public function __construct(string|int $foo) {

if (is_string($foo)) {

echo "Valid value!";

}

}

}

?>

このBrokenクラスは、PHP 8 のユニオン型を使用して、文字列と整数の両方を受け入れることが期待されています。しかし、ソースを見ると、実際には文字列のみを受け入れることがわかります。

私たちの架空の例では、パッケージのメンテナーは問題を認めていますが、まだ新しいリリースを作成していません。その間に、問題を回避するためにパッチを当てましょう。

壊れたファイルを、そのままコピーし、.old サフィックスを追加します:

cp vendor/example/broken-project/src/Broken.php vendor/example/broken-project/src/Broken.php.old

.oldファイルを編集しないようにしてください!

次に、元のファイルを編集して、あなたのコードベースで正しく機能するようにします。インプレースで編集しているため、変更はすぐに反映されます。あなたのコードベースが期待通りに動作するかどうかを確認してください。

<?php

class Broken {

public function __construct(string|int $foo) {

if (is_string($foo)) {

echo "Valid value!";

}

else if (is_int($foo)) {

echo "Also valid!";

}

}

}

?>

パッチファイルの作成

今、symplify/vendor-patchesプロジェクトを使用して、修正のためのパッチファイルを作成できます。このパッケージは、vendor-patchesバイナリを提供しており、自動的にvendorディレクトリをスキャンして、あなたが行った変更を見つけます。

vendor/bin/vendor-patches generate

コマンドを実行すると、差分が生成されます。それはプロジェクトのルートにあるpatchesディレクトリに保存されます。差分は、作成した.phpファイルと.php.oldファイルを比較することによって計算されます。

追加した新しいパッチを発見するために、コマンドを再度実行できます。変更された各ファイルは、patches ディレクトリ内の独自のパッチを持ちます。

自動パッチ適用

あなたのcomposer.jsonファイルの中に、新しいセクションが追加されたのが見えるでしょう:

{

"extra": {

"patches": {

"example/broken-package": [

"patches/example-broken-package-src-broken-php.patch"

]

}

}

}

patchesオブジェクトは、インストールされたパッケージの名前を、適用するパッチファイルの配列にマッピングします。これらのパッチは、composer installを実行すると自動的に適用されます。

simplify/vendor-patchesによってインストールスクリプトが登録されます。依存関係がインストールされるたびに呼び出されます。このスクリプトは、パッケージのために定義されているパッチがあるかどうかを確認します。見つけたパッチは自動的に適用されます。

パッチが適用された時期を示す行が composer install の出力に表示されます。エラーが報告された場合は、composer install --verbose を使用して、なぜパッチがスキップされたのかの詳細情報を取得できます。これはしばしば、パッケージの更新があなたがパッチをあてた問題を修正し、あなたのパッチファイルが冗長になったためです。

パッチを取り除く

パッチを一時的に削除するには、composer.jsonからその行を削除してください。これにより、composer installを実行したときにパッチが適用されなくなります。

プロジェクトからパッチを永久に削除するには、そのcomposer.jsonの行を削除します。その後、プロジェクトのpatchesディレクトリから.patchファイルを削除できます。

ローカルに適用したパッチを元に戻したい場合は、上記の手順に従ってパッチを削除または無効化するのが最も簡単です。その後、vendor ディレクトリからパッケージを削除し、composer install を実行してクリーンスレートに戻ります。

関連記事: