diff options
45 files changed, 373 insertions, 145 deletions
diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml index f063496e..31d977a0 100644 --- a/.idea/codeStyles/Project.xml +++ b/.idea/codeStyles/Project.xml @@ -3,9 +3,18 @@ <JetCodeStyleSettings> <option name="PACKAGES_TO_USE_STAR_IMPORTS"> <value> - <package name="java.util" withSubpackages="false" static="false" /> - <package name="kotlinx.android.synthetic" withSubpackages="true" static="false" /> - <package name="io.ktor" withSubpackages="true" static="false" /> + <package name="java.util" alias="false" withSubpackages="false" /> + <package name="kotlinx.android.synthetic" alias="false" withSubpackages="true" /> + <package name="io.ktor" alias="false" withSubpackages="true" /> + </value> + </option> + <option name="PACKAGES_IMPORT_LAYOUT"> + <value> + <package name="" alias="false" withSubpackages="true" /> + <package name="java" alias="false" withSubpackages="true" /> + <package name="javax" alias="false" withSubpackages="true" /> + <package name="kotlin" alias="false" withSubpackages="true" /> + <package name="" alias="true" withSubpackages="true" /> </value> </option> <option name="CODE_STYLE_DEFAULTS" value="KOTLIN_OFFICIAL" /> @@ -14,4 +23,4 @@ <option name="CODE_STYLE_DEFAULTS" value="KOTLIN_OFFICIAL" /> </codeStyleSettings> </code_scheme> -</component> +</component>
\ No newline at end of file diff --git a/core/build.gradle.kts b/core/build.gradle.kts index 971f08f4..b1c1dbb9 100644 --- a/core/build.gradle.kts +++ b/core/build.gradle.kts @@ -11,6 +11,7 @@ dependencies { implementation(kotlin("reflect")) implementation("org.jsoup:jsoup:1.12.1") implementation("com.fasterxml.jackson.module:jackson-module-kotlin:2.11.1") + implementation("com.fasterxml.jackson.dataformat:jackson-dataformat-xml:2.11.1") val coroutines_version: String by project implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:$coroutines_version") diff --git a/core/src/main/kotlin/configuration.kt b/core/src/main/kotlin/configuration.kt index f5b2254a..bc097ae4 100644 --- a/core/src/main/kotlin/configuration.kt +++ b/core/src/main/kotlin/configuration.kt @@ -2,6 +2,7 @@ package org.jetbrains.dokka +import org.jetbrains.dokka.plugability.ConfigurableBlock import org.jetbrains.dokka.utilities.parseJson import org.jetbrains.dokka.utilities.toJsonString import java.io.File @@ -29,6 +30,7 @@ object DokkaDefaults { const val sourceSetDisplayName = "JVM" const val sourceSetName = "main" val moduleVersion: String? = null + val pluginsConfiguration = mutableListOf<PluginConfigurationImpl>() } enum class Platform(val key: String) { @@ -81,6 +83,7 @@ data class DokkaSourceSetID( fun DokkaConfigurationImpl(json: String): DokkaConfigurationImpl = parseJson(json) fun DokkaConfiguration.toJsonString(): String = toJsonString(this) +fun <T : ConfigurableBlock> T.toJsonString(): String = toJsonString(this) interface DokkaConfiguration : Serializable { val moduleName: String @@ -92,7 +95,17 @@ interface DokkaConfiguration : Serializable { val sourceSets: List<DokkaSourceSet> val modules: List<DokkaModuleDescription> val pluginsClasspath: List<File> - val pluginsConfiguration: Map<String, String> + val pluginsConfiguration: List<PluginConfiguration> + + enum class SerializationFormat : Serializable { + JSON, XML + } + + interface PluginConfiguration : Serializable { + val fqPluginName: String + val serializationFormat: SerializationFormat + val values: String + } interface DokkaSourceSet : Serializable { val sourceSetID: DokkaSourceSetID diff --git a/core/src/main/kotlin/defaultConfiguration.kt b/core/src/main/kotlin/defaultConfiguration.kt index 45bf904d..a28df152 100644 --- a/core/src/main/kotlin/defaultConfiguration.kt +++ b/core/src/main/kotlin/defaultConfiguration.kt @@ -12,11 +12,17 @@ data class DokkaConfigurationImpl( override val offlineMode: Boolean = DokkaDefaults.offlineMode, override val sourceSets: List<DokkaSourceSetImpl> = emptyList(), override val pluginsClasspath: List<File> = emptyList(), - override val pluginsConfiguration: Map<String, String> = emptyMap(), + override val pluginsConfiguration: List<PluginConfigurationImpl> = DokkaDefaults.pluginsConfiguration, override val modules: List<DokkaModuleDescriptionImpl> = emptyList(), override val failOnWarning: Boolean = DokkaDefaults.failOnWarning ) : DokkaConfiguration +data class PluginConfigurationImpl( + override val fqPluginName: String, + override val serializationFormat: DokkaConfiguration.SerializationFormat, + override val values: String +) : DokkaConfiguration.PluginConfiguration + data class DokkaSourceSetImpl( override val displayName: String = DokkaDefaults.sourceSetDisplayName, diff --git a/core/src/main/kotlin/plugability/DokkaPlugin.kt b/core/src/main/kotlin/plugability/DokkaPlugin.kt index 13f59f6e..625a34e2 100644 --- a/core/src/main/kotlin/plugability/DokkaPlugin.kt +++ b/core/src/main/kotlin/plugability/DokkaPlugin.kt @@ -1,12 +1,13 @@ package org.jetbrains.dokka.plugability +import com.fasterxml.jackson.dataformat.xml.JacksonXmlModule +import com.fasterxml.jackson.dataformat.xml.XmlMapper +import com.fasterxml.jackson.module.kotlin.readValue import org.jetbrains.dokka.DokkaConfiguration import org.jetbrains.dokka.utilities.parseJson -import org.jetbrains.dokka.utilities.toJsonString import kotlin.properties.ReadOnlyProperty import kotlin.reflect.KProperty import kotlin.reflect.KProperty1 -import kotlin.reflect.full.createInstance abstract class DokkaPlugin { private val extensionDelegates = mutableListOf<KProperty<*>>() @@ -40,12 +41,12 @@ abstract class DokkaPlugin { internal fun internalInstall(ctx: DokkaContextConfiguration, configuration: DokkaConfiguration) { val extensionsToInstall = extensionDelegates.asSequence() .filterIsInstance<KProperty1<DokkaPlugin, Extension<*, *, *>>>() // should be always true - .map { it.get(this) } + unsafePlugins.map{ it.value } + .map { it.get(this) } + unsafePlugins.map { it.value } extensionsToInstall.forEach { if (configuration.(it.condition)()) ctx.installExtension(it) } } - protected fun <T: Any> unsafeInstall(ext: Lazy<Extension<T, *, *>>){ - unsafePlugins.add(ext) + protected fun <T : Any> unsafeInstall(ext: Lazy<Extension<T, *, *>>) { + unsafePlugins.add(ext) } } @@ -53,19 +54,8 @@ interface WithUnsafeExtensionSuppression { val extensionsSuppressed: List<Extension<*, *, *>> } -interface Configurable { - val pluginsConfiguration: Map<String, String> -} - interface ConfigurableBlock -inline fun <reified P : DokkaPlugin, reified T : ConfigurableBlock> Configurable.pluginConfiguration(block: T.() -> Unit) { - val instance = T::class.createInstance().apply(block) - - val mutablePluginsConfiguration = pluginsConfiguration as MutableMap<String, String> - mutablePluginsConfiguration[P::class.qualifiedName!!] = toJsonString(instance) -} - inline fun <reified P : DokkaPlugin, reified E : Any> P.query(extension: P.() -> ExtensionPoint<E>): List<E> = context?.let { it[extension()] } ?: throwIllegalQuery() @@ -75,11 +65,15 @@ inline fun <reified P : DokkaPlugin, reified E : Any> P.querySingle(extension: P fun throwIllegalQuery(): Nothing = throw IllegalStateException("Querying about plugins is only possible with dokka context initialised") -inline fun <reified T : DokkaPlugin, reified R : ConfigurableBlock> configuration(context: DokkaContext): ReadOnlyProperty<Any?, R> { - return ReadOnlyProperty { _, _ -> - val configuration = context.configuration.pluginsConfiguration[ - T::class.qualifiedName ?: throw AssertionError("Plugin must be named class") - ] - parseJson(checkNotNull(configuration)) - } -} +inline fun <reified T : DokkaPlugin, reified R : ConfigurableBlock> configuration(context: DokkaContext): R? = + context.configuration.pluginsConfiguration.firstOrNull { it.fqPluginName == T::class.qualifiedName } + ?.let { configuration -> + when (configuration.serializationFormat) { + DokkaConfiguration.SerializationFormat.JSON -> parseJson(configuration.values) + DokkaConfiguration.SerializationFormat.XML -> XmlMapper(JacksonXmlModule().apply { + setDefaultUseWrapper( + true + ) + }).readValue<R>(configuration.values) + } + } diff --git a/core/test-api/src/main/kotlin/testApi/testRunner/TestDokkaConfigurationBuilder.kt b/core/test-api/src/main/kotlin/testApi/testRunner/TestDokkaConfigurationBuilder.kt index 45656a43..cba13f2a 100644 --- a/core/test-api/src/main/kotlin/testApi/testRunner/TestDokkaConfigurationBuilder.kt +++ b/core/test-api/src/main/kotlin/testApi/testRunner/TestDokkaConfigurationBuilder.kt @@ -31,7 +31,7 @@ class TestDokkaConfigurationBuilder { var offlineMode: Boolean = false var cacheRoot: String? = null var pluginsClasspath: List<File> = emptyList() - var pluginsConfigurations: Map<String, String> = emptyMap() + var pluginsConfigurations: MutableList<PluginConfigurationImpl> = mutableListOf() var failOnWarning: Boolean = false private val lazySourceSets = mutableListOf<Lazy<DokkaSourceSetImpl>>() diff --git a/docs/src/doc/docs/user_guide/base-specific/frontend.md b/docs/src/doc/docs/user_guide/base-specific/frontend.md new file mode 100644 index 00000000..adeb38ad --- /dev/null +++ b/docs/src/doc/docs/user_guide/base-specific/frontend.md @@ -0,0 +1,29 @@ +# Configuration specific to HTML format + +## Modifying assets + +It is possible to change static assets that are used to generate dokka's HTML. +Currently, user can modify: + * customAssets + * customStyleSheets + +Every file provided in those values will be applied to **every** page. + +Dokka uses 3 stylesheets: +* `style.css` - main css file responsible for styling the page +* `jetbrains-mono.css` - fonts used across dokka +* `logo-styles.css` - logo styling + +User can choose to add or override those files. +Resources will be overridden when in `pluginConfiguration` block there is a resource with the same name. + +### Examples +In order to override a logo and style it accordingly a simple css file named `logo-styles.css` is needed: +```css +#logo { + background-image: url('https://upload.wikimedia.org/wikipedia/commons/9/9d/Ubuntu_logo.svg'); + /* other styles required to make your page pretty */ +} +``` + +For build system specific instructions please visit dedicated pages: [gradle](../gradle/usage.md#Applying plugins), [maven](../maven/usage.md#Applying plugins) and [cli](../cli/usage.md#Configuration options)
\ No newline at end of file diff --git a/docs/src/doc/docs/user_guide/cli/usage.md b/docs/src/doc/docs/user_guide/cli/usage.md index 9c73f8d3..e6bedf5e 100644 --- a/docs/src/doc/docs/user_guide/cli/usage.md +++ b/docs/src/doc/docs/user_guide/cli/usage.md @@ -14,6 +14,7 @@ Dokka supports the following command line arguments: * `-moduleName` - (required) - module name used as a part of source set ID when declaring dependent source sets * `-cacheRoot` - cache directory to enable package-list caching * `-pluginsClasspath` - artifacts with Dokka plugins, separated by `;`. At least `dokka-base` and all its dependencies must be added there + * `-pluginsConfiguration` - configuration for plugins in format fqPluginName=json^^fqPluginName=json... * `-offlineMode` - do not resolve package-lists online * `-failOnWarning` - throw an exception instead of a warning * `-globalPackageOptions` - per package options added to all source sets diff --git a/docs/src/doc/docs/user_guide/gradle/usage.md b/docs/src/doc/docs/user_guide/gradle/usage.md index 987bc4c0..e0f84e96 100644 --- a/docs/src/doc/docs/user_guide/gradle/usage.md +++ b/docs/src/doc/docs/user_guide/gradle/usage.md @@ -182,6 +182,10 @@ dokkaHtml { suppress.set(true) } } + // Configures a plugin separately from the global configuration + pluginConfiguration<PluginClass, ConfigurationClass>{ + // values + } } } ``` @@ -249,6 +253,21 @@ To generate the documentation, use the appropriate `dokka${format}` Gradle task: ./gradlew dokkaHtml ``` +Some plugins can be configured separately using a plugin class and configuration class. For example: + +```kotlin +pluginConfiguration<DokkaBase, DokkaBaseConfiguration> { + customAssets = listOf(file("<path to asset>")) + customStyleSheets = listOf(file("<path to custom stylesheet>")) +} +``` + +Keep in mind, that this only works when using a buildscript (with the configured plugin on classpath) since it is not possible to import plugin's class without it. + +If you don't want to use a buildscript or use Kotlin version lower than 1.3.50 you can achieve the same behaviour manually: +```kotlin +pluginsMapConfiguration.set(mapOf("<fully qualified plugin's name>" to """<json configuration>""")) +``` ## Android !!! important diff --git a/docs/src/doc/docs/user_guide/maven/usage.md b/docs/src/doc/docs/user_guide/maven/usage.md index a95b6629..812737fa 100644 --- a/docs/src/doc/docs/user_guide/maven/usage.md +++ b/docs/src/doc/docs/user_guide/maven/usage.md @@ -160,6 +160,14 @@ The available configuration options are shown below: <version>${dokka.version}</version> </plugin> </dokkaPlugins> + + <!-- Configures a plugin separately --> + <pluginsConfiguration> + <fullyQualifiedPluginName> + <!-- Configuration --> + </fullyQualifiedPluginName> + </pluginsConfiguration> + </configuration> </plugin> ``` @@ -192,6 +200,21 @@ You can add plugins inside the `dokkaPlugins` block: </plugin> ``` +Some plugins can be configured separately using plugin's fully qualified name. For example: + +```xml +<pluginsConfiguration> + <org.jetbrains.dokka.base.DokkaBase> + <customStyleSheets> + <customStyleSheet><!-- path to custom stylesheet --></customStyleSheet> + </customStyleSheets> + <customAssets> + <customAsset><!-- path to custom asset --></customAsset> + </customAssets> + </org.jetbrains.dokka.base.DokkaBase> +</pluginsConfiguration> +``` + ## Example project Please see the [Dokka Maven example project](https://github.com/JetBrains/kotlin-examples/tree/master/maven/dokka-maven-example) for an example. diff --git a/integration-tests/gradle/build.gradle.kts b/integration-tests/gradle/build.gradle.kts index 3da416bb..8d3e8247 100644 --- a/integration-tests/gradle/build.gradle.kts +++ b/integration-tests/gradle/build.gradle.kts @@ -7,6 +7,8 @@ dependencies { } tasks.integrationTest { + val dokka_version: String by project + environment("DOKKA_VERSION", dokka_version) inputs.dir(file("projects")) dependsOnMavenLocalPublication() } diff --git a/integration-tests/gradle/projects/it-basic-groovy/build.gradle b/integration-tests/gradle/projects/it-basic-groovy/build.gradle index df2e8624..dc469bba 100644 --- a/integration-tests/gradle/projects/it-basic-groovy/build.gradle +++ b/integration-tests/gradle/projects/it-basic-groovy/build.gradle @@ -11,7 +11,6 @@ dependencies { dokkaHtml { outputDirectory = new File(buildDir, "/dokka/customHtml") - pluginsConfiguration.put("pluginA", "configA") failOnWarning = false dokkaSourceSets { customSourceSet { diff --git a/integration-tests/gradle/projects/it-basic/build.gradle.kts b/integration-tests/gradle/projects/it-basic/build.gradle.kts index a155d9d7..6246bf93 100644 --- a/integration-tests/gradle/projects/it-basic/build.gradle.kts +++ b/integration-tests/gradle/projects/it-basic/build.gradle.kts @@ -1,5 +1,7 @@ import org.jetbrains.dokka.gradle.DokkaTask import org.jetbrains.dokka.gradle.kotlinSourceSet +import org.jetbrains.dokka.base.DokkaBase +import org.jetbrains.dokka.base.DokkaBaseConfiguration import java.net.URL plugins { @@ -7,6 +9,12 @@ plugins { id("org.jetbrains.dokka") } +buildscript { + dependencies { + classpath("org.jetbrains.dokka:dokka-base:${System.getenv("DOKKA_VERSION")}") + } +} + version = "1.5-SNAPSHOT" apply(from = "../template.root.gradle.kts") @@ -40,4 +48,5 @@ tasks.withType<DokkaTask> { kotlinSourceSet(kotlin.sourceSets["test"]) } } + pluginsMapConfiguration.set(mapOf(DokkaBase::class.qualifiedName to """{ "customStyleSheets": ["${file("customResources/logo-styles.css")}", "${file("customResources/custom-style-to-add.css")}"], "customAssets" : ["${file("customResources/custom-resource.svg")}"] }""")) } diff --git a/integration-tests/gradle/projects/it-basic/customResources/custom-resource.svg b/integration-tests/gradle/projects/it-basic/customResources/custom-resource.svg new file mode 100644 index 00000000..1865f739 --- /dev/null +++ b/integration-tests/gradle/projects/it-basic/customResources/custom-resource.svg @@ -0,0 +1,3 @@ +<svg width="18" height="18" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg"> + <path d="M18 9C18 14 14 18 9 18C4 18 0 14 0 9C0 4 4 0 9 0C14 0 18 4 18 9ZM14.2 6.2L12.8 4.8L7.5 10.1L5.3 7.8L3.8 9.2L7.5 13L14.2 6.2Z" fill="#4DBB5F"/> +</svg>
\ No newline at end of file diff --git a/integration-tests/gradle/projects/it-basic/customResources/custom-style-to-add.css b/integration-tests/gradle/projects/it-basic/customResources/custom-style-to-add.css new file mode 100644 index 00000000..408c210e --- /dev/null +++ b/integration-tests/gradle/projects/it-basic/customResources/custom-style-to-add.css @@ -0,0 +1 @@ +/* custom stylesheet */
\ No newline at end of file diff --git a/integration-tests/gradle/projects/it-basic/customResources/logo-styles.css b/integration-tests/gradle/projects/it-basic/customResources/logo-styles.css new file mode 100644 index 00000000..2ac57218 --- /dev/null +++ b/integration-tests/gradle/projects/it-basic/customResources/logo-styles.css @@ -0,0 +1,3 @@ +#logo { + background-image: url('https://upload.wikimedia.org/wikipedia/commons/9/9d/Ubuntu_logo.svg'); +}
\ No newline at end of file diff --git a/integration-tests/gradle/src/integrationTest/kotlin/org/jetbrains/dokka/it/gradle/BasicGradleIntegrationTest.kt b/integration-tests/gradle/src/integrationTest/kotlin/org/jetbrains/dokka/it/gradle/BasicGradleIntegrationTest.kt index 46306078..9da67fc3 100644 --- a/integration-tests/gradle/src/integrationTest/kotlin/org/jetbrains/dokka/it/gradle/BasicGradleIntegrationTest.kt +++ b/integration-tests/gradle/src/integrationTest/kotlin/org/jetbrains/dokka/it/gradle/BasicGradleIntegrationTest.kt @@ -25,6 +25,8 @@ class BasicGradleIntegrationTest(override val versions: BuildVersions) : Abstrac .forEach { topLevelFile -> topLevelFile.copyTo(File(projectDir, topLevelFile.name)) } File(templateProjectDir, "src").copyRecursively(File(projectDir, "src")) + val customResourcesDir = File(templateProjectDir, "customResources") + if(customResourcesDir.exists() && customResourcesDir.isDirectory) customResourcesDir.copyRecursively(File(projectDir, "customResources")) } @Test @@ -116,6 +118,17 @@ class BasicGradleIntegrationTest(override val versions: BuildVersions) : Abstrac }, "Anchors should not have hashes inside" ) + + assertEquals( + """#logo{background-image:url('https://upload.wikimedia.org/wikipedia/commons/9/9d/Ubuntu_logo.svg');}""", + stylesDir.resolve("logo-styles.css").readText().replace("\\s".toRegex(), ""), + ) + assertTrue(stylesDir.resolve("custom-style-to-add.css").isFile) + assertEquals("""/* custom stylesheet */""", stylesDir.resolve("custom-style-to-add.css").readText()) + allHtmlFiles().forEach { file -> + if(file.name != "navigation.html") assertTrue("custom-style-to-add.css" in file.readText(), "custom styles not added to html file ${file.name}") + } + assertTrue(imagesDir.resolve("custom-resource.svg").isFile) } private fun File.assertJavadocOutputDir() { diff --git a/integration-tests/maven/projects/it-maven/customResources/custom-resource.svg b/integration-tests/maven/projects/it-maven/customResources/custom-resource.svg new file mode 100644 index 00000000..1865f739 --- /dev/null +++ b/integration-tests/maven/projects/it-maven/customResources/custom-resource.svg @@ -0,0 +1,3 @@ +<svg width="18" height="18" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg"> + <path d="M18 9C18 14 14 18 9 18C4 18 0 14 0 9C0 4 4 0 9 0C14 0 18 4 18 9ZM14.2 6.2L12.8 4.8L7.5 10.1L5.3 7.8L3.8 9.2L7.5 13L14.2 6.2Z" fill="#4DBB5F"/> +</svg>
\ No newline at end of file diff --git a/integration-tests/maven/projects/it-maven/customResources/custom-style-to-add.css b/integration-tests/maven/projects/it-maven/customResources/custom-style-to-add.css new file mode 100644 index 00000000..408c210e --- /dev/null +++ b/integration-tests/maven/projects/it-maven/customResources/custom-style-to-add.css @@ -0,0 +1 @@ +/* custom stylesheet */
\ No newline at end of file diff --git a/integration-tests/maven/projects/it-maven/customResources/logo-styles.css b/integration-tests/maven/projects/it-maven/customResources/logo-styles.css new file mode 100644 index 00000000..2ac57218 --- /dev/null +++ b/integration-tests/maven/projects/it-maven/customResources/logo-styles.css @@ -0,0 +1,3 @@ +#logo { + background-image: url('https://upload.wikimedia.org/wikipedia/commons/9/9d/Ubuntu_logo.svg'); +}
\ No newline at end of file diff --git a/integration-tests/maven/projects/it-maven/pom.xml b/integration-tests/maven/projects/it-maven/pom.xml index 80620c82..8bd5d956 100644 --- a/integration-tests/maven/projects/it-maven/pom.xml +++ b/integration-tests/maven/projects/it-maven/pom.xml @@ -137,6 +137,17 @@ <includeNonPublic>false</includeNonPublic> </packageOptions> </perPackageOptions> + <pluginsConfiguration> + <org.jetbrains.dokka.base.DokkaBase> + <customAssets> + <customAsset>${project.basedir}/customResources/custom-resource.svg</customAsset> + </customAssets> + <customStyleSheets> + <customStyleSheet>${project.basedir}/customResources/logo-styles.css</customStyleSheet> + <customStyleSheet>${project.basedir}/customResources/custom-style-to-add.css</customStyleSheet> + </customStyleSheets> + </org.jetbrains.dokka.base.DokkaBase> + </pluginsConfiguration> </configuration> </plugin> </plugins> diff --git a/integration-tests/maven/src/integrationTest/kotlin/org/jetbrains/dokka/it/maven/MavenIntegrationTest.kt b/integration-tests/maven/src/integrationTest/kotlin/org/jetbrains/dokka/it/maven/MavenIntegrationTest.kt index 88fdc207..be70fdb4 100644 --- a/integration-tests/maven/src/integrationTest/kotlin/org/jetbrains/dokka/it/maven/MavenIntegrationTest.kt +++ b/integration-tests/maven/src/integrationTest/kotlin/org/jetbrains/dokka/it/maven/MavenIntegrationTest.kt @@ -24,6 +24,10 @@ class MavenIntegrationTest : AbstractIntegrationTest() { pomXml.apply { writeText(readText().replace("\$dokka_version", currentDokkaVersion)) } + val customResourcesDir = File(templateProjectDir, "customResources") + if(customResourcesDir.exists() && customResourcesDir.isDirectory) { + customResourcesDir.copyRecursively(File(projectDir, "customResources"), overwrite = true) + } } @Test @@ -54,6 +58,17 @@ class MavenIntegrationTest : AbstractIntegrationTest() { assertNoEmptyLinks(file) assertNoEmptySpans(file) } + + assertEquals( + """#logo{background-image:url('https://upload.wikimedia.org/wikipedia/commons/9/9d/Ubuntu_logo.svg');}""", + stylesDir.resolve("logo-styles.css").readText().replace("\\s".toRegex(), ""), + ) + assertTrue(stylesDir.resolve("custom-style-to-add.css").isFile) + projectDir.allHtmlFiles().forEach { file -> + if(file.name != "navigation.html") assertTrue("custom-style-to-add.css" in file.readText(), "custom styles not added to html file ${file.name}") + } + assertEquals("""/* custom stylesheet */""", stylesDir.resolve("custom-style-to-add.css").readText()) + assertTrue(imagesDir.resolve("custom-resource.svg").isFile) } @Test diff --git a/plugins/base/src/main/kotlin/DokkaBase.kt b/plugins/base/src/main/kotlin/DokkaBase.kt index be3c09b9..e709b48b 100644 --- a/plugins/base/src/main/kotlin/DokkaBase.kt +++ b/plugins/base/src/main/kotlin/DokkaBase.kt @@ -198,10 +198,6 @@ class DokkaBase : DokkaPlugin() { htmlPreprocessors with NavigationPageInstaller order { after(rootCreator) } } - val searchPageInstaller by extending { - htmlPreprocessors with SearchPageInstaller order { after(rootCreator) } - } - val scriptsInstaller by extending { htmlPreprocessors with ScriptsInstaller order { after(rootCreator) } } @@ -214,6 +210,14 @@ class DokkaBase : DokkaPlugin() { htmlPreprocessors with AssetsInstaller order { after(rootCreator) } } + val customResourceInstaller by extending { + htmlPreprocessors providing { ctx -> CustomResourceInstaller(ctx) } order { + after(stylesInstaller) + after(scriptsInstaller) + after(assetsInstaller) + } + } + val packageListCreator by extending { htmlPreprocessors providing { PackageListCreator(it, RecognizedLinkFormat.DokkaHtml) diff --git a/plugins/base/src/main/kotlin/DokkaBaseConfiguration.kt b/plugins/base/src/main/kotlin/DokkaBaseConfiguration.kt new file mode 100644 index 00000000..c18b3446 --- /dev/null +++ b/plugins/base/src/main/kotlin/DokkaBaseConfiguration.kt @@ -0,0 +1,14 @@ +package org.jetbrains.dokka.base + +import org.jetbrains.dokka.plugability.ConfigurableBlock +import java.io.File + +data class DokkaBaseConfiguration( + var customStyleSheets: List<File> = defaultCustomStyleSheets, + var customAssets: List<File> = defaultCustomAssets +): ConfigurableBlock { + companion object { + val defaultCustomStyleSheets: List<File> = emptyList() + val defaultCustomAssets: List<File> = emptyList() + } +}
\ No newline at end of file diff --git a/plugins/base/src/main/kotlin/renderers/DefaultRenderer.kt b/plugins/base/src/main/kotlin/renderers/DefaultRenderer.kt index 5c0f54d8..f393c0fa 100644 --- a/plugins/base/src/main/kotlin/renderers/DefaultRenderer.kt +++ b/plugins/base/src/main/kotlin/renderers/DefaultRenderer.kt @@ -15,7 +15,6 @@ import org.jetbrains.dokka.plugability.plugin import org.jetbrains.dokka.plugability.querySingle import org.jetbrains.dokka.renderers.Renderer import org.jetbrains.dokka.transformers.pages.PageTransformer -import java.io.File abstract class DefaultRenderer<T>( protected val context: DokkaContext @@ -223,9 +222,4 @@ abstract class DefaultRenderer<T>( internal typealias SerializedBeforeAndAfter = Pair<String, String> internal typealias InstanceWithSource = Pair<ContentDivergentInstance, DisplaySourceSet> -fun ContentPage.sourceSets() = this.content.sourceSets - -fun ContentEmbeddedResource.isImage(): Boolean { - val imageExtensions = setOf("png", "jpg", "jpeg", "gif", "bmp", "tif", "webp", "svg") - return File(address).extension.toLowerCase() in imageExtensions -} +fun ContentPage.sourceSets() = this.content.sourceSets
\ No newline at end of file diff --git a/plugins/base/src/main/kotlin/renderers/FileWriter.kt b/plugins/base/src/main/kotlin/renderers/FileWriter.kt index cd38f1b9..f8c0e882 100644 --- a/plugins/base/src/main/kotlin/renderers/FileWriter.kt +++ b/plugins/base/src/main/kotlin/renderers/FileWriter.kt @@ -33,7 +33,7 @@ class FileWriter(val context: DokkaContext): OutputWriter { } override suspend fun writeResources(pathFrom: String, pathTo: String) = - if (javaClass.getResource(pathFrom).toURI().toString().startsWith(jarUriPrefix)) { + if (javaClass.getResource(pathFrom)?.toURI()?.toString()?.startsWith(jarUriPrefix) == true) { copyFromJar(pathFrom, pathTo) } else { copyFromDirectory(pathFrom, pathTo) @@ -42,9 +42,10 @@ class FileWriter(val context: DokkaContext): OutputWriter { private suspend fun copyFromDirectory(pathFrom: String, pathTo: String) { val dest = Paths.get(root.path, pathTo).toFile() - val uri = javaClass.getResource(pathFrom).toURI() + val uri = javaClass.getResource(pathFrom)?.toURI() + val file = uri?.let { File(it) } ?: File(pathFrom) withContext(Dispatchers.IO) { - File(uri).copyRecursively(dest, true) + file.copyRecursively(dest, true) } } @@ -52,7 +53,11 @@ class FileWriter(val context: DokkaContext): OutputWriter { val rebase = fun(path: String) = "$pathTo/${path.removePrefix(pathFrom)}" val dest = Paths.get(root.path, pathTo).toFile() - dest.mkdirsOrFail() + if(dest.isDirectory){ + dest.mkdirsOrFail() + } else { + dest.parentFile.mkdirsOrFail() + } val uri = javaClass.getResource(pathFrom).toURI() val fs = getFileSystemForURI(uri) val path = fs.getPath(pathFrom) diff --git a/plugins/base/src/main/kotlin/renderers/contentTypeChecking.kt b/plugins/base/src/main/kotlin/renderers/contentTypeChecking.kt new file mode 100644 index 00000000..4619bc53 --- /dev/null +++ b/plugins/base/src/main/kotlin/renderers/contentTypeChecking.kt @@ -0,0 +1,16 @@ +package org.jetbrains.dokka.base.renderers + +import org.jetbrains.dokka.base.renderers.HtmlFileExtensions.imageExtensions +import org.jetbrains.dokka.pages.ContentEmbeddedResource +import java.io.File + +fun ContentEmbeddedResource.isImage(): Boolean { + return File(address).extension.toLowerCase() in imageExtensions +} + +fun String.isImage(): Boolean = + substringBefore('?').substringAfterLast('.') in imageExtensions + +object HtmlFileExtensions { + val imageExtensions = setOf("png", "jpg", "jpeg", "gif", "bmp", "tif", "webp", "svg") +}
\ No newline at end of file diff --git a/plugins/base/src/main/kotlin/renderers/html/HtmlRenderer.kt b/plugins/base/src/main/kotlin/renderers/html/HtmlRenderer.kt index 6bdeae62..7a047d3c 100644 --- a/plugins/base/src/main/kotlin/renderers/html/HtmlRenderer.kt +++ b/plugins/base/src/main/kotlin/renderers/html/HtmlRenderer.kt @@ -679,10 +679,10 @@ open class HtmlRenderer( ) { async = true } + it.isImage() -> link(href = page.root(it)) else -> unsafe { +it } } } - link(rel = LinkRel.stylesheet, href = page.root("styles/main.css")) {} script { unsafe { +"""var pathToRoot = "${locationProvider.pathToRoot(page)}";""" } } } body { diff --git a/plugins/base/src/main/kotlin/renderers/html/htmlPreprocessors.kt b/plugins/base/src/main/kotlin/renderers/html/htmlPreprocessors.kt index a5fca92f..a87254ce 100644 --- a/plugins/base/src/main/kotlin/renderers/html/htmlPreprocessors.kt +++ b/plugins/base/src/main/kotlin/renderers/html/htmlPreprocessors.kt @@ -7,6 +7,9 @@ import kotlinx.html.h1 import kotlinx.html.id import kotlinx.html.table import kotlinx.html.tbody +import org.jetbrains.dokka.DokkaConfiguration +import org.jetbrains.dokka.base.DokkaBase +import org.jetbrains.dokka.base.DokkaBaseConfiguration import org.jetbrains.dokka.base.renderers.sourceSets import org.jetbrains.dokka.links.DRI import org.jetbrains.dokka.model.DEnum @@ -14,30 +17,9 @@ import org.jetbrains.dokka.model.DEnumEntry import org.jetbrains.dokka.model.withDescendants import org.jetbrains.dokka.pages.* import org.jetbrains.dokka.plugability.DokkaContext +import org.jetbrains.dokka.plugability.configuration import org.jetbrains.dokka.transformers.pages.PageTransformer - -object SearchPageInstaller : PageTransformer { - override fun invoke(input: RootPageNode) = input.modified(children = input.children + searchPage) - - private val searchPage = RendererSpecificResourcePage( - name = "Search", - children = emptyList(), - strategy = RenderingStrategy<HtmlRenderer> { - buildHtml(it, listOf("styles/style.css", "scripts/pages.js", "scripts/search.js")) { - h1 { - id = "searchTitle" - text("Search results for ") - } - table { - tbody { - id = "searchTable" - } - } - } - }) -} - object NavigationPageInstaller : PageTransformer { private val mapper = jacksonObjectMapper() @@ -89,56 +71,79 @@ object NavigationPageInstaller : PageTransformer { }.sortedBy { it.name.toLowerCase() } } +class CustomResourceInstaller(val dokkaContext: DokkaContext) : PageTransformer { + private val configuration = configuration<DokkaBase, DokkaBaseConfiguration>(dokkaContext) + + private val customAssets = configuration?.customAssets?.map { + RendererSpecificResourcePage("images/${it.name}", emptyList(), RenderingStrategy.Copy(it.absolutePath)) + }.orEmpty() + + private val customStylesheets = configuration?.customStyleSheets?.map { + RendererSpecificResourcePage("styles/${it.name}", emptyList(), RenderingStrategy.Copy(it.absolutePath)) + }.orEmpty() + + override fun invoke(input: RootPageNode): RootPageNode { + val customResourcesPaths = (customAssets + customStylesheets).map { it.name }.toSet() + val withEmbeddedResources = input.transformContentPagesTree { it.modified(embeddedResources = it.embeddedResources + customResourcesPaths) } + val (currentResources, otherPages) = withEmbeddedResources.children.partition { it is RendererSpecificResourcePage } + return input.modified(children = otherPages + currentResources.filterNot { it.name in customResourcesPaths } + customAssets + customStylesheets) + } +} + object ScriptsInstaller : PageTransformer { + private val scriptsPages = listOf( + "scripts/clipboard.js", + "scripts/navigation-loader.js", + "scripts/platform-content-handler.js", + "scripts/main.js" + ) + override fun invoke(input: RootPageNode): RootPageNode { return input.modified( - children = input.children + RendererSpecificResourcePage( - "scripts", - emptyList(), - RenderingStrategy.Copy("/dokka/scripts") - ) + children = input.children + scriptsPages.toRenderSpecificResourcePage() ).transformContentPagesTree { it.modified( - embeddedResources = it.embeddedResources + listOf( - "scripts/navigationLoader.js", - "scripts/platformContentHandler.js", - "scripts/sourceset_dependencies.js", - "scripts/clipboard.js", - ) + embeddedResources = it.embeddedResources + scriptsPages ) } } } object StylesInstaller : PageTransformer { + private val stylesPages = listOf( + "styles/style.css", + "styles/logo-styles.css", + "styles/jetbrains-mono.css", + "styles/main.css" + ) + override fun invoke(input: RootPageNode): RootPageNode = input.modified( - children = input.children + RendererSpecificResourcePage( - "styles", - emptyList(), - RenderingStrategy.Copy("/dokka/styles") - ) + children = input.children + stylesPages.toRenderSpecificResourcePage() ).transformContentPagesTree { it.modified( - embeddedResources = it.embeddedResources + listOf( - "styles/style.css", - "styles/jetbrains-mono.css" - ) + embeddedResources = it.embeddedResources + stylesPages ) } } object AssetsInstaller : PageTransformer { + private val imagesPages = listOf( + "images/arrow_down.svg", + "images/docs_logo.svg", + "images/logo-icon.svg" + ) + override fun invoke(input: RootPageNode) = input.modified( - children = input.children + RendererSpecificResourcePage( - "images", - emptyList(), - RenderingStrategy.Copy("/dokka/images") - ) + children = input.children + imagesPages.toRenderSpecificResourcePage() ) } +private fun List<String>.toRenderSpecificResourcePage(): List<RendererSpecificResourcePage> = + map { RendererSpecificResourcePage(it, emptyList(), RenderingStrategy.Copy("/dokka/$it")) } + class SourcesetDependencyAppender(val context: DokkaContext) : PageTransformer { + private val name = "scripts/sourceset_dependencies.js" override fun invoke(input: RootPageNode): RootPageNode { val dependenciesMap = context.configuration.sourceSets.map { it.sourceSetID to it.dependentSourceSets @@ -155,14 +160,14 @@ class SourcesetDependencyAppender(val context: DokkaContext) : PageTransformer { }}'" val deps = RendererSpecificResourcePage( - name = "scripts/sourceset_dependencies.js", + name = name, children = emptyList(), strategy = RenderingStrategy.Write(createDependenciesJson()) ) return input.modified( children = input.children + deps - ) + ).transformContentPagesTree { it.modified(embeddedResources = it.embeddedResources + name) } } } diff --git a/plugins/base/src/main/resources/dokka/images/logo-text.svg b/plugins/base/src/main/resources/dokka/images/logo-text.svg deleted file mode 100755 index 7bf3e6c5..00000000 --- a/plugins/base/src/main/resources/dokka/images/logo-text.svg +++ /dev/null @@ -1,6 +0,0 @@ -<svg width="83" height="27" viewBox="0 0 83 27" fill="none" xmlns="http://www.w3.org/2000/svg"> -<path d="M47.1611 7.6297V25.6345V25.6867H61.8428V21.8039H51.3589V10.3852H61.8428V6.50244H47.1611V7.6297Z" fill="#27282C"/> -<path d="M82.9891 21.8039L72.778 10.3852H82.9051V6.50244H67.0586V10.3852L77.4585 21.8039H67.0586V25.6867H82.9996V21.8039H82.9891Z" fill="#27282C"/> -<path d="M16.2978 7.76556C14.5872 6.46086 12.4463 5.67804 10.1271 5.67804C4.53357 5.67804 0 10.1871 0 15.7503C0 21.3135 4.53357 25.8226 10.1271 25.8226C12.4463 25.8226 14.5872 25.0502 16.2978 23.735V25.7182H20.4955V0H16.2978V7.76556ZM10.1271 21.8041C6.75838 21.8041 4.02984 19.0903 4.02984 15.7399C4.02984 12.3894 6.75838 9.67563 10.1271 9.67563C13.4958 9.67563 16.2243 12.3894 16.2243 15.7399C16.2138 19.0903 13.4853 21.8041 10.1271 21.8041Z" fill="#27282C"/> -<path d="M33.9703 5.86566C28.3768 5.86566 23.8433 10.3747 23.8433 15.9379C23.8433 21.5011 28.3768 26.0102 33.9703 26.0102C39.5638 26.0102 44.0974 21.5011 44.0974 15.9379C44.0974 10.3747 39.5638 5.86566 33.9703 5.86566ZM33.9703 21.9917C30.6016 21.9917 27.8731 19.2779 27.8731 15.9275C27.8731 12.577 30.6016 9.86325 33.9703 9.86325C37.339 9.86325 40.0676 12.577 40.0676 15.9275C40.0676 19.2779 37.339 21.9917 33.9703 21.9917Z" fill="#27282C"/> -</svg> diff --git a/plugins/base/src/main/resources/dokka/scripts/navigationLoader.js b/plugins/base/src/main/resources/dokka/scripts/navigation-loader.js index c2f60ec5..c2f60ec5 100644 --- a/plugins/base/src/main/resources/dokka/scripts/navigationLoader.js +++ b/plugins/base/src/main/resources/dokka/scripts/navigation-loader.js diff --git a/plugins/base/src/main/resources/dokka/scripts/platformContentHandler.js b/plugins/base/src/main/resources/dokka/scripts/platform-content-handler.js index 022aca4f..022aca4f 100644 --- a/plugins/base/src/main/resources/dokka/scripts/platformContentHandler.js +++ b/plugins/base/src/main/resources/dokka/scripts/platform-content-handler.js diff --git a/plugins/base/src/main/resources/dokka/scripts/search.js b/plugins/base/src/main/resources/dokka/scripts/search.js deleted file mode 100644 index 04d88ab5..00000000 --- a/plugins/base/src/main/resources/dokka/scripts/search.js +++ /dev/null @@ -1,7 +0,0 @@ -let query = new URLSearchParams(window.location.search).get("query"); -document.getElementById("searchTitle").innerHTML += '"' + query + '":'; -document.getElementById("searchTable").innerHTML = pages - .filter(el => el.name.toLowerCase().startsWith(query.toLowerCase())) - .reduce((acc, element) => { - return acc + '<tr><td><a href="' + element.location + '">' + element.name + '</a></td></tr>' - }, "");
\ No newline at end of file diff --git a/plugins/base/src/main/resources/dokka/styles/logo-styles.css b/plugins/base/src/main/resources/dokka/styles/logo-styles.css new file mode 100644 index 00000000..a3a07d75 --- /dev/null +++ b/plugins/base/src/main/resources/dokka/styles/logo-styles.css @@ -0,0 +1,3 @@ +#logo { + background-image: url(../images/docs_logo.svg); +}
\ No newline at end of file diff --git a/plugins/base/src/main/resources/dokka/styles/style.css b/plugins/base/src/main/resources/dokka/styles/style.css index 24fd8fa3..7c1b2803 100644 --- a/plugins/base/src/main/resources/dokka/styles/style.css +++ b/plugins/base/src/main/resources/dokka/styles/style.css @@ -191,7 +191,6 @@ background-size: 125px 26px; border-bottom: 1px solid #DADFE6; background-repeat: no-repeat; - background-image: url(../images/docs_logo.svg); background-origin: content-box; padding-left: 24px; padding-top: 24px; diff --git a/runners/cli/src/main/kotlin/cli/main.kt b/runners/cli/src/main/kotlin/cli/main.kt index a1139e65..681ebfa6 100644 --- a/runners/cli/src/main/kotlin/cli/main.kt +++ b/runners/cli/src/main/kotlin/cli/main.kt @@ -46,7 +46,7 @@ class GlobalArguments(args: Array<String>) : DokkaConfiguration { override val pluginsConfiguration by parser.option( ArgTypePlugin, description = "Configuration for plugins in format fqPluginName=json^^fqPluginName=json..." - ).default(emptyMap()) + ).delimiter("^^") override val pluginsClasspath by parser.option( ArgTypeFile, @@ -254,16 +254,22 @@ object ArgTypeFile : ArgType<File>(true) { object ArgTypePlatform : ArgType<Platform>(true) { override fun convert(value: kotlin.String, name: kotlin.String): Platform = Platform.fromString(value) override val description: kotlin.String - get() = "{ String thar represents paltform }" + get() = "{ String that represents platform }" } -object ArgTypePlugin : ArgType<Map<String, String>>(true) { - override fun convert(value: kotlin.String, name: kotlin.String): Map<kotlin.String, kotlin.String> = - value.split("^^").map { - it.split("=").let { - it[0] to it[1] - } - }.toMap() +object ArgTypePlugin : ArgType<DokkaConfiguration.PluginConfiguration>(true) { + override fun convert( + value: kotlin.String, + name: kotlin.String + ): DokkaConfiguration.PluginConfiguration { + return value.split("=").let { + PluginConfigurationImpl( + fqPluginName = it[0], + serializationFormat = DokkaConfiguration.SerializationFormat.JSON, + values = it[1] + ) + } + } override val description: kotlin.String get() = "{ String fqName=json, remember to escape `\"` inside json }" diff --git a/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/AbstractDokkaTask.kt b/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/AbstractDokkaTask.kt index 9dab1f04..77b4b2e1 100644 --- a/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/AbstractDokkaTask.kt +++ b/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/AbstractDokkaTask.kt @@ -8,17 +8,19 @@ import org.gradle.api.DefaultTask import org.gradle.api.Task import org.gradle.api.artifacts.Configuration import org.gradle.api.plugins.JavaBasePlugin +import org.gradle.api.provider.ListProperty import org.gradle.api.provider.MapProperty import org.gradle.api.provider.Property import org.gradle.api.tasks.* +import org.gradle.kotlin.dsl.listProperty import org.gradle.kotlin.dsl.mapProperty -import org.jetbrains.dokka.DokkaBootstrap -import org.jetbrains.dokka.DokkaConfigurationImpl -import org.jetbrains.dokka.DokkaDefaults -import org.jetbrains.dokka.toJsonString +import org.jetbrains.dokka.* +import org.jetbrains.dokka.plugability.ConfigurableBlock +import org.jetbrains.dokka.plugability.DokkaPlugin import java.io.File import java.util.function.BiConsumer import kotlin.reflect.KClass +import kotlin.reflect.full.createInstance abstract class AbstractDokkaTask( private val bootstrapClass: KClass<out DokkaBootstrap> = DokkaBootstrap::class @@ -49,7 +51,23 @@ abstract class AbstractDokkaTask( .safeConvention(DokkaDefaults.offlineMode) @Input - val pluginsConfiguration: MapProperty<String, String> = project.objects.mapProperty() + val pluginsConfiguration: ListProperty<in DokkaConfiguration.PluginConfiguration> = project.objects.listProperty() + + /** + * Used to keep compatibility with gradle using Kotlin lower than 1.3.50 + */ + @Input + val pluginsMapConfiguration: MapProperty<String, String> = project.objects.mapProperty() + + inline fun <reified P : DokkaPlugin, reified T : ConfigurableBlock> pluginConfiguration(block: T.() -> Unit) { + val instance = T::class.createInstance().apply(block) + val pluginConfiguration = PluginConfigurationImpl( + fqPluginName = P::class.qualifiedName!!, + serializationFormat = DokkaConfiguration.SerializationFormat.JSON, + values = instance.toJsonString() + ) + pluginsConfiguration.add(pluginConfiguration) + } @Classpath val plugins: Configuration = project.maybeCreateDokkaPluginConfiguration(name) @@ -84,4 +102,15 @@ abstract class AbstractDokkaTask( init { group = JavaBasePlugin.DOCUMENTATION_GROUP } + + internal fun buildPluginsConfiguration(): List<PluginConfigurationImpl> { + val manuallyConfigured = pluginsMapConfiguration.getSafe().entries.map { entry -> + PluginConfigurationImpl( + entry.key, + DokkaConfiguration.SerializationFormat.JSON, + entry.value + ) + } + return pluginsConfiguration.getSafe().mapNotNull { it as? PluginConfigurationImpl } + manuallyConfigured + } } diff --git a/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/DokkaCollectorTask.kt b/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/DokkaCollectorTask.kt index cd53398a..b0fc5f22 100644 --- a/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/DokkaCollectorTask.kt +++ b/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/DokkaCollectorTask.kt @@ -17,6 +17,7 @@ abstract class DokkaCollectorTask : AbstractDokkaParentTask() { failOnWarning = failOnWarning.getSafe(), offlineMode = offlineMode.getSafe(), pluginsClasspath = plugins.resolve().toList(), + pluginsConfiguration = buildPluginsConfiguration() ) val subprojectDokkaConfigurations = childDokkaTasks.map { dokkaTask -> dokkaTask.buildDokkaConfiguration() } diff --git a/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/DokkaMultiModuleTask.kt b/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/DokkaMultiModuleTask.kt index 92560c94..03e0b4d7 100644 --- a/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/DokkaMultiModuleTask.kt +++ b/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/DokkaMultiModuleTask.kt @@ -6,6 +6,7 @@ import org.gradle.api.tasks.* import org.jetbrains.dokka.DokkaConfigurationImpl import org.jetbrains.dokka.DokkaModuleDescriptionImpl import org.jetbrains.dokka.DokkaMultimoduleBootstrapImpl +import org.jetbrains.dokka.PluginConfigurationImpl import java.io.File @Suppress("unused") // Shall provide source compatibility if possible @@ -49,7 +50,7 @@ abstract class DokkaMultiModuleTask : AbstractDokkaParentTask(DokkaMultimoduleBo moduleName = moduleName.getSafe(), outputDir = outputDirectory.getSafe(), cacheRoot = cacheRoot.getSafe(), - pluginsConfiguration = pluginsConfiguration.getSafe(), + pluginsConfiguration = buildPluginsConfiguration(), failOnWarning = failOnWarning.getSafe(), offlineMode = offlineMode.getSafe(), pluginsClasspath = plugins.resolve().toList(), diff --git a/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/DokkaTask.kt b/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/DokkaTask.kt index ed3989af..9944bacb 100644 --- a/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/DokkaTask.kt +++ b/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/DokkaTask.kt @@ -4,9 +4,7 @@ import org.gradle.api.NamedDomainObjectContainer import org.gradle.api.internal.plugins.DslObject import org.gradle.api.tasks.Internal import org.gradle.api.tasks.Nested -import org.jetbrains.dokka.DokkaBootstrapImpl -import org.jetbrains.dokka.DokkaConfigurationImpl -import org.jetbrains.dokka.build +import org.jetbrains.dokka.* abstract class DokkaTask : AbstractDokkaTask(DokkaBootstrapImpl::class) { @@ -34,8 +32,8 @@ abstract class DokkaTask : AbstractDokkaTask(DokkaBootstrapImpl::class) { .also(::checkSourceSetDependencies) .filterNot { it.suppress.getSafe() } - override fun buildDokkaConfiguration(): DokkaConfigurationImpl { - return DokkaConfigurationImpl( + override fun buildDokkaConfiguration(): DokkaConfigurationImpl = + DokkaConfigurationImpl( moduleName = moduleName.getSafe(), moduleVersion = moduleVersion.orNull, outputDir = outputDirectory.getSafe(), @@ -43,8 +41,7 @@ abstract class DokkaTask : AbstractDokkaTask(DokkaBootstrapImpl::class) { offlineMode = offlineMode.getSafe(), failOnWarning = failOnWarning.getSafe(), sourceSets = unsuppressedSourceSets.build(), - pluginsConfiguration = pluginsConfiguration.getSafe(), + pluginsConfiguration = buildPluginsConfiguration(), pluginsClasspath = plugins.resolve().toList() ) - } } diff --git a/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/utils.kt b/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/utils.kt index 14b2a045..1c0c8080 100644 --- a/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/utils.kt +++ b/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/utils.kt @@ -7,7 +7,6 @@ import org.gradle.api.provider.HasMultipleValues import org.gradle.api.provider.Property import org.gradle.api.provider.Provider import org.gradle.util.Path -import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension import org.jetbrains.kotlin.gradle.dsl.KotlinProjectExtension import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType import org.jetbrains.kotlin.gradle.plugin.KotlinTarget diff --git a/runners/gradle-plugin/src/test/kotlin/org/jetbrains/dokka/gradle/DokkaConfigurationJsonTest.kt b/runners/gradle-plugin/src/test/kotlin/org/jetbrains/dokka/gradle/DokkaConfigurationJsonTest.kt index d1bfb0e1..68506876 100644 --- a/runners/gradle-plugin/src/test/kotlin/org/jetbrains/dokka/gradle/DokkaConfigurationJsonTest.kt +++ b/runners/gradle-plugin/src/test/kotlin/org/jetbrains/dokka/gradle/DokkaConfigurationJsonTest.kt @@ -25,8 +25,8 @@ class DokkaConfigurationJsonTest { this.offlineMode by true this.outputDirectory by File("customOutputDir") this.cacheRoot by File("customCacheRoot") - this.pluginsConfiguration.put("0", "a") - this.pluginsConfiguration.put("1", "b") + this.pluginsConfiguration.add(PluginConfigurationImpl("A", DokkaConfiguration.SerializationFormat.JSON, """ { "key" : "value1" } """)) + this.pluginsConfiguration.add(PluginConfigurationImpl("B", DokkaConfiguration.SerializationFormat.JSON, """ { "key" : "value2" } """)) this.dokkaSourceSets.create("main") { sourceSet -> sourceSet.displayName by "customSourceSetDisplayName" sourceSet.reportUndocumented by true diff --git a/runners/gradle-plugin/src/test/kotlin/org/jetbrains/dokka/gradle/DokkaConfigurationSerializableTest.kt b/runners/gradle-plugin/src/test/kotlin/org/jetbrains/dokka/gradle/DokkaConfigurationSerializableTest.kt index 99fca12d..2887f957 100644 --- a/runners/gradle-plugin/src/test/kotlin/org/jetbrains/dokka/gradle/DokkaConfigurationSerializableTest.kt +++ b/runners/gradle-plugin/src/test/kotlin/org/jetbrains/dokka/gradle/DokkaConfigurationSerializableTest.kt @@ -3,6 +3,7 @@ package org.jetbrains.dokka.gradle import org.gradle.kotlin.dsl.withType import org.gradle.testfixtures.ProjectBuilder import org.jetbrains.dokka.DokkaConfiguration +import org.jetbrains.dokka.PluginConfigurationImpl import org.jetbrains.dokka.toJsonString import org.junit.Rule import org.junit.rules.TemporaryFolder @@ -32,8 +33,8 @@ class DokkaConfigurationSerializableTest { this.offlineMode by true this.outputDirectory by File("customOutputDir") this.cacheRoot by File("customCacheRoot") - this.pluginsConfiguration.put("0", "a") - this.pluginsConfiguration.put("1", "b") + this.pluginsConfiguration.add(PluginConfigurationImpl("A", DokkaConfiguration.SerializationFormat.JSON, """ { "key" : "value1" } """)) + this.pluginsConfiguration.add(PluginConfigurationImpl("B", DokkaConfiguration.SerializationFormat.JSON, """ { "key" : "value2" } """)) this.dokkaSourceSets.create("main") { sourceSet -> sourceSet.displayName by "customSourceSetDisplayName" sourceSet.reportUndocumented by true diff --git a/runners/gradle-plugin/src/test/kotlin/org/jetbrains/dokka/gradle/DokkaMultiModuleTaskTest.kt b/runners/gradle-plugin/src/test/kotlin/org/jetbrains/dokka/gradle/DokkaMultiModuleTaskTest.kt index bea80f1e..fd449346 100644 --- a/runners/gradle-plugin/src/test/kotlin/org/jetbrains/dokka/gradle/DokkaMultiModuleTaskTest.kt +++ b/runners/gradle-plugin/src/test/kotlin/org/jetbrains/dokka/gradle/DokkaMultiModuleTaskTest.kt @@ -4,9 +4,7 @@ package org.jetbrains.dokka.gradle import org.gradle.kotlin.dsl.* import org.gradle.testfixtures.ProjectBuilder -import org.jetbrains.dokka.DokkaConfigurationImpl -import org.jetbrains.dokka.DokkaException -import org.jetbrains.dokka.DokkaModuleDescriptionImpl +import org.jetbrains.dokka.* import java.io.File import kotlin.test.Test import kotlin.test.assertEquals @@ -68,7 +66,7 @@ class DokkaMultiModuleTaskTest { moduleName by "custom Module Name" outputDirectory by project.buildDir.resolve("customOutputDirectory") cacheRoot by File("customCacheRoot") - pluginsConfiguration.put("pluginA", "configA") + pluginsConfiguration.add(PluginConfigurationImpl("pluginA", DokkaConfiguration.SerializationFormat.JSON, """ { "key" : "value2" } """)) failOnWarning by true offlineMode by true } @@ -79,7 +77,7 @@ class DokkaMultiModuleTaskTest { moduleName = "custom Module Name", outputDir = multiModuleTask.project.buildDir.resolve("customOutputDirectory"), cacheRoot = File("customCacheRoot"), - pluginsConfiguration = mapOf("pluginA" to "configA"), + pluginsConfiguration = mutableListOf(PluginConfigurationImpl("pluginA", DokkaConfiguration.SerializationFormat.JSON, """ { "key" : "value2" } """)), pluginsClasspath = emptyList(), failOnWarning = true, offlineMode = true, diff --git a/runners/maven-plugin/src/main/kotlin/DokkaMojo.kt b/runners/maven-plugin/src/main/kotlin/DokkaMojo.kt index 89928b4c..b03d2811 100644 --- a/runners/maven-plugin/src/main/kotlin/DokkaMojo.kt +++ b/runners/maven-plugin/src/main/kotlin/DokkaMojo.kt @@ -12,6 +12,7 @@ import org.apache.maven.project.MavenProjectHelper import org.apache.maven.repository.internal.MavenRepositorySystemUtils import org.codehaus.plexus.archiver.Archiver import org.codehaus.plexus.archiver.jar.JarArchiver +import org.codehaus.plexus.util.xml.Xpp3Dom import org.eclipse.aether.DefaultRepositorySystemSession import org.eclipse.aether.RepositorySystem import org.eclipse.aether.RepositorySystemSession @@ -224,6 +225,16 @@ abstract class AbstractDokkaMojo(private val defaultDokkaPlugins: List<Dependenc val logger = MavenDokkaLogger(log) + val pluginsConfiguration = + (mavenProject?.getPlugin("org.jetbrains.dokka:dokka-maven-plugin")?.configuration as? Xpp3Dom) + ?.getChild("pluginsConfiguration")?.children?.map { + PluginConfigurationImpl( + it.name, + DokkaConfiguration.SerializationFormat.XML, + it.toString() + ) + }.orEmpty() + val configuration = DokkaConfigurationImpl( moduleName = moduleName, outputDir = File(getOutDir()), @@ -233,9 +244,9 @@ abstract class AbstractDokkaMojo(private val defaultDokkaPlugins: List<Dependenc pluginsClasspath = getArtifactByAether("org.jetbrains.dokka", "dokka-base", dokkaVersion) + dokkaPlugins.map { getArtifactByAether(it.groupId, it.artifactId, it.version ?: dokkaVersion) } .flatten(), - pluginsConfiguration = mutableMapOf(), //TODO implement as it is in Gradle + pluginsConfiguration = pluginsConfiguration.toMutableList(), modules = emptyList(), - failOnWarning = failOnWarning + failOnWarning = failOnWarning, ) val gen = DokkaGenerator(configuration, logger) |