diff --git a/libraries/tools/kotlin-gradle-plugin-core/src/main/kotlin/org/jetbrains/kotlin/gradle/tasks/Tasks.kt b/libraries/tools/kotlin-gradle-plugin-core/src/main/kotlin/org/jetbrains/kotlin/gradle/tasks/Tasks.kt index 6e6fe774b9e..eff94ca6a9c 100644 --- a/libraries/tools/kotlin-gradle-plugin-core/src/main/kotlin/org/jetbrains/kotlin/gradle/tasks/Tasks.kt +++ b/libraries/tools/kotlin-gradle-plugin-core/src/main/kotlin/org/jetbrains/kotlin/gradle/tasks/Tasks.kt @@ -73,6 +73,7 @@ abstract class AbstractKotlinCompile() : AbstractCo var compilerCalled: Boolean = false // TODO: consider more reliable approach (see usage) var anyClassesCompiled: Boolean = false + var friendTaskName: String? = null private val loggerInstance = Logging.getLogger(this.javaClass) override fun getLogger() = loggerInstance @@ -145,7 +146,6 @@ abstract class AbstractKotlinCompile() : AbstractCo } - open class KotlinCompile() : AbstractKotlinCompile() { override val compiler = K2JVMCompiler() override fun createBlankArgs(): K2JVMCompilerArguments = K2JVMCompilerArguments() @@ -154,12 +154,6 @@ open class KotlinCompile() : AbstractKotlinCompile() { // Should be SourceDirectorySet or File val srcDirsSources = HashSet() - private val testsMap = mapOf( - "compileTestKotlin" to "compileKotlin", - "compileDebugUnitTestKotlin" to "compileDebugKotlin", - "compileReleaseUnitTestKotlin" to "compileReleaseKotlin" - ) - // TODO: find out whether we really need to be able to override destination dir here, and how it should work with destinationDir property private val compilerDestinationDir: String get() = if (StringUtils.isEmpty(kotlinOptions.destination)) { kotlinDestinationDir?.path.orEmpty() } else { kotlinOptions.destination } @@ -209,7 +203,7 @@ open class KotlinCompile() : AbstractKotlinCompile() { args.moduleName = kotlinOptions.moduleName ?: extraProperties.getOrNull("defaultModuleName") args.languageVersion = kotlinOptions.languageVersion - fun addFriendPathForTestTask(taskName: String) { + fun addFriendPathForTestTask(taskName: String) { logger.kotlinDebug("try to determine the output directory of corresponding $taskName task") val tasks = project.getTasksByName("$taskName", false) logger.kotlinDebug("tasks for $taskName: ${tasks}") @@ -223,10 +217,8 @@ open class KotlinCompile() : AbstractKotlinCompile() { } } - testsMap.get(this.name)?.let { - addFriendPathForTestTask(it) - } - + logger.kotlinDebug { "friendTaskName = $friendTaskName" } + friendTaskName?.let { addFriendPathForTestTask(it) } logger.kotlinDebug("args.moduleName = ${args.moduleName}") } diff --git a/libraries/tools/kotlin-gradle-plugin/pom.xml b/libraries/tools/kotlin-gradle-plugin/pom.xml index d3a291a0335..e6f26e0ab64 100644 --- a/libraries/tools/kotlin-gradle-plugin/pom.xml +++ b/libraries/tools/kotlin-gradle-plugin/pom.xml @@ -66,7 +66,6 @@ - ${project.basedir}/src/main/kotlin ${project.basedir}/src/test/kotlin diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinPlugin.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinPlugin.kt index 92c8a96ceba..c765be1e9c8 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinPlugin.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinPlugin.kt @@ -48,7 +48,8 @@ abstract class KotlinSourceSetProcessor( val pluginName: String, val compileTaskNameSuffix: String, val taskDescription: String, - val compilerClass: Class + val compilerClass: Class, + val tasksProvider: KotlinTasksProvider ) { abstract protected fun doTargetSpecificProcessing() val logger = Logging.getLogger(this.javaClass) @@ -98,9 +99,9 @@ abstract class KotlinSourceSetProcessor( open protected fun createKotlinCompileTask(suffix: String = ""): T { val name = sourceSet.getCompileTaskName(compileTaskNameSuffix) + suffix logger.kotlinDebug("Creating kotlin compile task $name with class $compilerClass") - val compile = project.tasks.create(name, compilerClass) + val compile = tasksProvider.createKotlinJVMTask(project, name) compile.extensions.extraProperties.set("defaultModuleName", "${project.name}-$name") - return compile + return compilerClass.cast(compile) } open protected fun commonTaskConfiguration() { @@ -116,13 +117,14 @@ class Kotlin2JvmSourceSetProcessor( javaBasePlugin: JavaBasePlugin, sourceSet: SourceSet, val scriptHandler: ScriptHandler, - val tasksProvider: KotlinTasksProvider + tasksProvider: KotlinTasksProvider ) : KotlinSourceSetProcessor( project, javaBasePlugin, sourceSet, pluginName = "kotlin", compileTaskNameSuffix = "kotlin", taskDescription = "Compiles the $sourceSet.kotlin.", - compilerClass = tasksProvider.kotlinJVMCompileTaskClass + compilerClass = tasksProvider.kotlinJVMCompileTaskClass, + tasksProvider = tasksProvider ) { private companion object { @@ -186,13 +188,14 @@ class Kotlin2JsSourceSetProcessor( javaBasePlugin: JavaBasePlugin, sourceSet: SourceSet, val scriptHandler: ScriptHandler, - val tasksProvider: KotlinTasksProvider + tasksProvider: KotlinTasksProvider ) : KotlinSourceSetProcessor( project, javaBasePlugin, sourceSet, pluginName = "kotlin2js", taskDescription = "Compiles the kotlin sources in $sourceSet to JavaScript.", compileTaskNameSuffix = "kotlin2Js", - compilerClass = tasksProvider.kotlinJSCompileTaskClass + compilerClass = tasksProvider.kotlinJSCompileTaskClass, + tasksProvider = tasksProvider ) { val copyKotlinJsTaskName = sourceSet.getTaskName("copy", "kotlinJs") diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinPluginWrapper.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinPluginWrapper.kt index 22bf81aca39..7bbd85cf4c6 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinPluginWrapper.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinPluginWrapper.kt @@ -5,6 +5,7 @@ import org.gradle.api.Project import org.gradle.api.initialization.dsl.ScriptHandler import org.gradle.api.logging.Logger import org.gradle.api.logging.Logging +import org.jetbrains.kotlin.gradle.tasks.AndroidTasksProvider import org.jetbrains.kotlin.gradle.tasks.KotlinTasksProvider // TODO: simplify: the complicated structure is a leftover from dynamic loading of plugin core, could be significantly simplified now @@ -59,7 +60,7 @@ open class KotlinPluginWrapper: KotlinBasePluginWrapper() { } open class KotlinAndroidPluginWrapper : KotlinBasePluginWrapper() { - override fun getPlugin(pluginClassLoader: ClassLoader, scriptHandler: ScriptHandler) = KotlinAndroidPlugin(scriptHandler, KotlinTasksProvider(pluginClassLoader)) + override fun getPlugin(pluginClassLoader: ClassLoader, scriptHandler: ScriptHandler) = KotlinAndroidPlugin(scriptHandler, AndroidTasksProvider(pluginClassLoader)) } open class Kotlin2JsPluginWrapper : KotlinBasePluginWrapper() { diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/TaskToFriendTaskMapper.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/TaskToFriendTaskMapper.kt new file mode 100644 index 00000000000..95647bc8d49 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/TaskToFriendTaskMapper.kt @@ -0,0 +1,47 @@ +/* + * Copyright 2010-2016 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.kotlin.gradle.plugin + +import org.gradle.api.Task +import org.jetbrains.annotations.TestOnly + +abstract class TaskToFriendTaskMapper { + operator fun get(task: Task): String? = + getFriendByName(task.name) + + @TestOnly + operator fun get(name: String): String? = + getFriendByName(name) + + protected abstract fun getFriendByName(name: String): String? +} + +sealed class RegexTaskToFriendTaskMapper( + private val prefix: String, + private val suffix: String +) : TaskToFriendTaskMapper() { + class Default : RegexTaskToFriendTaskMapper("compile", "TestKotlin") + class Android : RegexTaskToFriendTaskMapper("compile", "(Unit|Android)TestKotlin") + + private val regex = "$prefix(.*)$suffix".toRegex() + + override fun getFriendByName(name: String): String? { + val match = regex.matchEntire(name) ?: return null + val variant = match.groups[1]?.value ?: "" + return prefix + variant + "Kotlin" + } +} \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/taskUtils.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/taskUtils.kt index 669118457a4..75369313a48 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/taskUtils.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/taskUtils.kt @@ -53,6 +53,7 @@ internal fun AbstractCompile.appendClasspathDynamically(file: File) { internal var AbstractTask.anyClassesCompiled: Boolean? by TaskPropertyDelegate("anyClassesCompiled") internal var AbstractTask.kotlinDestinationDir: File? by TaskPropertyDelegate("kotlinDestinationDir") +internal var AbstractTask.friendTaskName: String? by TaskPropertyDelegate("friendTaskName") inline internal fun TaskPropertyDelegate(propertyName: String) = diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/tasks/TasksProvider.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/tasks/TasksProvider.kt index 2c317d58a6c..0a68d85ee18 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/tasks/TasksProvider.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/tasks/TasksProvider.kt @@ -4,6 +4,9 @@ import org.gradle.api.tasks.compile.AbstractCompile import org.gradle.api.Task import org.gradle.api.Project import org.gradle.api.tasks.SourceTask +import org.jetbrains.kotlin.gradle.plugin.RegexTaskToFriendTaskMapper +import org.jetbrains.kotlin.gradle.plugin.TaskToFriendTaskMapper +import org.jetbrains.kotlin.gradle.plugin.friendTaskName import java.net.URLClassLoader /** @@ -12,7 +15,7 @@ import java.net.URLClassLoader * date: 17.12.2014. */ -public open class KotlinTasksProvider(val tasksLoader: ClassLoader) { +open class KotlinTasksProvider(val tasksLoader: ClassLoader) { val kotlinJVMCompileTaskClass: Class = tasksLoader.loadClass("org.jetbrains.kotlin.gradle.tasks.KotlinCompile") as Class @@ -22,12 +25,21 @@ public open class KotlinTasksProvider(val tasksLoader: ClassLoader) { val kotlinJVMOptionsClass: Class = tasksLoader.loadClass("org.jetbrains.kotlin.cli.common.arguments.K2JVMCompilerArguments") as Class - - public fun createKotlinJVMTask(project: Project, name: String): AbstractCompile { - return project.tasks.create(name, kotlinJVMCompileTaskClass) + fun createKotlinJVMTask(project: Project, name: String): AbstractCompile { + return project.tasks.create(name, kotlinJVMCompileTaskClass).apply { + friendTaskName = taskToFriendTaskMapper[this] + } } - public fun createKotlinJSTask(project: Project, name: String): AbstractCompile { + fun createKotlinJSTask(project: Project, name: String): AbstractCompile { return project.tasks.create(name, kotlinJSCompileTaskClass) } + + protected open val taskToFriendTaskMapper: TaskToFriendTaskMapper = + RegexTaskToFriendTaskMapper.Default() } + +class AndroidTasksProvider(tasksLoader: ClassLoader) : KotlinTasksProvider(tasksLoader) { + override val taskToFriendTaskMapper: TaskToFriendTaskMapper = + RegexTaskToFriendTaskMapper.Android() +} \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin/src/test/kotlin/org/jetbrains/kotlin/gradle/AbstractKotlinAndroidGradleTests.kt b/libraries/tools/kotlin-gradle-plugin/src/test/kotlin/org/jetbrains/kotlin/gradle/AbstractKotlinAndroidGradleTests.kt index c4359e80609..6580b52b9e5 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/test/kotlin/org/jetbrains/kotlin/gradle/AbstractKotlinAndroidGradleTests.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/test/kotlin/org/jetbrains/kotlin/gradle/AbstractKotlinAndroidGradleTests.kt @@ -18,11 +18,13 @@ abstract class AbstractKotlinAndroidGradleTests( androidHome = File("../../../dependencies/android-sdk-for-tests"), androidGradlePluginVersion = androidGradlePluginVersion) + + @Test fun testSimpleCompile() { val project = Project("AndroidProject", gradleVersion) - project.build("build") { + project.build("build", "assembleAndroidTest") { assertSuccessful() assertContains(":Lib:compileReleaseKotlin", ":Test:compileDebugKotlin", @@ -37,7 +39,10 @@ abstract class AbstractKotlinAndroidGradleTests( ":compileFlavor1Jnidebug", ":compileFlavor2Jnidebug", ":compileFlavor1Release", - ":compileFlavor2Release") + ":compileFlavor2Release", + ":compileFlavor1DebugUnitTestKotlin", + "InternalDummyTest PASSED", + ":compileFlavor1DebugAndroidTestKotlin") } // Run the build second time, assert everything is up-to-date diff --git a/libraries/tools/kotlin-gradle-plugin/src/test/kotlin/org/jetbrains/kotlin/gradle/plugin/RegexTaskToFriendTaskMapperTest.kt b/libraries/tools/kotlin-gradle-plugin/src/test/kotlin/org/jetbrains/kotlin/gradle/plugin/RegexTaskToFriendTaskMapperTest.kt new file mode 100644 index 00000000000..f8b6818d600 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin/src/test/kotlin/org/jetbrains/kotlin/gradle/plugin/RegexTaskToFriendTaskMapperTest.kt @@ -0,0 +1,44 @@ +/* + * Copyright 2010-2016 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.kotlin.gradle.plugin + +import org.junit.Assert +import org.junit.Test + +class RegexTaskToFriendTaskMapperTest { + @Test + fun getFriendTaskNameDefault() { + val mapper = RegexTaskToFriendTaskMapper.Default() + Assert.assertEquals("compileKotlin", mapper["compileTestKotlin"]) + Assert.assertEquals(null, mapper["compileKotlin"]) + } + + @Test + fun getFriendTaskNameAndroid() { + val mapper = RegexTaskToFriendTaskMapper.Android() + // Unit test examples + Assert.assertEquals("compileDebugKotlin", mapper["compileDebugUnitTestKotlin"]) + Assert.assertEquals("compileReleaseKotlin", mapper["compileReleaseUnitTestKotlin"]) + Assert.assertEquals("compileProdDebugKotlin", mapper["compileProdDebugUnitTestKotlin"]) + // Android test examples + Assert.assertEquals("compileDebugKotlin", mapper["compileDebugAndroidTestKotlin"]) + Assert.assertEquals("compileReleaseKotlin", mapper["compileReleaseAndroidTestKotlin"]) + Assert.assertEquals("compileProdDebugKotlin", mapper["compileProdDebugAndroidTestKotlin"]) + + Assert.assertEquals(null, mapper["compileDebugKotlin"]) + } +} \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin/src/test/resources/testProject/AndroidProject/Android/build.gradle b/libraries/tools/kotlin-gradle-plugin/src/test/resources/testProject/AndroidProject/Android/build.gradle index 6286c004c33..174e86dd3e0 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/test/resources/testProject/AndroidProject/Android/build.gradle +++ b/libraries/tools/kotlin-gradle-plugin/src/test/resources/testProject/AndroidProject/Android/build.gradle @@ -4,6 +4,8 @@ apply plugin: 'kotlin-android' dependencies { compile project(':Lib') + compile "org.jetbrains.kotlin:kotlin-stdlib:1.1-SNAPSHOT" + testCompile 'junit:junit:4.12' } android { @@ -12,6 +14,7 @@ android { sourceSets { main.kotlin.srcDirs += 'root/kotlin' + test.kotlin.srcDirs += 'src/test/kotlin' } defaultConfig { diff --git a/libraries/tools/kotlin-gradle-plugin/src/test/resources/testProject/AndroidProject/Android/src/androidTest/java/org/jetbrains/kotlin/gradle/InternalDummyApplicationTest.kt b/libraries/tools/kotlin-gradle-plugin/src/test/resources/testProject/AndroidProject/Android/src/androidTest/java/org/jetbrains/kotlin/gradle/InternalDummyApplicationTest.kt new file mode 100644 index 00000000000..8ca73021cab --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin/src/test/resources/testProject/AndroidProject/Android/src/androidTest/java/org/jetbrains/kotlin/gradle/InternalDummyApplicationTest.kt @@ -0,0 +1,27 @@ +/* + * Copyright 2010-2016 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.kotlin.gradle + +import android.app.Application +import android.test.ApplicationTestCase + +class InternalDummyApplicationTest : ApplicationTestCase(Application::class.java) { + init { + val dummy = InternalDummy("World") + assert("Hello World!" == dummy.greeting) { "Expected: 'Hello World!'. Actual value: ${dummy.greeting}" } + } +} \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin/src/test/resources/testProject/AndroidProject/Android/src/main/java/org/jetbrains/kotlin/gradle/InternalDummy.kt b/libraries/tools/kotlin-gradle-plugin/src/test/resources/testProject/AndroidProject/Android/src/main/java/org/jetbrains/kotlin/gradle/InternalDummy.kt new file mode 100644 index 00000000000..d51c156db27 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin/src/test/resources/testProject/AndroidProject/Android/src/main/java/org/jetbrains/kotlin/gradle/InternalDummy.kt @@ -0,0 +1,6 @@ +package org.jetbrains.kotlin.gradle + +internal class InternalDummy(private val name: String) { + internal val greeting: String + get() = "Hello $name!" +} \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin/src/test/resources/testProject/AndroidProject/Android/src/test/kotlin/org/jetbrains/kotlin/gradle/InternalDummyTest.kt b/libraries/tools/kotlin-gradle-plugin/src/test/resources/testProject/AndroidProject/Android/src/test/kotlin/org/jetbrains/kotlin/gradle/InternalDummyTest.kt new file mode 100644 index 00000000000..7fb62ec0627 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin/src/test/resources/testProject/AndroidProject/Android/src/test/kotlin/org/jetbrains/kotlin/gradle/InternalDummyTest.kt @@ -0,0 +1,12 @@ +package org.jetbrains.kotlin.gradle + +import org.junit.Assert +import org.junit.Test + +class InternalDummyTest { + @Test + fun testInternalDummy() { + val dummy = InternalDummy("World") + Assert.assertEquals("Hello World!", dummy.greeting) + } +} \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin/src/test/resources/testProject/AndroidProject/Lib/build.gradle b/libraries/tools/kotlin-gradle-plugin/src/test/resources/testProject/AndroidProject/Lib/build.gradle index b299fbac774..eebe0fce4a0 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/test/resources/testProject/AndroidProject/Lib/build.gradle +++ b/libraries/tools/kotlin-gradle-plugin/src/test/resources/testProject/AndroidProject/Lib/build.gradle @@ -2,10 +2,6 @@ apply plugin: 'android-sdk-manager' apply plugin: 'com.android.library' apply plugin: 'kotlin-android' -repositories { - mavenCentral() -} - dependencies { compile files('libs/android-support-v4.jar') } diff --git a/libraries/tools/kotlin-gradle-plugin/src/test/resources/testProject/AndroidProject/build.gradle b/libraries/tools/kotlin-gradle-plugin/src/test/resources/testProject/AndroidProject/build.gradle index e03c11f8cfe..7662ad0fc39 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/test/resources/testProject/AndroidProject/build.gradle +++ b/libraries/tools/kotlin-gradle-plugin/src/test/resources/testProject/AndroidProject/build.gradle @@ -1,8 +1,6 @@ buildscript { repositories { - maven { - url 'file://' + pathToKotlinPlugin - } + maven { url 'file://' + pathToKotlinPlugin } maven { url 'http://jcenter.bintray.com' } @@ -14,4 +12,11 @@ buildscript { classpath ('com.android.tools.build:gradle:' + androidToolsVersion) classpath 'com.jakewharton.sdkmanager:gradle-plugin:0.12.+' } +} + +allprojects { + repositories { + maven { url 'file://' + pathToKotlinPlugin } + mavenCentral() + } } \ No newline at end of file