PHPerkaigi 2020 で発表した資料です。
もっと気軽にOSSにPull Requestを出そう!@DQNEO (ドキュネオ)PHPerKaigi 2020/2/10
View Slide
自己紹介@DQNEO (ドキュネオ)● US版メルカリを開発しています● 趣味:○ コンパイラ自作 (去年)○ 英語 (いま)○ 突然アセンブリを書いてしまう
※注意このトークは初心者むけです
質問PHPの有名ライブラリにコントリビュートした ことのある方?
「コントリビューション」のイメージ○ まず、しっかり使いこなす (← すでにハードルが高い)○ 新機能追加して便利にしたよ (← 何も思いつかない)○ バグ見つけて直したよ (← バグとかある?)できたらカッコいいが、なかなかチャンスはない
私のコントリビューション実績SymfonyGuzzleAWS SDK for PHPDietCakeDietCubeEthnaFluent LoggerPHPBenchMonologPHPJavaAssertChainほか多数
4つの着眼点1. 作者の関心ゾーンの外側を見る2. 使ってなくてもコントリビュート3. 業務で得たノウハウを横展開4. ダメ元でも送ってみる
テストコードの可読性着眼点1: 作者の関心ゾーンの外側を見るメインコードの設計、実装、可読性● テストコードの可読性● テストコードのコメント● コメント、ドキュメント● CI設定● 環境変化への追従異常ケース
メインコードの設計、実装、可読性コメント、ドキュメント
例: Guzzleの README$client = new \GuzzleHttp\Client();$res = $client->request('GET','https://api.github.com/user', ['auth' => ['user', 'pass']]);echo $res->getStatusCode();// 200echo $res->getHeaderLine('content-type');// 'application/json; charset=utf8'echo $res->getBody();// {"type":"User"...'
そのまま実行するとエラーPHP Fatal error:Uncaught GuzzleHttp\Exception\ClientException: Clienterror: `GET https://api.github.com/user` resulted in a`401 Unauthorized` response:{"message": "Bad credentials","documentation_url": "https://developer.github.com/v3"}
Pull Request出してみた
PR説明欄を丁寧に書く
すぐマージされたhttps://github.com/guzzle/guzzle/pull/1658
いまGuzzleのトップページにあるサンプルコードは僕が書いたやつですhttps://github.com/guzzle/guzzle
https://github.com/symfony/symfony/pull/24618/filesPHPDocの修正: symfonyunion書き忘れ
PHPDocの修正: Aura.Sqlhttps://github.com/auraphp/Aura.Sql/pull/129/filesエラーケースは忘れられがち
PHPDocの修正: guzzle/psr7https://github.com/guzzle/psr7/pull/134/filesnullになるケースはなかった
テストコードの可読性メインコードの設計、実装、可読性テストコードの可読性テストコードのコメントコメント、ドキュメント
テストコードの可読性: Symfonyhttps://github.com/symfony/symfony/pull/11812/filesパラメータの可読性向上
テストコードのコメント: Symfony文章の間違いを修正https://github.com/symfony/symfony/pull/11811/files
躊躇しないでシュッとPR出してみるの大事
PRを出す習慣が身につく「次はもっと大きいコントリビューションを!」マージされるとやる気が出る
テストコードの可読性メインコードの設計、実装、可読性テストコードの可読性テストコードのコメントコメント、ドキュメント異常ケース
異常ケース: guzzlehandler オプションに不正な値を渡したとき
異常ケースの改善: guzzleコンストラクタで型をチェックするhttps://github.com/guzzle/guzzle/pull/1745/files
異常ケースの改善: guzzleエラー報告がわかりやすくなった
Guzzleのコンストラクタにコントリビュートした!
テストコードの可読性メインコードの設計、実装、可読性テストコードの可読性テストコードのコメントコメント、ドキュメント● CI設定● 環境変化への追従
環境変化への追従、CI設定の充実ライブラリというのは放っておくだけで古くなる● PHPの新バージョン● PHPUnitの新バージョン○ 後方互換がしばしば壊れる● 新しいPSRが策定される (例 PSR12)● Coding Styleチェッカーや静的解析ツールの進化
travis.yml にPHPのバージョンを追加これも立派な貢献https://github.com/dietcake/dietcake/pull/35/files
PHPJava: .php_cs.dist を追加https://github.com/php-java/php-java/pull/72/files
● エコシステム周りはチャンスの宝庫● ひとつの知識を横展開できる
着眼点2: 業務で得たノウハウを横展開● 会社の巨大アプリケーションが PHPUnit ver4だった● PHPUnit ver4 → ver7 にあげた● バージョンアップに異常に詳しくなった● OSS界隈を見渡すと、古いPHPUnitに依存してるライブラリが無数にあった● チャンス!!
PHPUnitのバージョンアップ職人● DietCake 4 → 5 → 6 → 7● DietCube 5 → 6 → 7● Monolog 5 → 6● PHPBench 6 → 7● AWS SDK for PHP 5 → 6● AssertChain 4 → 5 → 6● Chronous 6 → 7etc
詳しくは PHP Conference 2018の資料で大規模PHPプロジェクトでPHPUnitを3世代アップグレードするためにやったことhttps://speakerdeck.com/dqneo/phpunit-upgrade-story?slide=94
着眼点3: 使ってなくてもコントリビュート● 「読むだけ」でも結構見つかる● PHPStormの警告で気づいたり
Symfony: 使われてない変数https://github.com/symfony/symfony/pull/24617/files
Symfony: 子クラスでのreturnし忘れhttps://github.com/symfony/symfony/pull/24626/files
Symfony: 無名関数の引数の型https://github.com/symfony/symfony/pull/26821/files
Symfony: 無名関数の引数の型https://github.com/symfony/symfony/pull/24622/files
無名関数の引数の型宣言は忘れられがち● array_map(function(ここ $x){....})● ただし、型宣言を後から追加する場合は、後方互換を壊さないように注意
着眼点4: ダメ元でも送ってみる● 失うものはない● 「やった方がいいのにたまたま誰もやってなかった」 ケースもある● 超有名レポジトリにPRしてみた
React: 英語の難単語を置き換え● 公式ドキュメントで ”mandatory”(=必須)という難単語があった● 別の単語 ( a must ) への置き換えを提案● 「”mandatory”くらい普通に使うだろ」という反応を予想していたhttps://github.com/facebook/react/pull/8809↓
Goコンパイラ: 変数名をリファクタ● わかりにくい変数名を見つけた● 10年の歴史のあるコンパイラの変数名● 何か深い歴史的事情があるのかも、と思いながらも変数リネームのPRしてみた● あっさりOKが出たhttps://github.com/golang/go/commit/f07059d949057f414dd0f8303f93ca727d716c62
まずはPR出してみよう!
余談
余談: 1年前のPHPerkaigi
両方達成した!
PHPerkaigiで登壇すると夢が叶う!
つぎはあなたの番です!!