SBT: зависимости плагинов и путь к классам проекта - PullRequest
4 голосов
/ 27 октября 2011

Как добавить внешнюю зависимость в плагин SBT и сделать ее доступной как для проекта, так и для пути к классу плагина?:

В частности, у меня есть простой плагин, который должен запустить наши тестовые комплекты TestNG и выполнить некоторую постобработку. Вот упрощенная версия:

import sbt._
import java.util.ArrayList
import Keys._
import org.testng._

object RunTestSuitesPlugin extends Plugin {
  lazy val runTestSuites = TaskKey[Unit]("run-test-suites", "runs TestNG test suites")
  lazy val testSuites = SettingKey[Seq[String]]("test-suites", "list of test suites to run")

  class JavaListWrapper[T](val seq: Seq[T]) {
    def toJavaList = seq.foldLeft(new java.util.ArrayList[T](seq.size)) { (al, e) => al.add(e); al }
  }
  implicit def listToJavaList[T](l: Seq[T]) = new JavaListWrapper(l)

  def runTestSuitesTask = runTestSuites <<= (target, streams, testSuites) map {
    (targetDirectory, taskStream, suites) =>
      import taskStream.log
      log.info("running test suites: " + suites)
      runSuites(suites)
  }

  private def runSuites(testSuites: Seq[String]) = {
    var tester = new TestNG
    tester.setTestSuites(testSuites.toJavaList)
    tester.run()
  }

  def testSuiteSettings = {
    inConfig(Compile)(Seq(
      runTestSuitesTask,
      testSuites := Seq("testsuites/mysuite.xml"),
      libraryDependencies += "org.testng" % "testng" % "5.14"))
  }
}

Проблема в том, что когда я добавляю этот плагин в проект и запускаю его с run-test-suites , то происходит сбой с java.lang.NoClassDefFoundError: org / testng / TestNG хотя show full-classpath показывает, что testng.jar находится на пути к классам.

Так что путь к классу, используемый при выполнении плагина, каким-то образом отличается от того, который используется в моем проекте, так как мне сделать так, чтобы зависимость плагина появлялась в обоих местах?

Ответы [ 2 ]

1 голос
/ 31 октября 2011

Ошибка была исправлена ​​добавлением TestNG непосредственно к unmanagedJars в Compile в проекте, который использует плагин.

Я не нашел никаких ресурсов, объясняющих структуру пути класса SBT во время выполнения плагина, поэтому любая попытка объяснить, почему этот шаг необходим, будет принята с благодарностью.

1 голос
/ 27 октября 2011

Я попробую ответить, но я не очень знаком с внутренними деталями sbt.

Обычно путь для системы сборки (в отличие от вашей программы) находится в проекте, как объяснено здесь . Это было бы обычно в project/plugins.sbt. Звучит правильно, поскольку нет причин, по которым разрабатываемое вами приложение должно интересоваться тем, какие библиотеки использует ваша система сборки, или наоборот.

Когда ваш плагин запускает код приложения, это может быть не так просто, и могут возникнуть проблемы с classpath / classloader. Я не уверен, что это сработает. Обычно ваш плагин должен реализовывать среду тестирования, а не определять собственную задачу. Документация тестирования для sbt ограничена.

Среда тестирования должна реализовывать org.scalatools.testing.Framework в test-interface . Ваша сборка примет это во внимание после добавления

testFrameworks += new TestFramework("full.class.name")

Когда вы запускаете обычную тестовую команду, она позволяет каждой платформе распознавать тестовые классы, с которыми она имеет дело (доступны два критерия: расширение некоторого базового класса или наличие некоторой аннотации), и запускать их. Фреймворк запускается в сборке, ему предоставляется загрузчик классов для доступа к коду приложения.

Вы можете взглянуть на реализацию фреймворка для junit (поставляется с sbt). Также есть реализация TestNG . Я не знаю этого, согласно его документу, это немного неортодоксально, надеюсь, это сработает для вас.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...