From 0b63e11ea8129e291001ad8f8f0562527e270184 Mon Sep 17 00:00:00 2001 From: Ilya Chernikov Date: Wed, 15 Nov 2017 18:50:21 +0100 Subject: [PATCH] Replace android sdk dependencies with custom project build, cleanup update_dependencies.xml --- buildSrc/src/main/kotlin/dependencies.kt | 20 +- compiler/build.gradle.kts | 2 +- compiler/tests-common/build.gradle.kts | 2 +- .../kotlin/test/KotlinTestUtils.java | 22 +- .../android-sdk/build.gradle.kts | 99 +++++++++ idea/idea-android/build.gradle.kts | 8 +- .../jetbrains/kotlin/android/TestUtils.java | 3 +- idea/idea-gradle/build.gradle.kts | 1 + .../MultiplatformProjectImportingTest.kt | 5 +- .../gradle/GradleFacetImportTest.kt | 5 +- .../build.gradle | 7 + .../AbstractKotlinAndroidGradleTests.kt | 7 +- .../IncrementalCompilationMultiProjectIT.kt | 7 +- .../jetbrains/kotlin/gradle/Kapt3AndroidIT.kt | 7 +- .../android-extensions-idea/build.gradle.kts | 1 + .../android/AbstractParcelQuickFixTest.kt | 4 +- .../android/AbstractAndroidJpsTestCase.kt | 3 +- settings.gradle | 1 + update_dependencies.xml | 202 +----------------- 19 files changed, 184 insertions(+), 222 deletions(-) create mode 100644 custom-dependencies/android-sdk/build.gradle.kts diff --git a/buildSrc/src/main/kotlin/dependencies.kt b/buildSrc/src/main/kotlin/dependencies.kt index a246a4b6d4c..5d2da73cfba 100644 --- a/buildSrc/src/main/kotlin/dependencies.kt +++ b/buildSrc/src/main/kotlin/dependencies.kt @@ -2,10 +2,12 @@ import org.gradle.api.GradleException import org.gradle.api.Project -import org.gradle.api.artifacts.Dependency +import org.gradle.api.Task +import org.gradle.api.artifacts.Configuration import org.gradle.api.artifacts.ProjectDependency import org.gradle.api.artifacts.dsl.DependencyHandler import org.gradle.api.file.ConfigurableFileCollection +import org.gradle.kotlin.dsl.DependencyHandlerScope import org.gradle.kotlin.dsl.extra import org.gradle.kotlin.dsl.project import java.io.File @@ -97,3 +99,19 @@ fun firstFromJavaHomeThatExists(vararg paths: String): File? = paths.mapNotNull { File(jreHome, it).takeIf { it.exists() } }.firstOrNull() fun toolsJar(): File? = firstFromJavaHomeThatExists("../lib/tools.jar", "../Classes/tools.jar") + +private fun Task.addConfigurationAndProjectDependency(name: String, sourceProject: String, sourceConfiguration: String, sourceTask: String): Configuration { + dependsOn("$sourceProject:$sourceTask") + return project.configurations.findByName(name) // assuming that dependency is already added too + ?: project.configurations.create(name).also { + DependencyHandlerScope(project.dependencies).let { dh -> dh.add(name, dh.project(sourceProject, configuration = sourceConfiguration)) } + } +} + +fun Task.androidSdkPath(): String = + addConfigurationAndProjectDependency("androidSdk", ":custom-dependencies:android-sdk", "androidSdk", "prepareSdk") + .singleFile.canonicalPath + +fun Task.androidJarPath(): String = + addConfigurationAndProjectDependency("androidJar", ":custom-dependencies:android-sdk", "androidJar", "extractAndroidJar") + .singleFile.canonicalPath diff --git a/compiler/build.gradle.kts b/compiler/build.gradle.kts index abee1aca43b..df0875ff1ef 100644 --- a/compiler/build.gradle.kts +++ b/compiler/build.gradle.kts @@ -62,7 +62,7 @@ dependencies { testRuntime(projectDist(":kotlin-reflect")) testRuntime(projectDist(":kotlin-daemon-client")) - testRuntime(preloadedDeps("dx", subdir = "android-5.0/lib")) + testRuntime(project(":custom-dependencies:android-sdk", configuration = "dxJar")) testRuntime(files(toolsJar())) testJvm6ServerRuntime(projectTests(":compiler:tests-common-jvm6")) diff --git a/compiler/tests-common/build.gradle.kts b/compiler/tests-common/build.gradle.kts index 53979194b1b..7acad876e1c 100644 --- a/compiler/tests-common/build.gradle.kts +++ b/compiler/tests-common/build.gradle.kts @@ -29,7 +29,7 @@ dependencies { testCompile(projectTests(":compiler:tests-common-jvm6")) testCompileOnly(project(":kotlin-reflect-api")) testCompile(commonDep("junit:junit")) - testCompile(preloadedDeps("dx", subdir = "android-5.0/lib")) + testCompile(project(":custom-dependencies:android-sdk", configuration = "dxJar")) } afterEvaluate { diff --git a/compiler/tests-common/tests/org/jetbrains/kotlin/test/KotlinTestUtils.java b/compiler/tests-common/tests/org/jetbrains/kotlin/test/KotlinTestUtils.java index b33c424b023..c1e97f57c64 100644 --- a/compiler/tests-common/tests/org/jetbrains/kotlin/test/KotlinTestUtils.java +++ b/compiler/tests-common/tests/org/jetbrains/kotlin/test/KotlinTestUtils.java @@ -366,7 +366,27 @@ public class KotlinTestUtils { } public static File findAndroidApiJar() { - return new File(getHomeDirectory(), "dependencies/android.jar"); + String androidJarProp = System.getProperty("android.jar"); + File androidJarFile = androidJarProp == null ? null : new File(androidJarProp); + if (androidJarFile == null || !androidJarFile.isFile()) { + throw new RuntimeException( + "Unable to get a valid path from 'android.jar' property (" + + androidJarProp + + "), please point it to the 'android.jar' file location"); + } + return androidJarFile; + } + + public static File findAndroidSdk() { + String androidSdkProp = System.getProperty("android.sdk"); + File androidSdkDir = androidSdkProp == null ? null : new File(androidSdkProp); + if (androidSdkDir == null || !androidSdkDir.isDirectory()) { + throw new RuntimeException( + "Unable to get a valid path from 'android.sdk' property (" + + androidSdkProp + + "), please point it to the android SDK location"); + } + return androidSdkDir; } public static File getAnnotationsJar() { diff --git a/custom-dependencies/android-sdk/build.gradle.kts b/custom-dependencies/android-sdk/build.gradle.kts new file mode 100644 index 00000000000..1b2d9dd6ac3 --- /dev/null +++ b/custom-dependencies/android-sdk/build.gradle.kts @@ -0,0 +1,99 @@ + +import java.io.File + +// TODO: consider adding dx sources (the only jar used on the compile time so far) +// e.g. from "https://android.googlesource.com/platform/dalvik/+archive/android-5.0.0_r2/dx.tar.gz" + +repositories { + ivy { + artifactPattern("https://dl-ssl.google.com/android/repository/[artifact]-[revision].[ext]") + artifactPattern("https://dl-ssl.google.com/android/repository/[artifact]_[revision](-[classifier]).[ext]") + artifactPattern("https://dl.google.com/android/repository/[artifact]_[revision](-[classifier]).[ext]") + } +} + +val androidSdk by configurations.creating +val androidJar by configurations.creating +val dxJar by configurations.creating +val androidPlatform by configurations.creating +val buildTools by configurations.creating + +val libsDestDir = File(buildDir, "libs") +val sdkDestDir = File(buildDir, "androidSdk") + +data class LocMap(val name: String, val ver: String, val dest: String, val suffix: String, + val additionalConfig: Configuration? = null, val dirLevelsToSkit: Int = 0) + +val sdkLocMaps = listOf( + LocMap("platform", "26_r02", "platforms/android-26", "", androidPlatform, 1), + LocMap("android_m2repository", "r44", "extras/android", ""), + LocMap("platform-tools", "r25.0.3", "", "linux"), + LocMap("tools", "r24.3.4", "", "linux"), + LocMap("build-tools", "r23.0.1", "build-tools/23.0.1", "linux", buildTools, 1)) + + +val prepareSdk by task { + outputs.dir(sdkDestDir) + doLast {} +} + +fun LocMap.toDependency(): String = + "google:$name:$ver${suffix?.takeIf{ it.isNotEmpty() }?.let { ":$it" } ?: ""}@zip" + +sdkLocMaps.forEach { + val id = "${it.name}_${it.ver}" + val cfg = configurations.create(id) + val dependency = it.toDependency() + dependencies.add(cfg.name, dependency) + + val t = task("unzip_$id") { + afterEvaluate { + from(zipTree(cfg.singleFile)) + } + into(file("$sdkDestDir/${it.dest}")) + } + if (it.dirLevelsToSkit > 0) { + t.apply { + eachFile { + path = path.split("/").drop(it.dirLevelsToSkit).joinToString("/") + } + } + } + prepareSdk.dependsOn(t) + + it.additionalConfig?.also { + dependencies.add(it.name, dependency) + } +} + +val clean by task { + delete(buildDir) +} + +val extractAndroidJar by task { + configurations.add(androidJar) + afterEvaluate { + from(zipTree(androidPlatform.singleFile).matching { include("**/android.jar") }.files.first()) + } + into(libsDestDir) +} + +val extractDxJar by task { + configurations.add(dxJar) + afterEvaluate { + from(zipTree(buildTools.singleFile).matching { include("**/dx.jar") }.files.first()) + } + into(libsDestDir) +} + +artifacts.add(androidSdk.name, file("$sdkDestDir")) { + builtBy(prepareSdk) +} + +artifacts.add(androidJar.name, file("$libsDestDir/android.jar")) { + builtBy(extractAndroidJar) +} + +artifacts.add(dxJar.name, file("$libsDestDir/dx.jar")) { + builtBy(extractDxJar) +} diff --git a/idea/idea-android/build.gradle.kts b/idea/idea-android/build.gradle.kts index 48b3d93b03c..dc194521fb9 100644 --- a/idea/idea-android/build.gradle.kts +++ b/idea/idea-android/build.gradle.kts @@ -1,3 +1,4 @@ +import org.jetbrains.kotlin.gradle.tasks.KotlinCompile apply { plugin("kotlin") } @@ -18,7 +19,7 @@ dependencies { compile(project(":idea:ide-common")) compile(project(":idea:idea-gradle")) - compile(preloadedDeps("dx", subdir = "android-5.0/lib")) + compile(project(":custom-dependencies:android-sdk", configuration = "dxJar")) testCompile(projectDist(":kotlin-test:kotlin-test-jvm")) testCompile(project(":idea:idea-test-framework")) { isTransitive = false } @@ -56,8 +57,13 @@ sourceSets { "test" { projectDefault() } } +tasks.withType { + dependsOn(":custom-dependencies:android-sdk:extractDxJar") +} + projectTest { workingDir = rootDir + systemProperty("android.sdk", androidSdkPath()) } testsJar {} diff --git a/idea/idea-android/tests/org/jetbrains/kotlin/android/TestUtils.java b/idea/idea-android/tests/org/jetbrains/kotlin/android/TestUtils.java index 1d34458c91b..8e984c33b0f 100644 --- a/idea/idea-android/tests/org/jetbrains/kotlin/android/TestUtils.java +++ b/idea/idea-android/tests/org/jetbrains/kotlin/android/TestUtils.java @@ -19,6 +19,7 @@ package org.jetbrains.kotlin.android; import com.android.annotations.NonNull; import com.intellij.openapi.application.PathManager; +import org.jetbrains.kotlin.test.KotlinTestUtils; import java.io.File; @@ -29,7 +30,7 @@ import java.io.File; public class TestUtils { @NonNull public static File getSdk() { - return new File(PathManager.getHomePath() + "/../dependencies/androidSDK"); + return KotlinTestUtils.findAndroidSdk(); } @NonNull diff --git a/idea/idea-gradle/build.gradle.kts b/idea/idea-gradle/build.gradle.kts index c73b8cc2808..8a2b56aa01e 100644 --- a/idea/idea-gradle/build.gradle.kts +++ b/idea/idea-gradle/build.gradle.kts @@ -61,6 +61,7 @@ testsJar() projectTest { workingDir = rootDir + systemProperty("android.sdk", androidSdkPath()) } configureInstrumentation() diff --git a/idea/idea-gradle/tests/org/jetbrains/kotlin/gradle/MultiplatformProjectImportingTest.kt b/idea/idea-gradle/tests/org/jetbrains/kotlin/gradle/MultiplatformProjectImportingTest.kt index 297204c51d7..654430e91d6 100644 --- a/idea/idea-gradle/tests/org/jetbrains/kotlin/gradle/MultiplatformProjectImportingTest.kt +++ b/idea/idea-gradle/tests/org/jetbrains/kotlin/gradle/MultiplatformProjectImportingTest.kt @@ -22,6 +22,7 @@ import com.intellij.util.PathUtil import junit.framework.TestCase import org.jetbrains.kotlin.idea.codeInsight.gradle.GradleImportingTestCase import org.jetbrains.kotlin.idea.facet.KotlinFacet +import org.jetbrains.kotlin.test.KotlinTestUtils import org.junit.Test import java.io.File @@ -470,7 +471,7 @@ class MultiplatformProjectImportingTest : GradleImportingTestCase() { } """) createProjectSubFile("local.properties", """ - sdk.dir=/${StringUtil.escapeBackSlashes(File(homePath).parent + "/dependencies/androidSDK")} + sdk.dir=/${KotlinTestUtils.findAndroidSdk()} """) @@ -597,7 +598,7 @@ class MultiplatformProjectImportingTest : GradleImportingTestCase() { } """) createProjectSubFile("local.properties", """ - sdk.dir=/${StringUtil.escapeBackSlashes(File(homePath).parent + "/dependencies/androidSDK")} + sdk.dir=/${KotlinTestUtils.findAndroidSdk()} """) importProject() diff --git a/idea/idea-gradle/tests/org/jetbrains/kotlin/idea/codeInsight/gradle/GradleFacetImportTest.kt b/idea/idea-gradle/tests/org/jetbrains/kotlin/idea/codeInsight/gradle/GradleFacetImportTest.kt index 827f25c8e19..a8abcab0cf9 100644 --- a/idea/idea-gradle/tests/org/jetbrains/kotlin/idea/codeInsight/gradle/GradleFacetImportTest.kt +++ b/idea/idea-gradle/tests/org/jetbrains/kotlin/idea/codeInsight/gradle/GradleFacetImportTest.kt @@ -39,6 +39,7 @@ import org.jetbrains.kotlin.idea.framework.CommonLibraryKind import org.jetbrains.kotlin.idea.framework.JSLibraryKind import org.jetbrains.kotlin.idea.framework.KotlinSdkType import org.jetbrains.kotlin.idea.util.projectStructure.allModules +import org.jetbrains.kotlin.test.KotlinTestUtils import org.junit.Assert import org.junit.Test import java.io.File @@ -1108,7 +1109,7 @@ compileTestKotlin { include ':js-module' """) createProjectSubFile("local.properties", """ - sdk.dir=/${StringUtil.escapeBackSlashes(File(homePath).parent + "/dependencies/androidSDK")} + sdk.dir=/${KotlinTestUtils.findAndroidSdk()} """) importProject() @@ -1177,7 +1178,7 @@ compileTestKotlin { } """) createProjectSubFile("local.properties", """ - sdk.dir=/${StringUtil.escapeBackSlashes(File(homePath).parent + "/dependencies/androidSDK")} + sdk.dir=/${KotlinTestUtils.findAndroidSdk()} """) createProjectSubFile("src/main/AndroidManifest.xml", """ --> - - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -