aboutsummaryrefslogtreecommitdiff
path: root/plugins/templating/src/main/kotlin/templates/PackageListProcessingStrategy.kt
blob: 07238ea7dc4f80faf4ab64faf8390d40df5a20c9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
package org.jetbrains.dokka.allModulesPage.templates

import org.jetbrains.dokka.DokkaConfiguration.DokkaModuleDescription
import org.jetbrains.dokka.base.renderers.PackageListService
import org.jetbrains.dokka.base.resolvers.local.DokkaLocationProvider
import org.jetbrains.dokka.base.resolvers.shared.PackageList
import org.jetbrains.dokka.base.resolvers.shared.PackageList.Companion.PACKAGE_LIST_NAME
import org.jetbrains.dokka.plugability.DokkaContext
import org.jetbrains.dokka.templates.TemplateProcessingStrategy
import java.io.File

class PackageListProcessingStrategy(val context: DokkaContext) : TemplateProcessingStrategy {
    private val fragments = mutableSetOf<PackageList>()

    private fun canProcess(file: File, moduleContext: DokkaModuleDescription?): Boolean =
            file.extension.isBlank() && file.nameWithoutExtension == PACKAGE_LIST_NAME && moduleContext != null

    override fun process(input: File, output: File, moduleContext: DokkaModuleDescription?): Boolean {
        val canProcess = canProcess(input, moduleContext)
        if (canProcess) {
            val packageList = PackageList.load(input.toURI().toURL(), 8, true)
            val moduleFilename = moduleContext?.name?.let { "$it/" }
            packageList?.copy(
                    modules = mapOf(moduleContext?.name.orEmpty() to packageList.modules.getOrDefault(PackageList.SINGLE_MODULE_NAME, emptySet())),
                    locations = packageList.locations.entries.associate { it.key to "$moduleFilename${it.value}" }
            )?.let { fragments.add(it) } ?: fallbackToCopy(input, output)
        }
        return canProcess
    }

    override fun finish(output: File) {
        if (fragments.isNotEmpty()) {
            val linkFormat = fragments.first().linkFormat

            if (!fragments.all { it.linkFormat == linkFormat }) {
                context.logger.error("Link format is inconsistent between modules: " + fragments.joinToString { it.linkFormat.formatName } )
            }

            val locations: Map<String, String> = fragments.map { it.locations }.fold(emptyMap()) { acc, el -> acc + el }
            val modules: Map<String, Set<String>> = fragments.map { it.modules }.fold(emptyMap()) { acc, el -> acc + el }
            val mergedPackageList = PackageListService.renderPackageList(locations, modules, linkFormat.formatName, linkFormat.linkExtension)
            output.mkdirs()
            output.resolve(PACKAGE_LIST_NAME).writeText(mergedPackageList)
        }
    }

    private fun fallbackToCopy(input: File, output: File) {
        context.logger.warn("Falling back to just copying ${input.name} file even though it should have been processed")
        input.copyTo(output)
    }
}