sbtプラグインを作る

開発メモ。

20141002追記

sbtのドキュメントのリンクを最新のものに変更しました。 また0.13.5以降のAuto Pluginの説明には対応してないので、気が向いたら追記します。

作り方

以下の公式ドキュメントがわかりやすい。

必要なのは以下の2点のみ。

  • build.sbtにplugin用設定を書く
  • Pluginを継承したObjectを定義する
plugin用のビルド定義ファイルを用意する

おそらく最低限必要なのは以下の内容。

// build.sbt

sbtPlugin := true

name := "sample-plugin"

organization := "com.example.sample"
Pluginを継承したObjectを定義する

定義方法は2種類あり、Taskを利用する方法と、Commandを利用する方法。

全部読んでないけど、単純な処理はTaskを使って、Taskではできない処理(Stateを利用して、sbtの設定を参照/変更するなど)はCommandを利用する、という使い分けでよさそう。

以下は"Hello SBT World!"と表示するsampleCommandというCommandを定義する例。

// SamplePlugin.scala

package com.example.sample

import sbt._
import Keys._

object SamplePlugin extends Plugin {
  override lazy val settings = Seq(
    commands ++= Seq(
      sample
    )
  )

  lazy val sample = Command.command("sampleCommand") { state =>
    println("Hello SBT World!")
    state
  }
}

同じことをするsampleTaskというTaskの例。こっちではsampleSettingというSettingを定義しているとおり、sbtコンソールやビルド定義ファイルから参照や変更ができる。

// SamplePlugin.scala

package com.example.sample

import sbt._

object SamplePlugin extends Plugin {
  val sampleTask = taskKey[Unit]("Sample task")
  val sampleSetting = settingKey[String]("Sample setting")

  override val settings = Seq(
    sampleSetting := "Hello SBT World!",
    sampleTask := println(sampleSetting.value)
  )
}

作成したプラグインを利用する

プラグイン開発中の検証なども同じ要領。

  1. publishする
  2. プロジェクトに追加する
  3. 読み込む
1. publishする

プラグインのプロジェクトでsbtコンソールを開き、以下を実行。 publishLocalはローカルのivyリポジトリに作成したプラグインを登録しているため、参照は開発環境内でのみ解決可能となる。

> compile
> publishLocal
2. プロジェクトに追加する

プラグインを利用したいプロジェクトにプラグインを追加する。 例として作成したプラグインの場合だとバージョンは自動的に"0.1-SNAPSHOT"となる。

// project/plugins.sbt

addSbtPlugin("com.example.sample" % "sample-plugin" % "0.1-SNAPSHOT")

グローバルプラグインとして登録する場合も同じ要領で記述場所が違うだけ。

// ~/.sbt/0.13/plugins/build.sbt

addSbtPlugin("com.example.sample" % "sample-plugin" % "0.1-SNAPSHOT")
3. 読み込む

プラグインを利用したいプロジェクトのsbtコンソールで以下を実行。

> reload plugins

Command名を変更する場合はreload pluginsだけでは解決できず、sbt自体を再実行する必要があるようでちょっとハマった。

giter8テンプレート

すでにあるような気がするけど、wikiに載ってなさそうだったので作ってみた。

g8 akiomik/sbt-pluginを実行すれば上記のsampleCommandの実装例を吐き出してくれます。