有条件地使用 sbt 和通用插件包含提供的范围依赖项
Posted
技术标签:
【中文标题】有条件地使用 sbt 和通用插件包含提供的范围依赖项【英文标题】:Conditionally include provided scope dependencies with sbt and the universal plugin 【发布时间】:2016-08-19 04:33:57 【问题描述】:我有一个项目是 scala & scalatra API。我有两个使用 sbt-native-packager 构建的可分发文件 -
-
RPM 和 DEB 安装用于本地安装
用于云安装的 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 中不再有许可证限制。
我认为我有的选择...
-
添加
mapping
以在 stage
任务期间添加回提供的范围依赖项,但在 dist
任务期间不添加
在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").mapt =>
(t._1, "lib/"+t._2)
)
所以我觉得如果我真的尝试过,我可能会弄清楚如何添加/排除,但我在查找这些东西的任何文档时遇到了问题。 here 的例子并没有太大帮助,或者我理解的不够。
提前致谢!
【问题讨论】:
【参考方案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.. 添加了它们 真棒@卢卡斯!对不起,我没有想到:(以上是关于有条件地使用 sbt 和通用插件包含提供的范围依赖项的主要内容,如果未能解决你的问题,请参考以下文章
sbt 插件和使用插件本身的多项目构建中的项目之间的相互依赖关系