Sbt test: doc Не удалось найти пользователя для ссылки

Я пытаюсь запустить sbt test:doc, и я вижу несколько предупреждений, похожих на ниже:

[warn]/Users/tleese/code/my/stuff/src/test/scala/com/my/stuff/common/tests/util/NumberExtractorsSpecs.scala:9: не удалось найти ни одного участника для ссылки для "com.my.stuff.common.util.IntExtractor".

Проблема заключается в том, что ссылки Scaladoc из источников тестов в основные источники не могут правильно установить связь. Любая идея, что я могу сделать неправильно или вам нужно настроить?

Ниже приведены соответствующие разделы моей сборки .scala:

val docScalacOptions = Seq("-groups", "-implicits", "-external-urls:[urls]")

scalacOptions in (Compile, doc) ++= docScalacOptions
scalacOptions in (Test, doc) ++= docScalacOptions
autoAPIMappings := true

Ответ 1

Не уверен, что это удовлетворительное решение, но...

Scaladoc в настоящее время ожидает, что пары jar и URL получат внешнюю ссылку для работы. Вы можете заставить sbt связывать внутренние зависимости с помощью JAR с помощью exportJars. Сравните значение

$ show test:fullClasspath

до и после установки exportJars. Затем возьмите имя используемого JAR и привяжите его к URL-адресу, к которому вы его загрузите.

scalaVersion := "2.11.0"

autoAPIMappings := true

exportJars := true

scalacOptions in (Test, doc) ++= Opts.doc.externalAPI((
  file(s"${(packageBin in Compile).value}") -> url("http://example.com/")) :: Nil)

Теперь я вижу, что test:doc Scaladoc со ссылками на http://example.com/index.html#foo.IntExtractor из моего foo.IntExtractor.

Ответ 2

Используя идеи из Ответ Евгения Я сделал следующий фрагмент. Он использует переменную apiMapping sbt, как указано в sbt manual. К сожалению, он не говорит о том, как обращаться с управляемыми зависимостями, даже в заголовке подраздела.

// External documentation

/* You can print computed classpath by `show compile:fullClassPath`.
 * From that list you can check jar name (that is not so obvious with play dependencies etc).
 */
val documentationSettings = Seq(
  autoAPIMappings := true,
  apiMappings ++= {
    // Lookup the path to jar (it probably somewhere under ~/.ivy/cache) from computed classpath
    val classpath = (fullClasspath in Compile).value
    def findJar(name: String): File = {
      val regex = ("/" + name + "[^/]*.jar$").r
      classpath.find { jar => regex.findFirstIn(jar.data.toString).nonEmpty }.get.data // fail hard if not found
    }

    // Define external documentation paths
    Map(
      findJar("scala-library") -> url("http://scala-lang.org/api/" + currentScalaVersion + "/"),
      findJar("play-json") -> url("https://playframework.com/documentation/2.3.x/api/scala/index.html")
    )
  }
)

Ответ 3

Это модификация ответа от @phadej. К сожалению, этот ответ работает только с Unix/Linux, поскольку предполагает, что разделитель путей является /. В Windows разделитель путей \.

Следующее работает на всех платформах и немного более идиоматично ИМХО:

/* You can print the classpath with `show compile:fullClassPath` in the SBT REPL.
 * From that list you can find the name of the jar for the managed dependency.
 */
lazy val documentationSettings = Seq(
  autoAPIMappings := true,
  apiMappings ++= {
    // Lookup the path to jar from the classpath
    val classpath = (fullClasspath in Compile).value
    def findJar(nameBeginsWith: String): File = {
      classpath.find { attributed: Attributed[java.io.File] => (attributed.data ** s"$nameBeginsWith*.jar").get.nonEmpty }.get.data // fail hard if not found
    }
    // Define external documentation paths
    Map(
      findJar("scala-library") -> url("http://scala-lang.org/api/" + currentScalaVersion + "/"),
      findJar("play-json") -> url("https://playframework.com/documentation/2.3.x/api/scala/index.html")
    )
  }
)