I have a small utilities scala build with test classes under a dedicated test folder. Compiling and then publish-local
creates the package in my local repository.
As expected, the test folder is automatically excluded from the local jar of the utilities package.
However, the resulting POM still contains the related dependencies as defined in the sbt. The SBT dependencies:
libraryDependencies ++= Seq(
"org.scalactic" %% "scalactic" % "3.0.0" % Test,
"org.scalatest" %% "scalatest" % "3.0.0" % Test
)
The segment of the POM:
<dependency>
<groupId>org.scalactic</groupId>
<artifactId>scalactic_2.11</artifactId>
<version>3.0.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.scalatest</groupId>
<artifactId>scalatest_2.11</artifactId>
<version>3.0.0</version>
<scope>test</scope>
</dependency>
The scope clearly needs to be test in order to prevent issues in another project (main) that uses this library. In particular, the testing of the main project otherwise includes these test libraries, which causes version conflicts etc.
As these dependencies are only for the not included test package, having them listed in the POM seems silly. How do I tell SBT to not include these test scope dependencies into the final POM?
There was a similar question asked here: sbt - exclude certain dependency only during publish.
Riffing on the answer provided by lyomi, here's how you can exclude all <dependency>
elements that contains a child <scope>
element, including test
and provided
.
import scala.xml.{Node => XmlNode, NodeSeq => XmlNodeSeq, _}
import scala.xml.transform.{RewriteRule, RuleTransformer}
// skip dependency elements with a scope
pomPostProcess := { (node: XmlNode) =>
new RuleTransformer(new RewriteRule {
override def transform(node: XmlNode): XmlNodeSeq = node match {
case e: Elem if e.label == "dependency"
&& e.child.exists(child => child.label == "scope") =>
def txt(label: String): String = "\"" + e.child.filter(_.label == label).flatMap(_.text).mkString + "\""
Comment(s""" scoped dependency ${txt("groupId")} % ${txt("artifactId")} % ${txt("version")} % ${txt("scope")} has been omitted """)
case _ => node
}
}).transform(node).head
}
This should generate a POM that looks like this:
<dependencies>
<dependency>
<groupId>org.scala-lang</groupId>
<artifactId>scala-library</artifactId>
<version>2.12.5</version>
</dependency>
<!-- scoped dependency "org.scalatest" % "scalatest_2.12" % "3.0.5" % "test" has been omitted -->
</dependencies>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With