Caffe Builder

  1. Caffe Builder
    1. 1 概要
    2. 2 使い方
      1. 2.1 動作環境
      2. 2.2 インストール
      3. 2.3 概念
        1. 2.3.1 プロジェクト(Project)
        2. 2.3.2 プロパティ(Props)
        3. 2.3.3 パーシステント(Persistent)
        4. 2.3.4 タスク(Task)
        5. 2.3.5 デーモン(Daemon)
        6. 2.3.6 アクション(Action)
        7. 2.3.7 ヘルパ(Helper)
      4. 2.4 ビルドファイルの作成
        1. 2.4.1 ビルドスクリプトファイル名と配置
        2. 2.4.2 記述方法
      5. 2.5 実行方法
        1. 2.5.1 対話環境
    3. 3 ダウンロード
    4. 4 ライセンス
    5. Appendix
      1. A1 APIリファレンス
      2. A2 起動オプション
        1. ビルド環境のクリア
        2. インタラクティブ(対話)モード
        3. ヘルプ表示
      3. A3 プロジェクトヘッダ(ProjectHeader)
      4. A4 プロパティ(Props)
        1. 外部ファイルからロード: Props(path)
        2. 定数を設定: Props(ps)
      5. A5 タスク(Task)
      6. A6 デーモン(Daemon)
        1. アクションを定義: Daemon(name, cycle)(action)
        2. ファイル監視デーモンを定義: Daemon.fileMonitor(name,cycle,path,taskName,args)
      7. A7 ヘルパ(Helper)
        1. 標準
        2. ファイル操作
          1. MakeDir
          2. Copy
          3. Delete
          4. Jar
          5. Zip
        3. プロセス実行
          1. Exec
        4. Java実行, ツール実行
          1. Java
          2. JavaCompiler
          3. JavaDoc
        5. Scalaツール実行
          1. ScalaCompiler
          2. ScalaDoc
        6. CoffeeScriptツール
          1. CoffeeScriptCompiler
        7. Specs2実行
          1. Specs2
      8. A8 インタラクティブコンソールコマンド
        1. ヘルプ表示
        2. タスクリスト表示
        3. デーモンリスト表示
      9. A9 ToDo

1 概要

Scalaのコードでビルド手順を書く非常にシンプルなビルドツールです。

Caffe Builderは、以下の特徴をもっています。

例えば以下のようなコードを書いて、Scalaのコードをビルドすることができます。

Project("Scala build sample", ".", 'build)

Task('build) {task =>
MakeDir("classes")
ScalaCompiler("src", "classes", List("classes"))
}

2 使い方

2.1 動作環境

以下の環境を用意してください。

Java Java 6 Runtime Environment以上
Scala 2.9.1.final (標準添付)

2.2 インストール

Caffe Builderのアーカイブを解凍し、Caffe Builderをインストールしたディレクトリ($CBUILDER_HOME)ディレクトリにPATHを通してください。

また、環境変数$JAVA_HOMEの設定や$JAVA_HOME/binへPATHを通してください。

環境変数$JAVA_OPTSによってjavaコマンドの起動オプションを追加することができます。

2.3 概念

2.3.1 プロジェクト(Project)

ビルドスクリプトには1つのプロジェクトを持ちます。プロジェクトはビルド処理の全体を意味し、タスクやデーモンなどのビルド処理の定義を含みます。

build.scala
+ Project
+ Props
+ Persistent
+ Tasks
+ Daemons

2.3.2 プロパティ(Props)

プロパティはプロジェクト全体で利用される広域変数群です。

ディレクトリのパスやCLASSPATHなど、よく使う定数などを定義しておきます。

プロパティはmutable(再代入可能)であり、タスクなどで必要な状態を持たせることにも利用できます。

2.3.3 パーシステント(Persistent)

パシステントはプロジェクト全体で利用される永続的な広域変数群です。

ファイルの更新日付や各種状態を保存しておきたい変数として利用します。主にタスクやデーモンなど、実装コードから利用します。

2.3.4 タスク(Task)

タスクはビルド処理の1つの単位であり、ここに具体的なビルドの実装を書きます。

2.3.5 デーモン(Daemon)

デーモンは、タスクと並列に実行される処理の単位であり、例えばソースディレクトリを監視して書き換えられた時にタスクを起動させることができます。

2.3.6 アクション(Action)

アクションはタスクやデーモンの処理が書かれたクロージャであり、TaskやProjectなどの引数を持っています。

ここに具体的な処理を記述します。

2.3.7 ヘルパ(Helper)

ヘルパはファイル操作やScalaコマンドなどを実行するオブジェクトメソッドであり、一般的に必要な処理が定義されています。

2.4 ビルドファイルの作成

2.4.1 ビルドスクリプトファイル名と配置

ビルドスクリプトファイルは "build.scala" というファイル名で作成し、開発するトップディレクトリに配置します。

2.4.2 記述方法

ビルドスクリプト(build.scala)は、簡単なDSL(Domain Specific Language)になっていて、特定のルールを守ることによって記述を少なくすることができます。

記述は、以下の順番で記述されます。

  1. プロジェクト基本情報の定義
  2. プロパティの定義
  3. タスクの定義
  4. デーモンの定義

例えば、

// 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 \ ".")
}

2.5 実行方法

ビルドファイル "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

とします。

2.5.1 対話環境

ビルドスクリプトで定義されたタスクを実行できる対話環境です。

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>

3 ダウンロード

以下のサイトからダウンロードできます。

http://cappuccino.jp/keisuken/scala/CaffeBuilder/CaffeBuiler-0.2.2.zip (27.5MB, 2011-10-11)

4 ライセンス

ライセンスは以下のとおりです。

