はらへり日記

腹に弾丸

社内で横断的に使えるPHPライブラリを書こう!

この記事は

アイスタイルアドベントカレンダー3日目の記事です。

タイトル的に技術知見っぽいんですがどちらかと言うとポエムに近いのであしからず。。。

qiita.com

社内の共有ライブラリを作る

弊社といえば化粧品クチコミサイトの@cosmeを運営していることで有名だと思うのですが、

実は@cosme以外にもかなり多くのサイトを運営しています。

それらの大半はPHPで実装されており、そのバージョンや使用しているフレームワークは多種多様です。

そうなると問題になってくるのが社内で同じような処理を実装したものが各所で発生することです。

弊社の例でいうと以下のような実装コードが数々のリポジトリで見られるようになりました。

  • タグのバリデーション実装
  • 社内APIとの通信処理
  • OAuth認証のロジック

せっかく言語が共通なのにこれらの処理とテストを新しく実装するたびに作っているのはもったいないなと感じ、

いくつか社内で使いまわせるライブラリを作りました。

この記事ではその時に得られたノウハウを共有したいと思います。

目指すこと

まず初めに、社内ライブラリを作る際に目指すことを考えます。

  • Composerによる配布を前提とする
  • 保守性の高さを意識する
  • 属人性を排除する

Composerによる配布

この時点でPHP5.3.2+が必須になってしまいますが、下位互換性を意識すると出来ることの幅が狭くなるのでここでは意識しません。

PHP5.5以下はサポート切れてますし…ね…

社内ライブラリなのでOSS化できない場合はPrivateな環境で配布する必要があります。

この際、Gitを導入していればComposer配布が可能になります。

まずは作成したリポジトリをComposerで落とせるようにするところまでやってみます。

Composerパッケージを作る

Gitリポジトリを作成したらカレントディレクトリでcomposer initを実行します。

すると対話式で作成するComposerパッケージについて聞かれるので答えていきましょう。

入力が完了するとcomposer.jsonが自動で生成されます。

これで最低限の配布準備は完了です。簡単!

Composerライブラリを落とす

Composerは通常、Packagistでパッケージを配布し、インストールします。

ですが、明示的にgitリポジトリのURLを指定することでPackagistからでなくgitサーバーからパッケージをインストールすることが可能になります。

まず、インストールしたいリポジトリcomposer.jsonrepositoriesという項目に追記します。

{
  "repositories": {
    "type": "git",
    "url": "https://github.com/private_organization/sample_repo"
  }
}

これでcompsoer require private_organization/sample_repoを叩くことでパッケージを落とすことができます。

これでPrivateなgitサーバーからComposerパッケージを配布することができます。

開発する

ここから実際に実装したいコードを開発していくことができますが、1年間やってきてこうすればよかったよというのを述べていきます。

第三者がプルリクを出せる環境を作る

社内で共有ライブラリを作り、浸透していくとバグ修正や機能追加のプルリクが飛んで来ることがあります。

その際、必ずしもレビューするのはライブラリ作成者ではないのでライブラリの品質を担保できなくなる場面が時たまあります。

例えばテスト未実行によるデグレやコーディング規約の揺れ、ドキュメント不足等がそれにあたります。

頑張ってそれらを取り締まる共有ライブラリ警察をやってもいいのですが、せっかくプログラマーをしてるので自動化できる部分は自動化してしまうとよいです。

弊社の流れで言うと

  • GitHubにプルリクエストが来る
  • Jenkinsでテストジョブを実行する
    • このジョブが通らないとマージボタンが押せないようになっている
  • PHPUnitによる単体テスト、cs-fixerによる構文チェック等が行われる

と言った形で、テストの実行漏れやコーディング規約の制約をブランチテストという形で課しています。

また、GitHubを使用している場合はCONTRIBUTING.mdを追加することでプルリクを出す際にそれを読むよう促してくれたり、.githubディレクトリにテンプレートを入れるとPull Requestのテンプレートを追加できたりします。

