Refactoring: move gradle integration tests to separate module

This commit is contained in:
Alexey Tsvetkov
2016-09-26 16:34:03 +03:00
parent 8cc384a6dd
commit 1cc423b163
390 changed files with 193 additions and 52 deletions
@@ -0,0 +1,154 @@
<?xml version="1.0" encoding="UTF-8"?>
<project
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<properties>
<maven.version>3.0.4</maven.version>
</properties>
<parent>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-project</artifactId>
<version>1.1-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<artifactId>kotlin-gradle-plugin-integration-tests</artifactId>
<packaging>jar</packaging>
<dependencies>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-gradle-plugin</artifactId>
<version>${project.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-gradle-plugin</artifactId>
<type>test-jar</type>
<version>${project.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-gradle-subplugin-example</artifactId>
<version>${project.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-build-common-test</artifactId>
<version>${project.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>gradle-api</artifactId>
<version>2.2</version>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<testSourceDirectory>${project.basedir}/src/test/kotlin</testSourceDirectory>
<resources>
<resource>
<directory>${project.basedir}/src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
<plugins>
<plugin>
<artifactId>kotlin-maven-plugin</artifactId>
<groupId>org.jetbrains.kotlin</groupId>
<version>${project.version}</version>
<executions>
<execution>
<id>test-compile</id>
<phase>test-compile</phase>
<goals> <goal>test-compile</goal> </goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.19.1</version>
<configuration>
<excludes>
<exclude>src/test/resources/**</exclude>
</excludes>
</configuration>
</plugin>
<plugin>
<artifactId>maven-failsafe-plugin</artifactId>
<version>2.6</version>
<executions>
<execution>
<goals>
<goal>integration-test</goal>
<goal>verify</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-deploy-plugin</artifactId>
<configuration>
<skip>true</skip>
</configuration>
</plugin>
</plugins>
</build>
<profiles>
<profile>
<activation><activeByDefault>true</activeByDefault></activation>
<id>skip-gradle-integration-tests</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<configuration>
<skipTests>true</skipTests>
</configuration>
</plugin>
</plugins>
</build>
</profile>
<profile>
<id>run-gradle-integration-tests</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<configuration>
<skipTests>false</skipTests>
</configuration>
</plugin>
</plugins>
</build>
</profile>
</profiles>
<repositories>
<repository>
<id>jetbrains-utils</id>
<url>http://repository.jetbrains.com/utils</url>
</repository>
<repository>
<id>central</id>
<name>bintray</name>
<url>http://jcenter.bintray.com</url>
</repository>
</repositories>
</project>
@@ -0,0 +1,189 @@
package org.jetbrains.kotlin.gradle
import org.jetbrains.kotlin.gradle.util.getFileByName
import org.jetbrains.kotlin.gradle.util.modify
import org.junit.Test
import java.io.File
class KotlinAndroidGradleCLIOnly : AbstractKotlinAndroidGradleTests(gradleVersion = "2.3", androidGradlePluginVersion = "1.5.+")
abstract class AbstractKotlinAndroidGradleTests(
private val gradleVersion: String,
private val androidGradlePluginVersion: String
) : BaseGradleIT() {
override fun defaultBuildOptions() =
super.defaultBuildOptions().copy(androidHome = File("../../../dependencies/android-sdk-for-tests"),
androidGradlePluginVersion = androidGradlePluginVersion)
@Test
fun testSimpleCompile() {
val project = Project("AndroidProject", gradleVersion)
project.build("build", "assembleAndroidTest") {
assertSuccessful()
assertContains(":Lib:compileReleaseKotlin",
":Test:compileDebugKotlin",
":compileFlavor1DebugKotlin",
":compileFlavor2DebugKotlin",
":compileFlavor1JnidebugKotlin",
":compileFlavor1ReleaseKotlin",
":compileFlavor2JnidebugKotlin",
":compileFlavor2ReleaseKotlin",
":compileFlavor1Debug",
":compileFlavor2Debug",
":compileFlavor1Jnidebug",
":compileFlavor2Jnidebug",
":compileFlavor1Release",
":compileFlavor2Release",
":compileFlavor1DebugUnitTestKotlin",
"InternalDummyTest PASSED",
":compileFlavor1DebugAndroidTestKotlin")
checkKotlinGradleBuildServices()
}
// Run the build second time, assert everything is up-to-date
project.build("build") {
assertSuccessful()
assertContains(":Lib:compileReleaseKotlin UP-TO-DATE")
}
// Run the build third time, re-run tasks
project.build("build", "--rerun-tasks") {
assertSuccessful()
assertContains(":Lib:compileReleaseKotlin",
":Test:compileDebugKotlin",
":compileFlavor1DebugKotlin",
":compileFlavor2DebugKotlin",
":compileFlavor1JnidebugKotlin",
":compileFlavor1ReleaseKotlin",
":compileFlavor2JnidebugKotlin",
":compileFlavor2ReleaseKotlin",
":compileFlavor1Debug",
":compileFlavor2Debug",
":compileFlavor1Jnidebug",
":compileFlavor2Jnidebug",
":compileFlavor1Release",
":compileFlavor2Release")
checkKotlinGradleBuildServices()
}
}
@Test
fun testIncrementalCompile() {
val project = Project("AndroidIncrementalSingleModuleProject", gradleVersion)
val options = defaultBuildOptions().copy(incremental = true)
project.build("build", options = options) {
assertSuccessful()
}
val getSomethingKt = project.projectDir.walk().filter { it.isFile && it.name.endsWith("getSomething.kt") }.first()
getSomethingKt.writeText("""
package foo
fun getSomething() = 10
""")
project.build("build", options = options) {
assertSuccessful()
assertCompiledKotlinSources(listOf("app/src/main/kotlin/foo/KotlinActivity1.kt", "app/src/main/kotlin/foo/getSomething.kt"))
assertCompiledJavaSources(listOf("app/src/main/java/foo/JavaActivity.java"), weakTesting = true)
}
}
@Test
fun testIncrementalBuildWithNoChanges() {
val project = Project("AndroidIncrementalSingleModuleProject", gradleVersion)
val tasksToExecute = arrayOf(
":app:prepareComAndroidSupportAppcompatV72311Library",
":app:prepareComAndroidSupportSupportV42311Library",
":app:compileDebugKotlin",
":app:compileDebugJavaWithJavac"
)
project.build("assembleDebug") {
assertSuccessful()
assertContains(*tasksToExecute)
}
project.build("assembleDebug") {
assertSuccessful()
assertContains(*tasksToExecute.map { it + " UP-TO-DATE" }.toTypedArray())
}
}
@Test
fun testAndroidDaggerIC() {
val project = Project("AndroidDaggerProject", gradleVersion)
val options = defaultBuildOptions().copy(incremental = true)
project.build("assembleDebug", options = options) {
assertSuccessful()
}
val androidModuleKt = project.projectDir.getFileByName("AndroidModule.kt")
androidModuleKt.modify { it.replace("fun provideApplicationContext(): Context {",
"fun provideApplicationContext(): Context? {") }
// rebuilt because DaggerApplicationComponent.java was regenerated
val baseApplicationKt = project.projectDir.getFileByName("BaseApplication.kt")
// rebuilt because BuildConfig.java was regenerated (timestamp was changed)
val useBuildConfigJavaKt = project.projectDir.getFileByName("useBuildConfigJava.kt")
val stringsXml = project.projectDir.getFileByName("strings.xml")
stringsXml.modify { """
<resources>
<string name="app_name">kotlin</string>
<string name="app_name1">kotlin1</string>
</resources>
""" }
// rebuilt because R.java changed
val homeActivityKt = project.projectDir.getFileByName("HomeActivity.kt")
val useRJavaActivity = project.projectDir.getFileByName("UseRJavaActivity.kt")
project.build(":app:assembleDebug", options = options) {
assertSuccessful()
assertCompiledKotlinSources(project.relativize(
androidModuleKt,
baseApplicationKt,
useBuildConfigJavaKt,
homeActivityKt,
useRJavaActivity
))
}
}
@Test
fun testAndroidIcepickProject() {
val project = Project("AndroidIcepickProject", gradleVersion)
val options = defaultBuildOptions().copy(incremental = false)
project.build("assembleDebug", options = options) {
assertSuccessful()
}
}
@Test
fun testAndroidExtensions() {
val project = Project("AndroidExtensionsProject", gradleVersion)
val options = defaultBuildOptions().copy(incremental = false)
project.build("assembleDebug", options = options) {
assertSuccessful()
}
}
@Test
fun testAndroidKaptChangingDependencies() {
val project = Project("AndroidKaptChangingDependencies", gradleVersion)
project.build("build") {
assertSuccessful()
assertNotContains("Changed dependencies of configuration .+ after it has been included in dependency resolution".toRegex())
}
}
}
@@ -0,0 +1,314 @@
package org.jetbrains.kotlin.gradle
import org.gradle.api.logging.LogLevel
import org.jetbrains.kotlin.com.intellij.openapi.util.io.FileUtil
import org.jetbrains.kotlin.gradle.util.checkBytecodeNotContains
import org.jetbrains.kotlin.gradle.util.createGradleCommand
import org.jetbrains.kotlin.gradle.util.runProcess
import org.junit.After
import org.junit.AfterClass
import org.junit.Assert
import org.junit.Before
import java.io.File
import java.util.regex.Pattern
import kotlin.test.*
private val SYSTEM_LINE_SEPARATOR = System.getProperty("line.separator")
abstract class BaseGradleIT {
protected var workingDir = File(".")
protected open fun defaultBuildOptions(): BuildOptions = BuildOptions(withDaemon = true)
@Before
fun setUp() {
workingDir = FileUtil.createTempDirectory("BaseGradleIT", null)
}
@After
fun tearDown() {
deleteRecursively(workingDir)
}
companion object {
protected val ranDaemonVersions = hashMapOf<String, Int>()
val resourcesRootFile = File("src/test/resources")
val MAX_DAEMON_RUNS = 30
@AfterClass
@JvmStatic
@Synchronized
@Suppress("unused")
fun tearDownAll() {
ranDaemonVersions.keys.forEach { stopDaemon(it) }
ranDaemonVersions.clear()
}
fun stopDaemon(ver: String) {
println("Stopping gradle daemon v$ver")
val wrapperDir = File(resourcesRootFile, "GradleWrapper-$ver")
val cmd = createGradleCommand(arrayListOf("-stop"))
val result = runProcess(cmd, wrapperDir)
assert(result.isSuccessful) { "Could not stop daemon: $result" }
}
@Synchronized
fun prepareDaemon(version: String) {
val useCount = ranDaemonVersions.get(version)
if (useCount == null || useCount > MAX_DAEMON_RUNS) {
stopDaemon(version)
ranDaemonVersions.put(version, 1)
}
else {
ranDaemonVersions.put(version, useCount + 1)
}
}
}
// the second parameter is for using with ToolingAPI, that do not like --daemon/--no-daemon options at all
data class BuildOptions(
val withDaemon: Boolean = false,
val daemonOptionSupported: Boolean = true,
val incremental: Boolean? = null,
val androidHome: File? = null,
val androidGradlePluginVersion: String? = null)
open inner class Project(
val projectName: String,
val wrapperVersion: String,
directoryPrefix: String? = null,
val minLogLevel: LogLevel = LogLevel.DEBUG
) {
val resourceDirName = if (directoryPrefix != null) "$directoryPrefix/$projectName" else projectName
open val resourcesRoot = File(resourcesRootFile, "testProject/$resourceDirName")
val projectDir = File(workingDir.canonicalFile, projectName)
open fun setupWorkingDir() {
copyRecursively(this.resourcesRoot, workingDir)
copyDirRecursively(File(resourcesRootFile, "GradleWrapper-$wrapperVersion"), projectDir)
}
fun relativize(files: Iterable<File>): List<String> =
files.map { it.relativeTo(projectDir).path }
fun relativize(vararg files: File): List<String> =
files.map { it.relativeTo(projectDir).path }
fun performModifications() {
for (file in projectDir.walk()) {
if (!file.isFile) continue
val fileWithoutExt = File(file.parentFile, file.nameWithoutExtension)
when (file.extension) {
"new" -> {
file.copyTo(fileWithoutExt, overwrite = true)
file.delete()
}
"delete" -> {
fileWithoutExt.delete()
file.delete()
}
}
}
}
}
class CompiledProject(val project: Project, val output: String, val resultCode: Int) {
companion object {
val kotlinSourcesListRegex = Regex("\\[KOTLIN\\] compile iteration: ([^\\r\\n]*)")
val javaSourcesListRegex = Regex("\\[DEBUG\\] \\[[^\\]]*JavaCompiler\\] Compiler arguments: ([^\\r\\n]*)")
}
val compiledKotlinSources: Iterable<File> by lazy { kotlinSourcesListRegex.findAll(output).asIterable().flatMap { it.groups[1]!!.value.split(", ").map { File(project.projectDir, it).canonicalFile } } }
val compiledJavaSources: Iterable<File> by lazy { javaSourcesListRegex.findAll(output).asIterable().flatMap { it.groups[1]!!.value.split(" ").filter { it.endsWith(".java", ignoreCase = true) }.map { File(it).canonicalFile } } }
}
fun Project.build(vararg params: String, options: BuildOptions = defaultBuildOptions(), check: CompiledProject.() -> Unit) {
val cmd = createBuildCommand(params, options)
val env = createEnvironmentVariablesMap(options)
if (options.withDaemon) {
prepareDaemon(wrapperVersion)
}
println("<=== Test build: ${this.projectName} $cmd ===>")
val projectDir = File(workingDir, projectName)
if (!projectDir.exists()) {
setupWorkingDir()
}
val result = runProcess(cmd, projectDir, env)
try {
CompiledProject(this, result.output, result.exitCode).check()
}
catch (t: Throwable) {
System.out.println(result.output)
throw t
}
}
fun CompiledProject.assertSuccessful(): CompiledProject {
assertEquals(0, resultCode, "Gradle build failed")
return this
}
fun CompiledProject.assertFailed(): CompiledProject {
assertNotEquals(0, resultCode, "Expected that Gradle build failed")
return this
}
fun CompiledProject.assertContains(vararg expected: String): CompiledProject {
for (str in expected) {
assertTrue(output.contains(str.normalize()), "Output should contain '$str'")
}
return this
}
fun CompiledProject.assertClassFilesNotContain(dir: File, vararg strings: String) {
val classFiles = dir.walk().filter { it.isFile && it.extension.toLowerCase() == "class" }
for (cf in classFiles) {
checkBytecodeNotContains(cf, strings.toList())
}
}
fun CompiledProject.assertSubstringCount(substring: String, expectedCount: Int) {
val actualCount = Pattern.quote(substring).toRegex().findAll(output).count()
assertEquals(expectedCount, actualCount, "Number of occurrences in output for substring '$substring'")
}
fun CompiledProject.checkKotlinGradleBuildServices() {
assertSubstringCount("Initialized KotlinGradleBuildServices", expectedCount = 1)
assertSubstringCount("Disposed KotlinGradleBuildServices", expectedCount = 1)
}
fun CompiledProject.assertNotContains(vararg expected: String): CompiledProject {
for (str in expected) {
assertFalse(output.contains(str.normalize()), "Output should not contain '$str'")
}
return this
}
fun CompiledProject.assertNotContains(regex: Regex) {
assertNull(regex.find(output), "Output should not contain '$regex'")
}
fun CompiledProject.fileInWorkingDir(path: String) = File(File(workingDir, project.projectName), path)
fun CompiledProject.assertReportExists(pathToReport: String = ""): CompiledProject {
assertTrue(fileInWorkingDir(pathToReport).exists(), "The report [$pathToReport] does not exist.")
return this
}
fun CompiledProject.assertFileExists(path: String = ""): CompiledProject {
assertTrue(fileInWorkingDir(path).exists(), "The file [$path] does not exist.")
return this
}
fun CompiledProject.assertNoSuchFile(path: String = ""): CompiledProject {
assertFalse(fileInWorkingDir(path).exists(), "The file [$path] exists.")
return this
}
fun CompiledProject.assertFileContains(path: String, vararg expected: String): CompiledProject {
val text = fileInWorkingDir(path).readText()
expected.forEach {
assertTrue(text.contains(it), "$path should contain '$it', actual file contents:\n$text")
}
return this
}
private fun Iterable<File>.projectRelativePaths(project: Project): Iterable<String> {
// val projectDir = File(workingDir.canonicalFile, project.projectName)
return map { it.canonicalFile.toRelativeString(project.projectDir) }
}
fun CompiledProject.assertSameFiles(expected: Iterable<String>, actual: Iterable<String>, messagePrefix: String): CompiledProject {
val expectedSet = expected.toSortedSet().joinToString("\n")
val actualSet = actual.toSortedSet().joinToString("\n")
Assert.assertEquals(messagePrefix, expectedSet, actualSet)
return this
}
fun CompiledProject.assertContainFiles(expected: Iterable<String>, actual: Iterable<String>, messagePrefix: String = ""): CompiledProject {
val expectedNormalized = expected.map(FileUtil::normalize).toSortedSet()
val actualNormalized = actual.map(FileUtil::normalize).toSortedSet()
assertTrue(actualNormalized.containsAll(expectedNormalized), messagePrefix + "expected files: ${expectedNormalized.joinToString()}\n !in actual files: ${actualNormalized.joinToString()}")
return this
}
fun CompiledProject.assertCompiledKotlinSources(sources: Iterable<String>, weakTesting: Boolean = false): CompiledProject =
if (weakTesting)
assertContainFiles(sources, compiledKotlinSources.projectRelativePaths(this.project), "Compiled Kotlin files differ:\n ")
else
assertSameFiles(sources, compiledKotlinSources.projectRelativePaths(this.project), "Compiled Kotlin files differ:\n ")
fun CompiledProject.assertCompiledJavaSources(sources: Iterable<String>, weakTesting: Boolean = false): CompiledProject =
if (weakTesting)
assertContainFiles(sources, compiledJavaSources.projectRelativePaths(this.project), "Compiled Java files differ:\n ")
else
assertSameFiles(sources, compiledJavaSources.projectRelativePaths(this.project), "Compiled Java files differ:\n ")
private fun Project.createBuildCommand(params: Array<out String>, options: BuildOptions): List<String> =
createGradleCommand(createGradleTailParameters(options, params))
private fun Project.createGradleTailParameters(options: BuildOptions, params: Array<out String> = arrayOf()): List<String> =
params.toMutableList().apply {
add("--stacktrace")
add("--${minLogLevel.name.toLowerCase()}")
if (options.daemonOptionSupported) {
add(if (options.withDaemon) "--daemon" else "--no-daemon")
}
add("-Pkotlin_version=" + KOTLIN_VERSION)
options.incremental?.let { add("-Pkotlin.incremental=$it") }
options.androidGradlePluginVersion?.let { add("-Pandroid_tools_version=$it")}
}
private fun Project.createEnvironmentVariablesMap(options: BuildOptions): Map<String, String> =
hashMapOf<String, String>().apply {
val sdkDir = options.androidHome
if (sdkDir != null) {
sdkDir.parentFile.mkdirs()
put("ANDROID_HOME", sdkDir.canonicalPath)
}
}
private fun String.normalize() = this.lineSequence().joinToString(SYSTEM_LINE_SEPARATOR)
fun copyRecursively(source: File, target: File) {
assertTrue(target.isDirectory)
val targetFile = File(target, source.name)
if (source.isDirectory) {
targetFile.mkdir()
source.listFiles()?.forEach { copyRecursively(it, targetFile) }
} else {
source.copyTo(targetFile)
}
}
fun copyDirRecursively(source: File, target: File) {
assertTrue(source.isDirectory)
assertTrue(target.isDirectory)
source.listFiles()?.forEach { copyRecursively(it, target) }
}
fun deleteRecursively(f: File): Unit {
if (f.isDirectory) {
f.listFiles()?.forEach { deleteRecursively(it) }
val fileList = f.listFiles()
if (fileList != null) {
if (!fileList.isEmpty()) {
fail("Expected $f to be empty but it has files: ${fileList.joinToString { it.name }}")
}
} else {
fail("Error listing directory content")
}
}
f.delete()
}
}
@@ -0,0 +1,109 @@
/*
* 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 org.gradle.api.logging.LogLevel
import org.jetbrains.kotlin.gradle.incremental.BuildStep
import org.jetbrains.kotlin.gradle.incremental.parseTestBuildLog
import org.jetbrains.kotlin.incremental.testingUtils.*
import org.junit.Assume
import java.io.File
import kotlin.test.assertEquals
abstract class BaseIncrementalGradleIT : BaseGradleIT() {
inner class JpsTestProject(val buildLogFinder: BuildLogFinder, val resourcesBase: File, val relPath: String, wrapperVersion: String = "2.10", minLogLevel: LogLevel = LogLevel.DEBUG) : Project(File(relPath).name, wrapperVersion, null, minLogLevel) {
override val resourcesRoot = File(resourcesBase, relPath)
val mapWorkingToOriginalFile = hashMapOf<File, File>()
override fun setupWorkingDir() {
val srcDir = File(projectDir, "src")
srcDir.mkdirs()
val sourceMapping = copyTestSources(resourcesRoot, srcDir, filePrefix = "")
mapWorkingToOriginalFile.putAll(sourceMapping)
copyDirRecursively(File(resourcesRootFile, "GradleWrapper-$wrapperVersion"), projectDir)
copyDirRecursively(File(resourcesRootFile, "incrementalGradleProject"), projectDir)
}
}
fun JpsTestProject.performAndAssertBuildStages(options: BuildOptions = defaultBuildOptions(), weakTesting: Boolean = false) {
// TODO: support multimodule tests
if (resourcesRoot.walk().filter { it.name.equals("dependencies.txt", ignoreCase = true) }.any()) {
Assume.assumeTrue("multimodule tests are not supported yet", false)
}
build("build", options = options) {
assertSuccessful()
assertReportExists()
}
val buildLogFile = buildLogFinder.findBuildLog(resourcesRoot) ?:
throw IllegalStateException("build log file not found in $resourcesRoot")
val buildLogSteps = parseTestBuildLog(buildLogFile)
val modifications = getModificationsToPerform(resourcesRoot,
moduleNames = null,
allowNoFilesWithSuffixInTestData = false,
touchPolicy = TouchPolicy.CHECKSUM)
assert(modifications.size == buildLogSteps.size) {
"Modifications count (${modifications.size}) != expected build log steps count (${buildLogSteps.size})"
}
println("<--- Expected build log size: ${buildLogSteps.size}")
buildLogSteps.forEach {
println("<--- Expected build log stage: ${if (it.compileSucceeded) "succeeded" else "failed"}: kotlin: ${it.compiledKotlinFiles} java: ${it.compiledJavaFiles}")
}
for ((modificationStep, buildLogStep) in modifications.zip(buildLogSteps)) {
modificationStep.forEach { it.perform(projectDir, mapWorkingToOriginalFile) }
buildAndAssertStageResults(buildLogStep, weakTesting = weakTesting)
}
rebuildAndCompareOutput(rebuildSucceedExpected = buildLogSteps.last().compileSucceeded)
}
private fun JpsTestProject.buildAndAssertStageResults(expected: BuildStep, options: BuildOptions = defaultBuildOptions(), weakTesting: Boolean = false) {
build("build", options = options) {
if (expected.compileSucceeded) {
assertSuccessful()
assertCompiledJavaSources(expected.compiledJavaFiles, weakTesting)
assertCompiledKotlinSources(expected.compiledKotlinFiles, weakTesting)
}
else {
assertFailed()
}
}
}
private fun JpsTestProject.rebuildAndCompareOutput(rebuildSucceedExpected: Boolean) {
val outDir = File(File(projectDir, "build"), "classes")
val incrementalOutDir = File(workingDir, "kotlin-classes-incremental")
incrementalOutDir.mkdirs()
copyDirRecursively(outDir, incrementalOutDir)
build("clean", "build") {
val rebuildSucceed = resultCode == 0
assertEquals(rebuildSucceed, rebuildSucceedExpected, "Rebuild exit code differs from incremental exit code")
outDir.mkdirs()
assertEqualDirectories(outDir, incrementalOutDir, forgiveExtraFiles = !rebuildSucceed)
}
}
}
fun isJpsTestProject(projectRoot: File): Boolean = projectRoot.listFiles { f: File -> f.name.endsWith("build.log") }?.any() ?: false
@@ -0,0 +1,102 @@
package org.jetbrains.kotlin.gradle
import org.junit.Test
class SimpleKotlinGradleIT : BaseGradleIT() {
companion object {
private const val GRADLE_VERSION = "2.10"
}
@Test
fun testSimpleCompile() {
val project = Project("simpleProject", GRADLE_VERSION)
project.build("compileDeployKotlin", "build") {
assertSuccessful()
assertReportExists("build/reports/tests/classes/demo.TestSource.html")
assertContains(":compileKotlin", ":compileTestKotlin", ":compileDeployKotlin")
}
project.build("compileDeployKotlin", "build") {
assertSuccessful()
assertContains(":compileKotlin UP-TO-DATE", ":compileTestKotlin UP-TO-DATE", ":compileDeployKotlin UP-TO-DATE", ":compileJava UP-TO-DATE")
}
}
@Test
fun testSuppressWarnings() {
val project = Project("suppressWarnings", GRADLE_VERSION)
project.build("build") {
assertSuccessful()
assertContains(":compileKotlin")
assertNotContains("w:")
}
}
@Test
fun testKotlinCustomDirectory() {
Project("customSrcDir", GRADLE_VERSION).build("build") {
assertSuccessful()
}
}
@Test
fun testKotlinExtraJavaSrc() {
Project("additionalJavaSrc", GRADLE_VERSION).build("build") {
assertSuccessful()
}
}
@Test
fun testLanguageVersion() {
Project("languageVersion", GRADLE_VERSION).build("build") {
assertFailed()
assertContains("This type is sealed")
}
}
@Test
fun testJvmTarget() {
Project("jvmTarget", GRADLE_VERSION).build("build") {
assertFailed()
assertContains("Unknown JVM target version: 1.7")
}
}
@Test
fun testCustomJdk() {
Project("customJdk", GRADLE_VERSION).build("build") {
assertFailed()
assertContains("Unresolved reference: stream")
assertNotContains("AutoCloseable")
}
}
@Test
fun testGradleSubplugin() {
val project = Project("kotlinGradleSubplugin", GRADLE_VERSION)
project.build("compileKotlin", "build") {
assertSuccessful()
assertContains("ExampleSubplugin loaded")
assertContains("Project component registration: exampleValue")
assertContains(":compileKotlin")
}
project.build("compileKotlin", "build") {
assertSuccessful()
assertContains("ExampleSubplugin loaded")
assertNotContains("Project component registration: exampleValue")
assertContains(":compileKotlin UP-TO-DATE")
}
}
@Test
fun testDestinationDirReferencedDuringEvaluation() {
Project("destinationDirReferencedDuringEvaluation", GRADLE_VERSION).build("build") {
assertSuccessful()
assertContains("GreeterTest PASSED")
}
}
}
@@ -0,0 +1,55 @@
package org.jetbrains.kotlin.gradle
import org.jetbrains.kotlin.gradle.incremental.dumpBuildLog
import org.jetbrains.kotlin.gradle.incremental.parseTestBuildLog
import org.junit.Assert
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.Parameterized
import java.io.File
@RunWith(Parameterized::class)
class BuildLogParserParametrizedIT : BaseGradleIT() {
@Parameterized.Parameter
@JvmField
var testDirName: String = ""
@Test
fun testParser() {
val testDir = File(TEST_ROOT, testDirName)
val logFile = File(testDir, LOG_FILE_NAME)
assert(logFile.isFile) { "Log file: $logFile does not exist" }
val actualNormalized = dumpBuildLog(parseTestBuildLog(logFile)).trim()
val expectedFile = File(testDir, EXPECTED_PARSED_LOG_FILE_NAME)
if (!expectedFile.isFile) {
expectedFile.createNewFile()
expectedFile.writeText(actualNormalized)
throw AssertionError("Expected file log did not exist, created: $expectedFile")
}
val expectedNormalized = expectedFile.readText().trim()
Assert.assertEquals("Parsed content was unexpected: ", expectedNormalized, actualNormalized)
// parse expected, dump again and compare (to check that dumped log can be parsed again)
val reparsedActualNormalized = dumpBuildLog(parseTestBuildLog(expectedFile)).trim()
Assert.assertEquals("Reparsed content was unexpected: ", expectedNormalized, reparsedActualNormalized)
}
companion object {
private val TEST_ROOT = File(resourcesRootFile, "buildLogsParserData")
private val LOG_FILE_NAME = "build.log"
private val EXPECTED_PARSED_LOG_FILE_NAME = "expected.txt"
@Suppress("unused")
@Parameterized.Parameters(name = "{index}: {0}")
@JvmStatic
fun data(): List<Array<String>> {
val directories = TEST_ROOT.listFiles().filter { it.isDirectory }
return directories.map { arrayOf(it.name) }.toList()
}
}
}
@@ -0,0 +1,59 @@
package org.jetbrains.kotlin.gradle
import org.junit.Test
import java.io.File
import kotlin.test.assertNotEquals
import kotlin.test.assertTrue
class CacheVersionChangedIT : BaseGradleIT() {
@Test
fun testGradleCacheVersionChanged() {
compileIncrementallyWithChangedVersion("gradle-format-version.txt")
}
@Test
fun testNormalCacheVersionChanged() {
compileIncrementallyWithChangedVersion("format-version.txt")
}
@Test
fun testExperimentalCacheVersionChanged() {
compileIncrementallyWithChangedVersion("experimental-format-version.txt")
}
@Test
fun testDataContainerCacheVersionChanged() {
compileIncrementallyWithChangedVersion("data-container-format-version.txt")
}
private fun compileIncrementallyWithChangedVersion(versionFileName: String) {
val project = Project("kotlinProject", "2.10")
val options = defaultBuildOptions().copy(incremental = true)
fun File.projectPath() = relativeTo(project.projectDir).path
project.build("build", options = options) {
assertSuccessful()
}
val versionFile = File(project.projectDir, "build/kotlin/compileKotlin/$versionFileName")
assertTrue(versionFile.exists(), "${versionFile.projectPath()} does not exist!")
val modifiedVersion = "777"
versionFile.writeText(modifiedVersion)
project.build("build", options = options) {
assertSuccessful()
assertNotEquals(modifiedVersion, versionFile.readText(), "${versionFile.projectPath()} was not rewritten by build")
val mainDir = File(project.projectDir, "src/main")
val mainKotlinFiles = mainDir.walk().filter { it.isFile && it.extension.equals("kt", ignoreCase = true) }
val mainKotlinRelativePaths = mainKotlinFiles.map(File::projectPath).toList()
assertCompiledKotlinSources(mainKotlinRelativePaths)
}
project.build("build", options = options) {
assertSuccessful()
assertCompiledKotlinSources(listOf(), weakTesting = false)
}
}
}
@@ -0,0 +1,65 @@
package org.jetbrains.kotlin.gradle
import org.jetbrains.kotlin.gradle.util.findFileByName
import org.jetbrains.kotlin.gradle.util.getFileByName
import org.jetbrains.kotlin.gradle.util.modify
import org.junit.Test
import java.io.File
import kotlin.test.assertNull
import kotlin.test.assertTrue
class ClassFileIsRemovedIT : BaseGradleIT() {
@Test
fun testClassIsRemovedNonIC() {
doTestClassIsRemoved(defaultBuildOptions())
}
@Test
fun testClassIsRemovedIC() {
doTestClassIsRemoved(defaultBuildOptions().copy(incremental = true))
}
private fun doTestClassIsRemoved(buildOptions: BuildOptions) {
doTest(buildOptions) { dummyFile ->
assertTrue(dummyFile.delete(), "Could not delete $dummyFile")
}
}
@Test
fun testClassIsRenamedNonIC() {
doTestClassIsRenamed(defaultBuildOptions())
}
@Test
fun testClassIsRenamedIC() {
doTestClassIsRenamed(defaultBuildOptions().copy(incremental = true))
}
fun doTestClassIsRenamed(buildOptions: BuildOptions) {
doTest(buildOptions) { dummyFile ->
dummyFile.modify { it.replace("Dummy", "ForDummies") }
}
}
fun doTest(buildOptions: BuildOptions, transformDummy: (File)->Unit) {
val project = Project("kotlinInJavaRoot", "2.10")
project.build("build", options = buildOptions) {
assertSuccessful()
}
val dummyFile = project.projectDir.getFileByName("Dummy.kt")
transformDummy(dummyFile)
project.build("build", options = buildOptions) {
assertSuccessful()
val dummyClassFile = project.projectDir.findFileByName("Dummy.class")
assertNull(dummyClassFile, "$dummyClassFile should not exist!")
}
// check that class removal does not trigger rebuild
project.build("build", options = buildOptions) {
assertSuccessful()
assertContains(":compileKotlin UP-TO-DATE", ":compileJava UP-TO-DATE")
}
}
}
@@ -0,0 +1,214 @@
package org.jetbrains.kotlin.gradle
import org.jetbrains.kotlin.gradle.util.allKotlinFiles
import org.jetbrains.kotlin.gradle.util.getFileByName
import org.jetbrains.kotlin.gradle.util.getFilesByNames
import org.jetbrains.kotlin.gradle.util.modify
import org.junit.Test
import java.io.File
class IncrementalCompilationMultiProjectIT : BaseGradleIT() {
companion object {
private val GRADLE_VERSION = "2.10"
private val ANDROID_GRADLE_PLUGIN_VERSION = "1.5.+"
}
private fun androidBuildOptions() =
BuildOptions(withDaemon = true,
androidHome = File("../../../dependencies/android-sdk-for-tests"),
androidGradlePluginVersion = ANDROID_GRADLE_PLUGIN_VERSION,
incremental = true)
override fun defaultBuildOptions(): BuildOptions =
super.defaultBuildOptions().copy(withDaemon = true, incremental = true)
@Test
fun testMoveFunctionFromLib() {
val project = Project("incrementalMultiproject", GRADLE_VERSION)
project.build("build") {
assertSuccessful()
}
val barUseABKt = project.projectDir.getFileByName("barUseAB.kt")
val barInApp = File(project.projectDir, "app/src/main/java/bar").apply { mkdirs() }
barUseABKt.copyTo(File(barInApp, barUseABKt.name))
barUseABKt.delete()
project.build("build") {
assertSuccessful()
val affectedSources = project.projectDir.getFilesByNames("fooCallUseAB.kt", "barUseAB.kt")
val relativePaths = project.relativize(affectedSources)
assertCompiledKotlinSources(relativePaths, weakTesting = false)
}
}
@Test
fun testAddNewMethodToLib() {
val project = Project("incrementalMultiproject", GRADLE_VERSION)
project.build("build") {
assertSuccessful()
}
val aKt = project.projectDir.getFileByName("A.kt")
aKt.writeText("""
package bar
open class A {
fun a() {}
fun newA() {}
}
""")
project.build("build") {
assertSuccessful()
val affectedSources = project.projectDir.getFilesByNames("A.kt", "B.kt", "AA.kt", "BB.kt")
val relativePaths = project.relativize(affectedSources)
assertCompiledKotlinSources(relativePaths, weakTesting = false)
}
}
@Test
fun testLibClassBecameFinal() {
val project = Project("incrementalMultiproject", GRADLE_VERSION)
project.build("build") {
assertSuccessful()
}
val bKt = project.projectDir.getFileByName("B.kt")
bKt.modify { it.replace("open class", "class") }
project.build("build") {
assertFailed()
val affectedSources = project.projectDir.getFilesByNames(
"B.kt", "barUseAB.kt", "barUseB.kt",
"BB.kt", "fooCallUseAB.kt", "fooUseB.kt")
val relativePaths = project.relativize(affectedSources)
assertCompiledKotlinSources(relativePaths, weakTesting = false)
}
}
@Test
fun testModifyJavaInLib() {
val project = Project("incrementalMultiproject", GRADLE_VERSION)
project.build("build") {
assertSuccessful()
}
val javaClassJava = project.projectDir.getFileByName("JavaClass.java")
javaClassJava.modify { it.replace("String getString", "Object getString") }
project.build("build") {
assertSuccessful()
val affectedSources = project.projectDir.getFilesByNames("JavaClassChild.kt", "useJavaClass.kt")
val relativePaths = project.relativize(affectedSources)
assertCompiledKotlinSources(relativePaths, weakTesting = false)
}
}
@Test
fun testCleanBuildLib() {
val project = Project("incrementalMultiproject", GRADLE_VERSION)
project.build("build") {
assertSuccessful()
}
project.build(":lib:clean", ":lib:build") {
assertSuccessful()
val affectedSources = File(project.projectDir, "lib").allKotlinFiles()
val relativePaths = project.relativize(affectedSources)
assertCompiledKotlinSources(relativePaths, weakTesting = false)
}
project.build("build") {
assertSuccessful()
val affectedSources = File(project.projectDir, "app").allKotlinFiles()
val relativePaths = project.relativize(affectedSources)
assertCompiledKotlinSources(relativePaths, weakTesting = false)
}
}
@Test
fun testCompileErrorInLib() {
val project = Project("incrementalMultiproject", GRADLE_VERSION)
project.build("build") {
assertSuccessful()
}
val bKt = project.projectDir.getFileByName("B.kt")
bKt.delete()
project.build("build") {
assertFailed()
}
project.projectDir.getFileByName("barUseB.kt").delete()
project.projectDir.getFileByName("barUseAB.kt").delete()
project.build("build") {
assertFailed()
val affectedSources = project.projectDir.allKotlinFiles()
val relativePaths = project.relativize(affectedSources)
assertCompiledKotlinSources(relativePaths, weakTesting = false)
}
}
// checks that multi-project ic is disabled when there is a task that outputs to javaDestination dir
// that is not JavaCompile or KotlinCompile
@Test
fun testCompileLibWithGroovy() {
val project = Project("incrementalMultiproject", GRADLE_VERSION)
project.setupWorkingDir()
val lib = File(project.projectDir, "lib")
val libBuildGradle = File(lib, "build.gradle")
libBuildGradle.modify {
"""
apply plugin: 'groovy'
apply plugin: 'kotlin'
dependencies {
compile 'org.codehaus.groovy:groovy-all:2.4.7'
}
""".trimIndent()
}
val libGroovySrcBar = File(lib, "src/main/groovy/bar").apply { mkdirs() }
val groovyClass = File(libGroovySrcBar, "GroovyClass.groovy")
groovyClass.writeText("""
package bar
class GroovyClass {}
""")
project.build("build") {
assertSuccessful()
}
project.projectDir.getFileByName("barUseB.kt").delete()
project.build("build") {
assertSuccessful()
val affectedSources = File(project.projectDir, "app").allKotlinFiles()
val relativePaths = project.relativize(affectedSources)
assertCompiledKotlinSources(relativePaths, weakTesting = false)
}
}
@Test
fun testAndroid() {
val project = Project("AndroidProject", GRADLE_VERSION)
val options = androidBuildOptions()
project.build("assembleDebug", options = options) {
assertSuccessful()
}
val libUtilKt = project.projectDir.getFileByName("libUtil.kt")
libUtilKt.modify { it.replace("fun libUtil(): String", "fun libUtil(): Any") }
project.build("assembleDebug", options = options) {
assertSuccessful()
val affectedSources = project.projectDir.getFilesByNames("libUtil.kt", "MainActivity2.kt")
assertCompiledKotlinSources(project.relativize(affectedSources), weakTesting = false)
}
}
}
@@ -0,0 +1,5 @@
package org.jetbrains.kotlin.gradle
// constant is held in separate file intentionally for better discoverability
// and to prevent vcs conflicts (its value is 1.1-* in master branch, 0.1-* in 1.0.x branches)
const val KOTLIN_VERSION = "1.1-SNAPSHOT"
@@ -0,0 +1,245 @@
/*
* 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 org.jetbrains.kotlin.gradle.util.*
import org.junit.Test
import java.io.File
class Kapt2IT: BaseGradleIT() {
companion object {
private const val GRADLE_VERSION = "2.10"
private const val GRADLE_2_14_VERSION = "2.14.1"
private const val ANDROID_GRADLE_PLUGIN_VERSION = "1.5.+"
}
private fun androidBuildOptions() =
BuildOptions(withDaemon = true,
androidHome = File("../../../dependencies/android-sdk-for-tests"),
androidGradlePluginVersion = ANDROID_GRADLE_PLUGIN_VERSION)
override fun defaultBuildOptions(): BuildOptions =
super.defaultBuildOptions().copy(withDaemon = true)
private fun CompiledProject.assertKaptSuccessful() {
assertContains("Kapt: Annotation processing complete, 0 errors, 0 warnings")
}
@Test
fun testSimple() {
val project = Project("simple", GRADLE_VERSION, directoryPrefix = "kapt2")
project.build("build") {
assertSuccessful()
assertKaptSuccessful()
assertContains(":compileKotlin")
assertContains(":compileJava")
assertFileExists("build/generated/source/kapt2/main/example/TestClassGenerated.java")
assertFileExists("build/classes/main/example/TestClass.class")
assertFileExists("build/classes/main/example/TestClassGenerated.class")
assertFileExists("build/classes/main/example/SourceAnnotatedTestClassGenerated.class")
assertFileExists("build/classes/main/example/BinaryAnnotatedTestClassGenerated.class")
assertFileExists("build/classes/main/example/RuntimeAnnotatedTestClassGenerated.class")
assertContains("example.JavaTest PASSED")
assertClassFilesNotContain(File(project.projectDir, "build/classes"), "ExampleSourceAnnotation")
}
project.build("build") {
assertSuccessful()
assertContains(":compileKotlin UP-TO-DATE")
assertContains(":compileJava UP-TO-DATE")
}
}
@Test
fun testSimpleWithIC() {
val options = defaultBuildOptions().copy(incremental = true)
val project = Project("simple", GRADLE_VERSION, directoryPrefix = "kapt2")
val classesDir = File(project.projectDir, "build/classes")
project.build("build", options = options) {
assertSuccessful()
assertKaptSuccessful()
assertContains(":compileKotlin")
assertContains(":compileJava")
assertClassFilesNotContain(classesDir, "ExampleSourceAnnotation")
}
project.projectDir.getFilesByNames("InternalDummy.kt", "test.kt").forEach { it.appendText(" ") }
project.build("build", options = options) {
assertSuccessful()
assertKaptSuccessful()
assertContains(":compileKotlin")
assertContains(":compileJava")
assertClassFilesNotContain(classesDir, "ExampleSourceAnnotation")
}
// emulating wipe by android plugin's IncrementalSafeguardTask
classesDir.deleteRecursively()
project.build("build", options = options) {
assertSuccessful()
assertContains(":compileKotlin UP-TO-DATE")
assertFileExists("build/classes/main/example/TestClass.class")
assertClassFilesNotContain(classesDir, "ExampleSourceAnnotation")
}
}
@Test
fun testInheritedAnnotations() {
Project("inheritedAnnotations", GRADLE_VERSION, directoryPrefix = "kapt2").build("build") {
assertSuccessful()
assertKaptSuccessful()
assertFileExists("build/generated/source/kapt2/main/example/TestClassGenerated.java")
assertFileExists("build/generated/source/kapt2/main/example/AncestorClassGenerated.java")
assertFileExists("build/classes/main/example/TestClassGenerated.class")
assertFileExists("build/classes/main/example/AncestorClassGenerated.class")
}
}
@Test
fun testButterKnife() {
val project = Project("android-butterknife", GRADLE_VERSION, directoryPrefix = "kapt2")
val options = androidBuildOptions()
project.build("compileReleaseSources", options = options) {
assertSuccessful()
assertKaptSuccessful()
assertFileExists("app/build/generated/source/kapt2/release/org/example/kotlin/butterknife/SimpleActivity\$\$ViewBinder.java")
assertFileExists("app/build/intermediates/classes/release/org/example/kotlin/butterknife/SimpleActivity\$\$ViewBinder.class")
assertFileExists("app/build/intermediates/classes/release/org/example/kotlin/butterknife/SimpleAdapter\$ViewHolder.class")
}
project.build("compileReleaseSources", options = options) {
assertSuccessful()
assertContains(":compileReleaseKotlin UP-TO-DATE")
assertContains(":compileReleaseJavaWithJavac UP-TO-DATE")
}
}
@Test
fun testDagger() {
val project = Project("android-dagger", GRADLE_VERSION, directoryPrefix = "kapt2")
val options = androidBuildOptions()
project.build("compileReleaseSources", options = options) {
assertSuccessful()
assertKaptSuccessful()
assertFileExists("app/build/generated/source/kapt2/release/com/example/dagger/kotlin/DaggerApplicationComponent.java")
assertFileExists("app/build/generated/source/kapt2/release/com/example/dagger/kotlin/ui/HomeActivity_MembersInjector.java")
assertFileExists("app/build/intermediates/classes/release/com/example/dagger/kotlin/DaggerApplicationComponent.class")
assertFileExists("app/build/intermediates/classes/release/com/example/dagger/kotlin/AndroidModule.class")
}
}
@Test
fun testDbFlow() {
val project = Project("android-dbflow", GRADLE_VERSION, directoryPrefix = "kapt2")
val options = androidBuildOptions()
project.build("compileReleaseSources", options = options) {
assertSuccessful()
assertKaptSuccessful()
assertFileExists("app/build/generated/source/kapt2/release/com/raizlabs/android/dbflow/config/GeneratedDatabaseHolder.java")
assertFileExists("app/build/generated/source/kapt2/release/com/raizlabs/android/dbflow/config/AppDatabaseapp_Database.java")
assertFileExists("app/build/generated/source/kapt2/release/mobi/porquenao/poc/kotlin/core/Item_Table.java")
assertFileExists("app/build/generated/source/kapt2/release/mobi/porquenao/poc/kotlin/core/Item_Adapter.java")
}
}
@Test
fun testRealm() {
val project = Project("android-realm", GRADLE_VERSION, directoryPrefix = "kapt2")
val options = androidBuildOptions()
project.build("compileReleaseSources", options = options) {
assertSuccessful()
assertKaptSuccessful()
assertFileExists("build/generated/source/kapt2/release/io/realm/CatRealmProxy.java")
assertFileExists("build/generated/source/kapt2/release/io/realm/CatRealmProxyInterface.java")
assertFileExists("build/generated/source/kapt2/release/io/realm/DefaultRealmModule.java")
assertFileExists("build/generated/source/kapt2/release/io/realm/DefaultRealmModuleMediator.java")
}
}
@Test
fun testGeneratedDirectoryIsUpToDate() {
val project = Project("generatedDirUpToDate", GRADLE_2_14_VERSION, directoryPrefix = "kapt2")
project.build("build") {
assertSuccessful()
assertKaptSuccessful()
assertContains(":compileKotlin")
assertContains(":compileJava")
assertFileExists("build/classes/main/example/TestClass.class")
assertFileExists("build/generated/source/kapt2/main/example/TestClassGenerated.java")
assertFileExists("build/generated/source/kapt2/main/example/SourceAnnotatedTestClassGenerated.java")
assertFileExists("build/generated/source/kapt2/main/example/BinaryAnnotatedTestClassGenerated.java")
assertFileExists("build/generated/source/kapt2/main/example/RuntimeAnnotatedTestClassGenerated.java")
assertFileExists("build/classes/main/example/TestClassGenerated.class")
assertFileExists("build/classes/main/example/SourceAnnotatedTestClassGenerated.class")
assertFileExists("build/classes/main/example/BinaryAnnotatedTestClassGenerated.class")
assertFileExists("build/classes/main/example/RuntimeAnnotatedTestClassGenerated.class")
}
val testKt = project.projectDir.getFileByName("test.kt")
testKt.writeText(testKt.readText().replace("@ExampleBinaryAnnotation", ""))
project.build("build") {
assertSuccessful()
assertContains(":compileKotlin")
assertContains(":compileJava")
assertFileExists("build/classes/main/example/TestClass.class")
assertFileExists("build/generated/source/kapt2/main/example/TestClassGenerated.java")
assertFileExists("build/generated/source/kapt2/main/example/SourceAnnotatedTestClassGenerated.java")
/*!*/ assertNoSuchFile("build/generated/source/kapt2/main/example/BinaryAnnotatedTestClassGenerated.java")
assertFileExists("build/generated/source/kapt2/main/example/RuntimeAnnotatedTestClassGenerated.java")
assertFileExists("build/classes/main/example/TestClassGenerated.class")
assertFileExists("build/classes/main/example/SourceAnnotatedTestClassGenerated.class")
/*!*/ assertNoSuchFile("build/classes/main/example/BinaryAnnotatedTestClassGenerated.class")
assertFileExists("build/classes/main/example/RuntimeAnnotatedTestClassGenerated.class")
}
}
@Test
fun testRemoveAnnotationIC() {
val project = Project("simple", GRADLE_2_14_VERSION, directoryPrefix = "kapt2")
val options = defaultBuildOptions().copy(incremental = true)
project.setupWorkingDir()
val internalDummyKt = project.projectDir.getFileByName("InternalDummy.kt")
// add annotation
val exampleAnn = "@example.ExampleAnnotation "
internalDummyKt.modify { it.addBeforeSubstring(exampleAnn, "internal class InternalDummy")}
project.build("classes", options = options) {
assertSuccessful()
}
// remove annotation
internalDummyKt.modify { it.replace(exampleAnn, "")}
project.build("classes", options = options) {
assertSuccessful()
val allMainKotlinSrc = File(project.projectDir, "src/main").allKotlinFiles()
assertCompiledKotlinSources(project.relativize(allMainKotlinSrc))
}
}
}
@@ -0,0 +1,205 @@
package org.jetbrains.kotlin.gradle
import org.jetbrains.kotlin.gradle.util.allJavaFiles
import org.jetbrains.kotlin.gradle.util.getFileByName
import org.jetbrains.kotlin.gradle.util.modify
import org.junit.Test
import java.io.File
class KaptIT: BaseGradleIT() {
companion object {
private const val GRADLE_VERSION = "2.14.1"
}
@Test
fun testSimple() {
val project = Project("kaptSimple", GRADLE_VERSION)
project.build("build") {
assertSuccessful()
assertContains("kapt: Class file stubs are not used")
assertContains(":compileKotlin")
assertContains(":compileJava")
assertFileExists("build/tmp/kapt/main/wrappers/annotations.main.txt")
assertFileExists("build/generated/source/kapt/main/example/TestClassGenerated.java")
assertFileExists("build/classes/main/example/TestClass.class")
assertFileExists("build/classes/main/example/TestClassGenerated.class")
assertNoSuchFile("build/classes/main/example/SourceAnnotatedTestClassGenerated.class")
assertFileExists("build/classes/main/example/BinaryAnnotatedTestClassGenerated.class")
assertFileExists("build/classes/main/example/RuntimeAnnotatedTestClassGenerated.class")
assertContains("example.JavaTest PASSED")
assertContains("example.KotlinTest PASSED")
assertClassFilesNotContain(File(project.projectDir, "build/classes"), "ExampleSourceAnnotation")
}
// clean build is important
// because clean can delete hack annotation file before build
project.build("clean", "build") {
assertSuccessful()
}
}
@Test
fun testEnumConstructor() {
val project = Project("kaptEnumConstructor", GRADLE_VERSION)
project.build("build") {
assertSuccessful()
assertContains(":compileKotlin")
assertContains(":compileJava")
assertFileExists("build/tmp/kapt/main/wrappers/annotations.main.txt")
}
project.build("build") {
assertSuccessful()
}
}
@Test
fun testStubs() {
val project = Project("kaptStubs", GRADLE_VERSION)
project.build("build") {
assertSuccessful()
assertContains("kapt: Using class file stubs")
assertContains(":compileKotlin")
assertContains(":compileJava")
assertFileExists("build/tmp/kapt/main/wrappers/annotations.main.txt")
assertFileExists("build/generated/source/kapt/main/example/TestClassGenerated.java")
assertFileExists("build/classes/main/example/TestClass.class")
assertFileExists("build/classes/main/example/TestClassGenerated.class")
assertFileExists("build/classes/main/example/SourceAnnotatedTestClassGenerated.class")
assertFileExists("build/classes/main/example/BinaryAnnotatedTestClassGenerated.class")
assertFileExists("build/classes/main/example/RuntimeAnnotatedTestClassGenerated.class")
assertNotContains("w: Classpath entry points to a non-existent location")
assertContains("example.JavaTest PASSED")
}
project.build("build") {
assertSuccessful()
}
}
@Test
fun testStubsWithoutJava() {
val project = Project("kaptStubs", GRADLE_VERSION)
project.setupWorkingDir()
project.projectDir.allJavaFiles().forEach { it.delete() }
project.build("build") {
assertSuccessful()
assertContains("kapt: Using class file stubs")
assertContains(":compileKotlin")
assertContains(":compileJava")
assertFileExists("build/classes/main/example/TestClass.class")
assertFileExists("build/classes/main/example/TestClassGenerated.class")
}
}
@Test
fun testSimpleIncrementalBuild() {
doTestIncrementalBuild("kaptSimple", arrayOf(":compileKotlin", ":compileJava"))
}
@Test
fun testStubsIncrementalBuild() {
doTestIncrementalBuild("kaptStubs", arrayOf(":compileKotlin", ":compileJava", ":compileKotlinAfterJava"))
}
private fun doTestIncrementalBuild(projectName: String, compileTasks: Array<String>) {
val compileTasksUpToDate = compileTasks.map { it + " UP-TO-DATE" }.toTypedArray()
val project = Project(projectName, GRADLE_VERSION)
project.build("build") {
assertSuccessful()
}
project.projectDir.getFileByName("test.kt").appendText(" ")
project.build("build") {
assertSuccessful()
assertContains(*compileTasks)
assertNotContains(*compileTasksUpToDate)
}
repeat(2) {
project.build("build") {
assertSuccessful()
assertContains(*compileTasksUpToDate)
}
}
project.build("clean", "build") {
assertSuccessful()
assertContains(*compileTasks)
assertNotContains(*compileTasksUpToDate)
}
repeat(2) {
project.build("build") {
assertSuccessful()
assertContains(*compileTasksUpToDate)
}
}
}
@Test
fun testArguments() {
Project("kaptArguments", GRADLE_VERSION).build("build") {
assertSuccessful()
assertContains("kapt: Using class file stubs")
assertContains(":compileKotlin")
assertContains(":compileJava")
assertFileExists("build/tmp/kapt/main/wrappers/annotations.main.txt")
assertFileExists("build/generated/source/kapt/main/example/TestClassCustomized.java")
assertFileExists("build/classes/main/example/TestClass.class")
assertFileExists("build/classes/main/example/TestClassCustomized.class")
}
}
@Test
fun testInheritedAnnotations() {
Project("kaptInheritedAnnotations", GRADLE_VERSION).build("build") {
assertSuccessful()
assertFileExists("build/generated/source/kapt/main/example/TestClassGenerated.java")
assertFileExists("build/generated/source/kapt/main/example/AncestorClassGenerated.java")
assertFileExists("build/classes/main/example/TestClassGenerated.class")
assertFileExists("build/classes/main/example/AncestorClassGenerated.class")
}
}
@Test
fun testOutputKotlinCode() {
Project("kaptOutputKotlinCode", GRADLE_VERSION).build("build") {
assertSuccessful()
assertContains("kapt: Using class file stubs")
assertContains(":compileKotlin")
assertContains(":compileJava")
assertFileExists("build/tmp/kapt/main/wrappers/annotations.main.txt")
assertFileExists("build/generated/source/kapt/main/example/TestClassCustomized.java")
assertFileExists("build/tmp/kapt/main/kotlinGenerated/TestClass.kt")
assertFileExists("build/classes/main/example/TestClass.class")
assertFileExists("build/classes/main/example/TestClassCustomized.class")
}
}
@Test
fun testInternalUserIsModifiedStubsIC() {
val options = defaultBuildOptions().copy(incremental = true)
val project = Project("kaptStubs", GRADLE_VERSION)
project.build("build", options = options) {
assertSuccessful()
}
val internalDummyUserKt = project.projectDir.getFileByName("InternalDummyUser.kt")
internalDummyUserKt.modify { it + " " }
val internalDummyTestKt = project.projectDir.getFileByName("InternalDummyTest.kt")
internalDummyTestKt.modify { it + " " }
project.build("build", options = options) {
assertSuccessful()
assertCompiledKotlinSources(project.relativize(internalDummyUserKt, internalDummyTestKt))
}
}
}
@@ -0,0 +1,196 @@
package org.jetbrains.kotlin.gradle
import org.jetbrains.kotlin.gradle.util.allKotlinFiles
import org.jetbrains.kotlin.gradle.util.findFileByName
import org.jetbrains.kotlin.gradle.util.getFileByName
import org.jetbrains.kotlin.gradle.util.modify
import org.junit.Test
class KaptIncrementalNoStubsIT : KaptIncrementalBaseIT(shouldUseStubs = false)
class KaptIncrementalWithStubsIT : KaptIncrementalBaseIT(shouldUseStubs = true)
abstract class KaptIncrementalBaseIT(val shouldUseStubs: Boolean): BaseGradleIT() {
companion object {
private const val GRADLE_VERSION = "2.10"
private val EXAMPLE_ANNOTATION_REGEX = "@(field:)?example.ExampleAnnotation".toRegex()
private const val GENERATE_STUBS_PLACEHOLDER = "GENERATE_STUBS_PLACEHOLDER"
}
private fun getProject() =
Project("kaptIncrementalCompilationProject", GRADLE_VERSION).apply {
setupWorkingDir()
val buildGradle = projectDir.parentFile.getFileByName("build.gradle")
buildGradle.modify { it.replace(GENERATE_STUBS_PLACEHOLDER, shouldUseStubs.toString()) }
}
private val annotatedElements =
arrayOf("A", "funA", "valA", "funUtil", "valUtil", "B", "funB", "valB", "useB")
override fun defaultBuildOptions(): BuildOptions =
super.defaultBuildOptions().copy(incremental = true)
@Test
fun testBasic() {
val project = getProject()
project.build("build") {
assertSuccessful()
checkStubUsage()
checkGenerated(*annotatedElements)
checkNotGenerated("notAnnotatedFun")
assertContains("foo.ATest PASSED")
}
project.build("build") {
assertSuccessful()
assertContains(":compileKotlin UP-TO-DATE",
":compileJava UP-TO-DATE")
if (shouldUseStubs) {
assertContains(":compileKotlinAfterJava UP-TO-DATE")
}
}
}
@Test
fun testAddAnnotatedElement() {
val project = getProject()
project.build("build") {
assertSuccessful()
}
val utilKt = project.projectDir.getFileByName("util.kt")
utilKt.modify { oldContent ->
"""$oldContent
@example.ExampleAnnotation
fun newUtilFun() {}"""
}
project.build("build") {
assertSuccessful()
// todo: for kapt with stubs check compileKotlin and compileKotlinAfterJava separately
assertCompiledKotlinSources(project.relativize(utilKt))
checkGenerated(*(annotatedElements + arrayOf("newUtilFun")))
}
}
@Test
fun testAddAnnotation() {
val project = getProject()
project.build("build") {
assertSuccessful()
}
val utilKt = project.projectDir.getFileByName("util.kt")
utilKt.modify { it.replace("fun notAnnotatedFun", "@example.ExampleAnnotation fun notAnnotatedFun") }
project.build("build") {
assertSuccessful()
assertCompiledKotlinSources(project.relativize(utilKt))
checkGenerated(*(annotatedElements + arrayOf("notAnnotatedFun")))
}
}
@Test
fun testRemoveSourceFile() {
val project = getProject()
project.build("build") {
assertSuccessful()
}
with (project.projectDir) {
getFileByName("B.kt").delete()
getFileByName("useB.kt").delete()
}
project.build("build") {
assertFailed()
}
project.projectDir.getFileByName("JavaClass.java").delete()
project.build("build") {
assertSuccessful()
assertCompiledKotlinSources(project.relativize(project.projectDir.allKotlinFiles()))
val affectedElements = arrayOf("B", "funB", "valB", "useB")
checkGenerated(*(annotatedElements.toSet() - affectedElements).toTypedArray())
checkNotGenerated(*affectedElements)
}
}
@Test
fun testRemoveAnnotations() {
val project = getProject()
project.build("build") {
assertSuccessful()
}
val bKt = project.projectDir.getFileByName("B.kt")
bKt.modify { it.replace(EXAMPLE_ANNOTATION_REGEX, "") }
val affectedElements = arrayOf("B", "funB", "valB")
project.build("build") {
assertSuccessful()
if (shouldUseStubs) {
// java removal is detected
assertCompiledKotlinSources(project.relativize(project.projectDir.allKotlinFiles()))
}
else {
val useBKt = project.projectDir.getFileByName("useB.kt")
assertCompiledKotlinSources(project.relativize(bKt, useBKt))
}
checkGenerated(*(annotatedElements.toSet() - affectedElements).toTypedArray())
checkNotGenerated(*affectedElements)
}
}
@Test
fun testChangeAnnotatedPropertyType() {
val project = getProject()
project.build("build") {
assertSuccessful()
}
val bKt = project.projectDir.getFileByName("B.kt")
val useBKt = project.projectDir.getFileByName("useB.kt")
bKt.modify { it.replace("val valB = \"text\"", "val valB = 4") }
project.build("build") {
assertSuccessful()
assertCompiledKotlinSources(project.relativize(bKt, useBKt))
checkGenerated(*annotatedElements)
}
}
private fun CompiledProject.checkGenerated(vararg annotatedElementNames: String) {
getGeneratedFileNames(*annotatedElementNames).forEach {
val file = project.projectDir.getFileByName(it)
assert(file.isFile) { "$file must exist" }
}
}
private fun CompiledProject.checkNotGenerated(vararg annotatedElementNames: String) {
getGeneratedFileNames(*annotatedElementNames).forEach {
val file = project.projectDir.findFileByName(it)
assert(file == null) { "$file must not exist" }
}
}
private fun getGeneratedFileNames(vararg annotatedElementNames: String): Iterable<String> {
val names = annotatedElementNames.map { it.capitalize() + "Generated" }
return names.map { it + ".java" }
}
private fun CompiledProject.checkStubUsage() {
val usingStubs = "kapt: Using class file stubs"
if (shouldUseStubs) {
assertContains(usingStubs)
}
else {
assertNotContains(usingStubs)
}
}
}
@@ -0,0 +1,83 @@
package org.jetbrains.kotlin.gradle
import org.junit.Test
class Kotlin2JsGradlePluginIT : BaseGradleIT() {
@Test
fun testBuildAndClean() {
val project = Project("kotlin2JsProject", "2.10")
project.build("build") {
assertSuccessful()
assertReportExists()
assertContains(
":libraryProject:jarSources\n",
":mainProject:compileKotlin2Js\n",
":libraryProject:compileKotlin2Js\n"
)
listOf("mainProject/web/js/app.js",
"mainProject/web/js/lib/kotlin.js",
"libraryProject/build/kotlin2js/main/test-library.js",
"mainProject/web/js/app.js.map"
).forEach { assertFileExists(it) }
// TODO Should be updated to `new _.example.library.Counter` once namespaced imports from libraryFiles are implemented
// TODO It would be better to test these by behavior instead of implementation, for example by loading the files
// into Rhino and running assertions on that. See https://github.com/abesto/kotlin/commit/120ec1bda3d95630189d4d33d0b2afb4253b5186
// for the (original) discussion on this.
assertFileContains("libraryProject/build/kotlin2js/main/test-library.js", "Counter: Kotlin.createClass")
assertFileContains("mainProject/web/js/app.js", "var counter = new \$module\$test_library.example.library.Counter(counterText);")
}
project.build("build") {
assertSuccessful()
assertContains(
":mainProject:compileKotlin2Js UP-TO-DATE",
":libraryProject:compileTestKotlin2Js UP-TO-DATE"
)
}
project.build("clean") {
assertSuccessful()
assertReportExists()
assertContains(":mainProject:cleanCompileKotlin2Js\n")
assertNoSuchFile("mainProject/web/js/app.js")
// Test that we don't accidentally remove the containing directory
// This would fail if we used the default clean task of the copy task
assertFileExists("mainProject/web/js/lib")
assertNoSuchFile("main/project/web/js/app.js.map")
assertNoSuchFile("main/project/web/js/example/main.kt")
}
project.build("clean") {
assertSuccessful()
assertReportExists()
assertContains(":mainProject:cleanCompileKotlin2Js UP-TO-DATE")
}
}
@Test
fun testModuleKind() {
val project = Project("kotlin2JsModuleKind", "2.10")
project.build("runRhino") {
assertSuccessful()
}
}
@Test
fun testNoOutputFileFails() {
val project = Project("kotlin2JsNoOutputFileProject", "2.10")
project.build("build") {
assertFailed()
assertReportExists()
assertContains("compileKotlin2Js.kotlinOptions.outputFile should be specified.")
}
}
}
@@ -0,0 +1,285 @@
package org.jetbrains.kotlin.gradle
import org.gradle.api.logging.LogLevel
import org.jetbrains.kotlin.gradle.tasks.USING_EXPERIMENTAL_INCREMENTAL_MESSAGE
import org.jetbrains.kotlin.gradle.util.getFileByName
import org.jetbrains.kotlin.gradle.util.modify
import org.junit.Test
import java.io.File
import kotlin.test.assertNotEquals
import kotlin.test.assertTrue
class KotlinGradleIT: BaseGradleIT() {
companion object {
private const val GRADLE_VERSION = "2.10"
}
@Test
fun testCrossCompile() {
val project = Project("kotlinJavaProject", GRADLE_VERSION)
project.build("compileDeployKotlin", "build") {
assertSuccessful()
assertReportExists()
assertContains(":compileKotlin", ":compileTestKotlin", ":compileDeployKotlin")
}
project.build("compileDeployKotlin", "build") {
assertSuccessful()
assertContains(":compileKotlin UP-TO-DATE", ":compileTestKotlin UP-TO-DATE", ":compileDeployKotlin UP-TO-DATE", ":compileJava UP-TO-DATE")
}
}
@Test
fun testKotlinOnlyCompile() {
val project = Project("kotlinProject", GRADLE_VERSION)
project.build("build") {
assertSuccessful()
assertReportExists()
assertContains(":compileKotlin", ":compileTestKotlin")
}
project.build("build") {
assertSuccessful()
assertContains(":compileKotlin UP-TO-DATE", ":compileTestKotlin UP-TO-DATE")
}
}
// For corresponding documentation, see https://docs.gradle.org/current/userguide/gradle_daemon.html
// Setting user.variant to different value implies a new daemon process will be created.
// In order to stop daemon process, special exit task is used ( System.exit(0) ).
@Test
fun testKotlinOnlyDaemonMemory() {
val project = Project("kotlinProject", GRADLE_VERSION)
val VARIANT_CONSTANT = "ForTest"
val userVariantArg = "-Duser.variant=$VARIANT_CONSTANT"
val MEMORY_MAX_GROWTH_LIMIT_KB = 500
val BUILD_COUNT = 15
fun exitTestDaemon() {
project.build(userVariantArg, "exit", options = BaseGradleIT.BuildOptions(withDaemon = true)) {
assertFailed()
assertContains("The daemon has exited normally or was terminated in response to a user interrupt.")
}
}
fun buildAndGetMemoryAfterBuild(): Int {
var reportedMemory: Int? = null
project.build(userVariantArg, "clean", "build", options = BaseGradleIT.BuildOptions(withDaemon = true)) {
assertSuccessful()
val matches = "\\[PERF\\] Used memory after build: (\\d+) kb \\(difference since build start: ([+-]?\\d+) kb\\)".toRegex().find(output)
assert(matches != null && matches.groups.size == 3) { "Used memory after build is not reported by plugin" }
reportedMemory = matches!!.groupValues[1].toInt()
}
return reportedMemory!!
}
exitTestDaemon()
try {
val usedMemory = (1..BUILD_COUNT).map { buildAndGetMemoryAfterBuild() }
// ensure that the maximum of the used memory established after several first builds doesn't raise significantly in the subsequent builds
val establishedMaximum = usedMemory.take(5).max()!!
val totalMaximum = usedMemory.max()!!
val maxGrowth = totalMaximum - establishedMaximum
assertTrue(maxGrowth <= MEMORY_MAX_GROWTH_LIMIT_KB,
"Maximum used memory over series of builds growth $maxGrowth (from $establishedMaximum to $totalMaximum) kb > $MEMORY_MAX_GROWTH_LIMIT_KB kb")
// testing that nothing remains locked by daemon, see KT-9440
project.build(userVariantArg, "clean", options = BaseGradleIT.BuildOptions(withDaemon = true)) {
assertSuccessful()
}
}
finally {
exitTestDaemon()
}
}
@Test
fun testLogLevelForceGC() {
val debugProject = Project("simpleProject", GRADLE_VERSION, minLogLevel = LogLevel.DEBUG)
debugProject.build("build") {
assertContains("Forcing System.gc()")
}
val infoProject = Project("simpleProject", GRADLE_VERSION, minLogLevel = LogLevel.INFO)
infoProject.build("clean", "build") {
assertNotContains("Forcing System.gc()")
}
}
@Test
fun testKotlinClasspath() {
Project("classpathTest", GRADLE_VERSION).build("build") {
assertSuccessful()
assertReportExists()
assertContains(":compileKotlin", ":compileTestKotlin")
}
}
@Test
fun testInternalTest() {
Project("internalTest", GRADLE_VERSION).build("build") {
assertSuccessful()
assertReportExists()
assertContains(":compileKotlin", ":compileTestKotlin")
}
}
@Test
fun testMultiprojectPluginClasspath() {
Project("multiprojectClassPathTest", GRADLE_VERSION).build("build") {
assertSuccessful()
assertReportExists("subproject")
assertContains(":subproject:compileKotlin", ":subproject:compileTestKotlin")
checkKotlinGradleBuildServices()
}
}
@Test
fun testSimpleMultiprojectIncremental() {
fun Project.modify(body: Project.() -> Unit): Project {
this.body()
return this
}
val incremental = defaultBuildOptions().copy(incremental = true)
Project("multiprojectWithDependency", GRADLE_VERSION).build("assemble", options = incremental) {
assertSuccessful()
assertReportExists("projA")
assertContains(":projA:compileKotlin")
assertNotContains("projA:compileKotlin UP-TO-DATE")
assertReportExists("projB")
assertContains(":projB:compileKotlin")
assertNotContains("projB:compileKotlin UP-TO-DATE")
}
Project("multiprojectWithDependency", GRADLE_VERSION).modify {
val oldSrc = File(this.projectDir, "projA/src/main/kotlin/a.kt")
val newSrc = File(this.projectDir, "projA/src/main/kotlin/a.kt.new")
assertTrue { oldSrc.exists() }
assertTrue { newSrc.exists() }
newSrc.copyTo(oldSrc, overwrite = true)
}.build("assemble", options = incremental) {
assertSuccessful()
assertReportExists("projA")
assertContains(":projA:compileKotlin")
assertContains("[KOTLIN] is incremental == true")
assertNotContains("projA:compileKotlin UP-TO-DATE")
assertReportExists("projB")
assertContains(":projB:compileKotlin")
assertNotContains("projB:compileKotlin UP-TO-DATE")
}
}
@Test
fun testKotlinInJavaRoot() {
Project("kotlinInJavaRoot", GRADLE_VERSION).build("build") {
assertSuccessful()
assertReportExists()
assertContains(":compileKotlin", ":compileTestKotlin")
}
}
@Test
fun testIncrementalPropertyFromLocalPropertiesFile() {
val project = Project("kotlinProject", GRADLE_VERSION)
project.setupWorkingDir()
val localPropertyFile = File(project.projectDir, "local.properties")
localPropertyFile.writeText("kotlin.incremental=true")
project.build("build") {
assertContains(USING_EXPERIMENTAL_INCREMENTAL_MESSAGE)
}
}
@Test
fun testConvertJavaToKotlin() {
val project = Project("convertBetweenJavaAndKotlin", GRADLE_VERSION)
project.setupWorkingDir()
val barKt = project.projectDir.getFileByName("Bar.kt")
val barKtContent = barKt.readText()
barKt.delete()
project.build("build") {
assertSuccessful()
}
val barClass = project.projectDir.getFileByName("Bar.class")
val barClassTimestamp = barClass.lastModified()
val barJava = project.projectDir.getFileByName("Bar.java")
barJava.delete()
barKt.writeText(barKtContent)
project.build("build") {
assertSuccessful()
assertNotContains(":compileKotlin UP-TO-DATE", ":compileJava UP-TO-DATE")
assertNotEquals(barClassTimestamp, barClass.lastModified(), "Bar.class timestamp hasn't been updated")
}
}
@Test
fun testWipeClassesDirectoryBetweenBuilds() {
val project = Project("kotlinJavaProject", GRADLE_VERSION)
project.build("build") {
assertSuccessful()
}
val javaOutputDir = File(project.projectDir, "build/classes")
assert(javaOutputDir.isDirectory) { "Classes directory does not exist $javaOutputDir" }
javaOutputDir.deleteRecursively()
project.build("build") {
assertSuccessful()
assertContains(":compileKotlin UP-TO-DATE")
}
}
@Test
fun testMoveClassToOtherModule() {
val project = Project("moveClassToOtherModule", GRADLE_VERSION)
project.build("build") {
assertSuccessful()
assertContains("Connected to daemon")
}
project.performModifications()
project.build("build") {
assertSuccessful()
assertContains("Connected to daemon")
}
}
@Test
fun testTypeAliasIncremental() {
val project = Project("typeAlias", GRADLE_VERSION)
val options = defaultBuildOptions().copy(incremental = true)
project.build("build", options = options) {
assertSuccessful()
}
val curryKt = project.projectDir.getFileByName("Curry.kt")
val useCurryKt = project.projectDir.getFileByName("UseCurry.kt")
curryKt.modify {
it.replace("class Curry", "internal class Curry")
}
project.build("build", options = options) {
assertSuccessful()
assertCompiledKotlinSources(project.relativize(curryKt, useCurryKt))
}
}
}
@@ -0,0 +1,66 @@
/*
* 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 org.jetbrains.kotlin.incremental.testingUtils.BuildLogFinder
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.Parameterized
import java.io.File
// Test does not follow maven failsafe naming convention
// so it is ignored by maven integration-test phase,
// but it is possible run it from CLI (under separate CI configuration for example)
//
// To run this test from CLI:
// mvn integration-test -pl :kotlin-gradle-plugin -Dit.test=KotlinGradlePluginJpsParametrizedCLIOnly
@RunWith(Parameterized::class)
class KotlinGradlePluginJpsParametrizedCLIOnly : BaseIncrementalGradleIT() {
@Parameterized.Parameter
@JvmField
var relativePath: String = ""
@Test
fun testFromJps() {
JpsTestProject(buildLogFinder, jpsResourcesPath, relativePath).performAndAssertBuildStages(weakTesting = true)
}
override fun defaultBuildOptions() =
super.defaultBuildOptions().copy(incremental = true)
companion object {
private val jpsResourcesPath = File("../../../jps-plugin/testData/incremental")
private val ignoredDirs = setOf(File(jpsResourcesPath, "cacheVersionChanged"),
File(jpsResourcesPath, "changeIncrementalOption"),
File(jpsResourcesPath, "custom"),
File(jpsResourcesPath, "lookupTracker"))
private val buildLogFinder = BuildLogFinder(isExperimentalEnabled = true, isGradleEnabled = true)
@Suppress("unused")
@Parameterized.Parameters(name = "{index}: {0}")
@JvmStatic
fun data(): List<Array<String>> =
jpsResourcesPath.walk()
.onEnter { it !in ignoredDirs }
.filter { it.isDirectory && buildLogFinder.findBuildLog(it) != null }
.map { arrayOf(it.toRelativeString(jpsResourcesPath)) }
.toList()
}
}
@@ -0,0 +1,88 @@
package org.jetbrains.kotlin.gradle
import org.jetbrains.kotlin.gradle.util.allKotlinFiles
import org.jetbrains.kotlin.gradle.util.getFileByName
import org.jetbrains.kotlin.gradle.util.modify
import org.junit.Test
import java.io.File
class TestRootAffectedIT : BaseGradleIT() {
@Test
fun testSourceRootClassIsModifiedIC() {
val project = Project("kotlinProject", "2.10")
val buildOptions = defaultBuildOptions().copy(incremental = true)
project.build("build", options = buildOptions) {
assertSuccessful()
}
val kotlinGreetingJoinerFile = project.projectDir.getFileByName("KotlinGreetingJoiner.kt")
kotlinGreetingJoinerFile.modify {
val replacing = "fun addName(name: String?): Unit"
val replacement = "fun addName(name: String): Unit"
assert(it.contains(replacing)) { "API has changed!" }
it.replace(replacing, replacement)
}
project.build("build", options = buildOptions) {
assertSuccessful()
val expectedToCompile = project.relativize(listOf(kotlinGreetingJoinerFile) + project.allTestKotlinFiles())
assertCompiledKotlinSources(expectedToCompile)
}
project.build("build", options = buildOptions) {
assertSuccessful()
assertCompiledKotlinSources(emptyList())
}
}
@Test
fun testSourceRootClassIsRemovedIC() {
val project = Project("kotlinProject", "2.10")
val buildOptions = defaultBuildOptions().copy(incremental = true)
project.build("build", options = buildOptions) {
assertSuccessful()
}
val dummyFile = project.projectDir.getFileByName("Dummy.kt")
dummyFile.delete()
project.build("build", options = buildOptions) {
assertSuccessful()
val expectedToCompile = project.relativize(project.allTestKotlinFiles())
assertCompiledKotlinSources(expectedToCompile)
}
project.build("build", options = buildOptions) {
assertSuccessful()
assertCompiledKotlinSources(emptyList())
}
}
@Test
fun testTestRootClassIsRemovedIC() {
val project = Project("kotlinProject", "2.10")
val buildOptions = defaultBuildOptions().copy(incremental = true)
project.build("build", options = buildOptions) {
assertSuccessful()
}
val greeterTestFile = project.projectDir.getFileByName("TestGreeter.kt")
greeterTestFile.delete()
project.build("build", options = buildOptions) {
assertSuccessful()
assertCompiledKotlinSources(emptyList())
}
project.build("build", options = buildOptions) {
assertSuccessful()
assertCompiledKotlinSources(emptyList())
}
}
private fun Project.allTestKotlinFiles(): Iterable<File> =
File(projectDir, "src/test").allKotlinFiles()
}
@@ -0,0 +1,109 @@
package org.jetbrains.kotlin.gradle.incremental
import org.jetbrains.kotlin.com.intellij.openapi.util.io.FileUtil
import java.io.File
private const val BEGIN_COMPILED_FILES = "Compiling files:"
private const val END_COMPILED_FILES = "End of files"
private const val BEGIN_ERRORS = "COMPILATION FAILED"
class BuildStep(
val compiledKotlinFiles: MutableSet<String> = hashSetOf(),
val compiledJavaFiles: MutableSet<String> = hashSetOf(),
val compileErrors: MutableList<String> = arrayListOf()
) {
val compileSucceeded: Boolean
get() = compileErrors.isEmpty()
}
fun parseTestBuildLog(file: File): List<BuildStep> {
fun splitSteps(lines: List<String>): List<List<String>> {
val stepsLines = mutableListOf<MutableList<String>>()
for (line in lines) {
when {
line.matches("=+ Step #\\d+ =+".toRegex()) -> {
stepsLines.add(mutableListOf())
}
else -> {
stepsLines.lastOrNull()?.add(line)
}
}
}
return stepsLines
}
fun BuildStep.parseStepCompiledFiles(stepLines: List<String>) {
var readFiles = false
for (line in stepLines) {
if (line.startsWith(BEGIN_COMPILED_FILES)) {
readFiles = true
continue
}
if (readFiles && line.startsWith(END_COMPILED_FILES)) {
readFiles = false
continue
}
if (readFiles) {
val path = FileUtil.normalize(line.trim())
if (path.endsWith(".kt")) {
compiledKotlinFiles.add(path)
}
else if (path.endsWith(".java")) {
compiledJavaFiles.add(path)
}
else {
throw IllegalStateException("Expected .kt or .java file, got: $path")
}
}
}
}
fun BuildStep.parseErrors(stepLines: List<String>) {
val startIndex = stepLines.indexOfLast { it.startsWith(BEGIN_ERRORS) }
if (startIndex > 0) {
compileErrors.addAll(stepLines.subList(startIndex + 1, stepLines.size))
}
}
val stepsLines = splitSteps(file.readLines())
return stepsLines.map { stepLines ->
val buildStep = BuildStep()
buildStep.parseStepCompiledFiles(stepLines)
buildStep.parseErrors(stepLines)
buildStep
}
}
fun dumpBuildLog(buildSteps: Iterable<BuildStep>): String {
val sb = StringBuilder()
for ((i, step) in buildSteps.withIndex()) {
if (i > 0) {
sb.appendln()
}
sb.appendln("================ Step #${i+1} =================")
sb.appendln()
sb.appendln(BEGIN_COMPILED_FILES)
step.compiledKotlinFiles.sorted().forEach { sb.appendln(it) }
step.compiledJavaFiles.sorted().forEach { sb.appendln(it) }
sb.appendln(END_COMPILED_FILES)
sb.appendln("------------------------------------------")
if (!step.compileSucceeded) {
sb.appendln(BEGIN_ERRORS)
step.compileErrors.forEach { sb.appendln(it) }
}
}
return sb.toString()
}
@@ -0,0 +1,26 @@
package org.jetbrains.kotlin.gradle.util
import java.io.File
fun File.getFileByName(name: String): File =
findFileByName(name) ?: throw AssertionError("Could not find file with name '$name' in $this")
fun File.getFilesByNames(vararg names: String): List<File> =
names.map { getFileByName(it) }
fun File.findFileByName(name: String): File? =
walk().filter { it.isFile && it.name.equals(name, ignoreCase = true) }.firstOrNull()
fun File.allKotlinFiles(): Iterable<File> =
allFilesWithExtension("kt")
fun File.allJavaFiles(): Iterable<File> =
allFilesWithExtension("java")
fun File.allFilesWithExtension(ext: String): Iterable<File> =
walk().filter { it.isFile && it.extension.equals(ext, ignoreCase = true) }.toList()
fun File.modify(transform: (String)->String) {
writeText(transform(readText()))
}
@@ -0,0 +1,46 @@
package org.jetbrains.kotlin.gradle.util
import java.io.File
import java.io.StringWriter
class ProcessRunResult(
private val cmd: List<String>,
private val workingDir: File,
val exitCode: Int,
val output: String
) {
val isSuccessful: Boolean
get() = exitCode == 0
override fun toString(): String = """
Executing process was ${if (isSuccessful) "successful" else "unsuccessful"}
Command: ${cmd.joinToString()}
Working directory: ${workingDir.absolutePath}
Exit code: $exitCode
"""
}
fun runProcess(cmd: List<String>, workingDir: File, environmentVariables: Map<String, String> = mapOf()): ProcessRunResult {
val builder = ProcessBuilder(cmd)
builder.environment().putAll(environmentVariables)
builder.directory(workingDir)
// redirectErrorStream merges stdout and stderr, so it can be get from process.inputStream
builder.redirectErrorStream(true)
val process = builder.start()
// important to read inputStream, otherwise the process may hang on some systems
val sw = StringWriter()
process.inputStream!!.bufferedReader().copyTo(sw)
val exitCode = process.waitFor()
return ProcessRunResult(cmd, workingDir, exitCode, sw.toString())
}
fun createGradleCommand(tailParameters: List<String>): List<String> {
return if (isWindows())
listOf("cmd", "/C", "gradlew.bat") + tailParameters
else
listOf("/bin/bash", "./gradlew") + tailParameters
}
private fun isWindows(): Boolean = System.getProperty("os.name")!!.contains("Windows")
@@ -0,0 +1,4 @@
package org.jetbrains.kotlin.gradle.util
fun String.addBeforeSubstring(prefix: String, substring: String): String =
replace(substring, prefix + substring)
@@ -0,0 +1,6 @@
#Thu Feb 11 21:56:06 MSK 2016
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-2.10-bin.zip
@@ -0,0 +1,160 @@
#!/usr/bin/env bash
##############################################################################
##
## Gradle start up script for UN*X
##
##############################################################################
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS=""
APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
warn ( ) {
echo "$*"
}
die ( ) {
echo
echo "$*"
echo
exit 1
}
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
case "`uname`" in
CYGWIN* )
cygwin=true
;;
Darwin* )
darwin=true
;;
MINGW* )
msys=true
;;
esac
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG="$0"
# Need this for relative symlinks.
while [ -h "$PRG" ] ; do
ls=`ls -ld "$PRG"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
PRG="$link"
else
PRG=`dirname "$PRG"`"/$link"
fi
done
SAVED="`pwd`"
cd "`dirname \"$PRG\"`/" >/dev/null
APP_HOME="`pwd -P`"
cd "$SAVED" >/dev/null
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD="$JAVA_HOME/jre/sh/java"
else
JAVACMD="$JAVA_HOME/bin/java"
fi
if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
JAVACMD="java"
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
# Increase the maximum file descriptors if we can.
if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
MAX_FD_LIMIT=`ulimit -H -n`
if [ $? -eq 0 ] ; then
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
MAX_FD="$MAX_FD_LIMIT"
fi
ulimit -n $MAX_FD
if [ $? -ne 0 ] ; then
warn "Could not set maximum file descriptor limit: $MAX_FD"
fi
else
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
fi
fi
# For Darwin, add options to specify how the application appears in the dock
if $darwin; then
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi
# For Cygwin, switch paths to Windows format before running java
if $cygwin ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
JAVACMD=`cygpath --unix "$JAVACMD"`
# We build the pattern for arguments to be converted via cygpath
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
SEP=""
for dir in $ROOTDIRSRAW ; do
ROOTDIRS="$ROOTDIRS$SEP$dir"
SEP="|"
done
OURCYGPATTERN="(^($ROOTDIRS))"
# Add a user-defined pattern to the cygpath arguments
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
fi
# Now convert the arguments - kludge to limit ourselves to /bin/sh
i=0
for arg in "$@" ; do
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
else
eval `echo args$i`="\"$arg\""
fi
i=$((i+1))
done
case $i in
(0) set -- ;;
(1) set -- "$args0" ;;
(2) set -- "$args0" "$args1" ;;
(3) set -- "$args0" "$args1" "$args2" ;;
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
esac
fi
# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
function splitJvmOpts() {
JVM_OPTS=("$@")
}
eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
@@ -0,0 +1,90 @@
@if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@rem
@rem ##########################################################################
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS=
set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto init
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto init
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:init
@rem Get command-line arguments, handling Windowz variants
if not "%OS%" == "Windows_NT" goto win9xME_args
if "%@eval[2+2]" == "4" goto 4NT_args
:win9xME_args
@rem Slurp the command line arguments.
set CMD_LINE_ARGS=
set _SKIP=2
:win9xME_args_slurp
if "x%~1" == "x" goto execute
set CMD_LINE_ARGS=%*
goto execute
:4NT_args
@rem Get arguments from the 4NT Shell from JP Software
set CMD_LINE_ARGS=%$
:execute
@rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
:end
@rem End local scope for the variables with windows NT shell
if "%ERRORLEVEL%"=="0" goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
exit /b 1
:mainEnd
if "%OS%"=="Windows_NT" endlocal
:omega
@@ -0,0 +1,6 @@
#Mon Aug 08 19:21:19 MSK 2016
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-2.14.1-bin.zip
@@ -0,0 +1,160 @@
#!/usr/bin/env bash
##############################################################################
##
## Gradle start up script for UN*X
##
##############################################################################
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS=""
APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
warn ( ) {
echo "$*"
}
die ( ) {
echo
echo "$*"
echo
exit 1
}
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
case "`uname`" in
CYGWIN* )
cygwin=true
;;
Darwin* )
darwin=true
;;
MINGW* )
msys=true
;;
esac
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG="$0"
# Need this for relative symlinks.
while [ -h "$PRG" ] ; do
ls=`ls -ld "$PRG"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
PRG="$link"
else
PRG=`dirname "$PRG"`"/$link"
fi
done
SAVED="`pwd`"
cd "`dirname \"$PRG\"`/" >/dev/null
APP_HOME="`pwd -P`"
cd "$SAVED" >/dev/null
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD="$JAVA_HOME/jre/sh/java"
else
JAVACMD="$JAVA_HOME/bin/java"
fi
if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
JAVACMD="java"
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
# Increase the maximum file descriptors if we can.
if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
MAX_FD_LIMIT=`ulimit -H -n`
if [ $? -eq 0 ] ; then
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
MAX_FD="$MAX_FD_LIMIT"
fi
ulimit -n $MAX_FD
if [ $? -ne 0 ] ; then
warn "Could not set maximum file descriptor limit: $MAX_FD"
fi
else
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
fi
fi
# For Darwin, add options to specify how the application appears in the dock
if $darwin; then
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi
# For Cygwin, switch paths to Windows format before running java
if $cygwin ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
JAVACMD=`cygpath --unix "$JAVACMD"`
# We build the pattern for arguments to be converted via cygpath
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
SEP=""
for dir in $ROOTDIRSRAW ; do
ROOTDIRS="$ROOTDIRS$SEP$dir"
SEP="|"
done
OURCYGPATTERN="(^($ROOTDIRS))"
# Add a user-defined pattern to the cygpath arguments
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
fi
# Now convert the arguments - kludge to limit ourselves to /bin/sh
i=0
for arg in "$@" ; do
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
else
eval `echo args$i`="\"$arg\""
fi
i=$((i+1))
done
case $i in
(0) set -- ;;
(1) set -- "$args0" ;;
(2) set -- "$args0" "$args1" ;;
(3) set -- "$args0" "$args1" "$args2" ;;
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
esac
fi
# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
function splitJvmOpts() {
JVM_OPTS=("$@")
}
eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
@@ -0,0 +1,90 @@
@if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@rem
@rem ##########################################################################
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS=
set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto init
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto init
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:init
@rem Get command-line arguments, handling Windows variants
if not "%OS%" == "Windows_NT" goto win9xME_args
if "%@eval[2+2]" == "4" goto 4NT_args
:win9xME_args
@rem Slurp the command line arguments.
set CMD_LINE_ARGS=
set _SKIP=2
:win9xME_args_slurp
if "x%~1" == "x" goto execute
set CMD_LINE_ARGS=%*
goto execute
:4NT_args
@rem Get arguments from the 4NT Shell from JP Software
set CMD_LINE_ARGS=%$
:execute
@rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
:end
@rem End local scope for the variables with windows NT shell
if "%ERRORLEVEL%"=="0" goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
exit /b 1
:mainEnd
if "%OS%"=="Windows_NT" endlocal
:omega
@@ -0,0 +1,6 @@
#Wed Apr 22 16:22:48 MSK 2015
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-2.3-bin.zip
@@ -0,0 +1,164 @@
#!/usr/bin/env bash
##############################################################################
##
## Gradle start up script for UN*X
##
##############################################################################
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS=""
APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
warn ( ) {
echo "$*"
}
die ( ) {
echo
echo "$*"
echo
exit 1
}
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
case "`uname`" in
CYGWIN* )
cygwin=true
;;
Darwin* )
darwin=true
;;
MINGW* )
msys=true
;;
esac
# For Cygwin, ensure paths are in UNIX format before anything is touched.
if $cygwin ; then
[ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
fi
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG="$0"
# Need this for relative symlinks.
while [ -h "$PRG" ] ; do
ls=`ls -ld "$PRG"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
PRG="$link"
else
PRG=`dirname "$PRG"`"/$link"
fi
done
SAVED="`pwd`"
cd "`dirname \"$PRG\"`/" >&-
APP_HOME="`pwd -P`"
cd "$SAVED" >&-
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD="$JAVA_HOME/jre/sh/java"
else
JAVACMD="$JAVA_HOME/bin/java"
fi
if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
JAVACMD="java"
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
# Increase the maximum file descriptors if we can.
if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
MAX_FD_LIMIT=`ulimit -H -n`
if [ $? -eq 0 ] ; then
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
MAX_FD="$MAX_FD_LIMIT"
fi
ulimit -n $MAX_FD
if [ $? -ne 0 ] ; then
warn "Could not set maximum file descriptor limit: $MAX_FD"
fi
else
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
fi
fi
# For Darwin, add options to specify how the application appears in the dock
if $darwin; then
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi
# For Cygwin, switch paths to Windows format before running java
if $cygwin ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
# We build the pattern for arguments to be converted via cygpath
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
SEP=""
for dir in $ROOTDIRSRAW ; do
ROOTDIRS="$ROOTDIRS$SEP$dir"
SEP="|"
done
OURCYGPATTERN="(^($ROOTDIRS))"
# Add a user-defined pattern to the cygpath arguments
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
fi
# Now convert the arguments - kludge to limit ourselves to /bin/sh
i=0
for arg in "$@" ; do
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
else
eval `echo args$i`="\"$arg\""
fi
i=$((i+1))
done
case $i in
(0) set -- ;;
(1) set -- "$args0" ;;
(2) set -- "$args0" "$args1" ;;
(3) set -- "$args0" "$args1" "$args2" ;;
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
esac
fi
# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
function splitJvmOpts() {
JVM_OPTS=("$@")
}
eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
@@ -0,0 +1,90 @@
@if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@rem
@rem ##########################################################################
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS=
set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto init
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto init
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:init
@rem Get command-line arguments, handling Windowz variants
if not "%OS%" == "Windows_NT" goto win9xME_args
if "%@eval[2+2]" == "4" goto 4NT_args
:win9xME_args
@rem Slurp the command line arguments.
set CMD_LINE_ARGS=
set _SKIP=2
:win9xME_args_slurp
if "x%~1" == "x" goto execute
set CMD_LINE_ARGS=%*
goto execute
:4NT_args
@rem Get arguments from the 4NT Shell from JP Software
set CMD_LINE_ARGS=%$
:execute
@rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
:end
@rem End local scope for the variables with windows NT shell
if "%ERRORLEVEL%"=="0" goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
exit /b 1
:mainEnd
if "%OS%"=="Windows_NT" endlocal
:omega
@@ -0,0 +1,6 @@
#Mon Aug 10 11:44:23 CEST 2015
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-2.4-bin.zip
@@ -0,0 +1,164 @@
#!/usr/bin/env bash
##############################################################################
##
## Gradle start up script for UN*X
##
##############################################################################
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS=""
APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
warn ( ) {
echo "$*"
}
die ( ) {
echo
echo "$*"
echo
exit 1
}
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
case "`uname`" in
CYGWIN* )
cygwin=true
;;
Darwin* )
darwin=true
;;
MINGW* )
msys=true
;;
esac
# For Cygwin, ensure paths are in UNIX format before anything is touched.
if $cygwin ; then
[ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
fi
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG="$0"
# Need this for relative symlinks.
while [ -h "$PRG" ] ; do
ls=`ls -ld "$PRG"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
PRG="$link"
else
PRG=`dirname "$PRG"`"/$link"
fi
done
SAVED="`pwd`"
cd "`dirname \"$PRG\"`/" >&-
APP_HOME="`pwd -P`"
cd "$SAVED" >&-
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD="$JAVA_HOME/jre/sh/java"
else
JAVACMD="$JAVA_HOME/bin/java"
fi
if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
JAVACMD="java"
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
# Increase the maximum file descriptors if we can.
if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
MAX_FD_LIMIT=`ulimit -H -n`
if [ $? -eq 0 ] ; then
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
MAX_FD="$MAX_FD_LIMIT"
fi
ulimit -n $MAX_FD
if [ $? -ne 0 ] ; then
warn "Could not set maximum file descriptor limit: $MAX_FD"
fi
else
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
fi
fi
# For Darwin, add options to specify how the application appears in the dock
if $darwin; then
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi
# For Cygwin, switch paths to Windows format before running java
if $cygwin ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
# We build the pattern for arguments to be converted via cygpath
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
SEP=""
for dir in $ROOTDIRSRAW ; do
ROOTDIRS="$ROOTDIRS$SEP$dir"
SEP="|"
done
OURCYGPATTERN="(^($ROOTDIRS))"
# Add a user-defined pattern to the cygpath arguments
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
fi
# Now convert the arguments - kludge to limit ourselves to /bin/sh
i=0
for arg in "$@" ; do
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
else
eval `echo args$i`="\"$arg\""
fi
i=$((i+1))
done
case $i in
(0) set -- ;;
(1) set -- "$args0" ;;
(2) set -- "$args0" "$args1" ;;
(3) set -- "$args0" "$args1" "$args2" ;;
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
esac
fi
# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
function splitJvmOpts() {
JVM_OPTS=("$@")
}
eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
@@ -0,0 +1,90 @@
@if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@rem
@rem ##########################################################################
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS=
set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto init
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto init
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:init
@rem Get command-line arguments, handling Windowz variants
if not "%OS%" == "Windows_NT" goto win9xME_args
if "%@eval[2+2]" == "4" goto 4NT_args
:win9xME_args
@rem Slurp the command line arguments.
set CMD_LINE_ARGS=
set _SKIP=2
:win9xME_args_slurp
if "x%~1" == "x" goto execute
set CMD_LINE_ARGS=%*
goto execute
:4NT_args
@rem Get arguments from the 4NT Shell from JP Software
set CMD_LINE_ARGS=%$
:execute
@rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
:end
@rem End local scope for the variables with windows NT shell
if "%ERRORLEVEL%"=="0" goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
exit /b 1
:mainEnd
if "%OS%"=="Windows_NT" endlocal
:omega
@@ -0,0 +1,50 @@
================ Step #1 =================
Cleaning output files:
out/production/module/META-INF/module.kotlin_module
out/production/module/inline/InlineGetKt.class
End of files
Compiling files:
src/inlineGet.kt
End of files
Marked as dirty by Kotlin:
src/UsageVal.kt
src/UsageVar.kt
Exit code: ADDITIONAL_PASS_REQUIRED
------------------------------------------
Cleaning output files:
out/production/module/usage/UsageVal.class
out/production/module/usage/UsageVar.class
End of files
Compiling files:
src/UsageVal.kt
src/UsageVar.kt
End of files
Exit code: ADDITIONAL_PASS_REQUIRED
------------------------------------------
Exit code: NOTHING_DONE
------------------------------------------
================ Step #2 =================
Cleaning output files:
out/production/module/META-INF/module.kotlin_module
out/production/module/inline/InlineSetKt.class
End of files
Compiling files:
src/inlineSet.kt
End of files
Marked as dirty by Kotlin:
src/UsageVar.kt
Exit code: ADDITIONAL_PASS_REQUIRED
------------------------------------------
Cleaning output files:
out/production/module/usage/UsageVar.class
End of files
Compiling files:
src/UsageVar.kt
End of files
Exit code: ADDITIONAL_PASS_REQUIRED
------------------------------------------
Exit code: NOTHING_DONE
------------------------------------------
@@ -0,0 +1,16 @@
================ Step #1 =================
Compiling files:
src/UsageVal.kt
src/UsageVar.kt
src/inlineGet.kt
End of files
------------------------------------------
================ Step #2 =================
Compiling files:
src/UsageVar.kt
src/inlineSet.kt
End of files
------------------------------------------
@@ -0,0 +1,37 @@
================ Step #1 =================
Cleaning output files:
out/production/module1/META-INF/module1.kotlin_module
out/production/module1/a/A.class
out/production/module1/a/ClassAnnotation.class
out/production/module1/a/FileAnnotation.class
out/production/module1/a/Module1_aKt.class
End of files
Compiling files:
module1/src/module1_a.kt
End of files
Marked as dirty by Kotlin:
module2/src/module2_b.kt
Exit code: ADDITIONAL_PASS_REQUIRED
------------------------------------------
Exit code: NOTHING_DONE
------------------------------------------
Cleaning output files:
out/production/module2/META-INF/module2.kotlin_module
out/production/module2/b/B.class
out/production/module2/b/Module2_bKt.class
End of files
Compiling files:
module2/src/module2_b.kt
End of files
Exit code: ABORT
------------------------------------------
COMPILATION FAILED
Cannot access 'FileAnnotation': it is internal in 'a'
Cannot access 'A': it is internal in 'a'
Cannot access 'FileAnnotation': it is internal in 'a'
Cannot access 'ClassAnnotation': it is internal in 'a'
Cannot access 'ClassAnnotation': it is internal in 'a'
Function effective visibility 'public' should be the same or less permissive than its parameter type effective visibility 'internal'
Cannot access 'A': it is internal in 'a'
Cannot access 'a': it is internal in 'a'
@@ -0,0 +1,16 @@
================ Step #1 =================
Compiling files:
module1/src/module1_a.kt
module2/src/module2_b.kt
End of files
------------------------------------------
COMPILATION FAILED
Cannot access 'FileAnnotation': it is internal in 'a'
Cannot access 'A': it is internal in 'a'
Cannot access 'FileAnnotation': it is internal in 'a'
Cannot access 'ClassAnnotation': it is internal in 'a'
Cannot access 'ClassAnnotation': it is internal in 'a'
Function effective visibility 'public' should be the same or less permissive than its parameter type effective visibility 'internal'
Cannot access 'A': it is internal in 'a'
Cannot access 'a': it is internal in 'a'
@@ -0,0 +1,17 @@
================ Step #1 =================
Cleaning output files:
out/production/module/JavaClass.class
out/production/module/META-INF/module.kotlin_module
out/production/module/UsageKt.class
End of files
Compiling files:
src/usage.kt
End of files
Exit code: ADDITIONAL_PASS_REQUIRED
------------------------------------------
Compiling files:
src/JavaClass.java
End of files
Exit code: NOTHING_DONE
------------------------------------------
@@ -0,0 +1,7 @@
================ Step #1 =================
Compiling files:
src/usage.kt
src/JavaClass.java
End of files
------------------------------------------
@@ -0,0 +1,29 @@
buildscript {
repositories {
mavenLocal()
}
dependencies {
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}
apply plugin: "kotlin"
sourceSets {
main {
kotlin {
srcDir 'src'
}
java {
srcDir 'src'
}
}
}
repositories {
mavenLocal()
}
dependencies {
compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
}
@@ -0,0 +1 @@
org.gradle.jvmargs=-Xmx1024m -XX:MaxPermSize=512m
@@ -0,0 +1,53 @@
buildscript {
repositories {
mavenLocal()
jcenter()
}
dependencies {
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
classpath "com.android.tools.build:gradle:$android_tools_version"
classpath "com.jakewharton.sdkmanager:gradle-plugin:0.12.+"
}
}
apply plugin: 'android-sdk-manager'
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
android {
compileSdkVersion 23
buildToolsVersion "23.0.1"
defaultConfig {
applicationId "com.example.dagger.kotlin"
minSdkVersion 14
targetSdkVersion 23
versionCode 1
versionName "1.0"
buildConfigField "long", "BUILD_TIME_MILLIS", "${System.currentTimeMillis()}L"
}
sourceSets {
main.java.srcDirs += 'src/main/kotlin'
}
}
repositories {
mavenLocal()
jcenter()
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.android.support:appcompat-v7:23.1.1'
compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
compile 'com.google.dagger:dagger:2.0.1'
kapt 'com.google.dagger:dagger-compiler:2.0'
provided 'org.glassfish:javax.annotation:10.0-b28'
}
kapt {
generateStubs = true
}
@@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.dagger.kotlin">
<application
android:allowBackup="true"
android:label="app_name"
android:name=".DemoApplication">
<activity
android:label="app_name"
android:name=".ui.HomeActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</activity>
</application>
</manifest>
@@ -0,0 +1,44 @@
/*
* Copyright (C) 2013 Square, Inc.
*
* 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 com.example.dagger.kotlin
import android.content.Context
import android.content.Context.LOCATION_SERVICE
import android.location.LocationManager
import dagger.Module
import dagger.Provides
import javax.inject.Singleton
/**
* A module for Android-specific dependencies which require a [Context] or
* [android.app.Application] to create.
*/
@Module class AndroidModule(private val application: BaseApplication) {
/**
* Allow the application context to be injected but require that it be annotated with
* [@Annotation][ForApplication] to explicitly differentiate it from an activity context.
*/
@Provides @Singleton @ForApplication
fun provideApplicationContext(): Context {
return application
}
@Provides @Singleton
fun provideLocationManager(): LocationManager {
return application.getSystemService(LOCATION_SERVICE) as LocationManager
}
}
@@ -0,0 +1,13 @@
package com.example.dagger.kotlin
import com.example.dagger.kotlin.ui.HomeActivity
import dagger.Component
import javax.inject.Singleton
@Singleton
@Component(modules = arrayOf(AndroidModule::class))
interface ApplicationComponent {
fun inject(application: BaseApplication)
fun inject(homeActivity: HomeActivity)
fun inject(demoActivity: DemoActivity)
}
@@ -0,0 +1,11 @@
package com.example.dagger.kotlin
import android.app.Application
abstract class BaseApplication : Application() {
protected fun initDaggerComponent(): ApplicationComponent {
return DaggerApplicationComponent.builder().androidModule(AndroidModule(this)).build()
}
}
@@ -0,0 +1,12 @@
package com.example.dagger.kotlin
import android.app.Activity
import android.os.Bundle
abstract class DemoActivity : Activity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// Perform injection so that when this call returns all dependencies will be available for use.
(application as DemoApplication).component.inject(this)
}
}
@@ -0,0 +1,13 @@
package com.example.dagger.kotlin
class DemoApplication : BaseApplication() {
lateinit var component: ApplicationComponent
override fun onCreate() {
super.onCreate()
val component = initDaggerComponent()
component.inject(this) // As of now, LocationManager should be injected into this.
this.component = component
}
}
@@ -0,0 +1,6 @@
package com.example.dagger.kotlin
import javax.inject.Qualifier
@Qualifier
annotation class ForApplication
@@ -0,0 +1,9 @@
package com.example.dagger.kotlin
import android.app.Activity
class UseRJavaActivity : Activity() {
fun useRJava() {
val app_name = getResources().getString(R.string.app_name)
}
}
@@ -0,0 +1,38 @@
/*
* Copyright (C) 2013 Square, Inc.
*
* 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 com.example.dagger.kotlin.ui
import android.location.LocationManager
import android.os.Bundle
import com.example.dagger.kotlin.DemoActivity
import com.example.dagger.kotlin.DemoApplication
import com.example.dagger.kotlin.R
import kotlinx.android.synthetic.main.activity_main.locationInfo
import javax.inject.Inject
class HomeActivity : DemoActivity() {
@Inject
lateinit var locationManager: LocationManager
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
(application as DemoApplication).component.inject(this)
// TODO do something with the injected dependencies here!
locationInfo.text = "Injected LocationManager:\n$locationManager"
}
}
@@ -0,0 +1,5 @@
package com.example.dagger.kotlin
fun useBuildConfigJava() {
if (BuildConfig.APPLICATION_ID != "com.example.dagger.kotlin") throw AssertionError()
}
@@ -0,0 +1,10 @@
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
android:layout_height="match_parent" tools:context=".ui.HomeActivity">
<TextView android:id="@+id/locationInfo"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="16dp" />
</RelativeLayout>
@@ -0,0 +1,3 @@
<resources>
<string name="app_name">kotlin</string>
</resources>
@@ -0,0 +1,8 @@
<resources>
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<!-- Customize your theme here. -->
</style>
</resources>
@@ -0,0 +1 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules.
@@ -0,0 +1 @@
org.gradle.jvmargs=-ea -XX:MaxPermSize=512m
@@ -0,0 +1,26 @@
apply plugin: 'android-sdk-manager'
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
android {
compileSdkVersion 23
buildToolsVersion "23.0.1"
defaultConfig {
applicationId "com.example.dagger.kotlin"
minSdkVersion 14
targetSdkVersion 23
versionCode 1
versionName "1.0"
}
sourceSets {
main.java.srcDirs += 'src/main/kotlin'
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.android.support:appcompat-v7:23.1.1'
compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
}
@@ -0,0 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.androidextensions">
<application android:label="app_name">
<activity
android:label="app_name"
android:name="com.example.androidextensions.MyActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</activity>
</application>
</manifest>
@@ -0,0 +1,30 @@
/*
* 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 com.example.androidextensions
import android.os.Bundle
import android.app.Activity
import kotlinx.android.synthetic.main.activity_main.textView
class HomeActivity : Activity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
this.textView.setText("Hello, world!")
}
}
@@ -0,0 +1,9 @@
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</RelativeLayout>
@@ -0,0 +1,3 @@
<resources>
<string name="app_name">kotlin</string>
</resources>
@@ -0,0 +1,21 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
repositories {
mavenLocal()
jcenter()
}
dependencies {
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
classpath "com.android.tools.build:gradle:$android_tools_version"
classpath "com.jakewharton.sdkmanager:gradle-plugin:0.12.+"
}
}
allprojects {
repositories {
mavenLocal()
jcenter()
}
}
@@ -0,0 +1,45 @@
apply plugin: 'android-sdk-manager'
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
dependencies {
compile "frankiesardo:icepick:3.2.0"
kapt "frankiesardo:icepick-processor:3.2.0"
compile 'org.parceler:parceler-api:1.1.5'
kapt 'org.parceler:parceler:1.1.5'
compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
}
android {
compileSdkVersion 23
buildToolsVersion "23.0.1"
defaultConfig {
applicationId "com.example.icepick.kotlin"
minSdkVersion 14
targetSdkVersion 23
versionCode 1
versionName "1.0"
}
lintOptions {
abortOnError false
}
sourceSets {
main.java.srcDirs += 'src/main/kotlin'
}
}
repositories {
mavenCentral()
maven {
url "https://clojars.org/repo/"
}
mavenLocal()
}
kapt {
generateStubs = true
}
@@ -0,0 +1,22 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.github.frankiesardo.icepick"
android:versionCode="1"
android:versionName="1.0">
<application
android:allowBackup="true"
android:label="@string/app_name"
android:theme="@android:style/Theme.Holo.Light">
<activity
android:name=".MainActivity"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
</application>
</manifest>
@@ -0,0 +1,28 @@
package com.github.frankiesardo.icepick
import android.content.Context
import android.os.Parcelable
import android.util.AttributeSet
import com.sample.icepick.lib.BaseCustomView
import icepick.State
class CustomView : BaseCustomView {
@JvmField @State
var textColor: Int? = null
constructor(context: Context) : super(context)
constructor(context: Context, attrs: AttributeSet) : super(context, attrs)
constructor(context: Context, attrs: AttributeSet, defStyle: Int) : super(context, attrs, defStyle)
fun setTextColorWithAnotherMethod(color: Int) {
this.textColor = color
setTextColor(textColor!!)
}
override fun onRestoreInstanceState(state: Parcelable) {
super.onRestoreInstanceState(state)
if (textColor != null) {
setTextColorWithAnotherMethod(textColor!!)
}
}
}
@@ -0,0 +1,19 @@
package com.github.frankiesardo.icepick
import org.parceler.Parcel
@Parcel
class Example {
lateinit var name: String
@JvmField
var age: Int = 0
constructor() { /*Required empty bean constructor*/
}
constructor(age: Int, name: String) {
this.age = age
this.name = name
}
}
@@ -0,0 +1,18 @@
package com.github.frankiesardo.icepick
import android.os.Bundle
import android.os.Parcelable
import org.parceler.Parcels
import icepick.Bundler
class ExampleBundler : Bundler<Any> {
override fun put(s: String, example: Any, bundle: Bundle) {
bundle.putParcelable(s, Parcels.wrap(example))
}
override fun get(s: String, bundle: Bundle): Any {
return Parcels.unwrap<Any>(bundle.getParcelable<Parcelable>(s))
}
}
@@ -0,0 +1,49 @@
package com.github.frankiesardo.icepick
import android.graphics.Color
import android.os.Bundle
import android.view.Menu
import android.view.MenuItem
import com.sample.icepick.lib.BaseActivity
import icepick.State
class MainActivity : BaseActivity() {
@JvmField @State(MyBundler::class)
var message: String? = null
lateinit var customView: CustomView
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
customView = findViewById(R.id.custom_view) as CustomView
updateText()
}
private fun updateText() {
val defaultText = if (message == null || baseMessage == null) {
"Use the menu to add some state"
} else {
baseMessage + message
}
customView.text = defaultText
}
override fun onCreateOptionsMenu(menu: Menu): Boolean {
menuInflater.inflate(R.menu.main, menu)
return super.onPrepareOptionsMenu(menu)
}
override fun onMenuItemSelected(featureId: Int, item: MenuItem): Boolean {
if (item.itemId == R.id.action_add_state) {
customView.setBackgroundColorWithAnotherMethod(Color.BLUE)
customView.setTextColorWithAnotherMethod(Color.WHITE)
baseMessage = "This state will be automagically "
message = "saved and restored"
updateText()
return true
}
return super.onMenuItemSelected(featureId, item)
}
}
@@ -0,0 +1,17 @@
package com.github.frankiesardo.icepick
import android.os.Bundle
import icepick.Bundler
class MyBundler : Bundler<String> {
override fun put(key: String, value: String?, bundle: Bundle) {
if (value != null) {
bundle.putString(key, value + "*")
}
}
override fun get(key: String, bundle: Bundle): String? {
return bundle.getString(key)
}
}
@@ -0,0 +1,24 @@
package com.sample.icepick.lib
import android.app.Activity
import android.os.Bundle
import android.os.Parcelable
import icepick.Icepick
import icepick.State
import android.util.Log
open class BaseActivity : Activity() {
@JvmField @State
var baseMessage: String? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
Icepick.restoreInstanceState(this, savedInstanceState)
}
override fun onSaveInstanceState(outState: Bundle) {
super.onSaveInstanceState(outState)
Icepick.saveInstanceState(this, outState)
}
}
@@ -0,0 +1,34 @@
package com.sample.icepick.lib
import android.content.Context
import android.os.Parcelable
import android.util.AttributeSet
import android.widget.TextView
import icepick.Icepick
import icepick.State
open class BaseCustomView : TextView {
@JvmField @State
var backgroundColor: Int? = null
constructor(context: Context) : super(context)
constructor(context: Context, attrs: AttributeSet) : super(context, attrs)
constructor(context: Context, attrs: AttributeSet, defStyle: Int) : super(context, attrs, defStyle)
fun setBackgroundColorWithAnotherMethod(color: Int) {
this.backgroundColor = color
setBackgroundColor(color)
}
override fun onSaveInstanceState(): Parcelable {
return Icepick.saveInstanceState(this, super.onSaveInstanceState())
}
override fun onRestoreInstanceState(state: Parcelable) {
super.onRestoreInstanceState(Icepick.restoreInstanceState(this, state))
if (backgroundColor != null) {
setBackgroundColorWithAnotherMethod(backgroundColor!!)
}
}
}
@@ -0,0 +1,12 @@
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<com.github.frankiesardo.icepick.CustomView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:id="@+id/custom_view"/>
</LinearLayout>
@@ -0,0 +1,7 @@
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="@+id/action_add_state"
android:title="@string/action_add_state"
android:orderInCategory="100"
android:showAsAction="never" />
</menu>
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">Icepick</string>
<string name="action_add_state">Add some state</string>
</resources>
@@ -0,0 +1,12 @@
buildscript {
repositories {
mavenCentral()
mavenLocal()
jcenter()
}
dependencies {
classpath "com.android.tools.build:gradle:$android_tools_version"
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
classpath "com.jakewharton.sdkmanager:gradle-plugin:0.12.+"
}
}
@@ -0,0 +1 @@
org.gradle.jvmargs=-ea -XX:MaxPermSize=512m
@@ -0,0 +1,48 @@
buildscript {
repositories {
mavenLocal()
jcenter()
}
dependencies {
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
classpath "org.jetbrains.kotlin:kotlin-android-extensions:$kotlin_version"
classpath 'com.android.tools.build:gradle:' + android_tools_version
classpath 'com.jakewharton.sdkmanager:gradle-plugin:0.12.+'
}
}
apply plugin: 'android-sdk-manager'
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
android {
compileSdkVersion 23
buildToolsVersion "23.0.1"
defaultConfig {
applicationId "foo"
minSdkVersion 14
targetSdkVersion 23
versionCode 1
versionName "1.0"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
sourceSets {
main.java.srcDirs += 'src/main/kotlin'
}
}
repositories {
mavenLocal()
}
dependencies {
compile 'com.android.support:appcompat-v7:23.1.1'
compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
}
@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="foo" >
<application>
<activity android:name=".JavaActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".KotlinActivity1"/>
<activity android:name=".KotlinActivity2"/>
</application>
</manifest>
@@ -0,0 +1,6 @@
package foo;
import android.app.Activity;
public class JavaActivity extends Activity {
}
@@ -0,0 +1,8 @@
package foo
import android.app.Activity
open class KotlinActivity1 : Activity() {
val usage = getSomething()
}
@@ -0,0 +1,5 @@
package foo
import android.app.Activity
open class KotlinActivity2 : Activity()
@@ -0,0 +1 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules.
@@ -0,0 +1,24 @@
apply plugin: 'android-sdk-manager'
apply plugin: 'com.android.library'
apply plugin: 'kotlin-android'
android {
compileSdkVersion 23
buildToolsVersion "23.0.1"
defaultConfig {
minSdkVersion 19
targetSdkVersion 23
versionCode 1
versionName "1.0"
}
}
dependencies {
compile project(':lib-a')
kapt "com.squareup.dagger:dagger-compiler:$dagger_version"
}
kapt {
generateStubs = true
}
@@ -0,0 +1,3 @@
<manifest package="com.example.libb">
<application />
</manifest>
@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="Test.Inherited" />
</resources>
@@ -0,0 +1,32 @@
apply plugin: 'android-sdk-manager'
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
android {
compileSdkVersion 23
buildToolsVersion "23.0.1"
defaultConfig {
applicationId "com.example.kapt"
minSdkVersion 19
targetSdkVersion 23
versionCode 1
versionName "1.0"
}
sourceSets {
main.java.srcDirs += 'src/main/kotlin'
}
}
dependencies {
compile project(':aaa')
kapt "com.squareup.dagger:dagger-compiler:$dagger_version"
}
kapt {
generateStubs = true
}
repositories {
mavenCentral()
}
@@ -0,0 +1,6 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.kapt">
<application
android:theme="@style/AppTheme">
</application>
</manifest>
@@ -0,0 +1,7 @@
<resources>
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
</style>
<style name="Test.Inherited.Twice" />
</resources>

Some files were not shown because too many files have changed in this diff Show More