近年はモノレポでやるのが個人的にはやりやすいと感じていて、自分のリポジトリも仕事のリポジトリもその方向へ向かうようにしている。 (仕事のリポジトリは色々な事情があるので自分のリポジトリほどモノレポ構成にはなってないが)
いくつかのモノリポジトリを作ってきていつも悩むのがリポジトリ全体の構成。 リポジトリの構成にベストプラクティスは存在しなく、組織や用途などによって意図は様々なので組織の数だけやり方があるのかもしれない。
しかしいくつかの方針はあるのでそれを紹介しモノレポをどのように構成するかについて考えたい。
Language based
これはどうやら Google がやっている方針らしい。 実際に Google のモノレポを見ることは出来ないが OSS のリポジトリでその片鱗を見ることができる。 例えば vitess なんかはこの方針で管理されているように見える。
リポジトリの直下は言語ごとのディレクトリになっており、各言語ディレクトリの下は各言語のスタイルに合わせて配置する。 各言語ディレクトリ以下ではプロジェクトやプロダクト単位でディレクトリを分けたりせずにフラットに配置するようだ。
プロジェクト・プロダクト単位のディレクトリ分けを行うと組織変更のたびに大きな再構成が発生したりすることを嫌っているのだろう。 また同一言語は特定のディレクトリ以下に集まっているので同じ機能を実装しているコードを探しやすい。
一方デメリットとしてはザ・モノレポなのでリポジトリ全体をひと塊のように扱わないと行けないということである。 企業の社内リポジトリがモノレポでそのうち一部を OSS として公開したいといった場合に大変相性が悪い。 相性が悪いというより不可能に近い。
Project based
前項で軽く触れたがプロジェクト・プロダクトを起点にディレクトリを構成する方法である。
前職で管理していたリポジトリはこのやり方をしていた。
組織で一つで、コミットする人がかなり多い場合はこの方法はあまり上手く回らないだろう。 組織変更などで大きく構成変更が生じるかもしれない。 また同じ機能が各ディレクトリで実装されるかもしれないので、効率という面も少し劣る。
しかしこれらが避けられる状況であれば比較的上手く回ると思われる。
実際に前職で管理していたリポジトリは上手く回っていた。 これはリポジトリにコミットする人がそれほど多くなく、全体を把握できるレベルだったこと。 更に大きく触る人が限られていたのでコードの再利用をしたければ上位のライブラリディレクトリにコードを移動してから各プロジェクトで使うようにするなどの工夫をしていた。
コードを手に入れるともれなく全部手に入るというモノレポのメリットは大きく享受することができる。 とりあえずリポジトリのトップから grep すれば探しものをすることができる。 これが Poly repo だとそうはいかなく、串刺しで全てを検索する手段が用意されていないと新たにチームに参加する人がツライだけである。
Google のようにリポジトリが大きすぎて全体をチェックアウトできないというレベルであればコード検索に専用のサービスが必要なようだが、世界でその規模になる会社は数社であると考えられるので大半の会社では grep で事足りる。
なお過去の経験上、1000万行くらい入っているリポジトリでも grep で検索してコードの海を泳ぐことができる。(当時は ag はなく、 ack や git grep だったが) これくらいのコード規模でもそのコードの海の泳ぎ方さえ分かればそれほど苦労はしない。
Functional area based
機能ごとにディレクトリを分けるというやり方。
例えば HTTP 関連であれば言語に関係なく http
というディレクトリの下に入れるといった方法である。
このリポジトリ構成方法は試したことがなく、どのような使い心地になるのか正直よく分からない。 興味があるという方にぜひ試していただきたい。
Mixed
前述の3つの方法を混ぜて構成する方法である。 Facebook なんかはこのやり方をしているのではないかと予想している。
Facebook は OSS とも上手く付き合えているようで、結構な数のリポジトリを外に出している。 正直外部公開しているリポジトリは内部のモノレポから切り出しているのか、全く別にメンテしているのかはよく分からない。 ただ、もし前者で内部のリポジトリから切り出しているとしたら前述のいずれにも当てはまらない方法もしくは混合した方法にしているのではないだろうか。
結局どれがいいのか
というのは冒頭でも書いたように、リポジトリごとにモノレポにする意図が様々であると思われるのでそれに合わせて選択すれば良い。
ただ、一度成長したリポジトリの構成を変更するには相当な労力と痛みが伴うと思われる。 なので最初にモノレポにする意図をよく考えることが重要だと思う。
個人的には Project based と Language based のミックスで良い落とし所を見つけたいと思っている。 やはり個人のリポジトリであっても一部を別リポジトリとして切り出したいということがある。