エンジニアとして実務で使えるスキルをオープンソース活動で身につける

こんにちは、@kentya6です。
普段は[LITALICO](https://litalico.co.jp/)という会社でエンジニアをやっています。実務では主にUnityを使用したアプリの開発を行っています。

本記事は[【Mentor Ver.】TechTrain Advent Calendar 2019](https://qiita.com/advent-calendar/2019/techtrain-mentor) 24日目の記事です。

## はじめに
私は、まだ学生時代に実務としてプログラミングをしたことがない時に、オープンソース活動に関わった経験が実務に活かされているなと感じることが多々あります。なので、今回は主に学生時代におこなったオープンソース活動の実例を挙げながら、どういったスキルが学べたかをまとめてみました。

## こんな人におすすめ
- 最近プログラミングの入門書やチュートリアルをやってみた方
- 学生などで、まだ実務としてプログラミングに関わったことがない方
- オープンソース活動は敷居が高いと感じ手を出せていない方
- ライブラリは使っているけど内部がどうなっているかあまり意識をしたことがない方


## オープンソースとは
オープンソースについての説明は以下のページをご覧ください。

> オープンソースとは、人間が理解しやすいプログラミング言語で書かれたコンピュータプログラムであるソースコードを広く一般に公開し、誰でも自由に扱ってよいとする考え方。また、そのような考えに基づいて公開されたソフトウェアのこと。

[IT用語辞典](http://e-words.jp/w/%E3%82%AA%E3%83%BC%E3%83%97%E3%83%B3%E3%82%BD%E3%83%BC%E3%82%B9.html)より

例としてはGitHubでパブリックで公開されているリポジトリが挙げられます。
オープンソースは **OSS** （**O**pen **S**ource **S**oftware）とも表現されます。

## はじめに
実務でプログラミングをする場合、担当は違えど複数人のチームで開発をすることがほとんどです。（スタートアップや小規模開発では1人での開発もありますが）
エンジニアとしてサービス開発をするにあたり把握しておきたいスキルとして、例えば以下のような項目が挙げられます。

- gitの使い方
- 環境構築や利用方法が書かれたドキュメント整備
- プログラム言語に合ったコード規約把握
- プログラム上の問題が発生した時の報告の仕方
- 命名規則やインデントが適切になされており読みやすいコード
- 開発仲間や半年後の自分が見ても分かるようなコード設計
- 言語仕様を活用した綺麗な実装（短く、分かりやすく機能を実現する）

このようなことはプログラミングの入門書やチュートリアルを触っただけでは把握できないことも多く、開発を進めていったり、久しぶりにプロジェクトのコードを触った時に混乱する経験は誰しもあると思います。
そんな時に、オープンソース活動をすることによって上記のようなスキルを磨くことができます。

## オープンソース活動をしてみる
オープンソース活動でスキルを磨くといってもどういったものがあるのでしょうか。ここではGitHubを例にオープンソース活動の例を挙げます。
各項目ごとに、私が実際に学生時代に行った事例をもとにどういったことが学べたかを紹介します。
※リポジトリの内容はiOS関係が多いですが、内容を理解するにあたりiOS固有の知識は不要です。

# 1. ドキュメントの内容を修正・追加する
多くの人が使うオープンソースでは、公開しているものがどういうプログラムなのか、どうやって利用するのか等を記述したREADMEが用意されていることがほとんどです。
プログラムを開発した人自身は内容を分かっていても、外部の人はREADMEなどのドキュメントをもとに利用方法を把握します。このドキュメントにミスや不備があれば混乱のもとになります。なのでこのミスに気づいて修正することも立派なオープンソース活動です。

私が過去に行った例としては、Swiftがオープンソースで公開された時にドキュメントの単語ミスを修正しました。
https://github.com/apple/swift/pull/122
これは特にプログラミングスキルを必要とせず、Swift自体の内部仕様を理解していなくてもできます。
このプルリクエストを出したときに `squash` してくれと言われ、その時はsquashといったものが何なのか分かりませんでした。そこから初めてgitのsquashについて把握し、squashしてコミットし直しました。このように実際のリポジトリに対して手を動かすことで、自身の経験として蓄積することができました。

ちなみにこの時はドキュメントの内容を[Grammarly](https://www.grammarly.com/)を使用してミスを発見し、修正しました。
具体的なやり方は以下が分かりやすいと思います。
[超絶簡単OSSコントリビュート術](https://qiita.com/taigamikami/items/fa21c6c50bff9a6674d9)

# 2. ライブラリ利用時の問題点を報告する
あるプロジェクトでライブラリを利用している時に、パッケージ管理ツール経由でインストールしたライブラリのバージョンが古いままだったので、その報告をしたのが以下のissueです。
https://github.com/thii/FontAwesome.swift/issues/106
投稿してから数日以内に、同じ問題にぶつかっている人がコメントしたり、最後にはライブラリの作者がどう対応すればいいかのコメントをしてくれています。
この時にどういう報告の仕方をすれば伝わるか、再現性があるか等を詳しく書きます。エラーログが出力された場合は長くても省略せずに全て添付し、作者が検証しやすいように報告します。こうしたことは実務でも同じことが言えます。


リポジトリにはどういうフォーマットで貢献してほしいか等を書いた `CONTRIBUTING.md` や `CODE_OF_CONDUCT.md` といったファイルがある場合があります。その場合はそのルールに従いましょう。
例: TensorFlowの[CONTRIBUTING.md](https://github.com/tensorflow/tensorflow/blob/master/CONTRIBUTING.md)と[CODE_OF_CONDUCT.md](https://github.com/tensorflow/tensorflow/blob/master/CODE_OF_CONDUCT.md)

英語がよく分からなくても、翻訳サイト等を駆使すれば大丈夫です。深い議論をするわけではないので簡単な英語でだいたい伝わります。英語の勉強にもなります。


# 3. バグ・不具合を修正する
googleのmaterial design用webフレームワークのデモを手元の環境で動かしている時に、ブラウザの開発者コンソールで警告が出ている箇所がありました。その箇所を見ると冗長な記述があったため、削除して警告を1つ消したのが以下のプルリクエストです。
https://github.com/google/material-design-lite/pull/983
この時も、「何をどういった環境で動かしたらどういった警告が出たのか、その警告をなくすためにどういった対応をしたのか」を明確に書くように意識して説明を書いています。
大規模リポジトリともなると、プルリクエストの際に `Contributor License Agreement`に署名するためのbotが動いていたりと勉強になることが多かったです。実務では署名はしなくても、コミットやプルリクエストに応じてCIツールを動かしたり、テスト配布用のアプリのバイナリを作成して配布する等といったワークフロー構築をする場合もあるため、参考になります。
例: [GitHub Actions](https://github.co.jp/features)


# 4. 機能追加をする
iOSでよく使用される通信ライブラリの1つとして[Alamofire](https://github.com/Alamofire/Alamofire)というのがあります。このライブラリにはファイルのダウンロード機能がありますが、当時まだデモプロジェクトにその機能の使い方がなかったため追加したのが以下のプルリクエストです。
https://github.com/Alamofire/Alamofire/pull/579
このプルリクエストは[OSS Hack Weekend](http://sezemi.hatenablog.com/entry/2015/07/16/175628)という、オープンソース活動に関わるきっかけをくれたイベント中に作成したものなので、どういう流れでこのプルリクエストを作成することになったのかの詳細は[こちら](https://github.com/clear-code/sezemi-2015/issues/67)を参考にしてください。最初にテストを実行して動作を確認し、なぜその機能追加をするのかの理由、どう対応したかが書いてあるので参考になるかと思います。実務でも同じように、思っていることや作業内容をEvernoteにメモしながら開発をしています。


# 5. ライブラリを作って公開してみる
既存ライブラリへの不具合修正や機能追加ができるようになってくると、gitの使い方はもちろんのこと、様々なライブラリの設計方法やライブラリとして利用するインタフェースとしてどういったものが良いかなどが考えられるようになってきます。
そうなると、既存のライブラリの修正ではなく、自身でより良いライブラリを開発して利用するといった選択肢も増えてきます。
その際はその開発したライブラリをオープンソース化して多くの人に使ってもらうことをおすすめします。
公開時点で車輪の再発明だとしても、ライブラリを開発する過程で多くの知見が得られますし、徐々により良いものにしていくことができます。まず手を動かしてやってみることが重要です。

私が公開したライブラリとしては、iOS向けの任意の形のプログレスバーを手軽に利用できるようにするといったものがあります。
https://github.com/kentya6/KYCircularProgress
これは既存のライブラリだと対応しているiOSのバージョンが古かったり、利用方法があまり手軽でなかったり、グラデーション対応がなかったりといったことがあったため、自身で開発しました。
この時に初めて、良いREADMEとはどういったことかを意識したり、ライセンスはどうすべきかといったことを意識するようになりました。

ライブラリの[最初のコミット](https://github.com/kentya6/KYCircularProgress/blob/78545909c976bdfe5b693c09204fc226b810049d/KYCircularProgress/KYCircularProgress.swift)と[最新のコミット](https://github.com/kentya6/KYCircularProgress/blob/ee4214f4bb460bae7ae82439cf84309872f11fc5/Source/KYCircularProgress.swift)のコードを比較すると、ライセンス記述、適切なアクセス修飾子、各メソッドへのコメント追加、プラットフォーム固有の機能の活用（＠IBDesignableなど）を意識することができるようになっています。このあたりはライブラリを公開して他の人に見られている意識がないとなかなか気づく機会がなかったかなと思います。


参考:
- [わかりやすいREADME.mdを書く](https://deeeet.com/writing/2014/07/31/readme/)
- [オープンソースソフトウェア（OSS）ライセンスの比較・まとめ、GPLやMITは何が違うのか](https://www.sbbit.jp/article/cont1/34811)


## おわりに
今回は「エンジニアとして実務で使えるスキルをオープンソース活動で身につける」という題名で、主にプログラミングをこれから実務で使っていきたい人向けに、私自身の学生時代に行ったオープンソース活動の例とそこで身についたと実感したスキルを挙げました。
手を動かしながらオープンソース活動をすることで、今まで何となく使っていたライブラリへの理解が深まり、本記事冒頭に挙げたようなスキルレベルが上がったなと実感しています。
オープンソース活動は敷居が高いと思われがちですが、プログラミングを学び始めた段階だからこそGitHub等を使ってリアルなコードを読み、そのコードを改善することで、実務でも開発が取り組みやすくなると実感しています。
本記事をきっかけに少しでもオープンソース活動をやってみようかな、と思っていただけたら幸いです。