sbt筆記八 scala構建定義

.scala構建定義(sbt 0.13.0 Snapshot)

當前頁面假定你已經閱讀了Getting Started Guide的前面章節,尤爲是.sbt build definition和more about settings。 html

sbt是遞歸的

build.sbt很是簡單,它隱藏了sbt實際是如何工做的。sbt構建是用Scala代碼定義的。這些代碼自身須要創建。還有比sbt更好的方式嗎? java

project文件夾是你項目中的另外一個子項目,它知道如何構建你的項目。子項目(理論上)能夠能夠作任何其餘項目能作的事情。你的構建定義就是一個sbt項目。 ide

若是你喜歡,你能夠經過建立一個project/project/文件夾,來調整構建定義項目的構建定義。 佈局

這有一個例證。 ui

hello/                  # your project's base directory

    Hello.scala         # a source file in your project (could be in
                        #   src/main/scala too)

    build.sbt           # build.sbt is part of the source code for the
                        #   build definition project inside project/

    project/            # base directory of the build definition project

        Build.scala     # a source file in the project/ project,
                        #   that is, a source file in the build definition

        build.sbt       # this is part of a build definition for a project
                        #   in project/project ; build definition's build
                        #   definition


        project/        # base directory of the build definition project
                        #   for the build definition

            Build.scala # source file in the project/project/ project

別擔憂!多數時候你並不須要所有。但理解原理是頗有幫助的。 this

順便說一下:任什麼時候候,以.scala或.sbt結尾的文件都會被用上,把他們命名爲build.sbt和Build.scala僅僅是慣例而已。這也意味着多個文件也是容許的。 spa

構建定義項目中的.scala源文件

.sbt文件會合併入它們的兄弟項目文件夾。回顧一下項目佈局: 插件

hello/                  # your project's base directory

    build.sbt           # build.sbt is part of the source code for the
                        #   build definition project inside project/

    project/            # base directory of the build definition project

        Build.scala     # a source file in the project/ project,
                        #   that is, a source file in the build definition

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.(繞暈了)
項目根目錄下的`.sbt`文件若是成爲構建定義項目的一部分,也要放在相應的根目錄下(是這個意思嗎?)。 scala

.sbt文件格式是將設置添加到構建定義項目的方便的速記法。

關聯build.sbt到Build.scala

爲了混合你的構建定義中的.sbt和.scala文件,你須要瞭解如何關聯他們。

如下面兩個文件舉例。首先,若是你的項目在hello文件夾中,以下方式建立hello/project/Build.scala:
(譯註:0.12.x略有不一樣,見http://www.scala-sbt.org/0.12.3/docs/Getting-Started/Full-Def.html#relating-build-sbt-to-build-scala)

import sbt._ import Keys._ object HelloBuild extends Build { val sampleKeyA = settingKey[String]("demo key A") val sampleKeyB = settingKey[String]("demo key B") val sampleKeyC = settingKey[String]("demo key C") val sampleKeyD = settingKey[String]("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 sampleKeyA,而後你講看到(除了別的之外):

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

而後輸入inspect sampleKeyC,你將看到:

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

須要注意「Provided by」顯示了這兩個值的相同範圍。也就是,.sbt文件中的sampleKeyC in ThisBuild等價於將setting放在.scala文件的Build.settings列表中。sbt從這兩個地方獲取構建範圍的設置來建立構建 定義。

如今,輸入inspect sampleKeyB:

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

要注意sampleKeyB是項目範圍的({file:/home/hp/checkout/hello/}hello)而不是整個構建({file:/home/hp/checkout/hello/})。

正如你可能已經猜到的,inspect sampleKeyB和sampleKeyD匹配。

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

sbt將.sbt文件的設置追加到Build.settings和Project.settings中的設置,這意味着.sbt中的設置有優先權。 嘗試修改Build.scala中的sampleC或sampleD,它們依然是build.sbt中的值。build.sbt中的設置將賽過 Build.scala中的。

另外一個你須要注意的:sampleKeyC和sampleKeyD在build.sbt內部有效。這是由於sbt將你的Build對象的內容導入到.sbt文件。在這個例子中build.sbt文件的import HelloBuild._是隱式完成的。

歸納起來就是:

  • 在.scala文件中,你能夠將設置添加到Build.settings,sbt能夠找到它,並且它們自動是構建範圍的。
  • 在.scala文件中,你能夠將設置添加到Project.settings,sbt能夠找到它,並且它們自動是項目範圍的。
  • .scala文件中任何你寫的Build對象,它們的內容將導入到.sbt文件並對它有效。
  • .sbt文件中的設置會被追加到.scala文件的設置。
  • .sbt文件中的任何設置都是項目範圍的,除非你明確指定了另外一個範圍。

何時該使用.scala文件

在.scala文件中,你能夠寫任何Scala代碼,包括值,對象和方法定義。

一種推薦的方式是,在.sbt文件中定義設置,只在實際須要一個值,對象或方法定義的時候使用.scala文件。

有一個構建定義,它是你主項目的嵌套項目。.sbt和.scala文件將一塊兒被編譯來建立單一的定義。

在單一構建中定義多個項目時.scala文件也是必需的。更多內容在Multi-Project Builds中討論。

(在多項目構建中使用.sbt文件的一個缺點是,它們會在散佈不一樣的文件夾中。所以,若是有子項目,不少人更喜歡把設置放在他們的.scala文件中。在你看完多項目構建是如何工做的以後將更加清晰。)

交互模式中的構建定義項目

你能夠切換sbt交互命令行,使包含構建定義項目的project/做爲當前項目。只須要這麼作,輸入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)
>

如上所示,您可使用reload return離開構建定義項目並返回你的常規項目。

提示:全部都是不可變的

若是你認爲build.sbt中的設置是被添加到Build和Project對象的settings域,那就錯了。相反,Build和 Project,以及build.sbt中的設置,會被串聯入另外一個不可變的列表,而後做用於sbt。Build和Project對象只是構成完整構建定 義的一部分。

事實上,還有其餘來源的設置。它們按這個順序來追加:

  • .scala文件中來自Build.settings和Project.settings的設置。
  • 你的用戶全局設置;例如,在~/.sbt/build.sbt中你能夠定義設置來影響全部的項目。
  • 經過插件注入的設置,見後續使用插件章節。
  • 來自項目.sbt文件的設置。
  • 構建定義項目(也就是項目中的項目)擁有全局插件(~/.sbt/plugins)中添加的設置。使用插件章節有更詳細的說明。

後面的設置會覆蓋前面的。設置的完整列表構成了構建定義。

下一節

移到使用插件

相關文章
相關標籤/搜索