一個(gè)工程構(gòu)建定義一個(gè) Setting 類(lèi)型的列表,通過(guò)sbt轉(zhuǎn)化為sbt的描述數(shù)據(jù)結(jié)構(gòu)(key-value 鍵值對(duì)
),Setting作為一個(gè)轉(zhuǎn)化前的輸入類(lèi)型,轉(zhuǎn)化后輸出一個(gè) map表。
不同的配置項(xiàng)有不同的轉(zhuǎn)化方法,例如前面的 := 方法。 一個(gè) Setting類(lèi)型的配置項(xiàng)可以通過(guò) := 轉(zhuǎn)化成一個(gè)值為一個(gè)常量的map表,例如,轉(zhuǎn)化一個(gè)配置項(xiàng)name := "hello" 是將 hello 賦值給該配置項(xiàng)的key
Settings must end up in the master list of settings to do any good (all lines in a build.sbt automatically end up in the list, but in a .scala file you can get it wrong by creating a Setting without putting it where sbt will find it).
通過(guò)直接賦值方法 := 是最簡(jiǎn)單的一種轉(zhuǎn)化方法, 所有的配置項(xiàng)還有其他的方法,在 SettingKey[T] 中泛型 T 如果是一個(gè)序列類(lèi)型的話,支持追加操作不僅僅是重新賦值替換操作。
+= 操作是追加單個(gè)元素到序列中++= 操作是追加一個(gè)序列到序列中比如, 對(duì)于配置 sourceDirectories in Compile 值得類(lèi)型是 Seq[File], 默認(rèn)情況下這個(gè)配置已經(jīng)有包含了目錄src/main/scala。如果還想編譯目錄source下的源代碼可以添加該目錄:
sourceDirectories in Compile += new File("source")
或者,利用 sbt 包中提供的函數(shù) file() 更加方便
sourceDirectories in Compile += file("source")
file() 函數(shù)也是創(chuàng)建 File 對(duì)象
也可以用操作符++= 一次性添加多個(gè)目錄:
sourceDirectories in Compile ++= Seq(file("sources1"), file("sources2"))
其中Seq(a, b, c, ...)是 Scala的標(biāo)準(zhǔn)語(yǔ)法,用來(lái)創(chuàng)建一個(gè)序列
當(dāng)然了除了追加操作還支持直接賦值替換配置原值:
sourceDirectories in Compile := Seq(file("sources1"), file("sources2"))
引用其他的任務(wù)配置或參數(shù)配置的值通過(guò)調(diào)用任務(wù)或參數(shù)配置,通過(guò)方法:=、+=或++=來(lái)引用一個(gè)配置
比如,定義一個(gè)項(xiàng)目組織和項(xiàng)目名稱(chēng)一樣的配置:
// organization 接收的值類(lèi)型和 name一樣都是 Setting[String]
organization := name.value
或者通過(guò)引用項(xiàng)目目錄來(lái)定義項(xiàng)目名稱(chēng):
// name 是Key[String]類(lèi)型,baseDirectory是Key[File]
name := baseDirectory.value.getName
由于baseDirectory的值類(lèi)型和name的值類(lèi)型不一樣,需要調(diào)用java的java.io.File類(lèi)庫(kù)getName 方法轉(zhuǎn)化
sbt同時(shí)支持引用多個(gè)配置項(xiàng)的值,例如:
name := "project " + name.value + " from " + organization.value + " version " + version.value
在配置name := baseDirectory.value.getName中,參數(shù)配置 name 依賴配置baseDirectory, 如果在放有上述配置的build.sbt的目錄下交互模式運(yùn)行inspect name命令,將返回如下的提示信息:
[info] Dependencies:
[info] *:baseDirectory
sbt 是很容易的探測(cè)出各個(gè)參數(shù)配置間的依賴關(guān)系的,包括任務(wù)配置也可以依賴參數(shù)配置,或者任務(wù)配置間相互依賴, 例如運(yùn)行inspect compile 會(huì)發(fā)現(xiàn) compile 任務(wù)配置會(huì)依賴參數(shù)配置compileInputs, inspect compileInputs 還會(huì)發(fā)現(xiàn)參數(shù)配置compileInputs又依賴其他的參數(shù)配置,等等。最后會(huì)發(fā)現(xiàn)形成一個(gè)依賴鏈,這些依賴關(guān)系是在sbt編譯的時(shí)候自動(dòng)探測(cè)計(jì)算的。所以所有的依賴關(guān)系都是自動(dòng)計(jì)算的,不需要顯示的聲明。
當(dāng)用:=、+=或++=方法去引用一個(gè)配置,所依賴的配置必須存在,否則sbt會(huì)報(bào)錯(cuò)誤信息"Reference to undefined setting", 如果報(bào)錯(cuò)需要確認(rèn)依賴的配置是否在指定作用域中存在。
也可能會(huì)出現(xiàn)循環(huán)依賴的配置錯(cuò)誤,這個(gè)時(shí)候sbt會(huì)提示錯(cuò)誤
一個(gè)任務(wù)配置可以依賴參數(shù)配置或其他的任務(wù)配置,通過(guò) def.task或操作符(:=、+=或++=)引用配置
比如,一個(gè)源代碼生成任務(wù)將依賴項(xiàng)目根目錄和編譯classpath兩個(gè)參數(shù)配置:
sourceGenerators in Compile += Def.task {
myGenerator(baseDirectory.value, (managedClasspath in Compile).value)
}.taskValue
如配置文件 .sbt所述,一個(gè)任務(wù)配置用賦值方法:=操作的參數(shù)是Setting[Task[T]]而不是Setting[T]等, 任務(wù)配置輸入?yún)?shù)可以接收一個(gè)參數(shù)配置作為輸入,但是一個(gè)參數(shù)配置是不可以接收一個(gè)任務(wù)配置作為輸入
以下為兩個(gè)配置:
val scalacOptions = taskKey[Seq[String]]("Options for the Scala compiler.")
val checksums = settingKey[Seq[String]]("The list of checksums to generate and to verify for dependencies.")
(scalacOptions和checksums之間沒(méi)有任何聯(lián)系,它們只是配置值得類(lèi)型相同,但是其中scalacOptions是一個(gè)任務(wù)配置)
在build.sbt中允許一個(gè)任務(wù)配置依賴參數(shù)配置,比如:
// 合法的配置
scalacOptions := checksums.value
是合法的配置方法,但是如果將一個(gè)參數(shù)配置配置成依賴一個(gè)任務(wù)配置的時(shí)候就會(huì)報(bào)錯(cuò),因?yàn)閰?shù)配置在項(xiàng)目加載的時(shí)候只計(jì)算一次,可以當(dāng)做常量處理,但是任務(wù)配置是在不斷的重復(fù)的運(yùn)行的。
// 非法的配置
checksums := scalacOptions.value
一些配置可以被追加引用到一個(gè)已經(jīng)存在的配置中,和直接賦值操作:=一樣.
例如,有一個(gè)項(xiàng)目覆蓋率報(bào)告文件(文件名引用項(xiàng)目名稱(chēng)的參數(shù)配置)需要?jiǎng)h除,可以通過(guò)如下配置:
cleanFiles += file("coverage-report-" + name.value + ".txt")