aboutsummaryrefslogtreecommitdiff
path: root/dokka-runners/dokkatoo/modules/dokkatoo-plugin/src/main/kotlin
diff options
context:
space:
mode:
authorAdam <897017+aSemy@users.noreply.github.com>2023-10-20 00:39:12 +1300
committerGitHub <noreply@github.com>2023-10-19 13:39:12 +0200
commit35d15601f2d129a7d3db67dd9e2f4c41c87ef083 (patch)
treef9098cb5b79fc31b4a393347f5cebcf9d87dd139 /dokka-runners/dokkatoo/modules/dokkatoo-plugin/src/main/kotlin
parent8016c1face1283952e228aee348487bf0421ab90 (diff)
downloaddokka-35d15601f2d129a7d3db67dd9e2f4c41c87ef083.tar.gz
dokka-35d15601f2d129a7d3db67dd9e2f4c41c87ef083.tar.bz2
dokka-35d15601f2d129a7d3db67dd9e2f4c41c87ef083.zip
Contribute Dokkatoo (#3188)
Diffstat (limited to 'dokka-runners/dokkatoo/modules/dokkatoo-plugin/src/main/kotlin')
-rw-r--r--dokka-runners/dokkatoo/modules/dokkatoo-plugin/src/main/kotlin/DokkatooBasePlugin.kt355
-rw-r--r--dokka-runners/dokkatoo/modules/dokkatoo-plugin/src/main/kotlin/DokkatooExtension.kt130
-rw-r--r--dokka-runners/dokkatoo/modules/dokkatoo-plugin/src/main/kotlin/DokkatooPlugin.kt32
-rw-r--r--dokka-runners/dokkatoo/modules/dokkatoo-plugin/src/main/kotlin/adapters/DokkatooAndroidAdapter.kt214
-rw-r--r--dokka-runners/dokkatoo/modules/dokkatoo-plugin/src/main/kotlin/adapters/DokkatooJavaAdapter.kt40
-rw-r--r--dokka-runners/dokkatoo/modules/dokkatoo-plugin/src/main/kotlin/adapters/DokkatooKotlinAdapter.kt459
-rw-r--r--dokka-runners/dokkatoo/modules/dokkatoo-plugin/src/main/kotlin/distributions/DokkatooConfigurationAttributes.kt59
-rw-r--r--dokka-runners/dokkatoo/modules/dokkatoo-plugin/src/main/kotlin/dokka/DokkaPublication.kt122
-rw-r--r--dokka-runners/dokkatoo/modules/dokkatoo-plugin/src/main/kotlin/dokka/parameters/DokkaExternalDocumentationLinkSpec.kt120
-rw-r--r--dokka-runners/dokkatoo/modules/dokkatoo-plugin/src/main/kotlin/dokka/parameters/DokkaGeneratorParametersSpec.kt93
-rw-r--r--dokka-runners/dokkatoo/modules/dokkatoo-plugin/src/main/kotlin/dokka/parameters/DokkaModuleDescriptionSpec.kt49
-rw-r--r--dokka-runners/dokkatoo/modules/dokkatoo-plugin/src/main/kotlin/dokka/parameters/DokkaPackageOptionsSpec.kt84
-rw-r--r--dokka-runners/dokkatoo/modules/dokkatoo-plugin/src/main/kotlin/dokka/parameters/DokkaParametersKxs.kt78
-rw-r--r--dokka-runners/dokkatoo/modules/dokkatoo-plugin/src/main/kotlin/dokka/parameters/DokkaSourceLinkSpec.kt106
-rw-r--r--dokka-runners/dokkatoo/modules/dokkatoo-plugin/src/main/kotlin/dokka/parameters/DokkaSourceSetIdSpec.kt61
-rw-r--r--dokka-runners/dokkatoo/modules/dokkatoo-plugin/src/main/kotlin/dokka/parameters/DokkaSourceSetSpec.kt366
-rw-r--r--dokka-runners/dokkatoo/modules/dokkatoo-plugin/src/main/kotlin/dokka/parameters/HasConfigurableVisibilityModifiers.kt14
-rw-r--r--dokka-runners/dokkatoo/modules/dokkatoo-plugin/src/main/kotlin/dokka/parameters/KotlinPlatform.kt54
-rw-r--r--dokka-runners/dokkatoo/modules/dokkatoo-plugin/src/main/kotlin/dokka/parameters/VisibilityModifier.kt42
-rw-r--r--dokka-runners/dokkatoo/modules/dokkatoo-plugin/src/main/kotlin/dokka/parameters/builders/DokkaModuleDescriptionBuilder.kt33
-rw-r--r--dokka-runners/dokkatoo/modules/dokkatoo-plugin/src/main/kotlin/dokka/parameters/builders/DokkaParametersBuilder.kt77
-rw-r--r--dokka-runners/dokkatoo/modules/dokkatoo-plugin/src/main/kotlin/dokka/parameters/builders/DokkaSourceSetBuilder.kt112
-rw-r--r--dokka-runners/dokkatoo/modules/dokkatoo-plugin/src/main/kotlin/dokka/plugins/DokkaHtmlPluginParameters.kt129
-rw-r--r--dokka-runners/dokkatoo/modules/dokkatoo-plugin/src/main/kotlin/dokka/plugins/DokkaPluginParametersBaseSpec.kt32
-rw-r--r--dokka-runners/dokkatoo/modules/dokkatoo-plugin/src/main/kotlin/dokka/plugins/DokkaPluginParametersBuilder.kt232
-rw-r--r--dokka-runners/dokkatoo/modules/dokkatoo-plugin/src/main/kotlin/dokka/plugins/DokkaVersioningPluginParameters.kt101
-rw-r--r--dokka-runners/dokkatoo/modules/dokkatoo-plugin/src/main/kotlin/formats/DokkatooFormatDependencyContainers.kt152
-rw-r--r--dokka-runners/dokkatoo/modules/dokkatoo-plugin/src/main/kotlin/formats/DokkatooFormatPlugin.kt174
-rw-r--r--dokka-runners/dokkatoo/modules/dokkatoo-plugin/src/main/kotlin/formats/DokkatooFormatTasks.kt105
-rw-r--r--dokka-runners/dokkatoo/modules/dokkatoo-plugin/src/main/kotlin/formats/DokkatooGfmPlugin.kt14
-rw-r--r--dokka-runners/dokkatoo/modules/dokkatoo-plugin/src/main/kotlin/formats/DokkatooHtmlPlugin.kt72
-rw-r--r--dokka-runners/dokkatoo/modules/dokkatoo-plugin/src/main/kotlin/formats/DokkatooJavadocPlugin.kt14
-rw-r--r--dokka-runners/dokkatoo/modules/dokkatoo-plugin/src/main/kotlin/formats/DokkatooJekyllPlugin.kt14
-rw-r--r--dokka-runners/dokkatoo/modules/dokkatoo-plugin/src/main/kotlin/internal/DokkatooInternalApi.kt37
-rw-r--r--dokka-runners/dokkatoo/modules/dokkatoo-plugin/src/main/kotlin/internal/LoggerAdapter.kt65
-rw-r--r--dokka-runners/dokkatoo/modules/dokkatoo-plugin/src/main/kotlin/internal/collectionsUtils.kt7
-rw-r--r--dokka-runners/dokkatoo/modules/dokkatoo-plugin/src/main/kotlin/internal/gradleExtensionAccessors.kt9
-rw-r--r--dokka-runners/dokkatoo/modules/dokkatoo-plugin/src/main/kotlin/internal/gradleTypealiases.kt20
-rw-r--r--dokka-runners/dokkatoo/modules/dokkatoo-plugin/src/main/kotlin/internal/gradleUtils.kt187
-rw-r--r--dokka-runners/dokkatoo/modules/dokkatoo-plugin/src/main/kotlin/internal/kotlinxSerializationUtils.kt36
-rw-r--r--dokka-runners/dokkatoo/modules/dokkatoo-plugin/src/main/kotlin/internal/stringUtils.kt11
-rw-r--r--dokka-runners/dokkatoo/modules/dokkatoo-plugin/src/main/kotlin/internal/uriUtils.kt9
-rw-r--r--dokka-runners/dokkatoo/modules/dokkatoo-plugin/src/main/kotlin/tasks/DokkatooGenerateTask.kt187
-rw-r--r--dokka-runners/dokkatoo/modules/dokkatoo-plugin/src/main/kotlin/tasks/DokkatooPrepareModuleDescriptorTask.kt62
-rw-r--r--dokka-runners/dokkatoo/modules/dokkatoo-plugin/src/main/kotlin/tasks/DokkatooTask.kt22
-rw-r--r--dokka-runners/dokkatoo/modules/dokkatoo-plugin/src/main/kotlin/tasks/LogHtmlPublicationLinkTask.kt156
-rw-r--r--dokka-runners/dokkatoo/modules/dokkatoo-plugin/src/main/kotlin/workers/DokkaGeneratorWorker.kt77
47 files changed, 4624 insertions, 0 deletions
diff --git a/dokka-runners/dokkatoo/modules/dokkatoo-plugin/src/main/kotlin/DokkatooBasePlugin.kt b/dokka-runners/dokkatoo/modules/dokkatoo-plugin/src/main/kotlin/DokkatooBasePlugin.kt
new file mode 100644
index 00000000..9d67471a
--- /dev/null
+++ b/dokka-runners/dokkatoo/modules/dokkatoo-plugin/src/main/kotlin/DokkatooBasePlugin.kt
@@ -0,0 +1,355 @@
+package org.jetbrains.dokka.dokkatoo
+
+import org.jetbrains.dokka.dokkatoo.distributions.DokkatooConfigurationAttributes
+import org.jetbrains.dokka.dokkatoo.distributions.DokkatooConfigurationAttributes.Companion.DOKKATOO_BASE_ATTRIBUTE
+import org.jetbrains.dokka.dokkatoo.distributions.DokkatooConfigurationAttributes.Companion.DOKKATOO_CATEGORY_ATTRIBUTE
+import org.jetbrains.dokka.dokkatoo.distributions.DokkatooConfigurationAttributes.Companion.DOKKA_FORMAT_ATTRIBUTE
+import org.jetbrains.dokka.dokkatoo.dokka.parameters.DokkaSourceSetSpec
+import org.jetbrains.dokka.dokkatoo.dokka.parameters.KotlinPlatform
+import org.jetbrains.dokka.dokkatoo.dokka.parameters.VisibilityModifier
+import org.jetbrains.dokka.dokkatoo.internal.*
+import org.jetbrains.dokka.dokkatoo.tasks.DokkatooGenerateTask
+import org.jetbrains.dokka.dokkatoo.tasks.DokkatooPrepareModuleDescriptorTask
+import org.jetbrains.dokka.dokkatoo.tasks.DokkatooTask
+import java.io.File
+import javax.inject.Inject
+import kotlinx.serialization.ExperimentalSerializationApi
+import kotlinx.serialization.json.Json
+import org.gradle.api.NamedDomainObjectContainer
+import org.gradle.api.Plugin
+import org.gradle.api.Project
+import org.gradle.api.artifacts.Configuration
+import org.gradle.api.file.ProjectLayout
+import org.gradle.api.file.RegularFileProperty
+import org.gradle.api.model.ObjectFactory
+import org.gradle.api.provider.Property
+import org.gradle.api.provider.Provider
+import org.gradle.api.provider.ProviderFactory
+import org.gradle.api.tasks.TaskContainer
+import org.gradle.kotlin.dsl.*
+import org.gradle.language.base.plugins.LifecycleBasePlugin
+
+/**
+ * The base plugin for Dokkatoo. Sets up Dokkatoo and configures default values, but does not
+ * add any specific config (specifically, it does not create Dokka Publications).
+ */
+abstract class DokkatooBasePlugin
+@DokkatooInternalApi
+@Inject
+constructor(
+ private val providers: ProviderFactory,
+ private val layout: ProjectLayout,
+ private val objects: ObjectFactory,
+) : Plugin<Project> {
+
+ override fun apply(target: Project) {
+ // apply the lifecycle-base plugin so the clean task is available
+ target.pluginManager.apply(LifecycleBasePlugin::class)
+
+ val dokkatooExtension = createExtension(target)
+
+ target.tasks.createDokkaLifecycleTasks()
+
+ val configurationAttributes = objects.newInstance<DokkatooConfigurationAttributes>()
+
+ target.dependencies.attributesSchema {
+ attribute(DOKKATOO_BASE_ATTRIBUTE)
+ attribute(DOKKATOO_CATEGORY_ATTRIBUTE)
+ attribute(DOKKA_FORMAT_ATTRIBUTE)
+ }
+
+ target.configurations.register(dependencyContainerNames.dokkatoo) {
+ description = "Fetch all Dokkatoo files from all configurations in other subprojects"
+ asConsumer()
+ isVisible = false
+ attributes {
+ attribute(DOKKATOO_BASE_ATTRIBUTE, configurationAttributes.dokkatooBaseUsage)
+ }
+ }
+
+ configureDokkaPublicationsDefaults(dokkatooExtension)
+ dokkatooExtension.dokkatooSourceSets.configureDefaults(
+ sourceSetScopeConvention = dokkatooExtension.sourceSetScopeDefault
+ )
+
+ target.tasks.withType<DokkatooGenerateTask>().configureEach {
+ cacheDirectory.convention(dokkatooExtension.dokkatooCacheDirectory)
+ workerDebugEnabled.convention(false)
+ workerLogFile.convention(temporaryDir.resolve("dokka-worker.log"))
+ workerJvmArgs.set(
+ listOf(
+ //"-XX:MaxMetaspaceSize=512m",
+ "-XX:+HeapDumpOnOutOfMemoryError",
+ "-XX:+AlwaysPreTouch", // https://github.com/gradle/gradle/issues/3093#issuecomment-387259298
+ //"-XX:StartFlightRecording=disk=true,name={path.drop(1).map { if (it.isLetterOrDigit()) it else '-' }.joinToString("")},dumponexit=true,duration=30s",
+ //"-XX:FlightRecorderOptions=repository=$baseDir/jfr,stackdepth=512",
+ )
+ )
+ dokkaConfigurationJsonFile.convention(temporaryDir.resolve("dokka-configuration.json"))
+ }
+
+ target.tasks.withType<DokkatooPrepareModuleDescriptorTask>().configureEach {
+ moduleName.convention(dokkatooExtension.moduleName)
+ includes.from(providers.provider { dokkatooExtension.dokkatooSourceSets.flatMap { it.includes } })
+ modulePath.convention(dokkatooExtension.modulePath)
+ }
+
+ target.tasks.withType<DokkatooGenerateTask>().configureEach {
+
+ publicationEnabled.convention(true)
+ onlyIf("publication must be enabled") { publicationEnabled.getOrElse(true) }
+
+ generator.dokkaSourceSets.addAllLater(
+ providers.provider {
+ // exclude suppressed source sets as early as possible, to avoid unnecessary dependency resolution
+ dokkatooExtension.dokkatooSourceSets.filterNot { it.suppress.get() }
+ }
+ )
+
+ generator.dokkaSourceSets.configureDefaults(
+ sourceSetScopeConvention = dokkatooExtension.sourceSetScopeDefault
+ )
+ }
+
+ dokkatooExtension.dokkatooSourceSets.configureDefaults(
+ sourceSetScopeConvention = dokkatooExtension.sourceSetScopeDefault
+ )
+ }
+
+ private fun createExtension(project: Project): DokkatooExtension {
+ val dokkatooExtension = project.extensions.create<DokkatooExtension>(EXTENSION_NAME).apply {
+ moduleName.convention(providers.provider { project.name })
+ moduleVersion.convention(providers.provider { project.version.toString() })
+ modulePath.convention(project.pathAsFilePath())
+ konanHome.convention(
+ providers
+ .provider {
+ // konanHome is set into in extraProperties:
+ // https://github.com/JetBrains/kotlin/blob/v1.9.0/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/native/KotlinNativeTargetPreset.kt#L35-L38
+ project.extensions.extraProperties.get("konanHome") as? String?
+ }
+ .map { File(it) }
+ )
+
+ sourceSetScopeDefault.convention(project.path)
+ dokkatooPublicationDirectory.convention(layout.buildDirectory.dir("dokka"))
+ dokkatooModuleDirectory.convention(layout.buildDirectory.dir("dokka-module"))
+ dokkatooConfigurationsDirectory.convention(layout.buildDirectory.dir("dokka-config"))
+ }
+
+ dokkatooExtension.versions {
+ jetbrainsDokka.convention(DokkatooConstants.DOKKA_VERSION)
+ jetbrainsMarkdown.convention("0.3.1")
+ freemarker.convention("2.3.31")
+ kotlinxHtml.convention("0.8.0")
+ kotlinxCoroutines.convention("1.6.4")
+ }
+
+ return dokkatooExtension
+ }
+
+ /** Set defaults in all [DokkatooExtension.dokkatooPublications]s */
+ private fun configureDokkaPublicationsDefaults(
+ dokkatooExtension: DokkatooExtension,
+ ) {
+ dokkatooExtension.dokkatooPublications.all {
+ enabled.convention(true)
+ cacheRoot.convention(dokkatooExtension.dokkatooCacheDirectory)
+ delayTemplateSubstitution.convention(false)
+ failOnWarning.convention(false)
+ finalizeCoroutines.convention(false)
+ moduleName.convention(dokkatooExtension.moduleName)
+ moduleVersion.convention(dokkatooExtension.moduleVersion)
+ offlineMode.convention(false)
+ outputDir.convention(dokkatooExtension.dokkatooPublicationDirectory)
+ suppressInheritedMembers.convention(false)
+ suppressObviousFunctions.convention(true)
+ }
+ }
+
+ /** Set conventions for all [DokkaSourceSetSpec] properties */
+ private fun NamedDomainObjectContainer<DokkaSourceSetSpec>.configureDefaults(
+ sourceSetScopeConvention: Property<String>,
+ ) {
+ configureEach dss@{
+ analysisPlatform.convention(KotlinPlatform.DEFAULT)
+ displayName.convention(
+ analysisPlatform.map { platform ->
+ // Match existing Dokka naming conventions. (This should probably be simplified!)
+ when {
+ // Multiplatform source sets (e.g. commonMain, jvmMain, macosMain)
+ name.endsWith("Main") -> name.substringBeforeLast("Main")
+
+ // indeterminate source sets should be named by the Kotlin platform
+ else -> platform.displayName
+ }
+ }
+ )
+ documentedVisibilities.convention(setOf(VisibilityModifier.PUBLIC))
+ jdkVersion.convention(8)
+
+ enableKotlinStdLibDocumentationLink.convention(true)
+ enableJdkDocumentationLink.convention(true)
+ enableAndroidDocumentationLink.convention(
+ analysisPlatform.map { it == KotlinPlatform.AndroidJVM }
+ )
+
+ reportUndocumented.convention(false)
+ skipDeprecated.convention(false)
+ skipEmptyPackages.convention(true)
+ sourceSetScope.convention(sourceSetScopeConvention)
+
+ // Manually added sourceSets should not be suppressed by default. dokkatooSourceSets that are
+ // automatically added by DokkatooKotlinAdapter will have a sensible value for suppress.
+ suppress.convention(false)
+
+ suppressGeneratedFiles.convention(true)
+
+ sourceLinks.configureEach {
+ localDirectory.convention(layout.projectDirectory)
+ remoteLineSuffix.convention("#L")
+ }
+
+ perPackageOptions.configureEach {
+ matchingRegex.convention(".*")
+ suppress.convention(false)
+ skipDeprecated.convention(false)
+ reportUndocumented.convention(false)
+ }
+
+ externalDocumentationLinks {
+ configureEach {
+ enabled.convention(true)
+ packageListUrl.convention(url.map { it.appendPath("package-list") })
+ }
+
+ maybeCreate("jdk") {
+ enabled.convention(this@dss.enableJdkDocumentationLink)
+ url(this@dss.jdkVersion.map { jdkVersion ->
+ when {
+ jdkVersion < 11 -> "https://docs.oracle.com/javase/${jdkVersion}/docs/api/"
+ else -> "https://docs.oracle.com/en/java/javase/${jdkVersion}/docs/api/"
+ }
+ })
+ packageListUrl(this@dss.jdkVersion.map { jdkVersion ->
+ when {
+ jdkVersion < 11 -> "https://docs.oracle.com/javase/${jdkVersion}/docs/api/package-list"
+ else -> "https://docs.oracle.com/en/java/javase/${jdkVersion}/docs/api/element-list"
+ }
+ })
+ }
+
+ maybeCreate("kotlinStdlib") {
+ enabled.convention(this@dss.enableKotlinStdLibDocumentationLink)
+ url("https://kotlinlang.org/api/latest/jvm/stdlib/")
+ }
+
+ maybeCreate("androidSdk") {
+ enabled.convention(this@dss.enableAndroidDocumentationLink)
+ url("https://developer.android.com/reference/kotlin/")
+ }
+
+ maybeCreate("androidX") {
+ enabled.convention(this@dss.enableAndroidDocumentationLink)
+ url("https://developer.android.com/reference/kotlin/")
+ packageListUrl("https://developer.android.com/reference/kotlin/androidx/package-list")
+ }
+ }
+ }
+ }
+
+ private fun TaskContainer.createDokkaLifecycleTasks() {
+ register<DokkatooTask>(taskNames.generate) {
+ description = "Generates Dokkatoo publications for all formats"
+ dependsOn(withType<DokkatooGenerateTask>())
+ }
+ }
+
+ // workaround for https://github.com/gradle/gradle/issues/23708
+ private fun RegularFileProperty.convention(file: File): RegularFileProperty =
+ convention(objects.fileProperty().fileValue(file))
+
+ // workaround for https://github.com/gradle/gradle/issues/23708
+ private fun RegularFileProperty.convention(file: Provider<File>): RegularFileProperty =
+ convention(objects.fileProperty().fileProvider(file))
+
+ companion object {
+
+ const val EXTENSION_NAME = "dokkatoo"
+
+ /**
+ * The group of all Dokkatoo [Gradle tasks][org.gradle.api.Task].
+ *
+ * @see org.gradle.api.Task.getGroup
+ */
+ const val TASK_GROUP = "dokkatoo"
+
+ /** The names of [Gradle tasks][org.gradle.api.Task] created by Dokkatoo */
+ val taskNames = TaskNames(null)
+
+ /** The names of [Configuration]s created by Dokkatoo */
+ val dependencyContainerNames = DependencyContainerNames(null)
+
+ internal val jsonMapper = Json {
+ prettyPrint = true
+ @OptIn(ExperimentalSerializationApi::class)
+ prettyPrintIndent = " "
+ }
+ }
+
+ @DokkatooInternalApi
+ abstract class HasFormatName {
+ abstract val formatName: String?
+
+ /** Appends [formatName] to the end of the string, camelcase style, if [formatName] is not null */
+ protected fun String.appendFormat(): String =
+ when (val name = formatName) {
+ null -> this
+ else -> this + name.uppercaseFirstChar()
+ }
+ }
+
+ /**
+ * Names of the Gradle [Configuration]s used by the [Dokkatoo Plugin][DokkatooBasePlugin].
+ *
+ * Beware the confusing terminology:
+ * - [Gradle Configurations][org.gradle.api.artifacts.Configuration] - share files between subprojects. Each has a name.
+ * - [DokkaConfiguration][org.jetbrains.dokka.DokkaConfiguration] - parameters for executing the Dokka Generator
+ */
+ @DokkatooInternalApi
+ class DependencyContainerNames(override val formatName: String?) : HasFormatName() {
+
+ val dokkatoo = "dokkatoo".appendFormat()
+
+ /** Name of the [Configuration] that _consumes_ all [org.jetbrains.dokka.DokkaConfiguration.DokkaModuleDescription] files */
+ val dokkatooModuleFilesConsumer = "dokkatooModule".appendFormat()
+
+ /** Name of the [Configuration] that _provides_ all [org.jetbrains.dokka.DokkaConfiguration.DokkaModuleDescription] files to other projects */
+ val dokkatooModuleFilesProvider = "dokkatooModuleElements".appendFormat()
+
+ /**
+ * Classpath used to execute the Dokka Generator.
+ *
+ * Extends [dokkaPluginsClasspath], so Dokka plugins and their dependencies are included.
+ */
+ val dokkaGeneratorClasspath = "dokkatooGeneratorClasspath".appendFormat()
+
+ /** Dokka Plugins (including transitive dependencies, so this can be passed to the Dokka Generator Worker classpath) */
+ val dokkaPluginsClasspath = "dokkatooPlugin".appendFormat()
+
+ /**
+ * Dokka Plugins (excluding transitive dependencies) will be used to create Dokka Generator Parameters
+ *
+ * Generally, this configuration should not be invoked manually. Instead, use [dokkaPluginsClasspath].
+ */
+ val dokkaPluginsIntransitiveClasspath = "dokkatooPluginIntransitive".appendFormat()
+ }
+
+ @DokkatooInternalApi
+ class TaskNames(override val formatName: String?) : HasFormatName() {
+ val generate = "dokkatooGenerate".appendFormat()
+ val generatePublication = "dokkatooGeneratePublication".appendFormat()
+ val generateModule = "dokkatooGenerateModule".appendFormat()
+ val prepareModuleDescriptor = "prepareDokkatooModuleDescriptor".appendFormat()
+ }
+}
diff --git a/dokka-runners/dokkatoo/modules/dokkatoo-plugin/src/main/kotlin/DokkatooExtension.kt b/dokka-runners/dokkatoo/modules/dokkatoo-plugin/src/main/kotlin/DokkatooExtension.kt
new file mode 100644
index 00000000..d7b91541
--- /dev/null
+++ b/dokka-runners/dokkatoo/modules/dokkatoo-plugin/src/main/kotlin/DokkatooExtension.kt
@@ -0,0 +1,130 @@
+package org.jetbrains.dokka.dokkatoo
+
+import org.jetbrains.dokka.dokkatoo.dokka.DokkaPublication
+import org.jetbrains.dokka.dokkatoo.dokka.parameters.DokkaSourceSetSpec
+import org.jetbrains.dokka.dokkatoo.internal.*
+import java.io.Serializable
+import org.gradle.api.NamedDomainObjectContainer
+import org.gradle.api.file.DirectoryProperty
+import org.gradle.api.file.RegularFileProperty
+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(
+ objects: ObjectFactory,
+) : ExtensionAware, Serializable {
+
+ /** Directory into which [DokkaPublication]s will be produced */
+ abstract val dokkatooPublicationDirectory: DirectoryProperty
+
+ /** Directory into which Dokka Modules will be produced */
+ abstract val dokkatooModuleDirectory: DirectoryProperty
+
+ abstract val dokkatooConfigurationsDirectory: DirectoryProperty
+
+ /** Default Dokkatoo cache directory */
+ abstract val dokkatooCacheDirectory: DirectoryProperty
+
+ abstract val moduleName: Property<String>
+ abstract val moduleVersion: Property<String>
+ abstract val modulePath: Property<String>
+
+ /**
+ * An arbitrary string used to group source sets that originate from different Gradle subprojects.
+ *
+ * This is primarily used by Kotlin Multiplatform projects, which can have multiple source sets
+ * per subproject.
+ *
+ * Defaults to [the path of the subproject][org.gradle.api.Project.getPath].
+ */
+ abstract val sourceSetScopeDefault: Property<String>
+
+ /**
+ * The Konan home directory, which contains libraries for Kotlin/Native development.
+ *
+ * This is only required as a workaround to fetch the compile-time dependencies in Kotlin/Native
+ * projects with a version below 2.0.
+ */
+ // This property should be removed when Dokkatoo only supports KGP 2 or higher.
+ @DokkatooInternalApi
+ abstract val konanHome: RegularFileProperty
+
+ /**
+ * Configuration for creating Dokka Publications.
+ *
+ * Each publication will generate one Dokka site based on the included Dokka Source Sets.
+ *
+ * The type of site is determined by the Dokka Plugins. By default, an HTML site will be generated.
+ */
+ val dokkatooPublications: NamedDomainObjectContainer<DokkaPublication> =
+ extensions.adding(
+ "dokkatooPublications",
+ objects.domainObjectContainer { named -> objects.newInstance(named, pluginsConfiguration) }
+ )
+
+ /**
+ * Dokka Source Sets describe the source code that should be included in a Dokka Publication.
+ *
+ * Dokka will not generate documentation unless there is at least there is at least one Dokka Source Set.
+ *
+ * TODO make sure dokkatooSourceSets doc is up to date...
+ *
+ * Only source sets that are contained within _this project_ should be included here.
+ * To merge source sets from other projects, use the Gradle dependencies block.
+ *
+ * ```kotlin
+ * dependencies {
+ * // merge :other-project into this project's Dokka Configuration
+ * dokka(project(":other-project"))
+ * }
+ * ```
+ *
+ * Or, to include other Dokka Publications as a Dokka Module use
+ *
+ * ```kotlin
+ * dependencies {
+ * // include :other-project as a module in this project's Dokka Configuration
+ * dokkaModule(project(":other-project"))
+ * }
+ * ```
+ *
+ * Dokka will merge Dokka Source Sets from other subprojects if...
+ */
+ val dokkatooSourceSets: NamedDomainObjectContainer<DokkaSourceSetSpec> =
+ extensions.adding("dokkatooSourceSets", objects.domainObjectContainer())
+
+ /**
+ * 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 =
+ extensions.adding("pluginsConfiguration", objects.dokkaPluginParametersContainer())
+
+ /**
+ * Versions of dependencies that Dokkatoo will use to run Dokka Generator.
+ *
+ * These versions can be set to change the versions of dependencies that Dokkatoo uses defaults,
+ * or can be read to align versions.
+ */
+ val versions: Versions = extensions.adding("versions", objects.newInstance())
+