Appendix

A1 APIリファレンス

APIリファレンス

A2 起動オプション

ビルド環境のクリア

-c または --clean

インタラクティブ(対話)モード

-i または --interactive

ヘルプ表示

-h または --help

A3 プロジェクトヘッダ(ProjectHeader)

    プロジェクトの基本情報を定義する。
引数
引数内容
nameプロジェクト名"Foo"
baseDirベースとなるディレクトリ"."
defaultTaskデフォルトの実行タスク名'build
Project("Foo", ".", 'build)

A4 プロパティ(Props)

広域変数の定義をします。

外部ファイルからロード: Props(path)

引数
引数内容
pathプロパティファイルパス"build.properties"
Props("build.properties")

定数を設定: Props(ps)

引数
引数内容
psプロパティの組(名前->値)'src -> "src"
Props(
'src -> "src",
'classes -> "classes",
'docs -> "docs",
'api -> 'docs \ "/api"
)

A5 タスク(Task)

タスクの処理を定義する。

引数
引数内容
nameプロジェクト名'build
depends依存するタスク名リスト'compile, 'api
actionタスク処理アクション{task => Jar('classes, 'target_jar) }
Task('build, 'compile, 'api) {task =>
Jar('classes, 'tagte_jar)
}

A6 デーモン(Daemon)

デーモンの処理を定義する。

アクションを定義: Daemon(name, cycle)(action)

引数
引数内容
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時です。おやつにしましょう:)")
}
}

ファイル監視デーモンを定義: Daemon.fileMonitor(name,cycle,path,taskName,args)

引数
引数内容
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")

A7 ヘルパ(Helper)

標準

標準出力にメッセージを表示する。

引数
引数内容
message表示するメッセージ"Hello, world!"
Echo("Hello, world!")

ファイル操作

MakeDir

ディレクトリを作成する。

引数
引数内容
dir作成するディレクトリパス"classes"
quiettrueの場合エラーを無視するtrue
MakeDir("classes", true)
Copy

ファイルやディレクトリをコピーする。

引数
引数内容
src作成するディレクトリパス"src/resources"
desttrueの場合エラーを無視する"classes"
quiettrueの場合エラーを無視するtrue
filterファイルフィルタextFileFilter(".scala")
Copy("src/resources", "classes", true, extFileFilter(".scala"))
Delete

ファイルやディレクトリを削除する。

引数
引数内容
path作成するディレクトリパス"classes"
quiettrueの場合エラーを無視するtrue
filterファイルフィルタextFileFilter(".scala")
Delete("classes", true, extFileFilter(".scala"))
Jar

jarファイルを作成する。

引数
引数内容
srcDirアーカイブするディレクトリ"classes"
jarFile作成するjarファイル名"foo.jar"
Jar("classes", "foo.jar")
Zip

zipファイルを作成する。

引数
引数内容
srcDirアーカイブするディレクトリ"doc"
zipFile作成するzipファイル名"foo-doc.zip"
Zip("doc", "foo-doc.zip")

プロセス実行

Exec

プロセス起動する。

引数
引数内容
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実行, ツール実行

Java

Javaプログラムを実行する。

引数
引数内容
className実行するクラス名"com.example.foo.Main"
argsmainメソッド引数"This", "is", "a", "pen"
classpathCLASSPATHList("lib/foo.jar", "lib/scala-library.jar")
Java("com.example.foo.Main",
"This", "is", "a", "pen"
)(
List("lib/foo.jar", "lib/scala-library.jar")
)
JavaCompiler

Javaのソースをコンパイルする。

引数
引数内容
srcDirコンパイルするソースディレクトリ"src"
destDirmainメソッド引数"classes"
classpathCLASSPATHList("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")
)
JavaDoc

JavaのソースからAPIリファレンスを作成する。

引数
引数内容
srcDirコンパイルするソースディレクトリ"src"
destDirmainメソッド引数"docs/api"
packageNameドキュメントを作るパッケージ名"com.example.foo"
classpathCLASSPATHList("lib/foo.jar", "lib/scala-library.jar")
encodingソースの文字エンコーディング"UTF-8"
windowtitlewindowtitleを設定する"Foo Standard library"
doctitledoctitleを設定する"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ツール実行

ScalaCompiler

Scalaのソースをコンパイルする。

引数
引数内容
srcDirコンパイルするソースディレクトリ"src"
destDirmainメソッド引数"classes"
classpathCLASSPATHList("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")
)
ScalaDoc

ScalaのソースからAPIリファレンスを作成する。

引数
引数内容
srcDirコンパイルするソースディレクトリ"src"
destDirmainメソッド引数"docs/api"
packageNameドキュメントを作るパッケージ名"com.example.foo"
classpathCLASSPATHList("lib/foo.jar", "lib/scala-library.jar")
encodingソースの文字エンコーディング"UTF-8"
doctitledoctitleを設定する"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ツール

CoffeeScriptCompiler

CoffeeScriptのソースをコンパイルする。

引数
引数内容
srcDirコンパイルするソースディレクトリ"src"
destDirコンパイルされたJavaScriptを置くディレクトリ"js"
CoffeeScriptCompiler(
"src",
"js"
)

Specs2実行

Specs2

Specs2を実行する。

引数
引数内容
className実行するSpecificationクラス名"com.example.foo.test.FooSpecification"
classpathCLASSPATHList("lib/foo.jar", "lib/scala-library.jar")
Specs2(
"com.example.foo.test.FooSpecification",
List("lib/foo.jar", "lib/scala-library.jar")
)

A8 インタラクティブコンソールコマンド

ヘルプ表示

:help

タスクリスト表示

:tasks

デーモンリスト表示

:deamons

A9 ToDo