Locked History Actions

Diff for "sbt/Getting-Started-Basic-Def"

Differences between revisions 2 and 3
Deletions are marked like this. Additions are marked like this.
Line 48: Line 48:
サマリ:ビルド定義とはSetting[T]のリストを定義することであり、Setting[T]はsbtのキー・値マップペアへの変換であり、
Tとは各値のタイプである。
Line 49: Line 51:
== build.sbtにおけるsettingの定義方法 ==
Line 50: Line 53:
Summary: A build definition defines a list of Setting[T], where a Setting[T] is a transformation affecting sbt's map of key-value pairs and T is the type of each value.

== How build.sbt defines settings ==

Here's an example:
以下に例をあげる
Line 64: Line 63:
A build.sbt file is a list of Setting, separated by blank lines. Each Setting is defined with a Scala expression. build.sbtファイルは空行で区切られたsettingのリストだ。
それぞれのsettingはScalaの式で記述される。
Line 66: Line 66:
The expressions in build.sbt are independent of one another, and they are expressions, rather than complete Scala statements. An implication of this is that you can't define a top-level val, object, class, or method in build.sbt. build.sbtにおける式は、他との依存を持たない。また、それらは「式」であって、完全なScalaの「文」ではない。
だから、build.sbtの中でトップレベルのval、オブジェクト、クラス、メソッドを定義することはできない。
Line 68: Line 69:
On the left, name, version, and scalaVersion are keys. A key is an instance of SettingKey[T], TaskKey[T], or InputKey[T] where T is the expected value type. The kinds of key are explained more below. 左側のname、version、scalaVersionはキーだ。
キーはSettingKey[T]、TaskKey[T]、InputKey[T]のいずれかで、Tは値の型だ。
キーの種類については後で説明する。
Line 70: Line 73:
Keys have a method called :=, which returns a Setting[T]. You could use a Java-like syntax to call the method: キーは「:=」というメソッドを持つのだが、この返値はSetting[T]になる。
このメソッドを呼び出すには、Javaのように以下のような書き方でもいい。
Line 74: Line 78:
But Scala allows name := "hello" instead (in Scala, any method can use either syntax). Scalaでは「name := "hello"」という書き方でもいい(Scalaでは、どんなメソッドもどちらの書き方も許される)。
Line 76: Line 80:
The := method on key name returns a Setting, specifically a Setting[String]. String also appears in the type of name itself, which is SettingKey[String]. In this case, the returned Setting[String] is a transformation to add or replace the name key in sbt's map, giving it the value "hello". nameキーの:=メソッドはSettingを返すのだが、ここでは当然Setting[String]になる。
Stringはキー自身のタイプに現れる、つまりSettingKey[String]だ。
この場合には、返されたSetting[String]はsbtマップにnameキーを追加するか置換するものになる。その値は"hello"だ。
Line 78: Line 84:
If you use the wrong value type, the build definition will not compile: もし値のタイプを間違えるとビルド定義はコンパイルされない。
{{{
name := 42 // コンパイルできない
}}}
Line 80: Line 89:
name := 42 // will not compile == キーはKeysオブジェクトの中で定義されている ==
Line 82: Line 91:
Keys are defined in the Keys object ビルトインキーはKeysというオブジェクト中に定義されている単なるフィールドだ。
build.sbtでは暗黙的にsbt.Keys._がインポートされているので、sbt.Keys.nameを単にnameのみで参照することができる。
Line 84: Line 94:
The built-in keys are just fields in an object called Keys. A build.sbt implicitly has an import sbt.Keys._, so sbt.Keys.name can be referred to as name.
Line 86: Line 95:
Custom keys may be defined in a .scala file or a plugin.
Other ways to transform settings
カスタムキーは.scalaファイルかプラグインで定義することができる。
Line 89: Line 97:
Replacement with := is the simplest transformation, but there are several others. For example you can append to a list value with +=. == settingを変換する他の方法 ==
Line 91: Line 99:
The other transformations require an understanding of scopes, so the next page is about scopes and the page after that goes into more detail about settings.
Task Keys
:=による置換は最も単純な変換であり、他にも方法はある。
例えば、リスト値に+=で追加する方法だ。
Line 94: Line 102:
There are three flavors of key: その他の変換については、スコープを理解しておく必要がある。
次のページではスコープについて学習し、その後でsettingの詳細を説明する。
Line 96: Line 105:
    SettingKey[T]: a key with a value computed once (the value is computed one time when loading the project, and kept around).
    TaskKey[T]: a key with a value that has to be recomputed each time, potentially creating side effects.
    InputKey[T]: a task key which has command line arguments as input. The Getting Started Guide doesn't cover InputKey, but when you finish this guide, check out Input Tasks for more.
