aboutsummaryrefslogtreecommitdiff
path: root/runners/gradle-plugin/src
diff options
context:
space:
mode:
authorKamil Doległo <kamilok1965@interia.pl>2020-05-20 12:05:26 +0200
committerPaweł Marks <Kordyjan@users.noreply.github.com>2020-06-15 13:15:30 +0200
commitf3baf10b4c882230d382bfcdd94163d070bd0e25 (patch)
tree128b63b10f05242cfce88da6714d9e04987b5651 /runners/gradle-plugin/src
parent645e02fb42bbf1cd3ee2773a014ea1e553e09229 (diff)
downloaddokka-f3baf10b4c882230d382bfcdd94163d070bd0e25.tar.gz
dokka-f3baf10b4c882230d382bfcdd94163d070bd0e25.tar.bz2
dokka-f3baf10b4c882230d382bfcdd94163d070bd0e25.zip
Rework dokka configuration and Gradle plugin
Diffstat (limited to 'runners/gradle-plugin/src')
-rw-r--r--runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/ConfigurationExtractor.kt152
-rw-r--r--runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/DokkaCollectorTask.kt7
-rw-r--r--runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/DokkaMultimoduleTask.kt10
-rw-r--r--runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/DokkaTask.kt169
-rw-r--r--runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/configurationImplementations.kt11
-rw-r--r--runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/main.kt24
-rw-r--r--runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/utils.kt17
7 files changed, 176 insertions, 214 deletions
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
index c69c6f67..44a0635f 100644
--- 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
@@ -1,9 +1,5 @@
package org.jetbrains.dokka.gradle
-import com.android.build.gradle.*
-import com.android.build.gradle.api.BaseVariant
-import com.android.builder.core.BuilderConstants
-import org.gradle.api.NamedDomainObjectCollection
import org.gradle.api.Project
import org.gradle.api.Task
import org.gradle.api.UnknownDomainObjectException
@@ -13,57 +9,60 @@ 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.KotlinCommonOptions
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.*
+import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation
+import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
import java.io.File
import java.io.Serializable
class ConfigurationExtractor(private val project: Project) {
- fun extractConfiguration(targetName: String, variantName: String?) =
- extractFromKotlinProject(targetName, variantName)
-
- fun extractFromKotlinProject(sourceSetName: String, variantName: String?): PlatformData? {
+ fun extractConfiguration(sourceSetName: String): PlatformData? {
val projectExtension = project.extensions.getByType(KotlinProjectExtension::class.java)
val sourceSet = projectExtension.sourceSets.findByName(sourceSetName)
?: run { project.logger.error("No source set with name '$sourceSetName' found"); return null }
val compilation = when (projectExtension) {
- is KotlinMultiplatformExtension -> projectExtension.targets.flatMap { it.compilations }
- .find { it.kotlinSourceSets.contains(sourceSet) }
+ 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
- } ?: run { project.logger.error("No compilation found for set with name '$sourceSetName'"); return null }
+ }
+
+ val sourceRoots = sourceSet.sourceFiles
+ val classpath = compilation?.classpath
+ ?: sourceRoots + sourceSet.allParentSourceFiles()
- val classpath = compilation.compileDependencyFiles.files.filter { it.exists() }
- val dependencies = (compilation.allKotlinSourceSets - sourceSet).flatMap { it.kotlin.sourceDirectories }
return PlatformData(
sourceSetName,
- classpath,
- sourceSet.kotlin.sourceDirectories.filter { it.exists() }.toList(),
- dependencies,
- sourceSet.dependsOn.map { it.name },
- compilation.target.targetName
+ 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(), emptyList(), "") }
+ ?.let { PlatformData(null, emptyList(), it.toList(), emptyList(), "") }
- fun extractFromKotlinTasks(passName: String, kotlinTasks: List<Task>): PlatformData? =
+ fun extractFromKotlinTasks(kotlinTasks: List<Task>): List<PlatformData> =
try {
- kotlinTasks.find { it.toString() == passName }?.let { extractFromKotlinTask(it) }
+ kotlinTasks.map { extractFromKotlinTask(it) }
} catch (e: Throwable) {
when (e) {
is UnknownDomainObjectException, is NoClassDefFoundError, is ClassNotFoundException ->
- extractFromKotlinTasksTheHardWay(passName, kotlinTasks)
+ listOfNotNull(extractFromKotlinTasksTheHardWay(kotlinTasks))
else -> throw e
}
}
@@ -80,18 +79,17 @@ class ConfigurationExtractor(private val project: Project) {
.flatMap { it.compilations }.firstOrNull { it.compileKotlinTask == task }
else -> throw e
}
- }.let {
+ }.let { compilation ->
PlatformData(
task.name,
- getClasspath(it),
- getSourceSet(it),
- getDependentSourceSetRoots(it),
- getDependentSourceSet(it).map { it.name },
- it?.platformType?.toString() ?: ""
+ compilation?.classpath.orEmpty(),
+ compilation?.sourceFiles.orEmpty(),
+ compilation?.dependentSourceSets?.map { it.name }.orEmpty(),
+ compilation?.platformType?.toString() ?: ""
)
}
- private fun extractFromKotlinTasksTheHardWay(passName: String, kotlinTasks: List<Task>): PlatformData? {
+ private fun extractFromKotlinTasksTheHardWay(kotlinTasks: List<Task>): PlatformData? {
val allClasspath = mutableSetOf<File>()
var allClasspathFileCollection: FileCollection = project.files()
val allSourceRoots = mutableSetOf<File>()
@@ -128,93 +126,41 @@ class ConfigurationExtractor(private val project: Project) {
}
classpath.addAll(project.files(allClasspath).toList())
- return PlatformData(null, classpath, allSourceRoots.toList(), emptyList(), emptyList(),"")
+ return PlatformData(null, classpath, allSourceRoots.toList(), emptyList(), "")
}
- private fun getSourceSet(target: KotlinTarget, variantName: String? = null): List<File> =
- if (variantName != null)
- getSourceSet(getCompilation(target, variantName))
- else
- getSourceSet(getMainCompilation(target))
-
- private fun getClasspath(target: KotlinTarget, variantName: String? = null): List<File> =
- if (target.isAndroidTarget()) {
- if (variantName != null)
- getClasspathFromAndroidTask(getCompilation(target, variantName))
- else
- getClasspathFromAndroidTask(getMainCompilation(target))
- } else {
- getClasspath(getMainCompilation(target))
- }
-
- private fun getSourceSet(compilation: KotlinCompilation<*>?): List<File> = compilation
- ?.kotlinSourceSets
- ?.flatMap { it.kotlin.sourceDirectories }
- ?.filter { it.exists() }
- .orEmpty()
+ private val KotlinCompilation<*>.sourceFiles: List<File>
+ get() = kotlinSourceSets.flatMap { it.sourceFiles }
- private fun getDependentSourceSet(compilation: KotlinCompilation<*>?) = compilation
- ?.let { it.allKotlinSourceSets - it.kotlinSourceSets }.orEmpty()
+ private val KotlinSourceSet.sourceFiles: List<File>
+ get() = kotlin.sourceDirectories.filter { it.exists() }.toList()
- private fun getDependentSourceSetRoots(compilation: KotlinCompilation<*>?): List<File> =
- getDependentSourceSet(compilation)?.flatMap { it.kotlin.sourceDirectories }
- .filter { it.exists() }
+ private val KotlinCompilation<*>.dependentSourceSets: Set<KotlinSourceSet>
+ get() = (allKotlinSourceSets - kotlinSourceSets)
- private fun getClasspath(compilation: KotlinCompilation<*>?): List<File> = compilation
- ?.compileDependencyFiles
- ?.files
- ?.toList()
- ?.filter { it.exists() }
- .orEmpty()
+ 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() ?: getClasspath(compilation)
-
- private fun getMainCompilation(target: KotlinTarget) =
- getCompilation(target, getMainCompilationName(target))
-
- private fun getCompilation(target: KotlinTarget, name: String) =
- target.compilations.getByName(name)
-
- private fun getMainCompilationName(target: KotlinTarget) = if (target.isAndroidTarget())
- getVariants(project).filter { it.buildType.name == BuilderConstants.RELEASE }.map { it.name }.first()
- else
- KotlinCompilation.MAIN_COMPILATION_NAME
-
- private fun getVariants(project: Project): Set<BaseVariant> {
- val androidExtension = project.extensions.getByName("android")
- val baseVariants = when (androidExtension) {
- is AppExtension -> androidExtension.applicationVariants.toSet()
- is LibraryExtension -> {
- androidExtension.libraryVariants.toSet() +
- if (androidExtension is FeatureExtension) {
- androidExtension.featureVariants.toSet()
- } else {
- emptySet<BaseVariant>()
- }
- }
- is TestExtension -> androidExtension.applicationVariants.toSet()
- else -> emptySet()
- }
- val testVariants = if (androidExtension is TestedExtension) {
- androidExtension.testVariants.toSet() + androidExtension.unitTestVariants.toSet()
- } else {
- emptySet<BaseVariant>()
- }
-
- return baseVariants + testVariants
- }
+ ?.classpath?.files?.toList() ?: getClasspathFromRegularTask(compilation)
- private fun getPlatformName(platform: KotlinPlatformType): String =
- if (platform == KotlinPlatformType.androidJvm) KotlinPlatformType.jvm.toString() else platform.toString()
+ private fun getClasspathFromRegularTask(compilation: KotlinCompilation<*>): List<File> =
+ compilation
+ .compileDependencyFiles
+ .files
+ .toList()
+ .filter { it.exists() }
data class PlatformData(
val name: String?,
val classpath: List<File>,
val sourceRoots: List<File>,
- val dependentSourceRoots: 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 f4fa7aaa..8c4e0c4c 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
@@ -20,7 +20,7 @@ open class DokkaCollectorTask : DefaultTask() {
@TaskAction
fun collect() {
- val passesConfigurations = getProjects(project).filter { it.name in modules }.map {
+ val passesConfigurations = getProjects(project).filter { it.name in modules }.mapNotNull {
val task = try {
it.tasks.getByName(DOKKA_TASK_NAME, DokkaTask::class)
} catch (e: UnknownTaskException) {
@@ -33,12 +33,11 @@ open class DokkaCollectorTask : DefaultTask() {
outputDir = outputDirectory
cacheRoot = passesConfigurations.first().cacheRoot
format = passesConfigurations.first().format
- generateIndexPages = passesConfigurations.first().generateIndexPages
}
configuration = passesConfigurations.fold(initial) { acc, it: GradleDokkaConfigurationImpl ->
- if(acc.format != it.format || acc.generateIndexPages != it.generateIndexPages || acc.cacheRoot != it.cacheRoot)
- throw IllegalStateException("Dokka task configurations differ on core arguments (format, generateIndexPages, cacheRoot)")
+ if(acc.format != it.format || acc.cacheRoot != it.cacheRoot)
+ throw IllegalStateException("Dokka task configurations differ on core arguments (format, cacheRoot)")
acc.passesConfigurations = acc.passesConfigurations + it.passesConfigurations
acc.pluginsClasspath = (acc.pluginsClasspath + it.pluginsClasspath).distinct()
acc
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 a1bfdb96..2ef85de2 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
@@ -35,9 +35,9 @@ open class DokkaMultimoduleTask : DefaultTask(), Configurable {
System.setProperty(DokkaTask.COLORS_ENABLED_PROPERTY, "false")
try {
- loadFatJar()
+ loadCore()
val bootstrapClass =
- ClassloaderContainer.fatJarClassLoader!!.loadClass("org.jetbrains.dokka.DokkaMultimoduleBootstrapImpl")
+ ClassloaderContainer.coreClassLoader!!.loadClass("org.jetbrains.dokka.DokkaMultimoduleBootstrapImpl")
val bootstrapInstance = bootstrapClass.constructors.first().newInstance()
val bootstrapProxy: DokkaBootstrap = automagicTypedProxy(
javaClass.classLoader,
@@ -85,10 +85,10 @@ open class DokkaMultimoduleTask : DefaultTask(), Configurable {
}
}
- private fun loadFatJar() {
- if (ClassloaderContainer.fatJarClassLoader == null) {
+ private fun loadCore() {
+ if (ClassloaderContainer.coreClassLoader == null) {
val jars = dokkaRuntime!!.resolve()
- ClassloaderContainer.fatJarClassLoader = URLClassLoader(
+ ClassloaderContainer.coreClassLoader = URLClassLoader(
jars.map { it.toURI().toURL() }.toTypedArray(),
ClassLoader.getSystemClassLoader().parent
)
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 2de95493..5a420d4d 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
@@ -15,15 +15,16 @@ import org.jetbrains.dokka.ReflectDsl
import org.jetbrains.dokka.ReflectDsl.isNotInstance
import org.jetbrains.dokka.gradle.ConfigurationExtractor.PlatformData
import org.jetbrains.dokka.plugability.Configurable
-import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType
import java.io.File
import java.net.URLClassLoader
import java.util.concurrent.Callable
import java.util.function.BiConsumer
+import kotlin.system.exitProcess
open class DokkaTask : DefaultTask(), Configurable {
private val ANDROID_REFERENCE_URL = Builder("https://developer.android.com/reference/").build()
private val GLOBAL_CONFIGURATION_NAME = "global" // Used for copying perPackageOptions to other platforms
+ private val configExtractor = ConfigurationExtractor(project)
@Suppress("MemberVisibilityCanBePrivate")
fun defaultKotlinTasks(): List<Task> = with(ReflectDsl) {
@@ -57,8 +58,6 @@ open class DokkaTask : DefaultTask(), Configurable {
var subProjects: List<String> = emptyList()
@Input
- var impliedPlatforms: MutableList<String> = arrayListOf()
-
override val pluginsConfiguration: Map<String, String> = mutableMapOf()
@Optional
@@ -66,54 +65,47 @@ open class DokkaTask : DefaultTask(), Configurable {
var cacheRoot: String? = null
@Classpath
- lateinit var pluginsConfig: Configuration
+ lateinit var pluginsClasspathConfiguration: Configuration
var dokkaSourceSets: NamedDomainObjectContainer<GradlePassConfigurationImpl>
@Suppress("UNCHECKED_CAST")
@Nested get() = (DslObject(this).extensions.getByName(SOURCE_SETS_EXTENSION_NAME) as NamedDomainObjectContainer<GradlePassConfigurationImpl>)
internal set(value) = DslObject(this).extensions.add(SOURCE_SETS_EXTENSION_NAME, value)
- var configuration: GradlePassConfigurationImpl
- @Suppress("UNCHECKED_CAST")
- @Nested get() = DslObject(this).extensions.getByType(GradlePassConfigurationImpl::class.java)
- internal set(value) = DslObject(this).extensions.add(CONFIGURATION_EXTENSION_NAME, value)
-
- var config: GradleDokkaConfigurationImpl? = null
-
- // Configure Dokka with closure in Gradle Kotlin DSL
- fun configuration(action: Action<in GradlePassConfigurationImpl>) = action.execute(configuration)
-
private val kotlinTasks: List<Task> by lazy {
- extractKotlinCompileTasks(
- configuration.collectKotlinTasks ?: { defaultKotlinTasks() })
+ extractKotlinCompileTasks({
+ dokkaSourceSets.map {
+ it.collectKotlinTasks?.invoke()
+ }
+ }.takeIf { it().isNotEmpty() } ?: { defaultKotlinTasks() }
+ )
}
- private val configExtractor = ConfigurationExtractor(project)
-
@Input
var disableAutoconfiguration: 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
- private fun loadFatJar() {
- if (ClassloaderContainer.fatJarClassLoader == null) {
+ private fun loadCore() {
+ if (ClassloaderContainer.coreClassLoader == null) {
val jars = dokkaRuntime!!.resolve()
- ClassloaderContainer.fatJarClassLoader = URLClassLoader(
+ ClassloaderContainer.coreClassLoader = URLClassLoader(
jars.map { it.toURI().toURL() }.toTypedArray(),
ClassLoader.getSystemClassLoader().parent
)
}
}
- private fun extractKotlinCompileTasks(collectTasks: () -> List<Any?>?): List<Task> {
+ protected fun extractKotlinCompileTasks(collectTasks: () -> List<Any?>?): List<Task> {
val inputList = (collectTasks.invoke() ?: emptyList()).filterNotNull()
val (paths, other) = inputList.partition { it is String }
- val taskContainer = project.tasks
-
val tasksByPath = paths.map {
- taskContainer.findByPath(it as String) ?: throw IllegalArgumentException("Task with path '$it' not found")
+ project.tasks.findByPath(it as String) ?: throw IllegalArgumentException("Task with path '$it' not found")
}
other
@@ -134,7 +126,7 @@ open class DokkaTask : DefaultTask(), Configurable {
private fun Iterable<String>.toProjects(): List<Project> =
project.subprojects.toList().filter { this.contains(it.name) }
- private fun collectSuppressedFiles(sourceRoots: List<SourceRoot>) =
+ protected open fun collectSuppressedFiles(sourceRoots: List<SourceRoot>) =
if (project.isAndroidProject()) {
val generatedRoot = project.buildDir.resolve("generated").absoluteFile
sourceRoots
@@ -147,25 +139,21 @@ open class DokkaTask : DefaultTask(), Configurable {
}
@TaskAction
- fun generate() {
- generateForConfig(config ?: getConfiguration())
- }
+ fun generate() = getConfiguration()?.let { generate(it) } ?: exitProcess(0)
- internal fun generateForConfig(configuration: GradleDokkaConfigurationImpl) {
+ protected open fun generate(configuration: GradleDokkaConfigurationImpl) {
outputDiagnosticInfo = true
val kotlinColorsEnabledBefore = System.getProperty(COLORS_ENABLED_PROPERTY) ?: "false"
System.setProperty(COLORS_ENABLED_PROPERTY, "false")
try {
- loadFatJar()
+ loadCore()
val bootstrapClass =
- ClassloaderContainer.fatJarClassLoader!!.loadClass("org.jetbrains.dokka.DokkaBootstrapImpl")
+ ClassloaderContainer.coreClassLoader!!.loadClass("org.jetbrains.dokka.DokkaBootstrapImpl")
val bootstrapInstance = bootstrapClass.constructors.first().newInstance()
val bootstrapProxy: DokkaBootstrap =
automagicTypedProxy(javaClass.classLoader, bootstrapInstance)
- val gson = GsonBuilder().setPrettyPrinting().create()
-
bootstrapProxy.configure(
BiConsumer { level, message ->
when (level) {
@@ -176,7 +164,7 @@ open class DokkaTask : DefaultTask(), Configurable {
"error" -> logger.error(message)
}
},
- gson.toJson(configuration)
+ GsonBuilder().setPrettyPrinting().create().toJson(configuration)
)
bootstrapProxy.generate()
@@ -186,68 +174,78 @@ open class DokkaTask : DefaultTask(), Configurable {
}
}
- internal fun getConfiguration(): GradleDokkaConfigurationImpl {
+ internal open fun getConfiguration(): GradleDokkaConfigurationImpl? {
val globalConfig = dokkaSourceSets.toList().find { it.name.toLowerCase() == GLOBAL_CONFIGURATION_NAME }
- val defaultModulesConfiguration = collectConfigurations()
- .map { defaultPassConfiguration(it, globalConfig) }
+ val defaultModulesConfiguration = passConfigurations
+ .map { defaultPassConfiguration(it, globalConfig) }.takeIf { it.isNotEmpty() }
+ ?: listOf(
+ defaultPassConfiguration(
+ collectSinglePassConfiguration(GradlePassConfigurationImpl("main")),
+ null
+ )
+ ).takeIf { project.isNotMultiplatformProject() } ?: emptyList()
+
+ if (defaultModulesConfiguration.isEmpty()) {
+ logger.error("No source sets to document found, exiting")
+ return null
+ }
+
return GradleDokkaConfigurationImpl().apply {
outputDir = project.file(outputDirectory).absolutePath
format = outputFormat
- generateIndexPages = true
- cacheRoot = cacheRoot
- impliedPlatforms = impliedPlatforms
+ cacheRoot = this@DokkaTask.cacheRoot
+ offlineMode = this@DokkaTask.offlineMode
passesConfigurations = defaultModulesConfiguration
- pluginsClasspath = pluginsConfig.resolve().toList()
+ pluginsClasspath = pluginsClasspathConfiguration.resolve().toList()
pluginsConfiguration = this@DokkaTask.pluginsConfiguration
}
}
- private fun collectConfigurations() =
- if (this.dokkaSourceSets.isNotEmpty()) collectMultipassConfiguration() else listOf(collectSinglePassConfiguration(configuration))
- private fun collectMultipassConfiguration() = dokkaSourceSets
- .filterNot { it.name.toLowerCase() == GLOBAL_CONFIGURATION_NAME }
- .map { collectSinglePassConfiguration(it) }
+ protected val passConfigurations: List<GradlePassConfigurationImpl>
+ get() = dokkaSourceSets
+ .filterNot { it.name.toLowerCase() == GLOBAL_CONFIGURATION_NAME }
+ .map { collectSinglePassConfiguration(it) }
- private fun collectSinglePassConfiguration(config: GradlePassConfigurationImpl): GradlePassConfigurationImpl {
+ protected fun collectSinglePassConfiguration(config: GradlePassConfigurationImpl): GradlePassConfigurationImpl {
val userConfig = config
- /*.let {
- if (it.collectKotlinTasks != null) {
- configExtractor.extractFromKotlinTasks(extractKotlinCompileTasks(it.collectKotlinTasks!!))
- ?.let { platformData -> mergeUserConfigurationAndPlatformData(it, platformData) } ?: it
- } else {
- it
+ .apply {
+ collectKotlinTasks?.let {
+ configExtractor.extractFromKotlinTasks(extractKotlinCompileTasks(it))
+ .fold(this) { config, platformData ->
+ mergeUserConfigurationAndPlatformData(config, platformData)
+ }
+ }
}
- }*/
if (disableAutoconfiguration) return userConfig
- val baseConfig = configExtractor.extractConfiguration(userConfig.name, userConfig.androidVariant)
+ val baseConfig = configExtractor.extractConfiguration(userConfig.name)
?.let { mergeUserConfigurationAndPlatformData(userConfig, it) }
?: if (this.dokkaSourceSets.isNotEmpty()) {
if (outputDiagnosticInfo)
logger.warn(
- "Could not find target with name: ${userConfig.name} in Kotlin Gradle Plugin, " +
- "using only user provided configuration for this target"
+ "Could not find source set with name: ${userConfig.name} in Kotlin Gradle Plugin, " +
+ "using only user provided configuration for this source set"
)
userConfig
} else {
- logger.warn("Could not find target with name: ${userConfig.name} in Kotlin Gradle Plugin")
- collectFromSinglePlatformOldPlugin(userConfig.name)
+ if (outputDiagnosticInfo)
+ logger.warn("Could not find source set with name: ${userConfig.name} in Kotlin Gradle Plugin")
+ collectFromSinglePlatformOldPlugin(userConfig.name, userConfig)
}
return if (subProjects.isNotEmpty()) {
try {
- subProjects.toProjects().fold(baseConfig) { config, subProject ->
+ subProjects.toProjects().fold(baseConfig) { configAcc, subProject ->
mergeUserConfigurationAndPlatformData(
- config,
- ConfigurationExtractor(subProject).extractConfiguration(config.name, config.androidVariant)!!
+ configAcc,
+ ConfigurationExtractor(subProject).extractConfiguration(userConfig.name)!!
)
}
} catch (e: NullPointerException) {
logger.warn(
- "Cannot extract sources from subProjects. Do you have the Kotlin plugin in version 1.3.30+ " +
- "and the Kotlin plugin applied in the root project?"
+ "Cannot extract sources from subProjects. Do you have the Kotlin plugin applied in the root project?"
)
baseConfig
}
@@ -256,49 +254,52 @@ open class DokkaTask : DefaultTask(), Configurable {
}
}
- private fun collectFromSinglePlatformOldPlugin(name: String) =
- configExtractor.extractFromKotlinTasks(name, kotlinTasks)
- ?.let { mergeUserConfigurationAndPlatformData(configuration, it) }
+ protected fun collectFromSinglePlatformOldPlugin(name: String, userConfig: GradlePassConfigurationImpl) =
+ kotlinTasks.find { it.name == name }
+ ?.let { configExtractor.extractFromKotlinTasks(listOf(it)) }
+ ?.singleOrNull()
+ ?.let { mergeUserConfigurationAndPlatformData(userConfig, it) }
?: configExtractor.extractFromJavaPlugin()
- ?.let { mergeUserConfigurationAndPlatformData(configuration, it) }
- ?: configuration
+ ?.let { mergeUserConfigurationAndPlatformData(userConfig, it) }
+ ?: userConfig
- private fun mergeUserConfigurationAndPlatformData(
+ protected fun mergeUserConfigurationAndPlatformData(
userConfig: GradlePassConfigurationImpl,
autoConfig: PlatformData
) =
userConfig.copy().apply {
- sourceSetName = autoConfig.name ?: ""
+ sourceSetID = autoConfig.name ?: ""
sourceRoots.addAll(userConfig.sourceRoots.union(autoConfig.sourceRoots.toSourceRoots()).distinct())
- dependentSourceRoots.addAll(userConfig.dependentSourceRoots.union(autoConfig.dependentSourceRoots.toSourceRoots()).distinct())
dependentSourceSets.addAll(userConfig.dependentSourceSets.union(autoConfig.dependentSourceSets).distinct())
classpath = userConfig.classpath.union(autoConfig.classpath.map { it.absolutePath }).distinct()
if (userConfig.platform == null && autoConfig.platform != "")
platform = autoConfig.platform
}
- private fun defaultPassConfiguration(
+ protected fun defaultPassConfiguration(
config: GradlePassConfigurationImpl,
globalConfig: GradlePassConfigurationImpl?
): GradlePassConfigurationImpl {
- if (config.moduleName == "") {
+ if (config.moduleName.isBlank()) {
config.moduleName = project.name
}
- if (config.sourceSetName.isEmpty()) {
- config.sourceSetName = config.name.substringBeforeLast("Main").takeIf(String::isNotBlank) ?: config.platform.toString()
+ if (config.sourceSetID.isBlank()) {
+ config.sourceSetID = config.name.takeIf(String::isNotBlank) ?: config.analysisPlatform.key
}
- config.classpath = (config.classpath as List<Any>).map { it.toString() }.distinct() // Workaround for Groovy's GStringImpl
+ config.displayName = config.sourceSetID.substringBeforeLast("Main")
+ config.classpath =
+ (config.classpath as List<Any>).map { it.toString() }.distinct() // Workaround for Groovy's GStringImpl
config.sourceRoots = config.sourceRoots.distinct().toMutableList()
config.samples = config.samples.map { project.file(it).absolutePath }
config.includes = config.includes.map { project.file(it).absolutePath }
config.suppressedFiles += collectSuppressedFiles(config.sourceRoots)
- if (project.isAndroidProject() && !config.noAndroidSdkLink) { // TODO: introduce Android as a separate Dokka platform?
+ if (project.isAndroidProject() && !config.noAndroidSdkLink) {
config.externalDocumentationLinks.add(ANDROID_REFERENCE_URL)
}
- if (config.platform != null && config.platform.toString().isNotBlank()) {
+ if (config.platform?.isNotBlank() == true) {
config.analysisPlatform = dokkaPlatformFromString(config.platform.toString())
}
- if (globalConfig != null) {
+ globalConfig?.let {
config.perPackageOptions.addAll(globalConfig.perPackageOptions)
config.externalDocumentationLinks.addAll(globalConfig.externalDocumentationLinks)
config.sourceLinks.addAll(globalConfig.sourceLinks)
@@ -309,7 +310,7 @@ open class DokkaTask : DefaultTask(), Configurable {
}
private fun dokkaPlatformFromString(platform: String) = when (platform.toLowerCase()) {
- KotlinPlatformType.androidJvm.toString().toLowerCase(), "androidjvm", "android" -> Platform.jvm
+ "androidjvm", "android" -> Platform.jvm
"metadata" -> Platform.common
else -> Platform.fromString(platform)
}
@@ -321,7 +322,7 @@ open class DokkaTask : DefaultTask(), Configurable {
// Needed for Gradle incremental build
@InputFiles
fun getInputFiles(): FileCollection {
- val config = collectConfigurations()
+ val config = passConfigurations
return project.files(config.flatMap { it.sourceRoots }.map { project.fileTree(File(it.path)) }) +
project.files(config.flatMap { it.includes }) +
project.files(config.flatMap { it.samples }.map { project.fileTree(File(it)) })
@@ -329,7 +330,7 @@ open class DokkaTask : DefaultTask(), Configurable {
@Classpath
fun getInputClasspath(): FileCollection =
- project.files((collectConfigurations().flatMap { it.classpath } as List<Any>).map { project.fileTree(File(it.toString())) })
+ project.files((passConfigurations.flatMap { it.classpath } as List<Any>).map { project.fileTree(File(it.toString())) })
companion object {
const val COLORS_ENABLED_PROPERTY = "kotlin.colors.enabled"
diff --git a/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/configurationImplementations.kt b/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/configurationImplementations.kt
index 7fdadd41..2787bb4e 100644
--- a/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/configurationImplementations.kt
+++ b/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/configurationImplementations.kt
@@ -27,9 +27,9 @@ class GradleSourceRootImpl: SourceRoot, Serializable {
open class GradlePassConfigurationImpl(@Transient val name: String = ""): PassConfiguration {
@Input @Optional override var classpath: List<String> = emptyList()
@Input override var moduleName: String = ""
- @Input override var sourceSetName: String = ""
+ @Input override var displayName: String = ""
+ @Input override var sourceSetID: String = ""
@Input override var sourceRoots: MutableList<SourceRoot> = mutableListOf()
- @Input override var dependentSourceRoots: MutableList<SourceRoot> = mutableListOf()
@Input override var dependentSourceSets: MutableList<String> = mutableListOf()
@Input override var samples: List<String> = emptyList()
@Input override var includes: List<String> = emptyList()
@@ -48,13 +48,9 @@ open class GradlePassConfigurationImpl(@Transient val name: String = ""): PassCo
@Input override var noJdkLink: Boolean = false
@Input var noAndroidSdkLink: Boolean = false
@Input override var suppressedFiles: List<String> = emptyList()
- @Input override var collectInheritedExtensionsFromLibraries: Boolean = false
@Input override var analysisPlatform: Platform = Platform.DEFAULT
@Input @Optional var platform: String? = null
- @Input override var targets: List<String> = emptyList()
- @Input @Optional override var sinceKotlin: String? = null
@Transient var collectKotlinTasks: (() -> List<Any?>?)? = null
- @Input @Optional @Transient var androidVariant: String? = null
fun kotlinTasks(taskSupplier: Callable<List<Any>>) {
collectKotlinTasks = { taskSupplier.call() }
@@ -129,9 +125,8 @@ class GradleDokkaModuleDescription: DokkaModuleDescription {
class GradleDokkaConfigurationImpl: DokkaConfiguration {
override var outputDir: String = ""
override var format: String = "html"
- override var generateIndexPages: Boolean = false
override var cacheRoot: String? = null
- override var impliedPlatforms: List<String> = emptyList()
+ override var offlineMode: Boolean = false
override var passesConfigurations: List<GradlePassConfigurationImpl> = emptyList()
override var pluginsClasspath: List<File> = emptyList()
override var pluginsConfiguration: Map<String, String> = mutableMapOf()
diff --git a/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/main.kt b/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/main.kt
index 1049656e..d2a0f043 100644
--- a/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/main.kt
+++ b/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/main.kt
@@ -8,23 +8,31 @@ import java.io.File
import java.io.InputStream
import java.util.*
-internal const val CONFIGURATION_EXTENSION_NAME = "configuration"
internal const val SOURCE_SETS_EXTENSION_NAME = "dokkaSourceSets"
internal const val DOKKA_TASK_NAME = "dokka"
internal const val DOKKA_COLLECTOR_TASK_NAME = "dokkaCollector"
internal const val DOKKA_MULTIMODULE_TASK_NAME = "dokkaMultimodule"
open class DokkaPlugin : Plugin<Project> {
-
override fun apply(project: Project) {
loadDokkaVersion()
val dokkaRuntimeConfiguration = addConfiguration(project)
val pluginsConfiguration = project.configurations.create("dokkaPlugins").apply {
dependencies.add(project.dependencies.create("org.jetbrains.dokka:dokka-base:${DokkaVersion.version}"))
+ attributes.attribute(
+ org.gradle.api.attributes.Usage.USAGE_ATTRIBUTE,
+ project.objects.named(org.gradle.api.attributes.Usage::class.java, "java-runtime")
+ )
+ isCanBeConsumed = false
}
addDokkaTasks(project, dokkaRuntimeConfiguration, pluginsConfiguration, DokkaTask::class.java)
addDokkaCollectorTasks(project, DokkaCollectorTask::class.java)
- addDokkaMultimoduleTasks(project.rootProject, dokkaRuntimeConfiguration, pluginsConfiguration, DokkaMultimoduleTask::class.java)
+ addDokkaMultimoduleTasks(
+ project.rootProject,
+ dokkaRuntimeConfiguration,
+ pluginsConfiguration,
+ DokkaMultimoduleTask::class.java
+ )
}
private fun loadDokkaVersion() =
@@ -32,7 +40,9 @@ open class DokkaPlugin : Plugin<Project> {
private fun addConfiguration(project: Project) =
project.configurations.create("dokkaRuntime").apply {
- defaultDependencies { dependencies -> dependencies.add(project.dependencies.create("org.jetbrains.dokka:dokka-core:${DokkaVersion.version}")) }
+ defaultDependencies { dependencies ->
+ dependencies.add(project.dependencies.create("org.jetbrains.dokka:dokka-core:${DokkaVersion.version}"))
+ }
}
private fun addDokkaTasks(
@@ -48,9 +58,8 @@ open class DokkaPlugin : Plugin<Project> {
}
project.tasks.withType(taskClass) { task ->
task.dokkaSourceSets = project.container(GradlePassConfigurationImpl::class.java)
- task.configuration = GradlePassConfigurationImpl()
task.dokkaRuntime = runtimeConfiguration
- task.pluginsConfig = pluginsConfiguration
+ task.pluginsClasspathConfiguration = pluginsConfiguration
task.outputDirectory = File(project.rootProject.buildDir, "$DOKKA_TASK_NAME/${project.name}").absolutePath
}
}
@@ -65,7 +74,6 @@ open class DokkaPlugin : Plugin<Project> {
project.tasks.create(DOKKA_COLLECTOR_TASK_NAME, taskClass)
}
project.tasks.withType(taskClass) { task ->
- task.modules = emptyList()
task.outputDirectory = File(project.buildDir, DOKKA_TASK_NAME).absolutePath
}
}
@@ -103,5 +111,5 @@ object DokkaVersion {
object ClassloaderContainer {
@JvmField
- var fatJarClassLoader: ClassLoader? = null
+ var coreClassLoader: ClassLoader? = null
} \ No newline at end of file
diff --git a/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/utils.kt b/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/utils.kt
index 3369a640..a4bf65ee 100644
--- a/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/utils.kt
+++ b/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/utils.kt
@@ -7,7 +7,7 @@ import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType
import org.jetbrains.kotlin.gradle.plugin.KotlinTarget
-fun Project.isAndroidProject() = try {
+internal fun Project.isAndroidProject() = try {
project.extensions.getByName("android")
true
} catch(e: UnknownDomainObjectException) {
@@ -16,4 +16,17 @@ fun Project.isAndroidProject() = try {
false
}
-fun KotlinTarget.isAndroidTarget() = this.platformType == KotlinPlatformType.androidJvm \ No newline at end of file
+internal fun Project.isNotMultiplatformProject() = !isMultiplatformProject()
+
+internal fun Project.isMultiplatformProject() = try {
+ project.extensions.getByType(KotlinMultiplatformExtension::class.java)
+ true
+} catch(e: UnknownDomainObjectException) {
+ false
+} catch (e: NoClassDefFoundError){
+ false
+} catch(e: ClassNotFoundException) {
+ false
+}
+
+internal fun KotlinTarget.isAndroidTarget() = this.platformType == KotlinPlatformType.androidJvm \ No newline at end of file