aboutsummaryrefslogtreecommitdiff
path: root/runners/gradle-plugin/src/main
diff options
context:
space:
mode:
authorsebastian.sellmair <sebastian.sellmair@jetbrains.com>2020-07-18 12:18:59 +0200
committerSebastian Sellmair <34319766+sellmair@users.noreply.github.com>2020-08-14 17:51:11 +0200
commiteae1ce49d18c2978b49166ea502bf2c109a85504 (patch)
tree477f39e33f14c71042f06eecc938d6efaa95e66c /runners/gradle-plugin/src/main
parent6c635551ed3ea0cfe5f04b54a98cb28225061d26 (diff)
downloaddokka-eae1ce49d18c2978b49166ea502bf2c109a85504.tar.gz
dokka-eae1ce49d18c2978b49166ea502bf2c109a85504.tar.bz2
dokka-eae1ce49d18c2978b49166ea502bf2c109a85504.zip
Simplify Dokka Gradle Plugin
Diffstat (limited to 'runners/gradle-plugin/src/main')
-rw-r--r--runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/AbstractDokkaParentTask.kt73
-rw-r--r--runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/AbstractDokkaTask.kt55
-rw-r--r--runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/ConfigurationExtractor.kt185
-rw-r--r--runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/DokkaCollectorTask.kt73
-rw-r--r--runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/DokkaMultimoduleTask.kt78
-rw-r--r--runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/DokkaTask.kt315
-rw-r--r--runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/GradleDokkaSourceSetBuilder.kt298
-rw-r--r--runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/GradleExternalDocumentationLinkBuilder.kt22
-rw-r--r--runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/GradlePackageOptionsBuilder.kt36
-rw-r--r--runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/GradleSourceLinkBuilder.kt25
-rw-r--r--runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/GradleSourceRootBuilder.kt15
-rw-r--r--runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/KotlinSourceSetGist.kt105
-rw-r--r--runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/ReflectDsl.kt72
-rw-r--r--runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/TaskDependencyInternalWithAdditions.kt20
-rw-r--r--runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/automagicTypedProxy.kt (renamed from runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/ProxyUtils.kt)9
-rw-r--r--runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/configurationImplementations.kt259
-rw-r--r--runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/dokka.kt7
-rw-r--r--runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/dokkaBootstrapFactory.kt (renamed from runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/DokkaBootstrapFactory.kt)11
-rw-r--r--runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/dokkaDefaultOutputDirectory.kt (renamed from runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/defaultDokkaOutputDirectory.kt)0
-rw-r--r--runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/dokkaSourceSetIDFactory.kt (renamed from runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/DokkaSourceSetIDFactory.kt)0
-rw-r--r--runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/gradleConfigurations.kt (renamed from runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/dokkaConfigurations.kt)0
-rw-r--r--runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/main.kt1
-rw-r--r--runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/sourceSetKotlinGistConfiguration.kt21
-rw-r--r--runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/utils.kt12
24 files changed, 751 insertions, 941 deletions
diff --git a/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/AbstractDokkaParentTask.kt b/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/AbstractDokkaParentTask.kt
new file mode 100644
index 00000000..bf8308bf
--- /dev/null
+++ b/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/AbstractDokkaParentTask.kt
@@ -0,0 +1,73 @@
+package org.jetbrains.dokka.gradle
+
+import org.gradle.api.Project
+import org.gradle.api.tasks.Input
+import org.gradle.api.tasks.Internal
+import org.gradle.api.tasks.Nested
+import org.jetbrains.dokka.DokkaBootstrap
+import org.jetbrains.dokka.DokkaBootstrapImpl
+import kotlin.reflect.KClass
+
+// TODO NOW: Test UP-TO-DATE behaviour
+abstract class AbstractDokkaParentTask(
+ bootstrapClass: KClass<out DokkaBootstrap> = DokkaBootstrapImpl::class
+) : AbstractDokkaTask(bootstrapClass) {
+
+ @Input
+ open var dokkaTaskNames: Set<String> = setOf()
+
+ @Input
+ var subprojectPaths: Set<String> = project.subprojects.map { project -> project.path }.toSet()
+
+ @get:Internal
+ val subprojects: List<Project>
+ get() = subprojectPaths.map { path -> project.project(path) }.distinct()
+
+ @get:Nested
+ internal val dokkaTasks: List<AbstractDokkaTask>
+ get() = dokkaTaskNames.flatMap { dokkaTaskName -> findSubprojectDokkaTasks(dokkaTaskName) }
+
+
+ /**
+ * Will remove a single project from participating in this parent task.
+ * Note: This will not remove the [project]s subprojects.
+ *
+ * @see removeAllProjects
+ */
+ fun removeSubproject(project: Project) {
+ subprojectPaths = subprojectPaths - project.path
+ }
+
+ /**
+ * Will remove the [project] and all its subprojects from participating in this parent task.
+ * @see removeSubproject
+ */
+ fun removeAllProjects(project: Project) {
+ project.allprojects.forEach(::removeSubproject)
+ }
+
+ /**
+ * Includes the [project] to participate in this parent task.
+ * Note: This will not include any of the [project]s subprojects.
+ * @see addAllProjects
+ */
+ fun addSubproject(project: Project) {
+ subprojectPaths = (subprojectPaths + project.path)
+ }
+
+ /**
+ * Includes the [project] and all its subprojects to participate in this parent task.
+ * @see addSubproject
+ */
+ fun addAllProjects(project: Project) {
+ project.allprojects.forEach(::addSubproject)
+ }
+
+ protected fun findSubprojectDokkaTasks(dokkaTaskNames: Set<String>): List<AbstractDokkaTask> {
+ return dokkaTaskNames.flatMap { dokkaTaskName -> findSubprojectDokkaTasks(dokkaTaskName) }
+ }
+
+ private fun findSubprojectDokkaTasks(dokkaTaskName: String): List<AbstractDokkaTask> {
+ return subprojects.mapNotNull { subproject -> subproject.tasks.findByName(dokkaTaskName) as? DokkaTask }
+ }
+}
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 1269b305..6413d788 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
@@ -1,21 +1,33 @@
package org.jetbrains.dokka.gradle
import org.gradle.api.DefaultTask
-import org.gradle.api.Project
import org.gradle.api.artifacts.Configuration
-import org.gradle.api.attributes.Usage
-import org.gradle.api.tasks.Classpath
-import org.gradle.api.tasks.Input
-import org.gradle.api.tasks.Internal
-import org.gradle.api.tasks.TaskAction
-import org.gradle.kotlin.dsl.dependencies
+import org.gradle.api.plugins.JavaBasePlugin
+import org.gradle.api.tasks.*
import org.jetbrains.dokka.DokkaBootstrap
+import org.jetbrains.dokka.DokkaConfigurationImpl
import org.jetbrains.dokka.plugability.Configurable
+import org.jetbrains.dokka.toJsonString
+import java.io.File
+import java.util.function.BiConsumer
+import kotlin.reflect.KClass
+abstract class AbstractDokkaTask(
+ private val bootstrapClass: KClass<out DokkaBootstrap> = DokkaBootstrap::class
+) : DefaultTask(), Configurable {
+
+ @OutputDirectory
+ var outputDirectory: File = defaultDokkaOutputDirectory()
+
+ @Optional
+ @InputDirectory
+ var cacheRoot: File? = null
+
+ @Input
+ var failOnWarning: Boolean = false
-abstract class AbstractDokkaTask : DefaultTask(), Configurable {
@Input
- var outputDirectory: String = defaultDokkaOutputDirectory().absolutePath
+ var offlineMode: Boolean = false
@Input
override val pluginsConfiguration: MutableMap<String, String> = mutableMapOf()
@@ -27,19 +39,26 @@ abstract class AbstractDokkaTask : DefaultTask(), Configurable {
val runtime: Configuration = project.maybeCreateDokkaRuntimeConfiguration(name)
@TaskAction
- protected fun run() {
- val kotlinColorsEnabledBefore = System.getProperty(DokkaTask.COLORS_ENABLED_PROPERTY) ?: "false"
- System.setProperty(DokkaTask.COLORS_ENABLED_PROPERTY, "false")
- try {
+ protected open fun generateDocumentation() {
+ DokkaBootstrap(runtime, bootstrapClass).apply {
+ configure(buildDokkaConfiguration().toJsonString(), createProxyLogger())
generate()
- } finally {
- System.setProperty(DokkaTask.COLORS_ENABLED_PROPERTY, kotlinColorsEnabledBefore)
}
}
- protected abstract fun generate()
+ internal abstract fun buildDokkaConfiguration(): DokkaConfigurationImpl
+
+ private fun createProxyLogger(): BiConsumer<String, String> = BiConsumer { level, message ->
+ when (level) {
+ "debug" -> logger.debug(message)
+ "info" -> logger.info(message)
+ "progress" -> logger.lifecycle(message)
+ "warn" -> logger.warn(message)
+ "error" -> logger.error(message)
+ }
+ }
- protected fun DokkaBootstrap(bootstrapClassFQName: String): DokkaBootstrap {
- return DokkaBootstrap(runtime, bootstrapClassFQName)
+ init {
+ group = JavaBasePlugin.DOCUMENTATION_GROUP
}
}
diff --git a/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/ConfigurationExtractor.kt b/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/ConfigurationExtractor.kt
deleted file mode 100644
index 6217703f..00000000
--- a/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/ConfigurationExtractor.kt
+++ /dev/null
@@ -1,185 +0,0 @@
-package org.jetbrains.dokka.gradle
-
-import org.gradle.api.Project
-import org.gradle.api.Task
-import org.gradle.api.UnknownDomainObjectException
-import org.gradle.api.artifacts.ResolveException
-import org.gradle.api.file.FileCollection
-import org.gradle.api.plugins.JavaPluginConvention
-import org.gradle.api.tasks.SourceSet
-import org.gradle.api.tasks.compile.AbstractCompile
-import org.jetbrains.dokka.ReflectDsl
-import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension
-import org.jetbrains.kotlin.gradle.dsl.KotlinProjectExtension
-import org.jetbrains.kotlin.gradle.dsl.KotlinSingleTargetExtension
-import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation
-import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet
-import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeCompilation
-import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
-import java.io.File
-import java.io.Serializable
-
-class ConfigurationExtractor(private val project: Project) {
- fun extractConfiguration(sourceSetName: String): PlatformData? {
- val projectExtension = project.extensions.findByType(KotlinProjectExtension::class.java) ?: run {
- project.logger.error("Missing kotlin project extension")
- return null
- }
-
- val sourceSet = projectExtension.sourceSets.findByName(sourceSetName) ?: run {
- project.logger.error("No source set with name '$sourceSetName' found")
- return null
- }
-
- val compilation = try {
- when (projectExtension) {
- is KotlinMultiplatformExtension -> {
- val targets = projectExtension.targets.flatMap { it.compilations }
- targets.find { it.name == sourceSetName }
- ?: targets.find { it.kotlinSourceSets.contains(sourceSet) }
- }
- is KotlinSingleTargetExtension -> projectExtension.target.compilations.find {
- it.kotlinSourceSets.contains(sourceSet)
- }
- else -> null
- }
- } catch (e: NoClassDefFoundError) { // Old Kotlin plugin versions
- null
- }
-
- val sourceRoots = sourceSet.sourceFiles
- val classpath = compilation?.classpath
- ?: sourceRoots + sourceSet.allParentSourceFiles()
-
- return PlatformData(
- sourceSetName,
- classpath.filter { it.exists() },
- sourceRoots,
- sourceSet.dependsOn.map { it.name },
- compilation?.target?.platformType?.name ?: "common"
- )
- }
-
- private fun KotlinSourceSet.allParentSourceFiles(): List<File> =
- sourceFiles + dependsOn.flatMap { it.allParentSourceFiles() }
-
- fun extractFromJavaPlugin(): PlatformData? =
- project.convention.findPlugin(JavaPluginConvention::class.java)
- ?.run { sourceSets.findByName(SourceSet.MAIN_SOURCE_SET_NAME)?.allSource?.srcDirs }
- ?.let { PlatformData(null, emptyList(), it.toList(), emptyList(), "") }
-
- fun extractFromKotlinTasks(kotlinTasks: List<Task>): List<PlatformData> =
- try {
- kotlinTasks.map { extractFromKotlinTask(it) }
- } catch (e: Throwable) {
- when (e) {
- is UnknownDomainObjectException, is NoClassDefFoundError, is ClassNotFoundException ->
- listOfNotNull(extractFromKotlinTasksTheHardWay(kotlinTasks))
- else -> throw e
- }
- }
-
- private fun extractFromKotlinTask(task: Task): PlatformData =
- try {
- project.extensions.getByType(KotlinSingleTargetExtension::class.java).target
- .compilations
- .find { it.compileKotlinTask == task }
- } catch (e: Throwable) {
- when (e) {
- is UnknownDomainObjectException, is NoClassDefFoundError, is ClassNotFoundException ->
- project.extensions.getByType(KotlinMultiplatformExtension::class.java).targets
- .flatMap { it.compilations }.firstOrNull { it.compileKotlinTask == task }
- else -> throw e
- }
- }.let { compilation ->
- PlatformData(
- task.name,
- compilation?.classpath.orEmpty(),
- compilation?.sourceFiles.orEmpty(),
- compilation?.dependentSourceSets?.map { it.name }.orEmpty(),
- compilation?.platformType?.toString() ?: ""
- )
- }
-
- private fun extractFromKotlinTasksTheHardWay(kotlinTasks: List<Task>): PlatformData? {
- val allClasspath = mutableSetOf<File>()
- var allClasspathFileCollection: FileCollection = project.files()
- val allSourceRoots = mutableSetOf<File>()
-
- kotlinTasks.forEach {
- with(ReflectDsl) {
- val taskSourceRoots: List<File>
- val abstractKotlinCompileClz: Class<out Any>
- try {
- taskSourceRoots = it["sourceRootsContainer"]["sourceRoots"].v()
- abstractKotlinCompileClz = DokkaTask.getAbstractKotlinCompileFor(it)!!
- } catch (e: NullPointerException) {
- println("Error during extraction of sources from kotlinTasks. This may be a result of outdated Kotlin Gradle Plugin")
- return null
- }
-
- val taskClasspath: Iterable<File> =
- (it["getClasspath", AbstractCompile::class].takeIfIsFunc()?.invoke()
- ?: it["compileClasspath", abstractKotlinCompileClz].takeIfIsProp()?.v()
- ?: it["getClasspath", abstractKotlinCompileClz]())
-
- if (taskClasspath is FileCollection) {
- allClasspathFileCollection += taskClasspath
- } else {
- allClasspath += taskClasspath
- }
- allSourceRoots += taskSourceRoots.filter { it.exists() }
- }
- }
- val classpath: MutableList<File> = try {
- allClasspathFileCollection.toMutableList()
- } catch (e: ResolveException) {
- mutableListOf()
- }
- classpath.addAll(project.files(allClasspath).toList())
-
- return PlatformData(null, classpath, allSourceRoots.toList(), emptyList(), "")
- }
-
- private val KotlinCompilation<*>.sourceFiles: List<File>
- get() = kotlinSourceSets.flatMap { it.sourceFiles }
-
- private val KotlinSourceSet.sourceFiles: List<File>
- get() = kotlin.sourceDirectories.filter { it.exists() }.toList()
-
- private val KotlinCompilation<*>.dependentSourceSets: Set<KotlinSourceSet>
- get() = (allKotlinSourceSets - kotlinSourceSets)
-
- private val KotlinCompilation<*>.classpath: List<File>
- get() = if (target.isAndroidTarget()) {
- getClasspathFromAndroidTask(this)
- } else {
- getClasspathFromRegularTask(this)
- }
-
- // This is a workaround for KT-33893
- private fun getClasspathFromAndroidTask(compilation: KotlinCompilation<*>): List<File> = (compilation
- .compileKotlinTask as? KotlinCompile)
- ?.classpath?.files?.toList() ?: getClasspathFromRegularTask(compilation)
-
- private fun getClasspathFromRegularTask(compilation: KotlinCompilation<*>): List<File> {
- // explicit dependencies of the compilation
- val ownDependencyFiles: Set<File> = compilation.compileDependencyFiles.files
-
- // the dependencies provided by the platform (e.g. Kotlin/Native platform libs)
- val platformDependencyFiles: Set<File> = (compilation as? KotlinNativeCompilation)
- ?.target?.project?.configurations
- ?.findByName(compilation.defaultSourceSet.implementationMetadataConfigurationName)?.files
- ?: emptySet()
-
- return (ownDependencyFiles + platformDependencyFiles).toList().filter { it.exists() }
- }
-
- data class PlatformData(
- val name: String?,
- val classpath: List<File>,
- val sourceRoots: List<File>,
- val dependentSourceSets: List<String>,
- val platform: String
- ) : Serializable
-}
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 8d337795..7a73d633 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
@@ -1,59 +1,24 @@
package org.jetbrains.dokka.gradle
-import com.google.gson.GsonBuilder
-import org.gradle.api.plugins.JavaBasePlugin.DOCUMENTATION_GROUP
-import org.gradle.api.tasks.Input
-import org.jetbrains.dokka.toJsonString
-
-open class DokkaCollectorTask : AbstractDokkaTask() {
-
- @Input
- var modules: List<String> = emptyList()
-
- @Input
- var dokkaTaskNames: Set<String> = setOf()
-
- override fun generate() {
- val configurations = getSubprojectDokkaTasks(dokkaTaskNames)
- .mapNotNull { dokkaTask -> dokkaTask.getConfigurationOrNull() }
-
- val initial = GradleDokkaConfigurationImpl().apply {
- outputDir = outputDirectory
- cacheRoot = configurations.first().cacheRoot
- }
-
- val configuration = configurations.fold(initial) { acc, it: GradleDokkaConfigurationImpl ->
- if (acc.cacheRoot != it.cacheRoot)
- throw IllegalStateException("Dokka task configurations differ on core argument cacheRoot")
- acc.sourceSets = acc.sourceSets + it.sourceSets
- acc.pluginsClasspath = (acc.pluginsClasspath + it.pluginsClasspath).distinct()
- acc
+import org.jetbrains.dokka.DokkaConfigurationImpl
+
+open class DokkaCollectorTask : AbstractDokkaParentTask() {
+
+ override fun buildDokkaConfiguration(): DokkaConfigurationImpl {
+ val initialDokkaConfiguration = DokkaConfigurationImpl(
+ outputDir = outputDirectory,
+ cacheRoot = cacheRoot,
+ failOnWarning = failOnWarning,
+ offlineMode = offlineMode,
+ pluginsClasspath = plugins.resolve().toList(),
+ )
+
+ val subprojectDokkaConfigurations = dokkaTasks.map { dokkaTask -> dokkaTask.buildDokkaConfiguration() }
+ return subprojectDokkaConfigurations.fold(initialDokkaConfiguration) { acc, it: DokkaConfigurationImpl ->
+ acc.copy(
+ sourceSets = acc.sourceSets + it.sourceSets,
+ pluginsClasspath = acc.pluginsClasspath + it.pluginsClasspath
+ )
}
-
- val bootstrap = DokkaBootstrap("org.jetbrains.dokka.DokkaBootstrapImpl")
- bootstrap.configure(configuration.toJsonString()) { level, message ->
- when (level) {
- "debug" -> logger.debug(message)
- "info" -> logger.info(message)
- "progress" -> logger.lifecycle(message)
- "warn" -> logger.warn(message)
- "error" -> logger.error(message)
- }
- }
- bootstrap.generate()
- }
-
- private fun getSubprojectDokkaTasks(dokkaTaskName: String): List<DokkaTask> {
- return project.subprojects
- .filter { subproject -> subproject.name in modules }
- .mapNotNull { subproject -> subproject.tasks.findByName(dokkaTaskName) as? DokkaTask }
- }
-
- private fun getSubprojectDokkaTasks(dokkaTaskNames: Set<String>): List<DokkaTask> {
- return dokkaTaskNames.flatMap { dokkaTaskName -> getSubprojectDokkaTasks(dokkaTaskName) }
- }
-
- init {
- group = DOCUMENTATION_GROUP
}
}
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 986b883a..8369954b 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
@@ -1,66 +1,40 @@
package org.jetbrains.dokka.gradle
-import org.gradle.api.plugins.JavaBasePlugin.DOCUMENTATION_GROUP
+import org.gradle.api.internal.tasks.TaskDependencyInternal
import org.gradle.api.tasks.Input
-import org.gradle.api.tasks.Internal
+import org.jetbrains.dokka.DokkaConfigurationImpl
+import org.jetbrains.dokka.DokkaModuleDescriptionImpl
+import org.jetbrains.dokka.DokkaMultimoduleBootstrapImpl
import org.jetbrains.dokka.plugability.Configurable
-import org.jetbrains.dokka.toJsonString
-open class DokkaMultimoduleTask : AbstractDokkaTask(), Configurable {
+open class DokkaMultimoduleTask : AbstractDokkaParentTask(DokkaMultimoduleBootstrapImpl::class), Configurable {
+ /**
+ * Name of the file containing all necessary module information.
+ * This file has to be placed inside the subrpojects root directory.
+ */
@Input
var documentationFileName: String = "README.md"
-
- @Input
- var dokkaTaskNames: Set<String> = setOf()
- set(value) {
- field = value.toSet()
- setDependsOn(getSubprojectDokkaTasks(value))
- }
-
-
- override fun generate() {
- val bootstrap = DokkaBootstrap("org.jetbrains.dokka.DokkaMultimoduleBootstrapImpl")
- val configuration = getConfiguration()
- bootstrap.configure(configuration.toJsonString()) { level, message ->
- when (level) {
- "debug" -> logger.debug(message)
- "info" -> logger.info(message)
- "progress" -> logger.lifecycle(message)
- "warn" -> logger.warn(message)
- "error" -> logger.error(message)
- }
- }
- bootstrap.generate()
+ override fun getTaskDependencies(): TaskDependencyInternal {
+ return super.getTaskDependencies() + dokkaTasks
}
- @Internal
- internal fun getConfiguration(): GradleDokkaConfigurationImpl =
- GradleDokkaConfigurationImpl().apply {
- outputDir = project.file(outputDirectory).absolutePath
- pluginsClasspath = plugins.resolve().toList()
- pluginsConfiguration = this@DokkaMultimoduleTask.pluginsConfiguration
- modules = getSubprojectDokkaTasks(dokkaTaskNames).map { dokkaTask ->
- GradleDokkaModuleDescription().apply {
- name = dokkaTask.project.name
- path = dokkaTask.project.projectDir.resolve(dokkaTask.outputDirectory)
- .toRelativeString(project.file(outputDirectory))
- docFile = dokkaTask.project.projectDir.resolve(documentationFileName).absolutePath
- }
+ override fun buildDokkaConfiguration(): DokkaConfigurationImpl {
+ return DokkaConfigurationImpl(
+ outputDir = outputDirectory,
+ cacheRoot = cacheRoot,
+ pluginsConfiguration = pluginsConfiguration,
+ failOnWarning = failOnWarning,
+ offlineMode = offlineMode,
+ pluginsClasspath = plugins.resolve().toList(),
+ modules = dokkaTasks.map { dokkaTask ->
+ DokkaModuleDescriptionImpl(
+ name = dokkaTask.project.name,
+ path = dokkaTask.outputDirectory.relativeTo(outputDirectory),
+ docFile = dokkaTask.project.projectDir.resolve(documentationFileName).absoluteFile
+ )
}
- }
-
- private fun getSubprojectDokkaTasks(dokkaTaskName: String): List<DokkaTask> {
- return project.subprojects
- .mapNotNull { subproject -> subproject.tasks.findByName(dokkaTaskName) as? DokkaTask }
- }
-
- private fun getSubprojectDokkaTasks(dokkaTaskNames: Set<String>): List<DokkaTask> {
- return dokkaTaskNames.flatMap { dokkaTaskName -> getSubprojectDokkaTasks(dokkaTaskName) }
- }
-
- init {
- group = DOCUMENTATION_GROUP
+ )
}
}
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 b4601acf..a74068ae 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
@@ -1,306 +1,35 @@
package org.jetbrains.dokka.gradle
import org.gradle.api.NamedDomainObjectContainer
-import org.gradle.api.Project
-import org.gradle.api.Task
-import org.gradle.api.file.FileCollection
import org.gradle.api.internal.plugins.DslObject
-import org.gradle.api.plugins.JavaBasePlugin
-import org.gradle.api.tasks.*
-import org.jetbrains.dokka.DokkaConfiguration.ExternalDocumentationLink.Builder
-import org.jetbrains.dokka.DokkaConfiguration.SourceRoot
-import org.jetbrains.dokka.DokkaException
-import org.jetbrains.dokka.Platform
-import org.jetbrains.dokka.ReflectDsl
-import org.jetbrains.dokka.ReflectDsl.isNotInstance
-import org.jetbrains.dokka.gradle.ConfigurationExtractor.PlatformData
-import org.jetbrains.dokka.toJsonString
-import java.io.File
-import java.net.URL
-import java.util.concurrent.Callable
+import org.gradle.api.tasks.Nested
+import org.jetbrains.dokka.DokkaBootstrapImpl
+import org.jetbrains.dokka.DokkaConfigurationImpl
+import org.jetbrains.dokka.build
-open class DokkaTask : AbstractDokkaTask() {
- private val ANDROID_REFERENCE_URL = Builder("https://developer.android.com/reference/").build()
-
- private val ANDROIDX_REFERENCE_URL = Builder(
- url = URL("https://developer.android.com/reference/kotlin/"),
- packageListUrl = URL("https://developer.android.com/reference/androidx/package-list")
- ).build()
-
- private val configExtractor = ConfigurationExtractor(project)
-
- @Suppress("MemberVisibilityCanBePrivate")
- fun defaultKotlinTasks(): List<Task> = with(ReflectDsl) {
- val abstractKotlinCompileClz = try {
- project.buildscript.classLoader.loadClass(ABSTRACT_KOTLIN_COMPILE)
- } catch (cnfe: ClassNotFoundException) {
- logger.warn("$ABSTRACT_KOTLIN_COMPILE class not found, default kotlin tasks ignored")
- return@with emptyList<Task>()
- }
-
- return@with project.tasks.filter { it isInstance abstractKotlinCompileClz }.filter { "Test" !in it.name }
- }
-
- init {
- group = JavaBasePlugin.DOCUMENTATION_GROUP
- description = "Generates dokka documentation for Kotlin"
-
- @Suppress("LeakingThis")
- dependsOn(Callable { kotlinTasks.map { it.taskDependencies } })
- }
-
- @Optional
- @Input
- var cacheRoot: String? = null
-
-
- /**
- * Hack used by DokkaCollector to enforce a different configuration to be used.
- */
- @get:Internal
- internal var enforcedConfiguration: GradleDokkaConfigurationImpl? = null
+open class DokkaTask : AbstractDokkaTask(DokkaBootstrapImpl::class) {
@get:Nested
- val dokkaSourceSets: NamedDomainObjectContainer<GradleDokkaSourceSet> =
- project.container(GradleDokkaSourceSet::class.java) { name -> GradleDokkaSourceSet(name, project) }
- .also { container -> DslObject(this).extensions.add("dokkaSourceSets", container) }
-
-
- private val kotlinTasks: List<Task> by lazy {
- extractKotlinCompileTasks(
- dokkaSourceSets.mapNotNull {
- it.collectKotlinTasks?.invoke()
- }.takeIf { it.isNotEmpty() }?.flatten() ?: defaultKotlinTasks()
- )
- }
-
- @Input
- var disableAutoconfiguration: Boolean = false
-
- @Input
- var failOnWarning: Boolean = false
-
- @Input
- var offlineMode: Boolean = false
-
- private var outputDiagnosticInfo: Boolean =
- false // Workaround for Gradle, which fires some methods (like collectConfigurations()) multiple times in its lifecycle
-
- protected fun extractKotlinCompileTasks(collectTasks: List<Any?>?): List<Task> {
- val inputList = (collectTasks ?: emptyList()).filterNotNull()
- val (paths, other) = inputList.partition { it is String }
-
- val tasksByPath = paths.map {
- project.tasks.findByPath(it as String) ?: throw IllegalArgumentException("Task with path '$it' not found")
- }
-
- other
- .filter { it !is Task || it isNotInstance getAbstractKotlinCompileFor(it) }
- .forEach { throw IllegalArgumentException("Illegal entry in kotlinTasks, must be subtype of $ABSTRACT_KOTLIN_COMPILE or String, but was $it") }
-
- tasksByPath
- .filter { it isNotInstance getAbstractKotlinCompileFor(it) }
- .forEach { throw IllegalArgumentException("Illegal task path in kotlinTasks, must be subtype of $ABSTRACT_KOTLIN_COMPILE, but was $it") }
-
- @Suppress("UNCHECKED_CAST")
- return (tasksByPath + other) as List<Task>
- }
-
- private fun Iterable<File>.toSourceRoots(): List<GradleSourceRootImpl> =
- this.filter { it.exists() }.map { GradleSourceRootImpl().apply { path = it.path } }
-
- private fun Iterable<String>.toProjects(): List<Project> =
- project.subprojects.toList().filter { this.contains(it.name) }
-
- protected open fun collectSuppressedFiles(sourceRoots: List<SourceRoot>) =
- if (project.isAndroidProject()) {
- val generatedRoot = project.buildDir.resolve("generated").absoluteFile
- sourceRoots
- .map { File(it.path) }
- .filter { it.startsWith(generatedRoot) }
- .flatMap { it.walk().toList() }
- .map { it.absolutePath }
- } else {
- emptyList()