aboutsummaryrefslogtreecommitdiff
path: root/runners/gradle-plugin
diff options
context:
space:
mode:
authorKamil Doległo <kamilok1965@interia.pl>2019-08-22 16:04:19 +0200
committerKamil Doległo <kamilok1965@interia.pl>2019-08-22 16:04:19 +0200
commit1c4a3c6b21846271bcdba3818ba323d1b0bb096f (patch)
treefa3a5e40d879bd1dbb284c69cee1b418f5044021 /runners/gradle-plugin
parente224c709692adf450786e16e245b4574a480cdab (diff)
downloaddokka-1c4a3c6b21846271bcdba3818ba323d1b0bb096f.tar.gz
dokka-1c4a3c6b21846271bcdba3818ba323d1b0bb096f.tar.bz2
dokka-1c4a3c6b21846271bcdba3818ba323d1b0bb096f.zip
Merge Android plugin into Gradle plugin
Diffstat (limited to 'runners/gradle-plugin')
-rw-r--r--runners/gradle-plugin/build.gradle11
-rw-r--r--runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/AbstractConfigurationExtractor.kt135
-rw-r--r--runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/ConfigurationExtractor.kt161
-rw-r--r--runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/DokkaTask.kt25
-rw-r--r--runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/configurationImplementations.kt1
-rw-r--r--runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/main.kt6
-rw-r--r--runners/gradle-plugin/src/main/kotlin/org/jetbrains/dokka/gradle/utils.kt14
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