最新のsbtに面白い機能が入っていたのを見つけたので紹介。このコミット
これ書いている時点から一ヶ月前(つまり2013年の12月)に入ったばかりの機能です。なので0.13.1にも入っておらず、0.13.2-M1以降です。
どんな機能かというと
「TaskKey
に対して、previous
というマクロ呼出しをすると、Taskの前回実行時の結果が簡単に取得できる」
というものです。*1とりあえずサンプルを作ってみましょう。
まずは、previousマクロ使わずに、jarのサイズ(byte数)を取得するだけの簡単なタスクを定義してみましょう。
val jarSize = TaskKey[Long]("jarSize") jarSize := { val s = streams.value.log val size = (packageBin in Compile).value.length s.info(size.toString) size }
packageBin in Compile
が、普通にpackage
をした際に生成されるjarを表すもので、java.io.File
オブジェクトが取得できます。そしてそれに対してlength
を呼び出してprintするだけの単純なTaskです。
ちなみに、本当に単にprintしたいだけなら、上記のようにTaskKey[Long]
ではなくTaskKey[Unit]
にしてもいいです。
が、他のTaskからこのTask値を使う場合などを考慮して、値を返すようにしておくほうが便利です。
また、今回も「Taskの前回実行時の結果」を取得するには、値を返しておかないといけないので、TaskKey[Long]
というようにしておくことは必要不可欠です。
さて、ここからやっと本題です。以下が、previousマクロを使ったversionです。
val jarSize = TaskKey[Long]("jarSize") jarSize := { import sbinary.DefaultProtocol._ val s = streams.value.log val current = (packageBin in Compile).value.length s.info("current " + current) jarSize.previous.foreach{ previous => s.info("previous " + previous) s.info((current - previous).toString) } current }
previous
は、TaskKey
に対して呼び出します(今回はjarSize
のkeyに対して)。「初回実行で前回の値が存在しない場合」もありえるので、previousの結果値はOption
です。
上記の例では
- まず現在のjarSizeを表示し
- もし前回のjarSizeが取得出来た場合は、前回値をprint
- さらに、今回と前回の差分(何byte大きく or 小さくなったか?)
を表示します。
これを使って~jarSize
で継続実行すれば
「それぞれのコードの変更によって、jarのサイズがどのように変化するか?」
が簡単に取得でき
「jarファイルサイズのコードゴルフ」
をするのに役に立ちますね!(そんなことする人はほとんどいないでしょうが・・・)
ちなみに、コミットのコメントに
TODO: user documentation
TODO: stable selection of the Format when there are multiple .previous calls on the same task
TODO: make it usable in InputTasks, specifically Parsers
などとあったので、まだ改善の余地というかやること残っているようです。(もしかしたら、使い方変わったりするのだろうか?)
previous
マクロ使って、なにか面白い便利なTaskできたら教えて下さい。
*1:このマクロ使わなくても、頑張れば同じことできるはず?だけど、その場合どうやるんだろう・・・