またしてもWebSocketのデモアプリを作ることになりました。
それほど凝ったものを作るつもりはないので、さきに作った汎用のRedisService(のプロト)を再利用すれば簡単にできる見込みです。(^^v
が、ここでどうしたものかと考えるのはどのように再利用するか?です。
新しいプロジェクトにソースをコピーしても良いんですが、それはあまりに芸がない。。。
ちゃんとやるならプラグイン化するのが良いんでしょうが、まだプロトでしかない(=コードの改修がガンガン発生する)段階でプラグイン化しても、外側のアプリを作りつつプラグインを修正しては入れ直し。。。とやるのはかなり面倒です。。。。(--
そんな折、Heroku MeetupのLTネタを探してDevCenterをあさっていたらふとこんな文書が目に留まりました。
https://devcenter.heroku.com/articles/git-submodules
Herokuではgit submoduleが使えるらしい。。。
git submoduleって???(初耳)
★ git submoduleとは?
ググりましょう。(^^;
日本語のサイトだけでも十分な情報が得られます。
要するにあるgitプロジェクトの任意のディレクトリに別のgitプロジェクトをまるごと取り込む仕組みです。
コマンドの使い方の説明は他のサイトに譲るとしてここでは最初の課題(RedisServiceをどのように再利用するか?)に対して、どの程度有効であるかを検証します。
★ とりあえずsubmoduleプロジェクトを作ってみる
今回作成するのはPlay2で使用する(広義の)プラグインです。
submoduleとして取り込む場合はappディレクトリに任意のディレクトリを作成してそこに取り込むことになります。
なので、submoduleのプロジェクトはそれにあわせたディレクトリ構成になっていなければならない訳ですが、幸いにもScalaにはpackageとディレクトリ構成が同じでなければならないという制限はありません。
またREADME.md等コンパイルと無関係なファイルがapp以下にあってもPlayは単純にそれを無視するだけです。
これを踏まえて、
パッケージ名: flect.redis
ファイル構成:
- README.md
- src/flect/redis/RedisService.scala
という構成でsubmoduleプロジェクトを作成しました。
https://github.com/shunjikonishi/play-redis-submodule
新規のPlayプロジェクトでこれをsubmoduleとして使用する方法はREADMEに記載した通りです。
app/redisディレクトリの下にsrcというディレクトリが現れるのはあまり一般的なディレクトリ構成ではありませんが、Playでは実行に問題ありません。
(もちろんsubmodule側でこれとは異なるディレクトリ構成を採用してもOKです。)
★ 何が嬉しいの?
ずばり外側のアプリを作りながら内側のライブラリを改修できることです。
submoduleのディレクトリはそのディレクトリに入ってしまえば通常のgitのディレクトリと変わりありません。
なので、普段と同じようにそこで修正、commit、pushなどを行うことができます。
外側のgitではsubmoduleのコミットIDしか管理していないので内側のsubmoduleを更新した場合は、外側でそのsubmoduleのadd/commitが必要になります。
ネット上ではここでsubmoduleと外側のgitが連動しないのがわかりにくい、という意見もいくつか目にしましたがこれはむしろ好都合。。。というよりも完全に意図的にこういう仕様にしていると思います。
これはさらに別のプロジェクトで同じsubmoduleを使うケースを考えてみるとわかります。
別のプロジェクトに同じsubmoduleを追加して、そこでもsubmodule側になんらかの修正を加えたくなったとします。
この場合修正はどこで行うべきでしょうか?
答えはもちろんそのプロジェクトのディレクトリの中で修正してしまえば良いのです。gitのリポジトリはどこが正ということはないので、どこで修正したって構わない訳です。
ここでの修正は既存の別プロジェクトには影響を与えませんし、必要ならばそっちでもpullすればOKです。
★ どこで使えそう?
今回はPlay/Scalaで使いましたが、考え方自体はシンプルなので他のフレームワークでも応用可能です。(Javaみたいにパッケージ名の制約があるものはちょっと悩ましいですけど。。。)
ですが、本命はなんといってもJavaScriptですね。既存のライブラリに手を加えて使うこともちょいちょいありますが、それがそのままgitリポジトリであるならプルリクしようかという気にもなるしバージョンアップも楽です。
書いてて気がついたけど、プルリクするような汎用的な修正じゃない場合でもバージョンアップと同時にマージできちゃいますね。素晴らしすぎる。(^^v
他にも社内ユース専用のちょっとした小物ライブラリなんかもこっちの管理方法の方がマッチすることが多いんじゃないでしょうか。
正直SBTにはかなりうんざりしているので、これは新しい時代の依存性管理の仕方としてアリなんじゃないかとさえ思います。