Slide 1

Slide 1 text

もっと気軽にOSSに Pull Requestを出そう! @DQNEO (ドキュネオ) PHPerKaigi 2020/2/10

Slide 2

Slide 2 text

自己紹介 @DQNEO (ドキュネオ) ● US版メルカリを開発しています ● 趣味: ○ コンパイラ自作 (去年) ○ 英語 (いま) ○ 突然アセンブリを書いてしまう

Slide 3

Slide 3 text

※注意 このトークは初心者むけです


Slide 4

Slide 4 text

質問 PHPの有名ライブラリにコントリビュートした
 ことのある方?


Slide 5

Slide 5 text

「コントリビューション」のイメージ ○ まず、しっかり使いこなす (← すでにハードルが高い) ○ 新機能追加して便利にしたよ (← 何も思いつかない) ○ バグ見つけて直したよ (← バグとかある?) できたらカッコいいが、なかなかチャンスはない

Slide 6

Slide 6 text

私のコントリビューション実績 Symfony Guzzle AWS SDK for PHP DietCake DietCube Ethna Fluent Logger PHPBench Monolog PHPJava AssertChain ほか多数

Slide 7

Slide 7 text

4つの着眼点 1. 作者の関心ゾーンの外側を見る 2. 使ってなくてもコントリビュート 3. 業務で得たノウハウを横展開 4. ダメ元でも送ってみる

Slide 8

Slide 8 text

テストコードの可読性 着眼点1: 作者の関心ゾーンの外側を見る メインコードの 設計、実装、可読性 ● テストコードの可読性 ● テストコードのコメント ● コメント、ドキュメント ● CI設定 ● 環境変化への追従 異常 ケース

Slide 9

Slide 9 text

メインコードの 設計、実装、可読性 コメント、ドキュメント

Slide 10

Slide 10 text

例: Guzzleの README $client = new \GuzzleHttp\Client(); $res = $client->request('GET', 'https://api.github.com/user', [ 'auth' => ['user', 'pass'] ]); echo $res->getStatusCode(); // 200 echo $res->getHeaderLine('content-type'); // 'application/json; charset=utf8' echo $res->getBody(); // {"type":"User"...'

Slide 11

Slide 11 text

そのまま実行するとエラー PHP Fatal error: Uncaught GuzzleHttp\Exception\ClientException: Client error: `GET https://api.github.com/user` resulted in a `401 Unauthorized` response: { "message": "Bad credentials", "documentation_url": "https://developer.github.com/v3" }

Slide 12

Slide 12 text

Pull Request出してみた

Slide 13

Slide 13 text

PR説明欄を丁寧に書く

Slide 14

Slide 14 text

すぐマージされた https://github.com/guzzle/guzzle/pull/1658

Slide 15

Slide 15 text

いまGuzzleのトップページにある サンプルコードは 僕が書いたやつです https://github.com/guzzle/guzzle

Slide 16

Slide 16 text

https://github.com/symfony/symfony/pull/24618/files PHPDocの修正: symfony union書き忘れ

Slide 17

Slide 17 text

PHPDocの修正: Aura.Sql https://github.com/auraphp/Aura.Sql/pull/129/files エラーケースは忘れられがち

Slide 18

Slide 18 text

PHPDocの修正: guzzle/psr7 https://github.com/guzzle/psr7/pull/134/files nullになるケースはなかった

Slide 19

Slide 19 text

テストコードの可読性 メインコードの 設計、実装、可読性 テストコードの可読性 テストコードのコメント コメント、ドキュメント

Slide 20

Slide 20 text

テストコードの可読性: Symfony https://github.com/symfony/symfony/pull/11812/files パラメータの可読性向上

Slide 21

Slide 21 text

テストコードのコメント: Symfony 文章の間違いを修正 https://github.com/symfony/symfony/pull/11811/files

Slide 22

Slide 22 text

躊躇しないで シュッとPR出してみるの大事

Slide 23

Slide 23 text

PRを出す習慣が身につく 「次はもっと大きいコントリビュー ションを!」 マージされるとやる気が出る

Slide 24

Slide 24 text

テストコードの可読性 メインコードの 設計、実装、可読性 テストコードの可読性 テストコードのコメント コメント、ドキュメント 異常 ケース

Slide 25

Slide 25 text

異常ケース: guzzle handler オプションに不正な値を渡したとき

Slide 26

