将JAR添加到SBT任务运行时

时间:2018-04-16 23:24:19

标签: scala sbt classpath

我正在编写一个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语句未执行(控制台中没有输出)

1 个答案:

答案 0 :(得分:1)

我发现替罪羊罐确实在任务的 classpath 中,但由于某种原因(我不明白),可能与 sbt相关 classloader机制,快速类路径扫描程序无法找到它们。

对于有类似问题的任何人,要修复它,您只需要覆盖扫描仪类加载器。

 fastCPScanner
   .overrideClassLoaders(this.getClass.getClassLoader)
   (...)
   .scan()