寝ても覚めてもこんぴうた

プログラム書いたり、ネットワーク設計したり、サーバ構築したり、車いじったり、ゲームしたり。そんなひとにわたしはなりたい。

sbtのマルチプロジェクトを試す(build.sbt編)

まえがき

sbtを使ってAkkaのギッハブみたいにカッコ良くマルチプロジェクトをキメてみたいですよね? sbtは build.sbtBuild.scala の2つの設定の記述方法がありますが、まずは build.sbt でマルチプロジェクトを作ってみましょう。

こんな雰囲気で作りたい

/app-root
│
├── activator                       # <- activator起動スクリプト
├── activator-launch-1.3.2.jar
├── build.sbt                       # <- 全モジュールをまとめるbuild.sbt
│
├── modules
│   ├── app1                        # <- commonに依存している
│   │   └── build.sbt               # <- app1用のbuild.sbt(存在しない場合もあり)
│   │
│   ├── app2                        # <- commonに依存している
│   │   └── build.sbt               # <- app2用のbuild.sbt(存在しない場合もあり)
│   │
│   ├── common                      # <- 共通ライブラリ
│   │   └── build.sbt               # <- common用のbuild.sbt(存在しない場合もあり)
│   │
│   └── ...
│
├── documents
│   └── ...
│
└── etc

前提

  • modulesディレクトリ配下に各モジュールを配置する
  • app1はcommonライブラリに依存している
  • app2はcommonライブラリに依存している

いざ構築

/parent
│
├── activator
├── activator-launch-1.3.2.jar
├── build.sbt                       # <- parent用のbuild.sbt(A)
│
├── modules
│   ├── app1                        # <- commonに依存している
│   │
│   ├── app2                        # <- commonに依存している
│   │
│   ├── common                      # <- 共通ライブラリ
│   │
│   └── ...
│
├── documents
│   └── ...
│
└── etc

そして、作成するファイルの内容は以下の様な感じ

name := "root"

version := "0.2.0"

lazy val app1 = (project in file("modules/app1"))
  .enablePlugins(PlayScala)  // Playアプリケーションの場合
  .dependsOn(common)

lazy val app2 = (project in file("modules/app2"))
  .dependsOn(common)

lazy val common = project in file("modules/common")

動作チェックしてみます

1. 全プロジェクトまとめてビルドする
./activator package

or

./activator dist

で実行が可能

2. モジュール単位でのビルド実行をする
./activator
> project {target-project}  <- projectコマンドの引数にモジュール名を渡してプロジェクトを切り替える
> package

  or

> dist

で実行が可能

良い所・悪い所

よいところは
  • 一つののプロジェクトとしてまとまっているため、IDEリファクタリングの際に依存しているライブラリの修正が利用している側に反映される
  • 冗長なbuild.sbtの記述を排除できる。(同じような設定は共通化できる)
  • (Build.scalaと比較すると)build.sbtに慣れている場合の学習コストが抑えられる。
わるいところは
  • 複数のプロジェクトを別ブランチを作成して並行して作業するばあい、行ったり来たりが面倒。

総評

Akkaのプロジェクトもマルチプロジェクトになっていることを考えると、やり方としては正しそうな気がする。 file(git://hoge/huga.git)のように依存ライブラリを直接gitで取得できるようなので後々試してみたい。

次回

次回は Build.scala を使ったマルチプロジェクトを試します。