【问题标题】:Play 2.0 / SBT: Exclude certain transitive dependencies from some/all modules in Build.scalaPlay 2.0 / SBT:从 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 的。那么,欢迎提出建议?

【问题讨论】:

    标签: scala playframework-2.0 sbt


    【解决方案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")
      )
      

      【讨论】:

        猜你喜欢
        • 2015-03-06
        • 2018-11-28
        • 2017-06-04
        • 2018-08-19
        • 1970-01-01
        • 2021-03-31
        • 1970-01-01
        • 2018-04-13
        • 2019-01-22
        相关资源
        最近更新 更多