Slide 26 text

異常ケースの改善: guzzle コンストラクタで型をチェックする https://github.com/guzzle/guzzle/pull/1745/files

Slide 27

Slide 27 text

異常ケースの改善: guzzle エラー報告がわかりやすくなった

Slide 28

Slide 28 text

Guzzleのコンストラクタに コントリビュートした!

Slide 29

Slide 29 text

テストコードの可読性 メインコードの 設計、実装、可読性 テストコードの可読性 テストコードのコメント コメント、ドキュメント ● CI設定 ● 環境変化への追従

Slide 30

Slide 30 text

環境変化への追従、CI設定の充実 ライブラリというのは放っておくだけで古くなる ● PHPの新バージョン ● PHPUnitの新バージョン ○ 後方互換がしばしば壊れる ● 新しいPSRが策定される (例 PSR12) ● Coding Styleチェッカーや静的解析ツールの進化

Slide 31

Slide 31 text

travis.yml にPHPのバージョンを追加 これも立派な貢献 https://github.com/dietcake/dietcake/pull/35/files

Slide 32

Slide 32 text

PHPJava: .php_cs.dist を追加 https://github.com/php-java/php-java/pull/72/files

Slide 33

Slide 33 text

● エコシステム周りはチャンスの 宝庫 ● ひとつの知識を横展開できる

Slide 34

Slide 34 text

着眼点2: 業務で得たノウハウを横展開 ● 会社の巨大アプリケーションが PHPUnit ver4だった ● PHPUnit ver4 → ver7 にあげた ● バージョンアップに異常に詳しくなった ● OSS界隈を見渡すと、古いPHPUnitに依存してるライブラ リが無数にあった ● チャンス!!

Slide 35

Slide 35 text

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 → 7 etc

Slide 36

Slide 36 text

詳しくは PHP Conference 2018の資料で 大規模PHPプロジェクトでPHPUnitを3世代アップグレードするためにやったこと https://speakerdeck.com/dqneo/phpunit-upgrade-story?slide=94

Slide 37

Slide 37 text

着眼点3: 使ってなくてもコントリビュート ● 「読むだけ」でも結構見つかる ● PHPStormの警告で気づいたり

Slide 38

Slide 38 text

Symfony: 使われてない変数 https://github.com/symfony/symfony/pull/24617/files

Slide 39

Slide 39 text

Symfony: 子クラスでのreturnし忘れ https://github.com/symfony/symfony/pull/24626/files

Slide 40

Slide 40 text

Symfony: 無名関数の引数の型 https://github.com/symfony/symfony/pull/26821/files

Slide 41

Slide 41 text

Symfony: 無名関数の引数の型 https://github.com/symfony/symfony/pull/24622/files

Slide 42

Slide 42 text

無名関数の引数の型宣言は忘れられがち ● array_map(function(ここ $x){....}) ● ただし、型宣言を後から追加する場合は、 後方互換を壊さないように注意

Slide 43

Slide 43 text

着眼点4: ダメ元でも送ってみる ● 失うものはない ● 「やった方がいいのにたまたま誰もやってなかった」 ケー スもある ● 超有名レポジトリにPRしてみた

Slide 44

Slide 44 text

React: 英語の難単語を置き換え ● 公式ドキュメントで ”mandatory”(=必須)という難単 語があった ● 別の単語 ( a must ) への置き換えを提案 ● 「”mandatory”くらい普通に使うだろ」という反応を 予想していた https://github.com/facebook/react/pull/8809 ↓

Slide 45

Slide 45 text

Goコンパイラ: 変数名をリファクタ ● わかりにくい変数名を見つけた ● 10年の歴史のあるコンパイラの変数名 ● 何か深い歴史的事情があるのかも、 と思いながらも変数リネームのPRしてみた ● あっさりOKが出た https://github.com/golang/go/commit/f07059d949057f414dd0f8303 f93ca727d716c62

Slide 46

Slide 46 text

まずはPR出してみよう!

Slide 47

Slide 47 text

余談

Slide 48

Slide 48 text

余談: 1年前のPHPerkaigi

Slide 49

Slide 49 text

余談: 1年前のPHPerkaigi

Slide 50

Slide 50 text

両方達成した!

Slide 51

Slide 51 text

PHPerkaigiで登壇すると 夢が叶う!

Slide 52

Slide 52 text

つぎはあなたの番です!!