Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
Help us understand the problem. What is going on with this article?

SBTでオレオレCommandを作る

More than 1 year has passed since last update.

例えば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

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

leverages
インターネットを事業軸に、IT、医療、その他新規分野に30を超える自社メディア事業を展開しています。
https://leverages.jp/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away