From 1c4a3c6b21846271bcdba3818ba323d1b0bb096f Mon Sep 17 00:00:00 2001 From: Kamil Doległo Date: Thu, 22 Aug 2019 16:04:19 +0200 Subject: Merge Android plugin into Gradle plugin --- runners/android-gradle-plugin/build.gradle | 105 -------------- .../main/kotlin/AndroidConfigurationExtractor.kt | 32 ---- .../src/main/kotlin/mainAndroid.kt | 38 ----- .../org.jetbrains.dokka-android.properties | 2 - runners/gradle-integration-tests/build.gradle | 5 +- .../dokka/gradle/AbstractDokkaAndroidGradleTest.kt | 2 +- .../dokka/gradle/AbstractDokkaGradleTest.kt | 1 - .../testData/androidApp/app/build.gradle | 3 +- .../testData/androidAppJavadoc/app/build.gradle | 3 +- .../androidLibDependsOnJavaLib/lib/build.gradle | 3 +- .../androidMultiFlavourApp/app/build.gradle | 5 +- runners/gradle-plugin/build.gradle | 11 +- .../dokka/gradle/AbstractConfigurationExtractor.kt | 135 ----------------- .../dokka/gradle/ConfigurationExtractor.kt | 161 ++++++++++++++++++++- .../kotlin/org/jetbrains/dokka/gradle/DokkaTask.kt | 25 +++- .../dokka/gradle/configurationImplementations.kt | 1 + .../main/kotlin/org/jetbrains/dokka/gradle/main.kt | 6 +- .../kotlin/org/jetbrains/dokka/gradle/utils.kt | 14 ++ settings.gradle | 1 - 19 files changed, 213 insertions(+), 340 deletions(-) delete mode 100644 runners/android-gradle-plugin/build.gradle delete mode 100644 runners/android-gradle-plugin/src/main/kotlin/AndroidConfigurationExtractor.kt delete mode 100644 runners/android-gradle-plugin/src/main/kotlin/mainAndroid.kt delete mode 100644 runners/android-gradle-plugin/src/main/resources/META-INF/gradle-plugins/org.jetbrains.dokka-android.properties delete mode 100644 runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/AbstractConfigurationExtractor.kt create mode 100644 runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/utils.kt diff --git a/runners/android-gradle-plugin/build.gradle b/runners/android-gradle-plugin/build.gradle deleted file mode 100644 index 99e3abc6..00000000 --- a/runners/android-gradle-plugin/build.gradle +++ /dev/null @@ -1,105 +0,0 @@ -import com.gradle.publish.DependenciesBuilder -import org.jetbrains.CorrectShadowPublishing - -apply plugin: 'java' -apply plugin: 'kotlin' - - -apply plugin: 'com.github.johnrengelman.shadow' -apply plugin: "com.gradle.plugin-publish" - -sourceCompatibility = 1.8 - -tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile).all { - kotlinOptions { - freeCompilerArgs += "-Xjsr305=strict" - languageVersion = language_version - apiVersion = language_version - jvmTarget = "1.8" - } -} - -repositories { - jcenter() - google() -} - -dependencies { - testCompile group: 'junit', name: 'junit', version: '4.12' - - shadow project(path: ':runners:gradle-plugin', configuration: 'shadow') - compileOnly project(':integration') - - 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) { - from sourceSets.main.allSource -} - -processResources { - eachFile { - if (it.name == "org.jetbrains.dokka-android.properties") { - it.filter { line -> - line.replace("", dokka_version) - } - } - } -} - -shadowJar { - baseName = 'dokka-android-gradle-plugin' - classifier = '' -} - -apply plugin: 'maven-publish' - -publishing { - publications { - dokkaAndroidGradlePlugin(MavenPublication) { MavenPublication publication -> - artifactId = 'dokka-android-gradle-plugin' - - artifact sourceJar { - classifier "sources" - } - - CorrectShadowPublishing.configure(publication, project) - } - } -} - -bintrayPublication(project, ['dokkaAndroidGradlePlugin']) - -configurations.archives.artifacts.clear() -artifacts { - archives shadowJar -} - -pluginBundle { - website = 'https://www.kotlinlang.org/' - vcsUrl = 'https://github.com/kotlin/dokka.git' - description = 'Dokka, the Kotlin documentation tool' - tags = ['dokka', 'kotlin', 'kdoc', 'android'] - - plugins { - dokkaAndroidGradlePlugin { - id = 'org.jetbrains.dokka-android' - displayName = 'Dokka Android plugin' - } - } - - withDependencies { List list -> - list.clear() - def builder = new DependenciesBuilder() - builder.addUniqueScopedDependencies(list, configurations.shadow, "compile") - } - - mavenCoordinates { - groupId = "org.jetbrains.dokka" - artifactId = "dokka-android-gradle-plugin" - } -} \ No newline at end of file diff --git a/runners/android-gradle-plugin/src/main/kotlin/AndroidConfigurationExtractor.kt b/runners/android-gradle-plugin/src/main/kotlin/AndroidConfigurationExtractor.kt deleted file mode 100644 index 8a2a2dff..00000000 --- a/runners/android-gradle-plugin/src/main/kotlin/AndroidConfigurationExtractor.kt +++ /dev/null @@ -1,32 +0,0 @@ -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 deleted file mode 100644 index 8e293ed6..00000000 --- a/runners/android-gradle-plugin/src/main/kotlin/mainAndroid.kt +++ /dev/null @@ -1,38 +0,0 @@ -package org.jetbrains.dokka.gradle - -import org.gradle.api.Project -import org.gradle.api.tasks.Input -import org.jetbrains.dokka.DokkaConfiguration.ExternalDocumentationLink.Builder -import org.jetbrains.dokka.DokkaConfiguration.SourceRoot -import java.io.File - -open class DokkaAndroidPlugin : DokkaPlugin() { - - override fun apply(project: Project) { - loadDokkaVersion() - val dokkaRuntimeConfiguration = addConfiguration(project) - addTasks(project, dokkaRuntimeConfiguration, DokkaAndroidTask::class.java) - } -} - -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 - return sourceRoots - .map { File(it.path) } - .filter { it.startsWith(generatedRoot) } - .flatMap { it.walk().toList() } - .map { it.absolutePath } - } - - init { - project.afterEvaluate { - if (!noAndroidSdkLink) externalDocumentationLinks.add(ANDROID_REFERENCE_URL) - } - } -} \ No newline at end of file diff --git a/runners/android-gradle-plugin/src/main/resources/META-INF/gradle-plugins/org.jetbrains.dokka-android.properties b/runners/android-gradle-plugin/src/main/resources/META-INF/gradle-plugins/org.jetbrains.dokka-android.properties deleted file mode 100644 index b204da7b..00000000 --- a/runners/android-gradle-plugin/src/main/resources/META-INF/gradle-plugins/org.jetbrains.dokka-android.properties +++ /dev/null @@ -1,2 +0,0 @@ -implementation-class=org.jetbrains.dokka.gradle.DokkaAndroidPlugin -dokka-version= \ No newline at end of file diff --git a/runners/gradle-integration-tests/build.gradle b/runners/gradle-integration-tests/build.gradle index 9d0a20d7..1bfdbd5b 100644 --- a/runners/gradle-integration-tests/build.gradle +++ b/runners/gradle-integration-tests/build.gradle @@ -13,7 +13,6 @@ tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile).all { configurations { dokkaPlugin - dokkaAndroidPlugin dokkaFatJar } @@ -24,7 +23,6 @@ dependencies { testCompile ideaRT() dokkaPlugin project(path: ':runners:gradle-plugin', configuration: 'shadow') - dokkaAndroidPlugin project(path: ':runners:android-gradle-plugin', configuration: 'shadow') dokkaFatJar project(path: ":runners:fatjar", configuration: 'shadow') testCompile group: 'junit', name: 'junit', version: '4.12' @@ -36,13 +34,12 @@ dependencies { task createClasspathManifest { def outputDir = file("$buildDir/$name") - inputs.files(configurations.dokkaPlugin + configurations.dokkaAndroidPlugin + configurations.dokkaFatJar) + inputs.files(configurations.dokkaPlugin + configurations.dokkaFatJar) outputs.dir outputDir doLast { outputDir.mkdirs() file("$outputDir/dokka-plugin-classpath.txt").text = configurations.dokkaPlugin.join("\n") - file("$outputDir/android-dokka-plugin-classpath.txt").text = configurations.dokkaAndroidPlugin.join("\n") file("$outputDir/fatjar.txt").text = configurations.dokkaFatJar.join("\n") } } diff --git a/runners/gradle-integration-tests/src/test/kotlin/org/jetbrains/dokka/gradle/AbstractDokkaAndroidGradleTest.kt b/runners/gradle-integration-tests/src/test/kotlin/org/jetbrains/dokka/gradle/AbstractDokkaAndroidGradleTest.kt index d6ed610a..334fc7c8 100644 --- a/runners/gradle-integration-tests/src/test/kotlin/org/jetbrains/dokka/gradle/AbstractDokkaAndroidGradleTest.kt +++ b/runners/gradle-integration-tests/src/test/kotlin/org/jetbrains/dokka/gradle/AbstractDokkaAndroidGradleTest.kt @@ -5,7 +5,7 @@ import java.io.File abstract class AbstractDokkaAndroidGradleTest : AbstractDokkaGradleTest() { - override val pluginClasspath: List = androidPluginClasspathData.toFile().readLines().map { File(it) } + override val pluginClasspath: List = pluginClasspathData.toFile().readLines().map { File(it) } companion object { diff --git a/runners/gradle-integration-tests/src/test/kotlin/org/jetbrains/dokka/gradle/AbstractDokkaGradleTest.kt b/runners/gradle-integration-tests/src/test/kotlin/org/jetbrains/dokka/gradle/AbstractDokkaGradleTest.kt index 6bd5786f..4814e707 100644 --- a/runners/gradle-integration-tests/src/test/kotlin/org/jetbrains/dokka/gradle/AbstractDokkaGradleTest.kt +++ b/runners/gradle-integration-tests/src/test/kotlin/org/jetbrains/dokka/gradle/AbstractDokkaGradleTest.kt @@ -14,7 +14,6 @@ import java.nio.file.Paths val testDataFolder: Path = Paths.get("testData") val pluginClasspathData: Path = Paths.get("build", "createClasspathManifest", "dokka-plugin-classpath.txt") -val androidPluginClasspathData: Path = pluginClasspathData.resolveSibling("android-dokka-plugin-classpath.txt") val dokkaFatJarPathData: Path = pluginClasspathData.resolveSibling("fatjar.txt") diff --git a/runners/gradle-integration-tests/testData/androidApp/app/build.gradle b/runners/gradle-integration-tests/testData/androidApp/app/build.gradle index 74d65e57..2420107c 100644 --- a/runners/gradle-integration-tests/testData/androidApp/app/build.gradle +++ b/runners/gradle-integration-tests/testData/androidApp/app/build.gradle @@ -9,14 +9,13 @@ buildscript { } plugins { - id 'org.jetbrains.dokka-android' + id 'org.jetbrains.dokka' } apply plugin: 'com.android.application' apply plugin: 'kotlin-android' apply plugin: 'kotlin-android-extensions' -apply plugin: 'org.jetbrains.dokka-android' android { compileSdkVersion Integer.parseInt(sdk_version) diff --git a/runners/gradle-integration-tests/testData/androidAppJavadoc/app/build.gradle b/runners/gradle-integration-tests/testData/androidAppJavadoc/app/build.gradle index e62b6f3d..66421f52 100644 --- a/runners/gradle-integration-tests/testData/androidAppJavadoc/app/build.gradle +++ b/runners/gradle-integration-tests/testData/androidAppJavadoc/app/build.gradle @@ -9,13 +9,12 @@ buildscript { } plugins { - id 'org.jetbrains.dokka-android' + id 'org.jetbrains.dokka' } apply plugin: 'com.android.application' apply plugin: 'kotlin-android' -apply plugin: 'org.jetbrains.dokka-android' android { compileSdkVersion Integer.parseInt(sdk_version) diff --git a/runners/gradle-integration-tests/testData/androidLibDependsOnJavaLib/lib/build.gradle b/runners/gradle-integration-tests/testData/androidLibDependsOnJavaLib/lib/build.gradle index 5f2b0d77..b1ee52ab 100644 --- a/runners/gradle-integration-tests/testData/androidLibDependsOnJavaLib/lib/build.gradle +++ b/runners/gradle-integration-tests/testData/androidLibDependsOnJavaLib/lib/build.gradle @@ -7,13 +7,12 @@ buildscript { plugins { - id 'org.jetbrains.dokka-android' + id 'org.jetbrains.dokka' } apply plugin: 'com.android.library' apply plugin: 'kotlin-android' -apply plugin: 'org.jetbrains.dokka-android' android { diff --git a/runners/gradle-integration-tests/testData/androidMultiFlavourApp/app/build.gradle b/runners/gradle-integration-tests/testData/androidMultiFlavourApp/app/build.gradle index 1d35b37e..660257ab 100644 --- a/runners/gradle-integration-tests/testData/androidMultiFlavourApp/app/build.gradle +++ b/runners/gradle-integration-tests/testData/androidMultiFlavourApp/app/build.gradle @@ -9,14 +9,13 @@ buildscript { } plugins { - id 'org.jetbrains.dokka-android' + id 'org.jetbrains.dokka' } apply plugin: 'com.android.application' apply plugin: 'kotlin-android' apply plugin: 'kotlin-android-extensions' -apply plugin: 'org.jetbrains.dokka-android' android { compileSdkVersion Integer.parseInt(sdk_version) @@ -65,7 +64,7 @@ dokka { outputDirectory = "$buildDir/dokka/all" } -task dokkaFullFlavourOnly(type: org.jetbrains.dokka.gradle.DokkaAndroidTask) { +task dokkaFullFlavourOnly(type: org.jetbrains.dokka.gradle.DokkaTask) { outputDirectory = "$buildDir/dokka/fullOnly" configuration { moduleName = "full" diff --git a/runners/gradle-plugin/build.gradle b/runners/gradle-plugin/build.gradle index d993597d..ceb03bae 100644 --- a/runners/gradle-plugin/build.gradle +++ b/runners/gradle-plugin/build.gradle @@ -18,6 +18,11 @@ tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile).all { } } +repositories { + jcenter() + google() +} + dependencies { testCompile group: 'junit', name: 'junit', version: '4.12' @@ -27,6 +32,9 @@ dependencies { compile project(":integration") compileOnly "org.jetbrains.kotlin:kotlin-gradle-plugin" + 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") compileOnly gradleApi() compileOnly localGroovy() implementation "com.google.code.gson:gson:$gson_version" @@ -56,7 +64,6 @@ apply plugin: 'maven-publish' publishing { publications { dokkaGradlePlugin(MavenPublication) { publication -> - artifactId = 'dokka-gradle-plugin' artifact sourceJar { @@ -79,7 +86,7 @@ pluginBundle { website = 'https://www.kotlinlang.org/' vcsUrl = 'https://github.com/kotlin/dokka.git' description = 'Dokka, the Kotlin documentation tool' - tags = ['dokka', 'kotlin', 'kdoc'] + tags = ['dokka', 'kotlin', 'kdoc', 'android'] plugins { dokkaGradlePlugin { 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 deleted file mode 100644 index b882923a..00000000 --- a/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/AbstractConfigurationExtractor.kt +++ /dev/null @@ -1,135 +0,0 @@ -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 9bc37f50..dc9e7c1a 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,8 +1,165 @@ 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 +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 -class ConfigurationExtractor(private val project: Project): AbstractConfigurationExtractor(project) { - override fun getMainCompilationName(): String = KotlinCompilation.MAIN_COMPILATION_NAME +class ConfigurationExtractor(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()) + + private fun getMainCompilationName() = if (project.isAndroidProject()) + getVariants(project).filter { it.name == BuilderConstants.RELEASE }.map { it.name }.first() + else + KotlinCompilation.MAIN_COMPILATION_NAME + + private fun getVariants(project: Project): Set { + 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() + } + } + is TestExtension -> androidExtension.applicationVariants.toSet() + else -> emptySet() + } + val testVariants = if (androidExtension is TestedExtension) { + androidExtension.testVariants.toSet() + androidExtension.unitTestVariants.toSet() + } else { + emptySet() + } + + return baseVariants + testVariants + } + + 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/DokkaTask.kt b/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/DokkaTask.kt index c4ce3730..8878103c 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 @@ -9,17 +9,19 @@ import org.gradle.api.plugins.JavaBasePlugin import org.gradle.api.tasks.* import org.jetbrains.dokka.DokkaBootstrap import org.jetbrains.dokka.DokkaConfiguration +import org.jetbrains.dokka.DokkaConfiguration.ExternalDocumentationLink.Builder 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 org.jetbrains.dokka.gradle.ConfigurationExtractor.PlatformData import java.io.File import java.net.URLClassLoader import java.util.concurrent.Callable import java.util.function.BiConsumer open class DokkaTask : DefaultTask() { + private val ANDROID_REFERENCE_URL = Builder("https://developer.android.com/reference/").build() @Suppress("MemberVisibilityCanBePrivate") fun defaultKotlinTasks(): List = with(ReflectDsl) { @@ -69,11 +71,11 @@ open class DokkaTask : DefaultTask() { // Configure Dokka with closure in Gradle Kotlin DSL fun configuration(action: Action) = action.execute(configuration) - protected var externalDocumentationLinks: MutableList = mutableListOf() + private var externalDocumentationLinks: MutableList = mutableListOf() private val kotlinTasks: List by lazy { extractKotlinCompileTasks() } - protected open val configurationExtractor: AbstractConfigurationExtractor = ConfigurationExtractor(project) + private val configurationExtractor = ConfigurationExtractor(project) @Input var subProjects: List = emptyList() @@ -121,7 +123,17 @@ open class DokkaTask : DefaultTask() { private fun Iterable.toSourceRoots(): List = this.filter { it.exists() }.map { GradleSourceRootImpl().apply { path = it.path } } private fun Iterable.toProjects(): List = project.subprojects.toList().filter { this.contains(it.name) } - protected open fun collectSuppressedFiles(sourceRoots: List): List = emptyList() + protected open fun collectSuppressedFiles(sourceRoots: List) = + 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() + } @TaskAction fun generate() { @@ -255,8 +267,11 @@ open class DokkaTask : DefaultTask() { 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) { + config.externalDocumentationLinks.add(ANDROID_REFERENCE_URL) + } config.externalDocumentationLinks.addAll(externalDocumentationLinks) - if (config.platform != null && config.platform.toString().isNotEmpty()){ + if (config.platform != null && config.platform.toString().isNotEmpty()) { config.analysisPlatform = Platform.fromString(config.platform.toString()) } return config 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 fd5ea151..f772df3a 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 @@ -43,6 +43,7 @@ open class GradlePassConfigurationImpl(@Transient val name: String = ""): PassCo @Input @Optional override var apiVersion: String? = null @Input override var noStdlibLink: Boolean = false @Input override var noJdkLink: Boolean = false + @Input var noAndroidSdkLink: Boolean = false @Input override var suppressedFiles: List = emptyList() @Input override var collectInheritedExtensionsFromLibraries: Boolean = false @Input override var analysisPlatform: Platform = Platform.DEFAULT 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 a3aadd08..6f8d55e4 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 @@ -20,14 +20,14 @@ open class DokkaPlugin : Plugin { addTasks(project, dokkaRuntimeConfiguration, DokkaTask::class.java) } - protected fun loadDokkaVersion() = DokkaVersion.loadFrom(javaClass.getResourceAsStream("/META-INF/gradle-plugins/org.jetbrains.dokka.properties")) + private fun loadDokkaVersion() = DokkaVersion.loadFrom(javaClass.getResourceAsStream("/META-INF/gradle-plugins/org.jetbrains.dokka.properties")) - protected fun addConfiguration(project: Project) = + private fun addConfiguration(project: Project) = project.configurations.create("dokkaRuntime").apply { defaultDependencies{ dependencies -> dependencies.add(project.dependencies.create("org.jetbrains.dokka:dokka-fatjar:${DokkaVersion.version}")) } } - protected fun addTasks(project: Project, runtimeConfiguration: Configuration, taskClass: Class) { + private fun addTasks(project: Project, runtimeConfiguration: Configuration, taskClass: Class) { if(GradleVersion.current() >= GradleVersion.version("4.10")) { project.tasks.register(taskName, taskClass) } else { 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 new file mode 100644 index 00000000..64ea2405 --- /dev/null +++ b/runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/utils.kt @@ -0,0 +1,14 @@ +package org.jetbrains.dokka.gradle + +import org.gradle.api.Project +import org.gradle.api.UnknownDomainObjectException + + +fun Project.isAndroidProject() = try { + project.extensions.getByName("android") + true +} catch(e: UnknownDomainObjectException) { + false +} catch(e: ClassNotFoundException) { + false +} \ No newline at end of file diff --git a/settings.gradle b/settings.gradle index ef5f9869..8a89d827 100644 --- a/settings.gradle +++ b/settings.gradle @@ -7,5 +7,4 @@ include 'core', 'runners:cli', 'runners:maven-plugin', 'runners:gradle-plugin', - 'runners:android-gradle-plugin', 'runners:gradle-integration-tests' -- cgit