Exclude plugin's libraryDependencies from released application when "package" in SBT

957 views Asked by At

In my SBT project I use sbt-scoverage plugin. I did what the documentation says and added ScoverageSbtPlugin.instrumentSettings to build.sbt. Everything works great so far.

When I package my app I can see in pom.xml that there is a dependency that should not be there:

<dependency>
  <groupId>com.sksamuel.scoverage</groupId>
  <artifactId>scalac-scoverage-plugin</artifactId>
  <version>0.95.4</version>
</dependency>

This is a library dependency of the sbt-scoverage plugin that I don't want to have as a dependency in my released app.

I believe that this dependency is created by the following code in ScoverageSbtPlugin.scala:

libraryDependencies += "com.sksamuel.scoverage" %% "scalac-scoverage-plugin" %
    ScalacScoveragePluginVersion % scoverage.name

Can anyone tell me how to make this dependency to be added only when I run sbt scoverage:test?

2

There are 2 answers

1
Rado Buransky On BEST ANSWER

I came to following solution. I have replaced this:

ivyConfigurations ++= Seq(scoverage, scoverageTest)

with this:

ivyConfigurations ++= Seq(scoverage hide, scoverageTest hide)

Here's the changeset: https://github.com/scoverage/sbt-scoverage/commit/6d7ebe07482933f588e9feb23f80eeed2aa14f62

I would appreciate anybody's view on that. It works "on my machine".

2
danmbyrd On

The way that scoverage seems to be written forces this dependency to be added to libraryDependencies in Compile, as you've noticed. However one workaround is to use the makePomConfiguration Setting in sbt. You can perform transformations on the constructed POM to remove the added dependency, without affecting how scoverage works. Below I've made a build that will filter out the scoverage dependency in your POM. I've used a .scala file as you can't define objects in build.sbt pre 0.13. So this file would be located at project/Build.scala.

import sbt.Keys._
import sbt._
import scala.xml.{Elem, Node}
import scala.xml.transform.{RuleTransformer, RewriteRule}

object theBuild extends Build {

  object FilterBadDependency extends RewriteRule {

      override def transform(n: Node): Seq[Node] = n match {
        /**
         * When we find the dependencies node we want to rewrite it removing any of
         * the scoverage dependencies.
         */
        case dependencies @ Elem(_, "dependencies", _, _, _*) =>
          <dependencies>
            {
              dependencies.child filter { dep =>
                (dep \ "groupId").text != "com.sksamuel.scoverage"
              }
            }
          </dependencies>

        /**
         * Otherwise we just skip over the node and do nothing
         */
        case other => other
      }

  }

  object TransformFilterBadDependencies extends RuleTransformer(FilterBadDependency)

  val project = Project(
    id = "test-build",
    base = file(".")
  ).settings(
      ScoverageSbtPlugin.instrumentSettings: _*
  ).settings(
      /**
       * Here we alter our make pom configuration so that our transformation is applied to
       * the constructed pom
       */
    makePomConfiguration ~= { config =>
      config.copy(process = TransformFilterBadDependencies)
    })
}