我正在编写一个sbt任务来生成一些托管来源,为此我正在使用fast-classpath-scanner来提取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
注意:任务编译并运行完美,问题是生成的文件为空,因为扫描程序未找到检查。这可以确认,因为print("Hello world")
方法中的processMatch
语句未执行(控制台中没有输出)。
答案 0 :(得分:1)
我发现替罪羊罐确实在任务的 classpath 中,但由于某种原因(我不明白),可能与 sbt相关 classloader机制,快速类路径扫描程序无法找到它们。
对于有类似问题的任何人,要修复它,您只需要覆盖扫描仪类加载器。
fastCPScanner
.overrideClassLoaders(this.getClass.getClassLoader)
(...)
.scan()