From 5e3cbb34b229728da45886822c58e33a1750a2dd Mon Sep 17 00:00:00 2001 From: aSemy <897017+aSemy@users.noreply.github.com> Date: Thu, 16 Mar 2023 22:45:07 +0100 Subject: [PATCH] Improve Dokka plugin parameters DSL (#36) * dokka plugin parameters DSL - remove the old DokkaPluginConfigurationSpec, replace with a base plugin config class, DokkaPluginParametersBaseSpec - create specific config classes for the Versioning and HTML plugins. - create a plugin config class for dynamically creating plugin config. --- .../dokkatoo/build.gradle.kts | 25 +- .../it-basic/dokkatoo/build.gradle.kts | 27 +- .../dokkatoo-plugin/api/dokkatoo-plugin.api | 142 +++++++++-- .../src/main/kotlin/DokkatooBasePlugin.kt | 6 - .../src/main/kotlin/DokkatooExtension.kt | 22 +- .../src/main/kotlin/dokka/DokkaPublication.kt | 16 +- .../DokkaPluginConfigurationSpec.kt | 58 ----- .../plugins/DokkaHtmlPluginParameters.kt | 115 +++++++++ .../plugins/DokkaPluginParametersBaseSpec.kt | 44 ++++ .../plugins/DokkaPluginParametersBuilder.kt | 233 ++++++++++++++++++ .../DokkaVersioningPluginParameters.kt | 101 ++++++++ .../kotlin/formats/DokkatooFormatPlugin.kt | 26 +- .../main/kotlin/formats/DokkatooHtmlPlugin.kt | 31 ++- .../main/kotlin/internal/gradleTypealiases.kt | 19 ++ .../src/main/kotlin/internal/gradleUtils.kt | 16 +- .../internal/kotlinxSerializationUtils.kt | 33 +++ .../tasks/DokkatooPrepareParametersTask.kt | 27 +- .../src/main/kotlin/tasks/DokkatooTask.kt | 1 - 18 files changed, 779 insertions(+), 163 deletions(-) delete mode 100644 modules/dokkatoo-plugin/src/main/kotlin/dokka/parameters/DokkaPluginConfigurationSpec.kt create mode 100644 modules/dokkatoo-plugin/src/main/kotlin/dokka/plugins/DokkaHtmlPluginParameters.kt create mode 100644 modules/dokkatoo-plugin/src/main/kotlin/dokka/plugins/DokkaPluginParametersBaseSpec.kt create mode 100644 modules/dokkatoo-plugin/src/main/kotlin/dokka/plugins/DokkaPluginParametersBuilder.kt create mode 100644 modules/dokkatoo-plugin/src/main/kotlin/dokka/plugins/DokkaVersioningPluginParameters.kt create mode 100644 modules/dokkatoo-plugin/src/main/kotlin/internal/gradleTypealiases.kt create mode 100644 modules/dokkatoo-plugin/src/main/kotlin/internal/kotlinxSerializationUtils.kt diff --git a/examples/custom-format-example/dokkatoo/build.gradle.kts b/examples/custom-format-example/dokkatoo/build.gradle.kts index 066689cc..1910423c 100644 --- a/examples/custom-format-example/dokkatoo/build.gradle.kts +++ b/examples/custom-format-example/dokkatoo/build.gradle.kts @@ -1,3 +1,5 @@ +import dev.adamko.dokkatoo.dokka.plugins.DokkaHtmlPluginParameters + plugins { kotlin("jvm") version "1.7.20" id("dev.adamko.dokkatoo") version "0.0.5-SNAPSHOT" @@ -5,23 +7,10 @@ plugins { dokkatoo { moduleName.set("customFormat-example") - dokkatooPublications.named("html") { -// dokkatooPublications.configureEach { - pluginsConfiguration.create("org.jetbrains.dokka.base.DokkaBase") { - /** Custom format adds a custom logo */ - values.set( - """ - { - "customStyleSheets": [ - "${file("logo-styles.css").invariantSeparatorsPath}" - ], - "customAssets": [ - "${file("ktor-logo.png").invariantSeparatorsPath}" - ], - "footerMessage": "(c) Custom Format Dokka example" - } - """.trimIndent() - ) - } + pluginsConfiguration.named("html") { + // Custom format adds a custom logo + customStyleSheets.from("logo-styles.css") + customAssets.from("ktor-logo.png") + footerMessage.set("(c) Custom Format Dokka example") } } diff --git a/modules/dokkatoo-plugin-integration-tests/projects/it-basic/dokkatoo/build.gradle.kts b/modules/dokkatoo-plugin-integration-tests/projects/it-basic/dokkatoo/build.gradle.kts index 3dd1308a..110a4486 100644 --- a/modules/dokkatoo-plugin-integration-tests/projects/it-basic/dokkatoo/build.gradle.kts +++ b/modules/dokkatoo-plugin-integration-tests/projects/it-basic/dokkatoo/build.gradle.kts @@ -1,4 +1,5 @@ import dev.adamko.dokkatoo.dokka.parameters.VisibilityModifier +import dev.adamko.dokkatoo.dokka.plugins.DokkaHtmlPluginParameters plugins { kotlin("jvm") version "1.7.20" @@ -39,23 +40,19 @@ dokkatoo { ) } } + + pluginsConfiguration.named("html") { + customStyleSheets.from( + "./customResources/logo-styles.css", + "./customResources/custom-style-to-add.css", + ) + customAssets.from( + "./customResources/custom-resource.svg", + ) + } + dokkatooPublications.configureEach { suppressObviousFunctions.set(true) - pluginsConfiguration.create("org.jetbrains.dokka.base.DokkaBase") { - values.set( - """ - { - "customStyleSheets": [ - "${file("./customResources/logo-styles.css").invariantSeparatorsPath}", - "${file("./customResources/custom-style-to-add.css").invariantSeparatorsPath}" - ], - "customAssets": [ - "${file("./customResources/custom-resource.svg").invariantSeparatorsPath}" - ] - } - """.trimIndent() - ) - } suppressObviousFunctions.set(false) } } diff --git a/modules/dokkatoo-plugin/api/dokkatoo-plugin.api b/modules/dokkatoo-plugin/api/dokkatoo-plugin.api index 87165906..990e1240 100644 --- a/modules/dokkatoo-plugin/api/dokkatoo-plugin.api +++ b/modules/dokkatoo-plugin/api/dokkatoo-plugin.api @@ -16,11 +16,12 @@ public abstract class dev/adamko/dokkatoo/DokkatooExtension : java/io/Serializab public abstract fun getDokkatooConfigurationsDirectory ()Lorg/gradle/api/file/DirectoryProperty; public abstract fun getDokkatooModuleDirectory ()Lorg/gradle/api/file/DirectoryProperty; public abstract fun getDokkatooPublicationDirectory ()Lorg/gradle/api/file/DirectoryProperty; - public abstract fun getDokkatooPublications ()Lorg/gradle/api/NamedDomainObjectContainer; + public final fun getDokkatooPublications ()Lorg/gradle/api/NamedDomainObjectContainer; public abstract fun getDokkatooSourceSets ()Lorg/gradle/api/NamedDomainObjectContainer; public abstract fun getModuleName ()Lorg/gradle/api/provider/Property; public abstract fun getModulePath ()Lorg/gradle/api/provider/Property; public abstract fun getModuleVersion ()Lorg/gradle/api/provider/Property; + public final fun getPluginsConfiguration ()Lorg/gradle/api/ExtensiblePolymorphicDomainObjectContainer; public abstract fun getSourceSetScopeDefault ()Lorg/gradle/api/provider/Property; } @@ -51,7 +52,7 @@ public abstract class dev/adamko/dokkatoo/dokka/DokkaPublication : java/io/Seria public abstract fun getOfflineMode ()Lorg/gradle/api/provider/Property; public abstract fun getOutputDir ()Lorg/gradle/api/file/DirectoryProperty; protected final fun getOutputDirPath ()Lorg/gradle/api/provider/Provider; - public abstract fun getPluginsConfiguration ()Lorg/gradle/api/NamedDomainObjectContainer; + public final fun getPluginsConfiguration ()Lorg/gradle/api/ExtensiblePolymorphicDomainObjectContainer; public abstract fun getSuppressInheritedMembers ()Lorg/gradle/api/provider/Property; public abstract fun getSuppressObviousFunctions ()Lorg/gradle/api/provider/Property; } @@ -88,21 +89,6 @@ public final class dev/adamko/dokkatoo/dokka/parameters/DokkaParametersKxs$$seri public fun typeParametersSerializers ()[Lkotlinx/serialization/KSerializer; } -public abstract class dev/adamko/dokkatoo/dokka/parameters/DokkaPluginConfigurationSpec : dev/adamko/dokkatoo/dokka/parameters/DokkaParameterBuilder, java/io/Serializable, org/gradle/api/Named { - public synthetic fun build ()Ljava/lang/Object; - public fun getName ()Ljava/lang/String; - public final fun getPluginFqn ()Ljava/lang/String; - public abstract fun getSerializationFormat ()Lorg/gradle/api/provider/Property; - public abstract fun getValues ()Lorg/gradle/api/provider/Property; -} - -public final class dev/adamko/dokkatoo/dokka/parameters/DokkaPluginConfigurationSpec$EncodedFormat : java/lang/Enum { - public static final field JSON Ldev/adamko/dokkatoo/dokka/parameters/DokkaPluginConfigurationSpec$EncodedFormat; - public static final field XML Ldev/adamko/dokkatoo/dokka/parameters/DokkaPluginConfigurationSpec$EncodedFormat; - public static fun valueOf (Ljava/lang/String;)Ldev/adamko/dokkatoo/dokka/parameters/DokkaPluginConfigurationSpec$EncodedFormat; - public static fun values ()[Ldev/adamko/dokkatoo/dokka/parameters/DokkaPluginConfigurationSpec$EncodedFormat; -} - public abstract class dev/adamko/dokkatoo/dokka/parameters/DokkaSourceLinkSpec : dev/adamko/dokkatoo/dokka/parameters/DokkaParameterBuilder, java/io/Serializable { public synthetic fun build ()Ljava/lang/Object; public abstract fun getLocalDirectory ()Lorg/gradle/api/file/DirectoryProperty; @@ -172,6 +158,124 @@ public final class dev/adamko/dokkatoo/dokka/parameters/VisibilityModifier : jav public final class dev/adamko/dokkatoo/dokka/parameters/VisibilityModifier$Companion { } +public abstract class dev/adamko/dokkatoo/dokka/plugins/DokkaHtmlPluginParameters : dev/adamko/dokkatoo/dokka/plugins/DokkaPluginParametersBaseSpec { + public static final field Companion Ldev/adamko/dokkatoo/dokka/plugins/DokkaHtmlPluginParameters$Companion; + public static final field DOKKA_HTML_PARAMETERS_NAME Ljava/lang/String; + public static final field DOKKA_HTML_PLUGIN_FQN Ljava/lang/String; + public abstract fun getCustomAssets ()Lorg/gradle/api/file/ConfigurableFileCollection; + public abstract fun getCustomStyleSheets ()Lorg/gradle/api/file/ConfigurableFileCollection; + public abstract fun getFooterMessage ()Lorg/gradle/api/provider/Property; + public abstract fun getMergeImplicitExpectActualDeclarations ()Lorg/gradle/api/provider/Property; + public abstract fun getSeparateInheritedMembers ()Lorg/gradle/api/provider/Property; + public abstract fun getTemplatesDir ()Lorg/gradle/api/file/DirectoryProperty; + public fun jsonEncode ()Ljava/lang/String; +} + +public final class dev/adamko/dokkatoo/dokka/plugins/DokkaHtmlPluginParameters$Companion { +} + +public abstract class dev/adamko/dokkatoo/dokka/plugins/DokkaPluginParametersBaseSpec : dev/adamko/dokkatoo/dokka/parameters/DokkaParameterBuilder, java/io/Serializable, org/gradle/api/Named { + public fun build ()Ldev/adamko/dokkatoo/dokka/parameters/DokkaParametersKxs$PluginConfigurationKxs; + public synthetic fun build ()Ljava/lang/Object; + public fun getName ()Ljava/lang/String; + public fun getPluginFqn ()Ljava/lang/String; + public abstract fun jsonEncode ()Ljava/lang/String; +} + +public abstract class dev/adamko/dokkatoo/dokka/plugins/DokkaPluginParametersBuilder : dev/adamko/dokkatoo/dokka/plugins/DokkaPluginParametersBaseSpec { + public static final field Companion Ldev/adamko/dokkatoo/dokka/plugins/DokkaPluginParametersBuilder$Companion; + public fun getPluginFqn ()Ljava/lang/String; + public fun jsonEncode ()Ljava/lang/String; +} + +public final class dev/adamko/dokkatoo/dokka/plugins/DokkaPluginParametersBuilder$Companion { +} + +public final class dev/adamko/dokkatoo/dokka/plugins/DokkaPluginParametersBuilderKt { + public static final fun PluginConfigBooleanValue (Lorg/gradle/api/provider/Provider;)Lorg/gradle/api/provider/Provider; + public static final fun PluginConfigNumberValue (Lorg/gradle/api/provider/Provider;)Lorg/gradle/api/provider/Provider; + public static final fun PluginConfigStringValue (Lorg/gradle/api/provider/Provider;)Lorg/gradle/api/provider/Provider; + public static final fun PluginConfigValue (Ljava/lang/Number;)Ldev/adamko/dokkatoo/dokka/plugins/PluginConfigValue$Primitive$NumberValue; + public static final fun PluginConfigValue (Ljava/lang/String;)Ldev/adamko/dokkatoo/dokka/plugins/PluginConfigValue$Primitive$StringValue; + public static final fun PluginConfigValue (Z)Ldev/adamko/dokkatoo/dokka/plugins/PluginConfigValue$Primitive$BooleanValue; + public static final fun add (Ldev/adamko/dokkatoo/dokka/plugins/PluginConfigValue$Values;Ljava/lang/Number;)V + public static final fun add (Ldev/adamko/dokkatoo/dokka/plugins/PluginConfigValue$Values;Ljava/lang/String;)V + public static final fun add (Ldev/adamko/dokkatoo/dokka/plugins/PluginConfigValue$Values;Z)V + public static final fun addBoolean (Ldev/adamko/dokkatoo/dokka/plugins/PluginConfigValue$Values;Lorg/gradle/api/provider/Provider;)V + public static final fun addNumber (Ldev/adamko/dokkatoo/dokka/plugins/PluginConfigValue$Values;Lorg/gradle/api/provider/Provider;)V + public static final fun addString (Ldev/adamko/dokkatoo/dokka/plugins/PluginConfigValue$Values;Lorg/gradle/api/provider/Provider;)V + public static final fun booleanProperty (Ldev/adamko/dokkatoo/dokka/plugins/DokkaPluginParametersBuilder;Ljava/lang/String;Lorg/gradle/api/provider/Provider;)V + public static final fun files (Ldev/adamko/dokkatoo/dokka/plugins/DokkaPluginParametersBuilder;Ljava/lang/String;Lkotlin/jvm/functions/Function1;)V + public static final fun numberProperty (Ldev/adamko/dokkatoo/dokka/plugins/DokkaPluginParametersBuilder;Ljava/lang/String;Lorg/gradle/api/provider/Provider;)V + public static final fun pluginParameters (Lorg/gradle/api/ExtensiblePolymorphicDomainObjectContainer;Ljava/lang/String;Lkotlin/jvm/functions/Function1;)V + public static final fun properties (Ldev/adamko/dokkatoo/dokka/plugins/DokkaPluginParametersBuilder;Ljava/lang/String;Lkotlin/jvm/functions/Function1;)V + public static final fun property (Ldev/adamko/dokkatoo/dokka/plugins/DokkaPluginParametersBuilder;Ljava/lang/String;Ljava/lang/Number;)V + public static final fun property (Ldev/adamko/dokkatoo/dokka/plugins/DokkaPluginParametersBuilder;Ljava/lang/String;Ljava/lang/String;)V + public static final fun property (Ldev/adamko/dokkatoo/dokka/plugins/DokkaPluginParametersBuilder;Ljava/lang/String;Z)V + public static final fun stringProperty (Ldev/adamko/dokkatoo/dokka/plugins/DokkaPluginParametersBuilder;Ljava/lang/String;Lorg/gradle/api/provider/Provider;)V +} + +public abstract class dev/adamko/dokkatoo/dokka/plugins/DokkaVersioningPluginParameters : dev/adamko/dokkatoo/dokka/plugins/DokkaPluginParametersBaseSpec { + public static final field Companion Ldev/adamko/dokkatoo/dokka/plugins/DokkaVersioningPluginParameters$Companion; + public static final field DOKKA_VERSIONING_PLUGIN_FQN Ljava/lang/String; + public static final field DOKKA_VERSIONING_PLUGIN_PARAMETERS_NAME Ljava/lang/String; + public abstract fun getOlderVersions ()Lorg/gradle/api/file/ConfigurableFileCollection; + public abstract fun getOlderVersionsDir ()Lorg/gradle/api/file/DirectoryProperty; + public abstract fun getRenderVersionsNavigationOnAllPages ()Lorg/gradle/api/provider/Property; + public abstract fun getVersion ()Lorg/gradle/api/provider/Property; + public abstract fun getVersionsOrdering ()Lorg/gradle/api/provider/ListProperty; + public fun jsonEncode ()Ljava/lang/String; +} + +public final class dev/adamko/dokkatoo/dokka/plugins/DokkaVersioningPluginParameters$Companion { +} + +public abstract class dev/adamko/dokkatoo/dokka/plugins/PluginConfigValue { +} + +public final class dev/adamko/dokkatoo/dokka/plugins/PluginConfigValue$DirectoryValue : dev/adamko/dokkatoo/dokka/plugins/PluginConfigValue { + public fun (Lorg/gradle/api/file/DirectoryProperty;)V + public final fun getDirectory ()Lorg/gradle/api/file/DirectoryProperty; +} + +public final class dev/adamko/dokkatoo/dokka/plugins/PluginConfigValue$FileValue : dev/adamko/dokkatoo/dokka/plugins/PluginConfigValue { + public fun (Lorg/gradle/api/file/RegularFileProperty;)V + public final fun getFile ()Lorg/gradle/api/file/RegularFileProperty; +} + +public final class dev/adamko/dokkatoo/dokka/plugins/PluginConfigValue$FilesValue : dev/adamko/dokkatoo/dokka/plugins/PluginConfigValue { + public fun (Lorg/gradle/api/file/ConfigurableFileCollection;)V + public final fun getFiles ()Lorg/gradle/api/file/ConfigurableFileCollection; +} + +public abstract class dev/adamko/dokkatoo/dokka/plugins/PluginConfigValue$Primitive : dev/adamko/dokkatoo/dokka/plugins/PluginConfigValue { +} + +public final class dev/adamko/dokkatoo/dokka/plugins/PluginConfigValue$Primitive$BooleanValue : dev/adamko/dokkatoo/dokka/plugins/PluginConfigValue$Primitive { + public fun (Z)V + public final fun getBoolean ()Z +} + +public final class dev/adamko/dokkatoo/dokka/plugins/PluginConfigValue$Primitive$NumberValue : dev/adamko/dokkatoo/dokka/plugins/PluginConfigValue$Primitive { + public fun (Ljava/lang/Number;)V + public final fun getNumber ()Ljava/lang/Number; +} + +public final class dev/adamko/dokkatoo/dokka/plugins/PluginConfigValue$Primitive$StringValue : dev/adamko/dokkatoo/dokka/plugins/PluginConfigValue$Primitive { + public fun (Ljava/lang/String;)V + public final fun getString ()Ljava/lang/String; +} + +public final class dev/adamko/dokkatoo/dokka/plugins/PluginConfigValue$Properties : dev/adamko/dokkatoo/dokka/plugins/PluginConfigValue { + public fun (Lorg/gradle/api/provider/MapProperty;)V + public final fun getValues ()Lorg/gradle/api/provider/MapProperty; +} + +public final class dev/adamko/dokkatoo/dokka/plugins/PluginConfigValue$Values : dev/adamko/dokkatoo/dokka/plugins/PluginConfigValue { + public fun (Lorg/gradle/api/provider/ListProperty;)V + public final fun getValues ()Lorg/gradle/api/provider/ListProperty; +} + public abstract class dev/adamko/dokkatoo/formats/DokkatooFormatPlugin : org/gradle/api/Plugin { public static final field Companion Ldev/adamko/dokkatoo/formats/DokkatooFormatPlugin$Companion; public fun (Ljava/lang/String;)V @@ -186,6 +290,7 @@ public abstract class dev/adamko/dokkatoo/formats/DokkatooGfmPlugin : dev/adamko } public abstract class dev/adamko/dokkatoo/formats/DokkatooHtmlPlugin : dev/adamko/dokkatoo/formats/DokkatooFormatPlugin { + public fun configure (Ldev/adamko/dokkatoo/formats/DokkatooFormatPlugin$DokkatooFormatPluginContext;)V } public abstract class dev/adamko/dokkatoo/formats/DokkatooJavadocPlugin : dev/adamko/dokkatoo/formats/DokkatooFormatPlugin { @@ -240,8 +345,7 @@ public abstract class dev/adamko/dokkatoo/tasks/DokkatooPrepareParametersTask : public final fun getOutputDir ()Lorg/gradle/api/file/DirectoryProperty; protected final fun getOutputDirPath ()Lorg/gradle/api/provider/Provider; public abstract fun getPluginsClasspath ()Lorg/gradle/api/file/ConfigurableFileCollection; - public abstract fun getPluginsConfiguration ()Lorg/gradle/api/NamedDomainObjectContainer; - public abstract fun getPluginsMapConfiguration ()Lorg/gradle/api/provider/MapProperty; + public final fun getPluginsConfiguration ()Lorg/gradle/api/ExtensiblePolymorphicDomainObjectContainer; public abstract fun getPublicationEnabled ()Lorg/gradle/api/provider/Property; public abstract fun getSuppressInheritedMembers ()Lorg/gradle/api/provider/Property; public abstract fun getSuppressObviousFunctions ()Lorg/gradle/api/provider/Property; diff --git a/modules/dokkatoo-plugin/src/main/kotlin/DokkatooBasePlugin.kt b/modules/dokkatoo-plugin/src/main/kotlin/DokkatooBasePlugin.kt index 323618a5..bf5b7420 100644 --- a/modules/dokkatoo-plugin/src/main/kotlin/DokkatooBasePlugin.kt +++ b/modules/dokkatoo-plugin/src/main/kotlin/DokkatooBasePlugin.kt @@ -4,7 +4,6 @@ import dev.adamko.dokkatoo.distibutions.DokkatooConfigurationAttributes import dev.adamko.dokkatoo.distibutions.DokkatooConfigurationAttributes.Companion.DOKKATOO_BASE_ATTRIBUTE import dev.adamko.dokkatoo.distibutions.DokkatooConfigurationAttributes.Companion.DOKKATOO_CATEGORY_ATTRIBUTE import dev.adamko.dokkatoo.distibutions.DokkatooConfigurationAttributes.Companion.DOKKA_FORMAT_ATTRIBUTE -import dev.adamko.dokkatoo.dokka.parameters.DokkaPluginConfigurationSpec.EncodedFormat import dev.adamko.dokkatoo.dokka.parameters.VisibilityModifier import dev.adamko.dokkatoo.formats.* import dev.adamko.dokkatoo.internal.* @@ -130,7 +129,6 @@ constructor( ) { dokkatooExtension.dokkatooPublications.all { enabled.convention(true) - cacheRoot.convention(dokkatooExtension.dokkatooCacheDirectory) delayTemplateSubstitution.convention(false) failOnWarning.convention(false) @@ -141,10 +139,6 @@ constructor( outputDir.convention(dokkatooExtension.dokkatooPublicationDirectory) suppressInheritedMembers.convention(false) suppressObviousFunctions.convention(true) - - pluginsConfiguration.configureEach { - serializationFormat.convention(EncodedFormat.JSON) - } } } diff --git a/modules/dokkatoo-plugin/src/main/kotlin/DokkatooExtension.kt b/modules/dokkatoo-plugin/src/main/kotlin/DokkatooExtension.kt index fe79352b..59081b60 100644 --- a/modules/dokkatoo-plugin/src/main/kotlin/DokkatooExtension.kt +++ b/modules/dokkatoo-plugin/src/main/kotlin/DokkatooExtension.kt @@ -2,20 +2,25 @@ package dev.adamko.dokkatoo import dev.adamko.dokkatoo.dokka.DokkaPublication import dev.adamko.dokkatoo.dokka.parameters.DokkaSourceSetSpec +import dev.adamko.dokkatoo.dokka.plugins.DokkaPluginParametersBaseSpec +import dev.adamko.dokkatoo.internal.DokkaPluginParametersContainer import dev.adamko.dokkatoo.internal.DokkatooInternalApi import java.io.Serializable import org.gradle.api.NamedDomainObjectContainer import org.gradle.api.file.DirectoryProperty +import org.gradle.api.model.ObjectFactory import org.gradle.api.plugins.ExtensionAware import org.gradle.api.provider.Property +import org.gradle.kotlin.dsl.* /** * Configure the behaviour of the [DokkatooBasePlugin]. */ abstract class DokkatooExtension @DokkatooInternalApi -constructor() : - ExtensionAware, Serializable { +constructor( + objects: ObjectFactory, +) : ExtensionAware, Serializable { /** Directory into which [DokkaPublication]s will be produced */ abstract val dokkatooPublicationDirectory: DirectoryProperty @@ -46,7 +51,10 @@ constructor() : * * The type of site is determined by the Dokka Plugins. By default, an HTML site will be generated. */ - abstract val dokkatooPublications: NamedDomainObjectContainer + val dokkatooPublications: NamedDomainObjectContainer = + objects.domainObjectContainer(DokkaPublication::class) { named -> + objects.newInstance(named, pluginsConfiguration) + } /** * Dokka Source Sets describe the source code that should be included in a Dokka Publication. @@ -78,6 +86,14 @@ constructor() : */ abstract val dokkatooSourceSets: NamedDomainObjectContainer + /** + * Dokka Plugin are used to configure the way Dokka generates a format. + * Some plugins can be configured via parameters, and those parameters are stored in this + * container. + */ + val pluginsConfiguration: DokkaPluginParametersContainer = + objects.polymorphicDomainObjectContainer(DokkaPluginParametersBaseSpec::class) + interface Versions { /** Default version used for Dokka dependencies */ diff --git a/modules/dokkatoo-plugin/src/main/kotlin/dokka/DokkaPublication.kt b/modules/dokkatoo-plugin/src/main/kotlin/dokka/DokkaPublication.kt index 27f4a527..e6399757 100644 --- a/modules/dokkatoo-plugin/src/main/kotlin/dokka/DokkaPublication.kt +++ b/modules/dokkatoo-plugin/src/main/kotlin/dokka/DokkaPublication.kt @@ -1,17 +1,17 @@ package dev.adamko.dokkatoo.dokka -import dev.adamko.dokkatoo.dokka.parameters.DokkaPluginConfigurationSpec +import dev.adamko.dokkatoo.internal.DokkaPluginParametersContainer import dev.adamko.dokkatoo.internal.DokkatooInternalApi import java.io.Serializable import javax.inject.Inject import org.gradle.api.Named -import org.gradle.api.NamedDomainObjectContainer import org.gradle.api.file.ConfigurableFileCollection import org.gradle.api.file.DirectoryProperty import org.gradle.api.provider.Property import org.gradle.api.provider.Provider import org.gradle.api.tasks.* import org.gradle.api.tasks.PathSensitivity.RELATIVE +import org.gradle.kotlin.dsl.* /** * A [DokkaPublication] describes a single Dokka output. @@ -27,6 +27,13 @@ abstract class DokkaPublication constructor( @get:Internal val formatName: String, + + /** + * Configurations for Dokka Generator Plugins. Must be provided from + * [dev.adamko.dokkatoo.DokkatooExtension.pluginsConfiguration]. + */ + @get:Nested + val pluginsConfiguration: DokkaPluginParametersContainer, ) : Named, Serializable { @Internal @@ -51,6 +58,8 @@ constructor( * [outputDirPath] is required so Gradle can determine if the task is up-to-date. */ @get:Input + // marked as an Input because a DokkaPublication is used to configure the appropriate + // DokkatooTasks, which will then protected val outputDirPath: Provider get() = outputDir.map { it.asFile.invariantSeparatorsPath } @@ -70,9 +79,6 @@ constructor( @get:Input abstract val offlineMode: Property - @get:Nested - abstract val pluginsConfiguration: NamedDomainObjectContainer - // /** Dokka Configuration files from other subprojects that will be merged into this Dokka Configuration */ // @get:InputFiles //// @get:NormalizeLineEndings diff --git a/modules/dokkatoo-plugin/src/main/kotlin/dokka/parameters/DokkaPluginConfigurationSpec.kt b/modules/dokkatoo-plugin/src/main/kotlin/dokka/parameters/DokkaPluginConfigurationSpec.kt deleted file mode 100644 index f7fcee23..00000000 --- a/modules/dokkatoo-plugin/src/main/kotlin/dokka/parameters/DokkaPluginConfigurationSpec.kt +++ /dev/null @@ -1,58 +0,0 @@ -package dev.adamko.dokkatoo.dokka.parameters - -import dev.adamko.dokkatoo.dokka.parameters.DokkaPluginConfigurationSpec.EncodedFormat.JSON -import dev.adamko.dokkatoo.dokka.parameters.DokkaPluginConfigurationSpec.EncodedFormat.XML -import dev.adamko.dokkatoo.internal.DokkatooInternalApi -import java.io.Serializable -import javax.inject.Inject -import org.gradle.api.Named -import org.gradle.api.provider.Property -import org.gradle.api.tasks.Input -import org.gradle.api.tasks.Internal -import org.jetbrains.dokka.DokkaConfiguration - -/** - * @param[pluginFqn] Fully qualified classname of the Dokka Plugin - */ -abstract class DokkaPluginConfigurationSpec -@DokkatooInternalApi -@Inject -constructor( - @get:Input - val pluginFqn: String -) : - DokkaParameterBuilder, - Serializable, - Named { - - @get:Input - abstract val serializationFormat: Property - - @get:Input - abstract val values: Property - - @DokkatooInternalApi - override fun build() = DokkaParametersKxs.PluginConfigurationKxs( - fqPluginName = pluginFqn, - serializationFormat = serializationFormat.get().dokkaType, - values = values.get(), - ) - - @Internal - override fun getName(): String = pluginFqn - - /** - * Denotes how a [DokkaPluginConfigurationSpec] will be encoded. - * - * This should typically be [JSON]. [XML] is intended for use with the Dokka Maven plugin. - * - * @see org.jetbrains.dokka.DokkaConfiguration.SerializationFormat - */ - // TODO maybe remove XML? I'm not sure it's at all useful. - enum class EncodedFormat( - internal val dokkaType: DokkaConfiguration.SerializationFormat - ) { - JSON(DokkaConfiguration.SerializationFormat.JSON), - XML(DokkaConfiguration.SerializationFormat.XML), - } -} diff --git a/modules/dokkatoo-plugin/src/main/kotlin/dokka/plugins/DokkaHtmlPluginParameters.kt b/modules/dokkatoo-plugin/src/main/kotlin/dokka/plugins/DokkaHtmlPluginParameters.kt new file mode 100644 index 00000000..a9bca31d --- /dev/null +++ b/modules/dokkatoo-plugin/src/main/kotlin/dokka/plugins/DokkaHtmlPluginParameters.kt @@ -0,0 +1,115 @@ +package dev.adamko.dokkatoo.dokka.plugins + +import dev.adamko.dokkatoo.internal.DokkatooInternalApi +import dev.adamko.dokkatoo.internal.addAll +import dev.adamko.dokkatoo.internal.putIfNotNull +import javax.inject.Inject +import kotlinx.serialization.json.buildJsonObject +import kotlinx.serialization.json.putJsonArray +import org.gradle.api.file.ConfigurableFileCollection +import org.gradle.api.file.DirectoryProperty +import org.gradle.api.provider.Property +import org.gradle.api.tasks.* +import org.gradle.api.tasks.PathSensitivity.RELATIVE + + +/** + * Configuration for Dokka's base HTML format + * + * [More information is available in the Dokka docs.](https://kotlinlang.org/docs/dokka-html.html#configuration) + */ +abstract class DokkaHtmlPluginParameters +@DokkatooInternalApi +@Inject +constructor( + name: String +) : DokkaPluginParametersBaseSpec( + name, + DOKKA_HTML_PLUGIN_FQN, +) { + + /** + * List of paths for image assets to be bundled with documentation. + * The image assets can have any file extension. + * + * For more information, see + * [Customizing assets](https://kotlinlang.org/docs/dokka-html.html#customize-assets). + */ + @get:InputFiles + @get:PathSensitive(RELATIVE) + @get:Optional + abstract val customAssets: ConfigurableFileCollection + + /** + * List of paths for `.css` stylesheets to be bundled with documentation and used for rendering. + * + * For more information, see + * [Customizing assets](https://kotlinlang.org/docs/dokka-html.html#customize-assets). + */ + @get:InputFiles + @get:PathSensitive(RELATIVE) + @get:Optional + abstract val customStyleSheets: ConfigurableFileCollection + + /** + * This is a boolean option. If set to `true`, Dokka renders properties/functions and inherited + * properties/inherited functions separately. + * + * This is disabled by default. + */ + @get:Input + @get:Optional + abstract val separateInheritedMembers: Property + + /** + * This is a boolean option. If set to `true`, Dokka merges declarations that are not declared as + * [expect/actual](https://kotlinlang.org/docs/multiplatform-connect-to-apis.html), but have the + * same fully qualified name. This can be useful for legacy codebases. + * + * This is disabled by default. + */ + @get:Input + @get:Optional + abstract val mergeImplicitExpectActualDeclarations: Property + + /** The text displayed in the footer. */ + @get:Input + @get:Optional + abstract val footerMessage: Property + + /** + * Path to the directory containing custom HTML templates. + * + * For more information, see [Templates](https://kotlinlang.org/docs/dokka-html.html#templates). + */ + @get:InputDirectory + @get:PathSensitive(RELATIVE) + @get:Optional + abstract val templatesDir: DirectoryProperty + + override fun jsonEncode(): String = + buildJsonObject { + putJsonArray("customAssets") { + addAll(customAssets.files) + } + putJsonArray("customStyleSheets") { + addAll(customStyleSheets.files) + } + putIfNotNull("separateInheritedMembers", separateInheritedMembers.orNull) + putIfNotNull( + "mergeImplicitExpectActualDeclarations", + mergeImplicitExpectActualDeclarations.orNull + ) + putIfNotNull("footerMessage", footerMessage.orNull) + putIfNotNull("footerMessage", footerMessage.orNull) + putIfNotNull( + "templatesDir", + templatesDir.orNull?.asFile?.canonicalFile?.invariantSeparatorsPath + ) + }.toString() + + companion object { + const val DOKKA_HTML_PARAMETERS_NAME = "html" + const val DOKKA_HTML_PLUGIN_FQN = "org.jetbrains.dokka.base.DokkaBase" + } +} diff --git a/modules/dokkatoo-plugin/src/main/kotlin/dokka/plugins/DokkaPluginParametersBaseSpec.kt b/modules/dokkatoo-plugin/src/main/kotlin/dokka/plugins/DokkaPluginParametersBaseSpec.kt new file mode 100644 index 00000000..b779ec1c --- /dev/null +++ b/modules/dokkatoo-plugin/src/main/kotlin/dokka/plugins/DokkaPluginParametersBaseSpec.kt @@ -0,0 +1,44 @@ +package dev.adamko.dokkatoo.dokka.plugins + +import dev.adamko.dokkatoo.dokka.parameters.DokkaParameterBuilder +import dev.adamko.dokkatoo.dokka.parameters.DokkaParametersKxs +import dev.adamko.dokkatoo.internal.DokkatooInternalApi +import java.io.Serializable +import javax.inject.Inject +import org.gradle.api.Named +import org.gradle.api.tasks.Input + +/** + * Base class for defining Dokka Plugin configuration. + * + * This class should not be instantiated directly. Instead, use a subclass, or create plugin + * parameters dynamically using [DokkaPluginParametersBuilder]. + * + * [More information about Dokka Plugins is available in the Dokka docs.](https://kotlinlang.org/docs/dokka-plugins.html) + * + * @param[pluginFqn] Fully qualified classname of the Dokka Plugin + */ +abstract class DokkaPluginParametersBaseSpec +@DokkatooInternalApi +@Inject +constructor( + private val name: String, + @get:Input + open val pluginFqn: String, +) : DokkaParameterBuilder, + Serializable, + Named { + + override fun build(): DokkaParametersKxs.PluginConfigurationKxs { + return DokkaParametersKxs.PluginConfigurationKxs( + fqPluginName = pluginFqn, + serializationFormat = org.jetbrains.dokka.DokkaConfiguration.SerializationFormat.JSON, + values = jsonEncode(), + ) + } + + abstract fun jsonEncode(): String // to be implemented by subclasses + + @Input + override fun getName(): String = name +} diff --git a/modules/dokkatoo-plugin/src/main/kotlin/dokka/plugins/DokkaPluginParametersBuilder.kt b/modules/dokkatoo-plugin/src/main/kotlin/dokka/plugins/DokkaPluginParametersBuilder.kt new file mode 100644 index 00000000..6e67d191 --- /dev/null +++ b/modules/dokkatoo-plugin/src/main/kotlin/dokka/plugins/DokkaPluginParametersBuilder.kt @@ -0,0 +1,233 @@ +package dev.adamko.dokkatoo.dokka.plugins + +import dev.adamko.dokkatoo.internal.DokkaPluginParametersContainer +import dev.adamko.dokkatoo.internal.DokkatooInternalApi +import java.io.File +import javax.inject.Inject +import kotlinx.serialization.json.* +import org.gradle.api.file.ConfigurableFileCollection +import org.gradle.api.file.DirectoryProperty +import org.gradle.api.file.RegularFileProperty +import org.gradle.api.model.ObjectFactory +import org.gradle.api.provider.ListProperty +import org.gradle.api.provider.MapProperty +import org.gradle.api.provider.Provider +import org.gradle.api.tasks.* +import org.gradle.api.tasks.PathSensitivity.RELATIVE +import org.gradle.kotlin.dsl.* + + +/** + * Dynamically create some configuration to control the behaviour of a Dokka Plugin. + * + * @param[pluginFqn] The fully-qualified name of a Dokka Plugin. For example, the Dokka Base plugin's FQN is `org.jetbrains.dokka.base.DokkaBase` + */ +fun DokkaPluginParametersContainer.pluginParameters( + pluginFqn: String, + configure: DokkaPluginParametersBuilder.() -> Unit +) { + containerWithType(DokkaPluginParametersBuilder::class) + .maybeCreate(pluginFqn) + .configure() +} + + +/** + * Dynamically create some configuration to control the behaviour of a Dokka Plugin. + * + * This type of builder is necessary to respect + * [Gradle incremental build annotations](https://docs.gradle.org/current/userguide/incremental_build.html#sec:task_input_output_annotations). + * + * @param[pluginFqn] The fully-qualified name of a Dokka Plugin. For example, the Dokka Base plugin's FQN is `org.jetbrains.dokka.base.DokkaBase` + */ +abstract class DokkaPluginParametersBuilder +@Inject +@DokkatooInternalApi +constructor( + name: String, + @get:Input + override val pluginFqn: String, + + @Internal + internal val objects: ObjectFactory, +) : DokkaPluginParametersBaseSpec(name, pluginFqn) { + + @get:Nested + internal val properties = PluginConfigValue.Properties(objects.mapProperty()) + + @Internal + override fun jsonEncode(): String = properties.convertToJson().toString() + + companion object { + private fun PluginConfigValue.convertToJson(): JsonElement = + when (this) { + is PluginConfigValue.DirectoryValue -> directory.asFile.orNull.convertToJson() + is PluginConfigValue.FileValue -> file.asFile.orNull.convertToJson() + is PluginConfigValue.FilesValue -> JsonArray(files.files.map { it.convertToJson() }) + + is PluginConfigValue.Primitive.BooleanValue -> JsonPrimitive(boolean) + is PluginConfigValue.Primitive.NumberValue -> JsonPrimitive(number) + is PluginConfigValue.Primitive.StringValue -> JsonPrimitive(string) + + is PluginConfigValue.Properties -> + JsonObject(values.get().mapValues { (_, value) -> value.convertToJson() }) + + is PluginConfigValue.Values -> + JsonArray(values.get().map { it.convertToJson() }) + } + + /** Creates a [JsonPrimitive] from the given [File]. */ + private fun File?.convertToJson() = + JsonPrimitive(this?.canonicalFile?.invariantSeparatorsPath) + } +} + + +fun DokkaPluginParametersBuilder.files( + propertyName: String, + filesConfig: ConfigurableFileCollection.() -> Unit +) { + val files = objects.fileCollection() + files.filesConfig() + properties.values.put(propertyName, PluginConfigValue.FilesValue(files)) +} + +//region Primitive Properties +fun DokkaPluginParametersBuilder.property(propertyName: String, value: String) { + properties.values.put(propertyName, PluginConfigValue(value)) +} + +fun DokkaPluginParametersBuilder.property(propertyName: String, value: Number) { + properties.values.put(propertyName, PluginConfigValue(value)) +} + +fun DokkaPluginParametersBuilder.property(propertyName: String, value: Boolean) { + properties.values.put(propertyName, PluginConfigValue(value)) +} + +@JvmName("stringProperty") +fun DokkaPluginParametersBuilder.property(propertyName: String, provider: Provider) { + properties.values.put(propertyName, provider.map { PluginConfigValue(it) }) +} + +@JvmName("numberProperty") +fun DokkaPluginParametersBuilder.property(propertyName: String, provider: Provider) { + properties.values.put(propertyName, provider.map { PluginConfigValue(it) }) +} + +@JvmName("booleanProperty") +fun DokkaPluginParametersBuilder.property( + propertyName: String, + provider: Provider +) { + properties.values.put(propertyName, provider.map { PluginConfigValue(it) }) +} +//endregion + + +//region List Properties +fun DokkaPluginParametersBuilder.properties( + propertyName: String, + build: PluginConfigValue.Values.() -> Unit +) { + val values = PluginConfigValue.Values(objects.listProperty()) + values.build() + properties.values.put(propertyName, values) +} + +fun PluginConfigValue.Values.add(value: String) = + values.add(PluginConfigValue(value)) + +fun PluginConfigValue.Values.add(value: Number) = + values.add(PluginConfigValue(value)) + +fun PluginConfigValue.Values.add(value: Boolean) = + values.add(PluginConfigValue(value)) + +@JvmName("addString") +fun PluginConfigValue.Values.add(value: Provider) = + values.add(PluginConfigValue(value)) + +@JvmName("addNumber") +fun PluginConfigValue.Values.add(value: Provider) = + values.add(PluginConfigValue(value)) + +@JvmName("addBoolean") +fun PluginConfigValue.Values.add(value: Provider) = + values.add(PluginConfigValue(value)) +//endregion + + +sealed class PluginConfigValue { + + /** An input file */ + class FileValue( + @InputFile + @PathSensitive(RELATIVE) + val file: RegularFileProperty, + ) : PluginConfigValue() + + /** Input files and directories */ + class FilesValue( + @InputFiles + @PathSensitive(RELATIVE) + val files: ConfigurableFileCollection, + ) : PluginConfigValue() + + /** An input directory */ + class DirectoryValue( + @InputDirectory + @PathSensitive(RELATIVE) + val directory: DirectoryProperty, + ) : PluginConfigValue() + + /** Key-value properties. Analogous to a [JsonObject]. */ + class Properties( + @Nested + val values: MapProperty + ) : PluginConfigValue() + + /** Multiple values. Analogous to a [JsonArray]. */ + class Values( + @Nested + val values: ListProperty + ) : PluginConfigValue() + + sealed class Primitive : PluginConfigValue() { + // I would prefer it if these class weren't nested, but it's a restriction of Kotlin 1.4 + + /** A basic [String] value */ + class StringValue(@Input val string: String) : Primitive() + + /** A basic [Number] value */ + class NumberValue(@Input val number: Number) : Primitive() + + /** A basic [Boolean] value */ + class BooleanValue(@Input val boolean: Boolean) : Primitive() + } +} + + +fun PluginConfigValue(value: String) = + PluginConfigValue.Primitive.StringValue(value) + +fun PluginConfigValue(value: Number) = + PluginConfigValue.Primitive.NumberValue(value) + +fun PluginConfigValue(value: Boolean) = + PluginConfigValue.Primitive.BooleanValue(value) + +@Suppress("FunctionName") +@JvmName("PluginConfigStringValue") +fun PluginConfigValue(value: Provider): Provider = + value.map { PluginConfigValue(it) } + +@Suppress("FunctionName") +@JvmName("PluginConfigNumberValue") +fun PluginConfigValue(value: Provider): Provider = + value.map { PluginConfigValue(it) } + +@Suppress("FunctionName") +@JvmName("PluginConfigBooleanValue") +fun PluginConfigValue(value: Provider): Provider = + value.map { PluginConfigValue(it) } diff --git a/modules/dokkatoo-plugin/src/main/kotlin/dokka/plugins/DokkaVersioningPluginParameters.kt b/modules/dokkatoo-plugin/src/main/kotlin/dokka/plugins/DokkaVersioningPluginParameters.kt new file mode 100644 index 00000000..de862c29 --- /dev/null +++ b/modules/dokkatoo-plugin/src/main/kotlin/dokka/plugins/DokkaVersioningPluginParameters.kt @@ -0,0 +1,101 @@ +package dev.adamko.dokkatoo.dokka.plugins + +import dev.adamko.dokkatoo.internal.DokkatooInternalApi +import dev.adamko.dokkatoo.internal.addAll +import dev.adamko.dokkatoo.internal.addAllIfNotNull +import dev.adamko.dokkatoo.internal.putIfNotNull +import javax.inject.Inject +import kotlinx.serialization.json.buildJsonObject +import kotlinx.serialization.json.putJsonArray +import org.gradle.api.file.ConfigurableFileCollection +import org.gradle.api.file.DirectoryProperty +import org.gradle.api.provider.ListProperty +import org.gradle.api.provider.Property +import org.gradle.api.tasks.* +import org.gradle.api.tasks.PathSensitivity.RELATIVE + + +/** + * Configuration for + * [Dokka's Versioning plugin](https://github.com/Kotlin/dokka/tree/master/plugins/versioning#readme). + * + * The versioning plugin provides the ability to host documentation for multiple versions of your + * library/application with seamless switching between them. This, in turn, provides a better + * experience for your users. + * + * Note: The versioning plugin only works with Dokka's HTML format. + */ +abstract class DokkaVersioningPluginParameters +@DokkatooInternalApi +@Inject +constructor( + name: String, +) : DokkaPluginParametersBaseSpec( + name, + DOKKA_VERSIONING_PLUGIN_FQN, +) { + + /** + * The version of your application/library that documentation is going to be generated for. + * This will be the version shown in the dropdown menu. + */ + @get:Input + @get:Optional + abstract val version: Property + + /** + * An optional list of strings that represents the order that versions should appear in the + * dropdown menu. + * + * Must match [version] string exactly. The first item in the list is at the top of the dropdown. + */ + @get:Input + @get:Optional + abstract val versionsOrdering: ListProperty + + /** + * An optional path to a parent folder that contains other documentation versions. + * It requires a specific directory structure. + * + * For more information, see + * [Directory structure](https://github.com/Kotlin/dokka/blob/master/plugins/versioning/README.md#directory-structure). + */ + @get:InputDirectory + @get:PathSensitive(RELATIVE) + @get:Optional + abstract val olderVersionsDir: DirectoryProperty + + /** + * An optional list of paths to other documentation versions. It must point to Dokka's outputs + * directly. This is useful if different versions can't all be in the same directory. + */ + @get:InputFiles + @get:PathSensitive(RELATIVE) + @get:Optional + abstract val olderVersions: ConfigurableFileCollection + + /** + * An optional boolean value indicating whether to render the navigation dropdown on all pages. + * + * Set to `true` by default. + */ + @get:Input + @get:Optional + abstract val renderVersionsNavigationOnAllPages: Property + + override fun jsonEncode(): String = + buildJsonObject { + putIfNotNull("version", version.orNull) + putJsonArray("versionsOrdering") { addAllIfNotNull(versionsOrdering.orNull) } + putIfNotNull("olderVersionsDir", olderVersionsDir.orNull?.asFile) + putJsonArray("olderVersions") { + addAll(olderVersions.files) + } + putIfNotNull("renderVersionsNavigationOnAllPages", renderVersionsNavigationOnAllPages.orNull) + }.toString() + + companion object { + const val DOKKA_VERSIONING_PLUGIN_PARAMETERS_NAME = "versioning" + const val DOKKA_VERSIONING_PLUGIN_FQN = "org.jetbrains.dokka.versioning.VersioningPlugin" + } +} diff --git a/modules/dokkatoo-plugin/src/main/kotlin/formats/DokkatooFormatPlugin.kt b/modules/dokkatoo-plugin/src/main/kotlin/formats/DokkatooFormatPlugin.kt index 196b9f96..7def216b 100644 --- a/modules/dokkatoo-plugin/src/main/kotlin/formats/DokkatooFormatPlugin.kt +++ b/modules/dokkatoo-plugin/src/main/kotlin/formats/DokkatooFormatPlugin.kt @@ -9,8 +9,6 @@ import dev.adamko.dokkatoo.distibutions.DokkatooConfigurationAttributes.Companio import dev.adamko.dokkatoo.distibutions.DokkatooConfigurationAttributes.Companion.DOKKATOO_CATEGORY_ATTRIBUTE import dev.adamko.dokkatoo.distibutions.DokkatooConfigurationAttributes.Companion.DOKKA_FORMAT_ATTRIBUTE import dev.adamko.dokkatoo.dokka.DokkaPublication -import dev.adamko.dokkatoo.dokka.parameters.DokkaPluginConfigurationSpec -import dev.adamko.dokkatoo.dokka.parameters.DokkaPluginConfigurationSpec.EncodedFormat import dev.adamko.dokkatoo.internal.* import dev.adamko.dokkatoo.tasks.DokkatooGenerateTask import dev.adamko.dokkatoo.tasks.DokkatooPrepareModuleDescriptorTask @@ -39,7 +37,6 @@ import org.gradle.api.provider.Property import org.gradle.api.provider.Provider import org.gradle.api.provider.ProviderFactory import org.gradle.kotlin.dsl.* -import org.jetbrains.dokka.DokkaConfiguration /** * Base Gradle Plugin for setting up a Dokka Publication for a specific format. @@ -91,7 +88,6 @@ abstract class DokkatooFormatPlugin( publication = publication, dokkatooExtension = dokkatooExtension, dependencyContainers = dependencyContainers, - objects = objects, providers = providers, ) @@ -366,7 +362,6 @@ abstract class DokkatooFormatPlugin( private val dokkatooExtension: DokkatooExtension, private val dependencyContainers: DependencyContainers, - private val objects: ObjectFactory, private val providers: ProviderFactory, ) { private val formatName: String get() = publication.formatName @@ -374,8 +369,9 @@ abstract class DokkatooFormatPlugin( private val taskNames = DokkatooBasePlugin.TaskNames(formatName) val prepareParameters = project.tasks.register( - taskNames.prepareParameters - ) task@{ + taskNames.prepareParameters, + publication.pluginsConfiguration, + ).configuring task@{ description = "Prepares Dokka parameters for generating the $formatName publication" @@ -411,22 +407,6 @@ abstract class DokkatooFormatPlugin( pluginsConfiguration.addAllLater(providers.provider { publication.pluginsConfiguration }) - // - pluginsConfiguration.addAllLater( - @Suppress("DEPRECATION") - pluginsMapConfiguration.map { pluginConfig -> - pluginConfig.map { (pluginId, pluginConfiguration) -> - objects.newInstance(pluginId).apply { - values.set(pluginConfiguration) - } - } - } - ) - pluginsConfiguration.configureEach { - serializationFormat.convention(EncodedFormat.JSON) - } - // - suppressInheritedMembers.convention(publication.suppressInheritedMembers) suppressObviousFunctions.convention(publication.suppressObviousFunctions) } diff --git a/modules/dokkatoo-plugin/src/main/kotlin/formats/DokkatooHtmlPlugin.kt b/modules/dokkatoo-plugin/src/main/kotlin/formats/DokkatooHtmlPlugin.kt index 3c29fd58..803a18c3 100644 --- a/modules/dokkatoo-plugin/src/main/kotlin/formats/DokkatooHtmlPlugin.kt +++ b/modules/dokkatoo-plugin/src/main/kotlin/formats/DokkatooHtmlPlugin.kt @@ -1,9 +1,38 @@ package dev.adamko.dokkatoo.formats +import dev.adamko.dokkatoo.dokka.plugins.DokkaHtmlPluginParameters +import dev.adamko.dokkatoo.dokka.plugins.DokkaHtmlPluginParameters.Companion.DOKKA_HTML_PARAMETERS_NAME +import dev.adamko.dokkatoo.dokka.plugins.DokkaVersioningPluginParameters +import dev.adamko.dokkatoo.dokka.plugins.DokkaVersioningPluginParameters.Companion.DOKKA_VERSIONING_PLUGIN_PARAMETERS_NAME import dev.adamko.dokkatoo.internal.DokkatooInternalApi +import org.gradle.kotlin.dsl.* abstract class DokkatooHtmlPlugin @DokkatooInternalApi constructor() : DokkatooFormatPlugin(formatName = "html") { - // HTML is the default - no special config needed! + + override fun DokkatooFormatPluginContext.configure() { + configureDokkaHtmlPlugins() + } + + private fun DokkatooFormatPluginContext.configureDokkaHtmlPlugins() { + with(dokkatooExtension.pluginsConfiguration) { + registerFactory(DokkaHtmlPluginParameters::class.java) { named -> + objects.newInstance(named) + } + register(DOKKA_HTML_PARAMETERS_NAME) + withType().configureEach { + separateInheritedMembers.convention(false) + mergeImplicitExpectActualDeclarations.convention(false) + } + + registerFactory(DokkaVersioningPluginParameters::class.java) { named -> + objects.newInstance(named) + } + register(DOKKA_VERSIONING_PLUGIN_PARAMETERS_NAME) + withType().configureEach { + renderVersionsNavigationOnAllPages.convention(true) + } + } + } } diff --git a/modules/dokkatoo-plugin/src/main/kotlin/internal/gradleTypealiases.kt b/modules/dokkatoo-plugin/src/main/kotlin/internal/gradleTypealiases.kt new file mode 100644 index 00000000..03441d9f --- /dev/null +++ b/modules/dokkatoo-plugin/src/main/kotlin/internal/gradleTypealiases.kt @@ -0,0 +1,19 @@ +package dev.adamko.dokkatoo.internal + +import dev.adamko.dokkatoo.dokka.plugins.DokkaPluginParametersBaseSpec +import org.gradle.api.ExtensiblePolymorphicDomainObjectContainer + +/** Container for all [Dokka Plugin parameters][DokkaPluginParametersBaseSpec]. */ +typealias DokkaPluginParametersContainer = ExtensiblePolymorphicDomainObjectContainer + + +/** + * The path of a Gradle [Project][org.gradle.api.Project]. This is unique per subproject. + * This is _not_ the file path, which + * [can be configured to be different to the project path](https://docs.gradle.org/current/userguide/fine_tuning_project_layout.html#sub:modifying_element_of_the_project_tree). + * + * Example: `:modules:tests:alpha-project`. + * + * @see org.gradle.api.Project.getPath + */ +internal typealias GradleProjectPath = org.gradle.util.Path diff --git a/modules/dokkatoo-plugin/src/main/kotlin/internal/gradleUtils.kt b/modules/dokkatoo-plugin/src/main/kotlin/internal/gradleUtils.kt index 2f775794..eb707cf7 100644 --- a/modules/dokkatoo-plugin/src/main/kotlin/internal/gradleUtils.kt +++ b/modules/dokkatoo-plugin/src/main/kotlin/internal/gradleUtils.kt @@ -1,11 +1,14 @@ package dev.adamko.dokkatoo.internal +import org.gradle.api.Action import org.gradle.api.Project +import org.gradle.api.Task import org.gradle.api.artifacts.Configuration import org.gradle.api.artifacts.component.ComponentIdentifier import org.gradle.api.artifacts.component.ProjectComponentIdentifier import org.gradle.api.provider.Provider import org.gradle.api.specs.Spec +import org.gradle.api.tasks.TaskProvider /** @@ -48,9 +51,16 @@ internal object LocalProjectOnlyFilter : Spec { } -internal typealias GradleProjectPath = org.gradle.util.Path - - internal fun Project.pathAsFilePath() = path .removePrefix(GradleProjectPath.SEPARATOR) .replace(GradleProjectPath.SEPARATOR, "/") + + +/** + * Apply some configuration to a [Task] using + * [configure][org.gradle.api.tasks.TaskContainer.configure], + * and return the same [TaskProvider]. + */ +internal fun TaskProvider.configuring( + block: Action +): TaskProvider = apply { configure(block) } diff --git a/modules/dokkatoo-plugin/src/main/kotlin/internal/kotlinxSerializationUtils.kt b/modules/dokkatoo-plugin/src/main/kotlin/internal/kotlinxSerializationUtils.kt new file mode 100644 index 00000000..b58aaa5f --- /dev/null +++ b/modules/dokkatoo-plugin/src/main/kotlin/internal/kotlinxSerializationUtils.kt @@ -0,0 +1,33 @@ +package dev.adamko.dokkatoo.internal + +import java.io.File +import kotlinx.serialization.json.JsonArrayBuilder +import kotlinx.serialization.json.JsonObjectBuilder +import kotlinx.serialization.json.JsonPrimitive +import kotlinx.serialization.json.add + + +@JvmName("addAllFiles") +internal fun JsonArrayBuilder.addAll(files: Iterable) { + files + .map { it.canonicalFile.invariantSeparatorsPath } + .forEach { path -> add(path) } +} + +@JvmName("addAllStrings") +internal fun JsonArrayBuilder.addAll(values: Iterable) { + values.forEach { add(it) } +} + +internal fun JsonArrayBuilder.addAllIfNotNull(values: Iterable?) { + values?.let(::addAll) +} + +internal fun JsonObjectBuilder.putIfNotNull(key: String, value: Boolean?) = + value?.let { put(key, JsonPrimitive(it)) } + +internal fun JsonObjectBuilder.putIfNotNull(key: String, value: String?) = + value?.let { put(key, JsonPrimitive(it)) } + +internal fun JsonObjectBuilder.putIfNotNull(key: String, value: File?) = + value?.let { put(key, JsonPrimitive(it.canonicalFile.invariantSeparatorsPath)) } diff --git a/modules/dokkatoo-plugin/src/main/kotlin/tasks/DokkatooPrepareParametersTask.kt b/modules/dokkatoo-plugin/src/main/kotlin/tasks/DokkatooPrepareParametersTask.kt index 6aab3233..35c23aa7 100644 --- a/modules/dokkatoo-plugin/src/main/kotlin/tasks/DokkatooPrepareParametersTask.kt +++ b/modules/dokkatoo-plugin/src/main/kotlin/tasks/DokkatooPrepareParametersTask.kt @@ -2,22 +2,22 @@ package dev.adamko.dokkatoo.tasks import dev.adamko.dokkatoo.DokkatooBasePlugin.Companion.jsonMapper import dev.adamko.dokkatoo.dokka.parameters.DokkaParametersKxs -import dev.adamko.dokkatoo.dokka.parameters.DokkaPluginConfigurationSpec import dev.adamko.dokkatoo.dokka.parameters.DokkaSourceSetSpec +import dev.adamko.dokkatoo.dokka.plugins.DokkaPluginParametersBaseSpec +import dev.adamko.dokkatoo.internal.DokkaPluginParametersContainer import dev.adamko.dokkatoo.internal.DokkatooInternalApi import java.io.IOException import javax.inject.Inject import kotlinx.serialization.encodeToString -import org.gradle.api.NamedDomainObjectContainer import org.gradle.api.file.ConfigurableFileCollection import org.gradle.api.file.DirectoryProperty import org.gradle.api.file.RegularFileProperty import org.gradle.api.model.ObjectFactory -import org.gradle.api.provider.MapProperty import org.gradle.api.provider.Property import org.gradle.api.provider.Provider import org.gradle.api.tasks.* import org.gradle.api.tasks.PathSensitivity.RELATIVE +import org.gradle.kotlin.dsl.* /** * Builds the Dokka Parameters that the Dokka Generator will use to produce a Dokka Publication for this project. @@ -31,6 +31,13 @@ abstract class DokkatooPrepareParametersTask @Inject constructor( objects: ObjectFactory, + + /** + * Configurations for Dokka Generator Plugins. Must be provided from + * [dev.adamko.dokkatoo.dokka.DokkaPublication.pluginsConfiguration]. + */ + @get:Nested + val pluginsConfiguration: DokkaPluginParametersContainer, ) : DokkatooTask.WithSourceSets() { @get:OutputFile @@ -90,13 +97,15 @@ constructor( @get:Input abstract val offlineMode: Property + /** + * Classpath that contains the Dokka Generator Plugins used to modify this publication. + * + * The plugins should be configured in [dev.adamko.dokkatoo.dokka.DokkaPublication.pluginsConfiguration]. + */ @get:InputFiles @get:Classpath abstract val pluginsClasspath: ConfigurableFileCollection - @get:Nested - abstract val pluginsConfiguration: NamedDomainObjectContainer - @get:Input abstract val suppressObviousFunctions: Property @@ -140,7 +149,7 @@ constructor( val pluginsClasspath = pluginsClasspath.files.toList() val pluginsConfiguration = - pluginsConfiguration.map(DokkaPluginConfigurationSpec::build) + pluginsConfiguration.map(DokkaPluginParametersBaseSpec::build) val failOnWarning = failOnWarning.get() val delayTemplateSubstitution = delayTemplateSubstitution.get() val suppressObviousFunctions = suppressObviousFunctions.get() @@ -204,8 +213,4 @@ constructor( } } } - - @get:Input - @Deprecated("TODO write adapter to the new DSL") - abstract val pluginsMapConfiguration: MapProperty } diff --git a/modules/dokkatoo-plugin/src/main/kotlin/tasks/DokkatooTask.kt b/modules/dokkatoo-plugin/src/main/kotlin/tasks/DokkatooTask.kt index 993d0780..f9abee30 100644 --- a/modules/dokkatoo-plugin/src/main/kotlin/tasks/DokkatooTask.kt +++ b/modules/dokkatoo-plugin/src/main/kotlin/tasks/DokkatooTask.kt @@ -43,5 +43,4 @@ constructor() : DefaultTask() { dokkaSourceSets.addAllLater(sourceSets) } } - }