1. 產生檔案

產生檔案 

sbt 提供了標準掛勾,用於新增來源和資源產生任務。

產生來源 

來源產生任務應該在 sourceManaged 的子目錄中產生來源,並傳回產生檔案的序列。來源產生函式(成為任務基礎)的簽名通常如下所示

def makeSomeSources(base: File): Seq[File]

新增任務的鍵稱為 sourceGenerators。因為我們想要新增任務,而不是執行後的值,所以我們使用 taskValue 而不是常用的 valuesourceGenerators 應該根據產生的檔案是主要 (Compile) 或測試 (Test) 來源來設定範圍。這個基本結構如下所示

Compile / sourceGenerators += <task of type Seq[File]>.taskValue

例如,假設有一個方法 def makeSomeSources(base: File): Seq[File]

Compile / sourceGenerators += Def.task {
  makeSomeSources((Compile / sourceManaged).value / "demo")
}.taskValue

作為一個具體範例,以下來源產生器會產生 Test.scala 應用程式物件,該物件執行後會在主控台上列印 "Hi"

Compile / sourceGenerators += Def.task {
  val file = (Compile / sourceManaged).value / "demo" / "Test.scala"
  IO.write(file, """object Test extends App { println("Hi") }""")
  Seq(file)
}.taskValue

執行 run 將會列印 "Hi"

> run
[info] Running Test
Hi

Compile 變更為 Test 以使其成為測試來源。

注意:為了建置效率,sourceGenerators 應該避免在每次呼叫時都重新產生來源檔案。相反地,應該使用檔案追蹤系統,或使用 sbt.Tracked.{ inputChanged, outputChanged } 等手動追蹤輸入值來快取輸出。

預設情況下,產生的來源不會包含在封裝的來源 Artifact 中。若要這麼做,請像新增其他對應一樣新增它們。請參閱將檔案新增至封裝。來源產生器可以傳回混合在同一序列中的 Java 和 Scala 來源。稍後會透過它們的副檔名加以區分。

產生資源 

資源產生任務應該在 resourceManaged 的子目錄中產生資源,並傳回產生檔案的序列。就像來源產生函式一樣,資源產生函式(成為任務基礎)的簽名通常如下所示

def makeSomeResources(base: File): Seq[File]

新增任務的鍵稱為 resourceGenerators。因為我們想要新增任務,而不是執行後的值,所以我們使用 taskValue 而不是常用的 value。它應該根據產生的檔案是主要 (Compile) 或測試 (Test) 資源來設定範圍。這個基本結構如下所示

Compile / resourceGenerators += <task of type Seq[File]>.taskValue

例如,假設有一個方法 def makeSomeResources(base: File): Seq[File]

Compile / resourceGenerators += Def.task {
  makeSomeResources((Compile / resourceManaged).value / "demo")
}.taskValue

執行 run (或 package,而不是 compile) 將會將檔案 demo 新增至 resourceManaged,也就是 target/scala-*/resource_managed"。預設情況下,產生的資源不會包含在封裝的來源 Artifact 中。若要這麼做,請像新增其他對應一樣新增它們。請參閱將檔案新增至封裝

作為一個具體範例,以下會產生一個包含應用程式名稱和版本的屬性檔案 myapp.properties

Compile / resourceGenerators += Def.task {
  val file = (Compile / resourceManaged).value / "demo" / "myapp.properties"
  val contents = "name=%s\nversion=%s".format(name.value,version.value)
  IO.write(file, contents)
  Seq(file)
}.taskValue

Compile 變更為 Test 以使其成為測試資源。

注意:為了建置效率,resourceGenerators 應該避免在每次呼叫時都重新產生資源檔案,並改為使用 sbt.Tracked.{ inputChanged, outputChanged } 等,根據輸入值快取。