Locked History Actions

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

Differences between revisions 3 and 4
Deletions are marked like this. Additions are marked like this.
Line 53: Line 53:
.sbt files are merged into their sibling project directory. Looking back at the project layout: .sbtファイルはその兄弟プロジェクトディレクトリにマージされる。
先のプロジェクトレイアウトに戻ろう。
Line 55: Line 56:
 hello/ # your project's base directory  hello/ # 君のプロジェクトのベースディレクトリ
Line 57: Line 58:
     build.sbt # build.sbt is part of the source code for the
                         # build definition project inside project/
     Hello.scala # 君のプロジェクトのソースファイル (src/main/scalaに
                         # あってもよい)
Line 60: Line 61:
     project/ # base directory of the build definition project      build.sbt # build.sbtはproject/下にあるビルド定義プロジェクトのソースコードの一つ
                         #
Line 62: Line 64:
         Build.scala # a source file in the project/ project,
                         # that is, a source file in the build definition
     project/ # ビルド定義プロジェクトのベースディレクトリ

         Build.scala # project/プロジェクトのソースファイルの一つ
                         # つまり、ビルド定義のソースファイルの一つ
Line 66: Line 70:
The Scala expressions in build.sbt are compiled alongside and merged with Build.scala (or any other .scala files in the project/ directory). build.sbt中のScala式はコンパイルされて、Build.scala(あるいはproject/ディレクトリ中の.scalaファイル)にマージされる。
Line 71: Line 76:
Relating build.sbt to Build.scala
Line 73: Line 77:
To mix .sbt and .scala files in your build definition, you need to understand how they relate. == build.sbtのBuild.scalへの関連付け ==
Line 75: Line 79:
The following two files illustrate. First, if your project is in hello, create hello/project/Build.scala as follows: ビルド定義中で、.sbtと.scalaファイルをミックスするには、まずそれらがどのように関連付けられるかを知っておく必要がある。
二つのファイルで示そう。
第一に、君のプロジェクトがhelloにあり、hello/project/Build.scalaというファイルを次のように作成したとする。
Line 95: Line 101:
Now, create hello/build.sbt as follows: そして、hello.build.sbtを次のように記述する。
Line 102: Line 108:
Start up the sbt interactive prompt. Type inspect sample-a and you should see (among other things): sbt対話モードを開始しよう。「inspect sample-a」とタイプすると、以下が表示されるだろう。
Line 104: Line 110:
{{{
Line 107: Line 114:

and then inspect sample-c and you should see:
}}}
今度は「inspect sample-c」の結果だ。
{{{
Line 113: Line 120:
}}}
Line 116: Line 124:
Now, inspect sample-b: 次に「inspect sample-b」の結果だ。
{{{
Line 121: Line 129:
}}}
Line 125: Line 134:
{{{
Line 129: Line 138:
}}}
Line 142: Line 152:
When to use .scala files == いつ.scalaファイルを使うか ==
Line 155: Line 165:
The build definition project in interactive mode
== 対話モードでのビルド定義 ==
Line 159: Line 170:
{{{
Line 169: Line 181:
}}}

.scalaビルド定義

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

This page assumes you've read previous pages in the Getting Started Guide, especially .sbt build definition and more about settings.

sbtは再帰的である

build.sbtはとても単純だ。sbtが実際にどのように動作するかは隠されている。 sbtのビルドはScalaコードで定義される。 このコードは、それ自体がビルドされる必要があるのだが、それを行うのにsbt以外の適任者があるだろうか?

君自身のプロジェクトの中にはprojectというディレクトリがあるはずだが、これがもう一つのプロジェクトであり、それが君のプロジェクトのビルドの仕方を決めている。プロジェクト中のプロジェクトは(理屈の上では)、他のプロジェクトが可能な、いかなることも可能だ。 君のビルド定義はsbtプロジェクトなのだ。

