From da9d43e0b3293b36a3a6fd2986b0e6bc2e9b915d Mon Sep 17 00:00:00 2001 From: Kamil Doległo Date: Thu, 8 Aug 2019 14:14:44 +0300 Subject: Fix Android compilation name --- runners/android-gradle-plugin/build.gradle | 4 + .../main/kotlin/AndroidConfigurationExtractor.kt | 32 +++++ .../src/main/kotlin/mainAndroid.kt | 4 +- .../dokka/gradle/AbstractConfigurationExtractor.kt | 135 +++++++++++++++++++++ .../dokka/gradle/ConfigurationExtractor.kt | 128 +------------------ .../kotlin/org/jetbrains/dokka/gradle/DokkaTask.kt | 20 +-- .../main/kotlin/org/jetbrains/dokka/gradle/main.kt | 9 +- 7 files changed, 189 insertions(+), 143 deletions(-) create mode 100644 runners/android-gradle-plugin/src/main/kotlin/AndroidConfigurationExtractor.kt create mode 100644 runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/AbstractConfigurationExtractor.kt diff --git a/runners/android-gradle-plugin/build.gradle b/runners/android-gradle-plugin/build.gradle index 6126510b..99e3abc6 100644 --- a/runners/android-gradle-plugin/build.gradle +++ b/runners/android-gradle-plugin/build.gradle @@ -21,6 +21,7 @@ tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile).all { repositories { jcenter() + google() } dependencies { @@ -31,6 +32,9 @@ dependencies { compileOnly gradleApi() compileOnly localGroovy() + compileOnly("com.android.tools.build:gradle:3.0.0") + compileOnly("com.android.tools.build:gradle-core:3.0.0") + compileOnly("com.android.tools.build:builder-model:3.0.0") } task sourceJar(type: Jar) { diff --git a/runners/android-gradle-plugin/src/main/kotlin/AndroidConfigurationExtractor.kt b/runners/android-gradle-plugin/src/main/kotlin/AndroidConfigurationExtractor.kt new file mode 100644 index 00000000..8a2a2dff --- /dev/null +++ b/runners/android-gradle-plugin/src/main/kotlin/AndroidConfigurationExtractor.kt @@ -0,0 +1,32 @@ +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.Project + +class AndroidConfigurationExtractor(private val project: Project): AbstractConfigurationExtractor(project) { + override fun getMainCompilationName(): String = getVariants(project).filter { it.name == BuilderConstants.RELEASE }.map { it.name }.first() + + private fun getVariants(project: Project): Set { + val androidExtension = project.extensions.getByName("android") + return when (androidExtension) { + is AppExtension -> androidExtension.applicationVariants.toSet() + is LibraryExtension -> { + androidExtension.libraryVariants.toSet() + + if (androidExtension is FeatureExtension) { + androidExtension.featureVariants.toSet() + } else { + emptySet() + } + } + is TestExtension -> androidExtension.applicationVariants.toSet() + else -> emptySet() + } + + if (androidExtension is TestedExtension) { + androidExtension.testVariants.toSet() + androidExtension.unitTestVariants.toSet() + } else { + emptySet() + } + } +} \ No newline at end of file diff --git a/runners/android-gradle-plugin/src/main/kotlin/mainAndroid.kt b/runners/android-gradle-plugin/src/main/kotlin/mainAndroid.kt index 8aa76ef8..8e293ed6 100644 --- a/runners/android-gradle-plugin/src/main/kotlin/mainAndroid.kt +++ b/runners/android-gradle-plugin/src/main/kotlin/mainAndroid.kt @@ -18,8 +18,8 @@ open class DokkaAndroidPlugin : DokkaPlugin() { private val ANDROID_REFERENCE_URL = Builder("https://developer.android.com/reference/").build() open class DokkaAndroidTask : DokkaTask() { - @Input var noAndroidSdkLink: Boolean = false + override val configurationExtractor = AndroidConfigurationExtractor(project) override fun collectSuppressedFiles(sourceRoots: List): List { val generatedRoot = project.buildDir.resolve("generated").absoluteFile @@ -35,4 +35,4 @@ open class DokkaAndroidTask : DokkaTask() { if (!noAndroidSdkLink) externalDocumentationLinks.add(ANDROID_REFERENCE_URL) } } -} +} \ No newline at end of file diff --git a/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/AbstractConfigurationExtractor.kt b/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/AbstractConfigurationExtractor.kt new file mode 100644 index 00000000..b882923a --- /dev/null +++ b/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/AbstractConfigurationExtractor.kt @@ -0,0 +1,135 @@ +package org.jetbrains.dokka.gradle + +import org.gradle.api.NamedDomainObjectCollection +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.android.synthetic.diagnostic.AndroidExtensionPropertiesCallChecker +import org.jetbrains.kotlin.gradle.dsl.KotlinCommonOptions +import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension +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 java.io.File +import java.io.Serializable + +abstract class AbstractConfigurationExtractor(private val project: Project) { + + fun extractFromSinglePlatform(): PlatformData? { + val target: KotlinTarget + try { + target = project.extensions.getByType(KotlinSingleTargetExtension::class.java).target + } catch(e: UnknownDomainObjectException) { + return null + } catch(e: NoClassDefFoundError) { + return null + } catch(e: ClassNotFoundException) { + return null + } + + return try { + PlatformData(null, getClasspath(target), getSourceSet(target), getPlatformName(target.platformType)) + } catch(e: NoSuchMethodError){ + null + } + } + + fun extractFromMultiPlatform(): List? { + val targets: NamedDomainObjectCollection + try { + targets = project.extensions.getByType(KotlinMultiplatformExtension::class.java).targets + } catch(e: UnknownDomainObjectException) { + return null + } catch(e: ClassNotFoundException) { + return null + } catch(e: NoClassDefFoundError) { + return null + } + + val commonTarget = targets.find { it.platformType == KotlinPlatformType.common } + val platformTargets = targets.filter { it.platformType != KotlinPlatformType.common } + val config = platformTargets.map { + PlatformData(it.name, getClasspath(it), getSourceSet(it), it.platformType.toString()) + } + + return config + PlatformData("common", getClasspath(commonTarget), getSourceSet(commonTarget), "common") + } + + fun extractFromKotlinTasks(kotlinTasks: List): PlatformData? { + val allClasspath = mutableSetOf() + var allClasspathFileCollection: FileCollection = project.files() + val allSourceRoots = mutableSetOf() + + kotlinTasks.forEach { + with(ReflectDsl) { + val taskSourceRoots: List + val abstractKotlinCompileClz: Class + try { + taskSourceRoots = it["sourceRootsContainer"]["sourceRoots"].v() + abstractKotlinCompileClz = DokkaTask.getAbstractKotlinCompileFor(it)!! + } catch (e: NullPointerException) { + println("Cannot extract sources from Kotlin tasks! Consider upgrading Kotlin Gradle Plugin") + return null + } + + val taskClasspath: Iterable = + (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 = try { + allClasspathFileCollection.toMutableList() + } catch (e: ResolveException) { + mutableListOf() + } + classpath.addAll (project.files(allClasspath).toList()) + + return PlatformData(null, classpath, allSourceRoots.toList(), "") + } + + 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(), "") } + + private fun getSourceSet(target: KotlinTarget?): List = getMainCompilation(target) + ?.allKotlinSourceSets + ?.flatMap { it.kotlin.sourceDirectories } + ?.filter { it.exists() } + .orEmpty() + + private fun getClasspath(target: KotlinTarget?): List = getMainCompilation(target) + ?.compileDependencyFiles + ?.files + ?.toList() + ?.filter { it.exists() } + .orEmpty() + + private fun getMainCompilation(target: KotlinTarget?): KotlinCompilation? = + target?.compilations?.getByName(getMainCompilationName()) + + protected abstract fun getMainCompilationName(): String + + 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, + val sourceRoots: List, + val platform: String) : Serializable +} \ No newline at end of file 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 0ad1d1d3..9bc37f50 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,132 +1,8 @@ package org.jetbrains.dokka.gradle -import org.gradle.api.NamedDomainObjectCollection 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.KotlinCommonOptions -import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension -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 java.io.File -import java.io.Serializable -object ConfigurationExtractor { - - fun extractFromSinglePlatform(project: Project): PlatformData? { - val target: KotlinTarget - try { - target = project.extensions.getByType(KotlinSingleTargetExtension::class.java).target - } catch(e: UnknownDomainObjectException) { - return null - } catch(e: NoClassDefFoundError) { - return null - } catch(e: ClassNotFoundException) { - return null - } - - return try { - return PlatformData(null, getClasspath(target), getSourceSet(target), getPlatformName(target.platformType)) - } catch(e: NoSuchMethodError){ - null - } - } - - fun extractFromMultiPlatform(project: Project): List? { - val targets: NamedDomainObjectCollection - try { - targets = project.extensions.getByType(KotlinMultiplatformExtension::class.java).targets - } catch(e: UnknownDomainObjectException) { - return null - } catch(e: ClassNotFoundException) { - return null - } catch(e: NoClassDefFoundError) { - return null - } - - val commonTarget = targets.find { it.platformType == KotlinPlatformType.common } - val platformTargets = targets.filter { it.platformType != KotlinPlatformType.common } - val config = platformTargets.map { - PlatformData(it.name, getClasspath(it), getSourceSet(it), it.platformType.toString()) - } - - return config + PlatformData("common", getClasspath(commonTarget), getSourceSet(commonTarget), "common") - } - - fun extractFromKotlinTasks(kotlinTasks: List, project: Project): PlatformData? { - val allClasspath = mutableSetOf() - var allClasspathFileCollection: FileCollection = project.files() - val allSourceRoots = mutableSetOf() - - kotlinTasks.forEach { - with(ReflectDsl) { - val taskSourceRoots: List - val abstractKotlinCompileClz: Class - try { - taskSourceRoots = it["sourceRootsContainer"]["sourceRoots"].v() - abstractKotlinCompileClz = DokkaTask.getAbstractKotlinCompileFor(it)!! - } catch (e: NullPointerException) { - println("Cannot extract sources from Kotlin tasks! Consider upgrading Kotlin Gradle Plugin") - return null - } - - val taskClasspath: Iterable = - (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 = try { - allClasspathFileCollection.toMutableList() - } catch (e: ResolveException) { - mutableListOf() - } - classpath.addAll (project.files(allClasspath).toList()) - - return PlatformData(null, classpath, allSourceRoots.toList(), "") - } - - fun extractFromJavaPlugin(project: Project): PlatformData? = - project.convention.findPlugin(JavaPluginConvention::class.java) - ?.run { sourceSets.findByName(SourceSet.MAIN_SOURCE_SET_NAME)?.allSource?.srcDirs } - ?.let { PlatformData(null, emptyList(), it.toList(), "") } - - private fun getSourceSet(target: KotlinTarget?): List = getMainCompilation(target) - ?.allKotlinSourceSets - ?.flatMap { it.kotlin.sourceDirectories } - ?.filter { it.exists() } - .orEmpty() - - private fun getClasspath(target: KotlinTarget?): List = getMainCompilation(target) - ?.compileDependencyFiles - ?.files - ?.toList() - ?.filter { it.exists() } - .orEmpty() - - private fun getMainCompilation(target: KotlinTarget?): KotlinCompilation? = - target?.compilations?.getByName(KotlinCompilation.MAIN_COMPILATION_NAME) - - private fun getPlatformName(platform: KotlinPlatformType): String = - if (platform == KotlinPlatformType.androidJvm) "jvm" else platform.toString() - - data class PlatformData(val name: String?, - val classpath: List, - val sourceRoots: List, - val platform: String) : Serializable +class ConfigurationExtractor(private val project: Project): AbstractConfigurationExtractor(project) { + override fun getMainCompilationName(): String = KotlinCompilation.MAIN_COMPILATION_NAME } \ 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 6a4fbe4f..c4ce3730 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,7 +1,6 @@ package org.jetbrains.dokka.gradle import com.google.gson.GsonBuilder -import groovy.lang.Closure import org.gradle.api.* import org.gradle.api.artifacts.Configuration import org.gradle.api.file.FileCollection @@ -14,6 +13,7 @@ import org.jetbrains.dokka.DokkaConfiguration.SourceRoot import org.jetbrains.dokka.Platform import org.jetbrains.dokka.ReflectDsl import org.jetbrains.dokka.ReflectDsl.isNotInstance +import org.jetbrains.dokka.gradle.AbstractConfigurationExtractor.PlatformData import java.io.File import java.net.URLClassLoader import java.util.concurrent.Callable @@ -73,6 +73,8 @@ open class DokkaTask : DefaultTask() { private val kotlinTasks: List by lazy { extractKotlinCompileTasks() } + protected open val configurationExtractor: AbstractConfigurationExtractor = ConfigurationExtractor(project) + @Input var subProjects: List = emptyList() @@ -172,11 +174,11 @@ open class DokkaTask : DefaultTask() { val baseConfig = mergeUserAndAutoConfigurations( multiplatform.toList(), - ConfigurationExtractor.extractFromMultiPlatform(project).orEmpty() + configurationExtractor.extractFromMultiPlatform().orEmpty() ) return if (subProjects.isNotEmpty()) subProjects.toProjects().fold(baseConfig) { list, project -> - mergeUserAndAutoConfigurations(list, ConfigurationExtractor.extractFromMultiPlatform(project).orEmpty()) + mergeUserAndAutoConfigurations(list, configurationExtractor.extractFromMultiPlatform().orEmpty()) } else baseConfig @@ -185,7 +187,7 @@ open class DokkaTask : DefaultTask() { private fun collectFromSinglePlatform(): List { if (disableAutoconfiguration) return listOf(configuration) - val extractedConfig = ConfigurationExtractor.extractFromSinglePlatform(project) + val extractedConfig = configurationExtractor.extractFromSinglePlatform() val baseConfig = if (extractedConfig != null && configuration.collectKotlinTasks == null) listOf(mergeUserConfigurationAndPlatformData(configuration, extractedConfig)) else @@ -194,7 +196,7 @@ open class DokkaTask : DefaultTask() { return if (subProjects.isNotEmpty()) { try { subProjects.toProjects().fold(baseConfig) { list, project -> - listOf(mergeUserConfigurationAndPlatformData(list.first(), ConfigurationExtractor.extractFromSinglePlatform(project)!!)) + listOf(mergeUserConfigurationAndPlatformData(list.first(), configurationExtractor.extractFromSinglePlatform()!!)) } } catch(e: NullPointerException) { logger.warn("Cannot extract sources from subProjects. Do you have the Kotlin plugin in version 1.3.30+ " + @@ -207,18 +209,18 @@ open class DokkaTask : DefaultTask() { } private fun collectFromSinglePlatformOldPlugin(): List { - val kotlinTasks = ConfigurationExtractor.extractFromKotlinTasks(kotlinTasks, project) + val kotlinTasks = configurationExtractor.extractFromKotlinTasks(kotlinTasks) return if (kotlinTasks != null) { listOf(mergeUserConfigurationAndPlatformData(configuration, kotlinTasks)) } else { - val javaPlugin = ConfigurationExtractor.extractFromJavaPlugin(project) + val javaPlugin = configurationExtractor.extractFromJavaPlugin() if (javaPlugin != null) listOf(mergeUserConfigurationAndPlatformData(configuration, javaPlugin)) else listOf(configuration) } } private fun mergeUserAndAutoConfigurations(userConfigurations: List, - autoConfigurations: List): List { + autoConfigurations: List): List { val merged: MutableList = mutableListOf() merged.addAll( userConfigurations.map { userConfig -> @@ -230,7 +232,7 @@ open class DokkaTask : DefaultTask() { } private fun mergeUserConfigurationAndPlatformData(userConfig: GradlePassConfigurationImpl, - autoConfig: ConfigurationExtractor.PlatformData): GradlePassConfigurationImpl { + autoConfig: PlatformData): GradlePassConfigurationImpl { val merged = userConfig.copy() merged.apply { sourceRoots.addAll(userConfig.sourceRoots.union(autoConfig.sourceRoots.toSourceRoots()).distinct()) 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 a47c238f..a3aadd08 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 @@ -29,18 +29,15 @@ open class DokkaPlugin : Plugin { protected fun addTasks(project: Project, runtimeConfiguration: Configuration, taskClass: Class) { if(GradleVersion.current() >= GradleVersion.version("4.10")) { - project.tasks.register(taskName, taskClass).configure { - it.outputDirectory = File(project.buildDir, taskName).absolutePath - } + project.tasks.register(taskName, taskClass) } else { - project.tasks.create(taskName, taskClass).apply { - outputDirectory = File(project.buildDir, taskName).absolutePath - } + project.tasks.create(taskName, taskClass) } project.tasks.withType(taskClass) { task -> task.multiplatform = project.container(GradlePassConfigurationImpl::class.java) task.configuration = GradlePassConfigurationImpl() task.dokkaRuntime = runtimeConfiguration + task.outputDirectory = File(project.buildDir, taskName).absolutePath } } } -- cgit