diff --git a/.github/workflows/scala3doc.yaml b/.github/workflows/scala3doc.yaml index ad9d29a3c298..440cd6c8753f 100644 --- a/.github/workflows/scala3doc.yaml +++ b/.github/workflows/scala3doc.yaml @@ -62,3 +62,36 @@ jobs: echo uplading docs to https://scala3doc.virtuslab.com/$DOC_DEST az storage container create --name $DOC_DEST --account-name scala3docstorage --public-access container az storage blob sync -s scala3doc/output -c $DOC_DEST --account-name scala3docstorage + + community-docs: + env: + AZURE_STORAGE_SAS_TOKEN: ${{ secrets.AZURE_STORAGE_SAS_TOKEN }} + runs-on: ubuntu-latest + if: "github.event_name == 'pull_request' || contains(github.event.ref, 'scala3doc') || contains(github.event.ref, 'master')" + + steps: + - name: Git Checkout + uses: actions/checkout@v2 + + - name: Set up JDK 8 + uses: actions/setup-java@v1 + with: + java-version: 8 + + - name: Init submodules + run: git submodule update --init --recursive --jobs 7 + + - name: Generate docs + run: ./project/scripts/sbt "community-build/run doc all docsOutput" + + - name: Upload documentation to server + uses: azure/CLI@v1 + if: env.AZURE_STORAGE_SAS_TOKEN + env: + PR_NUMBER: ${{ github.event.pull_request.number }} + with: + inlineScript: | + DOC_DEST=pr-${PR_NUMBER:-${GITHUB_REF##*/}}-docs + echo uplading docs to https://scala3doc.virtuslab.com/$DOC_DEST + az storage container create --name $DOC_DEST --account-name scala3docstorage --public-access container + az storage blob sync -s community-build/docsOutput -c $DOC_DEST --account-name scala3docstorage diff --git a/community-build/src/scala/dotty/communitybuild/Fields.scala b/community-build/src/scala/dotty/communitybuild/Fields.scala new file mode 100644 index 000000000000..bbf729418a6b --- /dev/null +++ b/community-build/src/scala/dotty/communitybuild/Fields.scala @@ -0,0 +1,9 @@ +package dotty.communitybuild + +import scala.quoted.Type + +class FieldsDsl[V](v: V): + inline def of[T]: Seq[T] = FieldsImpl.fieldsOfType[V, T](v) + +extension [V](on: V): + def fields = FieldsDsl(on) \ No newline at end of file diff --git a/community-build/src/scala/dotty/communitybuild/FieldsImpl.scala b/community-build/src/scala/dotty/communitybuild/FieldsImpl.scala new file mode 100644 index 000000000000..2d7124727af2 --- /dev/null +++ b/community-build/src/scala/dotty/communitybuild/FieldsImpl.scala @@ -0,0 +1,17 @@ +package dotty.communitybuild + +import scala.quoted._ + +object FieldsImpl: + inline def fieldsOfType[V, T](inline v: V): Seq[T] = + ${ fieldsImpl[V, T]('v) } + + def fieldsImpl[V: Type, T: Type](from: Expr[V])(using Quotes): Expr[Seq[T]] = + import quotes.reflect._ + val retType = TypeTree.of[T].tpe + def isProjectField(s: Symbol) = + s.isValDef && s.tree.asInstanceOf[ValDef].tpt.tpe <:< retType + val projectsTree = Term.of(from) + val symbols = TypeTree.of[V].symbol.members.filter(isProjectField) + val selects = symbols.map(Select(projectsTree, _).asExprOf[T]) + '{ println(${Expr(retType.show)}); ${Varargs(selects)} } diff --git a/community-build/src/scala/dotty/communitybuild/Main.scala b/community-build/src/scala/dotty/communitybuild/Main.scala index 62f1b8a29159..13c9ae573772 100644 --- a/community-build/src/scala/dotty/communitybuild/Main.scala +++ b/community-build/src/scala/dotty/communitybuild/Main.scala @@ -1,13 +1,91 @@ package dotty.communitybuild -object Main { - /** Builds stdlib. - * - * Output is available in build/pack/lib directory in stdlib project. - * - * In the future, we allow building different projects based on arguments, - * but for now stdlib is the only usecase. - */ +import java.nio.file.Paths +import java.nio.file.Path +import java.nio.file.Files +import scala.sys.process._ + + +object Main: + + private def generateDocs(project: CommunityProject): Seq[Path] = + val name = project.project + try + project.doc() + val pathsOut = s"find community-projects/$name/ -name 'scala3doc.version'".!! + pathsOut.linesIterator.map(Paths.get(_).getParent).toList + catch + case e: Exception => + e.printStackTrace() + Nil + + /** Allows running various commands on community build projects. */ def main(args: Array[String]): Unit = - projects.stdLib213.publish() -} + args.toList match + case "publish" :: name :: Nil => + case "doc" :: "all" :: destStr :: Nil => + val dest = Paths.get(destStr) + Seq("rm", "-rf", "destStr").! + Files.createDirectory(dest) + val (toRun, ignored) = + allProjects.partition(_.docCommand != null) + + val paths = toRun.map { project => + val name = project.project + val projectDest = dest.resolve(name) + val projectRoot = Paths.get(s"community-projects/$name") + println(s"generating docs for $name into $projectDest") + val generatedDocs = generateDocs(project) + if !Files.exists(projectDest) && generatedDocs.nonEmpty then + Files.createDirectory(projectDest) + + val docsFiles = generatedDocs.map { docsPath => + val destFileName = + docsPath.subpath(2, docsPath.getNameCount).toString.replace('/', '_') + + Seq("cp", "-r", docsPath.toString, projectDest.resolve(destFileName).toString).! + destFileName + } + name -> docsFiles + } + + val (failed, withDocs) = paths.partition{ case (_, paths) => paths.isEmpty } + + val indexFile = withDocs.map { case (name, paths) => + paths.map(p => s"""$p
\n""") + .mkString(s"

$name

","\n", "\n") + }.mkString("\n", "\n", "\n") + + Files.write(dest.resolve("index.html"), indexFile.getBytes) + + if ignored.nonEmpty then + println(s"Ignored project without doc command: ${ignored.map(_.project)}") + + if failed.nonEmpty then + println(s"Documentation not found for ${failed.map(_._1).mkString(", ")}") + sys.exit(1) + + case "doc" :: names if names.nonEmpty => + val missing = names.filterNot(projectMap.contains) + if missing.nonEmpty then + println(s"Missing projects: ${missing.mkString(", ")}. All projects: ${allProjects.mkString(", ")}") + sys.exit(1) + + val failed = names.filter{ p => + val docsRoots = generateDocs(projectMap(p)) + if docsRoots.nonEmpty then println(s"Docs for $p generated in $docsRoots") + docsRoots.isEmpty + } + if failed.nonEmpty then + println(s"Documentation not found for ${failed.mkString(", ")}") + sys.exit(1) + + case args => + println("USAGE: ") + println("COMMAND is one of: publish doc") + println("Available projects are:") + allProjects.foreach { k => + println(s"\t$k") + } + sys.exit(1) + diff --git a/community-build/src/scala/dotty/communitybuild/projects.scala b/community-build/src/scala/dotty/communitybuild/projects.scala index 788735b7738f..1c252d5165eb 100644 --- a/community-build/src/scala/dotty/communitybuild/projects.scala +++ b/community-build/src/scala/dotty/communitybuild/projects.scala @@ -45,16 +45,20 @@ sealed trait CommunityProject: val project: String val testCommand: String val publishCommand: String + val docCommand: String val dependencies: List[CommunityProject] val binaryName: String val runCommandsArgs: List[String] = Nil final val projectDir = communitybuildDir.resolve("community-projects").resolve(project) + final def publishDependencies(): Unit = + dependencies.foreach(_.publish()) + /** Publish this project to the local Maven repository */ final def publish(): Unit = if !published then - dependencies.foreach(_.publish()) + publishDependencies() log(s"Publishing $project") if publishCommand eq null then throw RuntimeException(s"Publish command is not specified for $project. Project details:\n$this") @@ -62,6 +66,16 @@ sealed trait CommunityProject: if exitCode != 0 then throw RuntimeException(s"Publish command exited with code $exitCode for project $project. Project details:\n$this") published = true + + final def doc(): Unit = + publishDependencies() + log(s"Documenting $project") + if docCommand eq null then + throw RuntimeException(s"Doc command is not specified for $project. Project details:\n$this") + val exitCode = exec(projectDir, binaryName, (runCommandsArgs :+ docCommand): _*) + if exitCode != 0 then + throw RuntimeException(s"Doc command exited with code $exitCode for project $project. Project details:\n$this") + end CommunityProject final case class MillCommunityProject( @@ -71,6 +85,7 @@ final case class MillCommunityProject( override val binaryName: String = "./mill" override val testCommand = s"$baseCommand.test" override val publishCommand = s"$baseCommand.publishLocal" + override val docCommand = null override val runCommandsArgs = List("-i", "-D", s"dottyVersion=$compilerVersion") final case class SbtCommunityProject( @@ -78,7 +93,9 @@ final case class SbtCommunityProject( sbtTestCommand: String, extraSbtArgs: List[String] = Nil, dependencies: List[CommunityProject] = Nil, - sbtPublishCommand: String = null) extends CommunityProject: + sbtPublishCommand: String = null, + sbtDocCommand: String = null + ) extends CommunityProject: override val binaryName: String = "sbt" // A project in the community build can depend on an arbitrary version of @@ -105,7 +122,11 @@ final case class SbtCommunityProject( ++ s"++$compilerVersion!; " override val testCommand = s"$baseCommand$sbtTestCommand" - override val publishCommand = s"$baseCommand$sbtPublishCommand" + override val publishCommand = if sbtPublishCommand eq null then null else s"$baseCommand$sbtPublishCommand" + override val docCommand = + if sbtDocCommand eq null then null else + val cmd = if sbtDocCommand.startsWith(";") then sbtDocCommand else s";$sbtDocCommand" + s"$baseCommand set every useScala3doc := true; set every doc/logLevel := Level.Warn $cmd " override val runCommandsArgs: List[String] = // Run the sbt command with the compiler version and sbt plugin set in the build @@ -119,6 +140,17 @@ final case class SbtCommunityProject( ) object projects: + + private def forceDoc(projects: String*) = + projects.map(project => + s""";set $project/Compile/doc/sources ++= ($project/Compile/doc/tastyFiles).value ;$project/doc""" + ).mkString(" ") + + private def aggregateDoc(in: String)(projects: String*) = + val tastyFiles = + (in +: projects).map(p => s"($p/Compile/doc/tastyFiles).value").mkString(" ++ ") + s""";set $in/Compile/doc/sources ++= file("a.scala") +: ($tastyFiles) ;$in/doc""" + lazy val utest = MillCommunityProject( project = "utest", baseCommand = s"utest.jvm[$compilerVersion]", @@ -191,61 +223,81 @@ object projects: lazy val intent = SbtCommunityProject( project = "intent", sbtTestCommand = "test", + sbtDocCommand = "doc" ) lazy val algebra = SbtCommunityProject( project = "algebra", sbtTestCommand = "coreJVM/compile", + sbtDocCommand = forceDoc("coreJVM") ) lazy val scalacheck = SbtCommunityProject( project = "scalacheck", sbtTestCommand = "jvm/test;js/test", - sbtPublishCommand = "jvm/publishLocal;js/publishLocal" + sbtPublishCommand = "jvm/publishLocal;js/publishLocal", + sbtDocCommand = forceDoc("jvm") ) lazy val scalatest = SbtCommunityProject( project = "scalatest", sbtTestCommand = "scalacticDotty/clean;scalacticTestDotty/test; scalatestTestDotty/test", - sbtPublishCommand = "scalacticDotty/publishLocal; scalatestDotty/publishLocal" + sbtPublishCommand = "scalacticDotty/publishLocal; scalatestDotty/publishLocal", + sbtDocCommand = ";scalacticDotty/doc" // fails with missing type ;scalatestDotty/doc" + // cannot take signature of (test: org.scalatest.concurrent.ConductorFixture#OneArgTest): + // org.scalatest.Outcome + // Problem parsing scalatest.dotty/target/scala-3.0.0-M2/src_managed/main/org/scalatest/concurrent/ConductorFixture.scala:[602..624..3843], documentation may not be generated. + // dotty.tools.dotc.core.MissingType: ) lazy val scalatestplusScalacheck = SbtCommunityProject( project = "scalatestplus-scalacheck", sbtTestCommand = "scalatestPlusScalaCheckJVM/test", sbtPublishCommand = "scalatestPlusScalaCheckJVM/publishLocal", + sbtDocCommand = "scalatestPlusScalaCheckJVM/doc", dependencies = List(scalatest, scalacheck) ) lazy val scalaXml = SbtCommunityProject( project = "scala-xml", sbtTestCommand = "xml/test", + sbtDocCommand = "xml/doc" ) lazy val scalap = SbtCommunityProject( project = "scalap", sbtTestCommand = "scalap/compile", + sbtDocCommand = "scalap/doc" ) lazy val betterfiles = SbtCommunityProject( project = "betterfiles", sbtTestCommand = "dotty-community-build/compile", + sbtDocCommand = ";core/doc ;akka/doc ;shapelessScanner/doc" ) lazy val ScalaPB = SbtCommunityProject( project = "ScalaPB", sbtTestCommand = "dotty-community-build/compile", + // aggregateDoc("runtimeJVM")("scalapbc", "grpcRuntime", "compilerPlugin") fails with + // module class ScalaPbCodeGenerator$ has non-class parent: TypeRef(TermRef(ThisType(TypeRef(NoPrefix,module class )),module protocbridge),ProtocCodeGenerator) + // Also it seems that we do not handle correctly aggreagation projects + // sbtDocCommand = "dotty-community-build/doc" + sbtDocCommand = forceDoc("scalapbc", "grpcRuntime","runtimeJVM", "compilerPlugin") ) lazy val minitest = SbtCommunityProject( project = "minitest", sbtTestCommand = "test", + sbtDocCommand = aggregateDoc("lawsJVM")("minitestJVM"), dependencies = List(scalacheck) ) lazy val fastparse = SbtCommunityProject( project = "fastparse", sbtTestCommand = "dotty-community-build/compile;dotty-community-build/test:compile", + // Problem parsing perftests/bench2/src/perftests/PythonParse.scala:[0..18..694] + // sbtDocCommand = "dotty-community-build/doc" ) lazy val stdLib213 = SbtCommunityProject( @@ -253,16 +305,20 @@ object projects: extraSbtArgs = List("-Dscala.build.compileWithDotty=true"), sbtTestCommand = """library/compile""", sbtPublishCommand = """set publishArtifact in (library, Compile, packageDoc) := false ;library/publishLocal""", + // sbtDocCommand = "library/doc" // Does no compile? No idea :/ ) + lazy val shapeless = SbtCommunityProject( project = "shapeless", sbtTestCommand = "test", + sbtDocCommand = forceDoc("typeable", "deriving", "data") ) lazy val xmlInterpolator = SbtCommunityProject( project = "xml-interpolator", sbtTestCommand = "test", + sbtDocCommand = "doc", // Again we've got problem with extensions ) lazy val effpi = SbtCommunityProject( @@ -278,6 +334,7 @@ object projects: // sbtTestCommand = "set ThisBuild / useEffpiPlugin := false; effpi/test:compile; plugin/test:compile; benchmarks/test:compile; examples/test:compile; pluginBenchmarks/test:compile", sbtTestCommand = "set ThisBuild / useEffpiPlugin := false; effpi/test:compile; benchmarks/test:compile; examples/test:compile; pluginBenchmarks/test:compile", + sbtDocCommand = "set ThisBuild / useEffpiPlugin := false; effpi/doc; benchmarks/doc; examples/doc; pluginBenchmarks/doc", ) // TODO @odersky? It got broken by #5458 @@ -289,11 +346,16 @@ object projects: lazy val sconfig = SbtCommunityProject( project = "sconfig", sbtTestCommand = "sconfigJVM/test", + // sbtDocCommand = "sconfigJVM/doc", // Fails with: + // Problem parsing sconfig/sharedScala3/src/main/scala/org/ekrich/config/ConfigSyntax.scala:[73..92..1340], documentation may not be generated. + // scala.MatchError: ValDef(JSON,TypeTree[TypeRef(TermRef(ThisType(TypeRef(NoPrefix,module class ekrich)),module config),class ConfigSyntax)],Apply(Ident($new),List(Literal(Constant(0)), Literal(Constant(JSON))))) (of class dotty.tools.dotc.ast.Trees$ValDef) ) lazy val zio = SbtCommunityProject( project = "zio", sbtTestCommand = "testJVMDotty", + // sbtDocCommand = forceDoc("coreJVM"), + // Fails on tasty unpickling https://github.com/lampepfl/dotty/issues/10499 ) lazy val munit = SbtCommunityProject( @@ -301,6 +363,7 @@ object projects: sbtTestCommand = "testsJVM/test;testsJS/test;", // Hardcode the version to avoid having to deal with something set by sbt-dynver sbtPublishCommand = s"""set every version := "${Versions.munit}"; munitJVM/publishLocal; munitJS/publishLocal; munitScalacheckJVM/publishLocal; munitScalacheckJS/publishLocal; junit/publishLocal""", + sbtDocCommand = "munitJVM/doc", dependencies = List(scalacheck) ) @@ -309,50 +372,76 @@ object projects: sbtTestCommand = "coreJVM/test;coreJS/test", // Hardcode the version to avoid having to deal with something set by sbt-git sbtPublishCommand = s"""set every version := "${Versions.scodecBits}"; coreJVM/publishLocal;coreJS/publishLocal""", + sbtDocCommand = "coreJVM/doc", dependencies = List(munit) ) lazy val scodec = SbtCommunityProject( project = "scodec", sbtTestCommand = "unitTests/test", + // Adds package + sbtDocCommand = "coreJVM/doc", dependencies = List(munit, scodecBits) ) lazy val scalaParserCombinators = SbtCommunityProject( project = "scala-parser-combinators", sbtTestCommand = "parserCombinatorsJVM/test", + sbtDocCommand = forceDoc("parserCombinatorsJVM"), ) lazy val dottyCpsAsync = SbtCommunityProject( project = "dotty-cps-async", sbtTestCommand = "test", + // Does not compile (before reaches doc) + // sbtDocCommand = "cpsJVM/doc", ) lazy val scalaz = SbtCommunityProject( project = "scalaz", sbtTestCommand = "rootJVM/test", + + // sbtDocCommand = forceDoc("coreJVM"), // Fails with: + // [error] class scalaz.Conts cannot be unpickled because no class file was found + // [error] class scalaz.ContsT cannot be unpickled because no class file was found + // [error] class scalaz.IndexedCont cannot be unpickled because no class file was found + + // aggregateDoc("rootJVM")("effectJVM", "iterateeJVM"), // Fails With + // [error] Caused by: java.lang.AssertionError: assertion failed: + // trait MonadIO has non-class parent: AppliedType(TypeRef(TermRef(ThisType(TypeRef(NoPrefix,module class )),module scalaz),Monad),List(TypeRef(ThisType(TypeRef(TermRef(ThisType(TypeRef(NoPrefix,module class scalaz)),module effect),trait MonadIO)),type F))) + + // sbtDocCommand = forceDoc("iterateeJVM"), // Fails with + // [error] class scalaz.iteratee.Iteratee cannot be unpickled because no class file was found + + sbtDocCommand = forceDoc("effectJVM"), dependencies = List(scalacheck) ) lazy val endpoints4s = SbtCommunityProject( project = "endpoints4s", - sbtTestCommand = "json-schemaJVM/compile;algebraJVM/compile;openapiJVM/compile;http4s-server/compile;http4s-client/compile;play-server/compile;play-client/compile;akka-http-server/compile;akka-http-client/compile" + sbtTestCommand = "json-schemaJVM/compile;algebraJVM/compile;openapiJVM/compile;http4s-server/compile;http4s-client/compile;play-server/compile;play-client/compile;akka-http-server/compile;akka-http-client/compile", + sbtDocCommand = ";json-schemaJVM/doc ;algebraJVM/doc; openapiJVM/doc; http4s-server/doc ;http4s-client/doc ;play-server/doc ;play-client/doc ;akka-http-server/doc ;akka-http-client/doc", ) lazy val catsEffect2 = SbtCommunityProject( project = "cats-effect-2", - sbtTestCommand = "test" + sbtTestCommand = "test", + // Currently is excluded from community build + // sbtDocCommand = ";coreJVM/doc ;lawsJVM/doc", ) lazy val catsEffect3 = SbtCommunityProject( project = "cats-effect-3", - sbtTestCommand = "testIfRelevant" + sbtTestCommand = "testIfRelevant", + // The problem is that testIfRelevant does not compile and project does not compile + // sbtDocCommand = ";coreJVM/doc ;lawsJVM/doc ;kernelJVM/doc", ) lazy val scalaParallelCollections = SbtCommunityProject( project = "scala-parallel-collections", sbtTestCommand = "test", - dependencies = List(scalacheck) + sbtDocCommand = forceDoc("core"), + dependencies = List(scalacheck) ) lazy val scalaCollectionCompat = SbtCommunityProject( @@ -363,6 +452,11 @@ object projects: lazy val verify = SbtCommunityProject( project = "verify", sbtTestCommand = "verifyJVM/test", + sbtDocCommand = "verifyJVM/doc", ) end projects + +def allProjects = projects.fields.of[CommunityProject].sortBy(_.project) + +lazy val projectMap = allProjects.map(p => p.project -> p).toMap diff --git a/project/Build.scala b/project/Build.scala index f5de6714f93e..9666386b2100 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -1335,6 +1335,8 @@ object Build { (publishLocal in `tasty-core-bootstrapped`).value (publishLocal in `scala3-library-bootstrapped`).value (publishLocal in `scala3-doc-bootstrapped`).value + (publishLocal in `scala3-tasty-inspector`).value + (publishLocal in `scala3doc`).value (publishLocal in `scala3-compiler-bootstrapped`).value (publishLocal in `sbt-dotty`).value (publishLocal in `scala3-bootstrapped`).value @@ -1351,6 +1353,7 @@ object Build { TestFrameworks.JUnit, "--include-categories=dotty.communitybuild.TestCategory", ), + Compile/run := (Compile/run).dependsOn(prepareCommunityBuild).evaluated, (Test / testOnly) := ((Test / testOnly) dependsOn prepareCommunityBuild).evaluated, (Test / test ) := ((Test / test ) dependsOn prepareCommunityBuild).value, javaOptions ++= { @@ -1592,9 +1595,12 @@ object Build { Build.testcasesSourceRoot.in(Test), Build.testDocumentationRoot, ), + Compile / buildInfoKeys := Seq[BuildInfoKey](version), + Compile / buildInfoPackage := "dotty.dokka", testDocumentationRoot := (baseDirectory.value / "test-documentations").getAbsolutePath, - buildInfoPackage in Test := "dotty.dokka", + buildInfoPackage in Test := "dotty.dokka.test", BuildInfoPlugin.buildInfoScopedSettings(Test), + BuildInfoPlugin.buildInfoScopedSettings(Compile), BuildInfoPlugin.buildInfoDefaultSettings, // Uncomment to debug dokka processing (require to run debug in listen mode on 5005 port) // javaOptions.in(run) += "-agentlib:jdwp=transport=dt_socket,server=n,address=localhost:5005,suspend=y" diff --git a/sbt-dotty/src/dotty/tools/sbtplugin/DottyPlugin.scala b/sbt-dotty/src/dotty/tools/sbtplugin/DottyPlugin.scala index 16e8e71f8aaa..ea87b5473028 100644 --- a/sbt-dotty/src/dotty/tools/sbtplugin/DottyPlugin.scala +++ b/sbt-dotty/src/dotty/tools/sbtplugin/DottyPlugin.scala @@ -434,10 +434,12 @@ object DottyPlugin extends AutoPlugin { private val docSettings = inTask(doc)(Seq( tastyFiles := { val _ = compile.value // Ensure that everything is compiled, so TASTy is available. - (classDirectory.value ** "*.tasty").get.map(_.getAbsoluteFile) + // sbt is too smart and do not start doc task if there are no *.scala files defined + file("___fake___.scala") +: + (classDirectory.value ** "*.tasty").get.map(_.getAbsoluteFile) }, sources := Def.taskDyn[Seq[File]] { - if (isDotty.value) Def.task { tastyFiles.value } + if (isDotty.value && useScala3doc.value) Def.task { tastyFiles.value } else Def.task { sources.value } }.value, scalacOptions ++= { diff --git a/scala3doc/src/dotty/dokka/Scala3docArgs.scala b/scala3doc/src/dotty/dokka/Scala3docArgs.scala index 0951e845ac4f..6c53329a9f92 100644 --- a/scala3doc/src/dotty/dokka/Scala3docArgs.scala +++ b/scala3doc/src/dotty/dokka/Scala3docArgs.scala @@ -69,8 +69,8 @@ object Scala3docArgs: def parseTastyRoots(roots: String) = roots.split(File.pathSeparatorChar).toList.map(new File(_)) - val (existing, nonExisting) = - summary.arguments.map(File(_)).partition(_.exists) + val inFiles = summary.arguments.map(File(_)).filter(_.getName != "___fake___.scala") + val (existing, nonExisting) = inFiles.partition(_.exists) if nonExisting.nonEmpty then report.warning( s"Scala3doc will ignore following nonexisiten paths: ${nonExisting.mkString(", ")}" diff --git a/scala3doc/src/dotty/dokka/preprocessors/ScalaResourceInstaller.scala b/scala3doc/src/dotty/dokka/preprocessors/ScalaResourceInstaller.scala index 604f27c5f0dc..ed9db8933c10 100644 --- a/scala3doc/src/dotty/dokka/preprocessors/ScalaResourceInstaller.scala +++ b/scala3doc/src/dotty/dokka/preprocessors/ScalaResourceInstaller.scala @@ -12,16 +12,24 @@ class ScalaResourceInstaller(using ctx: DocContext) extends PageTransformer: new RendererSpecificResourcePage(resourceName, java.util.ArrayList(), RenderingStrategy$Copy(s"/dotty_res/$resourceName")) override def invoke(input: RootPageNode): RootPageNode = - val defaultResources = input.getChildren.asScala ++ Seq("fonts", "images", "styles", "scripts", "hljs", "favicon.ico").map(dottyRes) - val newResources = projectLogo ++ defaultResources ++ Seq(dynamicJsData) + val dirs = Seq("fonts", "images", "styles", "scripts", "hljs", "favicon.ico") + val defaultResources = input.getChildren.asScala ++ dirs.map(dottyRes) + val newResources = + projectLogo ++ defaultResources ++ Seq(dynamicJsData, scala3docVersionFile) input.modified(input.getName, newResources.asJava) + private def textFile(path: String, content: String) = + val strategy = RenderingStrategy$Write(content) + new RendererSpecificResourcePage(path, java.util.ArrayList(), strategy) + private def dynamicJsData = - // If data at any point will become more complex we should use a proper - val data: Map[String, Map[String, String]] = Map("filterDefaults" -> FilterAttributes.defaultValues) + // If data at any point will become more complex we should use a proper mapping + val data: Map[String, Map[String, String]] = + Map("filterDefaults" -> FilterAttributes.defaultValues) val str = new ObjectMapper().writeValueAsString(data.transform((_, v) => v.asJava).asJava) + textFile("scripts/data.js", s"var scala3DocData = $str") - new RendererSpecificResourcePage("scripts/data.js", java.util.ArrayList(), RenderingStrategy$Write(s"var scala3DocData = $str")) + private def scala3docVersionFile = textFile("scala3doc.version", BuildInfo.version) private def projectLogo = ctx.args.projectLogo.toSeq.map { path => val fileName = Paths.get(path).getFileName() diff --git a/scala3doc/test/dotty/dokka/SignatureTest.scala b/scala3doc/test/dotty/dokka/SignatureTest.scala index 9b2df12091ae..ec6f49c85dd4 100644 --- a/scala3doc/test/dotty/dokka/SignatureTest.scala +++ b/scala3doc/test/dotty/dokka/SignatureTest.scala @@ -3,6 +3,7 @@ package dotty.dokka import scala.io.Source import scala.jdk.CollectionConverters._ import scala.util.matching.Regex +import dotty.dokka.test.BuildInfo import org.jetbrains.dokka.pages.{RootPageNode, PageNode, ContentPage, ContentText, ContentNode, ContentComposite} diff --git a/scala3doc/test/dotty/dokka/site/SiteGeneratationTest.scala b/scala3doc/test/dotty/dokka/site/SiteGeneratationTest.scala index 8b6a5ca99a92..9180fd2f7bdf 100644 --- a/scala3doc/test/dotty/dokka/site/SiteGeneratationTest.scala +++ b/scala3doc/test/dotty/dokka/site/SiteGeneratationTest.scala @@ -9,6 +9,7 @@ import org.junit.Assert._ import org.jsoup.Jsoup import org.jsoup.nodes.Document import java.nio.charset.Charset +import dotty.dokka.test.BuildInfo class SiteGeneratationTest: val projectName = "Test Project Name" diff --git a/scala3doc/test/dotty/dokka/tasty/util/TestUtils.scala b/scala3doc/test/dotty/dokka/tasty/util/TestUtils.scala index 055cfe6f5003..3a1cec87d723 100644 --- a/scala3doc/test/dotty/dokka/tasty/util/TestUtils.scala +++ b/scala3doc/test/dotty/dokka/tasty/util/TestUtils.scala @@ -1,6 +1,6 @@ package dotty.dokka.tasty.util -import dotty.dokka.BuildInfo +import dotty.dokka.test.BuildInfo object TestUtils { def listOurClasses(): List[String] = { diff --git a/scala3doc/test/dotty/dokka/testUtils.scala b/scala3doc/test/dotty/dokka/testUtils.scala index a5972edcad2d..54dcb1d6de4b 100644 --- a/scala3doc/test/dotty/dokka/testUtils.scala +++ b/scala3doc/test/dotty/dokka/testUtils.scala @@ -4,9 +4,11 @@ import dotty.tools.dotc.core.Contexts._ import dotty.tools.dotc.reporting.Diagnostic import dotty.tools.dotc.reporting.ConsoleReporter import dotty.tools.dotc.interfaces.Diagnostic.{ERROR, INFO, WARNING} +import dotty.dokka.test.BuildInfo import org.junit.Assert._ import java.io.File + case class ReportedDiagnostics(errors: List[Diagnostic], warnings: List[Diagnostic], infos: List[Diagnostic]): def errorMsgs = errors.map(_.msg.rawMessage) def warningMsgs = warnings.map(_.msg.rawMessage)