【问题标题】:How to work around interaction between 'crossPaths := false' and '+publish'?如何解决“crossPaths := false”和“+publish”之间的交互?
【发布时间】:2019-01-04 00:57:48
【问题描述】:

我有一个 build.sbt 文件,我在其中定义了一个仅限 java 的子项目。所以在那个子项目中,我设置了crossPaths := false,这样scala版本就不会包含在工件名称中。

就目前而言,它可以工作,但是,如果我调用 sbt +publish,它会为两个版本的 scala 运行发布任务,并且由于它忽略了工件名称中的 scala 版本,因此发布在第二个跨 Scala 版本,因为在第一个版本上生成了同名的工件。

我可以通过允许在发布时覆盖来绕过它,但这有点难看,因为它不必要地重新生成工件,并且覆盖可能由于其他原因不安全。

我正在寻找一种在逻辑上等同于 skip in publish := false 的方法,用于除第一个版本之外的所有 scala 版本,特别是在 java 子项目中,但不是 scala 子项目。

【问题讨论】:

    标签: scala sbt


    【解决方案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
      )
    
    1. root 等聚合项目上,crossScalaVersions 必须设置为 Nil
    2. Java 子项目在 crossScalaVersions 中应该只有一个 Scala 版本以避免重复发布,通常是 scala212
    3. Scala 子项目可以在crossScalaVersions 中有多个 Scala 版本,但必须避免聚合 Java 子项目。

    【讨论】:

      【解决方案2】:

      下面的内容可以说是一种解决方法,但允许发布并且相对容易理解:

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

      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子项目插入一个shim子项目,并将java项目作为这个shim的子项目,然后在shim上配置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
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-09-06
        • 2016-11-11
        • 2016-05-15
        • 2015-03-31
        • 2014-06-28
        相关资源
        最近更新 更多