Skip to content

Commit c0c8d52

Browse files
author
Marcel Schnelle
authored
Add support for latest AGP 3.2.0 alpha versions (#70)
* Support changes to VariantType API in AGP 3.2.0-alpha06 * Update accessor for Java output directories for AGP 3.2.0-alpha04+06 support
1 parent 8aeae0d commit c0c8d52

File tree

7 files changed

+126
-25
lines changed

7 files changed

+126
-25
lines changed

android-junit5-tests/src/test/kotlin/de/mannodermaus/gradle/plugins/junit5/PluginSpec.kt

Lines changed: 29 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -578,15 +578,36 @@ class PluginSpec : Spek({
578578
context("using custom exclusion rules") {
579579
val project by memoized { testProjectBuilder.build() }
580580

581-
// Create some fake class files to verify the Jacoco tree
581+
// Create some fake files to verify the Jacoco tree
582582
beforeEachTest {
583-
project.file("build/intermediates/classes/debug").mkdirs()
584-
project.file("build/intermediates/classes/debug/R.class").createNewFile()
585-
project.file("build/intermediates/classes/debug/FirstFile.class").createNewFile()
586-
project.file("build/intermediates/classes/debug/SecondFile.class").createNewFile()
587-
project.file("build/intermediates/classes/release").mkdirs()
588-
project.file("build/intermediates/classes/release/R.class").createNewFile()
589-
project.file("build/intermediates/classes/release/SecondFile.class").createNewFile()
583+
// Since the location of intermediate class files changed in different
584+
// versions of the Android Gradle Plugin,
585+
// create each class file in multiple directories to remain compatible with all approaches
586+
listOf(
587+
// AGP 3.2.0-alpha06 and above
588+
"build/intermediates/artifact_transform/compileDebugJavaWithJavac/classes",
589+
// AGP 3.2.0-alpha04 and above
590+
"build/intermediates/artifact_transform/javac/debug/classes",
591+
// Everything below
592+
"build/intermediates/classes/debug").forEach { folder ->
593+
project.file(folder).mkdirs()
594+
project.file("$folder/R.class").createNewFile()
595+
project.file("$folder/FirstFile.class").createNewFile()
596+
project.file("$folder/SecondFile.class").createNewFile()
597+
}
598+
599+
listOf(
600+
// AGP 3.2.0-alpha06 and above
601+
"build/intermediates/artifact_transform/compileReleaseJavaWithJavac/classes",
602+
// AGP 3.2.0-alpha04 and above
603+
"build/intermediates/artifact_transform/javac/release/classes",
604+
// Everything below
605+
"build/intermediates/classes/release").forEach { folder ->
606+
project.file(folder).mkdirs()
607+
project.file("$folder/R.class").createNewFile()
608+
project.file("$folder/SecondFile.class").createNewFile()
609+
}
610+
590611
project.file("src/main/java").mkdirs()
591612
project.file("src/main/java/OkFile.java").createNewFile()
592613
project.file("src/main/java/AnnoyingFile.java").createNewFile()

android-junit5/build.gradle

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,9 +79,14 @@ dependencies {
7979
implementation "org.codehaus.groovy:groovy:$GROOVY_VERSION"
8080
implementation "org.jetbrains.kotlin:kotlin-stdlib:$KOTLIN_VERSION"
8181

82-
// Dependent Plugins
82+
// Other Dependencies
83+
implementation "com.annimon:stream:$STREAMS_BACKPORT_VERSION"
84+
85+
// JUnit Platform
8386
implementation "org.junit.platform:junit-platform-console:$JUNIT_PLATFORM_VERSION"
8487
implementation "org.junit.platform:junit-platform-commons:$JUNIT_PLATFORM_VERSION"
88+
89+
// Dependent Plugins
8590
implementation "com.android.tools.build:gradle:$ANDROID_PLUGIN_VERSION"
8691
compileOnly "org.jetbrains.kotlin:kotlin-gradle-plugin:$KOTLIN_VERSION"
8792
}

android-junit5/src/main/groovy/de/mannodermaus/gradle/plugins/junit5/GroovyInterop.groovy

Lines changed: 74 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,20 +4,43 @@ import com.android.annotations.NonNull
44
import com.android.build.gradle.api.BaseVariant
55
import com.android.build.gradle.internal.scope.VariantScope
66
import com.android.build.gradle.internal.variant.BaseVariantData
7+
import com.annimon.stream.Optional
78

89
/**
910
* Utility functions exposed to Kotlin consumers
10-
* that can't safely access Groovy members otherwise.*/
11+
* that can't safely access Groovy members otherwise,
12+
* or require reflection to access in a compatible manner
13+
* across all supported versions of the Android Gradle Plugin.*/
1114
class GroovyInterop {
1215

16+
// Access to UNIT_TEST was moved from VariantType to VariantTypeImpl in AGP 3.2.0-alpha06
17+
private static final def VariantType =
18+
reflectiveClass("com.android.builder.core.VariantTypeImpl")
19+
.or { reflectiveClass("com.android.builder.core.VariantType") }
20+
// Java outputs are accessed through this enum in AGP 3.2.0-alpha02
21+
private static final def InternalArtifactType =
22+
reflectiveClass("com.android.build.gradle.internal.scope.InternalArtifactType")
23+
1324
// No instances
1425
private GroovyInterop() { throw new AssertionError() }
1526

27+
/**
28+
* Attempts to look up a Class based on its FQCN, returns an empty Optional if this fails
29+
* @param fqcn Fully qualified class name
30+
* @return The class, or an empty Optional
31+
*/
32+
private static Optional<Class> reflectiveClass(String fqcn) {
33+
try {
34+
return Optional.of(Class.forName(fqcn))
35+
} catch (ignored) {
36+
return Optional.empty()
37+
}
38+
}
39+
1640
/**
1741
* Obtains the VariantData of the provided Variant.
18-
* BaseVariant#variantData is protected
19-
* and can't be accessed through Kotlin directly.
2042
*
43+
* @because 'BaseVariant.variantData' is protected and can't be accessed through Kotlin directly
2144
* @param variant Variant to retrieve the scope of
2245
* @return The scope
2346
*/
@@ -28,18 +51,60 @@ class GroovyInterop {
2851

2952
/**
3053
* Obtains the Java output directory of the provided VariantScope in a safe manner.
31-
* In Android Gradle Plugin 3.2.0-alpha02, the original method was removed.
3254
*
55+
* @because In Android Gradle Plugin 3.2.0-alpha02, the original method was removed
3356
* @param variant VariantScope to retrieve the Java output directory from
3457
* @return That file
3558
*/
3659
@NonNull
37-
static File variantScope_javaOutputDir(VariantScope scope) {
38-
if (scope.hasProperty("javaOutputDir")) {
39-
return scope.javaOutputDir
60+
static Set<File> variantScope_javaOutputDirs(VariantScope scope) {
61+
if (scope.hasProperty("buildArtifactsHolder") && InternalArtifactType.isPresent()) {
62+
def artifactType = InternalArtifactType
63+
.map { it.getDeclaredField("JAVAC").get(null) }
64+
.get()
65+
if (scope.buildArtifactsHolder.hasArtifact(artifactType)) {
66+
// 3.2.0-alpha04 and above:
67+
// Java outputs are moved into an "artifacts_transform" subdirectory
68+
return scope.buildArtifactsHolder.getArtifactFiles(artifactType).files
69+
} else {
70+
// 3.2.0-alpha02 and above:
71+
// Java outputs are still inside the "intermediates/classes" directory,
72+
// but there is no public API for that, so construct the path yourself
73+
return [new File(scope.globalScope.intermediatesDir,
74+
"/classes/" + scope.variantConfiguration.dirName)]
75+
}
4076
} else {
41-
return new File(scope.globalScope.intermediatesDir,
42-
"/classes/" + scope.variantConfiguration.dirName)
77+
// Below 3.2.0-alpha02:
78+
// Java outputs are expressed through the javaOutputDir property
79+
return [scope.javaOutputDir]
4380
}
4481
}
82+
83+
/**
84+
* Obtains the task name prefix for Unit Test variants.
85+
*
86+
* @because In Android Gradle Plugin 3.2.0-alpha06, the underlying constants on VariantType were renamed
87+
* @return The unit test prefix
88+
*/
89+
@NonNull
90+
static String variantType_unitTestPrefix() {
91+
return VariantType
92+
.map { it.getDeclaredField("UNIT_TEST").get(null) }
93+
.map { it.prefix }
94+
.orElseThrow { new IllegalArgumentException("can't get VariantType.UNIT_TEST.prefix") }
95+
}
96+
97+
/**
98+
* Obtains the task name suffix for Unit Test variants.
99+
*
100+
* @because In Android Gradle Plugin 3.2.0-alpha06, the underlying constants on VariantType were renamed
101+
* @return The unit test prefix
102+
*/
103+
@NonNull
104+
static String variantType_unitTestSuffix() {
105+
return VariantType
106+
.map { it.getDeclaredField("UNIT_TEST").get(null) }
107+
.map { it.suffix }
108+
.orElseThrow { new IllegalArgumentException("can't get VariantType.UNIT_TEST.suffix") }
109+
}
45110
}

android-junit5/src/main/kotlin/de/mannodermaus/gradle/plugins/junit5/Interop.kt

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,18 @@ import java.io.File
1616
val BaseVariant.variantData: BaseVariantData
1717
get() = GroovyInterop.baseVariant_variantData(this)
1818

19-
val VariantScope.safeJavaOutputDir: File
20-
get() = GroovyInterop.variantScope_javaOutputDir(this)
19+
val VariantScope.safeJavaOutputDirs: Set<File>
20+
get() = GroovyInterop.variantScope_javaOutputDirs(this)
2121

2222
/* Types */
2323

24+
class VariantTypeCompat {
25+
companion object {
26+
val UNIT_TEST_PREFIX = GroovyInterop.variantType_unitTestPrefix()
27+
val UNIT_TEST_SUFFIX = GroovyInterop.variantType_unitTestSuffix()
28+
}
29+
}
30+
2431
/**
2532
* Multi-language functional construct with no parameters,
2633
* mapped to Groovy's dynamic Closures as well as Kotlin's invoke syntax.

android-junit5/src/main/kotlin/de/mannodermaus/gradle/plugins/junit5/providers/Java.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ package de.mannodermaus.gradle.plugins.junit5.providers
22

33
import com.android.build.gradle.api.BaseVariant
44
import de.mannodermaus.gradle.plugins.junit5.internal.unitTestVariant
5-
import de.mannodermaus.gradle.plugins.junit5.safeJavaOutputDir
5+
import de.mannodermaus.gradle.plugins.junit5.safeJavaOutputDirs
66
import de.mannodermaus.gradle.plugins.junit5.variantData
77

88
/**
@@ -25,5 +25,5 @@ class JavaDirectoryProvider(private val variant: BaseVariant) : DirectoryProvide
2525
.toSet()
2626

2727
private fun classFoldersOf(variant: BaseVariant) =
28-
setOf(variant.variantData.scope.safeJavaOutputDir)
28+
variant.variantData.scope.safeJavaOutputDirs
2929
}

android-junit5/src/main/kotlin/de/mannodermaus/gradle/plugins/junit5/tasks/UnitTest.kt

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@ import com.android.build.gradle.api.BaseVariant
44
import com.android.build.gradle.internal.scope.TaskConfigAction
55
import com.android.build.gradle.internal.scope.VariantScope
66
import com.android.build.gradle.tasks.factory.AndroidUnitTest
7-
import com.android.builder.core.VariantType
87
import de.mannodermaus.gradle.plugins.junit5.AndroidJUnitPlatformExtension
98
import de.mannodermaus.gradle.plugins.junit5.JUnit5UnitTest
9+
import de.mannodermaus.gradle.plugins.junit5.VariantTypeCompat
1010
import de.mannodermaus.gradle.plugins.junit5.internal.android
1111
import de.mannodermaus.gradle.plugins.junit5.internal.junit5Info
1212
import de.mannodermaus.gradle.plugins.junit5.junitPlatform
@@ -138,7 +138,8 @@ open class AndroidJUnit5UnitTest : JavaExec(), JUnit5UnitTest {
138138
/* Private */
139139

140140
private fun getDefaultJUnit4Task(): AndroidUnitTest {
141-
val name = scope.getTaskName(VariantType.UNIT_TEST.prefix, VariantType.UNIT_TEST.suffix)
141+
val name = scope.getTaskName(VariantTypeCompat.UNIT_TEST_PREFIX,
142+
VariantTypeCompat.UNIT_TEST_SUFFIX)
142143
return project.tasks.getByName(name) as AndroidUnitTest
143144
}
144145

@@ -189,7 +190,8 @@ open class AndroidJUnit5UnitTest : JavaExec(), JUnit5UnitTest {
189190
variantUnitTestTask.dependsOn(task)
190191

191192
// Require that test classes are assembled first
192-
val defaultAssembleTestName = scope.getTaskName("assemble", VariantType.UNIT_TEST.suffix)
193+
val defaultAssembleTestName = scope.getTaskName("assemble",
194+
VariantTypeCompat.UNIT_TEST_SUFFIX)
193195
val defaultAssembleTask = project.tasks.getByName(defaultAssembleTestName)
194196
task.dependsOn(defaultAssembleTask)
195197

gradle.properties

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ TARGET_SDK_VERSION = 27
5858
SAMPLE_MIN_SDK_VERSION = 14
5959

6060
# Dependency versions
61+
STREAMS_BACKPORT_VERSION = 1.1.9
6162
JUNIT_PLATFORM_VERSION = 1.0.3
6263
JUNIT_JUPITER_VERSION = 5.0.3
6364
JUNIT_VINTAGE_VERSION = 4.12.2

0 commit comments

Comments
 (0)