Lock in $30 Savings on PRO—Offer Ends Soon! ⏳

#phperkaigi 作って遊ぼう!Composer Plugin

#phperkaigi 作って遊ぼう!Composer Plugin

PHPerKaigi2022での資料です。
https://fortee.jp/phperkaigi-2022/proposal/cc3f627d-4268-455e-9faf-fe7194a0c343

セッションでの発表時に利用していたものに加筆・修正したものになります。

- 一部のスライドの構成、表現などの変更
- Appendixの追加

hideki kinjyo

April 10, 2022
Tweet

More Decks by hideki kinjyo

Other Decks in Programming

Transcript

  1. PHPer͸ComposerʹٹΘΕ·ͨ͠ ͋Γ͕ͱ͏໊લۭؒɺ͋Γ͕ͱ͏Φʔτϩʔυ • 2006೥ / PHP5.1.2: spl_autoload_registerͷࢥ͍ग़ • 2009೥ /

    PHP5.3.0: ॳΊͯͷ໊લۭؒͷࢥ͍ग़ • 2009೥: PHP Standards GroupͱPSR-0ͷࢥ͍ग़ • 2010೥: SplClassLoader(RFC)ͷࢥ͍ग़
  2. ࣗݾ঺հ • ⾦城秀樹 / きんじょうひでき • GitHub: @o0h / Twitter:

    @o0h_ • 好きなFWはCakePHP • アイコンは 美味しい鮭親⼦丼の写真です
  3. ͓͠ͳ͕͖ 1.ຊ౰ʹ͋ͬͨʂComposer Plugin ʙ࣮ྫἫʙ 2. ֓આ: Composer Plugin 3. ͘͢͝؆୯ͳPluginͷ࣮૷ྫ

    4. ৭ʑͳPluginͷத਎ΛงғؾͰಡΜͰΈΔ 時間に余裕があれば!
  4. composer require symfony/thanks { ֦ுϙΠϯτ: ಠࣗͷίϚϯυΛ௥Ճ͢Δ } • `composer thanks`ͱ͍͏ίϚϯυΛ௥Ճ

    • ͋ͳͨͷϓϩδΣΫτͰ͓ੈ࿩ʹͳ͍ͬͯΔύοέʔδʹ GitHubͷελʔΛૹͬͯ͘ΕΔʂ
  5. composer require phpstan/extension-installer { 拡張ポイント: パッケージの追加時の挙動を追加する } • PHPStanのextensionがrequire/update時に、 ⾃動的にプラグインを有効化

    • PHPStanが読み込みに⾏くように設定ファイルに追記 • 設定ファイルを⼿動でいじる必要がなくなる!
  6. composer require bamarni/composer-bin-plugin { ֦ுϙΠϯτ: Πϯετʔϧͷઓུ(ϑΝΠϧͷ഑ஔઌ)Λมߋ͢Δ } • ։ൃܥͷπʔϧ(౳)Λɺ௨ৗͷvendorͱ͸ผͷ৔ॴʹ഑ஔ͢Δ •

    ؒ઀తʹґଘ͢Δύοέʔδ౳ͷίϯϑϦΫτΛղফ͢Δ • ʮϓϩμΫτίʔυͱlinterπʔϧͰཁٻ͢Δόʔδϣϯ͕ҧ ͏ʂʯͱ͍ͬͨ࣌ʹ΋ɺʮͦΕͧΕ͕ඞཁͳґଘόʔδϣϯΛ ֬อ͢Δʯ͜ͱ͕Ͱ͖Δ
  7. ݁ہͳΜͳͷͰ͔͢ʁ doc: https://getcomposer.org/doc/articles/plugins.md • “You may wish to alter or

    expand Composer's functionality with your own.” • “In these cases you could consider creating a plugin to handle your specific logic.” 意訳: 君だけのComposerロジックを⼿に⼊れろ!
  8. ಠࣗίϚϯυͷొ࿥ { Capability } Plugin͔ΒɺComposerʹରͯ͠ ʮར༻ՄೳͳίϚϯυҰཡͷऔಘํ ๏ʯΛڞ༗͢Δɻ `Capable::getCapabilities(): array<class-string, class-string>`

    ͷ࣮૷ ྫ: bamarni/composer-bin-plugin ࢀߟ 4FUUJOHVQBOEVTJOHQMVHJOT$PNQPTFS IUUQTHFUDPNQPTFSPSHEPDBSUJDMFTQMVHJOTNEQMVHJO DBQBCJMJUJFT
  9. Plugin Composer プラグイン本体 <Interface> Capable プラグインを 読み込むよ! お、Capability持ってるな 独⾃のコマンドを 提供できます!

    詳しくは プロバイダを参照! <Interface> CommandProvider プロバイダ どんなコマンド ある? コマンドの ⼀覧です! <Interface> PluginInterface コマンド Command DO COMMAND! I DO!
  10. Plugin Composer プラグイン本体 <Interface> EventSubscriberInterface プラグインを 読み込むよ! お、Subscriberだな <Interface> PluginInterface

    何を購読してる? 購読の⼀覧です! 処理 イベント発⽕ それ購読してる! I DO SOMETHING!
  11. コマンドの 前処理に⼊るよ! その前に◦◦が使えるか チェックして! イベント プラグイン パッケージの meta情報をDLしたよ! ライセンスを 確認して!

    パッケージの インストールを 完了したよ! tests以下は削除して! レポジトリ情報を 取得するよ! VPN有効? サーバー接続確認して! ྫ: Πϕϯτ㲗ϓϥάΠϯͰ৭ʑͳֻ͚߹͍͕Ͱ͖Δͷਤ .lockファイルを 書き込んだよ! minifyして!
  12. ͲΜͳΠϕϯτ͕͋ΔͷͰ͔͢ʁ • େ·͔ʹ4ܥ౷ͷΠϕϯτ͕͋Δ • Plugin Events / Command Events /

    Package Events / Installer Events • Πϕϯτ͸ͦΕͧΕʹԠͨ͡ίϯςΩετ৘ใΛؚ༗ͯ͠ ͓ΓɺϦεφ͸ͦΕΒͷ৘ใͱCompoerΦϒδΣΫτɾIO ΦϒδΣΫτΛ૊Έ߹Θͤͯ೚ҙͷॲཧΛ࣮૷͢Δ ࢀߟ &WFOUOBNFT IUUQTHFUDPNQPTFSPSHEPDBSUJDMFTTDSJQUTNEFWFOUOBNFT
  13. 1. Plugin Events ComposerͷجװΛ୲͏ॲཧͱͰ΋ݴ͏΂͖λΠϛϯάʹൃՐ͞ΕΔ { ओͳΠϕϯτ } ComposerΦϒδΣΫτͷॳظԽɺCommandͷॳظԽɺϑΝΠϧͷDLલޙͳͲ { ओͳίϯςΩετ

    } ʮϑΝΠϧͷμ΢ϯϩʔυલʯͰ͋Ε͹ʮऔಘઌͷURL৘ใʯɺʮCommandͷ ࣮ߦલ(ॳظԽத)ʯͰ͋Ε͹ʮೖྗ৘ใʯͱ͍ͬͨίϯςΩετΛѻ͑Δ ※ ϓϥάΠϯ಺෦΍ؔ࿈ॲཧʹ͍ͭͯͷΠϕϯτͱ͍͏ࣄͰ͸ͳ͘ɺ ʮϓϥάΠϯͱ͍͏ར༻ऀͷͨΊʹ༻ҙ͞ΕͨΠϕϯτͱ͍͏ػߏͷ͏ͪɺҰൠతͳ΋ͷʯΈ͍ͨͳχϡΞϯεͳͷͩ ͱࢥ͍·͢
  14. 3. Package Events ύοέʔδݸผͷల։΍഑ஔɺআڈͷલޙʹൃՐ͞ΕΔ { ओͳΠϕϯτ } ֤ύοέʔδʹର͢Δʮinstallʯʮupdateʯʮremoveʯͷ࣮ߦલɺ ࣮ߦޙ {

    ओͳίϯςΩετ } ର৅ύοέʔδ৘ใ(໊લɾόʔδϣϯetc)ɺૢ࡞಺༰(৽͘͠ஔ͘ͷ ͔ɺߋ৽͢Δͷ͔ɺআڈ͢Δͷ͔)ͱ͍ͬͨίϯςΩετΛѻ͑Δ ※ల։ = ΞʔΧΠϒͷղౚɺ഑ஔ = vendorσΟϨΫτϦԼ΁ͷҠಈ
  15. 4. Installer Events ύοέʔδશମͷ഑ஔ࣮ߦલʹൃՐ͞ΕΔ { ओͳΠϕϯτ } ಛఆ͞Εͨύοέʔδͷऔಘ΍഑ஔͷલ { ओͳίϯςΩετ

    } ഑ஔΛߦ͏͔dry-run͔ɺҰ࿈ͷ഑ஔॲཧΛྻڍͨ͠಺༰(τ ϥϯβΫγϣϯ)ͱ͍ͬͨίϯςΩετΛѻ͑Δ
  16. Ͳ͏͍͏ॲཧ͕ڬΊΔͷʁ • PluginΦϒδΣΫτ͸ɺComposerΦϒδΣΫτͱIOΦϒ δΣΫτΛར༻Ͱ͖Δ • Composer͕࢖͑Δ = PJ৘ใ΍ύοέʔδ৘ใΛѻ͑Δ • IO͕࢖͑Δ

    = ίϯιʔϧ΍ϑΝΠϧ΁ͷೖग़ྗΛѻ͑Δ • EventΦϒδΣΫτɾCommandΦϒδΣΫτͱˢͷ2ͭΛ ૊Έ߹Θͤͯɺ೚ҙͷॲཧΛ࣮ݱ͍ͯ͘͠
  17. ͲΜͳΠϕϯτ͕͋ΔͷͰ͔͢ʁ • େ·͔ʹ4ܥ౷ͷΠϕϯτ͕͋Δ • Plugin Events / Command Events /

    Package Events / Installer Events • Πϕϯτ͸ͦΕͧΕʹԠͨ͡ίϯςΩετ৘ใΛؚ༗ͯ͠ ͓ΓɺϦεφ͸ͦΕΒͷ৘ใͱCompoerΦϒδΣΫτɾIO ΦϒδΣΫτΛ૊Έ߹Θͤͯ೚ҙͷॲཧΛ࣮૷͢Δ ࢀߟ &WFOUOBNFT IUUQTHFUDPNQPTFSPSHEPDBSUJDMFTTDSJQUTNEFWFOUOBNFT ࠶ܝ
  18. EventΫϥεͱEvent໊ͷఆٛ • `◦◦Events` ΫϥεʹΠϕϯτ໊ͷҰཡ͕ఆٛ͞Ε͍ͯΔ • ex) ` Composer\Script\ScriptEvents::PRE_UPDATE_CMD // ’pre-update-cmd’`

    • `◦◦Event` Ϋϥε͕छྨʹԠͨ͡ΠϕϯτͷΫϥεʹͳΔ • ex) `Composer\Script\Event extends Composer\EventDispatcher\Event` • Plugin EventsܥͷEventͷΈಛघͰɺʮEvents - Eventʯͷؔ܎͕1:NʹͳΔ • EventΫϥεͷίϯετϥΫλͷҧ͍ʹΑΓɺίϯςΩετʹԠͯ͡Ҿ͖౉͞Ε Δ৘ใͷࠩҟ͕ੜ͍ͯ͡Δ
  19. ֤Πϕϯτ܈ͷॴࡏ(◦◦Events) Πϕϯτ໊͸ɺ4ͭͷఆٛΫϥεͰఆٛ(ྻڍ)͞Ε͍ͯΔɻ 4ܥ౷ͷΠϕϯτ͸ɺͦΕͧΕҟͳΔnamespaceʹଐ͢Δ 1. Plugin Events => Composer\Plugin\PluginEvents 2. Command

    Events => Composer\Script\ScriptEvents 3. Package Events => Composer\Installer\PackageEvents 4. Installer Events => Composer\Installer\InstallerEvents ࢀߟ $PNNBOE&WFOUT IUUQTHFUDPNQPTFSPSHEPDBSUJDMFTTDSJQUTNEFWFOUOBNFT
  20. • EventDispatcher͕ɺΠϕϯ τͷछྨʹԠͯ͡ϥοϓͨ͠ σΟεύονϝιουΛ࣋ͭ • Plugin EventsܥͷΠϕϯτʹ ͍ͭͯ͸ɺૉͷ `dispatch()`͕ ར༻͞ΕΔ

    • EventΦϒδΣΫτͷੜ੒ ͷ੹೚Λݺͼग़͠ଆʹҕͶ Δ ؔ࿈: EventDispatcher Composer\EventDispatcher\EventDispatcher +dispatch($eventName, $event) +dispatchScript($eventName, $devMode = false, $additionalArgs, $flags) +dispatchPackageEvent($eventName, $devMode, $localRepo, $operations, $operation) +dispatchInstallerEvent($eventName, $devMode, $executeOperations, $transaction)
  21. Πϕϯτ໊Ұཡ: Plugin Eventsᶃ src: \ Composer\Plugin\PluginEvents • init ComposerΠϯελϯεͷ࡞੒࣌ ※Ұ෦ͷCommandΫϥεͰ͸executeϝιου಺ͰComposerΠϯελϯεΛ

    ੜ੒͢Δॲཧ͕ೖΔͨΊɺ1ίϚϯυͷ࣮ߦ࣌ʹ2ճൃՐ͢ΔՄೳੑ͕͋Δ • pre-command-run ComposerίϚϯυͷ࣮ߦલ(ίϚϯυΦϒδΣΫτͷॳظ Խ࣌)
  22. Πϕϯτ໊Ұཡ: Plugin Eventsᶄ src: \ Composer\Plugin\PluginEvents • command ComposerίϚϯυͷ࣮ߦ࣌(ίϚϯυىಈ௚ޙ) •

    pre-file-download /post-file-download ϑΝΠϧͷDLલޙ(ύοέʔδ৘ใɺύοέʔδຊମ౳) • pre-pool-create ґଘؔ܎ղܾͷͨΊͷPoolΦϒδΣΫτ࡞੒લ ※ `PluginEvents::command` ͱɺυΩϡϝϯτ্ͰʮCommand Eventsʯͱͯ͠঺հ͞Εͯ ͍Δ `ScriptEvents::xxx` / `ScriptEvent`͕ଘࡏ͢Δͷ͕ฆΒΘ͍͠ɾɾɾ
  23. Πϕϯτ໊Ұཡ: Command Eventsᶃ src: \Composer\Script\ScriptEvents • pre-install-cmd / post-install-cmd .lockϑΝΠϧ͕ଘࡏ͢Δࡍͷ

    `composer install` ͷલޙ • pre-update-cmd / post-update-cmd `composer update`ɺ΋͘͠͸ .lockϑΝΠϧ͕ଘࡏ͠ͳ͍ ࡍͷ `composer install` ͷલޙ
  24. Πϕϯτ໊Ұཡ: Command Eventsᶄ src: \Composer\Script\ScriptEvents • pre-status-cmd / post-status-cmd `composer

    status` ͷલޙ • pre-archive-cmd / post-archive-cmd `composer archive` ͷલޙ • pre-autoload-dump / post-autoload-dump `composer install[update]`ͷautoload࡞੒ϑΣʔζ΍`composer dumpautoload` ͷલޙ • post-root-package-install / post-create-project-cmd `composer create-project` ͷલޙ
  25. Πϕϯτ໊Ұཡ: Package Events src: \Composer\Installer\PackageEvents • pre-package-install / post-package-install ύοέʔδͷΠϯετʔϧલޙ

    • pre-package-update / post-package-update ύοέʔδͷΞοϓσʔτલޙ • pre-package-uninstall / post-package-uninstall ύοέʔδͷΞϯΠϯετʔϧલޙ
  26. ิ଍: ͳͥPlugin Events͸ʮPluginʯͳͷ͔ʁ • ͦͷޙɺΑΓ൚༻తͳ֦ுػߏΛೖΕΑ͏ͱ͍͏͜ͱͰPluginͷ ΞΠσΟΞ͕औΓೖΕΒΕͨ • ౰ॳ͸ʮಛघͳϨϙδτϦ͔ΒύοέʔδΛऔಘ͢ΔΧελϜ ΠϯετʔϥʔʯͷΑ͏ͳϢʔεέʔεΛ૝ఆ •

    ͦͷࡍʹ༻ҙ͞Εͨͷ͕PluginEvents.php • ࠷ॳʹcommand, pre-file-download͕ఆٛ͞Ε͍ͯͨ ࢀߟྺ্࢙ͷٞ࿦΍εφοϓγϣοτ IUUQTHJUIVCDPNDPNQPTFSDPNQPTFSQVMM IUUQTHJUIVCDPNDPNQPTFSDPNQPTFSQVMM
  27. 2. σόοά༻Φϓγϣϯ • ֤ίϚϯυڞ௨ͷΦϓγϣϯͱͯ͠ `-vvv` ͕͋Γɺσόοά৘ใͷ ग़ྗΛߦ͑Δ • ؀ڥม਺ `COMPOSER_DEBUG_EVENTS=1`

    ʹ͢ΔͱɺΠϕϯτͷ ൃՐ৘ใͷग़ྗΛߦ͑Δ • ͦͷଞʹ΋ɺHOME΍CACHEͷσΟϨΫτϦͷมߋ΍ɺωοτ ϫʔΫͷແޮԽͱݴͬͨ։ൃ࣌΍σόοάʹศརͳ߲໨΋ ࢀߟ  $-*(MPCBM0QUJPOTcIUUQTHFUDPNQPTFSPSHEPDDMJNEHMPCBMPQUJPOT  $-*&OWJSPONFOU7BSJBCMFTcIUUQTHFUDPNQPTFSPSHEPDDMJNEFOWJSPONFOUWBSJBCMFT