.copy(...)
許多 case class 已被使用 Contraband 產生的偽 case class 取代。請將 .copy(foo = xxx)
遷移至 withFoo(xxx)
。假設您有 m: ModuleID
,並且您目前正在呼叫 m.copy(revision = "1.0.1")
。以下是如何遷移的方法
m.withRevision("1.0.1")
sbt 0.13、sbt 1.0 和 sbt 1.1 需要 sbtPlugin
設定和腳本外掛程式來開發 sbt 外掛程式。sbt 1.2.1 將兩者合併到 SbtPlugin
外掛程式中。
請從 project/plugins.sbt
移除 scripted-plugin,並僅使用
lazy val root = (project in file("."))
.enablePlugins(SbtPlugin)
如果您正在跨平台建置 sbt 外掛程式,我們有一個權宜之計是使用 sbt 版本特定原始碼目錄 src/main/scala-sbt-0.13
和 src/main/scala-sbt-1.0
。您可以在其中定義一個名為 PluginCompat
的物件,如下所示
package sbtfoo
import sbt._
import Keys._
object PluginCompat {
type UpdateConfiguration = sbt.librarymanagement.UpdateConfiguration
def subMissingOk(c: UpdateConfiguration, ok: Boolean): UpdateConfiguration =
c.withMissingOk(ok)
}
現在可以在 sbt 版本特定的方式中實作 subMissingOk(...)
函式。
在 sbt 0.13 中,鍵值使用 2 種不同的語法來限定範圍:一種用於 sbt 的 shell,另一種用於程式碼中。
<project-id>/config:intask::key
key in (<project-id>, Config, intask)
從 sbt 1.1.0 開始,限定鍵值範圍的語法已統一用於 shell 和建置定義,使用斜線語法,如下所示
<project-id> / Config / intask / key
以下是一些範例
version in ThisBuild := "1.0.0-SNAPSHOT"
lazy val root = (project in file("."))
.settings(
name := "hello",
scalacOptions in Compile += "-Xlint",
scalacOptions in (Compile, console) --= Seq("-Ywarn-unused", "-Ywarn-unused-import"),
fork in Test := true
)
現在可以寫成
ThisBuild / version := "1.0.0-SNAPSHOT"
lazy val root = (project in file("."))
.settings(
name := "hello",
Compile / scalacOptions += "-Xlint",
Compile / console / scalacOptions --= Seq("-Ywarn-unused", "-Ywarn-unused-import"),
Test / fork := true
)
現在在 sbt 的 shell 中使用相同的語法
sbt:hello> name
[info] hello
sbt:hello> ThisBuild / version
[info] 1.0.0-SNAPSHOT
sbt:hello> show Compile / scalacOptions
[info] * -Xlint
sbt:hello> show Compile / console / scalacOptions
[info] * -Xlint
sbt:hello> Test / fork
[info] true
有一個 用於統一斜線語法的語法 Scalafix 規則,可半自動地將現有的 sbt 0.13 語法重寫為斜線語法。目前它需要使用 scalafix CLI,而且不是很精確(因為它是一個僅查看程式碼形狀的語法規則),但它可以完成大部分工作。
$ scalafix --rules=https://gist.githubusercontent.com/eed3si9n/57e83f5330592d968ce49f0d5030d4d5/raw/7f576f16a90e432baa49911c9a66204c354947bb/Sbt0_13BuildSyntax.scala *.sbt project/*.scala
在 sbt 0.13 之前(sbt 0.9 到 0.12),在建置中很常見到使用 sbt 的三個方面
<<=
、<+=
、<++=
(foo, bar) map { (f, b) => ... }
)project/Build.scala
中使用 Build
特徵sbt 0.13 的發佈(三年前!)引入了 .value
DSL,它可以讓程式碼更容易讀寫,有效地使前兩個方面變得多餘,並從官方文件中刪除。
同樣地,sbt 0.13 引入的多專案 build.sbt
使 Build
特徵變得多餘。此外,現在在 sbt 0.13 中已成為標準的自動外掛程式功能啟用了外掛程式設定的自動排序和自動匯入功能,但它使 Build.scala
更難以維護。
由於它們已在 sbt 1.0.0 中移除,在此我們將協助您了解如何遷移您的程式碼。
對於簡單的運算式,例如
a <<= aTaskDef
b <+= bTaskDef
c <++= cTaskDefs
只需將它們替換為等效的
a := aTaskDef.value
b += bTaskDef.value
c ++= cTaskDefs.value
如上所述,有兩個 tuple enrichments .apply
和 .map
。差異在於您是否正在為 SettingKey
或 TaskKey
定義設定,前者使用 .apply
,後者使用 .map
val sett1 = settingKey[String]("SettingKey 1")
val sett2 = settingKey[String]("SettingKey 2")
val sett3 = settingKey[String]("SettingKey 3")
val task1 = taskKey[String]("TaskKey 1")
val task2 = taskKey[String]("TaskKey 2")
val task3 = taskKey[String]("TaskKey 3")
val task4 = taskKey[String]("TaskKey 4")
sett1 := "s1"
sett2 := "s2"
sett3 <<= (sett1, sett2)(_ + _)
task1 := { println("t1"); "t1" }
task2 := { println("t2"); "t2" }
task3 <<= (task1, task2) map { (t1, t2) => println(t1 + t2); t1 + t2 }
task4 <<= (sett1, sett2) map { (s1, s2) => println(s1 + s2); s1 + s2 }
(請記住,您可以用設定來定義任務,但反之則不行)
使用 .value
DSL,您不必知道或記住您的鍵是否為 SettingKey
或 TaskKey
sett1 := "s1"
sett2 := "s2"
sett3 := sett1.value + sett2.value
task1 := { println("t1"); "t1" }
task2 := { println("t2"); "t2" }
task3 := { println(task1.value + task2.value); task1.value + task2.value }
task4 := { println(sett1.value + sett2.value); sett1.value + sett2.value }
.dependsOn
、.triggeredBy
或 .runBefore
時遷移 當改為呼叫 .dependsOn
時,請勿使用
a <<= a dependsOn b
將其定義為
a := (a dependsOn b).value
請注意:由於問題 #1444,您需要在 sbt 0.13.13 和更早的版本中使用 <<=
運算子搭配 .triggeredBy
和 .runBefore
。
Task
時遷移 對於使用 sbt 的 Task 類型之鍵,例如 sourceGenerators
和 resourceGenerators
val sourceGenerators =
settingKey[Seq[Task[Seq[File]]]]("List of tasks that generate sources")
val resourceGenerators =
settingKey[Seq[Task[Seq[File]]]]("List of tasks that generate resources")
您先前會將其定義為
sourceGenerators in Compile <+= buildInfo
對於 sbt 1,您可以將其定義為
Compile / sourceGenerators += buildInfo
或一般來說,
Compile / sourceGenerators += Def.task { List(file1, file2) }
InputKey
遷移 當使用 InputKey
時,請勿使用
run <<= docsRunSetting
在遷移時,您不得使用 .value
,而應使用 .evaluated
run := docsRunSetting.evaluated
使用基於 Build
特徵的建置,例如
import sbt._
import Keys._
import xyz.XyzPlugin.autoImport._
object HelloBuild extends Build {
val shared = Defaults.defaultSettings ++ xyz.XyzPlugin.projectSettings ++ Seq(
organization := "com.example",
version := "0.1.0",
scalaVersion := "2.12.18")
lazy val hello =
Project("Hello", file("."),
settings = shared ++ Seq(
xyzSkipWrite := true)
).aggregate(core)
lazy val core =
Project("hello-core", file("core"),
settings = shared ++ Seq(
description := "Core interfaces",
libraryDependencies ++= scalaXml.value)
)
def scalaXml = Def.setting {
scalaBinaryVersion.value match {
case "2.10" => Nil
case _ => ("org.scala-lang.modules" %% "scala-xml" % "1.0.6") :: Nil
}
}
}
您可以遷移到 build.sbt
val shared = Seq(
organization := "com.example",
version := "0.1.0",
scalaVersion := "2.12.18"
)
lazy val helloRoot = (project in file("."))
.aggregate(core)
.enablePlugins(XyzPlugin)
.settings(
shared,
name := "Hello",
xyzSkipWrite := true
)
lazy val core = (project in file("core"))
.enablePlugins(XyzPlugin)
.settings(
shared,
name := "hello-core",
description := "Core interfaces",
libraryDependencies ++= scalaXml.value
)
def scalaXml = Def.setting {
scalaBinaryVersion.value match {
case "2.10" => Nil
case _ => ("org.scala-lang.modules" %% "scala-xml" % "1.0.6") :: Nil
}
}
project/Build.scala
重新命名為 build.sbt
。import sbt._
、import Keys._
和任何自動匯入。shared
、helloRoot
等)移出 object HelloBuild
,並移除 HelloBuild
。Project(...)
變更為 (project in file("x"))
樣式,並呼叫其 settings(...)
方法來傳入設定。這是為了讓自動外掛程式可以根據外掛程式相依性重新排序其設定順序。應該設定 name
設定以保留舊名稱。shared
移除 Defaults.defaultSettings
,因為這些設定已由內建的自動外掛程式設定,並從 shared
移除 xyz.XyzPlugin.projectSettings
,並改為呼叫 enablePlugins(XyzPlugin)
。請注意:Build
特徵已過時,但您仍然可以使用 project/*.scala
檔案來組織您的建置和/或定義 ad-hoc 外掛程式。請參閱組織建置。
在 0.13.x 中,您可以使用其他儲存庫,而不是 Maven Central 儲存庫
externalResolvers := Resolver.withDefaultResolvers(resolvers.value, mavenCentral = false)
在 1.x 之後,withDefaultResolvers
重新命名為 combineDefaultResolvers
。同時,其中一個參數 userResolvers
已變更為 Vector
,而不是 Seq
。
您可以使用 toVector
來協助遷移。
externalResolvers := Resolver.combineDefaultResolvers(resolvers.value.toVector, mavenCentral = false)
Vector
。