search
LoginSignup
3
Help us understand the problem. What are the problem?

More than 1 year has passed since last update.

Scala Advent Calendar 2019 Day 24

Organization

SBTでオレオレCommandを作る

例えばsbtで

  1. マルチプロジェクトで子プロジェクトの特定のMainクラスを実行
  2. Settingを変更しつつコマンドを実行

などしたくなったこと有りませんか?
そんなときは、ルートプロジェクトでオレオレコマンドを定義すると一発で実行できるようになります。

プロジェクトを切り替えて子プロジェクトのコマンドを実行

sbt:root> project core
sbt:core> runMain MainClass arg1 arg2

のようなコマンドを一発で実行したい場合は、以下のようにコマンドを定義することで

build.sbt

lazy val root = (project in file(".")).setting(
  commands ++= Seq(
    Command.args("codeGen","<args>")((state, args) => {
      // project coreを実行して、projectが切り替わったStateを取得
      val projectChanged: State = MainLoop.processCommand(Exec("project core", None), state)
      // projectが切り替わったStateを渡してコマンドを実行
      MainLoop.processCommand(Exec(s"runMain MainClass ${args.mkString(" ")}", None), projectChanged)
      state // project切り替え前のStateを戻すことで、実行時と同じprojectの状態に戻る
    })
  )
)

lazy val core = (project in file("core")).setting(
)

以下のコマンドで一発実行できるようになります

sbt:root> myRun arg1 arg2
# MainClass has run
sbt:root>

commandに関連するメソッドは戻り地にStateを帰すようになっています。Stateは普遍なオブジェクトで、戻り値のStateはコマンドなどの実行などで状態が変化したStateが帰ってきます。

Settingを変更してコマンドを実行

設定値を元に他の設定を変更しコマンド実行

sbt:root> show myOption1
sbt:root> set myOption2 := "hoge"
sbt:root> runMain Main1

※ myOption2にセットする値は、myOption1の値に依存

build.sbt
lazy val root = (project in file(".")).setting(
  commands ++= Seq(
    Command.command("updateAndRun")(state => {
      val extracted = Project.extract(state)
      // settingの値を取得
      val value = extracted.get(myOption1)
      // 取得した値に応じて、他のKeyを変更
      val settingUpdated: State = value match {
        case "update to hoge" => extracted.appendWithSession(Seq(myOption2 := "hoge"), state)
        case "update to fuga" => extracted.appendWithSession(Seq(myOption2 := "fuga"), state)
      }
      MainLoop.processCommand(Exec(s"runMain Main", None), settingUpdated)
    })
  )
)

と定義しておけば、

sbt:root> updateAndRun

で一連の操作が実行されます。

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
What you can do with signing up
3
Help us understand the problem. What are the problem?