sbtでコマンドを定義する
sbtでは独自にコマンドをできます。
使用するのは
Command.command, Command.single, Command.args
です。
引数なしのコマンドを定義する
Command.command を使います。
val command: Command = Command.command("name")(action)
1つ目の引数がコマンド名、
2つ目の引数が action です。
具体的な処理は action に書きます。
action の型を見てみると
val action: State => State = ...
何らかのアクションを実行する前の状態をとって、アクションを実行したあとの状態を返す関数って考えれば良いのでしょうか?
Command.command を使って "Hello" と言うだけの hello コマンドを作ると次のようになります。
// hello.sbt commands ++= Seq( Command.command("hello") { state => // state を引数にとる println("Hello") // ここにいろいろ書く state // state を返す } )
引数を1つ取るコマンドを定義する
Command.single を使います。
action の型だけが Command.command と違います。
State と引数のタプルを取って、State を返します。
val action: (State, String) => State = ...
Command.single で echo コマンドを作ってみます。
// echo.sbt commands ++= Seq( Command.single("echo") { (state, arg) => println(arg) state } )
可変長引数をとるコマンドを定義する
Command.args を使います。
val command: Command = Command.args("name", "<arg>")(action)
action は引数として State と 引数の Seq を取ります。
val action: (State, Seq[String]) => State = ...
Command.args で echo コマンドを作るとこんな感じ。
// echo2.sbt commands ++= Seq( Command.args("echo2", "<args>") { (state, args) => println(args.mkString(" ")) state } )
Full Configuration(Build.scala) に書く
まともなコマンド書こうとすると .sbt は窮屈なので Full Configuration に書くことになるでしょう。
import sbt._ import Keys._ object MyProject extends Build { def hello = Command.command("hello") { state => println("hello") state } def echo = Command.single("echo") { (state, arg) => println(arg) state } def echo2 = Command.args("echo2", "<args>") { (state, args) => println(args.mkString(" ")) state } lazy val root = Project ( id = "my-project", base = file ("."), settings = Defaults.defaultSettings ++ Seq ( commands ++= Seq( hello, echo, echo2 ) ) ) }