From 3347eb4fd3c9e0c13131ff83166a0359fcd91ed1 Mon Sep 17 00:00:00 2001 From: Lucas Date: Wed, 29 Mar 2023 15:04:33 +0200 Subject: [PATCH 1/3] Feat: Add a blog configuration with yaml - Add input config, who allow to define the path import - Add output config, who allow to define the path destination - Add hidden, who allow to not generate the blog --- .../scaladoc/site/StaticSiteContext.scala | 4 +++ .../scaladoc/site/StaticSiteLoader.scala | 32 +++++++++++++++++-- 2 files changed, 33 insertions(+), 3 deletions(-) diff --git a/scaladoc/src/dotty/tools/scaladoc/site/StaticSiteContext.scala b/scaladoc/src/dotty/tools/scaladoc/site/StaticSiteContext.scala index de3f511c8e67..7a90a462cba0 100644 --- a/scaladoc/src/dotty/tools/scaladoc/site/StaticSiteContext.scala +++ b/scaladoc/src/dotty/tools/scaladoc/site/StaticSiteContext.scala @@ -23,6 +23,10 @@ class StaticSiteContext( val docsPath = root.toPath.resolve("_docs") val blogPath = root.toPath.resolve("_blog") + def resolveNewBlogPath(stringPath: String): Path = + if stringPath.nonEmpty then root.toPath.resolve(stringPath) + else blogPath + def relativize(path: Path): Path = if args.apiSubdirectory then docsPath.relativize(path) diff --git a/scaladoc/src/dotty/tools/scaladoc/site/StaticSiteLoader.scala b/scaladoc/src/dotty/tools/scaladoc/site/StaticSiteLoader.scala index c9ace108c9b2..8277cd2a5d01 100644 --- a/scaladoc/src/dotty/tools/scaladoc/site/StaticSiteLoader.scala +++ b/scaladoc/src/dotty/tools/scaladoc/site/StaticSiteLoader.scala @@ -113,11 +113,37 @@ class StaticSiteLoader(val root: File, val args: Scaladoc.Args)(using StaticSite StaticSiteRoot(withBlog, mappings) } + var hiddenBlog = false + + def readYml: (Option[Boolean], Option[Boolean], Option[Boolean], String) = + val ymlPath = root.toPath.resolve("blog.yml") + if (Files.exists(ymlPath)) then + val yamlContent = Source.fromFile(ymlPath.toString).getLines().mkString("\n") + val hidden = if (yamlContent.contains("hidden: true")) Some(true) else None + val input = if (yamlContent.contains("input:")) Some(true) else None + val output = if (yamlContent.contains("output:")) Some(true) else None + (hidden, input, output, yamlContent) + else + (None, None, None, "") + def loadBlog(): Option[LoadedTemplate] = { + val (hidden, input, output, yamlContent) = readYml + val lines = yamlContent.split("\n") + val rootPath = input.collect { + case true => + lines.collectFirst { case line if line.contains("input:") => line.replaceFirst("input:", "").trim } + .map(ctx.resolveNewBlogPath) + .getOrElse(ctx.blogPath) + }.getOrElse(ctx.blogPath) + val defaultDirectory = output.collect { + case true => + lines + .collectFirst { case line if line.contains("output:") => line.replaceFirst("output:", "").trim } + .getOrElse("blog") + }.getOrElse("blog") + hidden.collect { case true => hiddenBlog = true } type Date = (String, String, String) - val rootPath = ctx.blogPath - val defaultDirectory = "blog" - if (!Files.exists(rootPath)) None + if (!Files.exists(rootPath) || hiddenBlog) None else { val indexPageOpt = Seq( rootPath.resolve("index.md"), From 0daeabed7c204bd883b7846ba3d98ca7375e39a6 Mon Sep 17 00:00:00 2001 From: Lucas Date: Wed, 3 May 2023 13:56:56 +0200 Subject: [PATCH 2/3] Fix: Refactor the function using jackson --- .../tools/scaladoc/site/BlogParser.scala | 29 +++++++++++++++ .../scaladoc/site/StaticSiteLoader.scala | 35 ++++--------------- 2 files changed, 35 insertions(+), 29 deletions(-) create mode 100644 scaladoc/src/dotty/tools/scaladoc/site/BlogParser.scala diff --git a/scaladoc/src/dotty/tools/scaladoc/site/BlogParser.scala b/scaladoc/src/dotty/tools/scaladoc/site/BlogParser.scala new file mode 100644 index 000000000000..6fd3d3db0c8d --- /dev/null +++ b/scaladoc/src/dotty/tools/scaladoc/site/BlogParser.scala @@ -0,0 +1,29 @@ +package dotty.tools.scaladoc +package site + +import com.fasterxml.jackson.databind.ObjectMapper +import com.fasterxml.jackson.dataformat.yaml.YAMLFactory +import com.fasterxml.jackson.databind.DeserializationFeature +import java.io.File +import scala.beans._ + +case class BlogConfig( + @BeanProperty var input: String, + @BeanProperty var output: String, + @BooleanBeanProperty var hidden: Boolean +): + def this() = this(null, null, false) + +object BlogParser: + def readYml(root: File): BlogConfig = + val ymlFile = root.toPath + .resolve("blog.yml") + .toFile + + if ymlFile.exists then + val mapper = new ObjectMapper(new YAMLFactory()) + mapper.findAndRegisterModules(); + + val blogConfig: BlogConfig = mapper.readValue(ymlFile, classOf[BlogConfig]) + blogConfig + else new BlogConfig diff --git a/scaladoc/src/dotty/tools/scaladoc/site/StaticSiteLoader.scala b/scaladoc/src/dotty/tools/scaladoc/site/StaticSiteLoader.scala index 8277cd2a5d01..489720cc5936 100644 --- a/scaladoc/src/dotty/tools/scaladoc/site/StaticSiteLoader.scala +++ b/scaladoc/src/dotty/tools/scaladoc/site/StaticSiteLoader.scala @@ -5,6 +5,7 @@ import java.io.File import java.nio.file.Files import java.nio.file.{ Paths, Path } import scala.io._ +import dotty.tools.scaladoc.site.BlogParser class StaticSiteLoader(val root: File, val args: Scaladoc.Args)(using StaticSiteContext, CompilerContext): val ctx: StaticSiteContext = summon[StaticSiteContext] @@ -113,37 +114,13 @@ class StaticSiteLoader(val root: File, val args: Scaladoc.Args)(using StaticSite StaticSiteRoot(withBlog, mappings) } - var hiddenBlog = false - - def readYml: (Option[Boolean], Option[Boolean], Option[Boolean], String) = - val ymlPath = root.toPath.resolve("blog.yml") - if (Files.exists(ymlPath)) then - val yamlContent = Source.fromFile(ymlPath.toString).getLines().mkString("\n") - val hidden = if (yamlContent.contains("hidden: true")) Some(true) else None - val input = if (yamlContent.contains("input:")) Some(true) else None - val output = if (yamlContent.contains("output:")) Some(true) else None - (hidden, input, output, yamlContent) - else - (None, None, None, "") - def loadBlog(): Option[LoadedTemplate] = { - val (hidden, input, output, yamlContent) = readYml - val lines = yamlContent.split("\n") - val rootPath = input.collect { - case true => - lines.collectFirst { case line if line.contains("input:") => line.replaceFirst("input:", "").trim } - .map(ctx.resolveNewBlogPath) - .getOrElse(ctx.blogPath) - }.getOrElse(ctx.blogPath) - val defaultDirectory = output.collect { - case true => - lines - .collectFirst { case line if line.contains("output:") => line.replaceFirst("output:", "").trim } - .getOrElse("blog") - }.getOrElse("blog") - hidden.collect { case true => hiddenBlog = true } + val blogConfig = BlogParser.readYml(root) + val rootPath = Option(blogConfig.input).map(input => ctx.resolveNewBlogPath(input)).getOrElse(ctx.blogPath) + val defaultDirectory = Option(blogConfig.output).getOrElse("blog") + type Date = (String, String, String) - if (!Files.exists(rootPath) || hiddenBlog) None + if (!Files.exists(rootPath) || blogConfig.hidden) None else { val indexPageOpt = Seq( rootPath.resolve("index.md"), From 968ebab3a525555fe50054fc5d6f504efe6db73c Mon Sep 17 00:00:00 2001 From: Lucas Date: Thu, 4 May 2023 10:52:01 +0200 Subject: [PATCH 3/3] Add test for BlogParser and Can parse a String --- .../tools/scaladoc/site/BlogParser.scala | 33 +++++++++---------- .../tools/scaladoc/site/BlogParserTest.scala | 19 +++++++++++ 2 files changed, 34 insertions(+), 18 deletions(-) create mode 100644 scaladoc/test/dotty/tools/scaladoc/site/BlogParserTest.scala diff --git a/scaladoc/src/dotty/tools/scaladoc/site/BlogParser.scala b/scaladoc/src/dotty/tools/scaladoc/site/BlogParser.scala index 6fd3d3db0c8d..68e709a339b2 100644 --- a/scaladoc/src/dotty/tools/scaladoc/site/BlogParser.scala +++ b/scaladoc/src/dotty/tools/scaladoc/site/BlogParser.scala @@ -1,29 +1,26 @@ -package dotty.tools.scaladoc -package site +package dotty.tools.scaladoc.site import com.fasterxml.jackson.databind.ObjectMapper import com.fasterxml.jackson.dataformat.yaml.YAMLFactory import com.fasterxml.jackson.databind.DeserializationFeature import java.io.File -import scala.beans._ +import scala.beans.{BooleanBeanProperty, BeanProperty} +import scala.util.Try case class BlogConfig( - @BeanProperty var input: String, - @BeanProperty var output: String, - @BooleanBeanProperty var hidden: Boolean + @BeanProperty input: String, + @BeanProperty output: String, + @BooleanBeanProperty hidden: Boolean ): - def this() = this(null, null, false) + def this() = this(null, null, false) object BlogParser: - def readYml(root: File): BlogConfig = - val ymlFile = root.toPath - .resolve("blog.yml") - .toFile + def readYml(content: File | String): BlogConfig = + val mapper = ObjectMapper(YAMLFactory()) + .findAndRegisterModules() - if ymlFile.exists then - val mapper = new ObjectMapper(new YAMLFactory()) - mapper.findAndRegisterModules(); - - val blogConfig: BlogConfig = mapper.readValue(ymlFile, classOf[BlogConfig]) - blogConfig - else new BlogConfig + content match + case f: File => + val ymlFile = f.toPath.resolve("blog.yml").toFile + if ymlFile.exists then mapper.readValue(ymlFile, classOf[BlogConfig]) else new BlogConfig + case s: String => Try(mapper.readValue(s, classOf[BlogConfig])).getOrElse(new BlogConfig) diff --git a/scaladoc/test/dotty/tools/scaladoc/site/BlogParserTest.scala b/scaladoc/test/dotty/tools/scaladoc/site/BlogParserTest.scala new file mode 100644 index 000000000000..e27c257c8e4a --- /dev/null +++ b/scaladoc/test/dotty/tools/scaladoc/site/BlogParserTest.scala @@ -0,0 +1,19 @@ +package dotty.tools.scaladoc +package site + +import org.junit.Test +import org.junit.Assert._ + +class BlogParserTest: + + private val blogConfig = + """input: blog + |output: blog + |hidden: false + |""".stripMargin + + @Test + def loadBlog(): Unit = assertEquals( + BlogConfig("blog", "blog", false), + BlogParser.readYml(blogConfig) + ) \ No newline at end of file