Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Play 2.0 / SBT: Exclude certain transitive dependencies from some/all modules in Build.scala

I have a large legacy Java application with a Grails front end, and I'm working on replacing the Grails front end with a new one written in Play. Some of the (Maven) module dependencies in the legacy Java bring in problematic/conflicting things. Sorting out all the legacy Java dependencies isn't really an option at this point, so I'd like to just exclude the transitive dependencies I don't like.

In Grails BuildConfig.groovy, I can define a list of exclusions:

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

and then use it for a whole block of direct dependencies:

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
    }
}

It's not obvious what the Build.scala syntax is for doing the same thing. Translating the actual dependencies is pretty straightforward ...

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

... but the exclusions aren't; it looks like I have to exclude everything individually:

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")

)

I assume there isn't a lot of rocket science going on here, and even if there's no out of the box way to globally exclude, it shouldn't be hard to write some helper function, or something, that would do it for me. But I'm a Scala newbie and it's not even obvious to me what types I'm looking at or what all the operators do, or how much of what I'm seeing is plain Scala / SBT and how much is Play-specific. So, suggestions welcome?

like image 592
David Moles Avatar asked Mar 22 '13 00:03

David Moles


2 Answers

Just found in SBT 0.13, we could simply do it via the code below:

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")
)
like image 71
Jake W Avatar answered Oct 20 '22 07:10

Jake W


A bit late answer but, you could write a filter that applies the exclude to each dependency in a list like this:

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

and then use that to filter your dependencies:

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

Or if you want to get a more fluent syntax, more like the regular sbt stuff, but with a little bit more advanced Scala code (edit: originally wrote it with Scala 2.10 implicit class):

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

which in turn would let you to declare your dependencies like this

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

I'm leaving the exclude a list of transitive deps that you need as an exercise for the reader, shouldn't be too hard given these examples, hope this helped!

like image 15
johanandren Avatar answered Oct 20 '22 05:10

johanandren