diff options
author | Kamil Doległo <kamilok1965@interia.pl> | 2019-08-22 16:04:19 +0200 |
---|---|---|
committer | Kamil Doległo <kamilok1965@interia.pl> | 2019-08-22 16:04:19 +0200 |
commit | 1c4a3c6b21846271bcdba3818ba323d1b0bb096f (patch) | |
tree | fa3a5e40d879bd1dbb284c69cee1b418f5044021 /runners/gradle-plugin | |
parent | e224c709692adf450786e16e245b4574a480cdab (diff) | |
download | dokka-1c4a3c6b21846271bcdba3818ba323d1b0bb096f.tar.gz dokka-1c4a3c6b21846271bcdba3818ba323d1b0bb096f.tar.bz2 dokka-1c4a3c6b21846271bcdba3818ba323d1b0bb096f.zip |
Merge Android plugin into Gradle plugin
Diffstat (limited to 'runners/gradle-plugin')
7 files changed, 206 insertions, 147 deletions
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<PlatformData>? { - val targets: NamedDomainObjectCollection<KotlinTarget> - 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<Task>): PlatformData? { - val allClasspath = mutableSetOf<File>() - var allClasspathFileCollection: FileCollection = project.files() - val allSourceRoots = mutableSetOf<File>() - - kotlinTasks.forEach { - with(ReflectDsl) { - val taskSourceRoots: List<File> - val abstractKotlinCompileClz: Class<out Any> - try { - taskSourceRoots = it["sourceRootsContainer"]["sourceRoots"].v() - abstractKotlinCompileClz = DokkaTask.getAbstractKotlinCompileFor(it)!! - } catch (e: NullPointerException) { - println("Cannot extract sources from Kotlin tasks! Consider upgrading Kotlin Gradle Plugin") - return null - } - - val taskClasspath: Iterable<File> = - (it["getClasspath", AbstractCompile::class].takeIfIsFunc()?.invoke() - ?: it["compileClasspath", abstractKotlinCompileClz].takeIfIsProp()?.v() - ?: it["getClasspath", abstractKotlinCompileClz]()) - - if (taskClasspath is FileCollection) { - allClasspathFileCollection += taskClasspath - } else { - allClasspath += taskClasspath - } - allSourceRoots += taskSourceRoots.filter { it.exists() } - } - } - val classpath: MutableList<File> = try { - allClasspathFileCollection.toMutableList() - } catch (e: ResolveException) { - mutableListOf() - } - classpath.addAll (project.files(allClasspath).toList()) - - return PlatformData(null, classpath, allSourceRoots.toList(), "") - } - - 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<File> = getMainCompilation(target) - ?.allKotlinSourceSets - ?.flatMap { it.kotlin.sourceDirectories } - ?.filter { it.exists() } - .orEmpty() - - private fun getClasspath(target: KotlinTarget?): List<File> = getMainCompilation(target) - ?.compileDependencyFiles - ?.files - ?.toList() - ?.filter { it.exists() } - .orEmpty() - - private fun getMainCompilation(target: KotlinTarget?): KotlinCompilation<KotlinCommonOptions>? = - 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<File>, - val sourceRoots: 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/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<PlatformData>? { + val targets: NamedDomainObjectCollection<KotlinTarget> + 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<Task>): PlatformData? { + val allClasspath = mutableSetOf<File>() + var allClasspathFileCollection: FileCollection = project.files() + val allSourceRoots = mutableSetOf<File>() + + kotlinTasks.forEach { + with(ReflectDsl) { + val taskSourceRoots: List<File> + val abstractKotlinCompileClz: Class<out Any> + try { + taskSourceRoots = it["sourceRootsContainer"]["sourceRoots"].v() + abstractKotlinCompileClz = DokkaTask.getAbstractKotlinCompileFor(it)!! + } catch (e: NullPointerException) { + println("Cannot extract sources from Kotlin tasks! Consider upgrading Kotlin Gradle Plugin") + return null + } + + val taskClasspath: Iterable<File> = + (it["getClasspath", AbstractCompile::class].takeIfIsFunc()?.invoke() + ?: it["compileClasspath", abstractKotlinCompileClz].takeIfIsProp()?.v() + ?: it["getClasspath", abstractKotlinCompileClz]()) + + if (taskClasspath is FileCollection) { + allClasspathFileCollection += taskClasspath + } else { + allClasspath += taskClasspath + } + allSourceRoots += taskSourceRoots.filter { it.exists() } + } + } + val classpath: MutableList<File> = try { + allClasspathFileCollection.toMutableList() + } catch (e: ResolveException) { + mutableListOf() + } + classpath.addAll (project.files(allClasspath).toList()) + + return PlatformData(null, classpath, allSourceRoots.toList(), "") + } + + 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<File> = getMainCompilation(target) + ?.allKotlinSourceSets + ?.flatMap { it.kotlin.sourceDirectories } + ?.filter { it.exists() } + .orEmpty() + + private fun getClasspath(target: KotlinTarget?): List<File> = getMainCompilation(target) + ?.compileDependencyFiles + ?.files + ?.toList() + ?.filter { it.exists() } + .orEmpty() + + private fun getMainCompilation(target: KotlinTarget?): KotlinCompilation<KotlinCommonOptions>? = + 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<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 + } + + 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 }
\ 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<Task> = with(ReflectDsl) { @@ -69,11 +71,11 @@ open class DokkaTask : DefaultTask() { // Configure Dokka with closure in Gradle Kotlin DSL fun configuration(action: Action<in GradlePassConfigurationImpl>) = action.execute(configuration) - protected var externalDocumentationLinks: MutableList<DokkaConfiguration.ExternalDocumentationLink> = mutableListOf() + private var externalDocumentationLinks: MutableList<DokkaConfiguration.ExternalDocumentationLink> = mutableListOf() private val kotlinTasks: List<Task> by lazy { extractKotlinCompileTasks() } - protected open val configurationExtractor: AbstractConfigurationExtractor = ConfigurationExtractor(project) + private val configurationExtractor = ConfigurationExtractor(project) @Input var subProjects: List<String> = emptyList() @@ -121,7 +123,17 @@ open class DokkaTask : DefaultTask() { private fun Iterable<File>.toSourceRoots(): List<GradleSourceRootImpl> = this.filter { it.exists() }.map { GradleSourceRootImpl().apply { path = it.path } } private fun Iterable<String>.toProjects(): List<Project> = project.subprojects.toList().filter { this.contains(it.name) } - protected open fun collectSuppressedFiles(sourceRoots: List<SourceRoot>): List<String> = emptyList() + protected open fun collectSuppressedFiles(sourceRoots: List<SourceRoot>) = + if(project.isAndroidProject()) { + val generatedRoot = project.buildDir.resolve("generated").absoluteFile + sourceRoots + .map { File(it.path) } + .filter { it.startsWith(generatedRoot) } + .flatMap { it.walk().toList() } + .map { it.absolutePath } + } else { + emptyList() + } @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<String> = 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<Project> { 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<out DokkaTask>) { + private fun addTasks(project: Project, runtimeConfiguration: Configuration, taskClass: Class<out DokkaTask>) { 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 |