【问题标题】:Conditionally include provided scope dependencies with sbt and the universal plugin有条件地使用 sbt 和通用插件包含提供的范围依赖项
【发布时间】:2016-08-19 04:33:57
【问题描述】:

我有一个项目是 scala & scalatra API。我有两个使用 sbt-native-packager 构建的可分发文件 -

  1. RPM 和 DEB 安装用于本地安装
  2. 用于云安装的 heroku 安装

我目前正在使用 provided 范围依赖项来处理我需要使用 RPM/DEB 方法手动管理的项目 - 由于许可证限制,我无法捆绑和分发的数据库库。

"mysql" % "mysql-connector-java" % "5.1.30" % "provided",
"com.microsoft" % "sqlserver.jdbc" % "4.1" % "provided",
..etc..

这一直很好。我使用通用插件和dist 任务,稍加处理,然后连接一些包构建脚本。

现在我正在构建 heroku 安装,但我不知道如何重新添加那些提供的依赖项。我正在使用通用插件并运行stage 任务。但是,提供的依赖项正在被过滤掉,我希望在运行 stage 时将它们包含在内,因为我在 heroku 中不再有许可证限制。

我认为我有的选择...

  1. 添加 mapping 以在 stage 任务期间添加回提供的范围依赖项,但在 dist 任务期间不添加
  2. dist 期间完全删除提供的范围并手动从打包过程中排除这些依赖项

我已经有一些这样的映射,

//add webapp dir to zip
mappings in Universal ++= directory("src/main/webapp")

//add db dir to zip, but move it into /lib/db instead of /db
mappings in Universal ++= (directory("src/main/resources/db").map{t => 
    (t._1, "lib/"+t._2)
  }
)

所以我觉得如果我真的尝试过,我可能会弄清楚如何添加/排除,但我在查找这些东西的任何文档时遇到了问题。 here 的例子并没有太大帮助,或者我理解的不够。

提前致谢!

【问题讨论】:

    标签: scala sbt sbt-native-packager


    【解决方案1】:

    这是一个有趣的问题。前段时间,我们在构建类路径中添加了add arbitrary artifacts 的可能性。 (也见scaladocs

    选项 1 可能如下所示。请注意,这并不像我预期的那样工作,因为本机打包程序并未完全拾取某些映射:

    // `show universal::stage:mappings` works properly
    mappings in (Universal, stage) ++= {
      // calculate provided dependencies.
      val compileDep = (managedClasspath in Compile).value.toSet
      val runtimeDep = (managedClasspath in Runtime).value.toSet
      val provided = compileDep -- runtimeDep
    
      // create mappings
      fromClasspath(provided.toSeq, "jar", artifact => true)
    }
    

    我通过提供build environment 并决定要添加哪些映射来建议选项 1 的变体。

    mappings in Universal ++= {
      // a build environment
      val env = buildEnv.value
    
      // calculate provided dependencies.
      val compileDep = (managedClasspath in Compile).value.toSet
      val runtimeDep = (managedClasspath in Runtime).value.toSet
      val provided = compileDep -- runtimeDep
    
      // create mappings, depending on build environment
      fromClasspath(provided.toSeq, "jar", _ => env == BuildEnv.Stage)
    }
    
    // add the dependencies to the start script as well
    scriptClasspath ++= { /* similar code as above */}
    

    我想做的事

    我希望能够做到这样的事情

    libraryDependencies += "com.google.guava" % "guava" % "19.0" % "provided"
    
    mappings in (Universal, stage) ++= fromClasspath(
       (managedClasspath in Compile).value,
       "jar",
        artifact => artifact.scope == "provided"
    )
    

    这是不可能的,因为sbt Artifact 无法访问常春藤范围(或者我没有找到它)。

    然后我尝试这样做

    libraryDependencies += "com.google.guava" % "guava" % "19.0" % "provided" extra("heroku" -> "true")
    
    mappings in (Universal, stage) ++= fromClasspath(
       (managedClasspath in Compile).value,
       "jar",
        artifact => artifact.extra.find(_ == "heroku")
          .map(_.toBoolean)
          .getOrElse(false)
    )
    

    这也不起作用,因为 SBT 似乎没有将 ModuleID 中的 extra 属性传递给 Artifact 模型。这给我留下了上述解决方案。

    【讨论】:

    • 似乎成功了,非常感谢您的帮助。我能够添加一些过滤来调整结果,然后我们就可以开始运行了。对 sbt Artifact 感到难过 - 你会认为应该能够在带内访问此类信息,而不是制作另一个配置项!
    • 实际上这并不太成功 - 它添加了映射文件,但没有设法将它们添加到运行脚本的类路径条目中。现在正在尝试解决这个问题
    • 使用 scriptClasspath ++= { ..same stuff.. } 添加了它们
    • 真棒@卢卡斯!对不起,我没有想到:(
    猜你喜欢
    • 2016-07-26
    • 1970-01-01
    • 2011-12-31
    • 2022-12-18
    • 2016-02-23
    • 2016-05-28
    • 2017-01-01
    • 2015-12-27
    • 1970-01-01
    相关资源
    最近更新 更多