Scalaのコードでビルド手順を書く非常にシンプルなビルドツールです。
Caffe Builderは、以下の特徴をもっています。
例えば以下のようなコードを書いて、Scalaのコードをビルドすることができます。
Project("Scala build sample", ".", 'build)
Task('build) {task =>
MakeDir("classes")
ScalaCompiler("src", "classes", List("classes"))
}
以下の環境を用意してください。
| Java | Java 6 Runtime Environment以上 |
|---|---|
| Scala | 2.9.1.final (標準添付) |
Caffe Builderのアーカイブを解凍し、Caffe Builderをインストールしたディレクトリ($CBUILDER_HOME)ディレクトリにPATHを通してください。
また、環境変数$JAVA_HOMEの設定や$JAVA_HOME/binへPATHを通してください。
環境変数$JAVA_OPTSによってjavaコマンドの起動オプションを追加することができます。
ビルドスクリプトには1つのプロジェクトを持ちます。プロジェクトはビルド処理の全体を意味し、タスクやデーモンなどのビルド処理の定義を含みます。
build.scala
+ Project
+ Props
+ Persistent
+ Tasks
+ Daemons
プロパティはプロジェクト全体で利用される広域変数群です。
ディレクトリのパスやCLASSPATHなど、よく使う定数などを定義しておきます。
プロパティはmutable(再代入可能)であり、タスクなどで必要な状態を持たせることにも利用できます。
パシステントはプロジェクト全体で利用される永続的な広域変数群です。
ファイルの更新日付や各種状態を保存しておきたい変数として利用します。主にタスクやデーモンなど、実装コードから利用します。
タスクはビルド処理の1つの単位であり、ここに具体的なビルドの実装を書きます。
デーモンは、タスクと並列に実行される処理の単位であり、例えばソースディレクトリを監視して書き換えられた時にタスクを起動させることができます。
アクションはタスクやデーモンの処理が書かれたクロージャであり、TaskやProjectなどの引数を持っています。
ここに具体的な処理を記述します。
ヘルパはファイル操作やScalaコマンドなどを実行するオブジェクトメソッドであり、一般的に必要な処理が定義されています。
ビルドスクリプトファイルは "build.scala" というファイル名で作成し、開発するトップディレクトリに配置します。
ビルドスクリプト(build.scala)は、簡単なDSL(Domain Specific Language)になっていて、特定のルールを守ることによって記述を少なくすることができます。
記述は、以下の順番で記述されます。
例えば、
// build.scala
// プロジェクトの基本情報の定義(プロジェクトヘッダ)
// プロジェクト名, ベースディレクトリ, デフォルトタスク名
Project("Foo", ".", 'build)
// プロパティの定義
Props(
'src -> "src",
'classes -> "classes",
'lib -> "lib",
'api -> 'lib \ "/api",
'target_jar -> 'lib \ "/foo.jar"
)
// CLASSPATHの定義
val classpath = List('"lib/foo.jar", "lib/scala-library.jar")
// タスクの定義
// タスク名, 依存タスク名..., アクション
Task('build, 'compile) {task =>
Jar("classes", 'target_jar)
}
Task('compile) {task =>
ScalaCompiler(
'src, 'classes,
classpath,
"UTF-8",
List("-g:none")
)
}
Task('clean) {task =>
Delete('classes)
Delete('target_jar)
}
のように書きます。
プロパティやヘルパなどに設定する文字列はBuildStringというテンプレート文字列になっており、Symbol('fooなど)で記述することによりプロパティで定義した値を代入できます。
例えば、
Props(
'language -> "Scala",
'message -> 'language \ ", world!"
)
の場合、'messageプロパティは、'languageプロパティを参照して代入し、"Scala, world!"文字列に変換してくれます。プロパティ変数や通常の文字列を連結する場合は、 \ を使ってください。
Props(
'arg1 -> "pen",
'arg2 -> "desk"
)
Task(...) {task =>
// "This is a pen. That is a desk."と表示される
Echo("This is a " \ 'arg1 \ ". That is a " \ 'arg2 \ ".")
}
ビルドファイル "build.scala" が配置されているディレクトリに移動して、cbdコマンドを実行します。
cbdコマンドの引数は以下のようになっています。
Usage: cbd [options] [args]
where [options] include:
-c, --clean clean build files
-i, --interactive run an interactive
-h, --help display this help message
デフォルトのタスクを実行する場合は、
$ cbd
ビルド引数を渡したい場合は、
$ cbd build
ビルド環境を初期化するには、
$ cbd -c
対話環境を実行するには、
$ cbd -i
とします。
ビルドスクリプトで定義されたタスクを実行できる対話環境です。
Caffe Builderを起動していますので、タスクを実行する時に起動時間を節約できます。
...\CaffeBuilder> cbd -i
Caffe Builder 0.2.0a1-2010.10.08
Copyright (C) NISHIMOTO Keisuke
src_monitor daemon started
console daemon started
>
起動したらタスク名を入力して改行することでタスクを実行します。
> build
Build: Caffe Builder
...
BUILD SUCCESSFUL
>
繰り返しタスク実行待ちになりますので、終了したい場合は、EOF(Windowsの場合CTRL+Z, MacやLinuxの場合CTRL+D)を入力して改行します。
> ^Z
...\CaffeBuilder>
以下のサイトからダウンロードできます。
http://cappuccino.jp/keisuken/scala/CaffeBuilder/CaffeBuiler-0.2.2.zip (27.5MB, 2011-10-11)
ライセンスは以下のとおりです。
-c または --clean
-i または --interactive
-h または --help
| 引数 | 内容 | 例 |
|---|---|---|
| name | プロジェクト名 | "Foo" |
| baseDir | ベースとなるディレクトリ | "." |
| defaultTask | デフォルトの実行タスク名 | 'build |
Project("Foo", ".", 'build)
広域変数の定義をします。
| 引数 | 内容 | 例 |
|---|---|---|
| path | プロパティファイルパス | "build.properties" |
Props("build.properties")| 引数 | 内容 | 例 |
|---|---|---|
| ps | プロパティの組(名前->値) | 'src -> "src" |
Props(
'src -> "src",
'classes -> "classes",
'docs -> "docs",
'api -> 'docs \ "/api"
)
タスクの処理を定義する。
| 引数 | 内容 | 例 |
|---|---|---|
| name | プロジェクト名 | 'build |
| depends | 依存するタスク名リスト | 'compile, 'api |
| action | タスク処理アクション | {task => Jar('classes, 'target_jar) } |
Task('build, 'compile, 'api) {task =>
Jar('classes, 'tagte_jar)
}デーモンの処理を定義する。
| 引数 | 内容 | 例 |
|---|---|---|
| name | デーモン名 | 'oyatsu_no_jikan |
| cycle | 処理間隔(ms) | 60000 |
| action | タスク処理アクション | {task => Jar('classes, 'target_jar) } |
Daemon('oyatsu_no_jikan, 60000) {project =>
import java.util.Calendar
val calendar = Calendar.getInstance
val hour = calendar.get(Calendar.HOUR_OF_DAY)
val minute = calendar.get(Calendar.MINUTE)
if (hour == 15 && miniute == 0) {
log("3時です。おやつにしましょう:)")
}
}| 引数 | 内容 | 例 |
|---|---|---|
| name | デーモン名 | 'src_file_monitor |
| cycle | 処理間隔(ms) | 10000 |
| path | 監視するパス | "src" |
| taskName | 実行するタスク名 | 'build |
| args | タスク引数 | "foo", "boo", "buzz" |
Daemon.fileMonitor('src_file_monitor, 10000, "src", 'build, "foo", "boo", "buzz")標準出力にメッセージを表示する。
| 引数 | 内容 | 例 |
|---|---|---|
| message | 表示するメッセージ | "Hello, world!" |
Echo("Hello, world!")ディレクトリを作成する。
| 引数 | 内容 | 例 |
|---|---|---|
| dir | 作成するディレクトリパス | "classes" |
| quiet | trueの場合エラーを無視する | true |
MakeDir("classes", true)ファイルやディレクトリをコピーする。
| 引数 | 内容 | 例 |
|---|---|---|
| src | 作成するディレクトリパス | "src/resources" |
| dest | trueの場合エラーを無視する | "classes" |
| quiet | trueの場合エラーを無視する | true |
| filter | ファイルフィルタ | extFileFilter(".scala") |
Copy("src/resources", "classes", true, extFileFilter(".scala"))ファイルやディレクトリを削除する。
| 引数 | 内容 | 例 |
|---|---|---|
| path | 作成するディレクトリパス | "classes" |
| quiet | trueの場合エラーを無視する | true |
| filter | ファイルフィルタ | extFileFilter(".scala") |
Delete("classes", true, extFileFilter(".scala"))
jarファイルを作成する。
| 引数 | 内容 | 例 |
|---|---|---|
| srcDir | アーカイブするディレクトリ | "classes" |
| jarFile | 作成するjarファイル名 | "foo.jar" |
Jar("classes", "foo.jar")zipファイルを作成する。
| 引数 | 内容 | 例 |
|---|---|---|
| srcDir | アーカイブするディレクトリ | "doc" |
| zipFile | 作成するzipファイル名 | "foo-doc.zip" |
Zip("doc", "foo-doc.zip")プロセス起動する。
| 引数 | 内容 | 例 |
|---|---|---|
| command | プロセス起動するコマンド | "javap.exe" |
| args | コマンド引数 | "-classes", "lib/caffe-builder.jar", "jp.cappuccino.caffe.builder.Project" |
| env | 環境変数を設定する | Map("JAVA_HOME", "C:/Program Files/Java/jdk1.6.x") |
Exec("javap.exe",
"-classes", "lib/caffe-builder.jar", "jp.cappuccino.caffe.builder.Project"
)(
Map("JAVA_HOME", "C:/Program Files/Java/jdk1.6.x")
)Javaプログラムを実行する。
| 引数 | 内容 | 例 |
|---|---|---|
| className | 実行するクラス名 | "com.example.foo.Main" |
| args | mainメソッド引数 | "This", "is", "a", "pen" |
| classpath | CLASSPATH | List("lib/foo.jar", "lib/scala-library.jar") |
Java("com.example.foo.Main",
"This", "is", "a", "pen"
)(
List("lib/foo.jar", "lib/scala-library.jar")
)Javaのソースをコンパイルする。
| 引数 | 内容 | 例 |
|---|---|---|
| srcDir | コンパイルするソースディレクトリ | "src" |
| destDir | mainメソッド引数 | "classes" |
| classpath | CLASSPATH | List("lib/foo.jar", "lib/scala-library.jar") |
| encoding | ソースの文字エンコーディング | "UTF-8" |
| options | その他のオプション | List("-g:none") |
JavaCompiler(
"src", "classes",
List("lib/foo.jar", "lib/scala-library.jar"),
"UTF-8",
List("-g:none")
)
JavaのソースからAPIリファレンスを作成する。
| 引数 | 内容 | 例 |
|---|---|---|
| srcDir | コンパイルするソースディレクトリ | "src" |
| destDir | mainメソッド引数 | "docs/api" |
| packageName | ドキュメントを作るパッケージ名 | "com.example.foo" |
| classpath | CLASSPATH | List("lib/foo.jar", "lib/scala-library.jar") |
| encoding | ソースの文字エンコーディング | "UTF-8" |
| windowtitle | windowtitleを設定する | "Foo Standard library" |
| doctitle | doctitleを設定する | "Foo Standard API Reference Manual" |
| options | その他のオプション | List("-g:none") |
JavaDoc(
"src", "docs/api",
"com.example.foo",
"comList("lib/foo.jar", "lib/scala-library.jar"),
"UTF-8",
"Foo Standard library",
"Foo Standard API Reference Manual",
List("-g:none")
)
Scalaのソースをコンパイルする。
| 引数 | 内容 | 例 |
|---|---|---|
| srcDir | コンパイルするソースディレクトリ | "src" |
| destDir | mainメソッド引数 | "classes" |
| classpath | CLASSPATH | List("lib/foo.jar", "lib/scala-library.jar") |
| encoding | ソースの文字エンコーディング | "UTF-8" |
| options | その他のオプション | List("-g:none") |
ScalaCompiler(
"src", "classes",
List("lib/foo.jar", "lib/scala-library.jar"),
"UTF-8",
List("-g:none")
)
ScalaのソースからAPIリファレンスを作成する。
| 引数 | 内容 | 例 |
|---|---|---|
| srcDir | コンパイルするソースディレクトリ | "src" |
| destDir | mainメソッド引数 | "docs/api" |
| packageName | ドキュメントを作るパッケージ名 | "com.example.foo" |
| classpath | CLASSPATH | List("lib/foo.jar", "lib/scala-library.jar") |
| encoding | ソースの文字エンコーディング | "UTF-8" |
| doctitle | doctitleを設定する | "Foo Standard API Reference Manual" |
| options | その他のオプション | List("-g:none") |
ScalaDoc(
"src", "docs/api",
"com.example.foo",
List("lib/foo.jar", "lib/scala-library.jar"),
"UTF-8",
"Foo Standard API Reference Manual",
List("-g:none")
)
CoffeeScriptのソースをコンパイルする。
| 引数 | 内容 | 例 |
|---|---|---|
| srcDir | コンパイルするソースディレクトリ | "src" |
| destDir | コンパイルされたJavaScriptを置くディレクトリ | "js" |
CoffeeScriptCompiler(
"src",
"js"
)
Specs2を実行する。
| 引数 | 内容 | 例 |
|---|---|---|
| className | 実行するSpecificationクラス名 | "com.example.foo.test.FooSpecification" |
| classpath | CLASSPATH | List("lib/foo.jar", "lib/scala-library.jar") |
Specs2(
"com.example.foo.test.FooSpecification",
List("lib/foo.jar", "lib/scala-library.jar")
)
:help
:tasks
:deamons