2013-06-05 10 views
18

Próbuję połączyć klasy z JDK do dokumentu generowanego przez skaladoc. Użyłem opcji -doc-external-doc programu scaladoc 2.10.1, ale bez powodzenia.Jak połączyć klasy z JDK w dokument generowany przez skaladoc?

Używam -doc-external-doc:/usr/lib/jvm/java-7-openjdk-amd64/jre/lib/rt.jar#http://docs.oracle.com/javase/7/docs/api/, ale otrzymuję linki, takie jak index.html#java.io.File zamiast index.html?java/io/File.html. Wygląda na to, że ta opcja działa tylko w przypadku dokumentów generowanych przez scaladoc.

Czy brakowało mi opcji w skaladoc lub czy powinienem wypełnić żądanie funkcji?

I skonfigurowaniu SBT następująco:

scalacOptions in (Compile,doc) += "-doc-external-doc:/usr/lib/jvm/java-7-openjdk-amd64/jre/lib/rt.jar#http://docs.oracle.com/javase/7/docs/api" 

Uwaga: Widziałem Opts.doc.externalAPI util w nadchodzącym SBT 0,13. Myślę, że miłym dodatkiem (nie jestem pewien, czy to możliwe) byłoby przekazanie ModuleID zamiast File. Użycie będzie dowiedzieć się, który plik odpowiada ModuleID.

+1

Powinieneś zgłosić się do skaladoc. – jsuereth

+0

Czy istnieje linia poleceń dla tego zewnętrznego sbt? Po odpowiedzi @ jsuereth, sbt po prostu przekazuje opcje do skaladoc i jeśli nie obsługuje tej funkcji, sbt też nie. –

Odpowiedz

7

Używam sbt 0.13.5.

Nie ma gotowego sposobu na posiadanie funkcji łączenia Javadoc wewnątrz skaladoc. I jak rozumiem, nie jest to wina sbt, ale sposób działania skaladoku. Jak Josh wskazał w swoim komentarzu You should report to scaladoc.

Jest jednak obejście wymyśliłem - przetworzenia w doc -generated scaladoc więc adresy URL Java zastępowane tworząc odpowiednie linki Javadoc.

Plik scaladoc.sbt powinien być umieszczony wewnątrz projektu SBT i ilekroć doc Zadanie zostanie zrealizowane, postprocessing poprzez fixJavaLinksTask kopnięć zadaniowych w.

UWAGA Istnieje wiele zakodowanych ścieżek więc używać go z uwaga (aka do polerowania, ale uważasz za stosowne).

import scala.util.matching.Regex.Match 

autoAPIMappings := true 

// builds -doc-external-doc 
apiMappings += (
    file("/Library/Java/JavaVirtualMachines/jdk1.8.0_11.jdk/Contents/Home/jre/lib/rt.jar") -> 
    url("http://docs.oracle.com/javase/8/docs/api") 
) 

lazy val fixJavaLinksTask = taskKey[Unit](
    "Fix Java links - replace #java.io.File with ?java/io/File.html" 
) 

fixJavaLinksTask := { 
    println("Fixing Java links") 
    val t = (target in (Compile, doc)).value 
    (t ** "*.html").get.filter(hasJavadocApiLink).foreach { f => 
    println("fixing " + f) 
    val newContent = javadocApiLink.replaceAllIn(IO.read(f), fixJavaLinks) 
    IO.write(f, newContent) 
    } 
} 

val fixJavaLinks: Match => String = m => 
    m.group(1) + "?" + m.group(2).replace(".", "/") + ".html" 

val javadocApiLink = """\"(http://docs\.oracle\.com/javase/8/docs/api/index\.html)#([^"]*)\"""".r 

def hasJavadocApiLink(f: File): Boolean = (javadocApiLink findFirstIn IO.read(f)).nonEmpty 

fixJavaLinksTask <<= fixJavaLinksTask triggeredBy (doc in Compile) 
6

