diff options
Diffstat (limited to 'runners/gradle-plugin/src/main/kotlin')
5 files changed, 102 insertions, 109 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 24bcd96d..393a3077 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 @@ -13,72 +13,58 @@ 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.KotlinCompilation -import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType -import org.jetbrains.kotlin.gradle.plugin.KotlinTarget +import org.jetbrains.kotlin.gradle.plugin.* 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?) = if (project.isMultiplatformProject()) { - extractFromMultiPlatform(targetName, variantName) - } else { - extractFromSinglePlatform(variantName) - } - - fun extractFromSinglePlatform(variantName: String? = null): PlatformData? { - val target: KotlinTarget - try { - target = project.extensions.getByType(KotlinSingleTargetExtension::class.java).target - } catch (e: Throwable) { - when (e){ - is UnknownDomainObjectException, is NoClassDefFoundError, is ClassNotFoundException -> - return null - else -> throw e + fun extractConfiguration(targetName: String, variantName: String?) = + extractFromKotlinProject(targetName, variantName) + + fun extractFromKotlinProject(sourceSetName: String, variantName: 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 } + .first { it.kotlinSourceSets.contains(sourceSet) } + is KotlinSingleTargetExtension -> projectExtension.target.compilations.find { + it.kotlinSourceSets.contains( + sourceSet + ) } - } - - return try { - PlatformData(null, getClasspath(target, variantName), getSourceSet(target, variantName), getPlatformName(target.platformType)) - } catch(e: NoSuchMethodError){ - null - } + else -> null + } ?: run { project.logger.error("No compilation found for set with name '$sourceSetName'"); return null } + + 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, + compilation.target.targetName + ) } - private fun extractFromMultiPlatform(targetName: String, variantName: String?): PlatformData? = - try { - project.extensions.getByType(KotlinMultiplatformExtension::class.java).targets - } catch (e: Throwable) { - when (e){ - is UnknownDomainObjectException, is NoClassDefFoundError, is ClassNotFoundException -> - null - else -> throw e - } - }?.let { - val fixedName = if(targetName.toLowerCase() == "common") "metadata" else targetName.toLowerCase() - it.find { target -> target.name.toLowerCase() == fixedName }?.let { target -> - PlatformData(fixedName, getClasspath(target, variantName), getSourceSet(target, variantName), target.platformType.toString()) - } - } - 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(), "") } + ?.let { PlatformData(null, emptyList(), it.toList(), emptyList(), "") } - fun extractFromKotlinTasks(kotlinTasks: List<Task>): PlatformData? = + fun extractFromKotlinTasks(passName: String, kotlinTasks: List<Task>): PlatformData? = try { - kotlinTasks.map { extractFromKotlinTask(it) }.let { platformDataList -> - PlatformData(null, platformDataList.flatMap { it.classpath }, platformDataList.flatMap { it.sourceRoots }, "") - } + kotlinTasks.find { it.toString() == passName }?.let { extractFromKotlinTask(it) } } catch (e: Throwable) { - when (e){ + when (e) { is UnknownDomainObjectException, is NoClassDefFoundError, is ClassNotFoundException -> - extractFromKotlinTasksTheHardWay(kotlinTasks) + extractFromKotlinTasksTheHardWay(passName, kotlinTasks) else -> throw e } } @@ -89,15 +75,23 @@ class ConfigurationExtractor(private val project: Project) { .compilations .find { it.compileKotlinTask == task } } catch (e: Throwable) { - when (e){ + 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 { PlatformData(task.name, getClasspath(it), getSourceSet(it), it?.platformType?.toString() ?: "") } + }.let { + PlatformData( + task.name, + getClasspath(it), + getSourceSet(it), + getDependentSourceSet(it), + it?.platformType?.toString() ?: "" + ) + } - private fun extractFromKotlinTasksTheHardWay(kotlinTasks: List<Task>): PlatformData? { + private fun extractFromKotlinTasksTheHardWay(passName: String, kotlinTasks: List<Task>): PlatformData? { val allClasspath = mutableSetOf<File>() var allClasspathFileCollection: FileCollection = project.files() val allSourceRoots = mutableSetOf<File>() @@ -116,8 +110,8 @@ class ConfigurationExtractor(private val project: Project) { val taskClasspath: Iterable<File> = (it["getClasspath", AbstractCompile::class].takeIfIsFunc()?.invoke() - ?: it["compileClasspath", abstractKotlinCompileClz].takeIfIsProp()?.v() - ?: it["getClasspath", abstractKotlinCompileClz]()) + ?: it["compileClasspath", abstractKotlinCompileClz].takeIfIsProp()?.v() + ?: it["getClasspath", abstractKotlinCompileClz]()) if (taskClasspath is FileCollection) { allClasspathFileCollection += taskClasspath @@ -132,28 +126,35 @@ class ConfigurationExtractor(private val project: Project) { } catch (e: ResolveException) { mutableListOf() } - classpath.addAll (project.files(allClasspath).toList()) + classpath.addAll(project.files(allClasspath).toList()) - return PlatformData(null, classpath, allSourceRoots.toList(), "") + return PlatformData(null, classpath, allSourceRoots.toList(), emptyList(), "") } private fun getSourceSet(target: KotlinTarget, variantName: String? = null): List<File> = - if(variantName != null) + 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 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 - ?.allKotlinSourceSets + ?.kotlinSourceSets + ?.flatMap { it.kotlin.sourceDirectories } + ?.filter { it.exists() } + .orEmpty() + + private fun getDependentSourceSet(compilation: KotlinCompilation<*>?): List<File> = compilation + ?.let { it.allKotlinSourceSets - it.kotlinSourceSets } ?.flatMap { it.kotlin.sourceDirectories } ?.filter { it.exists() } .orEmpty() @@ -183,7 +184,7 @@ class ConfigurationExtractor(private val project: Project) { private fun getVariants(project: Project): Set<BaseVariant> { val androidExtension = project.extensions.getByName("android") - val baseVariants = when (androidExtension) { + val baseVariants = when (androidExtension) { is AppExtension -> androidExtension.applicationVariants.toSet() is LibraryExtension -> { androidExtension.libraryVariants.toSet() + @@ -208,8 +209,11 @@ class ConfigurationExtractor(private val project: Project) { private fun getPlatformName(platform: KotlinPlatformType): String = if (platform == KotlinPlatformType.androidJvm) KotlinPlatformType.jvm.toString() else platform.toString() - data class PlatformData(val name: String?, - val classpath: List<File>, - val sourceRoots: List<File>, - val platform: String) : Serializable + data class PlatformData( + val name: String?, + val classpath: List<File>, + val sourceRoots: List<File>, + val dependentSourceRoots: List<File>, + val platform: String + ) : Serializable }
\ No newline at end of file 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 2018d3af..356661da 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,6 +1,5 @@ package org.jetbrains.dokka.gradle -import com.google.gson.Gson import com.google.gson.GsonBuilder import org.gradle.api.* import org.gradle.api.artifacts.Configuration @@ -24,7 +23,7 @@ import java.util.function.BiConsumer open class DokkaTask : DefaultTask(), Configurable { private val ANDROID_REFERENCE_URL = Builder("https://developer.android.com/reference/").build() - private val GLOBAL_PLATFORM_NAME = "global" // Used for copying perPackageOptions to other platforms + private val GLOBAL_CONFIGURATION_NAME = "global" // Used for copying perPackageOptions to other platforms @Suppress("MemberVisibilityCanBePrivate") fun defaultKotlinTasks(): List<Task> = with(ReflectDsl) { @@ -69,10 +68,10 @@ open class DokkaTask : DefaultTask(), Configurable { @Classpath lateinit var pluginsConfig: Configuration - var multiplatform: NamedDomainObjectContainer<GradlePassConfigurationImpl> + var dokkaSourceSets: NamedDomainObjectContainer<GradlePassConfigurationImpl> @Suppress("UNCHECKED_CAST") - @Nested get() = (DslObject(this).extensions.getByName(MULTIPLATFORM_EXTENSION_NAME) as NamedDomainObjectContainer<GradlePassConfigurationImpl>) - internal set(value) = DslObject(this).extensions.add(MULTIPLATFORM_EXTENSION_NAME, value) + @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") @@ -188,7 +187,7 @@ open class DokkaTask : DefaultTask(), Configurable { } internal fun getConfiguration(): GradleDokkaConfigurationImpl { - val globalConfig = multiplatform.toList().find { it.name.toLowerCase() == GLOBAL_PLATFORM_NAME } + val globalConfig = dokkaSourceSets.toList().find { it.name.toLowerCase() == GLOBAL_CONFIGURATION_NAME } val defaultModulesConfiguration = collectConfigurations() .map { defaultPassConfiguration(it, globalConfig) } return GradleDokkaConfigurationImpl().apply { @@ -204,27 +203,28 @@ open class DokkaTask : DefaultTask(), Configurable { } private fun collectConfigurations() = - if (this.isMultiplatformProject()) collectMultiplatform() else listOf(collectSinglePlatform(configuration)) + if (this.dokkaSourceSets.isNotEmpty()) collectMultipassConfiguration() else listOf(collectSinglePassConfiguration(configuration)) - private fun collectMultiplatform() = multiplatform - .filterNot { it.name.toLowerCase() == GLOBAL_PLATFORM_NAME } - .map { collectSinglePlatform(it) } + private fun collectMultipassConfiguration() = dokkaSourceSets + .filterNot { it.name.toLowerCase() == GLOBAL_CONFIGURATION_NAME } + .map { collectSinglePassConfiguration(it) } - private fun collectSinglePlatform(config: GradlePassConfigurationImpl): GradlePassConfigurationImpl { - val userConfig = config.let { + private 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 } - } + }*/ if (disableAutoconfiguration) return userConfig val baseConfig = configExtractor.extractConfiguration(userConfig.name, userConfig.androidVariant) ?.let { mergeUserConfigurationAndPlatformData(userConfig, it) } - ?: if (this.isMultiplatformProject()) { + ?: if (this.dokkaSourceSets.isNotEmpty()) { if (outputDiagnosticInfo) logger.warn( "Could not find target with name: ${userConfig.name} in Kotlin Gradle Plugin, " + @@ -233,7 +233,7 @@ open class DokkaTask : DefaultTask(), Configurable { userConfig } else { logger.warn("Could not find target with name: ${userConfig.name} in Kotlin Gradle Plugin") - collectFromSinglePlatformOldPlugin() + collectFromSinglePlatformOldPlugin(userConfig.name) } return if (subProjects.isNotEmpty()) { @@ -256,8 +256,8 @@ open class DokkaTask : DefaultTask(), Configurable { } } - private fun collectFromSinglePlatformOldPlugin() = - configExtractor.extractFromKotlinTasks(kotlinTasks) + private fun collectFromSinglePlatformOldPlugin(name: String) = + configExtractor.extractFromKotlinTasks(name, kotlinTasks) ?.let { mergeUserConfigurationAndPlatformData(configuration, it) } ?: configExtractor.extractFromJavaPlugin() ?.let { mergeUserConfigurationAndPlatformData(configuration, it) } @@ -269,6 +269,7 @@ open class DokkaTask : DefaultTask(), Configurable { ) = userConfig.copy().apply { sourceRoots.addAll(userConfig.sourceRoots.union(autoConfig.sourceRoots.toSourceRoots()).distinct()) + dependentSourceRoots.addAll(userConfig.dependentSourceRoots.union(autoConfig.dependentSourceRoots.toSourceRoots()).distinct()) classpath = userConfig.classpath.union(autoConfig.classpath.map { it.absolutePath }).distinct() if (userConfig.platform == null && autoConfig.platform != "") platform = autoConfig.platform @@ -281,11 +282,10 @@ open class DokkaTask : DefaultTask(), Configurable { if (config.moduleName == "") { config.moduleName = project.name } - if (config.targets.isEmpty() && multiplatform.isNotEmpty()) { - config.targets = listOf(config.name) + if (config.sourceSetName.isEmpty()) { + config.sourceSetName = config.platform ?: config.name } - config.classpath = - (config.classpath as List<Any>).map { it.toString() }.distinct() // Workaround for Groovy's GStringImpl + 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 } @@ -293,7 +293,7 @@ open class DokkaTask : DefaultTask(), Configurable { if (project.isAndroidProject() && !config.noAndroidSdkLink) { // TODO: introduce Android as a separate Dokka platform? config.externalDocumentationLinks.add(ANDROID_REFERENCE_URL) } - if (config.platform != null && config.platform.toString().isNotEmpty()) { + if (config.platform != null && config.platform.toString().isNotBlank()) { config.analysisPlatform = dokkaPlatformFromString(config.platform.toString()) } if (globalConfig != null) { @@ -339,5 +339,4 @@ open class DokkaTask : DefaultTask(), Configurable { null } } -} - +}
\ No newline at end of file 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 570da5f3..9719686e 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,7 +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 sourceRoots: MutableList<SourceRoot> = mutableListOf() + @Input override var dependentSourceRoots: MutableList<SourceRoot> = mutableListOf() @Input override var samples: List<String> = emptyList() @Input override var includes: List<String> = emptyList() @Input override var includeNonPublic: Boolean = false 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 1d93a310..fea0d864 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 @@ -9,7 +9,7 @@ import java.io.InputStream import java.util.* internal const val CONFIGURATION_EXTENSION_NAME = "configuration" -internal const val MULTIPLATFORM_EXTENSION_NAME = "multiplatform" +internal const val SOURCE_SETS_EXTENSION_NAME = "dokkaSourceSets" internal const val DOKKA_TASK_NAME = "dokka" internal const val DOKKA_COLLECTOR_TASK_NAME = "dokkaCollector" @@ -45,7 +45,7 @@ open class DokkaPlugin : Plugin<Project> { project.tasks.create(DOKKA_TASK_NAME, taskClass) } project.tasks.withType(taskClass) { task -> - task.multiplatform = project.container(GradlePassConfigurationImpl::class.java) + task.dokkaSourceSets = project.container(GradlePassConfigurationImpl::class.java) task.configuration = GradlePassConfigurationImpl() task.dokkaRuntime = runtimeConfiguration task.pluginsConfig = pluginsConfiguration 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 31892e8e..3369a640 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 @@ -16,16 +16,4 @@ fun Project.isAndroidProject() = try { false } -fun Project.isMultiplatformProject() = try { - project.extensions.getByType(KotlinMultiplatformExtension::class.java) - true -} catch(e: UnknownDomainObjectException) { - false -} catch (e: NoClassDefFoundError){ - false -} catch(e: ClassNotFoundException) { - false -} - -fun KotlinTarget.isAndroidTarget() = this.platformType == KotlinPlatformType.androidJvm -fun DokkaTask.isMultiplatformProject() = this.multiplatform.isNotEmpty()
\ No newline at end of file +fun KotlinTarget.isAndroidTarget() = this.platformType == KotlinPlatformType.androidJvm
\ No newline at end of file |