diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/build.gradle b/libraries/tools/kotlin-gradle-plugin-integration-tests/build.gradle index 7c56d30c6f6..296613fd1d6 100644 --- a/libraries/tools/kotlin-gradle-plugin-integration-tests/build.gradle +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/build.gradle @@ -59,4 +59,4 @@ tasks.withType(Test) { } } } -} \ No newline at end of file +} diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/PluginsDslIT.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/PluginsDslIT.kt new file mode 100644 index 00000000000..708c71db242 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/PluginsDslIT.kt @@ -0,0 +1,133 @@ +package org.jetbrains.kotlin.gradle + +import org.gradle.api.logging.LogLevel +import org.jetbrains.kotlin.gradle.util.modify +import org.junit.Assert +import org.junit.AssumptionViolatedException +import org.junit.Test +import java.io.File +import javax.xml.parsers.DocumentBuilderFactory + +class PluginsDslIT : BaseGradleIT() { + + @Test + fun testAllopenWithPluginsDsl() { + val project = projectWithMavenLocalPlugins("allopenPluginsDsl") + project.build("build") { + assertSuccessful() + assertTasksExecuted(listOf(":compileKotlin")) + } + } + + @Test + fun testApplyToSubprojects() { + val project = projectWithMavenLocalPlugins("applyToSubprojects") + project.build("build") { + assertSuccessful() + assertTasksExecuted(listOf(":subproject:compileKotlin")) + } + } + + @Test + fun testApplyAllPlugins() { + val project = projectWithMavenLocalPlugins("applyAllPlugins") + + val kotlinPluginClasses = setOf( + "org.jetbrains.kotlin.gradle.plugin.KotlinPluginWrapper", + "org.jetbrains.kotlin.gradle.internal.Kapt3GradleSubplugin", + "org.jetbrains.kotlin.allopen.gradle.AllOpenGradleSubplugin", + "org.jetbrains.kotlin.allopen.gradle.SpringGradleSubplugin", + "org.jetbrains.kotlin.noarg.gradle.NoArgGradleSubplugin", + "org.jetbrains.kotlin.noarg.gradle.KotlinJpaSubplugin") + + project.build("build") { + assertSuccessful() + val appliedPlugins = "applied plugin class\\:(.*)".toRegex().findAll(output).map { it.groupValues[1] }.toSet() + kotlinPluginClasses.forEach { + Assert.assertTrue("Plugin class $it should be in applied plugins", it in appliedPlugins) + } + } + } + + companion object { + private const val GRADLE_VERSION = "4.0" + private const val DIRECTORY_PREFIX = "pluginsDsl" + + private const val MAVEN_LOCAL_URL_PLACEHOLDER = "" + private const val PLUGIN_MARKER_VERSION_PLACEHOLDER = "" + + // Workaround for the restriction that snapshot versions are not supported + private val MARKER_VERSION = KOTLIN_VERSION + (System.getProperty("pluginMarkerVersionSuffix") ?: "-test") + } + + private fun projectWithMavenLocalPlugins( + projectName: String, + wrapperVersion: String = GRADLE_VERSION, + directoryPrefix: String? = DIRECTORY_PREFIX, + minLogLevel: LogLevel = LogLevel.DEBUG + ): Project { + + val result = Project(projectName, wrapperVersion, directoryPrefix, minLogLevel) + result.setupWorkingDir() + + val settingsGradle = File(result.projectDir, "settings.gradle") + settingsGradle.modify { + val mavenLocalUrl = MavenLocalUrlProvider.mavenLocalUrl + + it.replace(MAVEN_LOCAL_URL_PLACEHOLDER, mavenLocalUrl).apply { + if (this == it) + throw AssumptionViolatedException("$MAVEN_LOCAL_URL_PLACEHOLDER placeholder not found in settings.gradle") + } + } + + result.projectDir.walkTopDown() + .filter { it.isFile && it.name == "build.gradle" } + .forEach { buildGradle -> + buildGradle.modify { text -> + text.replace(PLUGIN_MARKER_VERSION_PLACEHOLDER, MARKER_VERSION) + } + } + + return result + } +} + +/** Copies the logic of Gradle [`mavenLocal()`](https://docs.gradle.org/3.4.1/dsl/org.gradle.api.artifacts.dsl.RepositoryHandler.html#org.gradle.api.artifacts.dsl.RepositoryHandler:mavenLocal()) + */ +private object MavenLocalUrlProvider { + /** The URL that points to the Gradle's mavenLocal() repository. */ + val mavenLocalUrl by lazy { + val path = propertyMavenLocalRepoPath ?: + homeSettingsLocalRepoPath ?: + m2HomeSettingsLocalRepoPath ?: + defaultM2RepoPath + File(path).toURI().toString() + } + + private val homeDir get() = File(System.getProperty("user.home")) + + private fun getLocalRepositoryFromXml(file: File): String? { + if (!file.isFile) + return null + + val xml = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(file) + val localRepoNodes = xml.getElementsByTagName("localRepository") + + if (localRepoNodes.length == 0) + return null + + val content = localRepoNodes.item(0).textContent + + return content.replace("\\$\\{(.*?)\\}".toRegex()) { System.getProperty(it.groupValues[1]) ?: it.value } + } + + private val propertyMavenLocalRepoPath get() = System.getProperty("maven.repo.local") + + private val homeSettingsLocalRepoPath + get() = getLocalRepositoryFromXml(File(homeDir, ".m2/settings.xml")) + + private val m2HomeSettingsLocalRepoPath + get() = System.getProperty("M2_HOME")?.let { getLocalRepositoryFromXml(File(it, "conf/settings.xml")) } + + private val defaultM2RepoPath get() = File(homeDir, ".m2/repository").absolutePath +} \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/pluginsDsl/allopenPluginsDsl/build.gradle b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/pluginsDsl/allopenPluginsDsl/build.gradle new file mode 100644 index 00000000000..83f6b157d04 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/pluginsDsl/allopenPluginsDsl/build.gradle @@ -0,0 +1,18 @@ +plugins { + id 'org.jetbrains.kotlin.jvm' version '' + id 'org.jetbrains.kotlin.plugin.allopen' version '' +} + +repositories { + mavenCentral() + mavenLocal() +} + +allOpen { + annotation("lib.AllOpen") +} + +dependencies { + compile "org.jetbrains.kotlin:kotlin-stdlib-jre8" + testCompile "junit:junit:4.12" +} \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/pluginsDsl/allopenPluginsDsl/settings.gradle b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/pluginsDsl/allopenPluginsDsl/settings.gradle new file mode 100644 index 00000000000..a3723bd2b65 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/pluginsDsl/allopenPluginsDsl/settings.gradle @@ -0,0 +1,6 @@ +pluginManagement { + repositories { + maven { url '' } + gradlePluginPortal() + } +} \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/pluginsDsl/allopenPluginsDsl/src/main/kotlin/annotations.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/pluginsDsl/allopenPluginsDsl/src/main/kotlin/annotations.kt new file mode 100644 index 00000000000..b3b21ba837a --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/pluginsDsl/allopenPluginsDsl/src/main/kotlin/annotations.kt @@ -0,0 +1,5 @@ +package lib + +annotation class AllOpen + +annotation class AllClose \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/pluginsDsl/allopenPluginsDsl/src/main/kotlin/test.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/pluginsDsl/allopenPluginsDsl/src/main/kotlin/test.kt new file mode 100644 index 00000000000..d33c0c3a094 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/pluginsDsl/allopenPluginsDsl/src/main/kotlin/test.kt @@ -0,0 +1,13 @@ +package test + +import lib.* + +@AllOpen +class OpenClass { + fun method() {} +} + +@AllClose // effectively does nothing +class ClosedClass { + fun method() {} +} \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/pluginsDsl/allopenPluginsDsl/src/test/kotlin/HelloTest.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/pluginsDsl/allopenPluginsDsl/src/test/kotlin/HelloTest.kt new file mode 100644 index 00000000000..236ca68fa9c --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/pluginsDsl/allopenPluginsDsl/src/test/kotlin/HelloTest.kt @@ -0,0 +1,14 @@ +import test.* + +import org.junit.Test +import org.junit.Assert.* + +class Derived : OpenClass() { +} + +class HelloTest { + @Test fun testOpen() { + val d = Derived() + assertTrue(d is OpenClass) + } +} \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/pluginsDsl/applyAllPlugins/build.gradle b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/pluginsDsl/applyAllPlugins/build.gradle new file mode 100644 index 00000000000..a76f042324c --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/pluginsDsl/applyAllPlugins/build.gradle @@ -0,0 +1,22 @@ +plugins { + id 'org.jetbrains.kotlin.jvm' version '' + id 'org.jetbrains.kotlin.kapt' version '' + id 'org.jetbrains.kotlin.plugin.allopen' version '' + id 'org.jetbrains.kotlin.plugin.spring' version '' + id 'org.jetbrains.kotlin.plugin.noarg' version '' + id 'org.jetbrains.kotlin.plugin.jpa' version '' +} + +repositories { + mavenCentral() + mavenLocal() +} + +dependencies { + compile "org.jetbrains.kotlin:kotlin-stdlib-jre8" + testCompile "junit:junit:4.12" +} + +afterEvaluate { + plugins.forEach { println("applied plugin class:" + it.class.canonicalName) } +} \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/pluginsDsl/applyAllPlugins/settings.gradle b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/pluginsDsl/applyAllPlugins/settings.gradle new file mode 100644 index 00000000000..bcbc4d55acf --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/pluginsDsl/applyAllPlugins/settings.gradle @@ -0,0 +1,6 @@ +pluginManagement { + repositories { + maven { url '' } + gradlePluginPortal() + } +} \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/pluginsDsl/applyToSubprojects/build.gradle b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/pluginsDsl/applyToSubprojects/build.gradle new file mode 100644 index 00000000000..9c0807baf87 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/pluginsDsl/applyToSubprojects/build.gradle @@ -0,0 +1,14 @@ +plugins { + id 'org.jetbrains.kotlin.jvm' version '' apply false +} + +allprojects { + repositories { + mavenLocal() + mavenCentral() + } +} + +subprojects { + apply plugin: 'org.jetbrains.kotlin.jvm' +} \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/pluginsDsl/applyToSubprojects/settings.gradle b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/pluginsDsl/applyToSubprojects/settings.gradle new file mode 100644 index 00000000000..9f109b9a3cd --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/pluginsDsl/applyToSubprojects/settings.gradle @@ -0,0 +1,8 @@ +pluginManagement { + repositories { + maven { url '' } + gradlePluginPortal() + } +} + +include 'subproject' \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/pluginsDsl/applyToSubprojects/subproject/build.gradle b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/pluginsDsl/applyToSubprojects/subproject/build.gradle new file mode 100644 index 00000000000..aff049022b6 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/pluginsDsl/applyToSubprojects/subproject/build.gradle @@ -0,0 +1,9 @@ +dependencies { + compile 'com.google.guava:guava:12.0' + testCompile 'org.testng:testng:6.8' + compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" +} + +test { + useTestNG() +} \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/pluginsDsl/applyToSubprojects/subproject/src/main/kotlin/helloWorld.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/pluginsDsl/applyToSubprojects/subproject/src/main/kotlin/helloWorld.kt new file mode 100644 index 00000000000..f1e2b0d1f91 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/pluginsDsl/applyToSubprojects/subproject/src/main/kotlin/helloWorld.kt @@ -0,0 +1,18 @@ +package demo + +import sun.nio.cs.ext.Big5 +import sun.net.spi.nameservice.dns.DNSNameService +import javax.crypto.Cipher +import com.sun.crypto.provider.SunJCE +import sun.nio.ByteBuffered + +fun box(): String { + val a = Big5() // charsets.jar + val c = DNSNameService() // dnsns.ajr + val e : Cipher? = null // jce.jar + val f : SunJCE? = null // sunjce_provider.jar + val j : ByteBuffered? = null // rt.jar + return "OK" +} + + diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/pluginsDsl/applyToSubprojects/subproject/src/test/kotlin/tests.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/pluginsDsl/applyToSubprojects/subproject/src/test/kotlin/tests.kt new file mode 100644 index 00000000000..6e9eb5e69b8 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/pluginsDsl/applyToSubprojects/subproject/src/test/kotlin/tests.kt @@ -0,0 +1,11 @@ +package demo + +import org.testng.Assert.* +import org.testng.annotations.Test as test + +class TestSource() { + @test fun f() { + assertEquals(box(), "OK") + } +} +