mirror of https://github.com/sbt/sbt.git
**Problem** When `autoAPIMappings := true` is set on a Scala 3 project, running `sbt doc` emits warnings: ``` [warn] bad option '-doc-external-doc:/modules/java.base#https://docs.oracle.com/... ``` This happens because Scala 3's scaladoc doesn't recognize Scala 2's `-doc-external-doc` option. Fixes #6652 **Solution** - Added `Opts.doc.externalAPIScala3` that generates the Scala 3 format: `-external-mappings:regex::[scaladoc3|javadoc]::url` - Modified `Defaults.scala` to use the appropriate method based on Scala version - Added heuristics to detect javadoc vs scaladoc based on file/URL patterns
This commit is contained in:
parent
c099be5f18
commit
f4ab500d19
|
|
@ -2030,7 +2030,10 @@ object Defaults extends BuildCommon {
|
|||
val xapisFiles = xapis.map { (k, v) =>
|
||||
converter.toPath(k).toFile() -> v
|
||||
}
|
||||
val options = sOpts ++ Opts.doc.externalAPI(xapisFiles)
|
||||
val externalApiOpts =
|
||||
if (ScalaArtifacts.isScala3(sv)) Opts.doc.externalAPIScala3(xapisFiles)
|
||||
else Opts.doc.externalAPI(xapisFiles)
|
||||
val options = sOpts ++ externalApiOpts
|
||||
val scalac = cs.scalac match
|
||||
case ac: AnalyzingCompiler => ac.onArgs(exported(s, "scaladoc"))
|
||||
val docSrcFiles = if ScalaArtifacts.isScala3(sv) then tFiles else srcs
|
||||
|
|
|
|||
|
|
@ -38,6 +38,37 @@ object Opts {
|
|||
mappings
|
||||
.map { (f, u) => s"${f.getAbsolutePath}#${u.toURL().toExternalForm}" }
|
||||
.mkString("-doc-external-doc:", ",", "") :: Nil
|
||||
|
||||
/**
|
||||
* Generates Scala 3 scaladoc external mappings option.
|
||||
* Format: -external-mappings:regex::[scaladoc3|scaladoc|javadoc]::url,...
|
||||
*/
|
||||
def externalAPIScala3(mappings: Iterable[(File, URI)]): Seq[String] =
|
||||
if (mappings.isEmpty) Nil
|
||||
else
|
||||
mappings
|
||||
.map { (f, u) =>
|
||||
val fileName = f.getName
|
||||
// Escape regex special characters in the filename
|
||||
val escapedName = fileName.replaceAll("([\\[\\]{}()*+?.\\\\^$|])", "\\\\$1")
|
||||
// Use a regex pattern that matches the file anywhere in the classpath
|
||||
val regex = s".*$escapedName"
|
||||
// Determine if this is javadoc or scaladoc based on the file/URL
|
||||
val docType = if (isJavaDoc(f, u)) "javadoc" else "scaladoc3"
|
||||
s"$regex::$docType::${u.toURL().toExternalForm}"
|
||||
}
|
||||
.mkString("-external-mappings:", ",", "") :: Nil
|
||||
|
||||
private def isJavaDoc(file: File, uri: URI): Boolean = {
|
||||
val name = file.getName.toLowerCase
|
||||
val url = uri.toString.toLowerCase
|
||||
// Heuristics to detect Java documentation
|
||||
name.startsWith("rt.jar") ||
|
||||
name.contains("java") && !name.contains("scala") ||
|
||||
url.contains("docs.oracle.com") ||
|
||||
url.contains("javadoc") ||
|
||||
url.contains("/java/") && !url.contains("scala")
|
||||
}
|
||||
}
|
||||
object resolver {
|
||||
import sbt.io.syntax.*
|
||||
|
|
|
|||
|
|
@ -0,0 +1,22 @@
|
|||
// Test for issue #6652: Doc task fails with `bad option '-doc-external-doc'` for scala3 project
|
||||
// This test verifies that autoAPIMappings works correctly with Scala 3's -external-mappings option
|
||||
|
||||
lazy val root = (project in file("."))
|
||||
.settings(
|
||||
scalaVersion := "3.3.4",
|
||||
autoAPIMappings := true,
|
||||
libraryDependencies += "org.typelevel" %% "cats-core" % "2.12.0",
|
||||
TaskKey[Unit]("checkDocGenerated") := {
|
||||
val docDir = (Compile / doc / target).value
|
||||
val indexFile = docDir / "index.html"
|
||||
assert(indexFile.exists(), s"Expected $indexFile to exist after doc generation")
|
||||
println(s"Documentation generated successfully at $docDir")
|
||||
},
|
||||
TaskKey[Unit]("checkApiMappings") := {
|
||||
val mappings = (Compile / doc / apiMappings).value
|
||||
println(s"API Mappings count: ${mappings.size}")
|
||||
// With autoAPIMappings and cats-core dependency, we should have some mappings
|
||||
// (cats-core publishes with apiURL)
|
||||
println(s"API Mappings: ${mappings.take(3).mkString("\n ", "\n ", "")}")
|
||||
}
|
||||
)
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
package example
|
||||
|
||||
/** An example class to generate documentation for. */
|
||||
class Example {
|
||||
/** Returns a greeting */
|
||||
def greet: String = "Hello"
|
||||
}
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
# Test for issue #6652: Doc task should use -external-mappings for Scala 3
|
||||
# instead of -doc-external-doc which causes "bad option" warnings
|
||||
|
||||
# Show the API mappings that will be used
|
||||
> checkApiMappings
|
||||
|
||||
# Run the doc task - this should succeed without "bad option" warnings
|
||||
# Before the fix, this would emit a warning about bad option -doc-external-doc
|
||||
> doc
|
||||
|
||||
# Verify documentation was actually generated
|
||||
> checkDocGenerated
|
||||
Loading…
Reference in New Issue