Wziąłem odpowiedź przez @ jacek-Laskowskiego i modyfikować je tak, aby uniknąć twardego zakodowane ciągi i mogą być stosowane dla dowolnej liczby bibliotek Java, a nie tylko jednego standardowego.

Edit: lokalizacja rt.jar jest teraz wyznaczona z wykorzystaniem sun.boot.class.path starcie i nie musi być trudne kodowane.

Jedyną rzeczą, którą należy zmodyfikować to mapa, którą nazwali externalJavadocMap w następujących przypadkach:

import scala.util.matching.Regex 
import scala.util.matching.Regex.Match 

val externalJavadocMap = Map(
    "owlapi" -> "http://owlcs.github.io/owlapi/apidocs_4_0_2/index.html" 
) 

/* 
* The rt.jar file is located in the path stored in the sun.boot.class.path system property. 
* See the Oracle documentation at http://docs.oracle.com/javase/6/docs/technotes/tools/findingclasses.html. 
*/ 
val rtJar: String = System.getProperty("sun.boot.class.path").split(java.io.File.pathSeparator).collectFirst { 
    case str: String if str.endsWith(java.io.File.separator + "rt.jar") => str 
}.get // fail hard if not found 

val javaApiUrl: String = "http://docs.oracle.com/javase/8/docs/api/index.html" 

val allExternalJavadocLinks: Seq[String] = javaApiUrl +: externalJavadocMap.values.toSeq 

def javadocLinkRegex(javadocURL: String): Regex = ("""\"(\Q""" + javadocURL + """\E)#([^"]*)\"""").r 

def hasJavadocLink(f: File): Boolean = allExternalJavadocLinks exists { 
    javadocURL: String => 
    (javadocLinkRegex(javadocURL) findFirstIn IO.read(f)).nonEmpty 
} 

val fixJavaLinks: Match => String = m => 
    m.group(1) + "?" + m.group(2).replace(".", "/") + ".html" 

/* 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(
    apiMappings ++= { 
    // Lookup the path to jar from the classpath 
    val classpath = (fullClasspath in Compile).value 
    def findJar(nameBeginsWith: String): File = { 
     classpath.find { attributed: Attributed[File] => (attributed.data ** s"$nameBeginsWith*.jar").get.nonEmpty }.get.data // fail hard if not found 
    } 
    // Define external documentation paths 
    (externalJavadocMap map { 
     case (name, javadocURL) => findJar(name) -> url(javadocURL) 
    }) + (file(rtJar) -> url(javaApiUrl)) 
    }, 
    // Override the task to fix the links to JavaDoc 
    doc in Compile <<= (doc in Compile) map { 
    target: File => 
     (target ** "*.html").get.filter(hasJavadocLink).foreach { f => 
     //println(s"Fixing $f.") 
     val newContent: String = allExternalJavadocLinks.foldLeft(IO.read(f)) { 
      case (oldContent: String, javadocURL: String) => 
      javadocLinkRegex(javadocURL).replaceAllIn(oldContent, fixJavaLinks) 
     } 
     IO.write(f, newContent) 
     } 
     target 
    } 
) 

Używam SBT 0.13.8.

+0

Próbowałem dodać twój kod do mojego pliku kompilacji SBT, ale ScalaDoc nadal nie może znaleźć klas JDK. Prawdopodobnie zrobiłem coś głupiego - to powinno być dodane do build.sbt, prawda? –

+1

Tak, należy go dodać do 'build.sbt'. Jaka jest wartość 'System.getProperty (" sun.boot.class.path ")'?Możesz sprawdzić, wpisując 'console' z REPL-u SBT, aby wprowadzić REAL Scala. Działasz w systemie Windows, Linux lub Mac? Czy otrzymujesz ostrzeżenia podczas uruchamiania zadania 'doc'? –

+1

@Hawk Być może, co najważniejsze, dodałeś opcję "documentationSettings" do ustawień swojego projektu? Na przykład coś takiego jak 'lazy val myProject = (projekt w pliku (" myProject ")). Settings (documentationSettings: _ *)' in 'build.sbt'. –

Powiązane problemy