1. 工件

工件 

选择默认工件 

默认情况下,发布的工件是主二进制 jar、包含主源代码和资源的 jar 以及包含 API 文档的 jar。您可以添加测试类、源代码或 API 的工件,也可以禁用一些主工件。

要添加所有测试工件

lazy val app = (project in file("app"))
  .settings(
    Test / publishArtifact := true,
  )

要分别添加它们

lazy val app = (project in file("app"))
  .settings(
    // enable publishing the jar produced by `Test/package`
    Test / packageBin / publishArtifact := true,

    // enable publishing the test API jar
    Test / packageDoc / publishArtifact := true,

    // enable publishing the test sources jar
    Test / packageSrc / publishArtifact := true,
  )

要分别禁用主工件

lazy val app = (project in file("app"))
  .settings(
    // disable publishing the main jar produced by `package`
    Compile / packageBin / publishArtifact := false,

    // disable publishing the main API jar
    Compile / packageDoc / publishArtifact := false,

    // disable publishing the main sources jar
    Compile / packageSrc / publishArtifact := false,
  )

修改默认工件 

除了 publishArtifact 之外,每个内置工件都有一些可配置的设置。基本设置是 artifact(类型为 SettingKey[Artifact])、mappings(类型为 TaskKey[(File, String)])和 artifactPath(类型为 SettingKey[File])。它们按 (Config / <task>) 范围划分,如上一节所述。

要修改主工件的类型,例如

Compile / packageBin / artifact := {
  val prev: Artifact = (Compile / packageBin / artifact).value
  prev.withType("bundle")
}

生成的工件名称由 artifactName 设置决定。此设置的类型为 (ScalaVersion, ModuleID, Artifact) => String。ScalaVersion 参数提供完整的 Scala 版本字符串和版本的二进制兼容部分字符串。字符串结果是生成的要生成的文件的名称。默认实现是 Artifact.artifactName _。可以修改函数以生成不同的本地名称,而不会影响发布名称,发布名称由 artifact 定义和仓库模式组合决定。

例如,要生成没有分类器或交叉路径的最小名称

artifactName := { (sv: ScalaVersion, module: ModuleID, artifact: Artifact) =>
  artifact.name + "-" + module.revision + "." + artifact.extension
}

(请注意,在实践中您很少想删除分类器。)

最后,您可以通过映射 packagedArtifact 任务获取 (Artifact, File) 对。请注意,如果您不需要 Artifact,则可以从 package 任务(packagepackageDocpackageSrc)中获取 File。在这两种情况下,映射任务以获取文件可确保首先生成工件,因此文件保证是最新的。

例如

val myTask = taskKey[Unit]("My task.")

myTask :=  {
  val (art, file) = (Compile / packageBin / packagedArtifact).value
  println("Artifact definition: " + art)
  println("Packaged file: " + file.getAbsolutePath)
}

定义自定义工件 

除了配置内置工件外,您还可以声明其他要发布的工件。在使用 Ivy 元数据时允许使用多个工件,但 Maven POM 文件只支持根据分类器区分工件,而这些分类器不会记录在 POM 中。

基本 Artifact 构造看起来像

Artifact("name", "type", "extension")
Artifact("name", "classifier")
Artifact("name", url: URL)
Artifact("name", Map("extra1" -> "value1", "extra2" -> "value2"))

例如

Artifact("myproject", "zip", "zip")
Artifact("myproject", "image", "jpg")
Artifact("myproject", "jdk15")

有关工件的更多详细信息,请参见 Ivy 文档。有关组合上述参数和指定 [配置] 和额外属性的信息,请参见 Artifact API

要声明这些工件以进行发布,请将它们映射到生成工件的任务

val myImageTask = taskKey[File](...)

myImageTask := {
  val artifact: File = makeArtifact(...)
  artifact
}

addArtifact(Artifact("myproject", "image", "jpg"), myImageTask)

addArtifact 返回一系列设置(包装在 SettingsDefinition 中)。在完整的构建配置中,用法如下

lazy val app = (project in file("app"))
  .settings(
    addArtifact(...)
  )

发布 .war 文件 

Web 应用程序的常见用例是发布 .war 文件而不是 .jar 文件。

lazy val app = (project in file("app"))
  .settings(
    // disable .jar publishing
    Compile / packageBin / publishArtifact := false,

    // create an Artifact for publishing the .war file
    Compile / packageWar / artifact := {
      val prev: Artifact = (Compile / packageWar / artifact).value
      prev.withType("war").withExtension("war")
    },

    // add the .war file to what gets published
    addArtifact(Compile / packageWar / artifact, packageWar),
  )

使用带工件的依赖项 

要指定要从具有自定义或多个工件的依赖项中使用的工件,请在依赖项上使用 artifacts 方法。例如

libraryDependencies += ("org" % "name" % "rev").artifacts(Artifact("name", "type", "ext"))

fromclassifer 方法(在 库管理 页面上描述)实际上是便利方法,它们会转换为 artifacts

def from(url: String) = artifacts(Artifact(name, new URL(url)))
def classifier(c: String) = artifacts(Artifact(name, c))

也就是说,以下两个依赖项声明是等效的

libraryDependencies += ("org.testng" % "testng" % "5.7").classifier("jdk15")

libraryDependencies += ("org.testng" % "testng" % "5.7").artifacts(Artifact("testng", "jdk15"))