From 528276d5b2a9469d8c869dd69750e73c96dd7584 Mon Sep 17 00:00:00 2001 From: technoir Date: Fri, 6 Sep 2019 16:13:46 +0100 Subject: [PATCH 1/3] Convert PluginTestHelper to Kotlin and move to test source set --- okreplay-gradle-plugin/build.gradle | 6 +- .../groovy/okreplay/PluginTestHelper.groovy | 91 ------------------- .../test/kotlin/okreplay/BasicAndroidTest.kt | 8 +- .../kotlin/okreplay/OkReplayPluginTest.kt | 12 +-- .../test/kotlin/okreplay/PluginTestHelper.kt | 80 ++++++++++++++++ .../buildScriptFixtures/settings.gradle | 0 6 files changed, 89 insertions(+), 108 deletions(-) delete mode 100644 okreplay-gradle-plugin/src/main/groovy/okreplay/PluginTestHelper.groovy create mode 100644 okreplay-gradle-plugin/src/test/kotlin/okreplay/PluginTestHelper.kt create mode 100644 okreplay-gradle-plugin/src/test/testProject/android/buildScriptFixtures/settings.gradle diff --git a/okreplay-gradle-plugin/build.gradle b/okreplay-gradle-plugin/build.gradle index 96ebb182..4e326fc9 100644 --- a/okreplay-gradle-plugin/build.gradle +++ b/okreplay-gradle-plugin/build.gradle @@ -1,15 +1,11 @@ apply plugin: 'org.jetbrains.kotlin.jvm' -apply plugin: 'groovy' apply plugin: 'java-gradle-plugin' sourceCompatibility = JavaVersion.VERSION_1_8 targetCompatibility = JavaVersion.VERSION_1_8 -sourceSets.main.groovy.srcDirs = ["src/main/groovy"] - dependencies { compileOnly gradleApi() - implementation localGroovy() implementation dep.androidPlugin implementation dep.kotlinStdLib implementation dep.ddmlib @@ -24,4 +20,4 @@ test { testLogging.showStandardStreams = isCi } -apply from: rootProject.file('gradle/gradle-mvn-push.gradle') \ No newline at end of file +apply from: rootProject.file('gradle/gradle-mvn-push.gradle') diff --git a/okreplay-gradle-plugin/src/main/groovy/okreplay/PluginTestHelper.groovy b/okreplay-gradle-plugin/src/main/groovy/okreplay/PluginTestHelper.groovy deleted file mode 100644 index b443f2c5..00000000 --- a/okreplay-gradle-plugin/src/main/groovy/okreplay/PluginTestHelper.groovy +++ /dev/null @@ -1,91 +0,0 @@ -package okreplay - -import org.apache.commons.io.FileUtils -import org.gradle.api.Project - -class PluginTestHelper { - static def setupDefaultAndroidProject(Project project) { - setupAndroidProject(project) - project.android { - compileSdkVersion 28 - buildToolsVersion "28.0.2" - } - } - - static def applyOkReplay(Project project) { - project.apply plugin: 'okreplay' - } - - static def evaluate(Project project) { - project.evaluate() - } - - static def androidHome() { - def envVar = System.getenv("ANDROID_HOME") - if (envVar) { - return envVar - } - File localPropFile = new File(new File(System.getProperty("user.dir")).parentFile, - "local.properties") - if (localPropFile.isFile()) { - Properties props = new Properties() - props.load(new FileInputStream(localPropFile)) - def sdkDir = props.getProperty("sdk.dir") - if (sdkDir) { - return sdkDir - } - throw IllegalStateException("SDK location not found. Define location with sdk.dir in the " + - "local.properties file or " + "with an ANDROID_HOME environment variable.") - } - } - - private static def setupAndroidProject(Project project) { - def localProperties = new File("${project.projectDir.absolutePath}", "local.properties") - localProperties.write("sdk.dir=${androidHome()}") - def manifest = new File("${project.projectDir.absolutePath}/src/main", "AndroidManifest.xml") - manifest.getParentFile().mkdirs() - manifest.createNewFile() - manifest.write("") - project.apply plugin: 'com.android.application' - project.repositories { - jcenter() - maven { url "https://oss.sonatype.org/content/repositories/snapshots" } - } - } - - static File createTempTestDirectory(String testProjectName) { - File dir = new File(System.getProperty("user.dir"), "build/inegrationTests/$testProjectName") - FileUtils.deleteDirectory(dir) - FileUtils.forceMkdir(dir) - return dir - } - - static void prepareProjectTestDir(File destDir, String testProjectName, - String testBuildScriptName) { - String testProjectsRoot = "src/test/testProject" - File projectTypeRoot = new File("$testProjectsRoot/android") - File projectUnderTest = new File(System.getProperty("user.dir"), - "$projectTypeRoot/$testProjectName") - if (!projectUnderTest.isDirectory()) { - throw new IllegalArgumentException("Couldn't find test project") - } - - File requestedBuildScript = new File( - "$projectTypeRoot/buildScriptFixtures/${testBuildScriptName}.gradle") - File requestedSettingsFile = new File( - "$projectTypeRoot/buildScriptFixtures/settings.gradle") - if (!requestedBuildScript.isFile()) { - throw new IllegalArgumentException("Couldn't find the test build script") - } - - prepareLocalProperties(destDir) - FileUtils.copyDirectory(projectUnderTest, destDir) - FileUtils.copyFile(requestedBuildScript, new File("$destDir/build.gradle")) - FileUtils.copyFile(requestedSettingsFile, new File("$destDir/settings.gradle")) - } - - static def prepareLocalProperties(File destDir) { - def localProperties = new File(destDir, "local.properties") - localProperties.write("sdk.dir=${androidHome()}") - } -} diff --git a/okreplay-gradle-plugin/src/test/kotlin/okreplay/BasicAndroidTest.kt b/okreplay-gradle-plugin/src/test/kotlin/okreplay/BasicAndroidTest.kt index 73471fa3..9db53c43 100644 --- a/okreplay-gradle-plugin/src/test/kotlin/okreplay/BasicAndroidTest.kt +++ b/okreplay-gradle-plugin/src/test/kotlin/okreplay/BasicAndroidTest.kt @@ -6,7 +6,6 @@ import org.gradle.testkit.runner.GradleRunner import org.gradle.testkit.runner.TaskOutcome import org.junit.Test import java.io.File -import java.io.IOException import java.io.OutputStreamWriter class BasicAndroidTest { @@ -41,10 +40,9 @@ class BasicAndroidTest { .build() } - @Throws(IOException::class) private fun setupBasicAndroidProject(dirName: String, buildScriptName: String = "basic"): File { - val destDir = PluginTestHelper.createTempTestDirectory(dirName) - PluginTestHelper.prepareProjectTestDir(destDir, dirName, buildScriptName) + val destDir = createTempTestDirectory(dirName) + prepareProjectTestDir(destDir, dirName, buildScriptName) return destDir } -} \ No newline at end of file +} diff --git a/okreplay-gradle-plugin/src/test/kotlin/okreplay/OkReplayPluginTest.kt b/okreplay-gradle-plugin/src/test/kotlin/okreplay/OkReplayPluginTest.kt index db7da102..020cc801 100644 --- a/okreplay-gradle-plugin/src/test/kotlin/okreplay/OkReplayPluginTest.kt +++ b/okreplay-gradle-plugin/src/test/kotlin/okreplay/OkReplayPluginTest.kt @@ -1,7 +1,6 @@ package okreplay import com.google.common.truth.Truth.assertThat -import okreplay.PluginTestHelper.* import org.gradle.api.Project import org.gradle.api.tasks.TaskExecutionException import org.gradle.testfixtures.ProjectBuilder @@ -45,11 +44,10 @@ class OkReplayPluginTest { } private fun prepareProject(): Project { - ProjectBuilder.builder().build().let { - setupDefaultAndroidProject(it) - applyOkReplay(it) - evaluate(it) - return it + return ProjectBuilder.builder().build().also { project -> + project.setupDefaultAndroidProject() + project.applyOkReplay() + project.evaluate() } } -} \ No newline at end of file +} diff --git a/okreplay-gradle-plugin/src/test/kotlin/okreplay/PluginTestHelper.kt b/okreplay-gradle-plugin/src/test/kotlin/okreplay/PluginTestHelper.kt new file mode 100644 index 00000000..179c3be2 --- /dev/null +++ b/okreplay-gradle-plugin/src/test/kotlin/okreplay/PluginTestHelper.kt @@ -0,0 +1,80 @@ +package okreplay + +import com.android.build.gradle.AppPlugin +import com.android.build.gradle.BaseExtension +import org.apache.commons.io.FileUtils +import org.gradle.api.Project +import org.gradle.api.internal.project.ProjectInternal +import java.io.File +import java.util.Properties + +fun Project.setupDefaultAndroidProject() { + prepareLocalProperties(projectDir) + + val manifest = File(projectDir, "src/main/AndroidManifest.xml") + manifest.parentFile.mkdirs() + manifest.writeText("") + pluginManager.apply(AppPlugin::class.java) + + val androidExtension = extensions.getByType(BaseExtension::class.java) + androidExtension.compileSdkVersion(28) +} + +fun Project.applyOkReplay() { + pluginManager.apply(OkReplayPlugin::class.java) +} + +fun Project.evaluate() { + (this as ProjectInternal).evaluate() +} + +fun createTempTestDirectory(testProjectName: String): File { + val dir = File(workingDir, "build/integrationTests/$testProjectName") + FileUtils.deleteDirectory(dir) + FileUtils.forceMkdir(dir) + return dir +} + +fun prepareProjectTestDir(destDir: File, testProjectName: String, testBuildScriptName: String) { + val testProjectsRoot = "src/test/testProject" + val projectTypeRoot = File("$testProjectsRoot/android") + val projectUnderTest = File(workingDir, "$projectTypeRoot/$testProjectName") + check(projectUnderTest.isDirectory) { "Couldn't find test project" } + + val requestedBuildScript = File( + "$projectTypeRoot/buildScriptFixtures/$testBuildScriptName.gradle") + val requestedSettingsFile = File( + "$projectTypeRoot/buildScriptFixtures/settings.gradle") + check(requestedBuildScript.isFile) { "Couldn't find the test build script" } + + prepareLocalProperties(destDir) + projectUnderTest.copyRecursively(destDir) + requestedBuildScript.copyTo(File(destDir, "build.gradle")) + requestedSettingsFile.copyTo(File(destDir, "settings.gradle")) +} + +private fun prepareLocalProperties(destDir: File) { + val localProperties = File(destDir, "local.properties") + localProperties.writeText("sdk.dir=${androidHome()}") +} + +private fun androidHome(): String { + val envVar = System.getenv("ANDROID_HOME") + if (envVar != null) { + return envVar + } + val localPropFile = File(workingDir.parentFile, "local.properties") + if (localPropFile.isFile) { + val props = Properties() + localPropFile.inputStream().use { props.load(it) } + val sdkDir = props.getProperty("sdk.dir") + if (sdkDir != null) { + return sdkDir + } + } + throw IllegalStateException("SDK location not found. Define location with sdk.dir in the " + + "local.properties file or with an ANDROID_HOME environment variable.") +} + +private val workingDir: File + get() = File(System.getProperty("user.dir")) diff --git a/okreplay-gradle-plugin/src/test/testProject/android/buildScriptFixtures/settings.gradle b/okreplay-gradle-plugin/src/test/testProject/android/buildScriptFixtures/settings.gradle new file mode 100644 index 00000000..e69de29b From c1511fcf3b4dd8599856229cf976e6b654f6d99c Mon Sep 17 00:00:00 2001 From: technoir Date: Fri, 6 Sep 2019 16:18:03 +0100 Subject: [PATCH 2/3] Change AGP and ddmlib to compileOnly instead of implementation This is to avoid pulling a higher version when OkReplay plugin is applied. --- okreplay-gradle-plugin/build.gradle | 6 ++++-- .../src/test/kotlin/okreplay/BasicAndroidTest.kt | 7 +++---- .../src/test/kotlin/okreplay/PluginTestHelper.kt | 13 ++++++++++++- .../android/buildScriptFixtures/basic.gradle | 7 +++---- 4 files changed, 22 insertions(+), 11 deletions(-) diff --git a/okreplay-gradle-plugin/build.gradle b/okreplay-gradle-plugin/build.gradle index 4e326fc9..639bb7f2 100644 --- a/okreplay-gradle-plugin/build.gradle +++ b/okreplay-gradle-plugin/build.gradle @@ -6,10 +6,12 @@ targetCompatibility = JavaVersion.VERSION_1_8 dependencies { compileOnly gradleApi() - implementation dep.androidPlugin + compileOnly dep.androidPlugin + compileOnly dep.ddmlib implementation dep.kotlinStdLib - implementation dep.ddmlib testImplementation gradleTestKit() + testImplementation dep.androidPlugin + testImplementation dep.ddmlib testImplementation dep.junit testImplementation dep.truth testImplementation dep.mockito diff --git a/okreplay-gradle-plugin/src/test/kotlin/okreplay/BasicAndroidTest.kt b/okreplay-gradle-plugin/src/test/kotlin/okreplay/BasicAndroidTest.kt index 9db53c43..ce0b2496 100644 --- a/okreplay-gradle-plugin/src/test/kotlin/okreplay/BasicAndroidTest.kt +++ b/okreplay-gradle-plugin/src/test/kotlin/okreplay/BasicAndroidTest.kt @@ -12,7 +12,7 @@ class BasicAndroidTest { @Test fun buildsAndPullsTapeFiles() { val testProjectDir = setupBasicAndroidProject("basic") val result = runGradleForProjectDir(testProjectDir, "connectedAndroidTest") - val clearTask = result!!.task(":clearDebugOkReplayTapes") + val clearTask = result.task(":clearDebugOkReplayTapes") val pullTask = result.task(":pullDebugOkReplayTapes") assertThat(clearTask).isNotNull() assertThat(pullTask).isNotNull() @@ -24,16 +24,15 @@ class BasicAndroidTest { @Test fun createsLocalTapesDirectoryIfNotExists() { val testProjectDir = setupBasicAndroidProject("notapes") val result = runGradleForProjectDir(testProjectDir, "pullDebugOkReplayTapes") - val pullTask = result!!.task(":pullDebugOkReplayTapes") + val pullTask = result.task(":pullDebugOkReplayTapes") assertThat(pullTask).isNotNull() assertThat(pullTask!!.outcome).isEqualTo(TaskOutcome.SUCCESS) assertThat(File(testProjectDir, "src/androidTest/assets/tapes").isDirectory).isTrue() } - private fun runGradleForProjectDir(projectDir: File, taskName: String): BuildResult? { + private fun runGradleForProjectDir(projectDir: File, taskName: String): BuildResult { return GradleRunner.create() .withProjectDir(projectDir) - .withPluginClasspath() .withArguments(taskName, "--stacktrace") .forwardStdError(OutputStreamWriter(System.err)) .forwardStdOutput(OutputStreamWriter(System.out)) diff --git a/okreplay-gradle-plugin/src/test/kotlin/okreplay/PluginTestHelper.kt b/okreplay-gradle-plugin/src/test/kotlin/okreplay/PluginTestHelper.kt index 179c3be2..a634ac5f 100644 --- a/okreplay-gradle-plugin/src/test/kotlin/okreplay/PluginTestHelper.kt +++ b/okreplay-gradle-plugin/src/test/kotlin/okreplay/PluginTestHelper.kt @@ -5,6 +5,7 @@ import com.android.build.gradle.BaseExtension import org.apache.commons.io.FileUtils import org.gradle.api.Project import org.gradle.api.internal.project.ProjectInternal +import org.gradle.testkit.runner.internal.PluginUnderTestMetadataReading import java.io.File import java.util.Properties @@ -49,8 +50,11 @@ fun prepareProjectTestDir(destDir: File, testProjectName: String, testBuildScrip prepareLocalProperties(destDir) projectUnderTest.copyRecursively(destDir) - requestedBuildScript.copyTo(File(destDir, "build.gradle")) requestedSettingsFile.copyTo(File(destDir, "settings.gradle")) + + val buildScript = requestedBuildScript.readText() + .replace("\$PLUGIN_CLASSPATH", getPluginClasspath()) + File(destDir, "build.gradle").writeText(buildScript) } private fun prepareLocalProperties(destDir: File) { @@ -76,5 +80,12 @@ private fun androidHome(): String { "local.properties file or with an ANDROID_HOME environment variable.") } +private fun getPluginClasspath(): String { + return PluginUnderTestMetadataReading.readImplementationClasspath() + .asSequence() + .map { it.absolutePath.replace("\\", "\\\\") } // escape backslashes on Windows + .joinToString(", ") { "'$it'" } +} + private val workingDir: File get() = File(System.getProperty("user.dir")) diff --git a/okreplay-gradle-plugin/src/test/testProject/android/buildScriptFixtures/basic.gradle b/okreplay-gradle-plugin/src/test/testProject/android/buildScriptFixtures/basic.gradle index 7f1c1766..466df71f 100644 --- a/okreplay-gradle-plugin/src/test/testProject/android/buildScriptFixtures/basic.gradle +++ b/okreplay-gradle-plugin/src/test/testProject/android/buildScriptFixtures/basic.gradle @@ -8,13 +8,12 @@ buildscript { dependencies { classpath dep.androidPlugin + classpath files($PLUGIN_CLASSPATH) } } -plugins { - id 'com.android.application' - id 'okreplay' -} +apply plugin: 'com.android.application' +apply plugin: 'okreplay' android { compileSdkVersion androidConfig.compileSdkVersion From 95775b9c4a21940f03c138493606a28826bad55b Mon Sep 17 00:00:00 2001 From: technoir Date: Fri, 6 Sep 2019 17:49:35 +0100 Subject: [PATCH 3/3] Remove no longer used function --- .../src/main/kotlin/okreplay/OkReplayPlugin.kt | 9 --------- 1 file changed, 9 deletions(-) diff --git a/okreplay-gradle-plugin/src/main/kotlin/okreplay/OkReplayPlugin.kt b/okreplay-gradle-plugin/src/main/kotlin/okreplay/OkReplayPlugin.kt index 56163af4..43360b49 100644 --- a/okreplay-gradle-plugin/src/main/kotlin/okreplay/OkReplayPlugin.kt +++ b/okreplay-gradle-plugin/src/main/kotlin/okreplay/OkReplayPlugin.kt @@ -2,8 +2,6 @@ package okreplay import com.android.build.gradle.* import com.android.build.gradle.api.BaseVariant -import com.android.build.gradle.internal.scope.GlobalScope -import com.android.build.gradle.internal.variant.BaseVariantData import org.gradle.api.Plugin import org.gradle.api.Project import org.gradle.api.Task @@ -77,13 +75,6 @@ class OkReplayPlugin } } - private fun BaseVariant.globalScope(): GlobalScope { - val getVariantData = this.javaClass.getDeclaredMethod("getVariantData") - getVariantData.isAccessible = true - val variantData = getVariantData.invoke(this) as BaseVariantData - return variantData.scope.globalScope - } - // TODO: Make this configurable from the plugin extension script companion object { const val LOCAL_TAPES_DIR = "src/androidTest/assets/tapes"