我有一个小的实用程序scala构建与专用测试文件夹下的测试类.编译然后publish-local在我的本地存储库中创建包.
正如预期的那样,测试文件夹会自动从实用程序包的本地jar中排除.
但是,生成的POM仍包含sbt中定义的相关依赖项.SBT依赖:
libraryDependencies ++= Seq(
"org.scalactic" %% "scalactic" % "3.0.0" % Test,
"org.scalatest" %% "scalatest" % "3.0.0" % Test
)
Run Code Online (Sandbox Code Playgroud)
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>
Run Code Online (Sandbox Code Playgroud)
范围显然需要进行测试,以防止使用此库的另一个项目(主)中的问题.特别是,主项目的测试否则包括这些测试库,这会导致版本冲突等.
由于这些依赖项仅适用于未包含的测试包,因此将它们列在POM中似乎很愚蠢.如何告诉SBT不要将这些测试范围依赖项包含在最终的POM中?
这里有一个类似的问题:sbt - 仅在发布期间排除某些依赖项。
根据 lyomi 提供的答案,这里是如何排除<dependency>包含子<scope>元素的所有元素,包括test和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
}
Run Code Online (Sandbox Code Playgroud)
这应该生成一个看起来像这样的 POM:
<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>
Run Code Online (Sandbox Code Playgroud)