将 JAR 添加到 SBT 任务运行时
Adding JAR to SBT task runtime
我正在编写一个 sbt 任务来生成一些托管源,为此我正在使用 fast-classpath-scanner to extract all sub-classes of the scapegoat inspection class。
我首先将它作为一个普通的 scala project 来实现并且它起作用了,但是当我试图将它作为一个 SBT 任务来实现时 我遇到了一个问题,它是替罪羊 jar 不在 运行 任务的 classpath 中,所以类路径扫描器失败了。
我在 project/plugins.sbt
文件中有任务的依赖项。
//adding the generation task dependencies
libraryDependencies ++= Seq(
"com.sksamuel.scapegoat" %% "scalac-scapegoat-plugin" % "1.3.4",
"io.github.lukehutch" % "fast-classpath-scanner" % "2.18.1"
)
并且我在build.sbt
文件中实现了生成任务:
//source generator task (simplified)
sourceGenerators in Compile += Def.task {
//_root_ is needed because there is a sbt.io package in scope
import _root_.io.github.lukehutch.fastclasspathscanner.FastClasspathScanner
import _root_.io.github.lukehutch.fastclasspathscanner.matchprocessor.SubclassMatchProcessor
import com.sksamuel.scapegoat.Inspection
import scala.collection.mutable
val inspectionClass = classOf[Inspection]
val fastCPScanner = new FastClasspathScanner(inspectionClass.getPackage.getName)
val inspections = mutable.ListBuffer.empty[Inspection]
fastCPScanner
.matchSubclassesOf(
inspectionClass,
new SubclassMatchProcessor[Inspection] {
override def processMatch(matchingClass: Class[_ <: Inspection]): Unit = {
inspections += matchingClass.newInstance()
println("Hello World")
}
}
).scan()
val lines = inspections.toList.zipWithIndex map {
case (inspection, idx) => s"${inspections.text} -> ${idx}"
}
val scapegoatInspectionsFile = (sourceManaged in Compile).value / "scapegoat" / "inspections.scala"
IO.writeLines(scapegoatInspectionsFile, lines)
Seq(scapegoatInspectionsFile)
}.taskValue
注意:任务编译运行完美,问题是生成的文件是空的,因为scanner没有发现检查。可以确认是因为processMatch
方法里面的print("Hello world")
语句没有执行(控制台无输出).
我发现替罪羊罐子确实在任务的类路径中,但由于某种原因(我不明白),可能与sbt 类加载器机制,fast-classpath-scanner 找不到它们。
对于有类似问题的任何人,要修复它,您只需要覆盖扫描器类加载器。
fastCPScanner
.overrideClassLoaders(this.getClass.getClassLoader)
(...)
.scan()
我正在编写一个 sbt 任务来生成一些托管源,为此我正在使用 fast-classpath-scanner to extract all sub-classes of the scapegoat inspection class。
我首先将它作为一个普通的 scala project 来实现并且它起作用了,但是当我试图将它作为一个 SBT 任务来实现时 我遇到了一个问题,它是替罪羊 jar 不在 运行 任务的 classpath 中,所以类路径扫描器失败了。
我在 project/plugins.sbt
文件中有任务的依赖项。
//adding the generation task dependencies
libraryDependencies ++= Seq(
"com.sksamuel.scapegoat" %% "scalac-scapegoat-plugin" % "1.3.4",
"io.github.lukehutch" % "fast-classpath-scanner" % "2.18.1"
)
并且我在build.sbt
文件中实现了生成任务:
//source generator task (simplified)
sourceGenerators in Compile += Def.task {
//_root_ is needed because there is a sbt.io package in scope
import _root_.io.github.lukehutch.fastclasspathscanner.FastClasspathScanner
import _root_.io.github.lukehutch.fastclasspathscanner.matchprocessor.SubclassMatchProcessor
import com.sksamuel.scapegoat.Inspection
import scala.collection.mutable
val inspectionClass = classOf[Inspection]
val fastCPScanner = new FastClasspathScanner(inspectionClass.getPackage.getName)
val inspections = mutable.ListBuffer.empty[Inspection]
fastCPScanner
.matchSubclassesOf(
inspectionClass,
new SubclassMatchProcessor[Inspection] {
override def processMatch(matchingClass: Class[_ <: Inspection]): Unit = {
inspections += matchingClass.newInstance()
println("Hello World")
}
}
).scan()
val lines = inspections.toList.zipWithIndex map {
case (inspection, idx) => s"${inspections.text} -> ${idx}"
}
val scapegoatInspectionsFile = (sourceManaged in Compile).value / "scapegoat" / "inspections.scala"
IO.writeLines(scapegoatInspectionsFile, lines)
Seq(scapegoatInspectionsFile)
}.taskValue
注意:任务编译运行完美,问题是生成的文件是空的,因为scanner没有发现检查。可以确认是因为processMatch
方法里面的print("Hello world")
语句没有执行(控制台无输出).
我发现替罪羊罐子确实在任务的类路径中,但由于某种原因(我不明白),可能与sbt 类加载器机制,fast-classpath-scanner 找不到它们。
对于有类似问题的任何人,要修复它,您只需要覆盖扫描器类加载器。
fastCPScanner
.overrideClassLoaders(this.getClass.getClassLoader)
(...)
.scan()