== タスクキー ==

キーには三種類ある。

 *
SettingKey[T]: a key with a value computed once (the value is computed one time when loading the project, and kept around).
 * TaskKey[T]: a key with a value that has to be recomputed each time, potentially creating side effects.
 * InputKey[T]: a task key which has command line arguments as input. The Getting Started Guide doesn't cover InputKey, but when you finish this guide, check out Input Tasks for more.
Line 110: Line 123:
{{{
Line 111: Line 125:
}}}
Line 123: Line 138:
{{{
Line 124: Line 140:
}}}
Line 128: Line 145:
Imports in build.sbt
== build.sbtにおけるインポート ==
Line 133: Line 151:
{{{
Line 137: Line 155:
}}}
Line 143: Line 162:
{{{
Line 144: Line 164:
}}}

.sbtビルド定義

https://github.com/harrah/xsbt/wiki/Getting-Started-Basic-Defの翻訳(2011/10/27時点)

ここではsbtビルド定義について説明するが、いくつかの「理屈」とbuild.sbtの構文が含まれる。 sbtの使い方とこれまでのページを読んだことを前提とするよ。

.sbtと.scala定義の違い

sbtのビルド定義はベースディレクトリに置かれた.sbtファイルに記述してもよいし、projectサブディレクトリに置かれた.scalaファイルに記述してもよい。

どちらか一方をつかってもいいし、両方を使ってもいい。通常は.sbtファイルを利用し、.sbtでは実現できない場合に.scalaを使うというのが良いアプローチだろう。 後者を使うのは、

  • sbtをカスタマイズする。つまり、新しいsettingやtaskを作る。
  • ネストされたサブプロジェクトを定義する。

ここでは、.sbtファイルについて説明する。.scalaについては「.scala build definition」で説明する。

ビルド定義とは何か?

ここは絶対に読むべし

sbtはプロジェクトを検証してビルド定義ファイルを処理したあと、ビルドを記述したイミュータブルなマップ(キー・値ペアの集合)を固定する。

例えば、nameというキーは文字列値をマップするが、それは君のプロジェクトの名前を表す。

ビルド定義ファイルはsbtマップに直接影響するわけではない。

そうではなく、ビルド定義はSetting[T]型の巨大なオブジェクトリストを生成する。Tとはマップ中の値の型だ(ScalaでのSetting[T]とは、JavaでいうSetting<T>のこと)。 Settingはマップに対する変換を表現している。例えば、(マップに対して)新たなキー・値ペアを追加したり、既存の値に追加したりすることだ (関数プログラミングの精神においては、変換は新しいマップを返す。古いマップを更新したりはしない)。

.sbtファイルの中では、プロジェクト名を表すSetting[String]を次のように作成することができる。

name := "hello"

このSetting[String]がマップに新しいnameというキーを追加し(あるいは置換し)、それに"hello"という名前を与える。 変換されたマップはsbtの新たなマップになる。

マップを作成するにあたり、事前にsbtはsettingのリストをソートするので同一のキーに対する変更は束ねられる。 そして、値が他のキーに依存するのであれば、その依存先がまず処理される。 そうしておいて、sbtはSettingのソート済リストをたどり、それぞれをマップに適用する。

サマリ:ビルド定義とはSetting[T]のリストを定義することであり、Setting[T]はsbtのキー・値マップペアへの変換であり、 Tとは各値のタイプである。

build.sbtにおけるsettingの定義方法

以下に例をあげる

name := "hello"

version := "1.0"

scalaVersion := "2.9.1"

build.sbtファイルは空行で区切られたsettingのリストだ。 それぞれのsettingはScalaの式で記述される。

build.sbtにおける式は、他との依存を持たない。また、それらは「式」であって、完全なScalaの「文」ではない。 だから、build.sbtの中でトップレベルのval、オブジェクト、クラス、メソッドを定義することはできない。

左側のname、version、scalaVersionはキーだ。 キーはSettingKey[T]、TaskKey[T]、InputKey[T]のいずれかで、Tは値の型だ。 キーの種類については後で説明する。

キーは「:=」というメソッドを持つのだが、この返値はSetting[T]になる。 このメソッドを呼び出すには、Javaのように以下のような書き方でもいい。

name.:=("hello")

Scalaでは「name := "hello"」という書き方でもいい(Scalaでは、どんなメソッドもどちらの書き方も許される)。

