如何解决“ crossPaths:= false”和“ + publish”之间的交互?

时间:2018-11-16 22:56:54

标签: scala sbt

我有一个build.sbt文件,其中定义了仅Java的子项目。因此,在该子项目中,我设置了crossPaths := false,以使Scala版本不包含在工件名称中。

它可以正常工作,但是,如果我调用sbt +publish,它将为两个版本的scala运行publish任务,并且由于它忽略了工件名称中的scala版本,因此该发布遇到了错误在第二个Scala交叉版本中,因为在第一个版本中生成了相同名称的工件。

我可以通过允许在publish上重写来解决它,但这有点丑陋,因为它不必要地重新生成工件,并且由于其他原因,overwrite可能是不安全的。

我正在寻找一种方法,对除第一个版本以外的所有scala版本进行逻辑上等效于skip in publish := false的操作,特别是在java子项目中,而不是在scala子项目中。

2 个答案:

答案 0 :(得分:1)

我已经添加了Cross building with a Java project的文档。

  

当交叉构建涉及纯Java项目时,必须格外小心。在下面的示例中,network是一个Java项目,而core是一个依赖网络的Scala项目。

lazy val scala212 = "2.12.8"
lazy val scala211 = "2.11.12"
lazy val supportedScalaVersions = List(scala212, scala211)

ThisBuild / organization := "com.example"
ThisBuild / version      := "0.1.0-SNAPSHOT"
ThisBuild / scalaVersion := scala212

lazy val root = (project in file("."))
  .aggregate(network, core)
  .settings(
    // crossScalaVersions must be set to Nil on the aggregating project
    crossScalaVersions := Nil,
    publish / skip := false
  )

// example Java project
lazy val network = (project in file("network"))
  .settings(
    // set to exactly one Scala version
    crossScalaVersions := List(scala212),
    crossPaths := false,
    autoScalaLibrary := false,
    // other settings
  )

lazy val core = (project in file("core"))
  .dependsOn(network)
  .settings(
    crossScalaVersions := supportedScalaVersions,
    // other settings
  )
  
      在诸如crossScalaVersions之类的汇总项目中,必须将
  1. Nil设置为root
  2.   
  3. Java子项目应该在crossScalaVersions中恰好有一个Scala版本,以避免重复发布,通常是scala212
  4.   
  5. Scala子项目在crossScalaVersions中可以有多个Scala版本,但是必须避免聚合Java子项目。
  6.   

答案 1 :(得分:0)

以下内容可以说是更多解决方法,但可以发布,并且相对容易理解:

在顶级项目中,您可以设置configure(aggregate in publish := false)。这允许大多数任务照常传播到java子项目,但是发布任务不会传播,因此您可以基于每个项目控制发布。现在,可以使用publish而不是+publish将java子项目发布一次:

sbt java_subproject/publish
sbt +top_level_project/publish

这种方法的缺点是,如果您有多个子项目,则每个子项目都需要单独发布:

sbt +sub_project_1/publish
sbt +sub_project_2/publish
...
sbt java_subproject/publish
sbt +top_level_project/publish

如果想花哨的话,可以为任何Java子项目插入一个垫片子项目,并使Java项目成为该垫片的子项目,然后在垫片上配置aggregate in publish := false。通过这个组织,您可以执行以下操作:

sbt java_shim_project/publish   // publish java projects exactly once
sbt +top_level_project/publish  // publish regular scala projects as usual