1. 如何定義自訂的依賴組態

如何定義自訂的依賴組態 

依賴組態(或簡稱組態)定義了函式庫依賴的圖表,可能具有其自己的類別路徑、來源、產生的套件等。依賴組態的概念來自 Ivy,sbt 過去使用它來管理依賴項 [函式庫依賴][Library-Dependencies],以及來自 [MavenScopes](https://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html#Dependency_Scope)。

您在 sbt 中會看到的一些組態

  • Compile,它定義了主要建置(src/main/scala)。
  • Test,它定義了如何建置測試(src/test/scala)。
  • Runtime,它定義了 run 任務的類別路徑。

自訂依賴組態的注意事項 

只有在您引入一組新的原始碼或其自己的函式庫依賴項(如 Test)時,才應考慮自訂組態。

一般來說,僅將組態作為命名空間鍵的一種方式是一個壞主意。

自訂組態的一個缺點是,使用者會對範圍設定的複雜性感到困惑。他們可能熟悉子專案和任務,但當涉及組態範圍設定時,情況會變得複雜。

另一個缺點是 sbt 的支援有限。例如,您可以表達組態旨在extend另一個組態,但沒有設定的繼承。您必須提供所有預期的設定和任務。這意味著當 sbt 新增新功能時,自訂組態很可能不會被涵蓋。第三方外掛程式也是如此。

基本自訂組態範例 

以下是一個最小自訂組態的範例。

project/FuzzPlugin.scala 

package com.example.sbtfuzz

import sbt._

object FuzzPlugin extends AutoPlugin {
  object autoImport {
    lazy val Fuzz = config("fuzz")
  }
  import autoImport._
  override lazy val projectSettings =
    inConfig(Fuzz)(Defaults.configSettings)
}

build.sbt 

ThisBuild / scalaVersion     := "2.13.4"
ThisBuild / version          := "0.1.0-SNAPSHOT"

lazy val root = (project in file("."))
  .configs(Fuzz)
  .enablePlugins(FuzzPlugin, ScalafmtCliPlugin)
  .settings(
    name := "use",
  )

沙箱組態範例 

組態的一個有時有用的技術是將一個側圖新增到使用者的專案中,以便 Coursier 下載一些 JAR,您的任務可以調用它們。這稱為沙箱組態。例如,這可以用於調用 scalafmt 的 Scala 2.13 CLI 版本。從 sbt 1.4.x 開始,有一個限制,因此沙箱組態必須使用與使用者子專案相同的 Scala 版本。

project/ScalafmtPlugin.scala 

package com.example

import sbt._
import Keys._

object ScalafmtCliPlugin extends AutoPlugin {
  object autoImport {
    lazy val ScalafmtSandbox = config("scalafmt").hide
    lazy val scalafmt = inputKey[Unit]("")
  }
  import autoImport._
  override lazy val projectSettings = Seq(
    ivyConfigurations += ScalafmtSandbox,
    libraryDependencies += "org.scalameta" %% "scalafmt-cli" % "2.7.5" % ScalafmtSandbox,
    scalafmt := (ScalafmtSandbox / run).evaluated
  ) ++ inConfig(ScalafmtSandbox)(
    Seq(
      run := Defaults.runTask(managedClasspath, run / mainClass, run / runner)
        .evaluated,
      managedClasspath := Classpaths.managedJars(
        ScalafmtSandbox,
        classpathTypes.value,
        update.value,
      )
    ) ++
      inTask(run)(
        Seq(
          mainClass := Some("org.scalafmt.cli.Cli"),
          fork := true, // to avoid exit
        ) ++ Defaults.runnerSettings
      )
  )
}

啟用 ScalafmtPlugin 將新增 scalafmt 任務,該任務將執行 CLI。

sbt:custom-configs> scalafmt --version
[info] running (fork) org.scalafmt.cli.Cli --version
[info] scalafmt 2.7.5
[success] Total time: 3 s, completed Feb 8, 2021 12:01:34 AM
sbt:custom-configs> scalafmt
[info] running (fork) org.scalafmt.cli.Cli
[info] Reformatting...
       Reformatting...
[success] Total time: 6 s, completed Feb 8, 2021 12:01:40 AM

如何新增測試組態? 

請參閱 測試其他測試組態 部分。