Slickのコミッタとして有名なJan Christopher Vogtさんが作っているcbt (Chris’s Build Tool) というScala用のビルドツールがあります。*1
昨年参加したScala Days NewYork 2017でもセッションがあり、興味本位で参加したのですが、sbtのdisなどもありなかなか楽しい発表でした。*2
cbtの特徴
Scalaにはsbtという標準的なビルドツールが存在するわけですが、非常に難解なsbtと異なり、cbtは既存のScalaの知識だけでカスタマイズができるという大きな特徴があります。
たとえばコンパイルの前後に処理を挟む場合、compile
メソッドをオーバーライドして前後に独自のScalaコードを記述し、super.compile
を呼び出せばよいだけです。タスクはただのメソッドなので別のタスクを呼ぶ場合もメソッドを呼び出すだけですし、以下のようにメソッドを定義するだけで独自タスクも簡単に定義することができます。
class Build(val context: Context) extends BaseBuild{ ... def hello = println("Hello CBT!!") }
cbtを使ってみる
まずはGitHubリポジトリをクローンし、リポジトリのルートディレクトリに環境変数PATHを通します。*3
$ cd ~/ $ git clone https://github.com/cvogt/cbt.git $ export PATH=$PATH:~/cbt
続いて適当なディレクトリを掘って動作を確認してみます。cbt tools
はファイルの雛形などを生成する便利ツールです。
$ mkdir my-project $ cd my-project $ cbt tools createMain
以下のような内容でMain.scala
が生成されます。
object Main{ def main( args: Array[String] ): Unit = { println( Console.GREEN ++ "Hello World" ++ Console.RESET ) } }
実行してみます。
$ cbt run Compiling to /tmp/my-project/target/scala-2.11/classes [warn] Pruning sources from previous analysis, due to incompatible CompileSetup. [info] Compiling 1 Scala source to /tmp/my-project/target/scala-2.11/classes... [info] Compile success at 2017/02/15 14:19:40 [0.457s] Hello World
このようにコンパイルや実行だけであればビルドファイルを作らなくても実行することができます。
ビルドファイルの作成
ビルドの設定などを行いたい場合はビルドファイルを作成する必要があります。
$ cbt tools createBuild
以下のような内容でbuild/build.scala
が生成されます。コメントでライブラリやマルチプトジェクト構成の場合の設定方法などが説明されています。
import cbt._ class Build(val context: Context) extends BaseBuild{ override def dependencies = super.dependencies ++ // don't forget super.dependencies here for scala-library, etc. Seq( // source dependency // DirectoryDependency( projectDirectory ++ "/subProject" ) ) ++ // pick resolvers explicitly for individual dependencies (and their transitive dependencies) Resolver( mavenCentral, sonatypeReleases ).bind( // CBT-style Scala dependencies // ScalaDependency( "com.lihaoyi", "ammonite-ops", "0.5.5" ) // MavenDependency( "com.lihaoyi", "ammonite-ops_2.11", "0.5.5" ) // SBT-style dependencies // "com.lihaoyi" %% "ammonite-ops" % "0.5.5" // "com.lihaoyi" % "ammonite-ops_2.11" % "0.5.5" ) }
デイレクトリレイアウトはsbtと同様で、デフォルトではsrc/main/scala
やsrc/test/scala
などにソースコードを配置することができます。
jarファイルにパッケージングしたいのでベーストレイトをPackageJars
変更します。name
、groupId
、version
という3つのメソッドを実装する必要があります。
import cbt._ class Build(val context: Context) extends PackageJars{ override def name = "my-project" override def groupId = "com.github.takezoe" override def version = "1.0.0" ... }
このようにしておくとsbt package
でjarファイルを作成することができます。
まとめ
実際にcbtを使ってみた感じ、sbtと比べるとカスタマイズしやすそうで好印象です。ただ、現実的にはやはり以下のような点がネックになってきます。
特に既存のsbtプラグインが利用できないというのは大きな欠点です。例えばサーブレットベースのWebアプリケーションを開発するためのxsbt-web-pluginやsbtプラグインでテンプレートをScalaコードにコンパイルするTwirlなども使えません。もちろん開発環境をがっつりsbtに依存しているPlayアプリケーションの開発を行うこともできません。
現時点ではネタ感を拭えないのが正直なところですが、開発は活発に続けられていますし*4、選択肢があることは重要だと思うので、Chrisさんには是非とも頑張っていただきたいところです。