そして、これを更に掘り下げることもできる。望むなら、project/projectディレクトリを作って、ビルド定義プロジェクトのビルド定義を記述することもできる。以下に示そう。

 hello/                  # 君のプロジェクトのベースディレクトリ

     Hello.scala         # 君のプロジェクトのソースファイル (src/main/scalaに
                         #   あってもよい)

     build.sbt           # build.sbtはproject/下にあるビルド定義プロジェクトのソースコードの一つ
                         # 

     project/            # ビルド定義プロジェクトのベースディレクトリ

         Build.scala     # project/プロジェクトのソースファイルの一つ
                         #   つまり、ビルド定義のソースファイルの一つ

         build.sbt       # これはproject/projectというプロジェクトのビルド定義の一部
                         #   つまり、ビルド定義のビルド定義
                         #


         project/        # ビルド定義のビルド定義のベースディレクトリ
                         #

             Build.scala # project/project/プロジェクトのソースファイル

心配すんな!たいていは、こんなものは必要ないよ。 理屈を知ることは助けになるだろうという程度だ。

ところで、.scalaや.sbtで終わるいかなる名前のファイルでもいい。 build.sbtやBuild.scalaという名前は便宜的なものだ。 これはつまり、複数のファイルが存在しうるということだ。

ビルド定義プロジェクト中の.scalaソースファイル

.sbtファイルはその兄弟プロジェクトディレクトリにマージされる。 先のプロジェクトレイアウトに戻ろう。

 hello/                  # 君のプロジェクトのベースディレクトリ

     Hello.scala         # 君のプロジェクトのソースファイル (src/main/scalaに
                         #   あってもよい)

     build.sbt           # build.sbtはproject/下にあるビルド定義プロジェクトのソースコードの一つ
                         # 

     project/            # ビルド定義プロジェクトのベースディレクトリ

         Build.scala     # project/プロジェクトのソースファイルの一つ
                         #   つまり、ビルド定義のソースファイルの一つ

build.sbt中のScala式はコンパイルされて、Build.scala(あるいはproject/ディレクトリ中の.scalaファイル)にマージされる。

.sbt files in the base directory for a project become part of the project build definition project also located in that base directory.

The .sbt file format is a convenient shorthand for adding settings to the build definition project.

build.sbtのBuild.scalへの関連付け

ビルド定義中で、.sbtと.scalaファイルをミックスするには、まずそれらがどのように関連付けられるかを知っておく必要がある。 二つのファイルで示そう。 第一に、君のプロジェクトがhelloにあり、hello/project/Build.scalaというファイルを次のように作成したとする。

import sbt._
import Keys._

object HelloBuild extends Build {

    val sampleKeyA = SettingKey[String]("sample-a", "demo key A")
    val sampleKeyB = SettingKey[String]("sample-b", "demo key B")
    val sampleKeyC = SettingKey[String]("sample-c", "demo key C")
    val sampleKeyD = SettingKey[String]("sample-d", "demo key D")

    override lazy val settings = super.settings ++
        Seq(sampleKeyA := "A: in Build.settings in Build.scala", resolvers := Seq())

    lazy val root = Project(id = "hello",
                            base = file("."),
                            settings = Project.defaultSettings ++ Seq(sampleKeyB := "B: in the root project settings in Build.scala"))
}

そして、hello.build.sbtを次のように記述する。

sampleKeyC in ThisBuild := "C: in build.sbt scoped to ThisBuild"

sampleKeyD := "D: in build.sbt"

sbt対話モードを開始しよう。「inspect sample-a」とタイプすると、以下が表示されるだろう。

