diff options
author | Błażej Kardyś <bkardys@virtuslab.com> | 2021-01-05 17:59:38 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-01-05 17:59:38 +0100 |
commit | 1618e552c136e25d86bf0708e0d760841c77c139 (patch) | |
tree | c608ce91b020bb0ecbfe75d0f456a0eae84b4c51 /plugins/all-modules-page/src/main/kotlin/templates | |
parent | ef98e4b6505c3fdd192b1d5057c718079d27b972 (diff) | |
download | dokka-1618e552c136e25d86bf0708e0d760841c77c139.tar.gz dokka-1618e552c136e25d86bf0708e0d760841c77c139.tar.bz2 dokka-1618e552c136e25d86bf0708e0d760841c77c139.zip |
Versioning (#1654)
* Adding versioning mechanism for multimodule
* Versioning improvement
* Refactor configuration, add ordering
* Fix integration tests
* Change packages, unignore test
Co-authored-by: Marcin Aman <marcin.aman@gmail.com>
Diffstat (limited to 'plugins/all-modules-page/src/main/kotlin/templates')
7 files changed, 0 insertions, 391 deletions
diff --git a/plugins/all-modules-page/src/main/kotlin/templates/DirectiveBasedTemplateProcessing.kt b/plugins/all-modules-page/src/main/kotlin/templates/DirectiveBasedTemplateProcessing.kt deleted file mode 100644 index 2b065731..00000000 --- a/plugins/all-modules-page/src/main/kotlin/templates/DirectiveBasedTemplateProcessing.kt +++ /dev/null @@ -1,141 +0,0 @@ -package org.jetbrains.dokka.allModulesPage.templates - -import kotlinx.coroutines.Dispatchers.IO -import kotlinx.coroutines.coroutineScope -import kotlinx.coroutines.launch -import kotlinx.coroutines.withContext -import org.jetbrains.dokka.allModulesPage.AllModulesPagePlugin -import org.jetbrains.dokka.base.templating.* -import org.jetbrains.dokka.plugability.DokkaContext -import org.jetbrains.dokka.plugability.plugin -import org.jetbrains.dokka.plugability.query -import org.jetbrains.dokka.plugability.querySingle -import org.jsoup.Jsoup -import org.jsoup.nodes.* -import org.jsoup.parser.Tag -import java.io.File -import java.nio.file.Files -import java.util.concurrent.ConcurrentHashMap - -class DirectiveBasedHtmlTemplateProcessingStrategy(private val context: DokkaContext) : TemplateProcessingStrategy { - private val navigationFragments = ConcurrentHashMap<String, Element>() - - private val substitutors = context.plugin<AllModulesPagePlugin>().query { substitutor } - private val externalModuleLinkResolver = context.plugin<AllModulesPagePlugin>().querySingle { externalModuleLinkResolver } - - override suspend fun process(input: File, output: File): Boolean = coroutineScope { - if (input.extension == "html") { - launch { - val document = withContext(IO) { Jsoup.parse(input, "UTF-8") } - document.outputSettings().indentAmount(0).prettyPrint(false) - document.select("dokka-template-command").forEach { - when (val command = parseJson<Command>(it.attr("data"))) { - is ResolveLinkCommand -> resolveLink(it, command, output) - is AddToNavigationCommand -> navigationFragments[command.moduleName] = it - is SubstitutionCommand -> substitute(it, TemplatingContext(input, output, it, command)) - else -> context.logger.warn("Unknown templating command $command") - } - } - withContext(IO) { Files.write(output.toPath(), listOf(document.outerHtml())) } - } - true - } else false - } - - private fun substitute(element: Element, commandContext: TemplatingContext<SubstitutionCommand>) { - val regex = commandContext.command.pattern.toRegex() - element.children().forEach { it.traverseToSubstitute(regex, commandContext) } - - val childrenCopy = element.children().toList() - val position = element.elementSiblingIndex() - val parent = element.parent() - element.remove() - - parent.insertChildren(position, childrenCopy) - } - - private fun Node.traverseToSubstitute(regex: Regex, commandContext: TemplatingContext<SubstitutionCommand>) { - when (this) { - is TextNode -> replaceWith(TextNode(wholeText.substitute(regex, commandContext))) - is DataNode -> replaceWith(DataNode(wholeData.substitute(regex, commandContext))) - is Element -> { - attributes().forEach { attr(it.key, it.value.substitute(regex, commandContext)) } - childNodes().forEach { it.traverseToSubstitute(regex, commandContext) } - } - } - } - - private fun String.substitute(regex: Regex, commandContext: TemplatingContext<SubstitutionCommand>) = buildString { - var lastOffset = 0 - regex.findAll(this@substitute).forEach { match -> - append(this@substitute, lastOffset, match.range.first) - append(findSubstitution(commandContext, match)) - lastOffset = match.range.last + 1 - } - append(this@substitute, lastOffset, this@substitute.length) - } - - private fun findSubstitution(commandContext: TemplatingContext<SubstitutionCommand>, match: MatchResult): String = - substitutors.asSequence().mapNotNull { it.trySubstitute(commandContext, match) }.firstOrNull() ?: match.value - - override suspend fun finish(output: File) { - if (navigationFragments.isNotEmpty()) { - val attributes = Attributes().apply { - put("class", "sideMenu") - } - val node = Element(Tag.valueOf("div"), "", attributes) - navigationFragments.entries.sortedBy { it.key }.forEach { (moduleName, command) -> - command.select("a").forEach { a -> - a.attr("href")?.also { a.attr("href", "${moduleName}/${it}") } - } - command.childNodes().toList().forEachIndexed { index, child -> - if (index == 0) { - child.attr("id", "$moduleName-nav-submenu") - } - node.appendChild(child) - } - } - - withContext(IO) { - Files.write(output.resolve("navigation.html").toPath(), listOf(node.outerHtml())) - } - - node.select("a").forEach { a -> - a.attr("href")?.also { a.attr("href", "../${it}") } - } - navigationFragments.keys.forEach { - withContext(IO) { - Files.write( - output.resolve(it).resolve("navigation.html").toPath(), - listOf(node.outerHtml()) - ) - } - } - } - } - - private fun resolveLink(it: Element, command: ResolveLinkCommand, fileContext: File) { - - val link = externalModuleLinkResolver.resolve(command.dri, fileContext) - if (link == null) { - val children = it.childNodes().toList() - val attributes = Attributes().apply { - put("data-unresolved-link", command.dri.toString()) - } - val element = Element(Tag.valueOf("span"), "", attributes).apply { - children.forEach { ch -> appendChild(ch) } - } - it.replaceWith(element) - return - } - - val attributes = Attributes().apply { - put("href", link) - } - val children = it.childNodes().toList() - val element = Element(Tag.valueOf("a"), "", attributes).apply { - children.forEach { ch -> appendChild(ch) } - } - it.replaceWith(element) - } -} diff --git a/plugins/all-modules-page/src/main/kotlin/templates/ExternalModuleLinkResolver.kt b/plugins/all-modules-page/src/main/kotlin/templates/ExternalModuleLinkResolver.kt deleted file mode 100644 index d0e787b6..00000000 --- a/plugins/all-modules-page/src/main/kotlin/templates/ExternalModuleLinkResolver.kt +++ /dev/null @@ -1,77 +0,0 @@ -package org.jetbrains.dokka.allModulesPage.templates - -import org.jetbrains.dokka.DokkaConfiguration -import org.jetbrains.dokka.base.DokkaBase -import org.jetbrains.dokka.base.resolvers.local.DokkaLocationProvider.Companion.identifierToFilename -import org.jetbrains.dokka.base.resolvers.shared.ExternalDocumentation -import org.jetbrains.dokka.base.resolvers.shared.PackageList -import org.jetbrains.dokka.base.resolvers.shared.RecognizedLinkFormat -import org.jetbrains.dokka.links.DRI -import org.jetbrains.dokka.plugability.DokkaContext -import org.jetbrains.dokka.plugability.plugin -import org.jetbrains.dokka.plugability.query -import java.io.File -import java.net.URL - -interface ExternalModuleLinkResolver { - fun resolve(dri: DRI, fileContext: File): String? - fun resolveLinkToModuleIndex(moduleName: String): String? -} - -class DefaultExternalModuleLinkResolver(val context: DokkaContext) : ExternalModuleLinkResolver { - private val elpFactory = context.plugin<DokkaBase>().query { externalLocationProviderFactory } - private val externalDocumentations by lazy(::setupExternalDocumentations) - private val elps by lazy { - elpFactory.flatMap { externalDocumentations.map { ed -> it.getExternalLocationProvider(ed) } }.filterNotNull() - } - - private fun setupExternalDocumentations(): List<ExternalDocumentation> { - val packageLists = - context.configuration.modules.map(::loadPackageListForModule).toMap() - return packageLists.mapNotNull { (module, packageList) -> - packageList?.let { - ExternalDocumentation( - URL("file:/${module.name}/${module.name}"), - packageList - ) - } - } - } - - private fun loadPackageListForModule(module: DokkaConfiguration.DokkaModuleDescription) = - module.sourceOutputDirectory.resolve(File(identifierToFilename(module.name))).let { - it to PackageList.load( - URL("file:" + it.resolve("package-list").path), - 8, - true - ) - } - - override fun resolve(dri: DRI, fileContext: File): String? { - val absoluteLink = elps.mapNotNull { it.resolve(dri) }.firstOrNull() ?: return null - val modulePath = context.configuration.outputDir.absolutePath.split(File.separator) - val contextPath = fileContext.absolutePath.split(File.separator) - val commonPathElements = modulePath.zip(contextPath) - .takeWhile { (a, b) -> a == b }.count() - - return (List(contextPath.size - commonPathElements - 1) { ".." } + modulePath.drop(commonPathElements)).joinToString( - "/" - ) + absoluteLink.removePrefix("file:") - } - - override fun resolveLinkToModuleIndex(moduleName: String): String? = - context.configuration.modules.firstOrNull { it.name == moduleName } - ?.let { module -> - val (_, packageList) = loadPackageListForModule(module) - val extension = when (packageList?.linkFormat) { - RecognizedLinkFormat.KotlinWebsiteHtml, - RecognizedLinkFormat.DokkaOldHtml, - RecognizedLinkFormat.DokkaHtml -> ".html" - RecognizedLinkFormat.DokkaGFM, - RecognizedLinkFormat.DokkaJekyll -> ".md" - else -> "" - } - "${module.relativePathToOutputDirectory}/${identifierToFilename(moduleName)}/index$extension" - } - -} diff --git a/plugins/all-modules-page/src/main/kotlin/templates/FallbackTemplateProcessingStrategy.kt b/plugins/all-modules-page/src/main/kotlin/templates/FallbackTemplateProcessingStrategy.kt deleted file mode 100644 index 9b5251ac..00000000 --- a/plugins/all-modules-page/src/main/kotlin/templates/FallbackTemplateProcessingStrategy.kt +++ /dev/null @@ -1,18 +0,0 @@ -package org.jetbrains.dokka.allModulesPage.templates - -import kotlinx.coroutines.Dispatchers.IO -import kotlinx.coroutines.coroutineScope -import kotlinx.coroutines.launch -import org.jetbrains.dokka.plugability.DokkaContext -import java.io.File -import java.nio.file.Files - -class FallbackTemplateProcessingStrategy(dokkaContext: DokkaContext) : TemplateProcessingStrategy { - - override suspend fun process(input: File, output: File): Boolean = coroutineScope { - launch(IO) { - Files.copy(input.toPath(), output.toPath()) - } - true - } -}
\ No newline at end of file diff --git a/plugins/all-modules-page/src/main/kotlin/templates/JsonElementBasedTemplateProcessingStrategy.kt b/plugins/all-modules-page/src/main/kotlin/templates/JsonElementBasedTemplateProcessingStrategy.kt deleted file mode 100644 index c6c67752..00000000 --- a/plugins/all-modules-page/src/main/kotlin/templates/JsonElementBasedTemplateProcessingStrategy.kt +++ /dev/null @@ -1,74 +0,0 @@ -package org.jetbrains.dokka.allModulesPage.templates - -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.coroutineScope -import kotlinx.coroutines.launch -import kotlinx.coroutines.withContext -import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper -import java.io.File -import java.nio.file.Files -import com.fasterxml.jackson.module.kotlin.treeToValue -import org.jetbrains.dokka.base.renderers.html.SearchRecord -import org.jetbrains.dokka.base.templating.* -import org.jetbrains.dokka.plugability.DokkaContext -import java.util.concurrent.ConcurrentHashMap - -abstract class BaseJsonNavigationTemplateProcessingStrategy(val context: DokkaContext) : TemplateProcessingStrategy { - abstract val navigationFileNameWithoutExtension: String - abstract val path: String - - private val fragments = ConcurrentHashMap<String, List<SearchRecord>>() - - open fun canProcess(file: File): Boolean = - file.extension == "json" && file.nameWithoutExtension == navigationFileNameWithoutExtension - - override suspend fun process(input: File, output: File): Boolean = coroutineScope { - val canProcess = canProcess(input) - if (canProcess) { - launch { - withContext(Dispatchers.IO) { - runCatching { parseJson<AddToSearch>(input.readText()) }.getOrNull() - }?.let { command -> - fragments[command.moduleName] = command.elements - } ?: fallbackToCopy(input, output) - } - } - canProcess - } - - override suspend fun finish(output: File) { - if (fragments.isNotEmpty()) { - val content = toJsonString(fragments.entries.flatMap { (moduleName, navigation) -> - navigation.map { it.withResolvedLocation(moduleName) } - }) - withContext(Dispatchers.IO) { - output.resolve("$path/$navigationFileNameWithoutExtension.json").writeText(content) - - fragments.keys.forEach { - output.resolve(it).resolve("$path/$navigationFileNameWithoutExtension.json").writeText(content) - } - } - } - } - - private suspend fun fallbackToCopy(input: File, output: File) { - context.logger.warn("Falling back to just copying file for ${input.name} even thought it should process it") - withContext(Dispatchers.IO) { input.copyTo(output) } - } - - private fun SearchRecord.withResolvedLocation(moduleName: String): SearchRecord = - copy(location = "$moduleName/$location") - -} - -class NavigationSearchTemplateStrategy(val dokkaContext: DokkaContext) : - BaseJsonNavigationTemplateProcessingStrategy(dokkaContext) { - override val navigationFileNameWithoutExtension: String = "navigation-pane" - override val path: String = "scripts" -} - -class PagesSearchTemplateStrategy(val dokkaContext: DokkaContext) : - BaseJsonNavigationTemplateProcessingStrategy(dokkaContext) { - override val navigationFileNameWithoutExtension: String = "pages" - override val path: String = "scripts" -}
\ No newline at end of file diff --git a/plugins/all-modules-page/src/main/kotlin/templates/PathToRootSubstitutor.kt b/plugins/all-modules-page/src/main/kotlin/templates/PathToRootSubstitutor.kt deleted file mode 100644 index 5056b724..00000000 --- a/plugins/all-modules-page/src/main/kotlin/templates/PathToRootSubstitutor.kt +++ /dev/null @@ -1,14 +0,0 @@ -package org.jetbrains.dokka.allModulesPage.templates - -import org.jetbrains.dokka.base.templating.PathToRootSubstitutionCommand -import org.jetbrains.dokka.base.templating.SubstitutionCommand -import org.jetbrains.dokka.plugability.DokkaContext -import java.io.File - -class PathToRootSubstitutor(private val dokkaContext: DokkaContext) : Substitutor { - override fun trySubstitute(context: TemplatingContext<SubstitutionCommand>, match: MatchResult): String? = - if (context.command is PathToRootSubstitutionCommand) { - context.output.toPath().parent.relativize(dokkaContext.configuration.outputDir.toPath()).toString().split(File.separator).joinToString(separator = "/", postfix = "/") { it } - } else null - -}
\ No newline at end of file diff --git a/plugins/all-modules-page/src/main/kotlin/templates/Substitutor.kt b/plugins/all-modules-page/src/main/kotlin/templates/Substitutor.kt deleted file mode 100644 index 98f1d88e..00000000 --- a/plugins/all-modules-page/src/main/kotlin/templates/Substitutor.kt +++ /dev/null @@ -1,7 +0,0 @@ -package org.jetbrains.dokka.allModulesPage.templates - -import org.jetbrains.dokka.base.templating.SubstitutionCommand - -fun interface Substitutor { - fun trySubstitute(context: TemplatingContext<SubstitutionCommand>, match: MatchResult): String? -}
\ No newline at end of file diff --git a/plugins/all-modules-page/src/main/kotlin/templates/TemplateProcessor.kt b/plugins/all-modules-page/src/main/kotlin/templates/TemplateProcessor.kt deleted file mode 100644 index 18d63df0..00000000 --- a/plugins/all-modules-page/src/main/kotlin/templates/TemplateProcessor.kt +++ /dev/null @@ -1,60 +0,0 @@ -package org.jetbrains.dokka.allModulesPage.templates - -import kotlinx.coroutines.* -import org.jetbrains.dokka.allModulesPage.AllModulesPagePlugin -import org.jetbrains.dokka.base.templating.Command -import org.jetbrains.dokka.plugability.DokkaContext -import org.jetbrains.dokka.plugability.plugin -import org.jetbrains.dokka.plugability.query -import org.jsoup.nodes.Element -import java.io.File -import java.nio.file.Files -import java.nio.file.Path -import kotlin.coroutines.coroutineContext - -interface TemplateProcessor { - fun process() -} - -interface TemplateProcessingStrategy { - suspend fun process(input: File, output: File): Boolean - suspend fun finish(output: File) {} -} - -class DefaultTemplateProcessor( - private val context: DokkaContext, -): TemplateProcessor { - - private val strategies: List<TemplateProcessingStrategy> = context.plugin<AllModulesPagePlugin>().query { templateProcessingStrategy } - - override fun process() = runBlocking(Dispatchers.Default) { - coroutineScope { - context.configuration.modules.forEach { - launch { - it.sourceOutputDirectory.visit(context.configuration.outputDir.resolve(it.relativePathToOutputDirectory)) - } - } - } - strategies.map { it.finish(context.configuration.outputDir) } - Unit - } - - private suspend fun File.visit(target: File): Unit = coroutineScope { - val source = this@visit - if (source.isDirectory) { - target.mkdir() - source.list()?.forEach { - launch { source.resolve(it).visit(target.resolve(it)) } - } - } else { - strategies.asSequence().first { it.process(source, target) } - } - } -} - -data class TemplatingContext<out T: Command>( - val input: File, - val output: File, - val element: Element, - val command: T, -)
\ No newline at end of file |