nameキーの:=メソッドはSettingを返すのだが、ここでは当然Setting[String]になる。 Stringはキー自身のタイプに現れる、つまりSettingKey[String]だ。 この場合には、返されたSetting[String]はsbtマップにnameキーを追加するか置換するものになる。その値は"hello"だ。

もし値のタイプを間違えるとビルド定義はコンパイルされない。

name := 42  // コンパイルできない

キーはKeysオブジェクトの中で定義されている

ビルトインキーはKeysというオブジェクト中に定義されている単なるフィールドだ。 build.sbtでは暗黙的にsbt.Keys._がインポートされているので、sbt.Keys.nameを単にnameのみで参照することができる。

カスタムキーは.scalaファイルかプラグインで定義することができる。

settingを変換する他の方法

:=による置換は最も単純な変換であり、他にも方法はある。 例えば、リスト値に+=で追加する方法だ。

その他の変換については、スコープを理解しておく必要がある。 次のページではスコープについて学習し、その後でsettingの詳細を説明する。

タスクキー

キーには三種類ある。

  • SettingKey[T]: a key with a value computed once (the value is computed one time when loading the project, and kept around).

  • TaskKey[T]: a key with a value that has to be recomputed each time, potentially creating side effects.

  • InputKey[T]: a task key which has command line arguments as input. The Getting Started Guide doesn't cover InputKey, but when you finish this guide, check out Input Tasks for more.

A TaskKey[T] is said to define a task. Tasks are operations such as compile or package. They may return Unit (Unit is Scala for void), or they may return a value related to the task, for example package is a TaskKey[File] and its value is the jar file it creates.

Each time you start a task execution, for example by typing compile at the interactive sbt prompt, sbt will re-run any tasks involved exactly once.

sbt's map describing the project can keep around a fixed string value for a setting such as name, but it has to keep around some executable code for a task such as compile -- even if that executable code eventually returns a string, it has to be re-run every time.

A given key always refers to either a task or a plain setting. That is, "taskiness" (whether to re-run each time) is a property of the key, not the value.

Using :=, you can assign a computation to a task, and that computation will be re-run each time:

hello := { println("Hello!") }

From a type-system perspective, the Setting created from a task key is slightly different from the one created from a setting key. taskKey := 42 results in a Setting[Task[T]] while settingKey := 42 results in a Setting[T]. For most purposes this makes no difference; the task key still creates a value of type T when the task executes.

The T vs. Task[T] type difference has this implication: a setting key can't depend on a task key, because a setting key is evaluated only once on project load, and not re-run. More on this in more about settings, coming up soon. Keys in sbt interactive mode

In sbt's interactive mode, you can type the name of any task to execute that task. This is why typing compile runs the compile task. compile is a task key.

If you type the name of a setting key rather than a task key, the value of the setting key will be displayed. Typing a task key name executes the task but doesn't display the resulting value; to see a task's result, use show <task name> rather than plain <task name>.

In build definition files, keys are named with camelCase following Scala convention, but the sbt command line uses hyphen-separated-words instead. The hyphen-separated string used in sbt comes from the definition of the key (see Keys). For example, in Keys.scala, there's this key:

val scalacOptions = TaskKey[Seq[String]]("scalac-options", "Options for the Scala compiler.")

In sbt you type scalac-options but in a build definition file you use scalacOptions.

To learn more about any key, type inspect <keyname> at the sbt interactive prompt. Some of the information inspect displays won't make sense yet, but at the top it shows you the setting's value type and a brief description of the setting.

build.sbtにおけるインポート

You can place import statements at the top of build.sbt; they need not be separated by blank lines.

There are some implied default imports, as follows:

import sbt._
import Process._
import Keys._

(In addition, if you have .scala files, the contents of any Build or Plugin objects in those files will be imported. More on that when we get to .scala build definitions.) Adding library dependencies

To depend on third-party libraries, there are two options. The first is to drop jars in lib/ (unmanaged dependencies) and the other is to add managed dependencies, which will look like this in build.sbt:

libraryDependencies += "org.apache.derby" % "derby" % "10.4.1.3"

This is how you add a managed dependency on the Apache Derby library, version 10.4.1.3.

The libraryDependencies key involves two complexities: += rather than :=, and the % method. += appends to the key's old value rather than replacing it, this is explained in more about settings. The % method is used to construct an Ivy module ID from strings, explained in library dependencies.

We'll skip over the details of library dependencies until later in the Getting Started Guide. There's a whole page covering it later on.