ドキュメントの追加等、開発者にしてほしい作業があればそのテンプレートにチェックボックス形式で追加することで作業を促しています。

バージョン管理を厳密に行う

ライブラリが社内に浸透していくと破壊的変更を行った時の影響範囲が大きくなります。

なのでバージョニングはセマンティックバージョニングに従い厳密に行います。

どんなに些細な変更でもAPI変更があればメジャーバージョンをあげることでバージョン変更によるバグが起きない用心がけましょう。

コードレビューは誰がするのか

作成するライブラリがどのプロジェクトにも該当しない場合、コードレビューを誰に頼めばいいかわかりづらい状況でした。

なので弊社ではSlackに#codereviewチャンネルを作成し、「自分の分かる言語ならレビューしていいよ」という人を募ってそこにレビュー依頼を投げるようにしました。

そうすることでレビューを投げる先が明確になり、放置されるPull Requestの数が減りました。

布教する

個人的に、これがかなり大事だと思っています

テストも完璧、ドキュメントも完璧な品質の高い便利ライブラリを作っても誰にも使われなければ時間の無駄になってしまうし保守もされなくなっていきます。

なので社内ライブラリを作ったら必ず社内に宣伝するようにしています。

社内wikiで「こんな便利ライブラリを作りました」と言って使い方を詳しく解説したり、その記事をSlackの#generalチャンネルに貼り付けたり。

また、自分がそのタイミングで入ってるPJTで採用できそうなら積極的に採用し、運用実績を作ると結構みんなノリ気になってくれることが多いように感じます。

社内ライブラリを作ってよかったこと

業務改善や再実装の無駄の排除はもちろんなのですが、それ以外にもよかったことがいくつかありました。

自分の勉強になる

ライブラリを作成するとフレームワークに頼って開発してるときと違い、全て1から自分で考えなければなりません。

どんなフォルダ構成にするのか。ライブラリのInterfaceはどうするのか。どこまで汎用化、抽象化するのか。

そういったことを考えるために普段使ってるライブラリのソースコードを読んだり、社内のできる先輩に設計を相談することでコーディングの知見を多く得られました。

社内に文化を広める

弊社は元々、OSS指向の人は多くなくGitHubによるプルリクエスト開発も導入して何年も経っていません。

なので隣のPJTのコードを読むとか、それにプルリクを出すと言ったことはほとんどありませんでした。

しかし、社内ライブラリが少しずつ増え、お互いコードレビューをしていくうちにその知見を各PJTで持ち帰ってもらったり、テストの書き方を学んでもらったりと社内の技術知見の風通しが改善されました。

普段はなかなか関わらない人と「このライブラリこう使いたいんだけど」みたいな相談をしたりとコミュニケーションも増え、100人規模になった弊社としては非常によい効果をもたらしていると感じています。

自分の名前を社内に残せる

これは完全にネタなんですが、私が作ったlaravel/socialiteを社内のOAuth向けに拡張したライブラリがあるのですが、そのGitHubリポジトリの作成を上長に依頼した時に

上長1「名前何にしましょう」

私「socialiteの拡張なのでis_auth_socialiteでお願いします」

上長2「sugi_socialite」

上長3「sugiurasocialite」

上長1「了解です」

私「ちょっと何言ってるかよくわからないです」

上長2「sugiura」

上長1「sugiulite」

上長3「sugiuliteいいですね!それでいきましょう。ぜひ」

私「マネージャー×3にいじめられてる…社会ってコワイ…」

って茶番がSlackに繰り広げられた末に弊社にはsugiuliteというライブラリが存在します。私の名前は杉浦です。

というわけでみなさんも積極的に社内ライブラリを作っていきましょう。楽しいです👏

明日は

明日はanntoque君の「changefinderの詳細について書く」だそうです。

お楽しみに!