Play 2.0 / SBT:从 Build.scala 中的某些/所有模块中排除某些传递依赖项

Posted

技术标签:

【中文标题】Play 2.0 / SBT:从 Build.scala 中的某些/所有模块中排除某些传递依赖项【英文标题】:Play 2.0 / SBT: Exclude certain transitive dependencies from some/all modules in Build.scala 【发布时间】:2013-03-11 17:37:38 【问题描述】:

我有一个带有 Grails 前端的大型遗留 Java 应用程序,我正在努力用 Play 编写的新前端替换 Grails 前端。遗留 Java 中的一些 (Maven) 模块依赖项会带来有问题/冲突的事情。在这一点上,整理出所有遗留的 Java 依赖项并不是一个真正的选择,所以我只想排除我不喜欢的传递依赖项。

在 Grails BuildConfig.groovy 中,我可以定义一个排除列表:

def some_bad_things = [
        [group: 'some-evil-group'],
        [name: 'some-evil-module-from-another-group'],
        [name: 'some-other-evil-module']
]

然后将其用于整个直接依赖块:

dependencies 
    compile (
        [group: 'com.foo', name: 'foo-module1', version: '1.0'],
        // ... 20 or 30 modules ...
        [group: 'com.quux', name: 'quux-module42', version: '7.2'],
    ) 
        excludes some_bad_things
    

Build.scala 语法用于做同样的事情并不明显。翻译实际的依赖关系非常简单......

val appDependencies = Seq(
    "com.foo" % "foo-module1" % "1.0" % "compile",
    // ... 20 or 30 modules ...
    "com.quux" % "quux-module42" % "7.2" % "compile"
)

...但排除不是;看来我必须单独排除所有内容:

val appDependencies = Seq(
    ("com.foo" % "foo-module1" % "1.0" % "compile"),
        .exclude("some-evil-group", "evil-module-1")
        .exclude("some-evil-group", "evil-module-2")
        .exclude("mostly-ok-group-1", "some-evil-module-from-another-group")
        .exclude("mostly-ok-group-2", "some-other-evil-module"),

    // ... 20 or 30 modules, each with four excludes ...

    ("com.quux" % "quux-module42" % "7.2" % "compile")
        .exclude("some-evil-group", "evil-module-1")
        .exclude("some-evil-group", "evil-module-2")
        .exclude("mostly-ok-group-1", "some-evil-module-from-another-group")
        .exclude("mostly-ok-group-2", "some-other-evil-module")

)

我认为这里没有很多火箭科学,即使没有开箱即用的全局排除方法,编写一些辅助函数或其他东西也不难对我来说。但是我是 Scala 新手,我甚至不清楚我正在查看什么类型或所有操作员做什么,或者我所看到的有多少是纯 Scala / SBT,有多少是特定于 Play 的。那么,欢迎提出建议?

【问题讨论】:

【参考方案1】:

回答有点晚了,但是您可以编写一个过滤器,将排除应用于列表中的每个依赖项,如下所示:

def excludeFromAll(items: Seq[ModuleID], group: String, artifact: String) = 
  items.map(_.exclude(group, artifact))

然后用它来过滤你的依赖:

val deps = Seq(dependencies)
val appDependencies = excludeFromAll(deps, "groupId", "artifactId")

或者,如果您想获得更流畅的语法,更像是常规的 sbt 东西,但使用更高级的 Scala 代码(编辑:最初使用 Scala 2.10 隐式类编写):

implicit def dependencyFilterer(deps: Seq[ModuleID]) = new Object 
  def excluding(group: String, artifactId: String) =
    deps.map(_.exclude(group, artifactId))

这反过来会让你像这样声明你的依赖项

val appDependencies = Seq(...).excluding("groupId", "artifactId")

我将排除您需要的传递性部门列表作为读者练习,鉴于这些示例,应该不会太难, 希望这会有所帮助!

【讨论】:

【参考方案2】:

刚刚在 SBT 0.13 中找到,我们可以通过以下代码简单地做到这一点:

excludeDependencies ++= Seq(
  SbtExclusionRule("com.google.gwt", "gwt-user"),
  SbtExclusionRule("com.google.gwt", "gwt-dev"),
  SbtExclusionRule("com.google.gwt", "gwt-servlet"),
  SbtExclusionRule("com.google.guava", "guava-gwt")
)

【讨论】:

这是我需要解决的一个问题,我已经为此苦苦挣扎了数周!谢谢!【参考方案3】:

我认为它告诉 SBT 文档更容易: http://www.scala-sbt.org/0.12.2/docs/Detailed-Topics/Library-Management.html

 libDependencies += "com.quux" % "quux-module42" % "7.2" % "compile" intransitive()

此方法的问题在于您排除了给定工件的所有依赖项。

【讨论】:

在所有子依赖项都是可选的情况下,这是迄今为止最优雅的解决方案。例如。它为我解决了 x-stream.github.io 包含问题,否则会遇到类重复问题。 这是一个可扩展的解决方案,因为依赖项会自动解析以排除。当包含任何新的传递依赖时,无需手动更新 excluseDependencies。【参考方案4】:

在 sbt 1.* 中是ExclusionRule。所以这是@Jake W的调整答案:

excludeDependencies ++= Seq(
  ExclusionRule("com.google.gwt", "gwt-user"),
  ExclusionRule("com.google.gwt", "gwt-dev"),
  ExclusionRule("com.google.gwt", "gwt-servlet"),
  ExclusionRule("com.google.guava", "guava-gwt")
)

【讨论】:

以上是关于Play 2.0 / SBT:从 Build.scala 中的某些/所有模块中排除某些传递依赖项的主要内容,如果未能解决你的问题,请参考以下文章

将项目升级到 Play Framework 的 2.2.0 版本

如何为 sbt/play 禁用彩色终端输出?

在 Play 2.3.x 应用程序中使用 sbt-rjs 从 WebJars 优化 JS

将 JVM Opts 从 build.sbt 传递到 Play Framework 2.2.x 中的启动脚本

在 Play 2.3 的 build.sbt 中应该如何定义 routesImport?

升级 Play/Scala/SBT/jOOQ/HSQLDB 应用程序时出错