[info] Setting: java.lang.String = A: in Build.settings in Build.scala
[info] Provided by:
[info]  {file:/home/hp/checkout/hello/}/*:sample-a

今度は「inspect sample-c」の結果だ。

[info] Setting: java.lang.String = C: in build.sbt scoped to ThisBuild
[info] Provided by:
[info]  {file:/home/hp/checkout/hello/}/*:sample-c

Note that the "Provided by" shows the same scope for the two values. That is, sampleKeyC in ThisBuild in a .sbt file is equivalent to placing a setting in the Build.settings list in a .scala file. sbt takes build-scoped settings from both places to create the build definition.

次に「inspect sample-b」の結果だ。

[info] Setting: java.lang.String = B: in the root project settings in Build.scala
[info] Provided by:
[info]  {file:/home/hp/checkout/hello/}hello/*:sample-b

Note that sample-b is scoped to the project ({file:/home/hp/checkout/hello/}hello) rather than the entire build ({file:/home/hp/checkout/hello/}).

As you've probably guessed, inspect sample-d matches sample-b:

[info] Setting: java.lang.String = D: in build.sbt
[info] Provided by:
[info]  {file:/home/hp/checkout/hello/}hello/*:sample-d

sbt appends the settings from .sbt files to the settings from Build.settings and Project.settings which means .sbt settings take precedence. Try changing Build.scala so it sets key sample-c or sample-d, which are also set in build.sbt. The setting in build.sbt should "win" over the one in Build.scala.

One other thing you may have noticed: sampleKeyC and sampleKeyD were available inside build.sbt. That's because sbt imports the contents of your Build object into your .sbt files. In this case import HelloBuild._ was implicitly done for the build.sbt file.

In summary:

  • In .scala files, you can add settings to Build.settings for sbt to find, and they are automatically build-scoped. In .scala files, you can add settings to Project.settings for sbt to find, and they are automatically project-scoped. Any Build object you write in a .scala file will have its contents imported and available to .sbt files. The settings in .sbt files are appended to the settings in .scala files. The settings in .sbt files are project-scoped unless you explicitly specify another scope.

いつ.scalaファイルを使うか

In .scala files, you are not limited to a series of settings expressions. You can write any Scala code including val, object, and method definitions.

One recommended approach is to define settings in .sbt files, using .scala files when you need to factor out a val or object or method definition.

Because the .sbt format allows only single expressions, it doesn't give you a way to share code among expressions. When you need to share code, you need a .scala file so you can set common variables or define methods.

There's one build definition, which is a nested project inside your main project. .sbt and .scala files are compiled together to create that single definition.

.scala files are also required to define multiple projects in a single build. More on that is coming up in Multi-Project Builds.

(A disadvantage of using .sbt files in a multi-project build is that they'll be spread around in different directories; for that reason, some people prefer to put settings in their .scala files if they have sub-projects. This will be clearer after you see how multi-project builds work.)

対話モードでのビルド定義

You can switch the sbt interactive prompt to have the build definition project in project/ as the current project. To do so, type reload plugins.

> reload plugins
[info] Set current project to default-a0e8e4 (in build file:/home/hp/checkout/hello/project/)
> show sources
[info] ArrayBuffer(/home/hp/checkout/hello/project/Build.scala)
> reload return
[info] Loading project definition from /home/hp/checkout/hello/project
[info] Set current project to hello (in build file:/home/hp/checkout/hello/)
> show sources
[info] ArrayBuffer(/home/hp/checkout/hello/hw.scala)
>

As shown above, you use reload return to leave the build definition project and return to your regular project. Reminder: it's all immutable

It would be wrong to think that the settings in build.sbt are added to the settings fields in Build and Project objects. Instead, the settings list from Build and Project, and the settings from build.sbt, are concatenated into another immutable list which is then used by sbt. The Build and Project objects are "immutable configuration" forming only part of the complete build definition.

In fact, there are other sources of settings as well. They are appended in this order:

  • Settings from Build.settings and Project.settings in your .scala files. Your user-global settings; for example in ~/.sbt/build.sbt you can define settings affecting all your projects. Settings injected by plugins, see using plugins coming up next. Settings from .sbt files in the project. Build definition projects (i.e. projects inside project) have settings from global plugins (~/.sbt/plugins) added. Using plugins explains this more.

Later settings override earlier ones. The entire list of settings forms the build definition. Next

Move on to using plugins.