Qiita::Teamに一度書いたものを、外部公開用に書き直し。まぁ、社内に限定しなくちゃいけない内容じゃないし。
- 依存関係のないプロジェクトを複数まとめたい
- タスクの呼び出しをプロジェクトごとに行えるようにしたい
- 独自タスクを追加したい
- https://github.com/myahal/scalaMultiTest
手順
SBTプロジェクトを作る。最終的にはこんな感じのディレクトリ構造になる
└── scalaMultiTest
├── README.md
├── build.sbt
├── project
│ ├── TaskTest.scala
│ ├── build.properties
│ └── plugins.sbt
├── project1
│ └── src
│ └── main
│ └── scala-2.11
│ └── Proj1.scala
└── project2
└── src
└── main
└── scala-2.11
└── Proj2.scala
使用したいプラグインとかはproject/plugins.sbtに記述している。今回はassemblyを使いたいので、以下の行を追加。
addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "0.13.0")
sbtに独自タスクを追加する場合はprojectの下にscalaプログラムとして追加した。今回はproject/TestTask.scala。
実際のプロジェクトではassemblyした結果を起動スクリプトなどと一緒にアーカイブしてS3にプッシュしたりするけど、今回はテストスクリプトで。呼び出し時にパラメータを二つ渡す。
object TaskTest {
def push(name:String, key:String): Unit = {
println("TaskTest push called")
println(name)
println(key)
}
}
sbtの設定はscalaMultiTest/build.sbtに記述。
import sbt._
lazy val pushName = settingKey[String]("test name")
lazy val pushKey = settingKey[String]("test key")
lazy val push = taskKey[Unit]("push zip to S3 for CodeDeploy Test")
lazy val commonSettings = Seq (
version := "1.0",
scalaVersion := "2.11.7",
push := {
TaskTest.push(pushName.value, pushKey.value)
}
)
lazy val root = (project in file(".")).
aggregate(proj1, proj2).
settings(
name := "multitest",
pushName := "push name is root",
pushKey := "push key is root"
)
lazy val proj1 = (project in file("project1")).
settings(commonSettings: _*).
settings (
name := "project1",
pushName := "push name is project1",
pushKey := "push key is project1"
)
lazy val proj2 = (project in file("project2")).
settings(commonSettings: _*).
settings(
name := "project2",
pushName := "push name is project2",
pushKey := "push key is project2"
)
すべてのプロジェクトに共通する設定はcommonSettingsに記述。
lazy val commonSettings = Seq (
version := "1.0",
scalaVersion := "2.11.7",
push := {
TaskTest.push(pushName.value, pushKey.value)
}
)
これを個別のプロジェクトで読み込んでいる。
個別プロジェクトは、共通設定の読み込みと、カスタムタスクのためのパラメータ設定などを行っている。
lazy val proj1 = (project in file("project1")).
settings(commonSettings: _*).
settings (
name := "project1",
pushName := "push name is project1",
pushKey := "push key is project1"
)
ルートプロジェクト。project1とproject2をまとめる役割として設定。ルートプロジェクトを対象としてsbtのタスクを呼び出すと、project1とproject2に対しても実行されるようにaggregationの設定を追加してある。
lazy val root = (project in file(".")).
aggregate(proj1, proj2).
settings(
name := "multitest",
pushName := "push name is root",
pushKey := "push key is root"
)
カスタムタスクのための設定のための変数を用意。pushNameとpushKeyはタスクに渡すパラメータ。実際に渡す値は各プロジェクトで設定。
pushはタスクキー。pushというsbtタスクが追加される。実際に何を呼び出すかはcommonSettingsで設定。
lazy val pushName = settingKey[String]("test name")
lazy val pushKey = settingKey[String]("test key")
lazy val push = taskKey[Unit]("push zip to S3 for CodeDeploy Test")
sbtでの実行例
$ sbt
> projects
[info] In file:/Users/miya/src/multitest/
[info] proj1
[info] proj2
[info] * root
> push
TaskTest push called
push name is project1
push key is project1
TaskTest push called
push name is project2
push key is project2
[success] Total time: 0 s, completed 2016/01/15 18:58:56
> project proj1
[info] Set current project to project1 (in build file:/Users/miya/src/multitest/)
> push
TaskTest push called
push name is project1
push key is project1
[success] Total time: 0 s, completed 2016/01/15 18:59:02
> run
[info] Running Proj1
project1
[success] Total time: 0 s, completed 2016/01/15 18:59:06
> project proj2
[info] Set current project to project2 (in build file:/Users/miya/src/multitest/)
> run
[info] Running Proj2
project2
[success] Total time: 0 s, completed 2016/01/15 18:59:23
> push
TaskTest push called
push name is project2
push key is project2
[success] Total time: 0 s, completed 2016/01/15 18:59:25
sbt起動直後はrootが操作対象。どんなプロジェクトが指定できるかはprojectsで一覧表示できる。project で操作対象を切り替える。
rootを操作対象にしている時にpushを実行するとaggregate設定のためにproject1, project2を対象としてタスクが実行される。