From 28e999766e8c4227f73364731eeacc642b89af00 Mon Sep 17 00:00:00 2001 From: Paul Merlin Date: Sat, 18 Jan 2020 17:23:55 +0100 Subject: [PATCH 01/39] Introduce task to fetch/update latest AGP versions Signed-off-by: Paul Merlin --- build.gradle.kts | 7 ++ .../gradle/gradlebuild/UpdateAgpVersions.kt | 73 +++++++++++++++++++ 2 files changed, 80 insertions(+) create mode 100644 buildSrc/subprojects/plugins/src/main/kotlin/org/gradle/gradlebuild/UpdateAgpVersions.kt diff --git a/build.gradle.kts b/build.gradle.kts index 1544b03e7e24..4fc3705f0d0b 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -20,6 +20,7 @@ import org.gradle.gradlebuild.ProjectGroups.javaProjects import org.gradle.gradlebuild.ProjectGroups.kotlinJsProjects import org.gradle.gradlebuild.ProjectGroups.pluginProjects import org.gradle.gradlebuild.ProjectGroups.publicJavaProjects +import org.gradle.gradlebuild.UpdateAgpVersions import org.gradle.gradlebuild.UpdateBranchStatus import org.gradle.gradlebuild.buildquality.incubation.IncubatingApiAggregateReportTask import org.gradle.gradlebuild.buildquality.incubation.IncubatingApiReportTask @@ -382,6 +383,12 @@ tasks.register("installAll") { tasks.register("updateBranchStatus") +tasks.register("updateAgpVersions") { + comment.set(" Generated - Update by running `./gradlew updateAgpVersions`") + minimumSupportedMinor.set("3.4") + propertiesFile.set(layout.projectDirectory.file("gradle/dependency-management/agp-versions.properties")) +} + fun distributionImage(named: String) = project(":distributions").property(named) as CopySpec diff --git a/buildSrc/subprojects/plugins/src/main/kotlin/org/gradle/gradlebuild/UpdateAgpVersions.kt b/buildSrc/subprojects/plugins/src/main/kotlin/org/gradle/gradlebuild/UpdateAgpVersions.kt new file mode 100644 index 000000000000..1d8ba33a4911 --- /dev/null +++ b/buildSrc/subprojects/plugins/src/main/kotlin/org/gradle/gradlebuild/UpdateAgpVersions.kt @@ -0,0 +1,73 @@ +/* + * Copyright 2020 the original author or authors. + * + * 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.gradle.gradlebuild + +import org.gradle.api.DefaultTask +import org.gradle.api.file.RegularFileProperty +import org.gradle.api.provider.Property +import org.gradle.api.tasks.Internal +import org.gradle.api.tasks.TaskAction +import org.gradle.build.ReproduciblePropertiesWriter +import org.jsoup.Jsoup +import java.util.Properties + + +/** + * Fetch the latest AGP versions and write a properties file. + * Never up-to-date, non-cacheable. + */ +abstract class UpdateAgpVersions : DefaultTask() { + + @get:Internal + abstract val comment: Property + + @get:Internal + abstract val minimumSupportedMinor: Property + + @get:Internal + abstract val propertiesFile: RegularFileProperty + + @TaskAction + fun fetch() { + + val minimumSupported = minimumSupportedMinor.get() + + val url = "https://mvnrepository.com/artifact/com.android.tools.build/gradle?repo=google" + val body = Jsoup.connect(url).get().body() + val minorSets = body.select("table.grid.versions tbody") + + var latests = minorSets.map { it.select("a.vbtn").first().text() } + latests = (latests + minimumSupported).sorted() + latests = latests.subList(latests.indexOf(minimumSupported) + 1, latests.size) + + val nightlyUrl = "https://repo.gradle.org/gradle/ext-snapshots-local/com/android/tools/build/gradle/" + val nightly = Jsoup.connect(nightlyUrl).get().body() + .select("a") + .last { it.text().matches(Regex("^[0-9].*")) } + .text().dropLast(1) + + val properties = Properties().apply { + setProperty("latests", latests.joinToString(",")) + setProperty("nightly", nightly) + } + ReproduciblePropertiesWriter.store( + properties, + propertiesFile.get().asFile, + comment.get() + ) + } +} From 8d3e9d683dfc652ff487465cde6b73f5c554bcda Mon Sep 17 00:00:00 2001 From: Paul Merlin Date: Sat, 18 Jan 2020 17:27:36 +0100 Subject: [PATCH 02/39] Store latest AGP versions in properties file Signed-off-by: Paul Merlin --- gradle/dependency-management/agp-versions.properties | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 gradle/dependency-management/agp-versions.properties diff --git a/gradle/dependency-management/agp-versions.properties b/gradle/dependency-management/agp-versions.properties new file mode 100644 index 000000000000..4f236f90f05e --- /dev/null +++ b/gradle/dependency-management/agp-versions.properties @@ -0,0 +1,3 @@ +# Generated - Update by running `./gradlew updateAgpVersions` +latests=3.4.2,3.5.3,3.6.0-rc01,4.0.0-alpha08 +nightly=4.0.0-20200118155917+0100 From 72a3a7e9046692a0bd049791a9253aacd7d371da Mon Sep 17 00:00:00 2001 From: Paul Merlin Date: Sat, 18 Jan 2020 17:27:49 +0100 Subject: [PATCH 03/39] Let latest AGP versions be available in integ tests classpath Signed-off-by: Paul Merlin --- .../internal-integ-testing.gradle.kts | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/subprojects/internal-integ-testing/internal-integ-testing.gradle.kts b/subprojects/internal-integ-testing/internal-integ-testing.gradle.kts index 2fd8549d492e..73eef702e180 100644 --- a/subprojects/internal-integ-testing/internal-integ-testing.gradle.kts +++ b/subprojects/internal-integ-testing/internal-integ-testing.gradle.kts @@ -93,7 +93,15 @@ val prepareVersionsInfo = tasks.register("prepareVersionsIn mostRecentSnapshot = releasedVersions.mostRecentSnapshot } -sourceSets.main { output.dir(mapOf("builtBy" to prepareVersionsInfo), generatedResourcesDir) } +val copyAgpVersionsInfo by tasks.registering(Copy::class) { + from(rootProject.layout.projectDirectory.file("gradle/dependency-management/agp-versions.properties")) + into(temporaryDir) +} + +sourceSets.main { + output.dir(mapOf("builtBy" to prepareVersionsInfo), generatedResourcesDir) + output.dir(copyAgpVersionsInfo) +} @CacheableTask open class PrepareVersionsInfo : DefaultTask() { From c9b311cbf62338e9ec5ab244490bd28fc981d91f Mon Sep 17 00:00:00 2001 From: Paul Merlin Date: Sat, 18 Jan 2020 18:33:50 +0100 Subject: [PATCH 04/39] Use declared latest AGP versions in :instantExecution integ tests introducing required fixtures Signed-off-by: Paul Merlin --- ...tantExecutionAndroidIntegrationTest.groovy | 69 ++------- ...tantExecutionAndroidIntegrationTest.groovy | 20 ++- ...xecutionSantaTrackerIntegrationTest.groovy | 32 ++--- .../AndroidGradlePluginVersions.groovy | 131 ++++++++++++++++++ 4 files changed, 175 insertions(+), 77 deletions(-) create mode 100644 subprojects/internal-integ-testing/src/main/groovy/org/gradle/integtests/fixtures/versions/AndroidGradlePluginVersions.groovy diff --git a/subprojects/instant-execution/src/integTest/groovy/org/gradle/instantexecution/AbstractInstantExecutionAndroidIntegrationTest.groovy b/subprojects/instant-execution/src/integTest/groovy/org/gradle/instantexecution/AbstractInstantExecutionAndroidIntegrationTest.groovy index 2408a4e980e0..408043e3b26f 100644 --- a/subprojects/instant-execution/src/integTest/groovy/org/gradle/instantexecution/AbstractInstantExecutionAndroidIntegrationTest.groovy +++ b/subprojects/instant-execution/src/integTest/groovy/org/gradle/instantexecution/AbstractInstantExecutionAndroidIntegrationTest.groovy @@ -18,79 +18,40 @@ package org.gradle.instantexecution import groovy.transform.CompileStatic import org.gradle.integtests.fixtures.android.AndroidHome +import org.gradle.integtests.fixtures.versions.AndroidGradlePluginVersions import org.gradle.internal.scan.config.fixtures.GradleEnterprisePluginSettingsFixture import org.gradle.test.fixtures.file.TestFile -import static org.gradle.integtests.fixtures.RepoScriptBlockUtil.kotlinEapRepositoryDefinition +import static org.gradle.integtests.fixtures.versions.AndroidGradlePluginVersions.usingAgpVersion + /** * Base Android / Instant execution integration test. - * - * In order to iterate quickly on changes to AGP: - * - change `AGP_VERSION` to `4.0.0-dev` - * - change the repository url in `AGP_NIGHTLY_REPOSITORY_DECLARATION` to `file:///path/to/agp-src/out/repo` - * - run `./gradlew :publishAndroidGradleLocal` in `/path/to/agp-src/tools` */ @CompileStatic abstract class AbstractInstantExecutionAndroidIntegrationTest extends AbstractInstantExecutionIntegrationTest { - static final String AGP_VERSION = "4.0.0-20191217200145+0100" + private static final AndroidGradlePluginVersions agpVersions = new AndroidGradlePluginVersions() - static final String AGP_NIGHTLY_REPOSITORY_DECLARATION = ''' - maven { - name = 'agp-nightlies' - url = 'https://repo.gradle.org/gradle/ext-snapshots-local/' - } - ''' - - static final String AGP_NIGHTLY_REPOSITORY_INIT_SCRIPT = """ - allprojects { - buildscript { - repositories { - $AGP_NIGHTLY_REPOSITORY_DECLARATION - ${kotlinEapRepositoryDefinition()} - } - } - repositories { - $AGP_NIGHTLY_REPOSITORY_DECLARATION - ${kotlinEapRepositoryDefinition()} - } - } - """ + protected static final String[] testedAgpVersions = [ + agpVersions.getLatestAgpVersionsFromMinor("4.0"), + [agpVersions.latestNightly] + ].flatten() as String[] def setup() { AndroidHome.assumeIsSet() } - static String replaceAgpVersion(String scriptText, String agpVersion = AGP_VERSION) { - return scriptText.replaceAll( - "(['\"]com.android.tools.build:gradle:).+(['\"])", - "${'$'}1$agpVersion${'$'}2" - ) - } - - void withAgpNightly(String agpVersion = AGP_VERSION) { - withAgpNightly(buildFile, agpVersion) + void copyRemoteProject(String remoteProject) { + new TestFile(new File("build/$remoteProject")).copyTo(testDirectory) + GradleEnterprisePluginSettingsFixture.applyEnterprisePlugin(settingsFile) } - void withAgpNightly(TestFile buildFile, String agpVersion = AGP_VERSION) { - - println "> Using AGP nightly ${agpVersion}" - - // Inject AGP nightly repository - def init = file("gradle/agp-nightly.init.gradle") << AGP_NIGHTLY_REPOSITORY_INIT_SCRIPT - executer.beforeExecute { - withArgument("-I") - withArgument(init.path) - withArgument("-Pandroid.overrideVersionCheck=true") - } - - // Inject AGP nightly version - buildFile.text = replaceAgpVersion(buildFile.text, agpVersion) + void usingAgpVersion(String agpVersion) { + usingAgpVersion(executer, buildFile, agpVersion) } - void copyRemoteProject(String remoteProject) { - new TestFile(new File("build/$remoteProject")).copyTo(testDirectory) - GradleEnterprisePluginSettingsFixture.applyEnterprisePlugin(settingsFile) + void usingAgpVersion(TestFile buildFile, String agpVersion) { + usingAgpVersion(executer, buildFile, agpVersion) } } diff --git a/subprojects/instant-execution/src/integTest/groovy/org/gradle/instantexecution/InstantExecutionAndroidIntegrationTest.groovy b/subprojects/instant-execution/src/integTest/groovy/org/gradle/instantexecution/InstantExecutionAndroidIntegrationTest.groovy index b3ae5042abcc..eae67d5cea58 100644 --- a/subprojects/instant-execution/src/integTest/groovy/org/gradle/instantexecution/InstantExecutionAndroidIntegrationTest.groovy +++ b/subprojects/instant-execution/src/integTest/groovy/org/gradle/instantexecution/InstantExecutionAndroidIntegrationTest.groovy @@ -29,21 +29,24 @@ class InstantExecutionAndroidIntegrationTest extends AbstractInstantExecutionAnd def instantExecution + def buildScript = file("android-3.6-mini").file("build.gradle") + def setup() { executer.noDeprecationChecks() executer.withRepositoryMirrors() - def rootDir = file("android-3.6-mini") executer.beforeExecute { - inDirectory(rootDir) + inDirectory(buildScript.parentFile) } - withAgpNightly(rootDir.file("build.gradle")) instantExecution = newInstantExecutionFixture() } @Unroll - def "android 3.6 minimal build assembleDebug up-to-date (fromIde=#fromIde)"() { + def "android minimal build assembleDebug up-to-date (agp=#agpVersion, fromIde=#fromIde)"() { + + given: + usingAgpVersion(buildScript, agpVersion) when: instantRun("assembleDebug", "-Pandroid.injected.invoked.from.ide=$fromIde") @@ -58,11 +61,14 @@ class InstantExecutionAndroidIntegrationTest extends AbstractInstantExecutionAnd instantExecution.assertStateLoaded() where: - fromIde << [false, true] + [agpVersion, fromIde] << [testedAgpVersions, [false, true]].combinations() } @Unroll - def "android 3.6 minimal build clean assembleDebug (fromIde=#fromIde)"() { + def "android minimal build clean assembleDebug (agp=#agpVersion, fromIde=#fromIde)"() { + + given: + usingAgpVersion(buildScript, agpVersion) when: instantRun("assembleDebug", "-Pandroid.injected.invoked.from.ide=$fromIde") @@ -78,6 +84,6 @@ class InstantExecutionAndroidIntegrationTest extends AbstractInstantExecutionAnd instantExecution.assertStateLoaded() where: - fromIde << [false, true] + [agpVersion, fromIde] << [testedAgpVersions, [false, true]].combinations() } } diff --git a/subprojects/instant-execution/src/integTest/groovy/org/gradle/instantexecution/InstantExecutionSantaTrackerIntegrationTest.groovy b/subprojects/instant-execution/src/integTest/groovy/org/gradle/instantexecution/InstantExecutionSantaTrackerIntegrationTest.groovy index 4060850368f4..11cb6c94b682 100644 --- a/subprojects/instant-execution/src/integTest/groovy/org/gradle/instantexecution/InstantExecutionSantaTrackerIntegrationTest.groovy +++ b/subprojects/instant-execution/src/integTest/groovy/org/gradle/instantexecution/InstantExecutionSantaTrackerIntegrationTest.groovy @@ -34,11 +34,11 @@ class InstantExecutionSantaTrackerIntegrationTest extends AbstractInstantExecuti } @Unroll - def "assembleDebug up-to-date on Santa Tracker #flavor (fromIde=#fromIde)"() { + def "assembleDebug up-to-date on #remoteProject (agp=#agpVersion, fromIde=#fromIde)"() { given: copyRemoteProject(remoteProject) - withAgpNightly() + usingAgpVersion(agpVersion) when: instantRun("assembleDebug", "--no-build-cache", "-Pandroid.injected.invoked.from.ide=$fromIde") @@ -47,20 +47,20 @@ class InstantExecutionSantaTrackerIntegrationTest extends AbstractInstantExecuti instantRun("assembleDebug", "--no-build-cache", "-Pandroid.injected.invoked.from.ide=$fromIde") where: - flavor | remoteProject | fromIde - 'Java' | "santaTrackerJava" | false - 'Java' | "santaTrackerJava" | true - // TODO:instant-execution Kotlin 1.3.70 - // 'Kotlin' | "santaTrackerKotlin" | false - // 'Kotlin' | "santaTrackerKotlin" | true + [remoteProject, agpVersion, fromIde] << [ + // TODO:instant-execution Kotlin 1.3.70 + ["santaTrackerJava" /*, "santaTrackerKotlin" */], + testedAgpVersions, + [false, true] + ].combinations() } @Unroll - def "clean assembleDebug on Santa Tracker #flavor (fromIde=#fromIde)"() { + def "clean assembleDebug on #remoteProject (agp=#agpVersion, fromIde=#fromIde)"() { given: copyRemoteProject(remoteProject) - withAgpNightly() + usingAgpVersion(agpVersion) when: instantRun("assembleDebug", "--no-build-cache", "-Pandroid.injected.invoked.from.ide=$fromIde") @@ -73,11 +73,11 @@ class InstantExecutionSantaTrackerIntegrationTest extends AbstractInstantExecuti instantRun("assembleDebug", "--no-build-cache", "-Pandroid.injected.invoked.from.ide=$fromIde") where: - flavor | remoteProject | fromIde - 'Java' | "santaTrackerJava" | false - 'Java' | "santaTrackerJava" | true - // TODO:instant-execution Kotlin 1.3.70 - // 'Kotlin' | "santaTrackerKotlin" | false - // 'Kotlin' | "santaTrackerKotlin" | true + [remoteProject, agpVersion, fromIde] << [ + // TODO:instant-execution Kotlin 1.3.70 + ["santaTrackerJava" /*, "santaTrackerKotlin" */], + testedAgpVersions, + [false, true] + ].combinations() } } diff --git a/subprojects/internal-integ-testing/src/main/groovy/org/gradle/integtests/fixtures/versions/AndroidGradlePluginVersions.groovy b/subprojects/internal-integ-testing/src/main/groovy/org/gradle/integtests/fixtures/versions/AndroidGradlePluginVersions.groovy new file mode 100644 index 000000000000..fed64a23298d --- /dev/null +++ b/subprojects/internal-integ-testing/src/main/groovy/org/gradle/integtests/fixtures/versions/AndroidGradlePluginVersions.groovy @@ -0,0 +1,131 @@ +/* + * Copyright 2020 the original author or authors. + * + * 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.gradle.integtests.fixtures.versions + +import org.gradle.integtests.fixtures.executer.GradleExecuter +import org.gradle.internal.Factory +import org.gradle.test.fixtures.file.TestFile + + +/** + * Android Gradle Plugin Versions. + * + * If you need to iterate locally on changes to AGP sources: + * - hardcode latest nightly to `4.0.0-dev` + * - change the repository url in `AGP_NIGHTLY_REPOSITORY_DECLARATION` to `file:///path/to/agp-src/out/repo` + * - run `./gradlew :publishAndroidGradleLocal` in `/path/to/agp-src/tools` + */ +class AndroidGradlePluginVersions { + + private static final String AGP_NIGHTLY_REPOSITORY_DECLARATION = ''' + maven { + name = 'agp-nightlies' + url = 'https://repo.gradle.org/gradle/ext-snapshots-local/' + } + ''' + + private static final String AGP_NIGHTLY_REPOSITORY_INIT_SCRIPT = """ + allprojects { + buildscript { + repositories { + $AGP_NIGHTLY_REPOSITORY_DECLARATION + } + } + repositories { + $AGP_NIGHTLY_REPOSITORY_DECLARATION + } + } + """ + + static void usingAgpVersion(GradleExecuter executer, TestFile buildFile, String agpVersion) { + println "> Using AGP version ${agpVersion}" + buildFile.text = replaceAgpVersion(buildFile.text, agpVersion) + executer.beforeExecute { + withArgument("-Pandroid.overrideVersionCheck=true") + } + if (isNightly(agpVersion)) { + usingAgpNightlyRepository(executer) + } + } + + private static boolean isNightly(String agpVersion) { + return agpVersion.contains("-") && agpVersion.substring(agpVersion.indexOf("-") + 1).matches("^[0-9].*") + } + + static void usingAgpNightlyRepository(GradleExecuter executer) { + def init = createAgpNightlyRepositoryInitScript() + executer.beforeExecute { + usingInitScript(init) + } + } + + private static File createAgpNightlyRepositoryInitScript() { + File mirrors = File.createTempFile("mirrors", ".gradle") + mirrors.deleteOnExit() + mirrors << AGP_NIGHTLY_REPOSITORY_INIT_SCRIPT + return mirrors + } + + + private static String replaceAgpVersion(String scriptText, String agpVersion) { + return scriptText.replaceAll( + "(['\"]com.android.tools.build:gradle:).+(['\"])", + "${'$'}1$agpVersion${'$'}2" + ) + } + + private final Factory propertiesFactory + private Properties properties + + AndroidGradlePluginVersions() { + this(new ClasspathVersionSource("agp-versions.properties", AndroidGradlePluginVersions.classLoader)) + } + + private AndroidGradlePluginVersions(Factory propertiesFactory) { + this.propertiesFactory = propertiesFactory + } + + List getLatestAgpVersions() { + return getVersionList("latests") + } + + List getLatestAgpVersionsFromMinor(String lowerBound) { + assert lowerBound.matches("^[0-9]+\\.[0-9]+\$") + def latests = getLatestAgpVersions() + def withBound = (latests + lowerBound).sort() + return withBound.subList(withBound.indexOf(lowerBound) + 1, withBound.size()) + } + + String getLatestNightly() { + return getVersion("nightly") + } + + private List getVersionList(String name) { + return loadedProperties().getProperty(name).split(",") + } + + private String getVersion(String name) { + return loadedProperties().getProperty(name) + } + + private Properties loadedProperties() { + if (properties == null) { + properties = propertiesFactory.create() + } + return properties + } +} From 425163fc926f61c3e34be7969117364028874bb4 Mon Sep 17 00:00:00 2001 From: Paul Merlin Date: Sat, 18 Jan 2020 18:34:28 +0100 Subject: [PATCH 05/39] Use declared latest AGP versions in :smokeTest Signed-off-by: Paul Merlin --- .../groovy/org/gradle/smoketests/AbstractSmokeTest.groovy | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/subprojects/smoke-test/src/smokeTest/groovy/org/gradle/smoketests/AbstractSmokeTest.groovy b/subprojects/smoke-test/src/smokeTest/groovy/org/gradle/smoketests/AbstractSmokeTest.groovy index df7f727a97af..7d6051592def 100644 --- a/subprojects/smoke-test/src/smokeTest/groovy/org/gradle/smoketests/AbstractSmokeTest.groovy +++ b/subprojects/smoke-test/src/smokeTest/groovy/org/gradle/smoketests/AbstractSmokeTest.groovy @@ -22,6 +22,7 @@ import org.gradle.integtests.fixtures.RepoScriptBlockUtil import org.gradle.integtests.fixtures.executer.GradleContextualExecuter import org.gradle.integtests.fixtures.executer.InstantExecutionGradleExecuter import org.gradle.integtests.fixtures.executer.IntegrationTestBuildContext +import org.gradle.integtests.fixtures.versions.AndroidGradlePluginVersions import org.gradle.internal.featurelifecycle.LoggingDeprecatedFeatureHandler import org.gradle.test.fixtures.file.TestFile import org.gradle.testkit.runner.BuildResult @@ -37,6 +38,8 @@ import static org.gradle.test.fixtures.server.http.MavenHttpPluginRepository.PLU abstract class AbstractSmokeTest extends Specification { + private static final AndroidGradlePluginVersions agpVersions = new AndroidGradlePluginVersions() + static class TestedVersions { /** * May also need to update @@ -82,7 +85,7 @@ abstract class AbstractSmokeTest extends Specification { // https://developer.android.com/studio/releases/build-tools static androidTools = "29.0.2" // https://developer.android.com/studio/releases/gradle-plugin - static androidGradle = Versions.of("3.4.2", "3.5.3", "3.6.0-rc01", "4.0.0-alpha06") + static androidGradle = Versions.of(*agpVersions.latestAgpVersions) // https://search.maven.org/search?q=g:org.jetbrains.kotlin%20AND%20a:kotlin-project&core=gav static kotlin = Versions.of('1.3.21', '1.3.31', '1.3.41', '1.3.50', '1.3.61') From 435b4f6597712611c79633c523a5ad9824e7c439 Mon Sep 17 00:00:00 2001 From: Paul Merlin Date: Sat, 18 Jan 2020 23:04:38 +0100 Subject: [PATCH 06/39] Let :smokeTest exercise latest AGP nightly Signed-off-by: Paul Merlin --- .../AndroidGradlePluginVersions.groovy | 8 ++++++-- .../smoketests/AbstractSmokeTest.groovy | 4 ++-- .../smoketests/AndroidPluginsSmokeTest.groovy | 15 +++++++++++++-- .../smoketests/KotlinPluginSmokeTest.groovy | 19 ++++++++++++++++--- .../app/build.gradle.kts | 6 +++++- 5 files changed, 42 insertions(+), 10 deletions(-) diff --git a/subprojects/internal-integ-testing/src/main/groovy/org/gradle/integtests/fixtures/versions/AndroidGradlePluginVersions.groovy b/subprojects/internal-integ-testing/src/main/groovy/org/gradle/integtests/fixtures/versions/AndroidGradlePluginVersions.groovy index fed64a23298d..1b98ab32d1d6 100644 --- a/subprojects/internal-integ-testing/src/main/groovy/org/gradle/integtests/fixtures/versions/AndroidGradlePluginVersions.groovy +++ b/subprojects/internal-integ-testing/src/main/groovy/org/gradle/integtests/fixtures/versions/AndroidGradlePluginVersions.groovy @@ -62,7 +62,7 @@ class AndroidGradlePluginVersions { } } - private static boolean isNightly(String agpVersion) { + static boolean isNightly(String agpVersion) { return agpVersion.contains("-") && agpVersion.substring(agpVersion.indexOf("-") + 1).matches("^[0-9].*") } @@ -73,7 +73,7 @@ class AndroidGradlePluginVersions { } } - private static File createAgpNightlyRepositoryInitScript() { + static File createAgpNightlyRepositoryInitScript() { File mirrors = File.createTempFile("mirrors", ".gradle") mirrors.deleteOnExit() mirrors << AGP_NIGHTLY_REPOSITORY_INIT_SCRIPT @@ -114,6 +114,10 @@ class AndroidGradlePluginVersions { return getVersion("nightly") } + List getLatestAgpVersionsIncludingNightly() { + return [getLatestAgpVersions(), [getLatestNightly()]].flatten() + } + private List getVersionList(String name) { return loadedProperties().getProperty(name).split(",") } diff --git a/subprojects/smoke-test/src/smokeTest/groovy/org/gradle/smoketests/AbstractSmokeTest.groovy b/subprojects/smoke-test/src/smokeTest/groovy/org/gradle/smoketests/AbstractSmokeTest.groovy index 7d6051592def..96ef7a200711 100644 --- a/subprojects/smoke-test/src/smokeTest/groovy/org/gradle/smoketests/AbstractSmokeTest.groovy +++ b/subprojects/smoke-test/src/smokeTest/groovy/org/gradle/smoketests/AbstractSmokeTest.groovy @@ -38,7 +38,7 @@ import static org.gradle.test.fixtures.server.http.MavenHttpPluginRepository.PLU abstract class AbstractSmokeTest extends Specification { - private static final AndroidGradlePluginVersions agpVersions = new AndroidGradlePluginVersions() + protected static final AndroidGradlePluginVersions agpVersions = new AndroidGradlePluginVersions() static class TestedVersions { /** @@ -85,7 +85,7 @@ abstract class AbstractSmokeTest extends Specification { // https://developer.android.com/studio/releases/build-tools static androidTools = "29.0.2" // https://developer.android.com/studio/releases/gradle-plugin - static androidGradle = Versions.of(*agpVersions.latestAgpVersions) + static androidGradle = Versions.of(*agpVersions.latestAgpVersionsIncludingNightly) // https://search.maven.org/search?q=g:org.jetbrains.kotlin%20AND%20a:kotlin-project&core=gav static kotlin = Versions.of('1.3.21', '1.3.31', '1.3.41', '1.3.50', '1.3.61') diff --git a/subprojects/smoke-test/src/smokeTest/groovy/org/gradle/smoketests/AndroidPluginsSmokeTest.groovy b/subprojects/smoke-test/src/smokeTest/groovy/org/gradle/smoketests/AndroidPluginsSmokeTest.groovy index 8dba9e7af439..5b82138bfd1e 100644 --- a/subprojects/smoke-test/src/smokeTest/groovy/org/gradle/smoketests/AndroidPluginsSmokeTest.groovy +++ b/subprojects/smoke-test/src/smokeTest/groovy/org/gradle/smoketests/AndroidPluginsSmokeTest.groovy @@ -18,6 +18,7 @@ package org.gradle.smoketests import org.gradle.integtests.fixtures.ToBeFixedForInstantExecution import org.gradle.integtests.fixtures.android.AndroidHome +import org.gradle.testkit.runner.GradleRunner import org.gradle.testkit.runner.TaskOutcome import org.gradle.util.VersionNumber import spock.lang.Unroll @@ -84,6 +85,7 @@ class AndroidPluginsSmokeTest extends AbstractSmokeTest { when: def result = runner( + pluginVersion, 'androidDependencies', 'build', 'connectedAndroidTest', @@ -192,7 +194,7 @@ class AndroidPluginsSmokeTest extends AbstractSmokeTest { libraryBuildFile << activityDependency() when: - def result = runner('build', '-x', 'lint').build() + def result = runner(pluginVersion, 'build', '-x', 'lint').build() then: result.task(':app:assemble').outcome == TaskOutcome.SUCCESS @@ -205,7 +207,7 @@ class AndroidPluginsSmokeTest extends AbstractSmokeTest { when: 'abi change on library' writeActivity(library, libPackage, libraryActivity, true) - result = runner('build', '-x', 'lint').build() + result = runner(pluginVersion, 'build', '-x', 'lint').build() then: 'dependent sources are recompiled' result.task(':library:compileReleaseJavaWithJavac').outcome == TaskOutcome.SUCCESS @@ -215,6 +217,15 @@ class AndroidPluginsSmokeTest extends AbstractSmokeTest { pluginVersion << TestedVersions.androidGradle } + private GradleRunner runner(String agpVersion, String... tasks) { + def runner = super.runner(tasks) + if (agpVersions.isNightly(agpVersion)) { + def init = agpVersions.createAgpNightlyRepositoryInitScript() + runner.withArguments([runner.arguments, ["-I", init.canonicalPath]].flatten()) + } + return runner + } + private static String activityDependency() { """ dependencies { diff --git a/subprojects/smoke-test/src/smokeTest/groovy/org/gradle/smoketests/KotlinPluginSmokeTest.groovy b/subprojects/smoke-test/src/smokeTest/groovy/org/gradle/smoketests/KotlinPluginSmokeTest.groovy index 221ab161e6a7..7ea177c4e893 100644 --- a/subprojects/smoke-test/src/smokeTest/groovy/org/gradle/smoketests/KotlinPluginSmokeTest.groovy +++ b/subprojects/smoke-test/src/smokeTest/groovy/org/gradle/smoketests/KotlinPluginSmokeTest.groovy @@ -19,6 +19,7 @@ package org.gradle.smoketests import org.gradle.integtests.fixtures.ToBeFixedForInstantExecution import org.gradle.integtests.fixtures.android.AndroidHome import org.gradle.testkit.runner.BuildResult +import org.gradle.testkit.runner.GradleRunner import org.gradle.util.Requires import spock.lang.Unroll @@ -53,7 +54,7 @@ class KotlinPluginSmokeTest extends AbstractSmokeTest { @Unroll @ToBeFixedForInstantExecution - def 'kotlin #kotlinPluginVersion android #androidPluginVersion plugins, workers=#workers'() { + def '#sampleName kotlin #kotlinPluginVersion android #androidPluginVersion plugins, workers=#workers'() { given: AndroidHome.assertIsSet() useSample(sampleName) @@ -70,7 +71,7 @@ class KotlinPluginSmokeTest extends AbstractSmokeTest { } when: - def result = build(workers, 'clean', ':app:testDebugUnitTestCoverage') + def result = build(androidPluginVersion, workers, 'clean', ':app:testDebugUnitTestCoverage') then: result.task(':app:testDebugUnitTestCoverage').outcome == SUCCESS @@ -172,8 +173,20 @@ class KotlinPluginSmokeTest extends AbstractSmokeTest { } private BuildResult build(boolean workers, String... tasks) { + return runner(workers, *tasks).build() + } + + private BuildResult build(String agpVersion, boolean workers, String... tasks) { + def runner = runner(workers, *tasks) + if (agpVersions.isNightly(agpVersion)) { + def init = agpVersions.createAgpNightlyRepositoryInitScript() + runner.withArguments([runner.arguments, ["-I", init.canonicalPath]].flatten()) + } + return runner.build() + } + + private GradleRunner runner(boolean workers, String... tasks) { return runner(tasks + ["--parallel", "-Pkotlin.parallel.tasks.in.project=$workers"] as String[]) .forwardOutput() - .build() } } diff --git a/subprojects/smoke-test/src/smokeTest/resources/org/gradle/smoketests/android-kotlin-example-kotlin-dsl/app/build.gradle.kts b/subprojects/smoke-test/src/smokeTest/resources/org/gradle/smoketests/android-kotlin-example-kotlin-dsl/app/build.gradle.kts index 57da5cc488f2..7b680f97605a 100644 --- a/subprojects/smoke-test/src/smokeTest/resources/org/gradle/smoketests/android-kotlin-example-kotlin-dsl/app/build.gradle.kts +++ b/subprojects/smoke-test/src/smokeTest/resources/org/gradle/smoketests/android-kotlin-example-kotlin-dsl/app/build.gradle.kts @@ -46,7 +46,11 @@ android { getByName("androidTest").java.srcDir("src/androidTest/kotlin") } testOptions { - unitTests.isReturnDefaultValues = true + unitTests.withGroovyBuilder { + // AGP >= 4.0.0 exposes `returnDefaultValues` + // AGP < 4.0.0 exposes `isReturnDefaultValues + setProperty("returnDefaultValues", true) + } } kotlinOptions { jvmTarget = "1.8" From fd3634c0e4fbebb5b9917146299ce36bde214451 Mon Sep 17 00:00:00 2001 From: Paul Merlin Date: Sun, 19 Jan 2020 11:43:45 +0100 Subject: [PATCH 07/39] Refine AndroidGradlePluginVersions fixture and deduplicate AGP nightly handling in smoke tests Signed-off-by: Paul Merlin --- ...tantExecutionAndroidIntegrationTest.groovy | 5 +-- .../AndroidGradlePluginVersions.groovy | 33 ++++++++++--------- .../smoketests/AbstractSmokeTest.groovy | 10 +++++- .../smoketests/AndroidPluginsSmokeTest.groovy | 20 +++-------- .../smoketests/KotlinPluginSmokeTest.groovy | 11 +------ 5 files changed, 33 insertions(+), 46 deletions(-) diff --git a/subprojects/instant-execution/src/integTest/groovy/org/gradle/instantexecution/AbstractInstantExecutionAndroidIntegrationTest.groovy b/subprojects/instant-execution/src/integTest/groovy/org/gradle/instantexecution/AbstractInstantExecutionAndroidIntegrationTest.groovy index 408043e3b26f..9aeabed0da49 100644 --- a/subprojects/instant-execution/src/integTest/groovy/org/gradle/instantexecution/AbstractInstantExecutionAndroidIntegrationTest.groovy +++ b/subprojects/instant-execution/src/integTest/groovy/org/gradle/instantexecution/AbstractInstantExecutionAndroidIntegrationTest.groovy @@ -33,10 +33,7 @@ abstract class AbstractInstantExecutionAndroidIntegrationTest extends AbstractIn private static final AndroidGradlePluginVersions agpVersions = new AndroidGradlePluginVersions() - protected static final String[] testedAgpVersions = [ - agpVersions.getLatestAgpVersionsFromMinor("4.0"), - [agpVersions.latestNightly] - ].flatten() as String[] + protected static final String[] testedAgpVersions = agpVersions.getLatestsFromMinorPlusNightly("4.0") def setup() { AndroidHome.assumeIsSet() diff --git a/subprojects/internal-integ-testing/src/main/groovy/org/gradle/integtests/fixtures/versions/AndroidGradlePluginVersions.groovy b/subprojects/internal-integ-testing/src/main/groovy/org/gradle/integtests/fixtures/versions/AndroidGradlePluginVersions.groovy index 1b98ab32d1d6..6113f53a88f4 100644 --- a/subprojects/internal-integ-testing/src/main/groovy/org/gradle/integtests/fixtures/versions/AndroidGradlePluginVersions.groovy +++ b/subprojects/internal-integ-testing/src/main/groovy/org/gradle/integtests/fixtures/versions/AndroidGradlePluginVersions.groovy @@ -57,12 +57,12 @@ class AndroidGradlePluginVersions { executer.beforeExecute { withArgument("-Pandroid.overrideVersionCheck=true") } - if (isNightly(agpVersion)) { + if (isAgpNightly(agpVersion)) { usingAgpNightlyRepository(executer) } } - static boolean isNightly(String agpVersion) { + static boolean isAgpNightly(String agpVersion) { return agpVersion.contains("-") && agpVersion.substring(agpVersion.indexOf("-") + 1).matches("^[0-9].*") } @@ -80,12 +80,10 @@ class AndroidGradlePluginVersions { return mirrors } - private static String replaceAgpVersion(String scriptText, String agpVersion) { - return scriptText.replaceAll( - "(['\"]com.android.tools.build:gradle:).+(['\"])", - "${'$'}1$agpVersion${'$'}2" - ) + def regex = "(['\"]com.android.tools.build:gradle:).+(['\"])" + scriptText.readLines().any { it.matches(".*${regex}.*") } + return scriptText.replaceAll(regex, "${'$'}1$agpVersion${'$'}2") } private final Factory propertiesFactory @@ -99,23 +97,26 @@ class AndroidGradlePluginVersions { this.propertiesFactory = propertiesFactory } - List getLatestAgpVersions() { + List getLatests() { return getVersionList("latests") } - List getLatestAgpVersionsFromMinor(String lowerBound) { + String getNightly() { + return getVersion("nightly") + } + + List getLatestsPlusNightly() { + return [latests, [nightly]].flatten() as List + } + + List getLatestsFromMinor(String lowerBound) { assert lowerBound.matches("^[0-9]+\\.[0-9]+\$") - def latests = getLatestAgpVersions() def withBound = (latests + lowerBound).sort() return withBound.subList(withBound.indexOf(lowerBound) + 1, withBound.size()) } - String getLatestNightly() { - return getVersion("nightly") - } - - List getLatestAgpVersionsIncludingNightly() { - return [getLatestAgpVersions(), [getLatestNightly()]].flatten() + List getLatestsFromMinorPlusNightly(String lowerBound) { + return [getLatestsFromMinor(lowerBound), [nightly]].flatten() as List } private List getVersionList(String name) { diff --git a/subprojects/smoke-test/src/smokeTest/groovy/org/gradle/smoketests/AbstractSmokeTest.groovy b/subprojects/smoke-test/src/smokeTest/groovy/org/gradle/smoketests/AbstractSmokeTest.groovy index 96ef7a200711..1930cbbf1b94 100644 --- a/subprojects/smoke-test/src/smokeTest/groovy/org/gradle/smoketests/AbstractSmokeTest.groovy +++ b/subprojects/smoke-test/src/smokeTest/groovy/org/gradle/smoketests/AbstractSmokeTest.groovy @@ -85,7 +85,7 @@ abstract class AbstractSmokeTest extends Specification { // https://developer.android.com/studio/releases/build-tools static androidTools = "29.0.2" // https://developer.android.com/studio/releases/gradle-plugin - static androidGradle = Versions.of(*agpVersions.latestAgpVersionsIncludingNightly) + static androidGradle = Versions.of(*agpVersions.latestsPlusNightly) // https://search.maven.org/search?q=g:org.jetbrains.kotlin%20AND%20a:kotlin-project&core=gav static kotlin = Versions.of('1.3.21', '1.3.31', '1.3.41', '1.3.50', '1.3.61') @@ -222,6 +222,14 @@ abstract class AbstractSmokeTest extends Specification { FileUtils.copyDirectory(smokeTestDirectory, testProjectDir.root) } + protected GradleRunner useAgpVersion(String agpVersion, GradleRunner runner) { + if (agpVersions.isAgpNightly(agpVersion)) { + def init = agpVersions.createAgpNightlyRepositoryInitScript() + runner.withArguments([runner.arguments, ["-I", init.canonicalPath]].flatten()) + } + return runner + } + protected void replaceVariablesInBuildFile(Map binding) { replaceVariablesInFile(binding, buildFile) } diff --git a/subprojects/smoke-test/src/smokeTest/groovy/org/gradle/smoketests/AndroidPluginsSmokeTest.groovy b/subprojects/smoke-test/src/smokeTest/groovy/org/gradle/smoketests/AndroidPluginsSmokeTest.groovy index 5b82138bfd1e..52827de03db6 100644 --- a/subprojects/smoke-test/src/smokeTest/groovy/org/gradle/smoketests/AndroidPluginsSmokeTest.groovy +++ b/subprojects/smoke-test/src/smokeTest/groovy/org/gradle/smoketests/AndroidPluginsSmokeTest.groovy @@ -18,7 +18,6 @@ package org.gradle.smoketests import org.gradle.integtests.fixtures.ToBeFixedForInstantExecution import org.gradle.integtests.fixtures.android.AndroidHome -import org.gradle.testkit.runner.GradleRunner import org.gradle.testkit.runner.TaskOutcome import org.gradle.util.VersionNumber import spock.lang.Unroll @@ -84,12 +83,12 @@ class AndroidPluginsSmokeTest extends AbstractSmokeTest { """.stripIndent() << androidPluginConfiguration() << activityDependency() when: - def result = runner( - pluginVersion, + def result = useAgpVersion(pluginVersion, runner( 'androidDependencies', 'build', 'connectedAndroidTest', - '-x', 'lint').build() + '-x', 'lint' + )).build() then: def pluginBaseVersion = VersionNumber.parse(pluginVersion).baseVersion @@ -194,7 +193,7 @@ class AndroidPluginsSmokeTest extends AbstractSmokeTest { libraryBuildFile << activityDependency() when: - def result = runner(pluginVersion, 'build', '-x', 'lint').build() + def result = useAgpVersion(pluginVersion, runner('build', '-x', 'lint')).build() then: result.task(':app:assemble').outcome == TaskOutcome.SUCCESS @@ -207,7 +206,7 @@ class AndroidPluginsSmokeTest extends AbstractSmokeTest { when: 'abi change on library' writeActivity(library, libPackage, libraryActivity, true) - result = runner(pluginVersion, 'build', '-x', 'lint').build() + result = useAgpVersion(pluginVersion, runner('build', '-x', 'lint')).build() then: 'dependent sources are recompiled' result.task(':library:compileReleaseJavaWithJavac').outcome == TaskOutcome.SUCCESS @@ -217,15 +216,6 @@ class AndroidPluginsSmokeTest extends AbstractSmokeTest { pluginVersion << TestedVersions.androidGradle } - private GradleRunner runner(String agpVersion, String... tasks) { - def runner = super.runner(tasks) - if (agpVersions.isNightly(agpVersion)) { - def init = agpVersions.createAgpNightlyRepositoryInitScript() - runner.withArguments([runner.arguments, ["-I", init.canonicalPath]].flatten()) - } - return runner - } - private static String activityDependency() { """ dependencies { diff --git a/subprojects/smoke-test/src/smokeTest/groovy/org/gradle/smoketests/KotlinPluginSmokeTest.groovy b/subprojects/smoke-test/src/smokeTest/groovy/org/gradle/smoketests/KotlinPluginSmokeTest.groovy index 7ea177c4e893..882ba1aac4db 100644 --- a/subprojects/smoke-test/src/smokeTest/groovy/org/gradle/smoketests/KotlinPluginSmokeTest.groovy +++ b/subprojects/smoke-test/src/smokeTest/groovy/org/gradle/smoketests/KotlinPluginSmokeTest.groovy @@ -71,7 +71,7 @@ class KotlinPluginSmokeTest extends AbstractSmokeTest { } when: - def result = build(androidPluginVersion, workers, 'clean', ':app:testDebugUnitTestCoverage') + def result = useAgpVersion(androidPluginVersion, runner(workers, 'clean', ':app:testDebugUnitTestCoverage')).build() then: result.task(':app:testDebugUnitTestCoverage').outcome == SUCCESS @@ -176,15 +176,6 @@ class KotlinPluginSmokeTest extends AbstractSmokeTest { return runner(workers, *tasks).build() } - private BuildResult build(String agpVersion, boolean workers, String... tasks) { - def runner = runner(workers, *tasks) - if (agpVersions.isNightly(agpVersion)) { - def init = agpVersions.createAgpNightlyRepositoryInitScript() - runner.withArguments([runner.arguments, ["-I", init.canonicalPath]].flatten()) - } - return runner.build() - } - private GradleRunner runner(boolean workers, String... tasks) { return runner(tasks + ["--parallel", "-Pkotlin.parallel.tasks.in.project=$workers"] as String[]) .forwardOutput() From 4290b0c1eddcadfd745aea5d1a6d7b7566427aed Mon Sep 17 00:00:00 2001 From: Paul Merlin Date: Mon, 20 Jan 2020 10:50:27 +0100 Subject: [PATCH 08/39] Extract com.android.build.gradle.overrideVersionCheck Signed-off-by: Paul Merlin --- .../fixtures/versions/AndroidGradlePluginVersions.groovy | 4 +++- .../FasterIncrementalAndroidBuildsPerformanceTest.groovy | 3 ++- .../android/RealLifeAndroidBuildPerformanceTest.groovy | 3 ++- .../groovy/org/gradle/smoketests/AbstractSmokeTest.groovy | 5 +++-- .../org/gradle/smoketests/AndroidPluginsSmokeTest.groovy | 2 -- .../android-kotlin-example-kotlin-dsl/app/build.gradle.kts | 2 -- .../smoketests/android-kotlin-example/app/build.gradle | 2 -- 7 files changed, 10 insertions(+), 11 deletions(-) diff --git a/subprojects/internal-integ-testing/src/main/groovy/org/gradle/integtests/fixtures/versions/AndroidGradlePluginVersions.groovy b/subprojects/internal-integ-testing/src/main/groovy/org/gradle/integtests/fixtures/versions/AndroidGradlePluginVersions.groovy index 6113f53a88f4..d20e36d6ed97 100644 --- a/subprojects/internal-integ-testing/src/main/groovy/org/gradle/integtests/fixtures/versions/AndroidGradlePluginVersions.groovy +++ b/subprojects/internal-integ-testing/src/main/groovy/org/gradle/integtests/fixtures/versions/AndroidGradlePluginVersions.groovy @@ -31,6 +31,8 @@ import org.gradle.test.fixtures.file.TestFile */ class AndroidGradlePluginVersions { + public static final String OVERRIDE_VERSION_CHECK = '-Dcom.android.build.gradle.overrideVersionCheck=true' + private static final String AGP_NIGHTLY_REPOSITORY_DECLARATION = ''' maven { name = 'agp-nightlies' @@ -55,7 +57,7 @@ class AndroidGradlePluginVersions { println "> Using AGP version ${agpVersion}" buildFile.text = replaceAgpVersion(buildFile.text, agpVersion) executer.beforeExecute { - withArgument("-Pandroid.overrideVersionCheck=true") + withArgument(OVERRIDE_VERSION_CHECK) } if (isAgpNightly(agpVersion)) { usingAgpNightlyRepository(executer) diff --git a/subprojects/performance/src/performanceTest/groovy/org/gradle/performance/regression/android/FasterIncrementalAndroidBuildsPerformanceTest.groovy b/subprojects/performance/src/performanceTest/groovy/org/gradle/performance/regression/android/FasterIncrementalAndroidBuildsPerformanceTest.groovy index c32834d911aa..ec4d7f4f6d3e 100644 --- a/subprojects/performance/src/performanceTest/groovy/org/gradle/performance/regression/android/FasterIncrementalAndroidBuildsPerformanceTest.groovy +++ b/subprojects/performance/src/performanceTest/groovy/org/gradle/performance/regression/android/FasterIncrementalAndroidBuildsPerformanceTest.groovy @@ -16,6 +16,7 @@ package org.gradle.performance.regression.android +import org.gradle.integtests.fixtures.versions.AndroidGradlePluginVersions import org.gradle.internal.service.scopes.VirtualFileSystemServices import org.gradle.performance.AbstractCrossBuildPerformanceTest import org.gradle.performance.categories.PerformanceExperiment @@ -76,7 +77,7 @@ class FasterIncrementalAndroidBuildsPerformanceTest extends AbstractCrossBuildPe @Override protected void defaultSpec(BuildExperimentSpec.Builder builder) { if (builder instanceof GradleBuildExperimentSpec.GradleBuilder) { - builder.invocation.args('-Dcom.android.build.gradle.overrideVersionCheck=true') + builder.invocation.args(AndroidGradlePluginVersions.OVERRIDE_VERSION_CHECK) } } diff --git a/subprojects/performance/src/performanceTest/groovy/org/gradle/performance/regression/android/RealLifeAndroidBuildPerformanceTest.groovy b/subprojects/performance/src/performanceTest/groovy/org/gradle/performance/regression/android/RealLifeAndroidBuildPerformanceTest.groovy index bfc067d38ab3..2713b927d9bf 100644 --- a/subprojects/performance/src/performanceTest/groovy/org/gradle/performance/regression/android/RealLifeAndroidBuildPerformanceTest.groovy +++ b/subprojects/performance/src/performanceTest/groovy/org/gradle/performance/regression/android/RealLifeAndroidBuildPerformanceTest.groovy @@ -16,6 +16,7 @@ package org.gradle.performance.regression.android +import org.gradle.integtests.fixtures.versions.AndroidGradlePluginVersions import org.gradle.internal.scan.config.fixtures.GradleEnterprisePluginSettingsFixture import org.gradle.performance.AbstractCrossVersionGradleProfilerPerformanceTest import org.gradle.performance.categories.SlowPerformanceRegressionTest @@ -32,7 +33,7 @@ import static org.gradle.performance.regression.android.IncrementalAndroidTestPr class RealLifeAndroidBuildPerformanceTest extends AbstractCrossVersionGradleProfilerPerformanceTest { def setup() { - runner.args = ['-Dcom.android.build.gradle.overrideVersionCheck=true'] + runner.args = [AndroidGradlePluginVersions.OVERRIDE_VERSION_CHECK] runner.targetVersions = ["6.2-20200108160029+0000"] // AGP 3.6 requires 5.6.1+ // The enterprise plugin requires Gradle 6.0 diff --git a/subprojects/smoke-test/src/smokeTest/groovy/org/gradle/smoketests/AbstractSmokeTest.groovy b/subprojects/smoke-test/src/smokeTest/groovy/org/gradle/smoketests/AbstractSmokeTest.groovy index 1930cbbf1b94..facedc566943 100644 --- a/subprojects/smoke-test/src/smokeTest/groovy/org/gradle/smoketests/AbstractSmokeTest.groovy +++ b/subprojects/smoke-test/src/smokeTest/groovy/org/gradle/smoketests/AbstractSmokeTest.groovy @@ -223,11 +223,12 @@ abstract class AbstractSmokeTest extends Specification { } protected GradleRunner useAgpVersion(String agpVersion, GradleRunner runner) { + def extraArgs = [agpVersions.OVERRIDE_VERSION_CHECK] if (agpVersions.isAgpNightly(agpVersion)) { def init = agpVersions.createAgpNightlyRepositoryInitScript() - runner.withArguments([runner.arguments, ["-I", init.canonicalPath]].flatten()) + extraArgs += ["-I", init.canonicalPath] } - return runner + return runner.withArguments([runner.arguments, extraArgs].flatten()) } protected void replaceVariablesInBuildFile(Map binding) { diff --git a/subprojects/smoke-test/src/smokeTest/groovy/org/gradle/smoketests/AndroidPluginsSmokeTest.groovy b/subprojects/smoke-test/src/smokeTest/groovy/org/gradle/smoketests/AndroidPluginsSmokeTest.groovy index 52827de03db6..2b08aa01ca3b 100644 --- a/subprojects/smoke-test/src/smokeTest/groovy/org/gradle/smoketests/AndroidPluginsSmokeTest.groovy +++ b/subprojects/smoke-test/src/smokeTest/groovy/org/gradle/smoketests/AndroidPluginsSmokeTest.groovy @@ -234,8 +234,6 @@ class AndroidPluginsSmokeTest extends AbstractSmokeTest { classpath 'com.android.tools.build:gradle:${pluginVersion}' } } - - System.properties['com.android.build.gradle.overrideVersionCheck'] = 'true' """.stripIndent() } diff --git a/subprojects/smoke-test/src/smokeTest/resources/org/gradle/smoketests/android-kotlin-example-kotlin-dsl/app/build.gradle.kts b/subprojects/smoke-test/src/smokeTest/resources/org/gradle/smoketests/android-kotlin-example-kotlin-dsl/app/build.gradle.kts index 7b680f97605a..f1590b307806 100644 --- a/subprojects/smoke-test/src/smokeTest/resources/org/gradle/smoketests/android-kotlin-example-kotlin-dsl/app/build.gradle.kts +++ b/subprojects/smoke-test/src/smokeTest/resources/org/gradle/smoketests/android-kotlin-example-kotlin-dsl/app/build.gradle.kts @@ -21,8 +21,6 @@ plugins { id("jacoco") } -//System.properties["com.android.build.gradle.overrideVersionCheck"] = "true" - android { compileSdkVersion(24) buildToolsVersion("$androidBuildToolsVersion") diff --git a/subprojects/smoke-test/src/smokeTest/resources/org/gradle/smoketests/android-kotlin-example/app/build.gradle b/subprojects/smoke-test/src/smokeTest/resources/org/gradle/smoketests/android-kotlin-example/app/build.gradle index f94c5dbd9f7f..cff982f119c7 100644 --- a/subprojects/smoke-test/src/smokeTest/resources/org/gradle/smoketests/android-kotlin-example/app/build.gradle +++ b/subprojects/smoke-test/src/smokeTest/resources/org/gradle/smoketests/android-kotlin-example/app/build.gradle @@ -5,8 +5,6 @@ plugins { id 'jacoco' } -System.properties['com.android.build.gradle.overrideVersionCheck'] = 'true' - android { compileSdkVersion 24 buildToolsVersion '$androidBuildToolsVersion' From 5cea892d926355e3ea923f5b2e7890aa50ae7fd7 Mon Sep 17 00:00:00 2001 From: Paul Merlin Date: Mon, 20 Jan 2020 14:00:28 +0100 Subject: [PATCH 09/39] Rework Santa Tracker smoke tests So they exercise - all latests AGP versions >= 3.6 - both Kotlin and Java flavours of Santa Tracker Before this commit, the only tested AGP version was 3.6.0-beta04 After this commit, 3.6.0-rc01, 4.0.0-alpha08, 4.0.0- are tested Tests on the Java flavour of Santa do pass with instant execution Signed-off-by: Paul Merlin --- subprojects/smoke-test/smoke-test.gradle.kts | 18 +- ...bstractAndroidSantaTrackerSmokeTest.groovy | 96 + ...oidSantaTrackerJavaCachingSmokeTest.groovy | 852 +++++++++ ...dSantaTrackerKotlinCachingSmokeTest.groovy | 1694 +++++++++++++++++ .../AndroidSantaTrackerSmokeTest.groovy | 686 +------ 5 files changed, 2714 insertions(+), 632 deletions(-) create mode 100644 subprojects/smoke-test/src/smokeTest/groovy/org/gradle/smoketests/AbstractAndroidSantaTrackerSmokeTest.groovy create mode 100644 subprojects/smoke-test/src/smokeTest/groovy/org/gradle/smoketests/AndroidSantaTrackerJavaCachingSmokeTest.groovy create mode 100644 subprojects/smoke-test/src/smokeTest/groovy/org/gradle/smoketests/AndroidSantaTrackerKotlinCachingSmokeTest.groovy diff --git a/subprojects/smoke-test/smoke-test.gradle.kts b/subprojects/smoke-test/smoke-test.gradle.kts index 3bcf99e115cf..81cff6d091ae 100644 --- a/subprojects/smoke-test/smoke-test.gradle.kts +++ b/subprojects/smoke-test/smoke-test.gradle.kts @@ -113,12 +113,26 @@ plugins.withType().configureEach { // TODO Copied from instant-execution.gradle.kts, we should have one place to clone this thing and clone it from there locally when needed tasks { - register("santaTracker") { - remoteUri.set("https://github.com/gradle/santa-tracker-android.git") + /** + * Santa Tracker git URI. + * + * Note that you can change it to `file:///path/to/your/santa-tracker-clone/.git` + * if you need to iterate quickly on changes to Santa Tracker. + */ + val santaGitUri = "https://github.com/gradle/santa-tracker-android.git" + + register("santaTrackerKotlin") { + remoteUri.set(santaGitUri) // From branch agp-3.6.0 ref.set("3bbbd895de38efafd0dd1789454d4e4cb72d46d5") } + register("santaTrackerJava") { + remoteUri.set(santaGitUri) + // From agp-3.6.0-java branch + ref.set("174705275e434adc843e8e9b28106a5e3ffd6733") + } + register("gradleBuildCurrent") { remoteUri.set(rootDir.absolutePath) ref.set(rootProject.tasks.named("determineCommitId").flatMap { it.determinedCommitId }) diff --git a/subprojects/smoke-test/src/smokeTest/groovy/org/gradle/smoketests/AbstractAndroidSantaTrackerSmokeTest.groovy b/subprojects/smoke-test/src/smokeTest/groovy/org/gradle/smoketests/AbstractAndroidSantaTrackerSmokeTest.groovy new file mode 100644 index 000000000000..05869070c8c6 --- /dev/null +++ b/subprojects/smoke-test/src/smokeTest/groovy/org/gradle/smoketests/AbstractAndroidSantaTrackerSmokeTest.groovy @@ -0,0 +1,96 @@ +/* + * Copyright 2020 the original author or authors. + * + * 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.gradle.smoketests + +import org.gradle.integtests.fixtures.daemon.DaemonLogsAnalyzer +import org.gradle.integtests.fixtures.versions.AndroidGradlePluginVersions +import org.gradle.internal.scan.config.fixtures.GradleEnterprisePluginSettingsFixture +import org.gradle.test.fixtures.file.TestFile +import org.gradle.test.fixtures.file.TestNameTestDirectoryProvider +import org.gradle.testkit.runner.BuildResult +import org.gradle.testkit.runner.TaskOutcome +import org.gradle.testkit.runner.internal.ToolingApiGradleExecutor +import org.junit.Rule + + +class AbstractAndroidSantaTrackerSmokeTest extends AbstractSmokeTest { + + protected static final List testedAgpVersions = agpVersions.getLatestsFromMinorPlusNightly("3.6") + // protected static final List testedAgpVersions = [agpVersions.nightly] + + @Rule + TestNameTestDirectoryProvider temporaryFolder + TestFile homeDir + + def setup() { + homeDir = temporaryFolder.createDir("test-kit-home") + } + + def cleanup() { + // The daemons started by test kit need to be killed, so no locked files are left behind. + DaemonLogsAnalyzer.newAnalyzer(homeDir.file(ToolingApiGradleExecutor.TEST_KIT_DAEMON_DIR_NAME)).killAll() + } + + protected void setupCopyOfSantaTracker(TestFile targetDir, String flavour, String agpVersion = null) { + copyRemoteProject("santaTracker${flavour.capitalize()}", targetDir) + GradleEnterprisePluginSettingsFixture.applyEnterprisePlugin(targetDir.file("settings.gradle")) + if (agpVersion != null) { + def buildFile = targetDir.file("build.gradle") + buildFile.text = agpVersions.replaceAgpVersion(buildFile.text, agpVersion) + } + } + + protected BuildResult buildLocation(File projectDir, String agpVersion = null) { + def runner = runner("assembleDebug") + .withProjectDir(projectDir) + .withTestKitDir(homeDir) + .forwardOutput() + if (agpVersion != null && AndroidGradlePluginVersions.isAgpNightly(agpVersion)) { + def init = AndroidGradlePluginVersions.createAgpNightlyRepositoryInitScript() + runner.withArguments([runner.arguments, ['-I', init.canonicalPath]].flatten()) + } + runner.build() + } + + protected static boolean verify(BuildResult result, Map outcomes) { + println "> Expecting ${outcomes.size()} tasks with outcomes:" + outcomes.values().groupBy { it }.sort().forEach { outcome, instances -> println "> - $outcome: ${instances.size()}" } + + def outcomesWithMatchingTasks = outcomes.findAll { result.task(it.key) } + def hasMatchingTasks = outcomesWithMatchingTasks.size() == outcomes.size() && outcomesWithMatchingTasks.size() == result.tasks.size() + if (!hasMatchingTasks) { + println "> Tasks missing: " + (outcomes.findAll { !outcomesWithMatchingTasks.keySet().contains(it.key) }) + println "> Tasks in surplus: " + (result.tasks.findAll { !outcomesWithMatchingTasks.keySet().contains(it.path) }) + println "> Updated definitions:" + result.tasks + .toSorted { a, b -> a.path <=> b.path } + .forEach { task -> + println "'${task.path}': ${task.outcome}," + } + } + + boolean allOutcomesMatched = true + outcomesWithMatchingTasks.each { taskName, expectedOutcome -> + def taskOutcome = result.task(taskName)?.outcome + if (taskOutcome != expectedOutcome) { + println "> Task '$taskName' was $taskOutcome but should have been $expectedOutcome" + allOutcomesMatched = false + } + } + return hasMatchingTasks && allOutcomesMatched + } +} diff --git a/subprojects/smoke-test/src/smokeTest/groovy/org/gradle/smoketests/AndroidSantaTrackerJavaCachingSmokeTest.groovy b/subprojects/smoke-test/src/smokeTest/groovy/org/gradle/smoketests/AndroidSantaTrackerJavaCachingSmokeTest.groovy new file mode 100644 index 000000000000..53263ae2efc8 --- /dev/null +++ b/subprojects/smoke-test/src/smokeTest/groovy/org/gradle/smoketests/AndroidSantaTrackerJavaCachingSmokeTest.groovy @@ -0,0 +1,852 @@ +/* + * Copyright 2020 the original author or authors. + * + * 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.gradle.smoketests + +import org.gradle.testkit.runner.BuildResult +import org.gradle.util.Requires +import org.gradle.util.TestPrecondition +import spock.lang.Unroll + +import static org.gradle.testkit.runner.TaskOutcome.FROM_CACHE +import static org.gradle.testkit.runner.TaskOutcome.NO_SOURCE +import static org.gradle.testkit.runner.TaskOutcome.SUCCESS +import static org.gradle.testkit.runner.TaskOutcome.UP_TO_DATE + + +@Requires(TestPrecondition.JDK11_OR_EARLIER) +class AndroidSantaTrackerJavaCachingSmokeTest extends AbstractAndroidSantaTrackerSmokeTest { + + @Unroll + def "can cache Santa Tracker Java Android application (agp=#agpVersion)"() { + + given: + def originalDir = temporaryFolder.createDir("original") + def relocatedDir = temporaryFolder.createDir("relocated") + + and: + setupCopyOfSantaTracker(originalDir, 'Java', agpVersion) + setupCopyOfSantaTracker(relocatedDir, 'Java', agpVersion) + + when: + buildLocation(originalDir, agpVersion) + BuildResult relocatedResult = buildLocation(relocatedDir, agpVersion) + + then: + def expectedResults = agpVersion.startsWith('3.6') + ? EXPECTED_RESULTS_3_6 + : agpVersion.startsWith('4.0.0-alpha') + ? EXPECTED_RESULTS_4_0_ALPHA + : EXPECTED_RESULTS + verify(relocatedResult, expectedResults) + + where: + agpVersion << testedAgpVersions + } + + private static final EXPECTED_RESULTS = [ + ':common:assembleDebug': SUCCESS, + ':common:bundleDebugAar': SUCCESS, + ':common:bundleLibCompileToJarDebug': FROM_CACHE, + ':common:bundleLibResDebug': NO_SOURCE, + ':common:bundleLibRuntimeToJarDebug': FROM_CACHE, + ':common:compileDebugAidl': NO_SOURCE, + ':common:compileDebugJavaWithJavac': FROM_CACHE, + ':common:compileDebugLibraryResources': SUCCESS, + ':common:compileDebugRenderscript': NO_SOURCE, + ':common:compileDebugShaders': NO_SOURCE, + ':common:compileDebugSources': UP_TO_DATE, + ':common:copyDebugJniLibsProjectAndLocalJars': FROM_CACHE, + ':common:copyDebugJniLibsProjectOnly': FROM_CACHE, + ':common:extractDebugAnnotations': FROM_CACHE, + ':common:extractDeepLinksDebug': FROM_CACHE, + ':common:generateDebugAssets': UP_TO_DATE, + ':common:generateDebugBuildConfig': FROM_CACHE, + ':common:generateDebugRFile': FROM_CACHE, + ':common:generateDebugResValues': FROM_CACHE, + ':common:generateDebugResources': UP_TO_DATE, + ':common:javaPreCompileDebug': FROM_CACHE, + ':common:mergeDebugConsumerProguardFiles': FROM_CACHE, + ':common:mergeDebugGeneratedProguardFiles': FROM_CACHE, + ':common:mergeDebugJavaResource': FROM_CACHE, + ':common:mergeDebugJniLibFolders': FROM_CACHE, + ':common:mergeDebugNativeLibs': FROM_CACHE, + ':common:mergeDebugShaders': FROM_CACHE, + ':common:packageDebugAssets': FROM_CACHE, + ':common:packageDebugRenderscript': NO_SOURCE, + ':common:packageDebugResources': FROM_CACHE, + ':common:parseDebugLocalResources': FROM_CACHE, + ':common:preBuild': UP_TO_DATE, + ':common:preDebugBuild': UP_TO_DATE, + ':common:prepareLintJarForPublish': SUCCESS, + ':common:processDebugJavaRes': NO_SOURCE, + ':common:processDebugManifest': FROM_CACHE, + ':common:stripDebugDebugSymbols': NO_SOURCE, + ':common:syncDebugLibJars': FROM_CACHE, + ':dasherdancer:assembleDebug': SUCCESS, + ':dasherdancer:bundleDebugAar': SUCCESS, + ':dasherdancer:bundleLibCompileToJarDebug': FROM_CACHE, + ':dasherdancer:bundleLibResDebug': NO_SOURCE, + ':dasherdancer:bundleLibRuntimeToJarDebug': FROM_CACHE, + ':dasherdancer:compileDebugAidl': NO_SOURCE, + ':dasherdancer:compileDebugJavaWithJavac': FROM_CACHE, + ':dasherdancer:compileDebugLibraryResources': SUCCESS, + ':dasherdancer:compileDebugRenderscript': NO_SOURCE, + ':dasherdancer:compileDebugShaders': NO_SOURCE, + ':dasherdancer:compileDebugSources': UP_TO_DATE, + ':dasherdancer:copyDebugJniLibsProjectAndLocalJars': FROM_CACHE, + ':dasherdancer:copyDebugJniLibsProjectOnly': FROM_CACHE, + ':dasherdancer:extractDebugAnnotations': FROM_CACHE, + ':dasherdancer:extractDeepLinksDebug': FROM_CACHE, + ':dasherdancer:generateDebugAssets': UP_TO_DATE, + ':dasherdancer:generateDebugBuildConfig': FROM_CACHE, + ':dasherdancer:generateDebugRFile': FROM_CACHE, + ':dasherdancer:generateDebugResValues': FROM_CACHE, + ':dasherdancer:generateDebugResources': UP_TO_DATE, + ':dasherdancer:javaPreCompileDebug': FROM_CACHE, + ':dasherdancer:mergeDebugConsumerProguardFiles': FROM_CACHE, + ':dasherdancer:mergeDebugGeneratedProguardFiles': FROM_CACHE, + ':dasherdancer:mergeDebugJavaResource': FROM_CACHE, + ':dasherdancer:mergeDebugJniLibFolders': FROM_CACHE, + ':dasherdancer:mergeDebugNativeLibs': FROM_CACHE, + ':dasherdancer:mergeDebugShaders': FROM_CACHE, + ':dasherdancer:packageDebugAssets': FROM_CACHE, + ':dasherdancer:packageDebugRenderscript': NO_SOURCE, + ':dasherdancer:packageDebugResources': FROM_CACHE, + ':dasherdancer:parseDebugLocalResources': FROM_CACHE, + ':dasherdancer:preBuild': UP_TO_DATE, + ':dasherdancer:preDebugBuild': UP_TO_DATE, + ':dasherdancer:prepareLintJarForPublish': SUCCESS, + ':dasherdancer:processDebugJavaRes': NO_SOURCE, + ':dasherdancer:processDebugManifest': FROM_CACHE, + ':dasherdancer:stripDebugDebugSymbols': NO_SOURCE, + ':dasherdancer:syncDebugLibJars': FROM_CACHE, + ':doodles:assembleDebug': SUCCESS, + ':doodles:bundleDebugAar': SUCCESS, + ':doodles:bundleLibCompileToJarDebug': FROM_CACHE, + ':doodles:bundleLibResDebug': NO_SOURCE, + ':doodles:bundleLibRuntimeToJarDebug': FROM_CACHE, + ':doodles:compileDebugAidl': NO_SOURCE, + ':doodles:compileDebugJavaWithJavac': FROM_CACHE, + ':doodles:compileDebugLibraryResources': SUCCESS, + ':doodles:compileDebugRenderscript': NO_SOURCE, + ':doodles:compileDebugShaders': NO_SOURCE, + ':doodles:compileDebugSources': UP_TO_DATE, + ':doodles:copyDebugJniLibsProjectAndLocalJars': FROM_CACHE, + ':doodles:copyDebugJniLibsProjectOnly': FROM_CACHE, + ':doodles:extractDebugAnnotations': FROM_CACHE, + ':doodles:extractDeepLinksDebug': FROM_CACHE, + ':doodles:generateDebugAssets': UP_TO_DATE, + ':doodles:generateDebugBuildConfig': FROM_CACHE, + ':doodles:generateDebugRFile': FROM_CACHE, + ':doodles:generateDebugResValues': FROM_CACHE, + ':doodles:generateDebugResources': UP_TO_DATE, + ':doodles:javaPreCompileDebug': FROM_CACHE, + ':doodles:mergeDebugConsumerProguardFiles': FROM_CACHE, + ':doodles:mergeDebugGeneratedProguardFiles': FROM_CACHE, + ':doodles:mergeDebugJavaResource': FROM_CACHE, + ':doodles:mergeDebugJniLibFolders': FROM_CACHE, + ':doodles:mergeDebugNativeLibs': FROM_CACHE, + ':doodles:mergeDebugShaders': FROM_CACHE, + ':doodles:packageDebugAssets': FROM_CACHE, + ':doodles:packageDebugRenderscript': NO_SOURCE, + ':doodles:packageDebugResources': FROM_CACHE, + ':doodles:parseDebugLocalResources': FROM_CACHE, + ':doodles:preBuild': UP_TO_DATE, + ':doodles:preDebugBuild': UP_TO_DATE, + ':doodles:prepareLintJarForPublish': SUCCESS, + ':doodles:processDebugJavaRes': NO_SOURCE, + ':doodles:processDebugManifest': FROM_CACHE, + ':doodles:stripDebugDebugSymbols': NO_SOURCE, + ':doodles:syncDebugLibJars': FROM_CACHE, + ':presentquest:assembleDebug': SUCCESS, + ':presentquest:bundleDebugAar': SUCCESS, + ':presentquest:bundleLibCompileToJarDebug': FROM_CACHE, + ':presentquest:bundleLibResDebug': NO_SOURCE, + ':presentquest:bundleLibRuntimeToJarDebug': FROM_CACHE, + ':presentquest:compileDebugAidl': NO_SOURCE, + ':presentquest:compileDebugJavaWithJavac': FROM_CACHE, + ':presentquest:compileDebugLibraryResources': SUCCESS, + ':presentquest:compileDebugRenderscript': NO_SOURCE, + ':presentquest:compileDebugShaders': NO_SOURCE, + ':presentquest:compileDebugSources': UP_TO_DATE, + ':presentquest:copyDebugJniLibsProjectAndLocalJars': FROM_CACHE, + ':presentquest:copyDebugJniLibsProjectOnly': FROM_CACHE, + ':presentquest:extractDebugAnnotations': FROM_CACHE, + ':presentquest:extractDeepLinksDebug': FROM_CACHE, + ':presentquest:generateDebugAssets': UP_TO_DATE, + ':presentquest:generateDebugBuildConfig': FROM_CACHE, + ':presentquest:generateDebugRFile': FROM_CACHE, + ':presentquest:generateDebugResValues': FROM_CACHE, + ':presentquest:generateDebugResources': UP_TO_DATE, + ':presentquest:javaPreCompileDebug': FROM_CACHE, + ':presentquest:mergeDebugConsumerProguardFiles': FROM_CACHE, + ':presentquest:mergeDebugGeneratedProguardFiles': FROM_CACHE, + ':presentquest:mergeDebugJavaResource': FROM_CACHE, + ':presentquest:mergeDebugJniLibFolders': FROM_CACHE, + ':presentquest:mergeDebugNativeLibs': FROM_CACHE, + ':presentquest:mergeDebugShaders': FROM_CACHE, + ':presentquest:packageDebugAssets': FROM_CACHE, + ':presentquest:packageDebugRenderscript': NO_SOURCE, + ':presentquest:packageDebugResources': FROM_CACHE, + ':presentquest:parseDebugLocalResources': FROM_CACHE, + ':presentquest:preBuild': UP_TO_DATE, + ':presentquest:preDebugBuild': UP_TO_DATE, + ':presentquest:prepareLintJarForPublish': SUCCESS, + ':presentquest:processDebugJavaRes': NO_SOURCE, + ':presentquest:processDebugManifest': FROM_CACHE, + ':presentquest:stripDebugDebugSymbols': NO_SOURCE, + ':presentquest:syncDebugLibJars': FROM_CACHE, + ':rocketsleigh:assembleDebug': SUCCESS, + ':rocketsleigh:bundleDebugAar': SUCCESS, + ':rocketsleigh:bundleLibCompileToJarDebug': FROM_CACHE, + ':rocketsleigh:bundleLibResDebug': NO_SOURCE, + ':rocketsleigh:bundleLibRuntimeToJarDebug': FROM_CACHE, + ':rocketsleigh:compileDebugAidl': NO_SOURCE, + ':rocketsleigh:compileDebugJavaWithJavac': FROM_CACHE, + ':rocketsleigh:compileDebugLibraryResources': SUCCESS, + ':rocketsleigh:compileDebugRenderscript': NO_SOURCE, + ':rocketsleigh:compileDebugShaders': NO_SOURCE, + ':rocketsleigh:compileDebugSources': UP_TO_DATE, + ':rocketsleigh:copyDebugJniLibsProjectAndLocalJars': FROM_CACHE, + ':rocketsleigh:copyDebugJniLibsProjectOnly': FROM_CACHE, + ':rocketsleigh:extractDebugAnnotations': FROM_CACHE, + ':rocketsleigh:extractDeepLinksDebug': FROM_CACHE, + ':rocketsleigh:generateDebugAssets': UP_TO_DATE, + ':rocketsleigh:generateDebugBuildConfig': FROM_CACHE, + ':rocketsleigh:generateDebugRFile': FROM_CACHE, + ':rocketsleigh:generateDebugResValues': FROM_CACHE, + ':rocketsleigh:generateDebugResources': UP_TO_DATE, + ':rocketsleigh:javaPreCompileDebug': FROM_CACHE, + ':rocketsleigh:mergeDebugConsumerProguardFiles': FROM_CACHE, + ':rocketsleigh:mergeDebugGeneratedProguardFiles': FROM_CACHE, + ':rocketsleigh:mergeDebugJavaResource': FROM_CACHE, + ':rocketsleigh:mergeDebugJniLibFolders': FROM_CACHE, + ':rocketsleigh:mergeDebugNativeLibs': FROM_CACHE, + ':rocketsleigh:mergeDebugShaders': FROM_CACHE, + ':rocketsleigh:packageDebugAssets': FROM_CACHE, + ':rocketsleigh:packageDebugRenderscript': NO_SOURCE, + ':rocketsleigh:packageDebugResources': FROM_CACHE, + ':rocketsleigh:parseDebugLocalResources': FROM_CACHE, + ':rocketsleigh:preBuild': UP_TO_DATE, + ':rocketsleigh:preDebugBuild': UP_TO_DATE, + ':rocketsleigh:prepareLintJarForPublish': SUCCESS, + ':rocketsleigh:processDebugJavaRes': NO_SOURCE, + ':rocketsleigh:processDebugManifest': FROM_CACHE, + ':rocketsleigh:stripDebugDebugSymbols': NO_SOURCE, + ':rocketsleigh:syncDebugLibJars': FROM_CACHE, + ':santa-tracker:assembleDebug': SUCCESS, + ':santa-tracker:assembleDevelopmentDebug': SUCCESS, + ':santa-tracker:checkDevelopmentDebugDuplicateClasses': FROM_CACHE, + ':santa-tracker:compileDevelopmentDebugAidl': NO_SOURCE, + ':santa-tracker:compileDevelopmentDebugJavaWithJavac': FROM_CACHE, + ':santa-tracker:compileDevelopmentDebugRenderscript': NO_SOURCE, + ':santa-tracker:compileDevelopmentDebugShaders': NO_SOURCE, + ':santa-tracker:compileDevelopmentDebugSources': UP_TO_DATE, + ':santa-tracker:createDevelopmentDebugCompatibleScreenManifests': FROM_CACHE, + ':santa-tracker:dexBuilderDevelopmentDebug': FROM_CACHE, + ':santa-tracker:extractDeepLinksDevelopmentDebug': FROM_CACHE, + ':santa-tracker:generateDevelopmentDebugAssets': UP_TO_DATE, + ':santa-tracker:generateDevelopmentDebugBuildConfig': FROM_CACHE, + ':santa-tracker:generateDevelopmentDebugResValues': FROM_CACHE, + ':santa-tracker:generateDevelopmentDebugResources': UP_TO_DATE, + ':santa-tracker:javaPreCompileDevelopmentDebug': FROM_CACHE, + ':santa-tracker:mergeDevelopmentDebugAssets': FROM_CACHE, + ':santa-tracker:mergeDevelopmentDebugJavaResource': FROM_CACHE, + ':santa-tracker:mergeDevelopmentDebugJniLibFolders': FROM_CACHE, + ':santa-tracker:mergeDevelopmentDebugNativeLibs': FROM_CACHE, + ':santa-tracker:mergeDevelopmentDebugResources': SUCCESS, + ':santa-tracker:mergeDevelopmentDebugShaders': FROM_CACHE, + ':santa-tracker:mergeExtDexDevelopmentDebug': FROM_CACHE, + ':santa-tracker:mergeLibDexDevelopmentDebug': FROM_CACHE, + ':santa-tracker:mergeProjectDexDevelopmentDebug': FROM_CACHE, + ':santa-tracker:packageDevelopmentDebug': SUCCESS, + ':santa-tracker:preBuild': UP_TO_DATE, + ':santa-tracker:preDevelopmentDebugBuild': UP_TO_DATE, + ':santa-tracker:processDevelopmentDebugJavaRes': NO_SOURCE, + ':santa-tracker:processDevelopmentDebugManifest': FROM_CACHE, + ':santa-tracker:processDevelopmentDebugResources': SUCCESS, + ':santa-tracker:stripDevelopmentDebugDebugSymbols': NO_SOURCE, + ':santa-tracker:validateSigningDevelopmentDebug': FROM_CACHE, + ':village:assembleDebug': SUCCESS, + ':village:bundleDebugAar': SUCCESS, + ':village:bundleLibCompileToJarDebug': FROM_CACHE, + ':village:bundleLibResDebug': NO_SOURCE, + ':village:bundleLibRuntimeToJarDebug': FROM_CACHE, + ':village:compileDebugAidl': NO_SOURCE, + ':village:compileDebugJavaWithJavac': FROM_CACHE, + ':village:compileDebugLibraryResources': SUCCESS, + ':village:compileDebugRenderscript': NO_SOURCE, + ':village:compileDebugShaders': NO_SOURCE, + ':village:compileDebugSources': UP_TO_DATE, + ':village:copyDebugJniLibsProjectAndLocalJars': FROM_CACHE, + ':village:copyDebugJniLibsProjectOnly': FROM_CACHE, + ':village:extractDebugAnnotations': FROM_CACHE, + ':village:extractDeepLinksDebug': FROM_CACHE, + ':village:generateDebugAssets': UP_TO_DATE, + ':village:generateDebugBuildConfig': FROM_CACHE, + ':village:generateDebugRFile': FROM_CACHE, + ':village:generateDebugResValues': FROM_CACHE, + ':village:generateDebugResources': UP_TO_DATE, + ':village:javaPreCompileDebug': FROM_CACHE, + ':village:mergeDebugConsumerProguardFiles': FROM_CACHE, + ':village:mergeDebugGeneratedProguardFiles': FROM_CACHE, + ':village:mergeDebugJavaResource': FROM_CACHE, + ':village:mergeDebugJniLibFolders': FROM_CACHE, + ':village:mergeDebugNativeLibs': FROM_CACHE, + ':village:mergeDebugShaders': FROM_CACHE, + ':village:packageDebugAssets': FROM_CACHE, + ':village:packageDebugRenderscript': NO_SOURCE, + ':village:packageDebugResources': FROM_CACHE, + ':village:parseDebugLocalResources': FROM_CACHE, + ':village:preBuild': UP_TO_DATE, + ':village:preDebugBuild': UP_TO_DATE, + ':village:prepareLintJarForPublish': SUCCESS, + ':village:processDebugJavaRes': NO_SOURCE, + ':village:processDebugManifest': FROM_CACHE, + ':village:stripDebugDebugSymbols': NO_SOURCE, + ':village:syncDebugLibJars': FROM_CACHE, + ] + + private static final EXPECTED_RESULTS_4_0_ALPHA = [ + ':common:assembleDebug': SUCCESS, + ':common:bundleDebugAar': SUCCESS, + ':common:bundleLibCompileDebug': FROM_CACHE, + ':common:bundleLibResDebug': FROM_CACHE, + ':common:bundleLibRuntimeDebug': FROM_CACHE, + ':common:compileDebugAidl': NO_SOURCE, + ':common:compileDebugJavaWithJavac': FROM_CACHE, + ':common:compileDebugLibraryResources': SUCCESS, + ':common:compileDebugRenderscript': NO_SOURCE, + ':common:compileDebugShaders': NO_SOURCE, + ':common:compileDebugSources': UP_TO_DATE, + ':common:copyDebugJniLibsProjectAndLocalJars': FROM_CACHE, + ':common:copyDebugJniLibsProjectOnly': FROM_CACHE, + ':common:extractDebugAnnotations': FROM_CACHE, + ':common:extractDeepLinksDebug': FROM_CACHE, + ':common:generateDebugAssets': UP_TO_DATE, + ':common:generateDebugBuildConfig': FROM_CACHE, + ':common:generateDebugRFile': FROM_CACHE, + ':common:generateDebugResValues': FROM_CACHE, + ':common:generateDebugResources': UP_TO_DATE, + ':common:javaPreCompileDebug': FROM_CACHE, + ':common:mergeDebugConsumerProguardFiles': FROM_CACHE, + ':common:mergeDebugGeneratedProguardFiles': FROM_CACHE, + ':common:mergeDebugJavaResource': FROM_CACHE, + ':common:mergeDebugJniLibFolders': FROM_CACHE, + ':common:mergeDebugNativeLibs': FROM_CACHE, + ':common:mergeDebugShaders': FROM_CACHE, + ':common:packageDebugAssets': FROM_CACHE, + ':common:packageDebugRenderscript': NO_SOURCE, + ':common:packageDebugResources': FROM_CACHE, + ':common:parseDebugLocalResources': FROM_CACHE, + ':common:preBuild': UP_TO_DATE, + ':common:preDebugBuild': UP_TO_DATE, + ':common:prepareLintJarForPublish': SUCCESS, + ':common:processDebugJavaRes': NO_SOURCE, + ':common:processDebugManifest': FROM_CACHE, + ':common:stripDebugDebugSymbols': FROM_CACHE, + ':common:syncDebugLibJars': FROM_CACHE, + ':dasherdancer:assembleDebug': SUCCESS, + ':dasherdancer:bundleDebugAar': SUCCESS, + ':dasherdancer:bundleLibCompileDebug': FROM_CACHE, + ':dasherdancer:bundleLibResDebug': FROM_CACHE, + ':dasherdancer:bundleLibRuntimeDebug': FROM_CACHE, + ':dasherdancer:compileDebugAidl': NO_SOURCE, + ':dasherdancer:compileDebugJavaWithJavac': FROM_CACHE, + ':dasherdancer:compileDebugLibraryResources': SUCCESS, + ':dasherdancer:compileDebugRenderscript': NO_SOURCE, + ':dasherdancer:compileDebugShaders': NO_SOURCE, + ':dasherdancer:compileDebugSources': UP_TO_DATE, + ':dasherdancer:copyDebugJniLibsProjectAndLocalJars': FROM_CACHE, + ':dasherdancer:copyDebugJniLibsProjectOnly': FROM_CACHE, + ':dasherdancer:extractDebugAnnotations': FROM_CACHE, + ':dasherdancer:extractDeepLinksDebug': FROM_CACHE, + ':dasherdancer:generateDebugAssets': UP_TO_DATE, + ':dasherdancer:generateDebugBuildConfig': FROM_CACHE, + ':dasherdancer:generateDebugRFile': FROM_CACHE, + ':dasherdancer:generateDebugResValues': FROM_CACHE, + ':dasherdancer:generateDebugResources': UP_TO_DATE, + ':dasherdancer:javaPreCompileDebug': FROM_CACHE, + ':dasherdancer:mergeDebugConsumerProguardFiles': FROM_CACHE, + ':dasherdancer:mergeDebugGeneratedProguardFiles': FROM_CACHE, + ':dasherdancer:mergeDebugJavaResource': FROM_CACHE, + ':dasherdancer:mergeDebugJniLibFolders': FROM_CACHE, + ':dasherdancer:mergeDebugNativeLibs': FROM_CACHE, + ':dasherdancer:mergeDebugShaders': FROM_CACHE, + ':dasherdancer:packageDebugAssets': FROM_CACHE, + ':dasherdancer:packageDebugRenderscript': NO_SOURCE, + ':dasherdancer:packageDebugResources': FROM_CACHE, + ':dasherdancer:parseDebugLocalResources': FROM_CACHE, + ':dasherdancer:preBuild': UP_TO_DATE, + ':dasherdancer:preDebugBuild': UP_TO_DATE, + ':dasherdancer:prepareLintJarForPublish': SUCCESS, + ':dasherdancer:processDebugJavaRes': NO_SOURCE, + ':dasherdancer:processDebugManifest': FROM_CACHE, + ':dasherdancer:stripDebugDebugSymbols': FROM_CACHE, + ':dasherdancer:syncDebugLibJars': FROM_CACHE, + ':doodles:assembleDebug': SUCCESS, + ':doodles:bundleDebugAar': SUCCESS, + ':doodles:bundleLibCompileDebug': FROM_CACHE, + ':doodles:bundleLibResDebug': FROM_CACHE, + ':doodles:bundleLibRuntimeDebug': FROM_CACHE, + ':doodles:compileDebugAidl': NO_SOURCE, + ':doodles:compileDebugJavaWithJavac': FROM_CACHE, + ':doodles:compileDebugLibraryResources': SUCCESS, + ':doodles:compileDebugRenderscript': NO_SOURCE, + ':doodles:compileDebugShaders': NO_SOURCE, + ':doodles:compileDebugSources': UP_TO_DATE, + ':doodles:copyDebugJniLibsProjectAndLocalJars': FROM_CACHE, + ':doodles:copyDebugJniLibsProjectOnly': FROM_CACHE, + ':doodles:extractDebugAnnotations': FROM_CACHE, + ':doodles:extractDeepLinksDebug': FROM_CACHE, + ':doodles:generateDebugAssets': UP_TO_DATE, + ':doodles:generateDebugBuildConfig': FROM_CACHE, + ':doodles:generateDebugRFile': FROM_CACHE, + ':doodles:generateDebugResValues': FROM_CACHE, + ':doodles:generateDebugResources': UP_TO_DATE, + ':doodles:javaPreCompileDebug': FROM_CACHE, + ':doodles:mergeDebugConsumerProguardFiles': FROM_CACHE, + ':doodles:mergeDebugGeneratedProguardFiles': FROM_CACHE, + ':doodles:mergeDebugJavaResource': FROM_CACHE, + ':doodles:mergeDebugJniLibFolders': FROM_CACHE, + ':doodles:mergeDebugNativeLibs': FROM_CACHE, + ':doodles:mergeDebugShaders': FROM_CACHE, + ':doodles:packageDebugAssets': FROM_CACHE, + ':doodles:packageDebugRenderscript': NO_SOURCE, + ':doodles:packageDebugResources': FROM_CACHE, + ':doodles:parseDebugLocalResources': FROM_CACHE, + ':doodles:preBuild': UP_TO_DATE, + ':doodles:preDebugBuild': UP_TO_DATE, + ':doodles:prepareLintJarForPublish': SUCCESS, + ':doodles:processDebugJavaRes': NO_SOURCE, + ':doodles:processDebugManifest': FROM_CACHE, + ':doodles:stripDebugDebugSymbols': FROM_CACHE, + ':doodles:syncDebugLibJars': FROM_CACHE, + ':presentquest:assembleDebug': SUCCESS, + ':presentquest:bundleDebugAar': SUCCESS, + ':presentquest:bundleLibCompileDebug': FROM_CACHE, + ':presentquest:bundleLibResDebug': FROM_CACHE, + ':presentquest:bundleLibRuntimeDebug': FROM_CACHE, + ':presentquest:compileDebugAidl': NO_SOURCE, + ':presentquest:compileDebugJavaWithJavac': FROM_CACHE, + ':presentquest:compileDebugLibraryResources': SUCCESS, + ':presentquest:compileDebugRenderscript': NO_SOURCE, + ':presentquest:compileDebugShaders': NO_SOURCE, + ':presentquest:compileDebugSources': UP_TO_DATE, + ':presentquest:copyDebugJniLibsProjectAndLocalJars': FROM_CACHE, + ':presentquest:copyDebugJniLibsProjectOnly': FROM_CACHE, + ':presentquest:extractDebugAnnotations': FROM_CACHE, + ':presentquest:extractDeepLinksDebug': FROM_CACHE, + ':presentquest:generateDebugAssets': UP_TO_DATE, + ':presentquest:generateDebugBuildConfig': FROM_CACHE, + ':presentquest:generateDebugRFile': FROM_CACHE, + ':presentquest:generateDebugResValues': FROM_CACHE, + ':presentquest:generateDebugResources': UP_TO_DATE, + ':presentquest:javaPreCompileDebug': FROM_CACHE, + ':presentquest:mergeDebugConsumerProguardFiles': FROM_CACHE, + ':presentquest:mergeDebugGeneratedProguardFiles': FROM_CACHE, + ':presentquest:mergeDebugJavaResource': FROM_CACHE, + ':presentquest:mergeDebugJniLibFolders': FROM_CACHE, + ':presentquest:mergeDebugNativeLibs': FROM_CACHE, + ':presentquest:mergeDebugShaders': FROM_CACHE, + ':presentquest:packageDebugAssets': FROM_CACHE, + ':presentquest:packageDebugRenderscript': NO_SOURCE, + ':presentquest:packageDebugResources': FROM_CACHE, + ':presentquest:parseDebugLocalResources': FROM_CACHE, + ':presentquest:preBuild': UP_TO_DATE, + ':presentquest:preDebugBuild': UP_TO_DATE, + ':presentquest:prepareLintJarForPublish': SUCCESS, + ':presentquest:processDebugJavaRes': NO_SOURCE, + ':presentquest:processDebugManifest': FROM_CACHE, + ':presentquest:stripDebugDebugSymbols': FROM_CACHE, + ':presentquest:syncDebugLibJars': FROM_CACHE, + ':rocketsleigh:assembleDebug': SUCCESS, + ':rocketsleigh:bundleDebugAar': SUCCESS, + ':rocketsleigh:bundleLibCompileDebug': FROM_CACHE, + ':rocketsleigh:bundleLibResDebug': FROM_CACHE, + ':rocketsleigh:bundleLibRuntimeDebug': FROM_CACHE, + ':rocketsleigh:compileDebugAidl': NO_SOURCE, + ':rocketsleigh:compileDebugJavaWithJavac': FROM_CACHE, + ':rocketsleigh:compileDebugLibraryResources': SUCCESS, + ':rocketsleigh:compileDebugRenderscript': NO_SOURCE, + ':rocketsleigh:compileDebugShaders': NO_SOURCE, + ':rocketsleigh:compileDebugSources': UP_TO_DATE, + ':rocketsleigh:copyDebugJniLibsProjectAndLocalJars': FROM_CACHE, + ':rocketsleigh:copyDebugJniLibsProjectOnly': FROM_CACHE, + ':rocketsleigh:extractDebugAnnotations': FROM_CACHE, + ':rocketsleigh:extractDeepLinksDebug': FROM_CACHE, + ':rocketsleigh:generateDebugAssets': UP_TO_DATE, + ':rocketsleigh:generateDebugBuildConfig': FROM_CACHE, + ':rocketsleigh:generateDebugRFile': FROM_CACHE, + ':rocketsleigh:generateDebugResValues': FROM_CACHE, + ':rocketsleigh:generateDebugResources': UP_TO_DATE, + ':rocketsleigh:javaPreCompileDebug': FROM_CACHE, + ':rocketsleigh:mergeDebugConsumerProguardFiles': FROM_CACHE, + ':rocketsleigh:mergeDebugGeneratedProguardFiles': FROM_CACHE, + ':rocketsleigh:mergeDebugJavaResource': FROM_CACHE, + ':rocketsleigh:mergeDebugJniLibFolders': FROM_CACHE, + ':rocketsleigh:mergeDebugNativeLibs': FROM_CACHE, + ':rocketsleigh:mergeDebugShaders': FROM_CACHE, + ':rocketsleigh:packageDebugAssets': FROM_CACHE, + ':rocketsleigh:packageDebugRenderscript': NO_SOURCE, + ':rocketsleigh:packageDebugResources': FROM_CACHE, + ':rocketsleigh:parseDebugLocalResources': FROM_CACHE, + ':rocketsleigh:preBuild': UP_TO_DATE, + ':rocketsleigh:preDebugBuild': UP_TO_DATE, + ':rocketsleigh:prepareLintJarForPublish': SUCCESS, + ':rocketsleigh:processDebugJavaRes': NO_SOURCE, + ':rocketsleigh:processDebugManifest': FROM_CACHE, + ':rocketsleigh:stripDebugDebugSymbols': FROM_CACHE, + ':rocketsleigh:syncDebugLibJars': FROM_CACHE, + ':santa-tracker:assembleDebug': SUCCESS, + ':santa-tracker:assembleDevelopmentDebug': SUCCESS, + ':santa-tracker:checkDevelopmentDebugDuplicateClasses': FROM_CACHE, + ':santa-tracker:compileDevelopmentDebugAidl': NO_SOURCE, + ':santa-tracker:compileDevelopmentDebugJavaWithJavac': FROM_CACHE, + ':santa-tracker:compileDevelopmentDebugRenderscript': NO_SOURCE, + ':santa-tracker:compileDevelopmentDebugShaders': NO_SOURCE, + ':santa-tracker:compileDevelopmentDebugSources': UP_TO_DATE, + ':santa-tracker:createDevelopmentDebugCompatibleScreenManifests': FROM_CACHE, + ':santa-tracker:dexBuilderDevelopmentDebug': FROM_CACHE, + ':santa-tracker:extractDeepLinksDevelopmentDebug': FROM_CACHE, + ':santa-tracker:generateDevelopmentDebugAssets': UP_TO_DATE, + ':santa-tracker:generateDevelopmentDebugBuildConfig': FROM_CACHE, + ':santa-tracker:generateDevelopmentDebugResValues': FROM_CACHE, + ':santa-tracker:generateDevelopmentDebugResources': UP_TO_DATE, + ':santa-tracker:javaPreCompileDevelopmentDebug': FROM_CACHE, + ':santa-tracker:mergeDevelopmentDebugAssets': FROM_CACHE, + ':santa-tracker:mergeDevelopmentDebugJavaResource': FROM_CACHE, + ':santa-tracker:mergeDevelopmentDebugJniLibFolders': FROM_CACHE, + ':santa-tracker:mergeDevelopmentDebugNativeLibs': FROM_CACHE, + ':santa-tracker:mergeDevelopmentDebugResources': SUCCESS, + ':santa-tracker:mergeDevelopmentDebugShaders': FROM_CACHE, + ':santa-tracker:mergeExtDexDevelopmentDebug': FROM_CACHE, + ':santa-tracker:mergeLibDexDevelopmentDebug': FROM_CACHE, + ':santa-tracker:mergeProjectDexDevelopmentDebug': FROM_CACHE, + ':santa-tracker:packageDevelopmentDebug': SUCCESS, + ':santa-tracker:preBuild': UP_TO_DATE, + ':santa-tracker:preDevelopmentDebugBuild': UP_TO_DATE, + ':santa-tracker:processDevelopmentDebugJavaRes': NO_SOURCE, + ':santa-tracker:processDevelopmentDebugManifest': FROM_CACHE, + ':santa-tracker:processDevelopmentDebugResources': SUCCESS, + ':santa-tracker:stripDevelopmentDebugDebugSymbols': FROM_CACHE, + ':santa-tracker:validateSigningDevelopmentDebug': FROM_CACHE, + ':village:assembleDebug': SUCCESS, + ':village:bundleDebugAar': SUCCESS, + ':village:bundleLibCompileDebug': FROM_CACHE, + ':village:bundleLibResDebug': FROM_CACHE, + ':village:bundleLibRuntimeDebug': FROM_CACHE, + ':village:compileDebugAidl': NO_SOURCE, + ':village:compileDebugJavaWithJavac': FROM_CACHE, + ':village:compileDebugLibraryResources': SUCCESS, + ':village:compileDebugRenderscript': NO_SOURCE, + ':village:compileDebugShaders': NO_SOURCE, + ':village:compileDebugSources': UP_TO_DATE, + ':village:copyDebugJniLibsProjectAndLocalJars': FROM_CACHE, + ':village:copyDebugJniLibsProjectOnly': FROM_CACHE, + ':village:extractDebugAnnotations': FROM_CACHE, + ':village:extractDeepLinksDebug': FROM_CACHE, + ':village:generateDebugAssets': UP_TO_DATE, + ':village:generateDebugBuildConfig': FROM_CACHE, + ':village:generateDebugRFile': FROM_CACHE, + ':village:generateDebugResValues': FROM_CACHE, + ':village:generateDebugResources': UP_TO_DATE, + ':village:javaPreCompileDebug': FROM_CACHE, + ':village:mergeDebugConsumerProguardFiles': FROM_CACHE, + ':village:mergeDebugGeneratedProguardFiles': FROM_CACHE, + ':village:mergeDebugJavaResource': FROM_CACHE, + ':village:mergeDebugJniLibFolders': FROM_CACHE, + ':village:mergeDebugNativeLibs': FROM_CACHE, + ':village:mergeDebugShaders': FROM_CACHE, + ':village:packageDebugAssets': FROM_CACHE, + ':village:packageDebugRenderscript': NO_SOURCE, + ':village:packageDebugResources': FROM_CACHE, + ':village:parseDebugLocalResources': FROM_CACHE, + ':village:preBuild': UP_TO_DATE, + ':village:preDebugBuild': UP_TO_DATE, + ':village:prepareLintJarForPublish': SUCCESS, + ':village:processDebugJavaRes': NO_SOURCE, + ':village:processDebugManifest': FROM_CACHE, + ':village:stripDebugDebugSymbols': FROM_CACHE, + ':village:syncDebugLibJars': FROM_CACHE, + ] + + private static final EXPECTED_RESULTS_3_6 = [ + ':common:assembleDebug': SUCCESS, + ':common:bundleDebugAar': SUCCESS, + ':common:bundleLibCompileDebug': SUCCESS, + ':common:bundleLibResDebug': SUCCESS, + ':common:bundleLibRuntimeDebug': SUCCESS, + ':common:compileDebugAidl': NO_SOURCE, + ':common:compileDebugJavaWithJavac': FROM_CACHE, + ':common:compileDebugLibraryResources': FROM_CACHE, + ':common:compileDebugRenderscript': NO_SOURCE, + ':common:compileDebugShaders': FROM_CACHE, + ':common:compileDebugSources': UP_TO_DATE, + ':common:copyDebugJniLibsProjectAndLocalJars': FROM_CACHE, + ':common:copyDebugJniLibsProjectOnly': FROM_CACHE, + ':common:extractDebugAnnotations': FROM_CACHE, + ':common:extractDeepLinksDebug': FROM_CACHE, + ':common:generateDebugAssets': UP_TO_DATE, + ':common:generateDebugBuildConfig': FROM_CACHE, + ':common:generateDebugRFile': FROM_CACHE, + ':common:generateDebugResValues': FROM_CACHE, + ':common:generateDebugResources': UP_TO_DATE, + ':common:javaPreCompileDebug': FROM_CACHE, + ':common:mergeDebugConsumerProguardFiles': SUCCESS, + ':common:mergeDebugGeneratedProguardFiles': SUCCESS, + ':common:mergeDebugJavaResource': FROM_CACHE, + ':common:mergeDebugJniLibFolders': FROM_CACHE, + ':common:mergeDebugNativeLibs': FROM_CACHE, + ':common:mergeDebugShaders': FROM_CACHE, + ':common:packageDebugAssets': FROM_CACHE, + ':common:packageDebugRenderscript': NO_SOURCE, + ':common:packageDebugResources': FROM_CACHE, + ':common:parseDebugLocalResources': FROM_CACHE, + ':common:preBuild': UP_TO_DATE, + ':common:preDebugBuild': UP_TO_DATE, + ':common:prepareLintJarForPublish': SUCCESS, + ':common:processDebugJavaRes': NO_SOURCE, + ':common:processDebugManifest': FROM_CACHE, + ':common:stripDebugDebugSymbols': FROM_CACHE, + ':common:syncDebugLibJars': FROM_CACHE, + ':dasherdancer:assembleDebug': SUCCESS, + ':dasherdancer:bundleDebugAar': SUCCESS, + ':dasherdancer:bundleLibCompileDebug': SUCCESS, + ':dasherdancer:bundleLibResDebug': SUCCESS, + ':dasherdancer:bundleLibRuntimeDebug': SUCCESS, + ':dasherdancer:compileDebugAidl': NO_SOURCE, + ':dasherdancer:compileDebugJavaWithJavac': FROM_CACHE, + ':dasherdancer:compileDebugLibraryResources': FROM_CACHE, + ':dasherdancer:compileDebugRenderscript': NO_SOURCE, + ':dasherdancer:compileDebugShaders': FROM_CACHE, + ':dasherdancer:compileDebugSources': UP_TO_DATE, + ':dasherdancer:copyDebugJniLibsProjectAndLocalJars': FROM_CACHE, + ':dasherdancer:copyDebugJniLibsProjectOnly': FROM_CACHE, + ':dasherdancer:extractDebugAnnotations': FROM_CACHE, + ':dasherdancer:extractDeepLinksDebug': FROM_CACHE, + ':dasherdancer:generateDebugAssets': UP_TO_DATE, + ':dasherdancer:generateDebugBuildConfig': FROM_CACHE, + ':dasherdancer:generateDebugRFile': FROM_CACHE, + ':dasherdancer:generateDebugResValues': FROM_CACHE, + ':dasherdancer:generateDebugResources': UP_TO_DATE, + ':dasherdancer:javaPreCompileDebug': FROM_CACHE, + ':dasherdancer:mergeDebugConsumerProguardFiles': SUCCESS, + ':dasherdancer:mergeDebugGeneratedProguardFiles': SUCCESS, + ':dasherdancer:mergeDebugJavaResource': FROM_CACHE, + ':dasherdancer:mergeDebugJniLibFolders': FROM_CACHE, + ':dasherdancer:mergeDebugNativeLibs': FROM_CACHE, + ':dasherdancer:mergeDebugShaders': FROM_CACHE, + ':dasherdancer:packageDebugAssets': FROM_CACHE, + ':dasherdancer:packageDebugRenderscript': NO_SOURCE, + ':dasherdancer:packageDebugResources': FROM_CACHE, + ':dasherdancer:parseDebugLocalResources': FROM_CACHE, + ':dasherdancer:preBuild': UP_TO_DATE, + ':dasherdancer:preDebugBuild': UP_TO_DATE, + ':dasherdancer:prepareLintJarForPublish': SUCCESS, + ':dasherdancer:processDebugJavaRes': NO_SOURCE, + ':dasherdancer:processDebugManifest': FROM_CACHE, + ':dasherdancer:stripDebugDebugSymbols': FROM_CACHE, + ':dasherdancer:syncDebugLibJars': FROM_CACHE, + ':doodles:assembleDebug': SUCCESS, + ':doodles:bundleDebugAar': SUCCESS, + ':doodles:bundleLibCompileDebug': SUCCESS, + ':doodles:bundleLibResDebug': SUCCESS, + ':doodles:bundleLibRuntimeDebug': SUCCESS, + ':doodles:compileDebugAidl': NO_SOURCE, + ':doodles:compileDebugJavaWithJavac': FROM_CACHE, + ':doodles:compileDebugLibraryResources': FROM_CACHE, + ':doodles:compileDebugRenderscript': NO_SOURCE, + ':doodles:compileDebugShaders': FROM_CACHE, + ':doodles:compileDebugSources': UP_TO_DATE, + ':doodles:copyDebugJniLibsProjectAndLocalJars': FROM_CACHE, + ':doodles:copyDebugJniLibsProjectOnly': FROM_CACHE, + ':doodles:extractDebugAnnotations': FROM_CACHE, + ':doodles:extractDeepLinksDebug': FROM_CACHE, + ':doodles:generateDebugAssets': UP_TO_DATE, + ':doodles:generateDebugBuildConfig': FROM_CACHE, + ':doodles:generateDebugRFile': FROM_CACHE, + ':doodles:generateDebugResValues': FROM_CACHE, + ':doodles:generateDebugResources': UP_TO_DATE, + ':doodles:javaPreCompileDebug': FROM_CACHE, + ':doodles:mergeDebugConsumerProguardFiles': SUCCESS, + ':doodles:mergeDebugGeneratedProguardFiles': SUCCESS, + ':doodles:mergeDebugJavaResource': FROM_CACHE, + ':doodles:mergeDebugJniLibFolders': FROM_CACHE, + ':doodles:mergeDebugNativeLibs': FROM_CACHE, + ':doodles:mergeDebugShaders': FROM_CACHE, + ':doodles:packageDebugAssets': FROM_CACHE, + ':doodles:packageDebugRenderscript': NO_SOURCE, + ':doodles:packageDebugResources': FROM_CACHE, + ':doodles:parseDebugLocalResources': FROM_CACHE, + ':doodles:preBuild': UP_TO_DATE, + ':doodles:preDebugBuild': UP_TO_DATE, + ':doodles:prepareLintJarForPublish': SUCCESS, + ':doodles:processDebugJavaRes': NO_SOURCE, + ':doodles:processDebugManifest': FROM_CACHE, + ':doodles:stripDebugDebugSymbols': FROM_CACHE, + ':doodles:syncDebugLibJars': FROM_CACHE, + ':presentquest:assembleDebug': SUCCESS, + ':presentquest:bundleDebugAar': SUCCESS, + ':presentquest:bundleLibCompileDebug': SUCCESS, + ':presentquest:bundleLibResDebug': SUCCESS, + ':presentquest:bundleLibRuntimeDebug': SUCCESS, + ':presentquest:compileDebugAidl': NO_SOURCE, + ':presentquest:compileDebugJavaWithJavac': FROM_CACHE, + ':presentquest:compileDebugLibraryResources': FROM_CACHE, + ':presentquest:compileDebugRenderscript': NO_SOURCE, + ':presentquest:compileDebugShaders': FROM_CACHE, + ':presentquest:compileDebugSources': UP_TO_DATE, + ':presentquest:copyDebugJniLibsProjectAndLocalJars': FROM_CACHE, + ':presentquest:copyDebugJniLibsProjectOnly': FROM_CACHE, + ':presentquest:extractDebugAnnotations': FROM_CACHE, + ':presentquest:extractDeepLinksDebug': FROM_CACHE, + ':presentquest:generateDebugAssets': UP_TO_DATE, + ':presentquest:generateDebugBuildConfig': FROM_CACHE, + ':presentquest:generateDebugRFile': FROM_CACHE, + ':presentquest:generateDebugResValues': FROM_CACHE, + ':presentquest:generateDebugResources': UP_TO_DATE, + ':presentquest:javaPreCompileDebug': FROM_CACHE, + ':presentquest:mergeDebugConsumerProguardFiles': SUCCESS, + ':presentquest:mergeDebugGeneratedProguardFiles': SUCCESS, + ':presentquest:mergeDebugJavaResource': FROM_CACHE, + ':presentquest:mergeDebugJniLibFolders': FROM_CACHE, + ':presentquest:mergeDebugNativeLibs': FROM_CACHE, + ':presentquest:mergeDebugShaders': FROM_CACHE, + ':presentquest:packageDebugAssets': FROM_CACHE, + ':presentquest:packageDebugRenderscript': NO_SOURCE, + ':presentquest:packageDebugResources': FROM_CACHE, + ':presentquest:parseDebugLocalResources': FROM_CACHE, + ':presentquest:preBuild': UP_TO_DATE, + ':presentquest:preDebugBuild': UP_TO_DATE, + ':presentquest:prepareLintJarForPublish': SUCCESS, + ':presentquest:processDebugJavaRes': NO_SOURCE, + ':presentquest:processDebugManifest': FROM_CACHE, + ':presentquest:stripDebugDebugSymbols': FROM_CACHE, + ':presentquest:syncDebugLibJars': FROM_CACHE, + ':rocketsleigh:assembleDebug': SUCCESS, + ':rocketsleigh:bundleDebugAar': SUCCESS, + ':rocketsleigh:bundleLibCompileDebug': SUCCESS, + ':rocketsleigh:bundleLibResDebug': SUCCESS, + ':rocketsleigh:bundleLibRuntimeDebug': SUCCESS, + ':rocketsleigh:compileDebugAidl': NO_SOURCE, + ':rocketsleigh:compileDebugJavaWithJavac': FROM_CACHE, + ':rocketsleigh:compileDebugLibraryResources': FROM_CACHE, + ':rocketsleigh:compileDebugRenderscript': NO_SOURCE, + ':rocketsleigh:compileDebugShaders': FROM_CACHE, + ':rocketsleigh:compileDebugSources': UP_TO_DATE, + ':rocketsleigh:copyDebugJniLibsProjectAndLocalJars': FROM_CACHE, + ':rocketsleigh:copyDebugJniLibsProjectOnly': FROM_CACHE, + ':rocketsleigh:extractDebugAnnotations': FROM_CACHE, + ':rocketsleigh:extractDeepLinksDebug': FROM_CACHE, + ':rocketsleigh:generateDebugAssets': UP_TO_DATE, + ':rocketsleigh:generateDebugBuildConfig': FROM_CACHE, + ':rocketsleigh:generateDebugRFile': FROM_CACHE, + ':rocketsleigh:generateDebugResValues': FROM_CACHE, + ':rocketsleigh:generateDebugResources': UP_TO_DATE, + ':rocketsleigh:javaPreCompileDebug': FROM_CACHE, + ':rocketsleigh:mergeDebugConsumerProguardFiles': SUCCESS, + ':rocketsleigh:mergeDebugGeneratedProguardFiles': SUCCESS, + ':rocketsleigh:mergeDebugJavaResource': FROM_CACHE, + ':rocketsleigh:mergeDebugJniLibFolders': FROM_CACHE, + ':rocketsleigh:mergeDebugNativeLibs': FROM_CACHE, + ':rocketsleigh:mergeDebugShaders': FROM_CACHE, + ':rocketsleigh:packageDebugAssets': FROM_CACHE, + ':rocketsleigh:packageDebugRenderscript': NO_SOURCE, + ':rocketsleigh:packageDebugResources': FROM_CACHE, + ':rocketsleigh:parseDebugLocalResources': FROM_CACHE, + ':rocketsleigh:preBuild': UP_TO_DATE, + ':rocketsleigh:preDebugBuild': UP_TO_DATE, + ':rocketsleigh:prepareLintJarForPublish': SUCCESS, + ':rocketsleigh:processDebugJavaRes': NO_SOURCE, + ':rocketsleigh:processDebugManifest': FROM_CACHE, + ':rocketsleigh:stripDebugDebugSymbols': FROM_CACHE, + ':rocketsleigh:syncDebugLibJars': FROM_CACHE, + ':santa-tracker:assembleDebug': SUCCESS, + ':santa-tracker:assembleDevelopmentDebug': SUCCESS, + ':santa-tracker:checkDevelopmentDebugDuplicateClasses': FROM_CACHE, + ':santa-tracker:compileDevelopmentDebugAidl': NO_SOURCE, + ':santa-tracker:compileDevelopmentDebugJavaWithJavac': FROM_CACHE, + ':santa-tracker:compileDevelopmentDebugRenderscript': NO_SOURCE, + ':santa-tracker:compileDevelopmentDebugShaders': FROM_CACHE, + ':santa-tracker:compileDevelopmentDebugSources': UP_TO_DATE, + ':santa-tracker:createDevelopmentDebugCompatibleScreenManifests': FROM_CACHE, + ':santa-tracker:dexBuilderDevelopmentDebug': FROM_CACHE, + ':santa-tracker:extractDeepLinksDevelopmentDebug': FROM_CACHE, + ':santa-tracker:generateDevelopmentDebugAssets': UP_TO_DATE, + ':santa-tracker:generateDevelopmentDebugBuildConfig': FROM_CACHE, + ':santa-tracker:generateDevelopmentDebugResValues': FROM_CACHE, + ':santa-tracker:generateDevelopmentDebugResources': UP_TO_DATE, + ':santa-tracker:javaPreCompileDevelopmentDebug': FROM_CACHE, + ':santa-tracker:mainApkListPersistenceDevelopmentDebug': FROM_CACHE, + ':santa-tracker:mergeDevelopmentDebugAssets': FROM_CACHE, + ':santa-tracker:mergeDevelopmentDebugJavaResource': FROM_CACHE, + ':santa-tracker:mergeDevelopmentDebugJniLibFolders': FROM_CACHE, + ':santa-tracker:mergeDevelopmentDebugNativeLibs': FROM_CACHE, + ':santa-tracker:mergeDevelopmentDebugResources': FROM_CACHE, + ':santa-tracker:mergeDevelopmentDebugShaders': FROM_CACHE, + ':santa-tracker:mergeExtDexDevelopmentDebug': FROM_CACHE, + ':santa-tracker:mergeLibDexDevelopmentDebug': FROM_CACHE, + ':santa-tracker:mergeProjectDexDevelopmentDebug': FROM_CACHE, + ':santa-tracker:packageDevelopmentDebug': SUCCESS, + ':santa-tracker:preBuild': UP_TO_DATE, + ':santa-tracker:preDevelopmentDebugBuild': UP_TO_DATE, + ':santa-tracker:processDevelopmentDebugJavaRes': NO_SOURCE, + ':santa-tracker:processDevelopmentDebugManifest': FROM_CACHE, + ':santa-tracker:processDevelopmentDebugResources': FROM_CACHE, + ':santa-tracker:stripDevelopmentDebugDebugSymbols': FROM_CACHE, + ':santa-tracker:validateSigningDevelopmentDebug': FROM_CACHE, + ':village:assembleDebug': SUCCESS, + ':village:bundleDebugAar': SUCCESS, + ':village:bundleLibCompileDebug': SUCCESS, + ':village:bundleLibResDebug': SUCCESS, + ':village:bundleLibRuntimeDebug': SUCCESS, + ':village:compileDebugAidl': NO_SOURCE, + ':village:compileDebugJavaWithJavac': FROM_CACHE, + ':village:compileDebugLibraryResources': FROM_CACHE, + ':village:compileDebugRenderscript': NO_SOURCE, + ':village:compileDebugShaders': FROM_CACHE, + ':village:compileDebugSources': UP_TO_DATE, + ':village:copyDebugJniLibsProjectAndLocalJars': FROM_CACHE, + ':village:copyDebugJniLibsProjectOnly': FROM_CACHE, + ':village:extractDebugAnnotations': FROM_CACHE, + ':village:extractDeepLinksDebug': FROM_CACHE, + ':village:generateDebugAssets': UP_TO_DATE, + ':village:generateDebugBuildConfig': FROM_CACHE, + ':village:generateDebugRFile': FROM_CACHE, + ':village:generateDebugResValues': FROM_CACHE, + ':village:generateDebugResources': UP_TO_DATE, + ':village:javaPreCompileDebug': FROM_CACHE, + ':village:mergeDebugConsumerProguardFiles': SUCCESS, + ':village:mergeDebugGeneratedProguardFiles': SUCCESS, + ':village:mergeDebugJavaResource': FROM_CACHE, + ':village:mergeDebugJniLibFolders': FROM_CACHE, + ':village:mergeDebugNativeLibs': FROM_CACHE, + ':village:mergeDebugShaders': FROM_CACHE, + ':village:packageDebugAssets': FROM_CACHE, + ':village:packageDebugRenderscript': NO_SOURCE, + ':village:packageDebugResources': FROM_CACHE, + ':village:parseDebugLocalResources': FROM_CACHE, + ':village:preBuild': UP_TO_DATE, + ':village:preDebugBuild': UP_TO_DATE, + ':village:prepareLintJarForPublish': SUCCESS, + ':village:processDebugJavaRes': NO_SOURCE, + ':village:processDebugManifest': FROM_CACHE, + ':village:stripDebugDebugSymbols': FROM_CACHE, + ':village:syncDebugLibJars': FROM_CACHE, + ] +} diff --git a/subprojects/smoke-test/src/smokeTest/groovy/org/gradle/smoketests/AndroidSantaTrackerKotlinCachingSmokeTest.groovy b/subprojects/smoke-test/src/smokeTest/groovy/org/gradle/smoketests/AndroidSantaTrackerKotlinCachingSmokeTest.groovy new file mode 100644 index 000000000000..f9f3643ca0a2 --- /dev/null +++ b/subprojects/smoke-test/src/smokeTest/groovy/org/gradle/smoketests/AndroidSantaTrackerKotlinCachingSmokeTest.groovy @@ -0,0 +1,1694 @@ +/* + * Copyright 2020 the original author or authors. + * + * 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.gradle.smoketests + +import org.gradle.integtests.fixtures.ToBeFixedForInstantExecution +import org.gradle.testkit.runner.BuildResult +import org.gradle.util.Requires +import org.gradle.util.TestPrecondition +import spock.lang.Unroll + +import static org.gradle.testkit.runner.TaskOutcome.FROM_CACHE +import static org.gradle.testkit.runner.TaskOutcome.NO_SOURCE +import static org.gradle.testkit.runner.TaskOutcome.SUCCESS +import static org.gradle.testkit.runner.TaskOutcome.UP_TO_DATE + + +@Requires(TestPrecondition.JDK11_OR_EARLIER) +class AndroidSantaTrackerKotlinCachingSmokeTest extends AbstractAndroidSantaTrackerSmokeTest { + + @Unroll + @ToBeFixedForInstantExecution + def "can cache Santa Tracker Kotlin Android application (agp=#agpVersion)"() { + + given: + def originalDir = temporaryFolder.createDir("original") + def relocatedDir = temporaryFolder.createDir("relocated") + + and: + setupCopyOfSantaTracker(originalDir, 'Kotlin', agpVersion) + setupCopyOfSantaTracker(relocatedDir, 'Kotlin', agpVersion) + + when: + buildLocation(originalDir, agpVersion) + BuildResult relocatedResult = buildLocation(relocatedDir, agpVersion) + + then: + def expectedResults = agpVersion.startsWith('3.6') + ? EXPECTED_RESULTS_3_6 + : agpVersion.startsWith('4.0.0-alpha') + ? EXPECTED_RESULTS_4_0_ALPHA + : EXPECTED_RESULTS + verify(relocatedResult, expectedResults) + + where: + agpVersion << testedAgpVersions + } + + private static final EXPECTED_RESULTS = [ + ':cityquiz:assembleDebug': SUCCESS, + ':cityquiz:checkDebugDuplicateClasses': FROM_CACHE, + ':cityquiz:compileDebugAidl': NO_SOURCE, + ':cityquiz:compileDebugJavaWithJavac': FROM_CACHE, + ':cityquiz:compileDebugKotlin': FROM_CACHE, + ':cityquiz:compileDebugRenderscript': NO_SOURCE, + ':cityquiz:compileDebugShaders': NO_SOURCE, + ':cityquiz:compileDebugSources': UP_TO_DATE, + ':cityquiz:createDebugCompatibleScreenManifests': FROM_CACHE, + ':cityquiz:dexBuilderDebug': FROM_CACHE, + ':cityquiz:extractDeepLinksDebug': FROM_CACHE, + ':cityquiz:featureDebugWriter': SUCCESS, + ':cityquiz:generateDebugAssets': UP_TO_DATE, + ':cityquiz:generateDebugBuildConfig': FROM_CACHE, + ':cityquiz:generateDebugFeatureTransitiveDeps': FROM_CACHE, + ':cityquiz:generateDebugResValues': FROM_CACHE, + ':cityquiz:generateDebugResources': UP_TO_DATE, + ':cityquiz:javaPreCompileDebug': FROM_CACHE, + ':cityquiz:mergeDebugAssets': FROM_CACHE, + ':cityquiz:mergeDebugJavaResource': SUCCESS, + ':cityquiz:mergeDebugJniLibFolders': FROM_CACHE, + ':cityquiz:mergeDebugNativeLibs': FROM_CACHE, + ':cityquiz:mergeDebugResources': SUCCESS, + ':cityquiz:mergeDebugShaders': FROM_CACHE, + ':cityquiz:mergeExtDexDebug': FROM_CACHE, + ':cityquiz:mergeLibDexDebug': FROM_CACHE, + ':cityquiz:mergeProjectDexDebug': FROM_CACHE, + ':cityquiz:packageDebug': SUCCESS, + ':cityquiz:preBuild': UP_TO_DATE, + ':cityquiz:preDebugBuild': UP_TO_DATE, + ':cityquiz:processDebugJavaRes': NO_SOURCE, + ':cityquiz:processDebugManifest': FROM_CACHE, + ':cityquiz:processDebugResources': SUCCESS, + ':cityquiz:stripDebugDebugSymbols': NO_SOURCE, + ':common:assembleDebug': SUCCESS, + ':common:bundleDebugAar': SUCCESS, + ':common:bundleLibCompileToJarDebug': FROM_CACHE, + ':common:bundleLibResDebug': FROM_CACHE, + ':common:bundleLibRuntimeToJarDebug': FROM_CACHE, + ':common:compileDebugAidl': NO_SOURCE, + ':common:compileDebugJavaWithJavac': FROM_CACHE, + ':common:compileDebugKotlin': FROM_CACHE, + ':common:compileDebugLibraryResources': SUCCESS, + ':common:compileDebugRenderscript': NO_SOURCE, + ':common:compileDebugShaders': NO_SOURCE, + ':common:compileDebugSources': UP_TO_DATE, + ':common:copyDebugJniLibsProjectAndLocalJars': FROM_CACHE, + ':common:copyDebugJniLibsProjectOnly': FROM_CACHE, + ':common:createFullJarDebug': FROM_CACHE, + ':common:extractDebugAnnotations': FROM_CACHE, + ':common:extractDeepLinksDebug': FROM_CACHE, + ':common:generateDebugAssets': UP_TO_DATE, + ':common:generateDebugBuildConfig': FROM_CACHE, + ':common:generateDebugRFile': FROM_CACHE, + ':common:generateDebugResValues': FROM_CACHE, + ':common:generateDebugResources': UP_TO_DATE, + ':common:javaPreCompileDebug': FROM_CACHE, + ':common:mergeDebugConsumerProguardFiles': FROM_CACHE, + ':common:mergeDebugGeneratedProguardFiles': FROM_CACHE, + ':common:mergeDebugJavaResource': SUCCESS, + ':common:mergeDebugJniLibFolders': FROM_CACHE, + ':common:mergeDebugNativeLibs': FROM_CACHE, + ':common:mergeDebugShaders': FROM_CACHE, + ':common:packageDebugAssets': FROM_CACHE, + ':common:packageDebugRenderscript': NO_SOURCE, + ':common:packageDebugResources': FROM_CACHE, + ':common:parseDebugLocalResources': FROM_CACHE, + ':common:preBuild': UP_TO_DATE, + ':common:preDebugBuild': UP_TO_DATE, + ':common:prepareLintJarForPublish': SUCCESS, + ':common:processDebugJavaRes': NO_SOURCE, + ':common:processDebugManifest': FROM_CACHE, + ':common:stripDebugDebugSymbols': NO_SOURCE, + ':common:syncDebugLibJars': SUCCESS, + ':dasherdancer:assembleDebug': SUCCESS, + ':dasherdancer:checkDebugDuplicateClasses': FROM_CACHE, + ':dasherdancer:compileDebugAidl': NO_SOURCE, + ':dasherdancer:compileDebugJavaWithJavac': FROM_CACHE, + ':dasherdancer:compileDebugKotlin': FROM_CACHE, + ':dasherdancer:compileDebugRenderscript': NO_SOURCE, + ':dasherdancer:compileDebugShaders': NO_SOURCE, + ':dasherdancer:compileDebugSources': UP_TO_DATE, + ':dasherdancer:createDebugCompatibleScreenManifests': FROM_CACHE, + ':dasherdancer:dexBuilderDebug': FROM_CACHE, + ':dasherdancer:extractDeepLinksDebug': FROM_CACHE, + ':dasherdancer:featureDebugWriter': SUCCESS, + ':dasherdancer:generateDebugAssets': UP_TO_DATE, + ':dasherdancer:generateDebugBuildConfig': FROM_CACHE, + ':dasherdancer:generateDebugFeatureTransitiveDeps': FROM_CACHE, + ':dasherdancer:generateDebugResValues': FROM_CACHE, + ':dasherdancer:generateDebugResources': UP_TO_DATE, + ':dasherdancer:javaPreCompileDebug': FROM_CACHE, + ':dasherdancer:mergeDebugAssets': FROM_CACHE, + ':dasherdancer:mergeDebugJavaResource': SUCCESS, + ':dasherdancer:mergeDebugJniLibFolders': FROM_CACHE, + ':dasherdancer:mergeDebugNativeLibs': FROM_CACHE, + ':dasherdancer:mergeDebugResources': SUCCESS, + ':dasherdancer:mergeDebugShaders': FROM_CACHE, + ':dasherdancer:mergeExtDexDebug': FROM_CACHE, + ':dasherdancer:mergeLibDexDebug': FROM_CACHE, + ':dasherdancer:mergeProjectDexDebug': FROM_CACHE, + ':dasherdancer:packageDebug': SUCCESS, + ':dasherdancer:preBuild': UP_TO_DATE, + ':dasherdancer:preDebugBuild': UP_TO_DATE, + ':dasherdancer:processDebugJavaRes': NO_SOURCE, + ':dasherdancer:processDebugManifest': FROM_CACHE, + ':dasherdancer:processDebugResources': SUCCESS, + ':dasherdancer:stripDebugDebugSymbols': NO_SOURCE, + ':doodles-lib:assembleDebug': SUCCESS, + ':doodles-lib:bundleDebugAar': SUCCESS, + ':doodles-lib:bundleLibCompileToJarDebug': FROM_CACHE, + ':doodles-lib:bundleLibResDebug': NO_SOURCE, + ':doodles-lib:bundleLibRuntimeToJarDebug': FROM_CACHE, + ':doodles-lib:compileDebugAidl': NO_SOURCE, + ':doodles-lib:compileDebugJavaWithJavac': FROM_CACHE, + ':doodles-lib:compileDebugLibraryResources': SUCCESS, + ':doodles-lib:compileDebugRenderscript': NO_SOURCE, + ':doodles-lib:compileDebugShaders': NO_SOURCE, + ':doodles-lib:compileDebugSources': UP_TO_DATE, + ':doodles-lib:copyDebugJniLibsProjectAndLocalJars': FROM_CACHE, + ':doodles-lib:copyDebugJniLibsProjectOnly': FROM_CACHE, + ':doodles-lib:createFullJarDebug': FROM_CACHE, + ':doodles-lib:extractDebugAnnotations': FROM_CACHE, + ':doodles-lib:extractDeepLinksDebug': FROM_CACHE, + ':doodles-lib:generateDebugAssets': UP_TO_DATE, + ':doodles-lib:generateDebugBuildConfig': FROM_CACHE, + ':doodles-lib:generateDebugRFile': FROM_CACHE, + ':doodles-lib:generateDebugResValues': FROM_CACHE, + ':doodles-lib:generateDebugResources': UP_TO_DATE, + ':doodles-lib:javaPreCompileDebug': FROM_CACHE, + ':doodles-lib:mergeDebugConsumerProguardFiles': FROM_CACHE, + ':doodles-lib:mergeDebugGeneratedProguardFiles': FROM_CACHE, + ':doodles-lib:mergeDebugJavaResource': FROM_CACHE, + ':doodles-lib:mergeDebugJniLibFolders': FROM_CACHE, + ':doodles-lib:mergeDebugNativeLibs': FROM_CACHE, + ':doodles-lib:mergeDebugShaders': FROM_CACHE, + ':doodles-lib:packageDebugAssets': FROM_CACHE, + ':doodles-lib:packageDebugRenderscript': NO_SOURCE, + ':doodles-lib:packageDebugResources': FROM_CACHE, + ':doodles-lib:parseDebugLocalResources': FROM_CACHE, + ':doodles-lib:preBuild': UP_TO_DATE, + ':doodles-lib:preDebugBuild': UP_TO_DATE, + ':doodles-lib:prepareLintJarForPublish': SUCCESS, + ':doodles-lib:processDebugJavaRes': NO_SOURCE, + ':doodles-lib:processDebugManifest': FROM_CACHE, + ':doodles-lib:stripDebugDebugSymbols': NO_SOURCE, + ':doodles-lib:syncDebugLibJars': FROM_CACHE, + ':gumball:assembleDebug': SUCCESS, + ':gumball:checkDebugDuplicateClasses': FROM_CACHE, + ':gumball:compileDebugAidl': NO_SOURCE, + ':gumball:compileDebugJavaWithJavac': FROM_CACHE, + ':gumball:compileDebugRenderscript': NO_SOURCE, + ':gumball:compileDebugShaders': NO_SOURCE, + ':gumball:compileDebugSources': UP_TO_DATE, + ':gumball:createDebugCompatibleScreenManifests': FROM_CACHE, + ':gumball:dexBuilderDebug': FROM_CACHE, + ':gumball:extractDeepLinksDebug': FROM_CACHE, + ':gumball:featureDebugWriter': SUCCESS, + ':gumball:generateDebugAssets': UP_TO_DATE, + ':gumball:generateDebugBuildConfig': FROM_CACHE, + ':gumball:generateDebugFeatureTransitiveDeps': FROM_CACHE, + ':gumball:generateDebugResValues': FROM_CACHE, + ':gumball:generateDebugResources': UP_TO_DATE, + ':gumball:javaPreCompileDebug': FROM_CACHE, + ':gumball:mergeDebugAssets': FROM_CACHE, + ':gumball:mergeDebugJavaResource': FROM_CACHE, + ':gumball:mergeDebugJniLibFolders': FROM_CACHE, + ':gumball:mergeDebugNativeLibs': FROM_CACHE, + ':gumball:mergeDebugResources': SUCCESS, + ':gumball:mergeDebugShaders': FROM_CACHE, + ':gumball:mergeExtDexDebug': FROM_CACHE, + ':gumball:mergeLibDexDebug': FROM_CACHE, + ':gumball:mergeProjectDexDebug': FROM_CACHE, + ':gumball:packageDebug': SUCCESS, + ':gumball:preBuild': UP_TO_DATE, + ':gumball:preDebugBuild': UP_TO_DATE, + ':gumball:processDebugJavaRes': NO_SOURCE, + ':gumball:processDebugManifest': FROM_CACHE, + ':gumball:processDebugResources': SUCCESS, + ':gumball:stripDebugDebugSymbols': NO_SOURCE, + ':jetpack:assembleDebug': SUCCESS, + ':jetpack:checkDebugDuplicateClasses': FROM_CACHE, + ':jetpack:compileDebugAidl': NO_SOURCE, + ':jetpack:compileDebugJavaWithJavac': FROM_CACHE, + ':jetpack:compileDebugKotlin': FROM_CACHE, + ':jetpack:compileDebugRenderscript': NO_SOURCE, + ':jetpack:compileDebugShaders': NO_SOURCE, + ':jetpack:compileDebugSources': UP_TO_DATE, + ':jetpack:createDebugCompatibleScreenManifests': FROM_CACHE, + ':jetpack:dexBuilderDebug': FROM_CACHE, + ':jetpack:extractDeepLinksDebug': FROM_CACHE, + ':jetpack:featureDebugWriter': SUCCESS, + ':jetpack:generateDebugAssets': UP_TO_DATE, + ':jetpack:generateDebugBuildConfig': FROM_CACHE, + ':jetpack:generateDebugFeatureTransitiveDeps': FROM_CACHE, + ':jetpack:generateDebugResValues': FROM_CACHE, + ':jetpack:generateDebugResources': UP_TO_DATE, + ':jetpack:javaPreCompileDebug': FROM_CACHE, + ':jetpack:mergeDebugAssets': FROM_CACHE, + ':jetpack:mergeDebugJavaResource': SUCCESS, + ':jetpack:mergeDebugJniLibFolders': FROM_CACHE, + ':jetpack:mergeDebugNativeLibs': FROM_CACHE, + ':jetpack:mergeDebugResources': SUCCESS, + ':jetpack:mergeDebugShaders': FROM_CACHE, + ':jetpack:mergeExtDexDebug': FROM_CACHE, + ':jetpack:mergeLibDexDebug': FROM_CACHE, + ':jetpack:mergeProjectDexDebug': FROM_CACHE, + ':jetpack:packageDebug': SUCCESS, + ':jetpack:preBuild': UP_TO_DATE, + ':jetpack:preDebugBuild': UP_TO_DATE, + ':jetpack:processDebugJavaRes': NO_SOURCE, + ':jetpack:processDebugManifest': FROM_CACHE, + ':jetpack:processDebugResources': SUCCESS, + ':jetpack:stripDebugDebugSymbols': NO_SOURCE, + ':memory:assembleDebug': SUCCESS, + ':memory:checkDebugDuplicateClasses': FROM_CACHE, + ':memory:compileDebugAidl': NO_SOURCE, + ':memory:compileDebugJavaWithJavac': FROM_CACHE, + ':memory:compileDebugRenderscript': NO_SOURCE, + ':memory:compileDebugShaders': NO_SOURCE, + ':memory:compileDebugSources': UP_TO_DATE, + ':memory:createDebugCompatibleScreenManifests': FROM_CACHE, + ':memory:dexBuilderDebug': FROM_CACHE, + ':memory:extractDeepLinksDebug': FROM_CACHE, + ':memory:featureDebugWriter': SUCCESS, + ':memory:generateDebugAssets': UP_TO_DATE, + ':memory:generateDebugBuildConfig': FROM_CACHE, + ':memory:generateDebugFeatureTransitiveDeps': FROM_CACHE, + ':memory:generateDebugResValues': FROM_CACHE, + ':memory:generateDebugResources': UP_TO_DATE, + ':memory:javaPreCompileDebug': FROM_CACHE, + ':memory:mergeDebugAssets': FROM_CACHE, + ':memory:mergeDebugJavaResource': FROM_CACHE, + ':memory:mergeDebugJniLibFolders': FROM_CACHE, + ':memory:mergeDebugNativeLibs': FROM_CACHE, + ':memory:mergeDebugResources': SUCCESS, + ':memory:mergeDebugShaders': FROM_CACHE, + ':memory:mergeExtDexDebug': FROM_CACHE, + ':memory:mergeLibDexDebug': FROM_CACHE, + ':memory:mergeProjectDexDebug': FROM_CACHE, + ':memory:packageDebug': SUCCESS, + ':memory:preBuild': UP_TO_DATE, + ':memory:preDebugBuild': UP_TO_DATE, + ':memory:processDebugJavaRes': NO_SOURCE, + ':memory:processDebugManifest': FROM_CACHE, + ':memory:processDebugResources': SUCCESS, + ':memory:stripDebugDebugSymbols': NO_SOURCE, + ':penguinswim:assembleDebug': SUCCESS, + ':penguinswim:checkDebugDuplicateClasses': FROM_CACHE, + ':penguinswim:compileDebugAidl': NO_SOURCE, + ':penguinswim:compileDebugJavaWithJavac': FROM_CACHE, + ':penguinswim:compileDebugRenderscript': NO_SOURCE, + ':penguinswim:compileDebugShaders': NO_SOURCE, + ':penguinswim:compileDebugSources': UP_TO_DATE, + ':penguinswim:createDebugCompatibleScreenManifests': FROM_CACHE, + ':penguinswim:dexBuilderDebug': FROM_CACHE, + ':penguinswim:extractDeepLinksDebug': FROM_CACHE, + ':penguinswim:featureDebugWriter': SUCCESS, + ':penguinswim:generateDebugAssets': UP_TO_DATE, + ':penguinswim:generateDebugBuildConfig': FROM_CACHE, + ':penguinswim:generateDebugFeatureTransitiveDeps': FROM_CACHE, + ':penguinswim:generateDebugResValues': FROM_CACHE, + ':penguinswim:generateDebugResources': UP_TO_DATE, + ':penguinswim:javaPreCompileDebug': FROM_CACHE, + ':penguinswim:mergeDebugAssets': FROM_CACHE, + ':penguinswim:mergeDebugJavaResource': FROM_CACHE, + ':penguinswim:mergeDebugJniLibFolders': FROM_CACHE, + ':penguinswim:mergeDebugNativeLibs': FROM_CACHE, + ':penguinswim:mergeDebugResources': SUCCESS, + ':penguinswim:mergeDebugShaders': FROM_CACHE, + ':penguinswim:mergeExtDexDebug': FROM_CACHE, + ':penguinswim:mergeLibDexDebug': FROM_CACHE, + ':penguinswim:mergeProjectDexDebug': FROM_CACHE, + ':penguinswim:packageDebug': SUCCESS, + ':penguinswim:preBuild': UP_TO_DATE, + ':penguinswim:preDebugBuild': UP_TO_DATE, + ':penguinswim:processDebugJavaRes': NO_SOURCE, + ':penguinswim:processDebugManifest': FROM_CACHE, + ':penguinswim:processDebugResources': SUCCESS, + ':penguinswim:stripDebugDebugSymbols': NO_SOURCE, + ':playgames:assembleDebug': SUCCESS, + ':playgames:bundleDebugAar': SUCCESS, + ':playgames:bundleLibCompileToJarDebug': FROM_CACHE, + ':playgames:bundleLibResDebug': NO_SOURCE, + ':playgames:bundleLibRuntimeToJarDebug': FROM_CACHE, + ':playgames:compileDebugAidl': NO_SOURCE, + ':playgames:compileDebugJavaWithJavac': FROM_CACHE, + ':playgames:compileDebugLibraryResources': SUCCESS, + ':playgames:compileDebugRenderscript': NO_SOURCE, + ':playgames:compileDebugShaders': NO_SOURCE, + ':playgames:compileDebugSources': UP_TO_DATE, + ':playgames:copyDebugJniLibsProjectAndLocalJars': FROM_CACHE, + ':playgames:copyDebugJniLibsProjectOnly': FROM_CACHE, + ':playgames:createFullJarDebug': FROM_CACHE, + ':playgames:extractDebugAnnotations': FROM_CACHE, + ':playgames:extractDeepLinksDebug': FROM_CACHE, + ':playgames:generateDebugAssets': UP_TO_DATE, + ':playgames:generateDebugBuildConfig': FROM_CACHE, + ':playgames:generateDebugRFile': FROM_CACHE, + ':playgames:generateDebugResValues': FROM_CACHE, + ':playgames:generateDebugResources': UP_TO_DATE, + ':playgames:javaPreCompileDebug': FROM_CACHE, + ':playgames:mergeDebugConsumerProguardFiles': FROM_CACHE, + ':playgames:mergeDebugGeneratedProguardFiles': FROM_CACHE, + ':playgames:mergeDebugJavaResource': FROM_CACHE, + ':playgames:mergeDebugJniLibFolders': FROM_CACHE, + ':playgames:mergeDebugNativeLibs': FROM_CACHE, + ':playgames:mergeDebugShaders': FROM_CACHE, + ':playgames:packageDebugAssets': FROM_CACHE, + ':playgames:packageDebugRenderscript': NO_SOURCE, + ':playgames:packageDebugResources': FROM_CACHE, + ':playgames:parseDebugLocalResources': FROM_CACHE, + ':playgames:preBuild': UP_TO_DATE, + ':playgames:preDebugBuild': UP_TO_DATE, + ':playgames:prepareLintJarForPublish': SUCCESS, + ':playgames:processDebugJavaRes': NO_SOURCE, + ':playgames:processDebugManifest': FROM_CACHE, + ':playgames:stripDebugDebugSymbols': NO_SOURCE, + ':playgames:syncDebugLibJars': FROM_CACHE, + ':presenttoss:assembleDebug': SUCCESS, + ':presenttoss:checkDebugDuplicateClasses': FROM_CACHE, + ':presenttoss:compileDebugAidl': NO_SOURCE, + ':presenttoss:compileDebugJavaWithJavac': FROM_CACHE, + ':presenttoss:compileDebugRenderscript': NO_SOURCE, + ':presenttoss:compileDebugShaders': NO_SOURCE, + ':presenttoss:compileDebugSources': UP_TO_DATE, + ':presenttoss:createDebugCompatibleScreenManifests': FROM_CACHE, + ':presenttoss:dexBuilderDebug': FROM_CACHE, + ':presenttoss:extractDeepLinksDebug': FROM_CACHE, + ':presenttoss:featureDebugWriter': SUCCESS, + ':presenttoss:generateDebugAssets': UP_TO_DATE, + ':presenttoss:generateDebugBuildConfig': FROM_CACHE, + ':presenttoss:generateDebugFeatureTransitiveDeps': FROM_CACHE, + ':presenttoss:generateDebugResValues': FROM_CACHE, + ':presenttoss:generateDebugResources': UP_TO_DATE, + ':presenttoss:javaPreCompileDebug': FROM_CACHE, + ':presenttoss:mergeDebugAssets': FROM_CACHE, + ':presenttoss:mergeDebugJavaResource': FROM_CACHE, + ':presenttoss:mergeDebugJniLibFolders': FROM_CACHE, + ':presenttoss:mergeDebugNativeLibs': FROM_CACHE, + ':presenttoss:mergeDebugResources': SUCCESS, + ':presenttoss:mergeDebugShaders': FROM_CACHE, + ':presenttoss:mergeExtDexDebug': FROM_CACHE, + ':presenttoss:mergeLibDexDebug': FROM_CACHE, + ':presenttoss:mergeProjectDexDebug': FROM_CACHE, + ':presenttoss:packageDebug': SUCCESS, + ':presenttoss:preBuild': UP_TO_DATE, + ':presenttoss:preDebugBuild': UP_TO_DATE, + ':presenttoss:processDebugJavaRes': NO_SOURCE, + ':presenttoss:processDebugManifest': FROM_CACHE, + ':presenttoss:processDebugResources': SUCCESS, + ':presenttoss:stripDebugDebugSymbols': NO_SOURCE, + ':rocketsleigh:assembleDebug': SUCCESS, + ':rocketsleigh:checkDebugDuplicateClasses': FROM_CACHE, + ':rocketsleigh:compileDebugAidl': NO_SOURCE, + ':rocketsleigh:compileDebugJavaWithJavac': FROM_CACHE, + ':rocketsleigh:compileDebugKotlin': FROM_CACHE, + ':rocketsleigh:compileDebugRenderscript': NO_SOURCE, + ':rocketsleigh:compileDebugShaders': NO_SOURCE, + ':rocketsleigh:compileDebugSources': UP_TO_DATE, + ':rocketsleigh:createDebugCompatibleScreenManifests': FROM_CACHE, + ':rocketsleigh:dexBuilderDebug': FROM_CACHE, + ':rocketsleigh:extractDeepLinksDebug': FROM_CACHE, + ':rocketsleigh:featureDebugWriter': SUCCESS, + ':rocketsleigh:generateDebugAssets': UP_TO_DATE, + ':rocketsleigh:generateDebugBuildConfig': FROM_CACHE, + ':rocketsleigh:generateDebugFeatureTransitiveDeps': FROM_CACHE, + ':rocketsleigh:generateDebugResValues': FROM_CACHE, + ':rocketsleigh:generateDebugResources': UP_TO_DATE, + ':rocketsleigh:javaPreCompileDebug': FROM_CACHE, + ':rocketsleigh:mergeDebugAssets': FROM_CACHE, + ':rocketsleigh:mergeDebugJavaResource': SUCCESS, + ':rocketsleigh:mergeDebugJniLibFolders': FROM_CACHE, + ':rocketsleigh:mergeDebugNativeLibs': FROM_CACHE, + ':rocketsleigh:mergeDebugResources': SUCCESS, + ':rocketsleigh:mergeDebugShaders': FROM_CACHE, + ':rocketsleigh:mergeExtDexDebug': FROM_CACHE, + ':rocketsleigh:mergeLibDexDebug': FROM_CACHE, + ':rocketsleigh:mergeProjectDexDebug': FROM_CACHE, + ':rocketsleigh:packageDebug': SUCCESS, + ':rocketsleigh:preBuild': UP_TO_DATE, + ':rocketsleigh:preDebugBuild': UP_TO_DATE, + ':rocketsleigh:processDebugJavaRes': NO_SOURCE, + ':rocketsleigh:processDebugManifest': FROM_CACHE, + ':rocketsleigh:processDebugResources': SUCCESS, + ':rocketsleigh:stripDebugDebugSymbols': NO_SOURCE, + ':santa-tracker:assembleDebug': SUCCESS, + ':santa-tracker:bundleDebugClasses': FROM_CACHE, + ':santa-tracker:checkDebugDuplicateClasses': FROM_CACHE, + ':santa-tracker:checkDebugLibraries': FROM_CACHE, + ':santa-tracker:compileDebugAidl': NO_SOURCE, + ':santa-tracker:compileDebugJavaWithJavac': FROM_CACHE, + ':santa-tracker:compileDebugKotlin': FROM_CACHE, + ':santa-tracker:compileDebugRenderscript': NO_SOURCE, + ':santa-tracker:compileDebugShaders': NO_SOURCE, + ':santa-tracker:compileDebugSources': UP_TO_DATE, + ':santa-tracker:createDebugCompatibleScreenManifests': FROM_CACHE, + ':santa-tracker:dexBuilderDebug': FROM_CACHE, + ':santa-tracker:extractDeepLinksDebug': FROM_CACHE, + ':santa-tracker:generateDebugAssets': UP_TO_DATE, + ':santa-tracker:generateDebugBuildConfig': FROM_CACHE, + ':santa-tracker:generateDebugFeatureMetadata': FROM_CACHE, + ':santa-tracker:generateDebugFeatureTransitiveDeps': FROM_CACHE, + ':santa-tracker:generateDebugResValues': FROM_CACHE, + ':santa-tracker:generateDebugResources': UP_TO_DATE, + ':santa-tracker:handleDebugMicroApk': FROM_CACHE, + ':santa-tracker:javaPreCompileDebug': FROM_CACHE, + ':santa-tracker:kaptDebugKotlin': SUCCESS, + ':santa-tracker:kaptGenerateStubsDebugKotlin': FROM_CACHE, + ':santa-tracker:mergeDebugAssets': FROM_CACHE, + ':santa-tracker:mergeDebugJavaResource': SUCCESS, + ':santa-tracker:mergeDebugJniLibFolders': FROM_CACHE, + ':santa-tracker:mergeDebugNativeLibs': FROM_CACHE, + ':santa-tracker:mergeDebugResources': SUCCESS, + ':santa-tracker:mergeDebugShaders': FROM_CACHE, + ':santa-tracker:mergeExtDexDebug': FROM_CACHE, + ':santa-tracker:mergeLibDexDebug': FROM_CACHE, + ':santa-tracker:mergeProjectDexDebug': FROM_CACHE, + ':santa-tracker:packageDebug': SUCCESS, + ':santa-tracker:preBuild': UP_TO_DATE, + ':santa-tracker:preDebugBuild': FROM_CACHE, + ':santa-tracker:processDebugJavaRes': NO_SOURCE, + ':santa-tracker:processDebugManifest': FROM_CACHE, + ':santa-tracker:processDebugResources': SUCCESS, + ':santa-tracker:signingConfigWriterDebug': FROM_CACHE, + ':santa-tracker:stripDebugDebugSymbols': NO_SOURCE, + ':santa-tracker:validateSigningDebug': FROM_CACHE, + ':santa-tracker:writeDebugModuleMetadata': SUCCESS, + ':snowballrun:assembleDebug': SUCCESS, + ':snowballrun:checkDebugDuplicateClasses': FROM_CACHE, + ':snowballrun:compileDebugAidl': NO_SOURCE, + ':snowballrun:compileDebugJavaWithJavac': FROM_CACHE, + ':snowballrun:compileDebugRenderscript': NO_SOURCE, + ':snowballrun:compileDebugShaders': NO_SOURCE, + ':snowballrun:compileDebugSources': UP_TO_DATE, + ':snowballrun:createDebugCompatibleScreenManifests': FROM_CACHE, + ':snowballrun:dexBuilderDebug': FROM_CACHE, + ':snowballrun:extractDeepLinksDebug': FROM_CACHE, + ':snowballrun:featureDebugWriter': SUCCESS, + ':snowballrun:generateDebugAssets': UP_TO_DATE, + ':snowballrun:generateDebugBuildConfig': FROM_CACHE, + ':snowballrun:generateDebugFeatureTransitiveDeps': FROM_CACHE, + ':snowballrun:generateDebugResValues': FROM_CACHE, + ':snowballrun:generateDebugResources': UP_TO_DATE, + ':snowballrun:javaPreCompileDebug': FROM_CACHE, + ':snowballrun:mergeDebugAssets': FROM_CACHE, + ':snowballrun:mergeDebugJavaResource': FROM_CACHE, + ':snowballrun:mergeDebugJniLibFolders': FROM_CACHE, + ':snowballrun:mergeDebugNativeLibs': FROM_CACHE, + ':snowballrun:mergeDebugResources': SUCCESS, + ':snowballrun:mergeDebugShaders': FROM_CACHE, + ':snowballrun:mergeExtDexDebug': FROM_CACHE, + ':snowballrun:mergeLibDexDebug': FROM_CACHE, + ':snowballrun:mergeProjectDexDebug': FROM_CACHE, + ':snowballrun:packageDebug': SUCCESS, + ':snowballrun:preBuild': UP_TO_DATE, + ':snowballrun:preDebugBuild': UP_TO_DATE, + ':snowballrun:processDebugJavaRes': NO_SOURCE, + ':snowballrun:processDebugManifest': FROM_CACHE, + ':snowballrun:processDebugResources': SUCCESS, + ':snowballrun:stripDebugDebugSymbols': NO_SOURCE, + ':tracker:assembleDebug': SUCCESS, + ':tracker:bundleDebugAar': SUCCESS, + ':tracker:bundleLibCompileToJarDebug': FROM_CACHE, + ':tracker:bundleLibResDebug': FROM_CACHE, + ':tracker:bundleLibRuntimeToJarDebug': FROM_CACHE, + ':tracker:compileDebugAidl': NO_SOURCE, + ':tracker:compileDebugJavaWithJavac': SUCCESS, + ':tracker:compileDebugKotlin': FROM_CACHE, + ':tracker:compileDebugLibraryResources': SUCCESS, + ':tracker:compileDebugRenderscript': NO_SOURCE, + ':tracker:compileDebugShaders': NO_SOURCE, + ':tracker:compileDebugSources': SUCCESS, + ':tracker:copyDebugJniLibsProjectAndLocalJars': FROM_CACHE, + ':tracker:copyDebugJniLibsProjectOnly': FROM_CACHE, + ':tracker:createFullJarDebug': FROM_CACHE, + ':tracker:extractDebugAnnotations': FROM_CACHE, + ':tracker:extractDeepLinksDebug': FROM_CACHE, + ':tracker:generateDebugAssets': UP_TO_DATE, + ':tracker:generateDebugBuildConfig': FROM_CACHE, + ':tracker:generateDebugRFile': FROM_CACHE, + ':tracker:generateDebugResValues': FROM_CACHE, + ':tracker:generateDebugResources': UP_TO_DATE, + ':tracker:javaPreCompileDebug': FROM_CACHE, + ':tracker:kaptDebugKotlin': SUCCESS, + ':tracker:kaptGenerateStubsDebugKotlin': SUCCESS, + ':tracker:mergeDebugConsumerProguardFiles': FROM_CACHE, + ':tracker:mergeDebugGeneratedProguardFiles': FROM_CACHE, + ':tracker:mergeDebugJavaResource': SUCCESS, + ':tracker:mergeDebugJniLibFolders': FROM_CACHE, + ':tracker:mergeDebugNativeLibs': FROM_CACHE, + ':tracker:mergeDebugResources': FROM_CACHE, + ':tracker:mergeDebugShaders': FROM_CACHE, + ':tracker:packageDebugAssets': FROM_CACHE, + ':tracker:packageDebugRenderscript': NO_SOURCE, + ':tracker:packageDebugResources': FROM_CACHE, + ':tracker:parseDebugLocalResources': FROM_CACHE, + ':tracker:preBuild': UP_TO_DATE, + ':tracker:preDebugBuild': UP_TO_DATE, + ':tracker:prepareLintJarForPublish': SUCCESS, + ':tracker:processDebugJavaRes': NO_SOURCE, + ':tracker:processDebugManifest': FROM_CACHE, + ':tracker:stripDebugDebugSymbols': NO_SOURCE, + ':tracker:syncDebugLibJars': SUCCESS, + ':wearable:assembleDebug': SUCCESS, + ':wearable:checkDebugDuplicateClasses': FROM_CACHE, + ':wearable:compileDebugAidl': NO_SOURCE, + ':wearable:compileDebugJavaWithJavac': FROM_CACHE, + ':wearable:compileDebugKotlin': FROM_CACHE, + ':wearable:compileDebugRenderscript': NO_SOURCE, + ':wearable:compileDebugShaders': NO_SOURCE, + ':wearable:compileDebugSources': UP_TO_DATE, + ':wearable:createDebugCompatibleScreenManifests': FROM_CACHE, + ':wearable:dexBuilderDebug': FROM_CACHE, + ':wearable:extractDeepLinksDebug': FROM_CACHE, + ':wearable:generateDebugAssets': UP_TO_DATE, + ':wearable:generateDebugBuildConfig': FROM_CACHE, + ':wearable:generateDebugResValues': FROM_CACHE, + ':wearable:generateDebugResources': UP_TO_DATE, + ':wearable:javaPreCompileDebug': FROM_CACHE, + ':wearable:kaptDebugKotlin': SUCCESS, + ':wearable:kaptGenerateStubsDebugKotlin': FROM_CACHE, + ':wearable:mergeDebugAssets': FROM_CACHE, + ':wearable:mergeDebugJavaResource': SUCCESS, + ':wearable:mergeDebugJniLibFolders': FROM_CACHE, + ':wearable:mergeDebugNativeLibs': FROM_CACHE, + ':wearable:mergeDebugResources': SUCCESS, + ':wearable:mergeDebugShaders': FROM_CACHE, + ':wearable:mergeExtDexDebug': FROM_CACHE, + ':wearable:mergeLibDexDebug': FROM_CACHE, + ':wearable:mergeProjectDexDebug': FROM_CACHE, + ':wearable:packageDebug': SUCCESS, + ':wearable:preBuild': UP_TO_DATE, + ':wearable:preDebugBuild': UP_TO_DATE, + ':wearable:processDebugJavaRes': NO_SOURCE, + ':wearable:processDebugManifest': FROM_CACHE, + ':wearable:processDebugResources': SUCCESS, + ':wearable:stripDebugDebugSymbols': NO_SOURCE, + ':wearable:validateSigningDebug': FROM_CACHE, + ] + + private static final EXPECTED_RESULTS_4_0_ALPHA = [ + ':cityquiz:assembleDebug': SUCCESS, + ':cityquiz:checkDebugDuplicateClasses': FROM_CACHE, + ':cityquiz:compileDebugAidl': NO_SOURCE, + ':cityquiz:compileDebugJavaWithJavac': FROM_CACHE, + ':cityquiz:compileDebugKotlin': FROM_CACHE, + ':cityquiz:compileDebugRenderscript': NO_SOURCE, + ':cityquiz:compileDebugShaders': NO_SOURCE, + ':cityquiz:compileDebugSources': UP_TO_DATE, + ':cityquiz:createDebugCompatibleScreenManifests': FROM_CACHE, + ':cityquiz:dexBuilderDebug': FROM_CACHE, + ':cityquiz:extractDeepLinksDebug': FROM_CACHE, + ':cityquiz:featureDebugWriter': SUCCESS, + ':cityquiz:generateDebugAssets': UP_TO_DATE, + ':cityquiz:generateDebugBuildConfig': FROM_CACHE, + ':cityquiz:generateDebugFeatureTransitiveDeps': FROM_CACHE, + ':cityquiz:generateDebugResValues': FROM_CACHE, + ':cityquiz:generateDebugResources': UP_TO_DATE, + ':cityquiz:javaPreCompileDebug': FROM_CACHE, + ':cityquiz:mergeDebugAssets': FROM_CACHE, + ':cityquiz:mergeDebugJavaResource': SUCCESS, + ':cityquiz:mergeDebugJniLibFolders': FROM_CACHE, + ':cityquiz:mergeDebugNativeLibs': FROM_CACHE, + ':cityquiz:mergeDebugResources': SUCCESS, + ':cityquiz:mergeDebugShaders': FROM_CACHE, + ':cityquiz:mergeExtDexDebug': FROM_CACHE, + ':cityquiz:mergeLibDexDebug': FROM_CACHE, + ':cityquiz:mergeProjectDexDebug': FROM_CACHE, + ':cityquiz:packageDebug': SUCCESS, + ':cityquiz:preBuild': UP_TO_DATE, + ':cityquiz:preDebugBuild': UP_TO_DATE, + ':cityquiz:processDebugJavaRes': NO_SOURCE, + ':cityquiz:processDebugManifest': FROM_CACHE, + ':cityquiz:processDebugResources': SUCCESS, + ':cityquiz:stripDebugDebugSymbols': FROM_CACHE, + ':common:assembleDebug': SUCCESS, + ':common:bundleDebugAar': SUCCESS, + ':common:bundleLibCompileDebug': FROM_CACHE, + ':common:bundleLibResDebug': FROM_CACHE, + ':common:bundleLibRuntimeDebug': FROM_CACHE, + ':common:compileDebugAidl': NO_SOURCE, + ':common:compileDebugJavaWithJavac': FROM_CACHE, + ':common:compileDebugKotlin': FROM_CACHE, + ':common:compileDebugLibraryResources': SUCCESS, + ':common:compileDebugRenderscript': NO_SOURCE, + ':common:compileDebugShaders': NO_SOURCE, + ':common:compileDebugSources': UP_TO_DATE, + ':common:copyDebugJniLibsProjectAndLocalJars': FROM_CACHE, + ':common:copyDebugJniLibsProjectOnly': FROM_CACHE, + ':common:createFullJarDebug': FROM_CACHE, + ':common:extractDebugAnnotations': FROM_CACHE, + ':common:extractDeepLinksDebug': FROM_CACHE, + ':common:generateDebugAssets': UP_TO_DATE, + ':common:generateDebugBuildConfig': FROM_CACHE, + ':common:generateDebugRFile': FROM_CACHE, + ':common:generateDebugResValues': FROM_CACHE, + ':common:generateDebugResources': UP_TO_DATE, + ':common:javaPreCompileDebug': FROM_CACHE, + ':common:mergeDebugConsumerProguardFiles': FROM_CACHE, + ':common:mergeDebugGeneratedProguardFiles': FROM_CACHE, + ':common:mergeDebugJavaResource': SUCCESS, + ':common:mergeDebugJniLibFolders': FROM_CACHE, + ':common:mergeDebugNativeLibs': FROM_CACHE, + ':common:mergeDebugShaders': FROM_CACHE, + ':common:packageDebugAssets': FROM_CACHE, + ':common:packageDebugRenderscript': NO_SOURCE, + ':common:packageDebugResources': FROM_CACHE, + ':common:parseDebugLocalResources': FROM_CACHE, + ':common:preBuild': UP_TO_DATE, + ':common:preDebugBuild': UP_TO_DATE, + ':common:prepareLintJarForPublish': SUCCESS, + ':common:processDebugJavaRes': NO_SOURCE, + ':common:processDebugManifest': FROM_CACHE, + ':common:stripDebugDebugSymbols': FROM_CACHE, + ':common:syncDebugLibJars': SUCCESS, + ':dasherdancer:assembleDebug': SUCCESS, + ':dasherdancer:checkDebugDuplicateClasses': FROM_CACHE, + ':dasherdancer:compileDebugAidl': NO_SOURCE, + ':dasherdancer:compileDebugJavaWithJavac': FROM_CACHE, + ':dasherdancer:compileDebugKotlin': FROM_CACHE, + ':dasherdancer:compileDebugRenderscript': NO_SOURCE, + ':dasherdancer:compileDebugShaders': NO_SOURCE, + ':dasherdancer:compileDebugSources': UP_TO_DATE, + ':dasherdancer:createDebugCompatibleScreenManifests': FROM_CACHE, + ':dasherdancer:dexBuilderDebug': FROM_CACHE, + ':dasherdancer:extractDeepLinksDebug': FROM_CACHE, + ':dasherdancer:featureDebugWriter': SUCCESS, + ':dasherdancer:generateDebugAssets': UP_TO_DATE, + ':dasherdancer:generateDebugBuildConfig': FROM_CACHE, + ':dasherdancer:generateDebugFeatureTransitiveDeps': FROM_CACHE, + ':dasherdancer:generateDebugResValues': FROM_CACHE, + ':dasherdancer:generateDebugResources': UP_TO_DATE, + ':dasherdancer:javaPreCompileDebug': FROM_CACHE, + ':dasherdancer:mergeDebugAssets': FROM_CACHE, + ':dasherdancer:mergeDebugJavaResource': SUCCESS, + ':dasherdancer:mergeDebugJniLibFolders': FROM_CACHE, + ':dasherdancer:mergeDebugNativeLibs': FROM_CACHE, + ':dasherdancer:mergeDebugResources': SUCCESS, + ':dasherdancer:mergeDebugShaders': FROM_CACHE, + ':dasherdancer:mergeExtDexDebug': FROM_CACHE, + ':dasherdancer:mergeLibDexDebug': FROM_CACHE, + ':dasherdancer:mergeProjectDexDebug': FROM_CACHE, + ':dasherdancer:packageDebug': SUCCESS, + ':dasherdancer:preBuild': UP_TO_DATE, + ':dasherdancer:preDebugBuild': UP_TO_DATE, + ':dasherdancer:processDebugJavaRes': NO_SOURCE, + ':dasherdancer:processDebugManifest': FROM_CACHE, + ':dasherdancer:processDebugResources': SUCCESS, + ':dasherdancer:stripDebugDebugSymbols': FROM_CACHE, + ':doodles-lib:assembleDebug': SUCCESS, + ':doodles-lib:bundleDebugAar': SUCCESS, + ':doodles-lib:bundleLibCompileDebug': FROM_CACHE, + ':doodles-lib:bundleLibResDebug': FROM_CACHE, + ':doodles-lib:bundleLibRuntimeDebug': FROM_CACHE, + ':doodles-lib:compileDebugAidl': NO_SOURCE, + ':doodles-lib:compileDebugJavaWithJavac': FROM_CACHE, + ':doodles-lib:compileDebugLibraryResources': SUCCESS, + ':doodles-lib:compileDebugRenderscript': NO_SOURCE, + ':doodles-lib:compileDebugShaders': NO_SOURCE, + ':doodles-lib:compileDebugSources': UP_TO_DATE, + ':doodles-lib:copyDebugJniLibsProjectAndLocalJars': FROM_CACHE, + ':doodles-lib:copyDebugJniLibsProjectOnly': FROM_CACHE, + ':doodles-lib:createFullJarDebug': FROM_CACHE, + ':doodles-lib:extractDebugAnnotations': FROM_CACHE, + ':doodles-lib:extractDeepLinksDebug': FROM_CACHE, + ':doodles-lib:generateDebugAssets': UP_TO_DATE, + ':doodles-lib:generateDebugBuildConfig': FROM_CACHE, + ':doodles-lib:generateDebugRFile': FROM_CACHE, + ':doodles-lib:generateDebugResValues': FROM_CACHE, + ':doodles-lib:generateDebugResources': UP_TO_DATE, + ':doodles-lib:javaPreCompileDebug': FROM_CACHE, + ':doodles-lib:mergeDebugConsumerProguardFiles': FROM_CACHE, + ':doodles-lib:mergeDebugGeneratedProguardFiles': FROM_CACHE, + ':doodles-lib:mergeDebugJavaResource': FROM_CACHE, + ':doodles-lib:mergeDebugJniLibFolders': FROM_CACHE, + ':doodles-lib:mergeDebugNativeLibs': FROM_CACHE, + ':doodles-lib:mergeDebugShaders': FROM_CACHE, + ':doodles-lib:packageDebugAssets': FROM_CACHE, + ':doodles-lib:packageDebugRenderscript': NO_SOURCE, + ':doodles-lib:packageDebugResources': FROM_CACHE, + ':doodles-lib:parseDebugLocalResources': FROM_CACHE, + ':doodles-lib:preBuild': UP_TO_DATE, + ':doodles-lib:preDebugBuild': UP_TO_DATE, + ':doodles-lib:prepareLintJarForPublish': SUCCESS, + ':doodles-lib:processDebugJavaRes': NO_SOURCE, + ':doodles-lib:processDebugManifest': FROM_CACHE, + ':doodles-lib:stripDebugDebugSymbols': FROM_CACHE, + ':doodles-lib:syncDebugLibJars': FROM_CACHE, + ':gumball:assembleDebug': SUCCESS, + ':gumball:checkDebugDuplicateClasses': FROM_CACHE, + ':gumball:compileDebugAidl': NO_SOURCE, + ':gumball:compileDebugJavaWithJavac': FROM_CACHE, + ':gumball:compileDebugRenderscript': NO_SOURCE, + ':gumball:compileDebugShaders': NO_SOURCE, + ':gumball:compileDebugSources': UP_TO_DATE, + ':gumball:createDebugCompatibleScreenManifests': FROM_CACHE, + ':gumball:dexBuilderDebug': FROM_CACHE, + ':gumball:extractDeepLinksDebug': FROM_CACHE, + ':gumball:featureDebugWriter': SUCCESS, + ':gumball:generateDebugAssets': UP_TO_DATE, + ':gumball:generateDebugBuildConfig': FROM_CACHE, + ':gumball:generateDebugFeatureTransitiveDeps': FROM_CACHE, + ':gumball:generateDebugResValues': FROM_CACHE, + ':gumball:generateDebugResources': UP_TO_DATE, + ':gumball:javaPreCompileDebug': FROM_CACHE, + ':gumball:mergeDebugAssets': FROM_CACHE, + ':gumball:mergeDebugJavaResource': FROM_CACHE, + ':gumball:mergeDebugJniLibFolders': FROM_CACHE, + ':gumball:mergeDebugNativeLibs': FROM_CACHE, + ':gumball:mergeDebugResources': SUCCESS, + ':gumball:mergeDebugShaders': FROM_CACHE, + ':gumball:mergeExtDexDebug': FROM_CACHE, + ':gumball:mergeLibDexDebug': FROM_CACHE, + ':gumball:mergeProjectDexDebug': FROM_CACHE, + ':gumball:packageDebug': SUCCESS, + ':gumball:preBuild': UP_TO_DATE, + ':gumball:preDebugBuild': UP_TO_DATE, + ':gumball:processDebugJavaRes': NO_SOURCE, + ':gumball:processDebugManifest': FROM_CACHE, + ':gumball:processDebugResources': SUCCESS, + ':gumball:stripDebugDebugSymbols': FROM_CACHE, + ':jetpack:assembleDebug': SUCCESS, + ':jetpack:checkDebugDuplicateClasses': FROM_CACHE, + ':jetpack:compileDebugAidl': NO_SOURCE, + ':jetpack:compileDebugJavaWithJavac': FROM_CACHE, + ':jetpack:compileDebugKotlin': FROM_CACHE, + ':jetpack:compileDebugRenderscript': NO_SOURCE, + ':jetpack:compileDebugShaders': NO_SOURCE, + ':jetpack:compileDebugSources': UP_TO_DATE, + ':jetpack:createDebugCompatibleScreenManifests': FROM_CACHE, + ':jetpack:dexBuilderDebug': FROM_CACHE, + ':jetpack:extractDeepLinksDebug': FROM_CACHE, + ':jetpack:featureDebugWriter': SUCCESS, + ':jetpack:generateDebugAssets': UP_TO_DATE, + ':jetpack:generateDebugBuildConfig': FROM_CACHE, + ':jetpack:generateDebugFeatureTransitiveDeps': FROM_CACHE, + ':jetpack:generateDebugResValues': FROM_CACHE, + ':jetpack:generateDebugResources': UP_TO_DATE, + ':jetpack:javaPreCompileDebug': FROM_CACHE, + ':jetpack:mergeDebugAssets': FROM_CACHE, + ':jetpack:mergeDebugJavaResource': SUCCESS, + ':jetpack:mergeDebugJniLibFolders': FROM_CACHE, + ':jetpack:mergeDebugNativeLibs': FROM_CACHE, + ':jetpack:mergeDebugResources': SUCCESS, + ':jetpack:mergeDebugShaders': FROM_CACHE, + ':jetpack:mergeExtDexDebug': FROM_CACHE, + ':jetpack:mergeLibDexDebug': FROM_CACHE, + ':jetpack:mergeProjectDexDebug': FROM_CACHE, + ':jetpack:packageDebug': SUCCESS, + ':jetpack:preBuild': UP_TO_DATE, + ':jetpack:preDebugBuild': UP_TO_DATE, + ':jetpack:processDebugJavaRes': NO_SOURCE, + ':jetpack:processDebugManifest': FROM_CACHE, + ':jetpack:processDebugResources': SUCCESS, + ':jetpack:stripDebugDebugSymbols': FROM_CACHE, + ':memory:assembleDebug': SUCCESS, + ':memory:checkDebugDuplicateClasses': FROM_CACHE, + ':memory:compileDebugAidl': NO_SOURCE, + ':memory:compileDebugJavaWithJavac': FROM_CACHE, + ':memory:compileDebugRenderscript': NO_SOURCE, + ':memory:compileDebugShaders': NO_SOURCE, + ':memory:compileDebugSources': UP_TO_DATE, + ':memory:createDebugCompatibleScreenManifests': FROM_CACHE, + ':memory:dexBuilderDebug': FROM_CACHE, + ':memory:extractDeepLinksDebug': FROM_CACHE, + ':memory:featureDebugWriter': SUCCESS, + ':memory:generateDebugAssets': UP_TO_DATE, + ':memory:generateDebugBuildConfig': FROM_CACHE, + ':memory:generateDebugFeatureTransitiveDeps': FROM_CACHE, + ':memory:generateDebugResValues': FROM_CACHE, + ':memory:generateDebugResources': UP_TO_DATE, + ':memory:javaPreCompileDebug': FROM_CACHE, + ':memory:mergeDebugAssets': FROM_CACHE, + ':memory:mergeDebugJavaResource': FROM_CACHE, + ':memory:mergeDebugJniLibFolders': FROM_CACHE, + ':memory:mergeDebugNativeLibs': FROM_CACHE, + ':memory:mergeDebugResources': SUCCESS, + ':memory:mergeDebugShaders': FROM_CACHE, + ':memory:mergeExtDexDebug': FROM_CACHE, + ':memory:mergeLibDexDebug': FROM_CACHE, + ':memory:mergeProjectDexDebug': FROM_CACHE, + ':memory:packageDebug': SUCCESS, + ':memory:preBuild': UP_TO_DATE, + ':memory:preDebugBuild': UP_TO_DATE, + ':memory:processDebugJavaRes': NO_SOURCE, + ':memory:processDebugManifest': FROM_CACHE, + ':memory:processDebugResources': SUCCESS, + ':memory:stripDebugDebugSymbols': FROM_CACHE, + ':penguinswim:assembleDebug': SUCCESS, + ':penguinswim:checkDebugDuplicateClasses': FROM_CACHE, + ':penguinswim:compileDebugAidl': NO_SOURCE, + ':penguinswim:compileDebugJavaWithJavac': FROM_CACHE, + ':penguinswim:compileDebugRenderscript': NO_SOURCE, + ':penguinswim:compileDebugShaders': NO_SOURCE, + ':penguinswim:compileDebugSources': UP_TO_DATE, + ':penguinswim:createDebugCompatibleScreenManifests': FROM_CACHE, + ':penguinswim:dexBuilderDebug': FROM_CACHE, + ':penguinswim:extractDeepLinksDebug': FROM_CACHE, + ':penguinswim:featureDebugWriter': SUCCESS, + ':penguinswim:generateDebugAssets': UP_TO_DATE, + ':penguinswim:generateDebugBuildConfig': FROM_CACHE, + ':penguinswim:generateDebugFeatureTransitiveDeps': FROM_CACHE, + ':penguinswim:generateDebugResValues': FROM_CACHE, + ':penguinswim:generateDebugResources': UP_TO_DATE, + ':penguinswim:javaPreCompileDebug': FROM_CACHE, + ':penguinswim:mergeDebugAssets': FROM_CACHE, + ':penguinswim:mergeDebugJavaResource': FROM_CACHE, + ':penguinswim:mergeDebugJniLibFolders': FROM_CACHE, + ':penguinswim:mergeDebugNativeLibs': FROM_CACHE, + ':penguinswim:mergeDebugResources': SUCCESS, + ':penguinswim:mergeDebugShaders': FROM_CACHE, + ':penguinswim:mergeExtDexDebug': FROM_CACHE, + ':penguinswim:mergeLibDexDebug': FROM_CACHE, + ':penguinswim:mergeProjectDexDebug': FROM_CACHE, + ':penguinswim:packageDebug': SUCCESS, + ':penguinswim:preBuild': UP_TO_DATE, + ':penguinswim:preDebugBuild': UP_TO_DATE, + ':penguinswim:processDebugJavaRes': NO_SOURCE, + ':penguinswim:processDebugManifest': FROM_CACHE, + ':penguinswim:processDebugResources': SUCCESS, + ':penguinswim:stripDebugDebugSymbols': FROM_CACHE, + ':playgames:assembleDebug': SUCCESS, + ':playgames:bundleDebugAar': SUCCESS, + ':playgames:bundleLibCompileDebug': FROM_CACHE, + ':playgames:bundleLibResDebug': FROM_CACHE, + ':playgames:bundleLibRuntimeDebug': FROM_CACHE, + ':playgames:compileDebugAidl': NO_SOURCE, + ':playgames:compileDebugJavaWithJavac': FROM_CACHE, + ':playgames:compileDebugLibraryResources': SUCCESS, + ':playgames:compileDebugRenderscript': NO_SOURCE, + ':playgames:compileDebugShaders': NO_SOURCE, + ':playgames:compileDebugSources': UP_TO_DATE, + ':playgames:copyDebugJniLibsProjectAndLocalJars': FROM_CACHE, + ':playgames:copyDebugJniLibsProjectOnly': FROM_CACHE, + ':playgames:createFullJarDebug': FROM_CACHE, + ':playgames:extractDebugAnnotations': FROM_CACHE, + ':playgames:extractDeepLinksDebug': FROM_CACHE, + ':playgames:generateDebugAssets': UP_TO_DATE, + ':playgames:generateDebugBuildConfig': FROM_CACHE, + ':playgames:generateDebugRFile': FROM_CACHE, + ':playgames:generateDebugResValues': FROM_CACHE, + ':playgames:generateDebugResources': UP_TO_DATE, + ':playgames:javaPreCompileDebug': FROM_CACHE, + ':playgames:mergeDebugConsumerProguardFiles': FROM_CACHE, + ':playgames:mergeDebugGeneratedProguardFiles': FROM_CACHE, + ':playgames:mergeDebugJavaResource': FROM_CACHE, + ':playgames:mergeDebugJniLibFolders': FROM_CACHE, + ':playgames:mergeDebugNativeLibs': FROM_CACHE, + ':playgames:mergeDebugShaders': FROM_CACHE, + ':playgames:packageDebugAssets': FROM_CACHE, + ':playgames:packageDebugRenderscript': NO_SOURCE, + ':playgames:packageDebugResources': FROM_CACHE, + ':playgames:parseDebugLocalResources': FROM_CACHE, + ':playgames:preBuild': UP_TO_DATE, + ':playgames:preDebugBuild': UP_TO_DATE, + ':playgames:prepareLintJarForPublish': SUCCESS, + ':playgames:processDebugJavaRes': NO_SOURCE, + ':playgames:processDebugManifest': FROM_CACHE, + ':playgames:stripDebugDebugSymbols': FROM_CACHE, + ':playgames:syncDebugLibJars': FROM_CACHE, + ':presenttoss:assembleDebug': SUCCESS, + ':presenttoss:checkDebugDuplicateClasses': FROM_CACHE, + ':presenttoss:compileDebugAidl': NO_SOURCE, + ':presenttoss:compileDebugJavaWithJavac': FROM_CACHE, + ':presenttoss:compileDebugRenderscript': NO_SOURCE, + ':presenttoss:compileDebugShaders': NO_SOURCE, + ':presenttoss:compileDebugSources': UP_TO_DATE, + ':presenttoss:createDebugCompatibleScreenManifests': FROM_CACHE, + ':presenttoss:dexBuilderDebug': FROM_CACHE, + ':presenttoss:extractDeepLinksDebug': FROM_CACHE, + ':presenttoss:featureDebugWriter': SUCCESS, + ':presenttoss:generateDebugAssets': UP_TO_DATE, + ':presenttoss:generateDebugBuildConfig': FROM_CACHE, + ':presenttoss:generateDebugFeatureTransitiveDeps': FROM_CACHE, + ':presenttoss:generateDebugResValues': FROM_CACHE, + ':presenttoss:generateDebugResources': UP_TO_DATE, + ':presenttoss:javaPreCompileDebug': FROM_CACHE, + ':presenttoss:mergeDebugAssets': FROM_CACHE, + ':presenttoss:mergeDebugJavaResource': FROM_CACHE, + ':presenttoss:mergeDebugJniLibFolders': FROM_CACHE, + ':presenttoss:mergeDebugNativeLibs': FROM_CACHE, + ':presenttoss:mergeDebugResources': SUCCESS, + ':presenttoss:mergeDebugShaders': FROM_CACHE, + ':presenttoss:mergeExtDexDebug': FROM_CACHE, + ':presenttoss:mergeLibDexDebug': FROM_CACHE, + ':presenttoss:mergeProjectDexDebug': FROM_CACHE, + ':presenttoss:packageDebug': SUCCESS, + ':presenttoss:preBuild': UP_TO_DATE, + ':presenttoss:preDebugBuild': UP_TO_DATE, + ':presenttoss:processDebugJavaRes': NO_SOURCE, + ':presenttoss:processDebugManifest': FROM_CACHE, + ':presenttoss:processDebugResources': SUCCESS, + ':presenttoss:stripDebugDebugSymbols': FROM_CACHE, + ':rocketsleigh:assembleDebug': SUCCESS, + ':rocketsleigh:checkDebugDuplicateClasses': FROM_CACHE, + ':rocketsleigh:compileDebugAidl': NO_SOURCE, + ':rocketsleigh:compileDebugJavaWithJavac': FROM_CACHE, + ':rocketsleigh:compileDebugKotlin': FROM_CACHE, + ':rocketsleigh:compileDebugRenderscript': NO_SOURCE, + ':rocketsleigh:compileDebugShaders': NO_SOURCE, + ':rocketsleigh:compileDebugSources': UP_TO_DATE, + ':rocketsleigh:createDebugCompatibleScreenManifests': FROM_CACHE, + ':rocketsleigh:dexBuilderDebug': FROM_CACHE, + ':rocketsleigh:extractDeepLinksDebug': FROM_CACHE, + ':rocketsleigh:featureDebugWriter': SUCCESS, + ':rocketsleigh:generateDebugAssets': UP_TO_DATE, + ':rocketsleigh:generateDebugBuildConfig': FROM_CACHE, + ':rocketsleigh:generateDebugFeatureTransitiveDeps': FROM_CACHE, + ':rocketsleigh:generateDebugResValues': FROM_CACHE, + ':rocketsleigh:generateDebugResources': UP_TO_DATE, + ':rocketsleigh:javaPreCompileDebug': FROM_CACHE, + ':rocketsleigh:mergeDebugAssets': FROM_CACHE, + ':rocketsleigh:mergeDebugJavaResource': SUCCESS, + ':rocketsleigh:mergeDebugJniLibFolders': FROM_CACHE, + ':rocketsleigh:mergeDebugNativeLibs': FROM_CACHE, + ':rocketsleigh:mergeDebugResources': SUCCESS, + ':rocketsleigh:mergeDebugShaders': FROM_CACHE, + ':rocketsleigh:mergeExtDexDebug': FROM_CACHE, + ':rocketsleigh:mergeLibDexDebug': FROM_CACHE, + ':rocketsleigh:mergeProjectDexDebug': FROM_CACHE, + ':rocketsleigh:packageDebug': SUCCESS, + ':rocketsleigh:preBuild': UP_TO_DATE, + ':rocketsleigh:preDebugBuild': UP_TO_DATE, + ':rocketsleigh:processDebugJavaRes': NO_SOURCE, + ':rocketsleigh:processDebugManifest': FROM_CACHE, + ':rocketsleigh:processDebugResources': SUCCESS, + ':rocketsleigh:stripDebugDebugSymbols': FROM_CACHE, + ':santa-tracker:assembleDebug': SUCCESS, + ':santa-tracker:bundleDebugClasses': FROM_CACHE, + ':santa-tracker:checkDebugDuplicateClasses': FROM_CACHE, + ':santa-tracker:checkDebugLibraries': FROM_CACHE, + ':santa-tracker:compileDebugAidl': NO_SOURCE, + ':santa-tracker:compileDebugJavaWithJavac': FROM_CACHE, + ':santa-tracker:compileDebugKotlin': FROM_CACHE, + ':santa-tracker:compileDebugRenderscript': NO_SOURCE, + ':santa-tracker:compileDebugShaders': NO_SOURCE, + ':santa-tracker:compileDebugSources': UP_TO_DATE, + ':santa-tracker:createDebugCompatibleScreenManifests': FROM_CACHE, + ':santa-tracker:dexBuilderDebug': FROM_CACHE, + ':santa-tracker:extractDeepLinksDebug': FROM_CACHE, + ':santa-tracker:generateDebugAssets': UP_TO_DATE, + ':santa-tracker:generateDebugBuildConfig': FROM_CACHE, + ':santa-tracker:generateDebugFeatureMetadata': FROM_CACHE, + ':santa-tracker:generateDebugFeatureTransitiveDeps': FROM_CACHE, + ':santa-tracker:generateDebugResValues': FROM_CACHE, + ':santa-tracker:generateDebugResources': UP_TO_DATE, + ':santa-tracker:handleDebugMicroApk': FROM_CACHE, + ':santa-tracker:javaPreCompileDebug': FROM_CACHE, + ':santa-tracker:kaptDebugKotlin': SUCCESS, + ':santa-tracker:kaptGenerateStubsDebugKotlin': FROM_CACHE, + ':santa-tracker:mergeDebugAssets': FROM_CACHE, + ':santa-tracker:mergeDebugJavaResource': SUCCESS, + ':santa-tracker:mergeDebugJniLibFolders': FROM_CACHE, + ':santa-tracker:mergeDebugNativeLibs': FROM_CACHE, + ':santa-tracker:mergeDebugResources': SUCCESS, + ':santa-tracker:mergeDebugShaders': FROM_CACHE, + ':santa-tracker:mergeExtDexDebug': FROM_CACHE, + ':santa-tracker:mergeLibDexDebug': FROM_CACHE, + ':santa-tracker:mergeProjectDexDebug': FROM_CACHE, + ':santa-tracker:packageDebug': SUCCESS, + ':santa-tracker:preBuild': UP_TO_DATE, + ':santa-tracker:preDebugBuild': FROM_CACHE, + ':santa-tracker:processDebugJavaRes': NO_SOURCE, + ':santa-tracker:processDebugManifest': FROM_CACHE, + ':santa-tracker:processDebugResources': SUCCESS, + ':santa-tracker:signingConfigWriterDebug': FROM_CACHE, + ':santa-tracker:stripDebugDebugSymbols': FROM_CACHE, + ':santa-tracker:validateSigningDebug': FROM_CACHE, + ':santa-tracker:writeDebugModuleMetadata': SUCCESS, + ':snowballrun:assembleDebug': SUCCESS, + ':snowballrun:checkDebugDuplicateClasses': FROM_CACHE, + ':snowballrun:compileDebugAidl': NO_SOURCE, + ':snowballrun:compileDebugJavaWithJavac': FROM_CACHE, + ':snowballrun:compileDebugRenderscript': NO_SOURCE, + ':snowballrun:compileDebugShaders': NO_SOURCE, + ':snowballrun:compileDebugSources': UP_TO_DATE, + ':snowballrun:createDebugCompatibleScreenManifests': FROM_CACHE, + ':snowballrun:dexBuilderDebug': FROM_CACHE, + ':snowballrun:extractDeepLinksDebug': FROM_CACHE, + ':snowballrun:featureDebugWriter': SUCCESS, + ':snowballrun:generateDebugAssets': UP_TO_DATE, + ':snowballrun:generateDebugBuildConfig': FROM_CACHE, + ':snowballrun:generateDebugFeatureTransitiveDeps': FROM_CACHE, + ':snowballrun:generateDebugResValues': FROM_CACHE, + ':snowballrun:generateDebugResources': UP_TO_DATE, + ':snowballrun:javaPreCompileDebug': FROM_CACHE, + ':snowballrun:mergeDebugAssets': FROM_CACHE, + ':snowballrun:mergeDebugJavaResource': FROM_CACHE, + ':snowballrun:mergeDebugJniLibFolders': FROM_CACHE, + ':snowballrun:mergeDebugNativeLibs': FROM_CACHE, + ':snowballrun:mergeDebugResources': SUCCESS, + ':snowballrun:mergeDebugShaders': FROM_CACHE, + ':snowballrun:mergeExtDexDebug': FROM_CACHE, + ':snowballrun:mergeLibDexDebug': FROM_CACHE, + ':snowballrun:mergeProjectDexDebug': FROM_CACHE, + ':snowballrun:packageDebug': SUCCESS, + ':snowballrun:preBuild': UP_TO_DATE, + ':snowballrun:preDebugBuild': UP_TO_DATE, + ':snowballrun:processDebugJavaRes': NO_SOURCE, + ':snowballrun:processDebugManifest': FROM_CACHE, + ':snowballrun:processDebugResources': SUCCESS, + ':snowballrun:stripDebugDebugSymbols': FROM_CACHE, + ':tracker:assembleDebug': SUCCESS, + ':tracker:bundleDebugAar': SUCCESS, + ':tracker:bundleLibCompileDebug': FROM_CACHE, + ':tracker:bundleLibResDebug': FROM_CACHE, + ':tracker:bundleLibRuntimeDebug': FROM_CACHE, + ':tracker:compileDebugAidl': NO_SOURCE, + ':tracker:compileDebugJavaWithJavac': SUCCESS, + ':tracker:compileDebugKotlin': FROM_CACHE, + ':tracker:compileDebugLibraryResources': SUCCESS, + ':tracker:compileDebugRenderscript': NO_SOURCE, + ':tracker:compileDebugShaders': NO_SOURCE, + ':tracker:compileDebugSources': SUCCESS, + ':tracker:copyDebugJniLibsProjectAndLocalJars': FROM_CACHE, + ':tracker:copyDebugJniLibsProjectOnly': FROM_CACHE, + ':tracker:createFullJarDebug': FROM_CACHE, + ':tracker:extractDebugAnnotations': FROM_CACHE, + ':tracker:extractDeepLinksDebug': FROM_CACHE, + ':tracker:generateDebugAssets': UP_TO_DATE, + ':tracker:generateDebugBuildConfig': FROM_CACHE, + ':tracker:generateDebugRFile': FROM_CACHE, + ':tracker:generateDebugResValues': FROM_CACHE, + ':tracker:generateDebugResources': UP_TO_DATE, + ':tracker:javaPreCompileDebug': FROM_CACHE, + ':tracker:kaptDebugKotlin': SUCCESS, + ':tracker:kaptGenerateStubsDebugKotlin': SUCCESS, + ':tracker:mergeDebugConsumerProguardFiles': FROM_CACHE, + ':tracker:mergeDebugGeneratedProguardFiles': FROM_CACHE, + ':tracker:mergeDebugJavaResource': SUCCESS, + ':tracker:mergeDebugJniLibFolders': FROM_CACHE, + ':tracker:mergeDebugNativeLibs': FROM_CACHE, + ':tracker:mergeDebugResources': FROM_CACHE, + ':tracker:mergeDebugShaders': FROM_CACHE, + ':tracker:packageDebugAssets': FROM_CACHE, + ':tracker:packageDebugRenderscript': NO_SOURCE, + ':tracker:packageDebugResources': FROM_CACHE, + ':tracker:parseDebugLocalResources': FROM_CACHE, + ':tracker:preBuild': UP_TO_DATE, + ':tracker:preDebugBuild': UP_TO_DATE, + ':tracker:prepareLintJarForPublish': SUCCESS, + ':tracker:processDebugJavaRes': NO_SOURCE, + ':tracker:processDebugManifest': FROM_CACHE, + ':tracker:stripDebugDebugSymbols': FROM_CACHE, + ':tracker:syncDebugLibJars': SUCCESS, + ':wearable:assembleDebug': SUCCESS, + ':wearable:checkDebugDuplicateClasses': FROM_CACHE, + ':wearable:compileDebugAidl': NO_SOURCE, + ':wearable:compileDebugJavaWithJavac': FROM_CACHE, + ':wearable:compileDebugKotlin': FROM_CACHE, + ':wearable:compileDebugRenderscript': NO_SOURCE, + ':wearable:compileDebugShaders': NO_SOURCE, + ':wearable:compileDebugSources': UP_TO_DATE, + ':wearable:createDebugCompatibleScreenManifests': FROM_CACHE, + ':wearable:dexBuilderDebug': FROM_CACHE, + ':wearable:extractDeepLinksDebug': FROM_CACHE, + ':wearable:generateDebugAssets': UP_TO_DATE, + ':wearable:generateDebugBuildConfig': FROM_CACHE, + ':wearable:generateDebugResValues': FROM_CACHE, + ':wearable:generateDebugResources': UP_TO_DATE, + ':wearable:javaPreCompileDebug': FROM_CACHE, + ':wearable:kaptDebugKotlin': SUCCESS, + ':wearable:kaptGenerateStubsDebugKotlin': FROM_CACHE, + ':wearable:mergeDebugAssets': FROM_CACHE, + ':wearable:mergeDebugJavaResource': SUCCESS, + ':wearable:mergeDebugJniLibFolders': FROM_CACHE, + ':wearable:mergeDebugNativeLibs': FROM_CACHE, + ':wearable:mergeDebugResources': SUCCESS, + ':wearable:mergeDebugShaders': FROM_CACHE, + ':wearable:mergeExtDexDebug': FROM_CACHE, + ':wearable:mergeLibDexDebug': FROM_CACHE, + ':wearable:mergeProjectDexDebug': FROM_CACHE, + ':wearable:packageDebug': SUCCESS, + ':wearable:preBuild': UP_TO_DATE, + ':wearable:preDebugBuild': UP_TO_DATE, + ':wearable:processDebugJavaRes': NO_SOURCE, + ':wearable:processDebugManifest': FROM_CACHE, + ':wearable:processDebugResources': SUCCESS, + ':wearable:stripDebugDebugSymbols': FROM_CACHE, + ':wearable:validateSigningDebug': FROM_CACHE, + ] + + private static final EXPECTED_RESULTS_3_6 = [ + ':cityquiz:assembleDebug': SUCCESS, + ':cityquiz:checkDebugDuplicateClasses': FROM_CACHE, + ':cityquiz:compileDebugAidl': NO_SOURCE, + ':cityquiz:compileDebugJavaWithJavac': FROM_CACHE, + ':cityquiz:compileDebugKotlin': FROM_CACHE, + ':cityquiz:compileDebugRenderscript': NO_SOURCE, + ':cityquiz:compileDebugShaders': FROM_CACHE, + ':cityquiz:compileDebugSources': UP_TO_DATE, + ':cityquiz:createDebugCompatibleScreenManifests': FROM_CACHE, + ':cityquiz:dexBuilderDebug': FROM_CACHE, + ':cityquiz:extractDeepLinksDebug': FROM_CACHE, + ':cityquiz:featureDebugWriter': SUCCESS, + ':cityquiz:generateDebugAssets': UP_TO_DATE, + ':cityquiz:generateDebugBuildConfig': FROM_CACHE, + ':cityquiz:generateDebugFeatureTransitiveDeps': FROM_CACHE, + ':cityquiz:generateDebugResValues': FROM_CACHE, + ':cityquiz:generateDebugResources': UP_TO_DATE, + ':cityquiz:javaPreCompileDebug': FROM_CACHE, + ':cityquiz:mainApkListPersistenceDebug': FROM_CACHE, + ':cityquiz:mergeDebugAssets': FROM_CACHE, + ':cityquiz:mergeDebugJavaResource': SUCCESS, + ':cityquiz:mergeDebugJniLibFolders': FROM_CACHE, + ':cityquiz:mergeDebugNativeLibs': FROM_CACHE, + ':cityquiz:mergeDebugResources': FROM_CACHE, + ':cityquiz:mergeDebugShaders': FROM_CACHE, + ':cityquiz:mergeExtDexDebug': FROM_CACHE, + ':cityquiz:mergeLibDexDebug': FROM_CACHE, + ':cityquiz:mergeProjectDexDebug': FROM_CACHE, + ':cityquiz:packageDebug': SUCCESS, + ':cityquiz:preBuild': UP_TO_DATE, + ':cityquiz:preDebugBuild': UP_TO_DATE, + ':cityquiz:processDebugJavaRes': NO_SOURCE, + ':cityquiz:processDebugManifest': FROM_CACHE, + ':cityquiz:processDebugResources': FROM_CACHE, + ':cityquiz:stripDebugDebugSymbols': FROM_CACHE, + ':common:assembleDebug': SUCCESS, + ':common:bundleDebugAar': SUCCESS, + ':common:bundleLibCompileDebug': SUCCESS, + ':common:bundleLibResDebug': SUCCESS, + ':common:bundleLibRuntimeDebug': SUCCESS, + ':common:compileDebugAidl': NO_SOURCE, + ':common:compileDebugJavaWithJavac': FROM_CACHE, + ':common:compileDebugKotlin': FROM_CACHE, + ':common:compileDebugLibraryResources': FROM_CACHE, + ':common:compileDebugRenderscript': NO_SOURCE, + ':common:compileDebugShaders': FROM_CACHE, + ':common:compileDebugSources': UP_TO_DATE, + ':common:copyDebugJniLibsProjectAndLocalJars': FROM_CACHE, + ':common:copyDebugJniLibsProjectOnly': FROM_CACHE, + ':common:extractDebugAnnotations': FROM_CACHE, + ':common:extractDeepLinksDebug': FROM_CACHE, + ':common:generateDebugAssets': UP_TO_DATE, + ':common:generateDebugBuildConfig': FROM_CACHE, + ':common:generateDebugRFile': FROM_CACHE, + ':common:generateDebugResValues': FROM_CACHE, + ':common:generateDebugResources': UP_TO_DATE, + ':common:javaPreCompileDebug': FROM_CACHE, + ':common:mergeDebugConsumerProguardFiles': SUCCESS, + ':common:mergeDebugGeneratedProguardFiles': SUCCESS, + ':common:mergeDebugJavaResource': SUCCESS, + ':common:mergeDebugJniLibFolders': FROM_CACHE, + ':common:mergeDebugNativeLibs': FROM_CACHE, + ':common:mergeDebugShaders': FROM_CACHE, + ':common:packageDebugAssets': FROM_CACHE, + ':common:packageDebugRenderscript': NO_SOURCE, + ':common:packageDebugResources': FROM_CACHE, + ':common:parseDebugLocalResources': FROM_CACHE, + ':common:preBuild': UP_TO_DATE, + ':common:preDebugBuild': UP_TO_DATE, + ':common:prepareLintJarForPublish': SUCCESS, + ':common:processDebugJavaRes': NO_SOURCE, + ':common:processDebugManifest': FROM_CACHE, + ':common:stripDebugDebugSymbols': FROM_CACHE, + ':common:syncDebugLibJars': SUCCESS, + ':dasherdancer:assembleDebug': SUCCESS, + ':dasherdancer:checkDebugDuplicateClasses': FROM_CACHE, + ':dasherdancer:compileDebugAidl': NO_SOURCE, + ':dasherdancer:compileDebugJavaWithJavac': FROM_CACHE, + ':dasherdancer:compileDebugKotlin': FROM_CACHE, + ':dasherdancer:compileDebugRenderscript': NO_SOURCE, + ':dasherdancer:compileDebugShaders': FROM_CACHE, + ':dasherdancer:compileDebugSources': UP_TO_DATE, + ':dasherdancer:createDebugCompatibleScreenManifests': FROM_CACHE, + ':dasherdancer:dexBuilderDebug': FROM_CACHE, + ':dasherdancer:extractDeepLinksDebug': FROM_CACHE, + ':dasherdancer:featureDebugWriter': SUCCESS, + ':dasherdancer:generateDebugAssets': UP_TO_DATE, + ':dasherdancer:generateDebugBuildConfig': FROM_CACHE, + ':dasherdancer:generateDebugFeatureTransitiveDeps': FROM_CACHE, + ':dasherdancer:generateDebugResValues': FROM_CACHE, + ':dasherdancer:generateDebugResources': UP_TO_DATE, + ':dasherdancer:javaPreCompileDebug': FROM_CACHE, + ':dasherdancer:mainApkListPersistenceDebug': FROM_CACHE, + ':dasherdancer:mergeDebugAssets': FROM_CACHE, + ':dasherdancer:mergeDebugJavaResource': SUCCESS, + ':dasherdancer:mergeDebugJniLibFolders': FROM_CACHE, + ':dasherdancer:mergeDebugNativeLibs': FROM_CACHE, + ':dasherdancer:mergeDebugResources': FROM_CACHE, + ':dasherdancer:mergeDebugShaders': FROM_CACHE, + ':dasherdancer:mergeExtDexDebug': FROM_CACHE, + ':dasherdancer:mergeLibDexDebug': FROM_CACHE, + ':dasherdancer:mergeProjectDexDebug': FROM_CACHE, + ':dasherdancer:packageDebug': SUCCESS, + ':dasherdancer:preBuild': UP_TO_DATE, + ':dasherdancer:preDebugBuild': UP_TO_DATE, + ':dasherdancer:processDebugJavaRes': NO_SOURCE, + ':dasherdancer:processDebugManifest': FROM_CACHE, + ':dasherdancer:processDebugResources': FROM_CACHE, + ':dasherdancer:stripDebugDebugSymbols': FROM_CACHE, + ':doodles-lib:assembleDebug': SUCCESS, + ':doodles-lib:bundleDebugAar': SUCCESS, + ':doodles-lib:bundleLibCompileDebug': SUCCESS, + ':doodles-lib:bundleLibResDebug': SUCCESS, + ':doodles-lib:bundleLibRuntimeDebug': SUCCESS, + ':doodles-lib:compileDebugAidl': NO_SOURCE, + ':doodles-lib:compileDebugJavaWithJavac': FROM_CACHE, + ':doodles-lib:compileDebugLibraryResources': FROM_CACHE, + ':doodles-lib:compileDebugRenderscript': NO_SOURCE, + ':doodles-lib:compileDebugShaders': FROM_CACHE, + ':doodles-lib:compileDebugSources': UP_TO_DATE, + ':doodles-lib:copyDebugJniLibsProjectAndLocalJars': FROM_CACHE, + ':doodles-lib:copyDebugJniLibsProjectOnly': FROM_CACHE, + ':doodles-lib:extractDebugAnnotations': FROM_CACHE, + ':doodles-lib:extractDeepLinksDebug': FROM_CACHE, + ':doodles-lib:generateDebugAssets': UP_TO_DATE, + ':doodles-lib:generateDebugBuildConfig': FROM_CACHE, + ':doodles-lib:generateDebugRFile': FROM_CACHE, + ':doodles-lib:generateDebugResValues': FROM_CACHE, + ':doodles-lib:generateDebugResources': UP_TO_DATE, + ':doodles-lib:javaPreCompileDebug': FROM_CACHE, + ':doodles-lib:mergeDebugConsumerProguardFiles': SUCCESS, + ':doodles-lib:mergeDebugGeneratedProguardFiles': SUCCESS, + ':doodles-lib:mergeDebugJavaResource': FROM_CACHE, + ':doodles-lib:mergeDebugJniLibFolders': FROM_CACHE, + ':doodles-lib:mergeDebugNativeLibs': FROM_CACHE, + ':doodles-lib:mergeDebugShaders': FROM_CACHE, + ':doodles-lib:packageDebugAssets': FROM_CACHE, + ':doodles-lib:packageDebugRenderscript': NO_SOURCE, + ':doodles-lib:packageDebugResources': FROM_CACHE, + ':doodles-lib:parseDebugLocalResources': FROM_CACHE, + ':doodles-lib:preBuild': UP_TO_DATE, + ':doodles-lib:preDebugBuild': UP_TO_DATE, + ':doodles-lib:prepareLintJarForPublish': SUCCESS, + ':doodles-lib:processDebugJavaRes': NO_SOURCE, + ':doodles-lib:processDebugManifest': FROM_CACHE, + ':doodles-lib:stripDebugDebugSymbols': FROM_CACHE, + ':doodles-lib:syncDebugLibJars': FROM_CACHE, + ':gumball:assembleDebug': SUCCESS, + ':gumball:checkDebugDuplicateClasses': FROM_CACHE, + ':gumball:compileDebugAidl': NO_SOURCE, + ':gumball:compileDebugJavaWithJavac': FROM_CACHE, + ':gumball:compileDebugRenderscript': NO_SOURCE, + ':gumball:compileDebugShaders': FROM_CACHE, + ':gumball:compileDebugSources': UP_TO_DATE, + ':gumball:createDebugCompatibleScreenManifests': FROM_CACHE, + ':gumball:dexBuilderDebug': FROM_CACHE, + ':gumball:extractDeepLinksDebug': FROM_CACHE, + ':gumball:featureDebugWriter': SUCCESS, + ':gumball:generateDebugAssets': UP_TO_DATE, + ':gumball:generateDebugBuildConfig': FROM_CACHE, + ':gumball:generateDebugFeatureTransitiveDeps': FROM_CACHE, + ':gumball:generateDebugResValues': FROM_CACHE, + ':gumball:generateDebugResources': UP_TO_DATE, + ':gumball:javaPreCompileDebug': FROM_CACHE, + ':gumball:mainApkListPersistenceDebug': FROM_CACHE, + ':gumball:mergeDebugAssets': FROM_CACHE, + ':gumball:mergeDebugJavaResource': FROM_CACHE, + ':gumball:mergeDebugJniLibFolders': FROM_CACHE, + ':gumball:mergeDebugNativeLibs': FROM_CACHE, + ':gumball:mergeDebugResources': FROM_CACHE, + ':gumball:mergeDebugShaders': FROM_CACHE, + ':gumball:mergeExtDexDebug': FROM_CACHE, + ':gumball:mergeLibDexDebug': FROM_CACHE, + ':gumball:mergeProjectDexDebug': FROM_CACHE, + ':gumball:packageDebug': SUCCESS, + ':gumball:preBuild': UP_TO_DATE, + ':gumball:preDebugBuild': UP_TO_DATE, + ':gumball:processDebugJavaRes': NO_SOURCE, + ':gumball:processDebugManifest': FROM_CACHE, + ':gumball:processDebugResources': FROM_CACHE, + ':gumball:stripDebugDebugSymbols': FROM_CACHE, + ':jetpack:assembleDebug': SUCCESS, + ':jetpack:checkDebugDuplicateClasses': FROM_CACHE, + ':jetpack:compileDebugAidl': NO_SOURCE, + ':jetpack:compileDebugJavaWithJavac': FROM_CACHE, + ':jetpack:compileDebugKotlin': FROM_CACHE, + ':jetpack:compileDebugRenderscript': NO_SOURCE, + ':jetpack:compileDebugShaders': FROM_CACHE, + ':jetpack:compileDebugSources': UP_TO_DATE, + ':jetpack:createDebugCompatibleScreenManifests': FROM_CACHE, + ':jetpack:dexBuilderDebug': FROM_CACHE, + ':jetpack:extractDeepLinksDebug': FROM_CACHE, + ':jetpack:featureDebugWriter': SUCCESS, + ':jetpack:generateDebugAssets': UP_TO_DATE, + ':jetpack:generateDebugBuildConfig': FROM_CACHE, + ':jetpack:generateDebugFeatureTransitiveDeps': FROM_CACHE, + ':jetpack:generateDebugResValues': FROM_CACHE, + ':jetpack:generateDebugResources': UP_TO_DATE, + ':jetpack:javaPreCompileDebug': FROM_CACHE, + ':jetpack:mainApkListPersistenceDebug': FROM_CACHE, + ':jetpack:mergeDebugAssets': FROM_CACHE, + ':jetpack:mergeDebugJavaResource': SUCCESS, + ':jetpack:mergeDebugJniLibFolders': FROM_CACHE, + ':jetpack:mergeDebugNativeLibs': FROM_CACHE, + ':jetpack:mergeDebugResources': FROM_CACHE, + ':jetpack:mergeDebugShaders': FROM_CACHE, + ':jetpack:mergeExtDexDebug': FROM_CACHE, + ':jetpack:mergeLibDexDebug': FROM_CACHE, + ':jetpack:mergeProjectDexDebug': FROM_CACHE, + ':jetpack:packageDebug': SUCCESS, + ':jetpack:preBuild': UP_TO_DATE, + ':jetpack:preDebugBuild': UP_TO_DATE, + ':jetpack:processDebugJavaRes': NO_SOURCE, + ':jetpack:processDebugManifest': FROM_CACHE, + ':jetpack:processDebugResources': FROM_CACHE, + ':jetpack:stripDebugDebugSymbols': FROM_CACHE, + ':memory:assembleDebug': SUCCESS, + ':memory:checkDebugDuplicateClasses': FROM_CACHE, + ':memory:compileDebugAidl': NO_SOURCE, + ':memory:compileDebugJavaWithJavac': FROM_CACHE, + ':memory:compileDebugRenderscript': NO_SOURCE, + ':memory:compileDebugShaders': FROM_CACHE, + ':memory:compileDebugSources': UP_TO_DATE, + ':memory:createDebugCompatibleScreenManifests': FROM_CACHE, + ':memory:dexBuilderDebug': FROM_CACHE, + ':memory:extractDeepLinksDebug': FROM_CACHE, + ':memory:featureDebugWriter': SUCCESS, + ':memory:generateDebugAssets': UP_TO_DATE, + ':memory:generateDebugBuildConfig': FROM_CACHE, + ':memory:generateDebugFeatureTransitiveDeps': FROM_CACHE, + ':memory:generateDebugResValues': FROM_CACHE, + ':memory:generateDebugResources': UP_TO_DATE, + ':memory:javaPreCompileDebug': FROM_CACHE, + ':memory:mainApkListPersistenceDebug': FROM_CACHE, + ':memory:mergeDebugAssets': FROM_CACHE, + ':memory:mergeDebugJavaResource': FROM_CACHE, + ':memory:mergeDebugJniLibFolders': FROM_CACHE, + ':memory:mergeDebugNativeLibs': FROM_CACHE, + ':memory:mergeDebugResources': FROM_CACHE, + ':memory:mergeDebugShaders': FROM_CACHE, + ':memory:mergeExtDexDebug': FROM_CACHE, + ':memory:mergeLibDexDebug': FROM_CACHE, + ':memory:mergeProjectDexDebug': FROM_CACHE, + ':memory:packageDebug': SUCCESS, + ':memory:preBuild': UP_TO_DATE, + ':memory:preDebugBuild': UP_TO_DATE, + ':memory:processDebugJavaRes': NO_SOURCE, + ':memory:processDebugManifest': FROM_CACHE, + ':memory:processDebugResources': FROM_CACHE, + ':memory:stripDebugDebugSymbols': FROM_CACHE, + ':penguinswim:assembleDebug': SUCCESS, + ':penguinswim:checkDebugDuplicateClasses': FROM_CACHE, + ':penguinswim:compileDebugAidl': NO_SOURCE, + ':penguinswim:compileDebugJavaWithJavac': FROM_CACHE, + ':penguinswim:compileDebugRenderscript': NO_SOURCE, + ':penguinswim:compileDebugShaders': FROM_CACHE, + ':penguinswim:compileDebugSources': UP_TO_DATE, + ':penguinswim:createDebugCompatibleScreenManifests': FROM_CACHE, + ':penguinswim:dexBuilderDebug': FROM_CACHE, + ':penguinswim:extractDeepLinksDebug': FROM_CACHE, + ':penguinswim:featureDebugWriter': SUCCESS, + ':penguinswim:generateDebugAssets': UP_TO_DATE, + ':penguinswim:generateDebugBuildConfig': FROM_CACHE, + ':penguinswim:generateDebugFeatureTransitiveDeps': FROM_CACHE, + ':penguinswim:generateDebugResValues': FROM_CACHE, + ':penguinswim:generateDebugResources': UP_TO_DATE, + ':penguinswim:javaPreCompileDebug': FROM_CACHE, + ':penguinswim:mainApkListPersistenceDebug': FROM_CACHE, + ':penguinswim:mergeDebugAssets': FROM_CACHE, + ':penguinswim:mergeDebugJavaResource': FROM_CACHE, + ':penguinswim:mergeDebugJniLibFolders': FROM_CACHE, + ':penguinswim:mergeDebugNativeLibs': FROM_CACHE, + ':penguinswim:mergeDebugResources': FROM_CACHE, + ':penguinswim:mergeDebugShaders': FROM_CACHE, + ':penguinswim:mergeExtDexDebug': FROM_CACHE, + ':penguinswim:mergeLibDexDebug': FROM_CACHE, + ':penguinswim:mergeProjectDexDebug': FROM_CACHE, + ':penguinswim:packageDebug': SUCCESS, + ':penguinswim:preBuild': UP_TO_DATE, + ':penguinswim:preDebugBuild': UP_TO_DATE, + ':penguinswim:processDebugJavaRes': NO_SOURCE, + ':penguinswim:processDebugManifest': FROM_CACHE, + ':penguinswim:processDebugResources': FROM_CACHE, + ':penguinswim:stripDebugDebugSymbols': FROM_CACHE, + ':playgames:assembleDebug': SUCCESS, + ':playgames:bundleDebugAar': SUCCESS, + ':playgames:bundleLibCompileDebug': SUCCESS, + ':playgames:bundleLibResDebug': SUCCESS, + ':playgames:bundleLibRuntimeDebug': SUCCESS, + ':playgames:compileDebugAidl': NO_SOURCE, + ':playgames:compileDebugJavaWithJavac': FROM_CACHE, + ':playgames:compileDebugLibraryResources': FROM_CACHE, + ':playgames:compileDebugRenderscript': NO_SOURCE, + ':playgames:compileDebugShaders': FROM_CACHE, + ':playgames:compileDebugSources': UP_TO_DATE, + ':playgames:copyDebugJniLibsProjectAndLocalJars': FROM_CACHE, + ':playgames:copyDebugJniLibsProjectOnly': FROM_CACHE, + ':playgames:extractDebugAnnotations': FROM_CACHE, + ':playgames:extractDeepLinksDebug': FROM_CACHE, + ':playgames:generateDebugAssets': UP_TO_DATE, + ':playgames:generateDebugBuildConfig': FROM_CACHE, + ':playgames:generateDebugRFile': FROM_CACHE, + ':playgames:generateDebugResValues': FROM_CACHE, + ':playgames:generateDebugResources': UP_TO_DATE, + ':playgames:javaPreCompileDebug': FROM_CACHE, + ':playgames:mergeDebugConsumerProguardFiles': SUCCESS, + ':playgames:mergeDebugGeneratedProguardFiles': SUCCESS, + ':playgames:mergeDebugJavaResource': FROM_CACHE, + ':playgames:mergeDebugJniLibFolders': FROM_CACHE, + ':playgames:mergeDebugNativeLibs': FROM_CACHE, + ':playgames:mergeDebugShaders': FROM_CACHE, + ':playgames:packageDebugAssets': FROM_CACHE, + ':playgames:packageDebugRenderscript': NO_SOURCE, + ':playgames:packageDebugResources': FROM_CACHE, + ':playgames:parseDebugLocalResources': FROM_CACHE, + ':playgames:preBuild': UP_TO_DATE, + ':playgames:preDebugBuild': UP_TO_DATE, + ':playgames:prepareLintJarForPublish': SUCCESS, + ':playgames:processDebugJavaRes': NO_SOURCE, + ':playgames:processDebugManifest': FROM_CACHE, + ':playgames:stripDebugDebugSymbols': FROM_CACHE, + ':playgames:syncDebugLibJars': FROM_CACHE, + ':presenttoss:assembleDebug': SUCCESS, + ':presenttoss:checkDebugDuplicateClasses': FROM_CACHE, + ':presenttoss:compileDebugAidl': NO_SOURCE, + ':presenttoss:compileDebugJavaWithJavac': FROM_CACHE, + ':presenttoss:compileDebugRenderscript': NO_SOURCE, + ':presenttoss:compileDebugShaders': FROM_CACHE, + ':presenttoss:compileDebugSources': UP_TO_DATE, + ':presenttoss:createDebugCompatibleScreenManifests': FROM_CACHE, + ':presenttoss:dexBuilderDebug': FROM_CACHE, + ':presenttoss:extractDeepLinksDebug': FROM_CACHE, + ':presenttoss:featureDebugWriter': SUCCESS, + ':presenttoss:generateDebugAssets': UP_TO_DATE, + ':presenttoss:generateDebugBuildConfig': FROM_CACHE, + ':presenttoss:generateDebugFeatureTransitiveDeps': FROM_CACHE, + ':presenttoss:generateDebugResValues': FROM_CACHE, + ':presenttoss:generateDebugResources': UP_TO_DATE, + ':presenttoss:javaPreCompileDebug': FROM_CACHE, + ':presenttoss:mainApkListPersistenceDebug': FROM_CACHE, + ':presenttoss:mergeDebugAssets': FROM_CACHE, + ':presenttoss:mergeDebugJavaResource': FROM_CACHE, + ':presenttoss:mergeDebugJniLibFolders': FROM_CACHE, + ':presenttoss:mergeDebugNativeLibs': FROM_CACHE, + ':presenttoss:mergeDebugResources': FROM_CACHE, + ':presenttoss:mergeDebugShaders': FROM_CACHE, + ':presenttoss:mergeExtDexDebug': FROM_CACHE, + ':presenttoss:mergeLibDexDebug': FROM_CACHE, + ':presenttoss:mergeProjectDexDebug': FROM_CACHE, + ':presenttoss:packageDebug': SUCCESS, + ':presenttoss:preBuild': UP_TO_DATE, + ':presenttoss:preDebugBuild': UP_TO_DATE, + ':presenttoss:processDebugJavaRes': NO_SOURCE, + ':presenttoss:processDebugManifest': FROM_CACHE, + ':presenttoss:processDebugResources': FROM_CACHE, + ':presenttoss:stripDebugDebugSymbols': FROM_CACHE, + ':rocketsleigh:assembleDebug': SUCCESS, + ':rocketsleigh:checkDebugDuplicateClasses': FROM_CACHE, + ':rocketsleigh:compileDebugAidl': NO_SOURCE, + ':rocketsleigh:compileDebugJavaWithJavac': FROM_CACHE, + ':rocketsleigh:compileDebugKotlin': FROM_CACHE, + ':rocketsleigh:compileDebugRenderscript': NO_SOURCE, + ':rocketsleigh:compileDebugShaders': FROM_CACHE, + ':rocketsleigh:compileDebugSources': UP_TO_DATE, + ':rocketsleigh:createDebugCompatibleScreenManifests': FROM_CACHE, + ':rocketsleigh:dexBuilderDebug': FROM_CACHE, + ':rocketsleigh:extractDeepLinksDebug': FROM_CACHE, + ':rocketsleigh:featureDebugWriter': SUCCESS, + ':rocketsleigh:generateDebugAssets': UP_TO_DATE, + ':rocketsleigh:generateDebugBuildConfig': FROM_CACHE, + ':rocketsleigh:generateDebugFeatureTransitiveDeps': FROM_CACHE, + ':rocketsleigh:generateDebugResValues': FROM_CACHE, + ':rocketsleigh:generateDebugResources': UP_TO_DATE, + ':rocketsleigh:javaPreCompileDebug': FROM_CACHE, + ':rocketsleigh:mainApkListPersistenceDebug': FROM_CACHE, + ':rocketsleigh:mergeDebugAssets': FROM_CACHE, + ':rocketsleigh:mergeDebugJavaResource': SUCCESS, + ':rocketsleigh:mergeDebugJniLibFolders': FROM_CACHE, + ':rocketsleigh:mergeDebugNativeLibs': FROM_CACHE, + ':rocketsleigh:mergeDebugResources': FROM_CACHE, + ':rocketsleigh:mergeDebugShaders': FROM_CACHE, + ':rocketsleigh:mergeExtDexDebug': FROM_CACHE, + ':rocketsleigh:mergeLibDexDebug': FROM_CACHE, + ':rocketsleigh:mergeProjectDexDebug': FROM_CACHE, + ':rocketsleigh:packageDebug': SUCCESS, + ':rocketsleigh:preBuild': UP_TO_DATE, + ':rocketsleigh:preDebugBuild': UP_TO_DATE, + ':rocketsleigh:processDebugJavaRes': NO_SOURCE, + ':rocketsleigh:processDebugManifest': FROM_CACHE, + ':rocketsleigh:processDebugResources': FROM_CACHE, + ':rocketsleigh:stripDebugDebugSymbols': FROM_CACHE, + ':santa-tracker:assembleDebug': SUCCESS, + ':santa-tracker:bundleDebugClasses': SUCCESS, + ':santa-tracker:checkDebugDuplicateClasses': FROM_CACHE, + ':santa-tracker:checkDebugLibraries': FROM_CACHE, + ':santa-tracker:compileDebugAidl': NO_SOURCE, + ':santa-tracker:compileDebugJavaWithJavac': FROM_CACHE, + ':santa-tracker:compileDebugKotlin': FROM_CACHE, + ':santa-tracker:compileDebugRenderscript': NO_SOURCE, + ':santa-tracker:compileDebugShaders': FROM_CACHE, + ':santa-tracker:compileDebugSources': UP_TO_DATE, + ':santa-tracker:createDebugCompatibleScreenManifests': FROM_CACHE, + ':santa-tracker:dexBuilderDebug': FROM_CACHE, + ':santa-tracker:extractDeepLinksDebug': FROM_CACHE, + ':santa-tracker:generateDebugAssets': UP_TO_DATE, + ':santa-tracker:generateDebugBuildConfig': FROM_CACHE, + ':santa-tracker:generateDebugFeatureMetadata': FROM_CACHE, + ':santa-tracker:generateDebugFeatureTransitiveDeps': FROM_CACHE, + ':santa-tracker:generateDebugResValues': FROM_CACHE, + ':santa-tracker:generateDebugResources': SUCCESS, + ':santa-tracker:handleDebugMicroApk': SUCCESS, + ':santa-tracker:javaPreCompileDebug': FROM_CACHE, + ':santa-tracker:kaptDebugKotlin': SUCCESS, + ':santa-tracker:kaptGenerateStubsDebugKotlin': FROM_CACHE, + ':santa-tracker:mainApkListPersistenceDebug': FROM_CACHE, + ':santa-tracker:mergeDebugAssets': FROM_CACHE, + ':santa-tracker:mergeDebugJavaResource': SUCCESS, + ':santa-tracker:mergeDebugJniLibFolders': FROM_CACHE, + ':santa-tracker:mergeDebugNativeLibs': FROM_CACHE, + ':santa-tracker:mergeDebugResources': FROM_CACHE, + ':santa-tracker:mergeDebugShaders': FROM_CACHE, + ':santa-tracker:mergeExtDexDebug': FROM_CACHE, + ':santa-tracker:mergeLibDexDebug': FROM_CACHE, + ':santa-tracker:mergeProjectDexDebug': FROM_CACHE, + ':santa-tracker:packageDebug': SUCCESS, + ':santa-tracker:preBuild': UP_TO_DATE, + ':santa-tracker:preDebugBuild': FROM_CACHE, + ':santa-tracker:processDebugJavaRes': NO_SOURCE, + ':santa-tracker:processDebugManifest': FROM_CACHE, + ':santa-tracker:processDebugResources': FROM_CACHE, + ':santa-tracker:signingConfigWriterDebug': FROM_CACHE, + ':santa-tracker:stripDebugDebugSymbols': FROM_CACHE, + ':santa-tracker:validateSigningDebug': FROM_CACHE, + ':santa-tracker:writeDebugModuleMetadata': SUCCESS, + ':snowballrun:assembleDebug': SUCCESS, + ':snowballrun:checkDebugDuplicateClasses': FROM_CACHE, + ':snowballrun:compileDebugAidl': NO_SOURCE, + ':snowballrun:compileDebugJavaWithJavac': FROM_CACHE, + ':snowballrun:compileDebugRenderscript': NO_SOURCE, + ':snowballrun:compileDebugShaders': FROM_CACHE, + ':snowballrun:compileDebugSources': UP_TO_DATE, + ':snowballrun:createDebugCompatibleScreenManifests': FROM_CACHE, + ':snowballrun:dexBuilderDebug': FROM_CACHE, + ':snowballrun:extractDeepLinksDebug': FROM_CACHE, + ':snowballrun:featureDebugWriter': SUCCESS, + ':snowballrun:generateDebugAssets': UP_TO_DATE, + ':snowballrun:generateDebugBuildConfig': FROM_CACHE, + ':snowballrun:generateDebugFeatureTransitiveDeps': FROM_CACHE, + ':snowballrun:generateDebugResValues': FROM_CACHE, + ':snowballrun:generateDebugResources': UP_TO_DATE, + ':snowballrun:javaPreCompileDebug': FROM_CACHE, + ':snowballrun:mainApkListPersistenceDebug': FROM_CACHE, + ':snowballrun:mergeDebugAssets': FROM_CACHE, + ':snowballrun:mergeDebugJavaResource': FROM_CACHE, + ':snowballrun:mergeDebugJniLibFolders': FROM_CACHE, + ':snowballrun:mergeDebugNativeLibs': FROM_CACHE, + ':snowballrun:mergeDebugResources': FROM_CACHE, + ':snowballrun:mergeDebugShaders': FROM_CACHE, + ':snowballrun:mergeExtDexDebug': FROM_CACHE, + ':snowballrun:mergeLibDexDebug': FROM_CACHE, + ':snowballrun:mergeProjectDexDebug': FROM_CACHE, + ':snowballrun:packageDebug': SUCCESS, + ':snowballrun:preBuild': UP_TO_DATE, + ':snowballrun:preDebugBuild': UP_TO_DATE, + ':snowballrun:processDebugJavaRes': NO_SOURCE, + ':snowballrun:processDebugManifest': FROM_CACHE, + ':snowballrun:processDebugResources': FROM_CACHE, + ':snowballrun:stripDebugDebugSymbols': FROM_CACHE, + ':tracker:assembleDebug': SUCCESS, + ':tracker:bundleDebugAar': SUCCESS, + ':tracker:bundleLibCompileDebug': SUCCESS, + ':tracker:bundleLibResDebug': SUCCESS, + ':tracker:bundleLibRuntimeDebug': SUCCESS, + ':tracker:compileDebugAidl': NO_SOURCE, + ':tracker:compileDebugJavaWithJavac': SUCCESS, + ':tracker:compileDebugKotlin': FROM_CACHE, + ':tracker:compileDebugLibraryResources': FROM_CACHE, + ':tracker:compileDebugRenderscript': NO_SOURCE, + ':tracker:compileDebugShaders': FROM_CACHE, + ':tracker:compileDebugSources': SUCCESS, + ':tracker:copyDebugJniLibsProjectAndLocalJars': FROM_CACHE, + ':tracker:copyDebugJniLibsProjectOnly': FROM_CACHE, + ':tracker:extractDebugAnnotations': FROM_CACHE, + ':tracker:extractDeepLinksDebug': FROM_CACHE, + ':tracker:generateDebugAssets': UP_TO_DATE, + ':tracker:generateDebugBuildConfig': FROM_CACHE, + ':tracker:generateDebugRFile': FROM_CACHE, + ':tracker:generateDebugResValues': FROM_CACHE, + ':tracker:generateDebugResources': UP_TO_DATE, + ':tracker:javaPreCompileDebug': FROM_CACHE, + ':tracker:kaptDebugKotlin': SUCCESS, + ':tracker:kaptGenerateStubsDebugKotlin': SUCCESS, + ':tracker:mergeDebugConsumerProguardFiles': SUCCESS, + ':tracker:mergeDebugGeneratedProguardFiles': SUCCESS, + ':tracker:mergeDebugJavaResource': SUCCESS, + ':tracker:mergeDebugJniLibFolders': FROM_CACHE, + ':tracker:mergeDebugNativeLibs': FROM_CACHE, + ':tracker:mergeDebugResources': FROM_CACHE, + ':tracker:mergeDebugShaders': FROM_CACHE, + ':tracker:packageDebugAssets': FROM_CACHE, + ':tracker:packageDebugRenderscript': NO_SOURCE, + ':tracker:packageDebugResources': FROM_CACHE, + ':tracker:parseDebugLocalResources': FROM_CACHE, + ':tracker:preBuild': UP_TO_DATE, + ':tracker:preDebugBuild': UP_TO_DATE, + ':tracker:prepareLintJarForPublish': SUCCESS, + ':tracker:processDebugJavaRes': NO_SOURCE, + ':tracker:processDebugManifest': FROM_CACHE, + ':tracker:stripDebugDebugSymbols': FROM_CACHE, + ':tracker:syncDebugLibJars': SUCCESS, + ':wearable:assembleDebug': SUCCESS, + ':wearable:checkDebugDuplicateClasses': FROM_CACHE, + ':wearable:compileDebugAidl': NO_SOURCE, + ':wearable:compileDebugJavaWithJavac': FROM_CACHE, + ':wearable:compileDebugKotlin': FROM_CACHE, + ':wearable:compileDebugRenderscript': NO_SOURCE, + ':wearable:compileDebugShaders': FROM_CACHE, + ':wearable:compileDebugSources': UP_TO_DATE, + ':wearable:createDebugCompatibleScreenManifests': FROM_CACHE, + ':wearable:dexBuilderDebug': FROM_CACHE, + ':wearable:extractDeepLinksDebug': FROM_CACHE, + ':wearable:generateDebugAssets': UP_TO_DATE, + ':wearable:generateDebugBuildConfig': FROM_CACHE, + ':wearable:generateDebugResValues': FROM_CACHE, + ':wearable:generateDebugResources': UP_TO_DATE, + ':wearable:javaPreCompileDebug': FROM_CACHE, + ':wearable:kaptDebugKotlin': SUCCESS, + ':wearable:kaptGenerateStubsDebugKotlin': FROM_CACHE, + ':wearable:mainApkListPersistenceDebug': FROM_CACHE, + ':wearable:mergeDebugAssets': FROM_CACHE, + ':wearable:mergeDebugJavaResource': SUCCESS, + ':wearable:mergeDebugJniLibFolders': FROM_CACHE, + ':wearable:mergeDebugNativeLibs': FROM_CACHE, + ':wearable:mergeDebugResources': FROM_CACHE, + ':wearable:mergeDebugShaders': FROM_CACHE, + ':wearable:mergeExtDexDebug': FROM_CACHE, + ':wearable:mergeLibDexDebug': FROM_CACHE, + ':wearable:mergeProjectDexDebug': FROM_CACHE, + ':wearable:packageDebug': SUCCESS, + ':wearable:preBuild': UP_TO_DATE, + ':wearable:preDebugBuild': UP_TO_DATE, + ':wearable:processDebugJavaRes': NO_SOURCE, + ':wearable:processDebugManifest': FROM_CACHE, + ':wearable:processDebugResources': FROM_CACHE, + ':wearable:stripDebugDebugSymbols': FROM_CACHE, + ':wearable:validateSigningDebug': FROM_CACHE, + ] +} diff --git a/subprojects/smoke-test/src/smokeTest/groovy/org/gradle/smoketests/AndroidSantaTrackerSmokeTest.groovy b/subprojects/smoke-test/src/smokeTest/groovy/org/gradle/smoketests/AndroidSantaTrackerSmokeTest.groovy index 6cd64a803220..bada02d90627 100644 --- a/subprojects/smoke-test/src/smokeTest/groovy/org/gradle/smoketests/AndroidSantaTrackerSmokeTest.groovy +++ b/subprojects/smoke-test/src/smokeTest/groovy/org/gradle/smoketests/AndroidSantaTrackerSmokeTest.groovy @@ -17,40 +17,25 @@ package org.gradle.smoketests import org.gradle.integtests.fixtures.ToBeFixedForInstantExecution -import org.gradle.integtests.fixtures.daemon.DaemonLogsAnalyzer -import org.gradle.internal.scan.config.fixtures.GradleEnterprisePluginSettingsFixture import org.gradle.profiler.mutations.ApplyNonAbiChangeToJavaSourceFileMutator -import org.gradle.test.fixtures.file.TestFile -import org.gradle.test.fixtures.file.TestNameTestDirectoryProvider -import org.gradle.testkit.runner.BuildResult -import org.gradle.testkit.runner.TaskOutcome -import org.gradle.testkit.runner.internal.ToolingApiGradleExecutor import org.gradle.util.GradleVersion import org.gradle.util.Requires import org.gradle.util.TestPrecondition -import org.junit.Rule +import spock.lang.Unroll -import static org.gradle.testkit.runner.TaskOutcome.FROM_CACHE -import static org.gradle.testkit.runner.TaskOutcome.NO_SOURCE import static org.gradle.testkit.runner.TaskOutcome.SUCCESS -import static org.gradle.testkit.runner.TaskOutcome.UP_TO_DATE -@Requires(TestPrecondition.JDK11_OR_EARLIER) -class AndroidSantaTrackerSmokeTest extends AbstractSmokeTest { - @Rule - TestNameTestDirectoryProvider temporaryFolder - TestFile homeDir - def setup() { - homeDir = temporaryFolder.createDir("test-kit-home") - } +@Requires(TestPrecondition.JDK11_OR_EARLIER) +class AndroidSantaTrackerSmokeTest extends AbstractAndroidSantaTrackerSmokeTest { + @Unroll @ToBeFixedForInstantExecution - def "check deprecation warnings produced by building Santa Tracker"() { - def checkoutDir = temporaryFolder.createDir ("checkout") - setupCopyOfSantaTracker(checkoutDir) + def "check deprecation warnings produced by building Santa Tracker Kotlin (agp=#agpVersion)"() { + def checkoutDir = temporaryFolder.createDir("checkout") + setupCopyOfSantaTracker(checkoutDir, 'Kotlin', agpVersion) - def result = buildLocation(checkoutDir) + def result = buildLocation(checkoutDir, agpVersion) expect: expectDeprecationWarnings(result, @@ -70,27 +55,36 @@ class AndroidSantaTrackerSmokeTest extends AbstractSmokeTest { "The configuration :detachedConfiguration8 was resolved without accessing the project in a safe manner. This may happen when a configuration is resolved from a different project. This behaviour has been deprecated and is scheduled to be removed in Gradle 7.0. See https://docs.gradle.org/${GradleVersion.current().version}/userguide/viewing_debugging_dependencies.html#sub:resolving-unsafe-configuration-resolution-errors for more details.", "The configuration :detachedConfiguration9 was resolved without accessing the project in a safe manner. This may happen when a configuration is resolved from a different project. This behaviour has been deprecated and is scheduled to be removed in Gradle 7.0. See https://docs.gradle.org/${GradleVersion.current().version}/userguide/viewing_debugging_dependencies.html#sub:resolving-unsafe-configuration-resolution-errors for more details.", ) - } - @ToBeFixedForInstantExecution - def "can cache Santa Tracker Android application"() { - def originalDir = temporaryFolder.createDir ("original") - def relocatedDir = temporaryFolder.createDir("relocated") + where: + agpVersion << testedAgpVersions + } - setupCopyOfSantaTracker(originalDir) - setupCopyOfSantaTracker(relocatedDir) + @Unroll + def "check deprecation warnings produced by building Santa Tracker Java (agp=#agpVersion)"() { + def checkoutDir = temporaryFolder.createDir("checkout") + setupCopyOfSantaTracker(checkoutDir, 'Java', agpVersion) - buildLocation(originalDir) - BuildResult relocatedResult = buildLocation(relocatedDir) + def result = buildLocation(checkoutDir, agpVersion) expect: - verify(relocatedResult, EXPECTED_RESULTS) + if (agpVersion.startsWith('3.6')) { + expectDeprecationWarnings(result, + "Internal API constructor DefaultDomainObjectSet(Class) has been deprecated. This is scheduled to be removed in Gradle 7.0. Please use ObjectFactory.domainObjectSet(Class) instead." + ) + } else { + expectNoDeprecationWarnings(result) + } + + where: + agpVersion << testedAgpVersions } + @Unroll @ToBeFixedForInstantExecution - def "incremental Java compilation works for Santa Tracker"() { - def checkoutDir = temporaryFolder.createDir ("checkout") - setupCopyOfSantaTracker(checkoutDir) + def "incremental Java compilation works for Santa Tracker Kotlin (agp=#agpVersion)"() { + def checkoutDir = temporaryFolder.createDir("checkout") + setupCopyOfSantaTracker(checkoutDir, 'Kotlin', agpVersion) def pathToClass = "com/google/android/apps/santatracker/tracker/ui/BottomSheetBehavior" def fileToChange = checkoutDir.file("tracker/src/main/java/${pathToClass}.java") @@ -98,616 +92,48 @@ class AndroidSantaTrackerSmokeTest extends AbstractSmokeTest { def nonAbiChangeMutator = new ApplyNonAbiChangeToJavaSourceFileMutator(fileToChange) when: - def result = buildLocation(checkoutDir) + def result = buildLocation(checkoutDir, agpVersion) def md5Before = compiledClassFile.md5Hash then: result.task(":tracker:compileDebugJavaWithJavac").outcome == SUCCESS when: nonAbiChangeMutator.beforeBuild() - buildLocation(checkoutDir) + buildLocation(checkoutDir, agpVersion) def md5After = compiledClassFile.md5Hash then: result.task(":tracker:compileDebugJavaWithJavac").outcome == SUCCESS md5After != md5Before - } - private void setupCopyOfSantaTracker(TestFile targetDir) { - copyRemoteProject("santaTracker", targetDir) - GradleEnterprisePluginSettingsFixture.applyEnterprisePlugin(targetDir.file("settings.gradle")) + where: + agpVersion << testedAgpVersions } - private BuildResult buildLocation(File projectDir) { - runner("assembleDebug") - .withProjectDir(projectDir) - .withTestKitDir(homeDir) - .forwardOutput() - .build() - } - - private static boolean verify(BuildResult result, Map outcomes) { - println "> Expecting ${outcomes.size()} tasks with outcomes:" - outcomes.values().groupBy { it }.sort().forEach { outcome, instances -> println "> - $outcome: ${instances.size()}" } + @Unroll + def "incremental Java compilation works for Santa Tracker Java (agp=#agpVersion)"() { + def checkoutDir = temporaryFolder.createDir("checkout") + setupCopyOfSantaTracker(checkoutDir, 'Java', agpVersion) - def outcomesWithMatchingTasks = outcomes.findAll { result.task(it.key) } - def hasMatchingTasks = outcomesWithMatchingTasks.size() == outcomes.size() && outcomesWithMatchingTasks.size() == result.tasks.size() - if (!hasMatchingTasks) { - println "> Tasks missing: " + (outcomes.findAll { !outcomesWithMatchingTasks.keySet().contains(it.key) }) - println "> Tasks in surplus: " + (result.tasks.findAll { !outcomesWithMatchingTasks.keySet().contains(it.path) }) - println "> Updated definitions:" - result.tasks - .toSorted { a, b -> a.path <=> b.path } - .forEach { task -> - println "'${task.path}': ${task.outcome}" - } - } + def pathToClass = "com/google/android/apps/santatracker/map/BottomSheetBehavior" + def fileToChange = checkoutDir.file("santa-tracker/src/main/java/${pathToClass}.java") + def compiledClassFile = checkoutDir.file("santa-tracker/build/intermediates/javac/developmentDebug/classes/${pathToClass}.class") + def nonAbiChangeMutator = new ApplyNonAbiChangeToJavaSourceFileMutator(fileToChange) - boolean allOutcomesMatched = true - outcomesWithMatchingTasks.each { taskName, expectedOutcome -> - def taskOutcome = result.task(taskName)?.outcome - if (taskOutcome != expectedOutcome) { - println "> Task '$taskName' was $taskOutcome but should have been $expectedOutcome" - allOutcomesMatched = false - } - } - return hasMatchingTasks && allOutcomesMatched - } + when: + def result = buildLocation(checkoutDir, agpVersion) + def md5Before = compiledClassFile.md5Hash + then: + result.task(":santa-tracker:compileDevelopmentDebugJavaWithJavac").outcome == SUCCESS - private static final EXPECTED_RESULTS = [ - ':cityquiz:assembleDebug': SUCCESS, - ':cityquiz:checkDebugDuplicateClasses': FROM_CACHE, - ':cityquiz:compileDebugAidl': NO_SOURCE, - ':cityquiz:compileDebugJavaWithJavac': FROM_CACHE, - ':cityquiz:compileDebugKotlin': FROM_CACHE, - ':cityquiz:compileDebugRenderscript': NO_SOURCE, - ':cityquiz:compileDebugShaders': FROM_CACHE, - ':cityquiz:compileDebugSources': UP_TO_DATE, - ':cityquiz:createDebugCompatibleScreenManifests': FROM_CACHE, - ':cityquiz:dexBuilderDebug': FROM_CACHE, - ':cityquiz:extractDeepLinksDebug': FROM_CACHE, - ':cityquiz:featureDebugWriter': SUCCESS, - ':cityquiz:generateDebugAssets': UP_TO_DATE, - ':cityquiz:generateDebugBuildConfig': FROM_CACHE, - ':cityquiz:generateDebugFeatureTransitiveDeps': FROM_CACHE, - ':cityquiz:generateDebugResValues': FROM_CACHE, - ':cityquiz:generateDebugResources': UP_TO_DATE, - ':cityquiz:javaPreCompileDebug': FROM_CACHE, - ':cityquiz:mainApkListPersistenceDebug': FROM_CACHE, - ':cityquiz:mergeDebugAssets': FROM_CACHE, - ':cityquiz:mergeDebugJavaResource': SUCCESS, - ':cityquiz:mergeDebugJniLibFolders': FROM_CACHE, - ':cityquiz:mergeDebugNativeLibs': FROM_CACHE, - ':cityquiz:mergeDebugResources': FROM_CACHE, - ':cityquiz:mergeDebugShaders': FROM_CACHE, - ':cityquiz:mergeExtDexDebug': FROM_CACHE, - ':cityquiz:mergeLibDexDebug': FROM_CACHE, - ':cityquiz:mergeProjectDexDebug': FROM_CACHE, - ':cityquiz:packageDebug': SUCCESS, - ':cityquiz:preBuild': UP_TO_DATE, - ':cityquiz:preDebugBuild': UP_TO_DATE, - ':cityquiz:processDebugJavaRes': NO_SOURCE, - ':cityquiz:processDebugManifest': FROM_CACHE, - ':cityquiz:processDebugResources': FROM_CACHE, - ':cityquiz:stripDebugDebugSymbols': FROM_CACHE, - ':common:assembleDebug': SUCCESS, - ':common:bundleDebugAar': SUCCESS, - ':common:bundleLibCompileDebug': SUCCESS, - ':common:bundleLibResDebug': SUCCESS, - ':common:bundleLibRuntimeDebug': SUCCESS, - ':common:compileDebugAidl': NO_SOURCE, - ':common:compileDebugJavaWithJavac': FROM_CACHE, - ':common:compileDebugKotlin': FROM_CACHE, - ':common:compileDebugLibraryResources': FROM_CACHE, - ':common:compileDebugRenderscript': NO_SOURCE, - ':common:compileDebugShaders': FROM_CACHE, - ':common:compileDebugSources': UP_TO_DATE, - ':common:copyDebugJniLibsProjectAndLocalJars': FROM_CACHE, - ':common:copyDebugJniLibsProjectOnly': FROM_CACHE, - ':common:createFullJarDebug': FROM_CACHE, - ':common:extractDebugAnnotations': FROM_CACHE, - ':common:extractDeepLinksDebug': FROM_CACHE, - ':common:generateDebugAssets': UP_TO_DATE, - ':common:generateDebugBuildConfig': FROM_CACHE, - ':common:generateDebugRFile': FROM_CACHE, - ':common:generateDebugResValues': FROM_CACHE, - ':common:generateDebugResources': UP_TO_DATE, - ':common:javaPreCompileDebug': FROM_CACHE, - ':common:mergeDebugConsumerProguardFiles': SUCCESS, - ':common:mergeDebugGeneratedProguardFiles': SUCCESS, - ':common:mergeDebugJavaResource': SUCCESS, - ':common:mergeDebugJniLibFolders': FROM_CACHE, - ':common:mergeDebugNativeLibs': FROM_CACHE, - ':common:mergeDebugShaders': FROM_CACHE, - ':common:packageDebugAssets': FROM_CACHE, - ':common:packageDebugRenderscript': NO_SOURCE, - ':common:packageDebugResources': FROM_CACHE, - ':common:parseDebugLocalResources': FROM_CACHE, - ':common:preBuild': UP_TO_DATE, - ':common:preDebugBuild': UP_TO_DATE, - ':common:prepareLintJarForPublish': SUCCESS, - ':common:processDebugJavaRes': NO_SOURCE, - ':common:processDebugManifest': FROM_CACHE, - ':common:stripDebugDebugSymbols': FROM_CACHE, - ':common:syncDebugLibJars': SUCCESS, - ':dasherdancer:assembleDebug': SUCCESS, - ':dasherdancer:checkDebugDuplicateClasses': FROM_CACHE, - ':dasherdancer:compileDebugAidl': NO_SOURCE, - ':dasherdancer:compileDebugJavaWithJavac': FROM_CACHE, - ':dasherdancer:compileDebugKotlin': FROM_CACHE, - ':dasherdancer:compileDebugRenderscript': NO_SOURCE, - ':dasherdancer:compileDebugShaders': FROM_CACHE, - ':dasherdancer:compileDebugSources': UP_TO_DATE, - ':dasherdancer:createDebugCompatibleScreenManifests': FROM_CACHE, - ':dasherdancer:dexBuilderDebug': FROM_CACHE, - ':dasherdancer:extractDeepLinksDebug': FROM_CACHE, - ':dasherdancer:featureDebugWriter': SUCCESS, - ':dasherdancer:generateDebugAssets': UP_TO_DATE, - ':dasherdancer:generateDebugBuildConfig': FROM_CACHE, - ':dasherdancer:generateDebugFeatureTransitiveDeps': FROM_CACHE, - ':dasherdancer:generateDebugResValues': FROM_CACHE, - ':dasherdancer:generateDebugResources': UP_TO_DATE, - ':dasherdancer:javaPreCompileDebug': FROM_CACHE, - ':dasherdancer:mainApkListPersistenceDebug': FROM_CACHE, - ':dasherdancer:mergeDebugAssets': FROM_CACHE, - ':dasherdancer:mergeDebugJavaResource': SUCCESS, - ':dasherdancer:mergeDebugJniLibFolders': FROM_CACHE, - ':dasherdancer:mergeDebugNativeLibs': FROM_CACHE, - ':dasherdancer:mergeDebugResources': FROM_CACHE, - ':dasherdancer:mergeDebugShaders': FROM_CACHE, - ':dasherdancer:mergeExtDexDebug': FROM_CACHE, - ':dasherdancer:mergeLibDexDebug': FROM_CACHE, - ':dasherdancer:mergeProjectDexDebug': FROM_CACHE, - ':dasherdancer:packageDebug': SUCCESS, - ':dasherdancer:preBuild': UP_TO_DATE, - ':dasherdancer:preDebugBuild': UP_TO_DATE, - ':dasherdancer:processDebugJavaRes': NO_SOURCE, - ':dasherdancer:processDebugManifest': FROM_CACHE, - ':dasherdancer:processDebugResources': FROM_CACHE, - ':dasherdancer:stripDebugDebugSymbols': FROM_CACHE, - ':doodles-lib:assembleDebug': SUCCESS, - ':doodles-lib:bundleDebugAar': SUCCESS, - ':doodles-lib:bundleLibCompileDebug': SUCCESS, - ':doodles-lib:bundleLibResDebug': SUCCESS, - ':doodles-lib:bundleLibRuntimeDebug': SUCCESS, - ':doodles-lib:compileDebugAidl': NO_SOURCE, - ':doodles-lib:compileDebugJavaWithJavac': FROM_CACHE, - ':doodles-lib:compileDebugLibraryResources': FROM_CACHE, - ':doodles-lib:compileDebugRenderscript': NO_SOURCE, - ':doodles-lib:compileDebugShaders': FROM_CACHE, - ':doodles-lib:compileDebugSources': UP_TO_DATE, - ':doodles-lib:copyDebugJniLibsProjectAndLocalJars': FROM_CACHE, - ':doodles-lib:copyDebugJniLibsProjectOnly': FROM_CACHE, - ':doodles-lib:createFullJarDebug': FROM_CACHE, - ':doodles-lib:extractDebugAnnotations': FROM_CACHE, - ':doodles-lib:extractDeepLinksDebug': FROM_CACHE, - ':doodles-lib:generateDebugAssets': UP_TO_DATE, - ':doodles-lib:generateDebugBuildConfig': FROM_CACHE, - ':doodles-lib:generateDebugRFile': FROM_CACHE, - ':doodles-lib:generateDebugResValues': FROM_CACHE, - ':doodles-lib:generateDebugResources': UP_TO_DATE, - ':doodles-lib:javaPreCompileDebug': FROM_CACHE, - ':doodles-lib:mergeDebugConsumerProguardFiles': SUCCESS, - ':doodles-lib:mergeDebugGeneratedProguardFiles': SUCCESS, - ':doodles-lib:mergeDebugJavaResource': FROM_CACHE, - ':doodles-lib:mergeDebugJniLibFolders': FROM_CACHE, - ':doodles-lib:mergeDebugNativeLibs': FROM_CACHE, - ':doodles-lib:mergeDebugShaders': FROM_CACHE, - ':doodles-lib:packageDebugAssets': FROM_CACHE, - ':doodles-lib:packageDebugRenderscript': NO_SOURCE, - ':doodles-lib:packageDebugResources': FROM_CACHE, - ':doodles-lib:parseDebugLocalResources': FROM_CACHE, - ':doodles-lib:preBuild': UP_TO_DATE, - ':doodles-lib:preDebugBuild': UP_TO_DATE, - ':doodles-lib:prepareLintJarForPublish': SUCCESS, - ':doodles-lib:processDebugJavaRes': NO_SOURCE, - ':doodles-lib:processDebugManifest': FROM_CACHE, - ':doodles-lib:stripDebugDebugSymbols': FROM_CACHE, - ':doodles-lib:syncDebugLibJars': FROM_CACHE, - ':gumball:assembleDebug': SUCCESS, - ':gumball:checkDebugDuplicateClasses': FROM_CACHE, - ':gumball:compileDebugAidl': NO_SOURCE, - ':gumball:compileDebugJavaWithJavac': FROM_CACHE, - ':gumball:compileDebugRenderscript': NO_SOURCE, - ':gumball:compileDebugShaders': FROM_CACHE, - ':gumball:compileDebugSources': UP_TO_DATE, - ':gumball:createDebugCompatibleScreenManifests': FROM_CACHE, - ':gumball:dexBuilderDebug': FROM_CACHE, - ':gumball:extractDeepLinksDebug': FROM_CACHE, - ':gumball:featureDebugWriter': SUCCESS, - ':gumball:generateDebugAssets': UP_TO_DATE, - ':gumball:generateDebugBuildConfig': FROM_CACHE, - ':gumball:generateDebugFeatureTransitiveDeps': FROM_CACHE, - ':gumball:generateDebugResValues': FROM_CACHE, - ':gumball:generateDebugResources': UP_TO_DATE, - ':gumball:javaPreCompileDebug': FROM_CACHE, - ':gumball:mainApkListPersistenceDebug': FROM_CACHE, - ':gumball:mergeDebugAssets': FROM_CACHE, - ':gumball:mergeDebugJavaResource': FROM_CACHE, - ':gumball:mergeDebugJniLibFolders': FROM_CACHE, - ':gumball:mergeDebugNativeLibs': FROM_CACHE, - ':gumball:mergeDebugResources': FROM_CACHE, - ':gumball:mergeDebugShaders': FROM_CACHE, - ':gumball:mergeExtDexDebug': FROM_CACHE, - ':gumball:mergeLibDexDebug': FROM_CACHE, - ':gumball:mergeProjectDexDebug': FROM_CACHE, - ':gumball:packageDebug': SUCCESS, - ':gumball:preBuild': UP_TO_DATE, - ':gumball:preDebugBuild': UP_TO_DATE, - ':gumball:processDebugJavaRes': NO_SOURCE, - ':gumball:processDebugManifest': FROM_CACHE, - ':gumball:processDebugResources': FROM_CACHE, - ':gumball:stripDebugDebugSymbols': FROM_CACHE, - ':jetpack:assembleDebug': SUCCESS, - ':jetpack:checkDebugDuplicateClasses': FROM_CACHE, - ':jetpack:compileDebugAidl': NO_SOURCE, - ':jetpack:compileDebugJavaWithJavac': FROM_CACHE, - ':jetpack:compileDebugKotlin': FROM_CACHE, - ':jetpack:compileDebugRenderscript': NO_SOURCE, - ':jetpack:compileDebugShaders': FROM_CACHE, - ':jetpack:compileDebugSources': UP_TO_DATE, - ':jetpack:createDebugCompatibleScreenManifests': FROM_CACHE, - ':jetpack:dexBuilderDebug': FROM_CACHE, - ':jetpack:extractDeepLinksDebug': FROM_CACHE, - ':jetpack:featureDebugWriter': SUCCESS, - ':jetpack:generateDebugAssets': UP_TO_DATE, - ':jetpack:generateDebugBuildConfig': FROM_CACHE, - ':jetpack:generateDebugFeatureTransitiveDeps': FROM_CACHE, - ':jetpack:generateDebugResValues': FROM_CACHE, - ':jetpack:generateDebugResources': UP_TO_DATE, - ':jetpack:javaPreCompileDebug': FROM_CACHE, - ':jetpack:mainApkListPersistenceDebug': FROM_CACHE, - ':jetpack:mergeDebugAssets': FROM_CACHE, - ':jetpack:mergeDebugJavaResource': SUCCESS, - ':jetpack:mergeDebugJniLibFolders': FROM_CACHE, - ':jetpack:mergeDebugNativeLibs': FROM_CACHE, - ':jetpack:mergeDebugResources': FROM_CACHE, - ':jetpack:mergeDebugShaders': FROM_CACHE, - ':jetpack:mergeExtDexDebug': FROM_CACHE, - ':jetpack:mergeLibDexDebug': FROM_CACHE, - ':jetpack:mergeProjectDexDebug': FROM_CACHE, - ':jetpack:packageDebug': SUCCESS, - ':jetpack:preBuild': UP_TO_DATE, - ':jetpack:preDebugBuild': UP_TO_DATE, - ':jetpack:processDebugJavaRes': NO_SOURCE, - ':jetpack:processDebugManifest': FROM_CACHE, - ':jetpack:processDebugResources': FROM_CACHE, - ':jetpack:stripDebugDebugSymbols': FROM_CACHE, - ':memory:assembleDebug': SUCCESS, - ':memory:checkDebugDuplicateClasses': FROM_CACHE, - ':memory:compileDebugAidl': NO_SOURCE, - ':memory:compileDebugJavaWithJavac': FROM_CACHE, - ':memory:compileDebugRenderscript': NO_SOURCE, - ':memory:compileDebugShaders': FROM_CACHE, - ':memory:compileDebugSources': UP_TO_DATE, - ':memory:createDebugCompatibleScreenManifests': FROM_CACHE, - ':memory:dexBuilderDebug': FROM_CACHE, - ':memory:extractDeepLinksDebug': FROM_CACHE, - ':memory:featureDebugWriter': SUCCESS, - ':memory:generateDebugAssets': UP_TO_DATE, - ':memory:generateDebugBuildConfig': FROM_CACHE, - ':memory:generateDebugFeatureTransitiveDeps': FROM_CACHE, - ':memory:generateDebugResValues': FROM_CACHE, - ':memory:generateDebugResources': UP_TO_DATE, - ':memory:javaPreCompileDebug': FROM_CACHE, - ':memory:mainApkListPersistenceDebug': FROM_CACHE, - ':memory:mergeDebugAssets': FROM_CACHE, - ':memory:mergeDebugJavaResource': FROM_CACHE, - ':memory:mergeDebugJniLibFolders': FROM_CACHE, - ':memory:mergeDebugNativeLibs': FROM_CACHE, - ':memory:mergeDebugResources': FROM_CACHE, - ':memory:mergeDebugShaders': FROM_CACHE, - ':memory:mergeExtDexDebug': FROM_CACHE, - ':memory:mergeLibDexDebug': FROM_CACHE, - ':memory:mergeProjectDexDebug': FROM_CACHE, - ':memory:packageDebug': SUCCESS, - ':memory:preBuild': UP_TO_DATE, - ':memory:preDebugBuild': UP_TO_DATE, - ':memory:processDebugJavaRes': NO_SOURCE, - ':memory:processDebugManifest': FROM_CACHE, - ':memory:processDebugResources': FROM_CACHE, - ':memory:stripDebugDebugSymbols': FROM_CACHE, - ':penguinswim:assembleDebug': SUCCESS, - ':penguinswim:checkDebugDuplicateClasses': FROM_CACHE, - ':penguinswim:compileDebugAidl': NO_SOURCE, - ':penguinswim:compileDebugJavaWithJavac': FROM_CACHE, - ':penguinswim:compileDebugRenderscript': NO_SOURCE, - ':penguinswim:compileDebugShaders': FROM_CACHE, - ':penguinswim:compileDebugSources': UP_TO_DATE, - ':penguinswim:createDebugCompatibleScreenManifests': FROM_CACHE, - ':penguinswim:dexBuilderDebug': FROM_CACHE, - ':penguinswim:extractDeepLinksDebug': FROM_CACHE, - ':penguinswim:featureDebugWriter': SUCCESS, - ':penguinswim:generateDebugAssets': UP_TO_DATE, - ':penguinswim:generateDebugBuildConfig': FROM_CACHE, - ':penguinswim:generateDebugFeatureTransitiveDeps': FROM_CACHE, - ':penguinswim:generateDebugResValues': FROM_CACHE, - ':penguinswim:generateDebugResources': UP_TO_DATE, - ':penguinswim:javaPreCompileDebug': FROM_CACHE, - ':penguinswim:mainApkListPersistenceDebug': FROM_CACHE, - ':penguinswim:mergeDebugAssets': FROM_CACHE, - ':penguinswim:mergeDebugJavaResource': FROM_CACHE, - ':penguinswim:mergeDebugJniLibFolders': FROM_CACHE, - ':penguinswim:mergeDebugNativeLibs': FROM_CACHE, - ':penguinswim:mergeDebugResources': FROM_CACHE, - ':penguinswim:mergeDebugShaders': FROM_CACHE, - ':penguinswim:mergeExtDexDebug': FROM_CACHE, - ':penguinswim:mergeLibDexDebug': FROM_CACHE, - ':penguinswim:mergeProjectDexDebug': FROM_CACHE, - ':penguinswim:packageDebug': SUCCESS, - ':penguinswim:preBuild': UP_TO_DATE, - ':penguinswim:preDebugBuild': UP_TO_DATE, - ':penguinswim:processDebugJavaRes': NO_SOURCE, - ':penguinswim:processDebugManifest': FROM_CACHE, - ':penguinswim:processDebugResources': FROM_CACHE, - ':penguinswim:stripDebugDebugSymbols': FROM_CACHE, - ':playgames:assembleDebug': SUCCESS, - ':playgames:bundleDebugAar': SUCCESS, - ':playgames:bundleLibCompileDebug': SUCCESS, - ':playgames:bundleLibResDebug': SUCCESS, - ':playgames:bundleLibRuntimeDebug': SUCCESS, - ':playgames:compileDebugAidl': NO_SOURCE, - ':playgames:compileDebugJavaWithJavac': FROM_CACHE, - ':playgames:compileDebugLibraryResources': FROM_CACHE, - ':playgames:compileDebugRenderscript': NO_SOURCE, - ':playgames:compileDebugShaders': FROM_CACHE, - ':playgames:compileDebugSources': UP_TO_DATE, - ':playgames:copyDebugJniLibsProjectAndLocalJars': FROM_CACHE, - ':playgames:copyDebugJniLibsProjectOnly': FROM_CACHE, - ':playgames:createFullJarDebug': FROM_CACHE, - ':playgames:extractDebugAnnotations': FROM_CACHE, - ':playgames:extractDeepLinksDebug': FROM_CACHE, - ':playgames:generateDebugAssets': UP_TO_DATE, - ':playgames:generateDebugBuildConfig': FROM_CACHE, - ':playgames:generateDebugRFile': FROM_CACHE, - ':playgames:generateDebugResValues': FROM_CACHE, - ':playgames:generateDebugResources': UP_TO_DATE, - ':playgames:javaPreCompileDebug': FROM_CACHE, - ':playgames:mergeDebugConsumerProguardFiles': SUCCESS, - ':playgames:mergeDebugGeneratedProguardFiles': SUCCESS, - ':playgames:mergeDebugJavaResource': FROM_CACHE, - ':playgames:mergeDebugJniLibFolders': FROM_CACHE, - ':playgames:mergeDebugNativeLibs': FROM_CACHE, - ':playgames:mergeDebugShaders': FROM_CACHE, - ':playgames:packageDebugAssets': FROM_CACHE, - ':playgames:packageDebugRenderscript': NO_SOURCE, - ':playgames:packageDebugResources': FROM_CACHE, - ':playgames:parseDebugLocalResources': FROM_CACHE, - ':playgames:preBuild': UP_TO_DATE, - ':playgames:preDebugBuild': UP_TO_DATE, - ':playgames:prepareLintJarForPublish': SUCCESS, - ':playgames:processDebugJavaRes': NO_SOURCE, - ':playgames:processDebugManifest': FROM_CACHE, - ':playgames:stripDebugDebugSymbols': FROM_CACHE, - ':playgames:syncDebugLibJars': FROM_CACHE, - ':presenttoss:assembleDebug': SUCCESS, - ':presenttoss:checkDebugDuplicateClasses': FROM_CACHE, - ':presenttoss:compileDebugAidl': NO_SOURCE, - ':presenttoss:compileDebugJavaWithJavac': FROM_CACHE, - ':presenttoss:compileDebugRenderscript': NO_SOURCE, - ':presenttoss:compileDebugShaders': FROM_CACHE, - ':presenttoss:compileDebugSources': UP_TO_DATE, - ':presenttoss:createDebugCompatibleScreenManifests': FROM_CACHE, - ':presenttoss:dexBuilderDebug': FROM_CACHE, - ':presenttoss:extractDeepLinksDebug': FROM_CACHE, - ':presenttoss:featureDebugWriter': SUCCESS, - ':presenttoss:generateDebugAssets': UP_TO_DATE, - ':presenttoss:generateDebugBuildConfig': FROM_CACHE, - ':presenttoss:generateDebugFeatureTransitiveDeps': FROM_CACHE, - ':presenttoss:generateDebugResValues': FROM_CACHE, - ':presenttoss:generateDebugResources': UP_TO_DATE, - ':presenttoss:javaPreCompileDebug': FROM_CACHE, - ':presenttoss:mainApkListPersistenceDebug': FROM_CACHE, - ':presenttoss:mergeDebugAssets': FROM_CACHE, - ':presenttoss:mergeDebugJavaResource': FROM_CACHE, - ':presenttoss:mergeDebugJniLibFolders': FROM_CACHE, - ':presenttoss:mergeDebugNativeLibs': FROM_CACHE, - ':presenttoss:mergeDebugResources': FROM_CACHE, - ':presenttoss:mergeDebugShaders': FROM_CACHE, - ':presenttoss:mergeExtDexDebug': FROM_CACHE, - ':presenttoss:mergeLibDexDebug': FROM_CACHE, - ':presenttoss:mergeProjectDexDebug': FROM_CACHE, - ':presenttoss:packageDebug': SUCCESS, - ':presenttoss:preBuild': UP_TO_DATE, - ':presenttoss:preDebugBuild': UP_TO_DATE, - ':presenttoss:processDebugJavaRes': NO_SOURCE, - ':presenttoss:processDebugManifest': FROM_CACHE, - ':presenttoss:processDebugResources': FROM_CACHE, - ':presenttoss:stripDebugDebugSymbols': FROM_CACHE, - ':rocketsleigh:assembleDebug': SUCCESS, - ':rocketsleigh:checkDebugDuplicateClasses': FROM_CACHE, - ':rocketsleigh:compileDebugAidl': NO_SOURCE, - ':rocketsleigh:compileDebugJavaWithJavac': FROM_CACHE, - ':rocketsleigh:compileDebugKotlin': FROM_CACHE, - ':rocketsleigh:compileDebugRenderscript': NO_SOURCE, - ':rocketsleigh:compileDebugShaders': FROM_CACHE, - ':rocketsleigh:compileDebugSources': UP_TO_DATE, - ':rocketsleigh:createDebugCompatibleScreenManifests': FROM_CACHE, - ':rocketsleigh:dexBuilderDebug': FROM_CACHE, - ':rocketsleigh:extractDeepLinksDebug': FROM_CACHE, - ':rocketsleigh:featureDebugWriter': SUCCESS, - ':rocketsleigh:generateDebugAssets': UP_TO_DATE, - ':rocketsleigh:generateDebugBuildConfig': FROM_CACHE, - ':rocketsleigh:generateDebugFeatureTransitiveDeps': FROM_CACHE, - ':rocketsleigh:generateDebugResValues': FROM_CACHE, - ':rocketsleigh:generateDebugResources': UP_TO_DATE, - ':rocketsleigh:javaPreCompileDebug': FROM_CACHE, - ':rocketsleigh:mainApkListPersistenceDebug': FROM_CACHE, - ':rocketsleigh:mergeDebugAssets': FROM_CACHE, - ':rocketsleigh:mergeDebugJavaResource': SUCCESS, - ':rocketsleigh:mergeDebugJniLibFolders': FROM_CACHE, - ':rocketsleigh:mergeDebugNativeLibs': FROM_CACHE, - ':rocketsleigh:mergeDebugResources': FROM_CACHE, - ':rocketsleigh:mergeDebugShaders': FROM_CACHE, - ':rocketsleigh:mergeExtDexDebug': FROM_CACHE, - ':rocketsleigh:mergeLibDexDebug': FROM_CACHE, - ':rocketsleigh:mergeProjectDexDebug': FROM_CACHE, - ':rocketsleigh:packageDebug': SUCCESS, - ':rocketsleigh:preBuild': UP_TO_DATE, - ':rocketsleigh:preDebugBuild': UP_TO_DATE, - ':rocketsleigh:processDebugJavaRes': NO_SOURCE, - ':rocketsleigh:processDebugManifest': FROM_CACHE, - ':rocketsleigh:processDebugResources': FROM_CACHE, - ':rocketsleigh:stripDebugDebugSymbols': FROM_CACHE, - ':santa-tracker:assembleDebug': SUCCESS, - ':santa-tracker:bundleDebugClasses': SUCCESS, - ':santa-tracker:checkDebugDuplicateClasses': FROM_CACHE, - ':santa-tracker:checkDebugLibraries': FROM_CACHE, - ':santa-tracker:compileDebugAidl': NO_SOURCE, - ':santa-tracker:compileDebugJavaWithJavac': FROM_CACHE, - ':santa-tracker:compileDebugKotlin': FROM_CACHE, - ':santa-tracker:compileDebugRenderscript': NO_SOURCE, - ':santa-tracker:compileDebugShaders': FROM_CACHE, - ':santa-tracker:compileDebugSources': UP_TO_DATE, - ':santa-tracker:createDebugCompatibleScreenManifests': FROM_CACHE, - ':santa-tracker:dexBuilderDebug': FROM_CACHE, - ':santa-tracker:extractDeepLinksDebug': FROM_CACHE, - ':santa-tracker:generateDebugAssets': UP_TO_DATE, - ':santa-tracker:generateDebugBuildConfig': FROM_CACHE, - ':santa-tracker:generateDebugFeatureMetadata': FROM_CACHE, - ':santa-tracker:generateDebugFeatureTransitiveDeps': FROM_CACHE, - ':santa-tracker:generateDebugResValues': FROM_CACHE, - ':santa-tracker:generateDebugResources': SUCCESS, - ':santa-tracker:handleDebugMicroApk': SUCCESS, - ':santa-tracker:javaPreCompileDebug': FROM_CACHE, - ':santa-tracker:kaptDebugKotlin': SUCCESS, - ':santa-tracker:kaptGenerateStubsDebugKotlin': FROM_CACHE, - ':santa-tracker:mainApkListPersistenceDebug': FROM_CACHE, - ':santa-tracker:mergeDebugAssets': FROM_CACHE, - ':santa-tracker:mergeDebugJavaResource': SUCCESS, - ':santa-tracker:mergeDebugJniLibFolders': FROM_CACHE, - ':santa-tracker:mergeDebugNativeLibs': FROM_CACHE, - ':santa-tracker:mergeDebugResources': FROM_CACHE, - ':santa-tracker:mergeDebugShaders': FROM_CACHE, - ':santa-tracker:mergeExtDexDebug': FROM_CACHE, - ':santa-tracker:mergeLibDexDebug': FROM_CACHE, - ':santa-tracker:mergeProjectDexDebug': FROM_CACHE, - ':santa-tracker:packageDebug': SUCCESS, - ':santa-tracker:preBuild': UP_TO_DATE, - ':santa-tracker:preDebugBuild': FROM_CACHE, - ':santa-tracker:processDebugJavaRes': NO_SOURCE, - ':santa-tracker:processDebugManifest': FROM_CACHE, - ':santa-tracker:processDebugResources': FROM_CACHE, - ':santa-tracker:signingConfigWriterDebug': FROM_CACHE, - ':santa-tracker:stripDebugDebugSymbols': FROM_CACHE, - ':santa-tracker:validateSigningDebug': FROM_CACHE, - ':santa-tracker:writeDebugModuleMetadata': SUCCESS, - ':snowballrun:assembleDebug': SUCCESS, - ':snowballrun:checkDebugDuplicateClasses': FROM_CACHE, - ':snowballrun:compileDebugAidl': NO_SOURCE, - ':snowballrun:compileDebugJavaWithJavac': FROM_CACHE, - ':snowballrun:compileDebugRenderscript': NO_SOURCE, - ':snowballrun:compileDebugShaders': FROM_CACHE, - ':snowballrun:compileDebugSources': UP_TO_DATE, - ':snowballrun:createDebugCompatibleScreenManifests': FROM_CACHE, - ':snowballrun:dexBuilderDebug': FROM_CACHE, - ':snowballrun:extractDeepLinksDebug': FROM_CACHE, - ':snowballrun:featureDebugWriter': SUCCESS, - ':snowballrun:generateDebugAssets': UP_TO_DATE, - ':snowballrun:generateDebugBuildConfig': FROM_CACHE, - ':snowballrun:generateDebugFeatureTransitiveDeps': FROM_CACHE, - ':snowballrun:generateDebugResValues': FROM_CACHE, - ':snowballrun:generateDebugResources': UP_TO_DATE, - ':snowballrun:javaPreCompileDebug': FROM_CACHE, - ':snowballrun:mainApkListPersistenceDebug': FROM_CACHE, - ':snowballrun:mergeDebugAssets': FROM_CACHE, - ':snowballrun:mergeDebugJavaResource': FROM_CACHE, - ':snowballrun:mergeDebugJniLibFolders': FROM_CACHE, - ':snowballrun:mergeDebugNativeLibs': FROM_CACHE, - ':snowballrun:mergeDebugResources': FROM_CACHE, - ':snowballrun:mergeDebugShaders': FROM_CACHE, - ':snowballrun:mergeExtDexDebug': FROM_CACHE, - ':snowballrun:mergeLibDexDebug': FROM_CACHE, - ':snowballrun:mergeProjectDexDebug': FROM_CACHE, - ':snowballrun:packageDebug': SUCCESS, - ':snowballrun:preBuild': UP_TO_DATE, - ':snowballrun:preDebugBuild': UP_TO_DATE, - ':snowballrun:processDebugJavaRes': NO_SOURCE, - ':snowballrun:processDebugManifest': FROM_CACHE, - ':snowballrun:processDebugResources': FROM_CACHE, - ':snowballrun:stripDebugDebugSymbols': FROM_CACHE, - ':tracker:assembleDebug': SUCCESS, - ':tracker:bundleDebugAar': SUCCESS, - ':tracker:bundleLibCompileDebug': SUCCESS, - ':tracker:bundleLibResDebug': SUCCESS, - ':tracker:bundleLibRuntimeDebug': SUCCESS, - ':tracker:compileDebugAidl': NO_SOURCE, - ':tracker:compileDebugJavaWithJavac': SUCCESS, - ':tracker:compileDebugKotlin': FROM_CACHE, - ':tracker:compileDebugLibraryResources': FROM_CACHE, - ':tracker:compileDebugRenderscript': NO_SOURCE, - ':tracker:compileDebugShaders': FROM_CACHE, - ':tracker:compileDebugSources': SUCCESS, - ':tracker:copyDebugJniLibsProjectAndLocalJars': FROM_CACHE, - ':tracker:copyDebugJniLibsProjectOnly': FROM_CACHE, - ':tracker:createFullJarDebug': FROM_CACHE, - ':tracker:extractDebugAnnotations': FROM_CACHE, - ':tracker:extractDeepLinksDebug': FROM_CACHE, - ':tracker:generateDebugAssets': UP_TO_DATE, - ':tracker:generateDebugBuildConfig': FROM_CACHE, - ':tracker:generateDebugRFile': FROM_CACHE, - ':tracker:generateDebugResValues': FROM_CACHE, - ':tracker:generateDebugResources': UP_TO_DATE, - ':tracker:javaPreCompileDebug': FROM_CACHE, - ':tracker:kaptDebugKotlin': SUCCESS, - ':tracker:kaptGenerateStubsDebugKotlin': SUCCESS, - ':tracker:mergeDebugConsumerProguardFiles': SUCCESS, - ':tracker:mergeDebugGeneratedProguardFiles': SUCCESS, - ':tracker:mergeDebugJavaResource': SUCCESS, - ':tracker:mergeDebugJniLibFolders': FROM_CACHE, - ':tracker:mergeDebugNativeLibs': FROM_CACHE, - ':tracker:mergeDebugResources': FROM_CACHE, - ':tracker:mergeDebugShaders': FROM_CACHE, - ':tracker:packageDebugAssets': FROM_CACHE, - ':tracker:packageDebugRenderscript': NO_SOURCE, - ':tracker:packageDebugResources': FROM_CACHE, - ':tracker:parseDebugLocalResources': FROM_CACHE, - ':tracker:preBuild': UP_TO_DATE, - ':tracker:preDebugBuild': UP_TO_DATE, - ':tracker:prepareLintJarForPublish': SUCCESS, - ':tracker:processDebugJavaRes': NO_SOURCE, - ':tracker:processDebugManifest': FROM_CACHE, - ':tracker:stripDebugDebugSymbols': FROM_CACHE, - ':tracker:syncDebugLibJars': SUCCESS, - ':wearable:assembleDebug': SUCCESS, - ':wearable:checkDebugDuplicateClasses': FROM_CACHE, - ':wearable:compileDebugAidl': NO_SOURCE, - ':wearable:compileDebugJavaWithJavac': FROM_CACHE, - ':wearable:compileDebugKotlin': FROM_CACHE, - ':wearable:compileDebugRenderscript': NO_SOURCE, - ':wearable:compileDebugShaders': FROM_CACHE, - ':wearable:compileDebugSources': UP_TO_DATE, - ':wearable:createDebugCompatibleScreenManifests': FROM_CACHE, - ':wearable:dexBuilderDebug': FROM_CACHE, - ':wearable:extractDeepLinksDebug': FROM_CACHE, - ':wearable:generateDebugAssets': UP_TO_DATE, - ':wearable:generateDebugBuildConfig': FROM_CACHE, - ':wearable:generateDebugResValues': FROM_CACHE, - ':wearable:generateDebugResources': UP_TO_DATE, - ':wearable:javaPreCompileDebug': FROM_CACHE, - ':wearable:kaptDebugKotlin': SUCCESS, - ':wearable:kaptGenerateStubsDebugKotlin': FROM_CACHE, - ':wearable:mainApkListPersistenceDebug': FROM_CACHE, - ':wearable:mergeDebugAssets': FROM_CACHE, - ':wearable:mergeDebugJavaResource': SUCCESS, - ':wearable:mergeDebugJniLibFolders': FROM_CACHE, - ':wearable:mergeDebugNativeLibs': FROM_CACHE, - ':wearable:mergeDebugResources': FROM_CACHE, - ':wearable:mergeDebugShaders': FROM_CACHE, - ':wearable:mergeExtDexDebug': FROM_CACHE, - ':wearable:mergeLibDexDebug': FROM_CACHE, - ':wearable:mergeProjectDexDebug': FROM_CACHE, - ':wearable:packageDebug': SUCCESS, - ':wearable:preBuild': UP_TO_DATE, - ':wearable:preDebugBuild': UP_TO_DATE, - ':wearable:processDebugJavaRes': NO_SOURCE, - ':wearable:processDebugManifest': FROM_CACHE, - ':wearable:processDebugResources': FROM_CACHE, - ':wearable:stripDebugDebugSymbols': FROM_CACHE, - ':wearable:validateSigningDebug': FROM_CACHE, - ] + when: + nonAbiChangeMutator.beforeBuild() + buildLocation(checkoutDir, agpVersion) + def md5After = compiledClassFile.md5Hash + then: + result.task(":santa-tracker:compileDevelopmentDebugJavaWithJavac").outcome == SUCCESS + md5After != md5Before - def cleanup() { - // The daemons started by test kit need to be killed, so no locked files are left behind. - DaemonLogsAnalyzer.newAnalyzer(homeDir.file(ToolingApiGradleExecutor.TEST_KIT_DAEMON_DIR_NAME)).killAll() + where: + agpVersion << testedAgpVersions } } From cf98abb6de299664fd9b3141065e31ba557eaf32 Mon Sep 17 00:00:00 2001 From: Paul Merlin Date: Mon, 20 Jan 2020 14:20:38 +0100 Subject: [PATCH 10/39] Refine AndroidPluginsSmokeTest Signed-off-by: Paul Merlin --- .../smoketests/AndroidPluginsSmokeTest.groovy | 23 +++++++++++++++---- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/subprojects/smoke-test/src/smokeTest/groovy/org/gradle/smoketests/AndroidPluginsSmokeTest.groovy b/subprojects/smoke-test/src/smokeTest/groovy/org/gradle/smoketests/AndroidPluginsSmokeTest.groovy index 2b08aa01ca3b..ba599453cc28 100644 --- a/subprojects/smoke-test/src/smokeTest/groovy/org/gradle/smoketests/AndroidPluginsSmokeTest.groovy +++ b/subprojects/smoke-test/src/smokeTest/groovy/org/gradle/smoketests/AndroidPluginsSmokeTest.groovy @@ -82,13 +82,16 @@ class AndroidPluginsSmokeTest extends AbstractSmokeTest { android.defaultConfig.applicationId "org.gradle.android.myapplication" """.stripIndent() << androidPluginConfiguration() << activityDependency() - when: - def result = useAgpVersion(pluginVersion, runner( + and: + def runner = useAgpVersion(pluginVersion, runner( 'androidDependencies', 'build', 'connectedAndroidTest', '-x', 'lint' - )).build() + )) + + when: + def result = runner.build() then: def pluginBaseVersion = VersionNumber.parse(pluginVersion).baseVersion @@ -105,6 +108,13 @@ class AndroidPluginsSmokeTest extends AbstractSmokeTest { expectNoDeprecationWarnings(result) } + when: 'abi change on application' + writeActivity(basedir, packageName, activity, true) + result = runner.build() + + then: 'sources are recompiled' + result.task(':compileReleaseJavaWithJavac').outcome == TaskOutcome.SUCCESS + where: pluginVersion << TestedVersions.androidGradle } @@ -192,8 +202,11 @@ class AndroidPluginsSmokeTest extends AbstractSmokeTest { libraryBuildFile << androidPluginConfiguration() libraryBuildFile << activityDependency() + and: + def runner = useAgpVersion(pluginVersion, runner('build', '-x', 'lint')) + when: - def result = useAgpVersion(pluginVersion, runner('build', '-x', 'lint')).build() + def result = runner.build() then: result.task(':app:assemble').outcome == TaskOutcome.SUCCESS @@ -206,7 +219,7 @@ class AndroidPluginsSmokeTest extends AbstractSmokeTest { when: 'abi change on library' writeActivity(library, libPackage, libraryActivity, true) - result = useAgpVersion(pluginVersion, runner('build', '-x', 'lint')).build() + result = runner.build() then: 'dependent sources are recompiled' result.task(':library:compileReleaseJavaWithJavac').outcome == TaskOutcome.SUCCESS From f61f3732013f6e48ebdb1dbade9df8af83710bdb Mon Sep 17 00:00:00 2001 From: Paul Merlin Date: Mon, 20 Jan 2020 15:09:38 +0100 Subject: [PATCH 11/39] Make CodeNarc happy Signed-off-by: Paul Merlin --- ...stractInstantExecutionAndroidIntegrationTest.groovy | 4 ++-- .../InstantExecutionAndroidIntegrationTest.groovy | 4 ++-- .../InstantExecutionSantaTrackerIntegrationTest.groovy | 4 ++-- .../AbstractAndroidSantaTrackerSmokeTest.groovy | 5 ++--- .../org/gradle/smoketests/AbstractSmokeTest.groovy | 10 +++++----- .../AndroidSantaTrackerJavaCachingSmokeTest.groovy | 2 +- .../AndroidSantaTrackerKotlinCachingSmokeTest.groovy | 2 +- .../smoketests/AndroidSantaTrackerSmokeTest.groovy | 8 ++++---- 8 files changed, 19 insertions(+), 20 deletions(-) diff --git a/subprojects/instant-execution/src/integTest/groovy/org/gradle/instantexecution/AbstractInstantExecutionAndroidIntegrationTest.groovy b/subprojects/instant-execution/src/integTest/groovy/org/gradle/instantexecution/AbstractInstantExecutionAndroidIntegrationTest.groovy index 9aeabed0da49..91c0394e8da2 100644 --- a/subprojects/instant-execution/src/integTest/groovy/org/gradle/instantexecution/AbstractInstantExecutionAndroidIntegrationTest.groovy +++ b/subprojects/instant-execution/src/integTest/groovy/org/gradle/instantexecution/AbstractInstantExecutionAndroidIntegrationTest.groovy @@ -31,9 +31,9 @@ import static org.gradle.integtests.fixtures.versions.AndroidGradlePluginVersion @CompileStatic abstract class AbstractInstantExecutionAndroidIntegrationTest extends AbstractInstantExecutionIntegrationTest { - private static final AndroidGradlePluginVersions agpVersions = new AndroidGradlePluginVersions() + private static final AndroidGradlePluginVersions AGP_VERSIONS = new AndroidGradlePluginVersions() - protected static final String[] testedAgpVersions = agpVersions.getLatestsFromMinorPlusNightly("4.0") + protected static final List TESTED_AGP_VERSIONS = AGP_VERSIONS.getLatestsFromMinorPlusNightly("4.0") def setup() { AndroidHome.assumeIsSet() diff --git a/subprojects/instant-execution/src/integTest/groovy/org/gradle/instantexecution/InstantExecutionAndroidIntegrationTest.groovy b/subprojects/instant-execution/src/integTest/groovy/org/gradle/instantexecution/InstantExecutionAndroidIntegrationTest.groovy index eae67d5cea58..f07a35be3963 100644 --- a/subprojects/instant-execution/src/integTest/groovy/org/gradle/instantexecution/InstantExecutionAndroidIntegrationTest.groovy +++ b/subprojects/instant-execution/src/integTest/groovy/org/gradle/instantexecution/InstantExecutionAndroidIntegrationTest.groovy @@ -61,7 +61,7 @@ class InstantExecutionAndroidIntegrationTest extends AbstractInstantExecutionAnd instantExecution.assertStateLoaded() where: - [agpVersion, fromIde] << [testedAgpVersions, [false, true]].combinations() + [agpVersion, fromIde] << [TESTED_AGP_VERSIONS, [false, true]].combinations() } @Unroll @@ -84,6 +84,6 @@ class InstantExecutionAndroidIntegrationTest extends AbstractInstantExecutionAnd instantExecution.assertStateLoaded() where: - [agpVersion, fromIde] << [testedAgpVersions, [false, true]].combinations() + [agpVersion, fromIde] << [TESTED_AGP_VERSIONS, [false, true]].combinations() } } diff --git a/subprojects/instant-execution/src/integTest/groovy/org/gradle/instantexecution/InstantExecutionSantaTrackerIntegrationTest.groovy b/subprojects/instant-execution/src/integTest/groovy/org/gradle/instantexecution/InstantExecutionSantaTrackerIntegrationTest.groovy index 11cb6c94b682..38ca3c009dd0 100644 --- a/subprojects/instant-execution/src/integTest/groovy/org/gradle/instantexecution/InstantExecutionSantaTrackerIntegrationTest.groovy +++ b/subprojects/instant-execution/src/integTest/groovy/org/gradle/instantexecution/InstantExecutionSantaTrackerIntegrationTest.groovy @@ -50,7 +50,7 @@ class InstantExecutionSantaTrackerIntegrationTest extends AbstractInstantExecuti [remoteProject, agpVersion, fromIde] << [ // TODO:instant-execution Kotlin 1.3.70 ["santaTrackerJava" /*, "santaTrackerKotlin" */], - testedAgpVersions, + TESTED_AGP_VERSIONS, [false, true] ].combinations() } @@ -76,7 +76,7 @@ class InstantExecutionSantaTrackerIntegrationTest extends AbstractInstantExecuti [remoteProject, agpVersion, fromIde] << [ // TODO:instant-execution Kotlin 1.3.70 ["santaTrackerJava" /*, "santaTrackerKotlin" */], - testedAgpVersions, + TESTED_AGP_VERSIONS, [false, true] ].combinations() } diff --git a/subprojects/smoke-test/src/smokeTest/groovy/org/gradle/smoketests/AbstractAndroidSantaTrackerSmokeTest.groovy b/subprojects/smoke-test/src/smokeTest/groovy/org/gradle/smoketests/AbstractAndroidSantaTrackerSmokeTest.groovy index 05869070c8c6..95ef70fc037a 100644 --- a/subprojects/smoke-test/src/smokeTest/groovy/org/gradle/smoketests/AbstractAndroidSantaTrackerSmokeTest.groovy +++ b/subprojects/smoke-test/src/smokeTest/groovy/org/gradle/smoketests/AbstractAndroidSantaTrackerSmokeTest.groovy @@ -29,8 +29,7 @@ import org.junit.Rule class AbstractAndroidSantaTrackerSmokeTest extends AbstractSmokeTest { - protected static final List testedAgpVersions = agpVersions.getLatestsFromMinorPlusNightly("3.6") - // protected static final List testedAgpVersions = [agpVersions.nightly] + protected static final List TESTED_AGP_VERSIONS = AGP_VERSIONS.getLatestsFromMinorPlusNightly("3.6") @Rule TestNameTestDirectoryProvider temporaryFolder @@ -50,7 +49,7 @@ class AbstractAndroidSantaTrackerSmokeTest extends AbstractSmokeTest { GradleEnterprisePluginSettingsFixture.applyEnterprisePlugin(targetDir.file("settings.gradle")) if (agpVersion != null) { def buildFile = targetDir.file("build.gradle") - buildFile.text = agpVersions.replaceAgpVersion(buildFile.text, agpVersion) + buildFile.text = AGP_VERSIONS.replaceAgpVersion(buildFile.text, agpVersion) } } diff --git a/subprojects/smoke-test/src/smokeTest/groovy/org/gradle/smoketests/AbstractSmokeTest.groovy b/subprojects/smoke-test/src/smokeTest/groovy/org/gradle/smoketests/AbstractSmokeTest.groovy index facedc566943..a7d3ae14c2af 100644 --- a/subprojects/smoke-test/src/smokeTest/groovy/org/gradle/smoketests/AbstractSmokeTest.groovy +++ b/subprojects/smoke-test/src/smokeTest/groovy/org/gradle/smoketests/AbstractSmokeTest.groovy @@ -38,7 +38,7 @@ import static org.gradle.test.fixtures.server.http.MavenHttpPluginRepository.PLU abstract class AbstractSmokeTest extends Specification { - protected static final AndroidGradlePluginVersions agpVersions = new AndroidGradlePluginVersions() + protected static final AndroidGradlePluginVersions AGP_VERSIONS = new AndroidGradlePluginVersions() static class TestedVersions { /** @@ -85,7 +85,7 @@ abstract class AbstractSmokeTest extends Specification { // https://developer.android.com/studio/releases/build-tools static androidTools = "29.0.2" // https://developer.android.com/studio/releases/gradle-plugin - static androidGradle = Versions.of(*agpVersions.latestsPlusNightly) + static androidGradle = Versions.of(*AGP_VERSIONS.latestsPlusNightly) // https://search.maven.org/search?q=g:org.jetbrains.kotlin%20AND%20a:kotlin-project&core=gav static kotlin = Versions.of('1.3.21', '1.3.31', '1.3.41', '1.3.50', '1.3.61') @@ -223,9 +223,9 @@ abstract class AbstractSmokeTest extends Specification { } protected GradleRunner useAgpVersion(String agpVersion, GradleRunner runner) { - def extraArgs = [agpVersions.OVERRIDE_VERSION_CHECK] - if (agpVersions.isAgpNightly(agpVersion)) { - def init = agpVersions.createAgpNightlyRepositoryInitScript() + def extraArgs = [AGP_VERSIONS.OVERRIDE_VERSION_CHECK] + if (AGP_VERSIONS.isAgpNightly(agpVersion)) { + def init = AGP_VERSIONS.createAgpNightlyRepositoryInitScript() extraArgs += ["-I", init.canonicalPath] } return runner.withArguments([runner.arguments, extraArgs].flatten()) diff --git a/subprojects/smoke-test/src/smokeTest/groovy/org/gradle/smoketests/AndroidSantaTrackerJavaCachingSmokeTest.groovy b/subprojects/smoke-test/src/smokeTest/groovy/org/gradle/smoketests/AndroidSantaTrackerJavaCachingSmokeTest.groovy index 53263ae2efc8..803d3b0a2c29 100644 --- a/subprojects/smoke-test/src/smokeTest/groovy/org/gradle/smoketests/AndroidSantaTrackerJavaCachingSmokeTest.groovy +++ b/subprojects/smoke-test/src/smokeTest/groovy/org/gradle/smoketests/AndroidSantaTrackerJavaCachingSmokeTest.groovy @@ -54,7 +54,7 @@ class AndroidSantaTrackerJavaCachingSmokeTest extends AbstractAndroidSantaTracke verify(relocatedResult, expectedResults) where: - agpVersion << testedAgpVersions + agpVersion << TESTED_AGP_VERSIONS } private static final EXPECTED_RESULTS = [ diff --git a/subprojects/smoke-test/src/smokeTest/groovy/org/gradle/smoketests/AndroidSantaTrackerKotlinCachingSmokeTest.groovy b/subprojects/smoke-test/src/smokeTest/groovy/org/gradle/smoketests/AndroidSantaTrackerKotlinCachingSmokeTest.groovy index f9f3643ca0a2..dfdff09a65d9 100644 --- a/subprojects/smoke-test/src/smokeTest/groovy/org/gradle/smoketests/AndroidSantaTrackerKotlinCachingSmokeTest.groovy +++ b/subprojects/smoke-test/src/smokeTest/groovy/org/gradle/smoketests/AndroidSantaTrackerKotlinCachingSmokeTest.groovy @@ -56,7 +56,7 @@ class AndroidSantaTrackerKotlinCachingSmokeTest extends AbstractAndroidSantaTrac verify(relocatedResult, expectedResults) where: - agpVersion << testedAgpVersions + agpVersion << TESTED_AGP_VERSIONS } private static final EXPECTED_RESULTS = [ diff --git a/subprojects/smoke-test/src/smokeTest/groovy/org/gradle/smoketests/AndroidSantaTrackerSmokeTest.groovy b/subprojects/smoke-test/src/smokeTest/groovy/org/gradle/smoketests/AndroidSantaTrackerSmokeTest.groovy index bada02d90627..830758f147c8 100644 --- a/subprojects/smoke-test/src/smokeTest/groovy/org/gradle/smoketests/AndroidSantaTrackerSmokeTest.groovy +++ b/subprojects/smoke-test/src/smokeTest/groovy/org/gradle/smoketests/AndroidSantaTrackerSmokeTest.groovy @@ -57,7 +57,7 @@ class AndroidSantaTrackerSmokeTest extends AbstractAndroidSantaTrackerSmokeTest ) where: - agpVersion << testedAgpVersions + agpVersion << TESTED_AGP_VERSIONS } @Unroll @@ -77,7 +77,7 @@ class AndroidSantaTrackerSmokeTest extends AbstractAndroidSantaTrackerSmokeTest } where: - agpVersion << testedAgpVersions + agpVersion << TESTED_AGP_VERSIONS } @Unroll @@ -106,7 +106,7 @@ class AndroidSantaTrackerSmokeTest extends AbstractAndroidSantaTrackerSmokeTest md5After != md5Before where: - agpVersion << testedAgpVersions + agpVersion << TESTED_AGP_VERSIONS } @Unroll @@ -134,6 +134,6 @@ class AndroidSantaTrackerSmokeTest extends AbstractAndroidSantaTrackerSmokeTest md5After != md5Before where: - agpVersion << testedAgpVersions + agpVersion << TESTED_AGP_VERSIONS } } From 1016a6eb7957dd29d0316bf0b63334a2edbe6c8d Mon Sep 17 00:00:00 2001 From: Paul Merlin Date: Tue, 21 Jan 2020 10:46:13 +0100 Subject: [PATCH 12/39] AGP 4.0 doesn't support Java > 11 Signed-off-by: Paul Merlin --- .../org/gradle/smoketests/AndroidPluginsSmokeTest.groovy | 3 +++ 1 file changed, 3 insertions(+) diff --git a/subprojects/smoke-test/src/smokeTest/groovy/org/gradle/smoketests/AndroidPluginsSmokeTest.groovy b/subprojects/smoke-test/src/smokeTest/groovy/org/gradle/smoketests/AndroidPluginsSmokeTest.groovy index ba599453cc28..120ceccc9452 100644 --- a/subprojects/smoke-test/src/smokeTest/groovy/org/gradle/smoketests/AndroidPluginsSmokeTest.groovy +++ b/subprojects/smoke-test/src/smokeTest/groovy/org/gradle/smoketests/AndroidPluginsSmokeTest.groovy @@ -19,6 +19,8 @@ package org.gradle.smoketests import org.gradle.integtests.fixtures.ToBeFixedForInstantExecution import org.gradle.integtests.fixtures.android.AndroidHome import org.gradle.testkit.runner.TaskOutcome +import org.gradle.util.Requires +import org.gradle.util.TestPrecondition import org.gradle.util.VersionNumber import spock.lang.Unroll @@ -30,6 +32,7 @@ import spock.lang.Unroll * https://androidstudio.googleblog.com/ * */ +@Requires(TestPrecondition.JDK11_OR_EARLIER) class AndroidPluginsSmokeTest extends AbstractSmokeTest { From e0951c66a650656468c029c96b7f1c244ba44c40 Mon Sep 17 00:00:00 2001 From: Paul Merlin Date: Tue, 21 Jan 2020 14:23:03 +0100 Subject: [PATCH 13/39] Simplify AndroidPluginsSmokeTest and prepare for instant execution Signed-off-by: Paul Merlin --- .../smoketests/AndroidPluginsSmokeTest.groovy | 134 ++++++------------ 1 file changed, 46 insertions(+), 88 deletions(-) diff --git a/subprojects/smoke-test/src/smokeTest/groovy/org/gradle/smoketests/AndroidPluginsSmokeTest.groovy b/subprojects/smoke-test/src/smokeTest/groovy/org/gradle/smoketests/AndroidPluginsSmokeTest.groovy index 120ceccc9452..d990b945fb94 100644 --- a/subprojects/smoke-test/src/smokeTest/groovy/org/gradle/smoketests/AndroidPluginsSmokeTest.groovy +++ b/subprojects/smoke-test/src/smokeTest/groovy/org/gradle/smoketests/AndroidPluginsSmokeTest.groovy @@ -35,7 +35,6 @@ import spock.lang.Unroll @Requires(TestPrecondition.JDK11_OR_EARLIER) class AndroidPluginsSmokeTest extends AbstractSmokeTest { - public static final String JAVA_COMPILE_DEPRECATION_MESSAGE = "Extending the JavaCompile task has been deprecated. This is scheduled to be removed in Gradle 7.0. Configure the task instead." def setup() { @@ -44,88 +43,69 @@ class AndroidPluginsSmokeTest extends AbstractSmokeTest { @Unroll @ToBeFixedForInstantExecution - def "android application plugin #pluginVersion"(String pluginVersion) { - given: - - def basedir = '.' - - def packageName = 'org.gradle.android.example' - def activity = 'MyActivity' - writeActivity(basedir, packageName, activity) - - file("${basedir}/src/main/res/values/strings.xml") << ''' - - Android Gradle - '''.stripIndent() - - - file('src/main/AndroidManifest.xml') << """ - - - - - - - - - - - - """.stripIndent() + def "android library and application APK assembly (agp=#agpVersion)"() { - buildFile << buildscript(pluginVersion) << """ - apply plugin: 'com.android.application' - - ${jcenterRepository()} - ${googleRepository()} - - android.defaultConfig.applicationId "org.gradle.android.myapplication" - """.stripIndent() << androidPluginConfiguration() << activityDependency() + given: + def abiChange = androidLibraryAndApplicationBuild(agpVersion) and: - def runner = useAgpVersion(pluginVersion, runner( - 'androidDependencies', - 'build', - 'connectedAndroidTest', - '-x', 'lint' - )) - - when: + def runner = useAgpVersion(agpVersion, runner('assembleDebug')) + + when: 'first build' def result = runner.build() then: - def pluginBaseVersion = VersionNumber.parse(pluginVersion).baseVersion + result.task(':app:compileDebugJavaWithJavac').outcome == TaskOutcome.SUCCESS + result.task(':library:assembleDebug').outcome == TaskOutcome.SUCCESS + result.task(':app:assembleDebug').outcome == TaskOutcome.SUCCESS + + and: + def agpBaseVersion = VersionNumber.parse(agpVersion).baseVersion def threeDotSixBaseVersion = VersionNumber.parse("3.6.0").baseVersion - if (pluginBaseVersion < threeDotSixBaseVersion) { + if (agpBaseVersion < threeDotSixBaseVersion) { assert result.output.contains(JAVA_COMPILE_DEPRECATION_MESSAGE) } else { assert !result.output.contains(JAVA_COMPILE_DEPRECATION_MESSAGE) } - result.task(':assemble').outcome == TaskOutcome.SUCCESS - result.task(':compileReleaseJavaWithJavac').outcome == TaskOutcome.SUCCESS - - if (pluginBaseVersion >= threeDotSixBaseVersion) { + if (agpBaseVersion >= threeDotSixBaseVersion) { expectNoDeprecationWarnings(result) } - when: 'abi change on application' - writeActivity(basedir, packageName, activity, true) + when: 'up-to-date build' + result = runner.build() + + then: + result.task(':app:compileDebugJavaWithJavac').outcome == TaskOutcome.UP_TO_DATE + result.task(':library:assembleDebug').outcome == TaskOutcome.UP_TO_DATE + result.task(':app:assembleDebug').outcome == TaskOutcome.UP_TO_DATE + + when: 'abi change on library' + abiChange.run() result = runner.build() - then: 'sources are recompiled' - result.task(':compileReleaseJavaWithJavac').outcome == TaskOutcome.SUCCESS + then: 'dependent sources are recompiled' + result.task(':library:compileDebugJavaWithJavac').outcome == TaskOutcome.SUCCESS + result.task(':app:compileDebugJavaWithJavac').outcome == TaskOutcome.SUCCESS + result.task(':library:assembleDebug').outcome == TaskOutcome.SUCCESS + result.task(':app:assembleDebug').outcome == TaskOutcome.SUCCESS + + when: 'clean re-build' + useAgpVersion(agpVersion, this.runner('clean')).build() + result = runner.build() + + then: + result.task(':app:compileDebugJavaWithJavac').outcome == TaskOutcome.SUCCESS + result.task(':library:assembleDebug').outcome == TaskOutcome.SUCCESS + result.task(':app:assembleDebug').outcome == TaskOutcome.SUCCESS where: - pluginVersion << TestedVersions.androidGradle + agpVersion << TestedVersions.androidGradle } - @Unroll - @ToBeFixedForInstantExecution - def "android library plugin #pluginVersion"(String pluginVersion) { - given: + /** + * @return ABI change runnable + */ + private Runnable androidLibraryAndApplicationBuild(String agpVersion) { def app = 'app' def appPackage = 'org.gradle.android.example.app' @@ -177,7 +157,7 @@ class AndroidPluginsSmokeTest extends AbstractSmokeTest { include ':${library}' """ - file('build.gradle') << buildscript(pluginVersion) << """ + file('build.gradle') << buildscript(agpVersion) << """ subprojects { ${jcenterRepository()} ${googleRepository()} @@ -205,31 +185,9 @@ class AndroidPluginsSmokeTest extends AbstractSmokeTest { libraryBuildFile << androidPluginConfiguration() libraryBuildFile << activityDependency() - and: - def runner = useAgpVersion(pluginVersion, runner('build', '-x', 'lint')) - - when: - def result = runner.build() - - then: - result.task(':app:assemble').outcome == TaskOutcome.SUCCESS - result.task(':library:assemble').outcome == TaskOutcome.SUCCESS - result.task(':app:compileReleaseJavaWithJavac').outcome == TaskOutcome.SUCCESS - - if (pluginVersion == TestedVersions.androidGradle.latest()) { - expectNoDeprecationWarnings(result) + return { + writeActivity(library, libPackage, libraryActivity, true) } - - when: 'abi change on library' - writeActivity(library, libPackage, libraryActivity, true) - result = runner.build() - - then: 'dependent sources are recompiled' - result.task(':library:compileReleaseJavaWithJavac').outcome == TaskOutcome.SUCCESS - result.task(':app:compileReleaseJavaWithJavac').outcome == TaskOutcome.SUCCESS - - where: - pluginVersion << TestedVersions.androidGradle } private static String activityDependency() { From be271bf2772123f0c31c72229fde14fbf0481ab6 Mon Sep 17 00:00:00 2001 From: Paul Merlin Date: Wed, 15 Jan 2020 15:33:36 +0100 Subject: [PATCH 14/39] Let @UnsupportedWithInstantExecution allow to match on parameterized JUnit tests iterations Signed-off-by: Paul Merlin --- .../fixtures/UnsupportedWithInstantExecution.java | 7 +++++++ .../UnsupportedWithInstantExecutionExtension.groovy | 8 ++++++++ .../fixtures/UnsupportedWithInstantExecutionRule.groovy | 5 ++++- 3 files changed, 19 insertions(+), 1 deletion(-) diff --git a/subprojects/internal-integ-testing/src/main/groovy/org/gradle/integtests/fixtures/UnsupportedWithInstantExecution.java b/subprojects/internal-integ-testing/src/main/groovy/org/gradle/integtests/fixtures/UnsupportedWithInstantExecution.java index 7b028bf54453..fe4d57ff4666 100644 --- a/subprojects/internal-integ-testing/src/main/groovy/org/gradle/integtests/fixtures/UnsupportedWithInstantExecution.java +++ b/subprojects/internal-integ-testing/src/main/groovy/org/gradle/integtests/fixtures/UnsupportedWithInstantExecution.java @@ -32,5 +32,12 @@ @Target(ElementType.METHOD) @ExtensionAnnotation(UnsupportedWithInstantExecutionExtension.class) public @interface UnsupportedWithInstantExecution { + String[] bottomSpecs() default {}; + + /** + * Declare regular expressions matching the iteration name. + * Defaults to an empty array, meaning this annotation applies to all iterations of the annotated feature. + */ + String[] iterationMatchers() default {}; } diff --git a/subprojects/internal-integ-testing/src/main/groovy/org/gradle/integtests/fixtures/UnsupportedWithInstantExecutionExtension.groovy b/subprojects/internal-integ-testing/src/main/groovy/org/gradle/integtests/fixtures/UnsupportedWithInstantExecutionExtension.groovy index d3a1a73eca8c..bf65c61d59ae 100644 --- a/subprojects/internal-integ-testing/src/main/groovy/org/gradle/integtests/fixtures/UnsupportedWithInstantExecutionExtension.groovy +++ b/subprojects/internal-integ-testing/src/main/groovy/org/gradle/integtests/fixtures/UnsupportedWithInstantExecutionExtension.groovy @@ -33,4 +33,12 @@ class UnsupportedWithInstantExecutionExtension extends AbstractAnnotationDrivenE } } } + + static boolean iterationMatches(String[] iterationMatchers, String iterationName) { + return isAllIterations(iterationMatchers) || iterationMatchers.any { iterationName.matches(it) } + } + + private static boolean isAllIterations(String[] iterationMatchers) { + return iterationMatchers.length == 0 + } } diff --git a/subprojects/internal-integ-testing/src/main/groovy/org/gradle/integtests/fixtures/UnsupportedWithInstantExecutionRule.groovy b/subprojects/internal-integ-testing/src/main/groovy/org/gradle/integtests/fixtures/UnsupportedWithInstantExecutionRule.groovy index ed88f2d7a2c5..84f35bfef944 100644 --- a/subprojects/internal-integ-testing/src/main/groovy/org/gradle/integtests/fixtures/UnsupportedWithInstantExecutionRule.groovy +++ b/subprojects/internal-integ-testing/src/main/groovy/org/gradle/integtests/fixtures/UnsupportedWithInstantExecutionRule.groovy @@ -22,6 +22,7 @@ import org.junit.runner.Description import org.junit.runners.model.Statement import static org.gradle.integtests.fixtures.ToBeFixedForInstantExecutionExtension.isEnabledBottomSpec +import static org.gradle.integtests.fixtures.UnsupportedWithInstantExecutionExtension.iterationMatches import static org.junit.Assume.assumeFalse @@ -33,7 +34,9 @@ class UnsupportedWithInstantExecutionRule implements TestRule { if (!GradleContextualExecuter.isInstant() || annotation == null) { return base } - if (isEnabledBottomSpec(annotation.bottomSpecs(), { description.className.endsWith(".$it") })) { + def enabledBottomSpec = isEnabledBottomSpec(annotation.bottomSpecs(), { description.className.endsWith(".$it") }) + def enabledIteration = iterationMatches(annotation.iterationMatchers(), description.methodName) + if (enabledBottomSpec && enabledIteration) { return new SkippingRuleStatement(base) } return base From b81c1839d1e05f4c799a6b5fe26e0b9476294722 Mon Sep 17 00:00:00 2001 From: Paul Merlin Date: Wed, 15 Jan 2020 18:02:41 +0100 Subject: [PATCH 15/39] Let @UnsupportedWithInstantExecution(iterationMatchers) work with Spock Signed-off-by: Paul Merlin --- ...portedWithInstantExecutionExtension.groovy | 25 ++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/subprojects/internal-integ-testing/src/main/groovy/org/gradle/integtests/fixtures/UnsupportedWithInstantExecutionExtension.groovy b/subprojects/internal-integ-testing/src/main/groovy/org/gradle/integtests/fixtures/UnsupportedWithInstantExecutionExtension.groovy index bf65c61d59ae..5d8806d7749b 100644 --- a/subprojects/internal-integ-testing/src/main/groovy/org/gradle/integtests/fixtures/UnsupportedWithInstantExecutionExtension.groovy +++ b/subprojects/internal-integ-testing/src/main/groovy/org/gradle/integtests/fixtures/UnsupportedWithInstantExecutionExtension.groovy @@ -18,6 +18,8 @@ package org.gradle.integtests.fixtures import org.gradle.integtests.fixtures.executer.GradleContextualExecuter import org.spockframework.runtime.extension.AbstractAnnotationDrivenExtension +import org.spockframework.runtime.extension.IMethodInterceptor +import org.spockframework.runtime.extension.IMethodInvocation import org.spockframework.runtime.model.FeatureInfo import static org.gradle.integtests.fixtures.ToBeFixedForInstantExecutionExtension.isEnabledBottomSpec @@ -28,8 +30,10 @@ class UnsupportedWithInstantExecutionExtension extends AbstractAnnotationDrivenE @Override void visitFeatureAnnotation(UnsupportedWithInstantExecution annotation, FeatureInfo feature) { if (GradleContextualExecuter.isInstant()) { - if (isEnabledBottomSpec(annotation.bottomSpecs(), { feature.parent.bottomSpec.name == it })) { + if (isAllIterations(annotation.iterationMatchers()) && isEnabledBottomSpec(annotation.bottomSpecs(), { feature.parent.bottomSpec.name == it })) { feature.skipped = true + } else { + feature.iterationInterceptors.add(new IterationMatchingMethodInterceptor(annotation.iterationMatchers())) } } } @@ -41,4 +45,23 @@ class UnsupportedWithInstantExecutionExtension extends AbstractAnnotationDrivenE private static boolean isAllIterations(String[] iterationMatchers) { return iterationMatchers.length == 0 } + + private static class IterationMatchingMethodInterceptor implements IMethodInterceptor { + + private final String[] iterationMatchers + + IterationMatchingMethodInterceptor(String[] iterationMatchers) { + this.iterationMatchers = iterationMatchers + } + + @Override + void intercept(IMethodInvocation invocation) throws Throwable { + if (!iterationMatches(iterationMatchers, invocation.iteration.name)) { + invocation.proceed() + } else { + // This will show up in test reports, necessary because we can't mark the test as skipped + println("Skipping test @${UnsupportedWithInstantExecution.simpleName}") + } + } + } } From d18b39e5f1296be368f0a206a487cdcb3340154a Mon Sep 17 00:00:00 2001 From: Paul Merlin Date: Tue, 21 Jan 2020 14:28:23 +0100 Subject: [PATCH 16/39] AndroidPluginsSmokeTest with AGP >= 3.6 works with instant execution Signed-off-by: Paul Merlin --- .../org/gradle/smoketests/AndroidPluginsSmokeTest.groovy | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/subprojects/smoke-test/src/smokeTest/groovy/org/gradle/smoketests/AndroidPluginsSmokeTest.groovy b/subprojects/smoke-test/src/smokeTest/groovy/org/gradle/smoketests/AndroidPluginsSmokeTest.groovy index d990b945fb94..95a8a821b60b 100644 --- a/subprojects/smoke-test/src/smokeTest/groovy/org/gradle/smoketests/AndroidPluginsSmokeTest.groovy +++ b/subprojects/smoke-test/src/smokeTest/groovy/org/gradle/smoketests/AndroidPluginsSmokeTest.groovy @@ -16,7 +16,7 @@ package org.gradle.smoketests -import org.gradle.integtests.fixtures.ToBeFixedForInstantExecution +import org.gradle.integtests.fixtures.UnsupportedWithInstantExecution import org.gradle.integtests.fixtures.android.AndroidHome import org.gradle.testkit.runner.TaskOutcome import org.gradle.util.Requires @@ -42,7 +42,7 @@ class AndroidPluginsSmokeTest extends AbstractSmokeTest { } @Unroll - @ToBeFixedForInstantExecution + @UnsupportedWithInstantExecution(iterationMatchers = ".*agp=3\\.[45]\\..*") def "android library and application APK assembly (agp=#agpVersion)"() { given: From 44a8d687a50f0d66da1d9f58f16de07fb8ce4432 Mon Sep 17 00:00:00 2001 From: Paul Merlin Date: Tue, 21 Jan 2020 14:38:04 +0100 Subject: [PATCH 17/39] AndroidPluginsSmokeTest run in IDE mode instant execution supported on AGP >= 4.0 Signed-off-by: Paul Merlin --- .../smoketests/AndroidPluginsSmokeTest.groovy | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/subprojects/smoke-test/src/smokeTest/groovy/org/gradle/smoketests/AndroidPluginsSmokeTest.groovy b/subprojects/smoke-test/src/smokeTest/groovy/org/gradle/smoketests/AndroidPluginsSmokeTest.groovy index 95a8a821b60b..d6caf764468f 100644 --- a/subprojects/smoke-test/src/smokeTest/groovy/org/gradle/smoketests/AndroidPluginsSmokeTest.groovy +++ b/subprojects/smoke-test/src/smokeTest/groovy/org/gradle/smoketests/AndroidPluginsSmokeTest.groovy @@ -42,14 +42,19 @@ class AndroidPluginsSmokeTest extends AbstractSmokeTest { } @Unroll - @UnsupportedWithInstantExecution(iterationMatchers = ".*agp=3\\.[45]\\..*") - def "android library and application APK assembly (agp=#agpVersion)"() { + @UnsupportedWithInstantExecution(iterationMatchers = ".*agp=3\\..*") + def "android library and application APK assembly (agp=#agpVersion, ide=#ide)"( + String agpVersion, boolean ide + ) { given: def abiChange = androidLibraryAndApplicationBuild(agpVersion) and: - def runner = useAgpVersion(agpVersion, runner('assembleDebug')) + def runner = useAgpVersion(agpVersion, runner( + 'assembleDebug', + "-Pandroid.injected.invoked.from.ide=$ide" + )) when: 'first build' def result = runner.build() @@ -99,7 +104,10 @@ class AndroidPluginsSmokeTest extends AbstractSmokeTest { result.task(':app:assembleDebug').outcome == TaskOutcome.SUCCESS where: - agpVersion << TestedVersions.androidGradle + [agpVersion, ide] << [ + TestedVersions.androidGradle.toList(), + [false, true] + ].combinations() } /** From e750d6b3cbaae255d1cb2997d5896c75f65979fc Mon Sep 17 00:00:00 2001 From: Stefan Wolf Date: Tue, 21 Jan 2020 15:02:33 +0100 Subject: [PATCH 18/39] Take field annotation into account for conflicting ignore annotations When a field is annotated with `@Internal` and the getter is annotated with another ignore annotation or another input annotation, then the user should be warned about the conflict. #11805 --- .../IncrementalBuildIntegrationTest.groovy | 6 +++-- .../DefaultTypeAnnotationMetadataStore.java | 25 ++++++++----------- ...aultTypeAnnotationMetadataStoreTest.groovy | 24 ++++++++++++++++-- ...ractPluginValidationIntegrationSpec.groovy | 2 +- 4 files changed, 37 insertions(+), 20 deletions(-) diff --git a/subprojects/core/src/integTest/groovy/org/gradle/api/tasks/IncrementalBuildIntegrationTest.groovy b/subprojects/core/src/integTest/groovy/org/gradle/api/tasks/IncrementalBuildIntegrationTest.groovy index 60619bab242b..d10a7ad99df1 100644 --- a/subprojects/core/src/integTest/groovy/org/gradle/api/tasks/IncrementalBuildIntegrationTest.groovy +++ b/subprojects/core/src/integTest/groovy/org/gradle/api/tasks/IncrementalBuildIntegrationTest.groovy @@ -1392,7 +1392,6 @@ task generate(type: TransformerTask) { outputFile.text == 'second' } - @ToBeImplemented @Issue("https://github.com/gradle/gradle/issues/11805") def "Groovy property annotated as @Internal with differently annotated getter emits warning about conflicting annotations"() { def inputFile = file("input.txt") @@ -1425,21 +1424,24 @@ task generate(type: TransformerTask) { """ when: + executer.expectDeprecationWarning() run "custom" then: executedAndNotSkipped ":custom" + outputContains("Property 'classpath' annotated with @Internal should not be also annotated with @InputFiles, @Classpath. This behaviour has been deprecated and is scheduled to be removed in Gradle 7.0.") when: + executer.expectDeprecationWarning() run "custom" then: skipped ":custom" when: + executer.expectDeprecationWarning() inputFile.text = "changed" run "custom" then: - // FIXME This should execute instead of being skipped, or emit a warning skipped ":custom" } } diff --git a/subprojects/model-core/src/main/java/org/gradle/internal/reflect/annotations/impl/DefaultTypeAnnotationMetadataStore.java b/subprojects/model-core/src/main/java/org/gradle/internal/reflect/annotations/impl/DefaultTypeAnnotationMetadataStore.java index d784d477a897..fefb90fe7c1b 100644 --- a/subprojects/model-core/src/main/java/org/gradle/internal/reflect/annotations/impl/DefaultTypeAnnotationMetadataStore.java +++ b/subprojects/model-core/src/main/java/org/gradle/internal/reflect/annotations/impl/DefaultTypeAnnotationMetadataStore.java @@ -381,20 +381,6 @@ private void processMethodAnnotations(Method method, Map 1) { - annotations.keySet().stream() - .filter(ignoredMethodAnnotations::contains) - .findFirst() - .ifPresent(ignoredMethodAnnotation -> metadataBuilder.recordProblem( - String.format("getter '%s()' annotated with @%s should not be also annotated with %s", - method.getName(), - ignoredMethodAnnotation.getSimpleName(), - simpleAnnotationNames(annotations.keySet().stream() - .filter(annotationType -> !annotationType.equals(ignoredMethodAnnotation))) - ) - )); - } - for (Annotation annotation : annotations.values()) { metadataBuilder.declareAnnotation(annotation); } @@ -511,7 +497,16 @@ private ImmutableMap resolveAnnotations() { // If method should be ignored, then ignore all other annotations List declaredTypes = declaredAnnotations.get(TYPE); for (Annotation declaredType : declaredTypes) { - if (ignoredMethodAnnotations.contains(declaredType.annotationType())) { + Class ignoredMethodAnnotation = declaredType.annotationType(); + if (ignoredMethodAnnotations.contains(ignoredMethodAnnotation)) { + if (declaredAnnotations.values().size() > 1) { + recordProblem(String.format("annotated with @%s should not be also annotated with %s", + ignoredMethodAnnotation.getSimpleName(), + simpleAnnotationNames(declaredAnnotations.values().stream() + .>map(Annotation::annotationType) + .filter(annotationType -> !annotationType.equals(ignoredMethodAnnotation))) + )); + } return ImmutableMap.of(TYPE, declaredType); } } diff --git a/subprojects/model-core/src/test/groovy/org/gradle/internal/reflect/annotations/impl/DefaultTypeAnnotationMetadataStoreTest.groovy b/subprojects/model-core/src/test/groovy/org/gradle/internal/reflect/annotations/impl/DefaultTypeAnnotationMetadataStoreTest.groovy index c64e415993a8..196456976fb1 100644 --- a/subprojects/model-core/src/test/groovy/org/gradle/internal/reflect/annotations/impl/DefaultTypeAnnotationMetadataStoreTest.groovy +++ b/subprojects/model-core/src/test/groovy/org/gradle/internal/reflect/annotations/impl/DefaultTypeAnnotationMetadataStoreTest.groovy @@ -257,7 +257,7 @@ class DefaultTypeAnnotationMetadataStoreTest extends Specification { assertProperties TypeWithIgnoredPropertyWithOtherAnnotations, [ ignoredProperty: [(TYPE): Ignored] ], [ - "Property 'ignoredProperty' getter 'getIgnoredProperty()' annotated with @Ignored should not be also annotated with @Color." + "Property 'ignoredProperty' annotated with @Ignored should not be also annotated with @Color." ] } @@ -272,7 +272,7 @@ class DefaultTypeAnnotationMetadataStoreTest extends Specification { assertProperties TypeWithIgnoredPropertyWithMultipleIgnoreAnnotations, [ twiceIgnoredProperty: [(TYPE): Ignored] ], [ - "Property 'twiceIgnoredProperty' getter 'getTwiceIgnoredProperty()' annotated with @Ignored should not be also annotated with @Ignored2." + "Property 'twiceIgnoredProperty' annotated with @Ignored should not be also annotated with @Ignored2." ] } @@ -282,6 +282,26 @@ class DefaultTypeAnnotationMetadataStoreTest extends Specification { String getTwiceIgnoredProperty() } + def "warns when field is ignored but there is another annotation on the getter"() { + expect: + assertProperties TypeWithIgnoredFieldAndGetterInput, [ + ignoredByField: [(TYPE): Ignored] + ], [ + "Property 'ignoredByField' annotated with @Ignored should not be also annotated with @Small." + ] + } + + @SuppressWarnings("unused") + static class TypeWithIgnoredFieldAndGetterInput { + @Ignored + private String ignoredByField; + + @Small + String getIgnoredByField() { + return ignoredByField + } + } + def "superclass properties are present in subclass"() { expect: assertProperties TypeWithSuperclassProperties, [ diff --git a/subprojects/plugin-development/src/integTest/groovy/org/gradle/plugin/devel/tasks/AbstractPluginValidationIntegrationSpec.groovy b/subprojects/plugin-development/src/integTest/groovy/org/gradle/plugin/devel/tasks/AbstractPluginValidationIntegrationSpec.groovy index b559203b9423..c46a52063d14 100644 --- a/subprojects/plugin-development/src/integTest/groovy/org/gradle/plugin/devel/tasks/AbstractPluginValidationIntegrationSpec.groovy +++ b/subprojects/plugin-development/src/integTest/groovy/org/gradle/plugin/devel/tasks/AbstractPluginValidationIntegrationSpec.groovy @@ -763,7 +763,7 @@ abstract class AbstractPluginValidationIntegrationSpec extends AbstractIntegrati expect: assertValidationFailsWith( - "Type 'MyTask': property 'oldProperty' getter 'getOldProperty()' annotated with @ReplacedBy should not be also annotated with @Input.": WARNING, + "Type 'MyTask': property 'oldProperty' annotated with @ReplacedBy should not be also annotated with @Input.": WARNING, ) } From 80bb42fe570c92ac3984f2d007a5ce3facbf32d9 Mon Sep 17 00:00:00 2001 From: Paul Merlin Date: Wed, 22 Jan 2020 10:48:24 +0100 Subject: [PATCH 19/39] Extract BuildOperationTreeQueries from BuildOperationFixture in order for it to be usable without GradleExecuter Signed-off-by: Paul Merlin --- .../fixtures/BuildOperationTreeFixture.groovy | 145 +++++++++ .../fixtures/BuildOperationTreeQueries.groovy | 249 +++++++++++++++ .../fixtures/BuildOperationsFixture.groovy | 297 ++---------------- 3 files changed, 422 insertions(+), 269 deletions(-) create mode 100644 subprojects/internal-integ-testing/src/main/groovy/org/gradle/integtests/fixtures/BuildOperationTreeFixture.groovy create mode 100644 subprojects/internal-integ-testing/src/main/groovy/org/gradle/integtests/fixtures/BuildOperationTreeQueries.groovy diff --git a/subprojects/internal-integ-testing/src/main/groovy/org/gradle/integtests/fixtures/BuildOperationTreeFixture.groovy b/subprojects/internal-integ-testing/src/main/groovy/org/gradle/integtests/fixtures/BuildOperationTreeFixture.groovy new file mode 100644 index 000000000000..07feb884003e --- /dev/null +++ b/subprojects/internal-integ-testing/src/main/groovy/org/gradle/integtests/fixtures/BuildOperationTreeFixture.groovy @@ -0,0 +1,145 @@ +/* + * Copyright 2020 the original author or authors. + * + * 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.gradle.integtests.fixtures + +import org.gradle.api.specs.Spec +import org.gradle.api.specs.Specs +import org.gradle.internal.logging.events.StyledTextOutputEvent +import org.gradle.internal.operations.BuildOperationType +import org.gradle.internal.operations.BuildOperationTypes +import org.gradle.internal.operations.trace.BuildOperationRecord +import org.gradle.internal.operations.trace.BuildOperationTree + +import java.util.regex.Pattern + + +class BuildOperationTreeFixture extends BuildOperationTreeQueries { + + private final BuildOperationTree operations + + BuildOperationTreeFixture(BuildOperationTree operations) { + this.operations = operations + } + + @Override + @SuppressWarnings("GrUnnecessaryPublicModifier") + public > BuildOperationRecord root(Class type, Spec predicate = Specs.satisfyAll()) { + def detailsType = BuildOperationTypes.detailsType(type) + def roots = operations.roots.findAll { + it.detailsType && detailsType.isAssignableFrom(it.detailsType) && predicate.isSatisfiedBy(it) + } + assert roots.size() == 1 + return roots[0] + } + + @Override + @SuppressWarnings("GrUnnecessaryPublicModifier") + public > BuildOperationRecord first(Class type, Spec predicate = Specs.satisfyAll()) { + def detailsType = BuildOperationTypes.detailsType(type) + return operations.records.values().find { + it.detailsType && detailsType.isAssignableFrom(it.detailsType) && predicate.isSatisfiedBy(it) + } + } + + @Override + @SuppressWarnings("GrUnnecessaryPublicModifier") + public > boolean isType(BuildOperationRecord record, Class type) { + assert record.detailsType + def detailsType = BuildOperationTypes.detailsType(type) + detailsType.isAssignableFrom(record.detailsType) + } + + @Override + @SuppressWarnings("GrUnnecessaryPublicModifier") + public > List all(Class type, Spec predicate = Specs.satisfyAll()) { + def detailsType = BuildOperationTypes.detailsType(type) + return operations.records.values().findAll { + it.detailsType && detailsType.isAssignableFrom(it.detailsType) && predicate.isSatisfiedBy(it) + }.toList() + } + + @Override + BuildOperationRecord first(Pattern displayName) { + return operations.records.values().find { it.displayName ==~ displayName } + } + + @Override + List all(Pattern displayName) { + return operations.records.values().findAll { it.displayName ==~ displayName } + } + + @Override + BuildOperationRecord only(Pattern displayName) { + def records = all(displayName) + assert records.size() == 1: "Error matching pattern: $displayName" + return records.first() + } + + @Override + List parentsOf(BuildOperationRecord child) { + def parents = [] + def parentId = child.parentId + while (parentId != null) { + def parent = operations.records.get(parentId) + parents.add(0, parent) + parentId = parent.parentId + } + return parents + } + + @Override + void none(Pattern displayName) { + def records = all(displayName) + assert records.size() == 0 + } + + @Override + void debugTree( + Spec predicate = Specs.SATISFIES_ALL, + Spec progressPredicate = Specs.SATISFIES_ALL + ) { + operations.roots.each { debugOpTree(it, 0, predicate, progressPredicate) } + } + + private void debugOpTree( + BuildOperationRecord op, + int level, + Spec predicate, + Spec progressPredicate + ) { + if (predicate.isSatisfiedBy(op)) { + println "${' ' * level}(${op.displayName}, id: $op.id${op.detailsType ? ", details type: ${simpleClassName(op.detailsType)}" : ''})${op.details ? " $op.details" : ''}" + if (progressPredicate.isSatisfiedBy(op)) { + op.progress.each { p -> + def repr = p.hasDetailsOfType(StyledTextOutputEvent) ? p.details.spans*.text.join('') : "$p.detailsType.simpleName ${p.details?.toString() ?: ''}\n" + print "${' ' * (level + 1)} $repr" + } + } + op.children.each { debugOpTree(it, level + 1, predicate, progressPredicate) } + } + } + + private static String simpleClassName(Class detailsType) { + if (!detailsType) { + return null + } else { + // Class.simpleName returns "" for certain anonymous classes and unhelpful things like "Details" for our op interfaces + String clsName = detailsType.interfaces.length == 0 ? detailsType.name : detailsType.interfaces.first().name + clsName.substring(clsName.lastIndexOf('.') + 1) + } + } +} diff --git a/subprojects/internal-integ-testing/src/main/groovy/org/gradle/integtests/fixtures/BuildOperationTreeQueries.groovy b/subprojects/internal-integ-testing/src/main/groovy/org/gradle/integtests/fixtures/BuildOperationTreeQueries.groovy new file mode 100644 index 000000000000..6d3af66a14a2 --- /dev/null +++ b/subprojects/internal-integ-testing/src/main/groovy/org/gradle/integtests/fixtures/BuildOperationTreeQueries.groovy @@ -0,0 +1,249 @@ +/* + * Copyright 2020 the original author or authors. + * + * 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.gradle.integtests.fixtures + +import org.gradle.api.Action +import org.gradle.api.specs.Spec +import org.gradle.api.specs.Specs +import org.gradle.internal.operations.BuildOperationType +import org.gradle.internal.operations.BuildOperationTypes +import org.gradle.internal.operations.trace.BuildOperationRecord + +import java.util.concurrent.ConcurrentLinkedQueue +import java.util.regex.Pattern + +abstract class BuildOperationTreeQueries { + + abstract > BuildOperationRecord root(Class type, Spec predicate = Specs.satisfyAll()) + + abstract > BuildOperationRecord first(Class type, Spec predicate = Specs.satisfyAll()) + + abstract > boolean isType(BuildOperationRecord record, Class type) + + abstract > List all(Class type, Spec predicate = Specs.satisfyAll()) + + @SuppressWarnings("GrUnnecessaryPublicModifier") + public > void none(Class type, Spec predicate = Specs.satisfyAll()) { + assert all(type, predicate).isEmpty() + } + + @SuppressWarnings("GrUnnecessaryPublicModifier") + public > BuildOperationRecord only(Class type, Spec predicate = Specs.satisfyAll()) { + def records = all(type, predicate) + assert records.size() == 1 + return records.first() + } + + BuildOperationRecord first(String displayName) { + first(Pattern.compile(Pattern.quote(displayName))) + } + + abstract BuildOperationRecord first(Pattern displayName) + + List all(String displayName) { + return all(Pattern.compile(Pattern.quote(displayName))) + } + + abstract List all(Pattern displayName) + + BuildOperationRecord only(String displayName) { + return only(Pattern.compile(Pattern.quote(displayName))) + } + + abstract BuildOperationRecord only(Pattern displayName) + + abstract List parentsOf(BuildOperationRecord child) + + void none(String displayName) { + none(Pattern.compile(Pattern.quote(displayName))) + } + + abstract void none(Pattern displayName) + + Map result(String displayName) { + first(displayName).result + } + + String failure(String displayName) { + first(displayName).failure + } + + boolean hasOperation(String displayName) { + first(displayName) != null + } + + @SuppressWarnings("GrUnnecessaryPublicModifier") + public > boolean hasOperation(Class type) { + first(type) != null + } + + @SuppressWarnings(["GrMethodMayBeStatic", "GrUnnecessaryPublicModifier"]) + public > List search(BuildOperationRecord parent, Class type, Spec predicate = Specs.SATISFIES_ALL) { + def detailsType = BuildOperationTypes.detailsType(type) + Spec typeSpec = { + it.detailsType && detailsType.isAssignableFrom(it.detailsType) + } + search(parent, Specs.intersect(typeSpec, predicate)) + } + + @SuppressWarnings(["GrMethodMayBeStatic", "GrUnnecessaryPublicModifier"]) + public > List children(BuildOperationRecord parent, Class type, Spec predicate = Specs.SATISFIES_ALL) { + Spec parentSpec = { + it.parentId == parent.id + } + return search(parent, type, Specs.intersect(parentSpec, predicate)) + } + + @SuppressWarnings("GrMethodMayBeStatic") + List search(BuildOperationRecord parent, Spec predicate = Specs.SATISFIES_ALL) { + def matches = [] + walk(parent) { + if (predicate.isSatisfiedBy(it)) { + matches << it + } + } + matches + } + + @SuppressWarnings("GrMethodMayBeStatic") + void walk(BuildOperationRecord parent, Action action) { + def search = new ConcurrentLinkedQueue(parent.children) + + def operation = search.poll() + while (operation != null) { + action.execute(operation) + search.addAll(operation.children) + operation = search.poll() + } + } + + void orderedSerialSiblings(BuildOperationRecord... expectedOrder) { + def expectedOrderList = expectedOrder.toList() + assert expectedOrder*.parentId.unique().size() == 1 + def startTimeOrdered = expectedOrderList.sort(false) { it.startTime } + assert expectedOrderList == startTimeOrdered + def endTimeOrdered = expectedOrderList.sort(false) { it.endTime } + assert endTimeOrdered == startTimeOrdered + } + + + private static class TimePoint implements Comparable { + private final boolean end + private final long time + private final BuildOperationRecord operation + + TimePoint(BuildOperationRecord operation, long time) { + this(operation, time, false) + } + + TimePoint(BuildOperationRecord operation, long time, boolean end) { + this.operation = operation + this.time = time + this.end = end + } + + @Override + int compareTo(TimePoint o) { + if (o.time > time) { + return -1 + } else if (o.time < time) { + return 1 + } else { + if (end && o.end) { + return 0 + } else if (end) { + return -1 + } else { + return 1 + } + } + } + + @Override + String toString() { + if (end) { + time + "E" + } else { + time + "S" + } + } + } + + /** + * Asserts that no more than maximumConcurrentOperations of the given type of build operation are executing at the same time. + * + * @param type type of build operation + * @param maximumConcurrentOperations maximum concurrent operations allowed + * @param concurrencyExpected whether or not to expect _any_ concurrency + */ + void assertConcurrentOperationsDoNotExceed(Class type, int maximumConcurrentOperations, boolean concurrencyExpected = false) { + int maxConcurrency = getMaximumConcurrentOperations(type) + assert maxConcurrency <= maximumConcurrentOperations + if (concurrencyExpected) { + assert maxConcurrency > 1: "No operations were executed concurrently" + } + } + + void assertConcurrentOperationsExecuted(Class type) { + assert getMaximumConcurrentOperations(type) > 1: "No operations were executed concurrently" + } + + int getMaximumConcurrentOperations(Class type) { + def highWaterPoint = 0 + def allOperations = all(type) + + List points = [] + + allOperations.each { + points.add(new TimePoint(it, it.startTime)) + points.add(new TimePoint(it, it.endTime, true)) + } + + def concurrentOperations = [] + points.sort().each { + if (it.end) { + concurrentOperations.remove(it.operation) + } else { + if ((it.operation.endTime - it.operation.startTime) > 0) { + concurrentOperations.add(it.operation) + } + } + if (concurrentOperations.size() > highWaterPoint) { + highWaterPoint = concurrentOperations.size() + } + } + return highWaterPoint + } + + /** + * Return a list of operations (possibly empty) that executed concurrently with the given operation. + */ + List getOperationsConcurrentWith(Class type, BuildOperationRecord operation) { + def concurrentOperations = [] + all(type).each { candidate -> + if (candidate != operation && candidate.startTime < operation.endTime && candidate.endTime > operation.startTime) { + concurrentOperations << candidate + } + } + return concurrentOperations + } + + abstract void debugTree( + Spec predicate = Specs.SATISFIES_ALL, + Spec progressPredicate = Specs.SATISFIES_ALL + ) +} diff --git a/subprojects/internal-integ-testing/src/main/groovy/org/gradle/integtests/fixtures/BuildOperationsFixture.groovy b/subprojects/internal-integ-testing/src/main/groovy/org/gradle/integtests/fixtures/BuildOperationsFixture.groovy index 298924e588e2..fbf1997cb918 100644 --- a/subprojects/internal-integ-testing/src/main/groovy/org/gradle/integtests/fixtures/BuildOperationsFixture.groovy +++ b/subprojects/internal-integ-testing/src/main/groovy/org/gradle/integtests/fixtures/BuildOperationsFixture.groovy @@ -16,327 +16,86 @@ package org.gradle.integtests.fixtures -import org.gradle.api.Action + import org.gradle.api.specs.Spec import org.gradle.api.specs.Specs import org.gradle.integtests.fixtures.executer.GradleExecuter -import org.gradle.internal.logging.events.StyledTextOutputEvent import org.gradle.internal.operations.BuildOperationType -import org.gradle.internal.operations.BuildOperationTypes import org.gradle.internal.operations.trace.BuildOperationRecord import org.gradle.internal.operations.trace.BuildOperationTrace -import org.gradle.internal.operations.trace.BuildOperationTree import org.gradle.test.fixtures.file.TestDirectoryProvider -import java.util.concurrent.ConcurrentLinkedQueue import java.util.regex.Pattern -class BuildOperationsFixture { - - private final String path +class BuildOperationsFixture extends BuildOperationTreeQueries { - private BuildOperationTree operations + private BuildOperationTreeFixture tree BuildOperationsFixture(GradleExecuter executer, TestDirectoryProvider projectDir) { - this.path = projectDir.testDirectory.file("operations").absolutePath + String path = projectDir.testDirectory.file("operations").absolutePath executer.beforeExecute { executer.withArgument("-D$BuildOperationTrace.SYSPROP=$path") } executer.afterExecute { - operations = BuildOperationTrace.read(path) + tree = new BuildOperationTreeFixture(BuildOperationTrace.read(path)) } } + @Override @SuppressWarnings("GrUnnecessaryPublicModifier") public > BuildOperationRecord root(Class type, Spec predicate = Specs.satisfyAll()) { - def detailsType = BuildOperationTypes.detailsType(type) - def roots = operations.roots.findAll { - it.detailsType && detailsType.isAssignableFrom(it.detailsType) && predicate.isSatisfiedBy(it) - } - assert roots.size() == 1 - return roots[0] + return tree.root(type, predicate) } + @Override @SuppressWarnings("GrUnnecessaryPublicModifier") public > BuildOperationRecord first(Class type, Spec predicate = Specs.satisfyAll()) { - def detailsType = BuildOperationTypes.detailsType(type) - operations.records.values().find { - it.detailsType && detailsType.isAssignableFrom(it.detailsType) && predicate.isSatisfiedBy(it) - } - } - - static > boolean isType(BuildOperationRecord record, Class type) { - assert record.detailsType - def detailsType = BuildOperationTypes.detailsType(type) - detailsType.isAssignableFrom(record.detailsType) - } - - @SuppressWarnings("GrUnnecessaryPublicModifier") - public > List all(Class type, Spec predicate = Specs.satisfyAll()) { - def detailsType = BuildOperationTypes.detailsType(type) - operations.records.values().findAll { - it.detailsType && detailsType.isAssignableFrom(it.detailsType) && predicate.isSatisfiedBy(it) - }.toList() + return tree.first(type, predicate) } + @Override @SuppressWarnings("GrUnnecessaryPublicModifier") - public > void none(Class type, Spec predicate = Specs.satisfyAll()) { - assert all(type, predicate).isEmpty() + public > boolean isType(BuildOperationRecord record, Class type) { + return tree.isType(record, type) } + @Override @SuppressWarnings("GrUnnecessaryPublicModifier") - public > BuildOperationRecord only(Class type, Spec predicate = Specs.satisfyAll()) { - def records = all(type, predicate) - assert records.size() == 1 - records.first() - } - - BuildOperationRecord first(String displayName) { - first(Pattern.compile(Pattern.quote(displayName))) + public > List all(Class type, Spec predicate = Specs.satisfyAll()) { + return tree.all(type, predicate) } + @Override BuildOperationRecord first(Pattern displayName) { - operations.records.values().find { it.displayName ==~ displayName } - } - - List all(String displayName) { - all(Pattern.compile(Pattern.quote(displayName))) + return tree.first(displayName) } + @Override List all(Pattern displayName) { - operations.records.values().findAll { it.displayName ==~ displayName } - } - - BuildOperationRecord only(String displayName) { - only(Pattern.compile(Pattern.quote(displayName))) - } - - List parentsOf(BuildOperationRecord child) { - def parents = [] - def parentId = child.parentId - while (parentId != null) { - def parent = operations.records.get(parentId) - parents.add(0, parent) - parentId = parent.parentId - } - parents + return tree.all(displayName) } + @Override BuildOperationRecord only(Pattern displayName) { - def records = all(displayName) - assert records.size() == 1: "Error matching pattern: $displayName" - records.first() + return tree.only(displayName) } - void none(String displayName) { - none(Pattern.compile(Pattern.quote(displayName))) + @Override + List parentsOf(BuildOperationRecord child) { + return tree.parentsOf(child) } + @Override void none(Pattern displayName) { - def records = all(displayName) - assert records.size() == 0 - } - - Map result(String displayName) { - first(displayName).result - } - - String failure(String displayName) { - first(displayName).failure - } - - boolean hasOperation(String displayName) { - first(displayName) != null - } - - @SuppressWarnings("GrUnnecessaryPublicModifier") - public > boolean hasOperation(Class type) { - first(type) != null - } - - @SuppressWarnings(["GrMethodMayBeStatic", "GrUnnecessaryPublicModifier"]) - public > List search(BuildOperationRecord parent, Class type, Spec predicate = Specs.SATISFIES_ALL) { - def detailsType = BuildOperationTypes.detailsType(type) - Spec typeSpec = { - it.detailsType && detailsType.isAssignableFrom(it.detailsType) - } - search(parent, Specs.intersect(typeSpec, predicate)) - } - - @SuppressWarnings(["GrMethodMayBeStatic", "GrUnnecessaryPublicModifier"]) - public > List children(BuildOperationRecord parent, Class type, Spec predicate = Specs.SATISFIES_ALL) { - Spec parentSpec = { - it.parentId == parent.id - } - return search(parent, type, Specs.intersect(parentSpec, predicate)) - } - - @SuppressWarnings("GrMethodMayBeStatic") - List search(BuildOperationRecord parent, Spec predicate = Specs.SATISFIES_ALL) { - def matches = [] - walk(parent) { - if (predicate.isSatisfiedBy(it)) { - matches << it - } - } - matches - } - - @SuppressWarnings("GrMethodMayBeStatic") - void walk(BuildOperationRecord parent, Action action) { - def search = new ConcurrentLinkedQueue(parent.children) - - def operation = search.poll() - while (operation != null) { - action.execute(operation) - search.addAll(operation.children) - operation = search.poll() - } - } - - void orderedSerialSiblings(BuildOperationRecord... expectedOrder) { - def expectedOrderList = expectedOrder.toList() - assert expectedOrder*.parentId.unique().size() == 1 - def startTimeOrdered = expectedOrderList.sort(false) { it.startTime } - assert expectedOrderList == startTimeOrdered - def endTimeOrdered = expectedOrderList.sort(false) { it.endTime } - assert endTimeOrdered == startTimeOrdered - } - - static class TimePoint implements Comparable { - private final boolean end - private final long time - private final BuildOperationRecord operation - - TimePoint(BuildOperationRecord operation, long time) { - this(operation, time, false) - } - - TimePoint(BuildOperationRecord operation, long time, boolean end) { - this.operation = operation - this.time = time - this.end = end - } - - @Override - int compareTo(TimePoint o) { - if (o.time > time) { - return -1 - } else if (o.time < time) { - return 1 - } else { - if (end && o.end) { - return 0 - } else if (end) { - return -1 - } else { - return 1 - } - } - } - - @Override - String toString() { - if (end) { - time + "E" - } else { - time + "S" - } - } - } - - /** - * Asserts that no more than maximumConcurrentOperations of the given type of build operation are executing at the same time. - * - * @param type type of build operation - * @param maximumConcurrentOperations maximum concurrent operations allowed - * @param concurrencyExpected whether or not to expect _any_ concurrency - */ - void assertConcurrentOperationsDoNotExceed(Class type, int maximumConcurrentOperations, boolean concurrencyExpected = false) { - int maxConcurrency = getMaximumConcurrentOperations(type) - assert maxConcurrency <= maximumConcurrentOperations - if (concurrencyExpected) { - assert maxConcurrency > 1: "No operations were executed concurrently" - } - } - - void assertConcurrentOperationsExecuted(Class type) { - assert getMaximumConcurrentOperations(type) > 1: "No operations were executed concurrently" - } - - int getMaximumConcurrentOperations(Class type) { - def highWaterPoint = 0 - def allOperations = all(type) - - List points = [] - - allOperations.each { - points.add(new TimePoint(it, it.startTime)) - points.add(new TimePoint(it, it.endTime, true)) - } - - def concurrentOperations = [] - points.sort().each { - if (it.end) { - concurrentOperations.remove(it.operation) - } else { - if ((it.operation.endTime - it.operation.startTime) > 0) { - concurrentOperations.add(it.operation) - } - } - if (concurrentOperations.size() > highWaterPoint) { - highWaterPoint = concurrentOperations.size() - } - } - return highWaterPoint - } - - /** - * Return a list of operations (possibly empty) that executed concurrently with the given operation. - */ - List getOperationsConcurrentWith(Class type, BuildOperationRecord operation) { - def concurrentOperations = [] - all(type).each { candidate -> - if (candidate != operation && candidate.startTime < operation.endTime && candidate.endTime > operation.startTime) { - concurrentOperations << candidate - } - } - return concurrentOperations + tree.none(displayName) } + @Override void debugTree( Spec predicate = Specs.SATISFIES_ALL, Spec progressPredicate = Specs.SATISFIES_ALL ) { - operations.roots.each { debugOpTree(it, 0, predicate, progressPredicate) } - } - - private void debugOpTree( - BuildOperationRecord op, - int level, - Spec predicate, - Spec progressPredicate - ) { - if (predicate.isSatisfiedBy(op)) { - println "${' ' * level}(${op.displayName}, id: $op.id${op.detailsType ? ", details type: ${simpleClassName(op.detailsType)}" : ''})${op.details ? " $op.details" : ''}" - if (progressPredicate.isSatisfiedBy(op)) { - op.progress.each { p -> - def repr = p.hasDetailsOfType(StyledTextOutputEvent) ? p.details.spans*.text.join('') : "$p.detailsType.simpleName ${p.details?.toString() ?: ''}\n" - print "${' ' * (level + 1)} $repr" - } - } - op.children.each { debugOpTree(it, level + 1, predicate, progressPredicate) } - } - } - - private static String simpleClassName(Class detailsType) { - if (!detailsType) { - return null - } else { - // Class.simpleName returns "" for certain anonymous classes and unhelpful things like "Details" for our op interfaces - String clsName = detailsType.interfaces.length == 0 ? detailsType.name : detailsType.interfaces.first().name - clsName.substring(clsName.lastIndexOf('.') + 1) - } + tree.debugTree(predicate, progressPredicate) } } From b5aef713e5e4963bddb40097850230de1023de4b Mon Sep 17 00:00:00 2001 From: Paul Merlin Date: Wed, 22 Jan 2020 12:00:42 +0100 Subject: [PATCH 20/39] Extract InstantExecutionBuildOperationsFixture in :internalIntegTesting can't use `testFixtures` because of https://github.com/gradle/gradle/issues/11501 Signed-off-by: Paul Merlin --- .../AbstractInstantExecutionIntegrationTest.groovy | 4 +++- .../InstantExecutionJavaIntegrationTest.groovy | 5 +++-- .../InstantExecutionBuildOperationsFixture.groovy | 14 ++++++-------- 3 files changed, 12 insertions(+), 11 deletions(-) rename subprojects/{instant-execution/src/integTest/groovy/org/gradle => internal-integ-testing/src/main/groovy/org/gradle/integtests/fixtures}/instantexecution/InstantExecutionBuildOperationsFixture.groovy (75%) diff --git a/subprojects/instant-execution/src/integTest/groovy/org/gradle/instantexecution/AbstractInstantExecutionIntegrationTest.groovy b/subprojects/instant-execution/src/integTest/groovy/org/gradle/instantexecution/AbstractInstantExecutionIntegrationTest.groovy index 13ee77b3d0be..01e3daaa0542 100644 --- a/subprojects/instant-execution/src/integTest/groovy/org/gradle/instantexecution/AbstractInstantExecutionIntegrationTest.groovy +++ b/subprojects/instant-execution/src/integTest/groovy/org/gradle/instantexecution/AbstractInstantExecutionIntegrationTest.groovy @@ -17,7 +17,9 @@ package org.gradle.instantexecution import org.gradle.integtests.fixtures.AbstractIntegrationSpec +import org.gradle.integtests.fixtures.BuildOperationsFixture import org.gradle.integtests.fixtures.DefaultTestExecutionResult +import org.gradle.integtests.fixtures.instantexecution.InstantExecutionBuildOperationsFixture import org.intellij.lang.annotations.Language @@ -38,7 +40,7 @@ class AbstractInstantExecutionIntegrationTest extends AbstractIntegrationSpec { public static final String INSTANT_EXECUTION_PROPERTY = "-Dorg.gradle.unsafe.instant-execution=true" protected InstantExecutionBuildOperationsFixture newInstantExecutionFixture() { - return new InstantExecutionBuildOperationsFixture(executer, temporaryFolder) + return new InstantExecutionBuildOperationsFixture(new BuildOperationsFixture(executer, temporaryFolder)) } protected void assertTestsExecuted(String testClass, String... testNames) { diff --git a/subprojects/instant-execution/src/integTest/groovy/org/gradle/instantexecution/InstantExecutionJavaIntegrationTest.groovy b/subprojects/instant-execution/src/integTest/groovy/org/gradle/instantexecution/InstantExecutionJavaIntegrationTest.groovy index db5ec06bd927..7860a43b5f01 100644 --- a/subprojects/instant-execution/src/integTest/groovy/org/gradle/instantexecution/InstantExecutionJavaIntegrationTest.groovy +++ b/subprojects/instant-execution/src/integTest/groovy/org/gradle/instantexecution/InstantExecutionJavaIntegrationTest.groovy @@ -16,6 +16,7 @@ package org.gradle.instantexecution +import org.gradle.integtests.fixtures.instantexecution.InstantExecutionBuildOperationsFixture import org.gradle.test.fixtures.archive.ZipTestFixture import org.junit.Test @@ -102,8 +103,8 @@ class InstantExecutionJavaIntegrationTest extends AbstractInstantExecutionIntegr """ buildFile << """ plugins { id 'java' } - - sourceSets.main.java.srcDir("src/common/java") + + sourceSets.main.java.srcDir("src/common/java") """ file("src/common/java/OtherThing.java") << """ class OtherThing { diff --git a/subprojects/instant-execution/src/integTest/groovy/org/gradle/instantexecution/InstantExecutionBuildOperationsFixture.groovy b/subprojects/internal-integ-testing/src/main/groovy/org/gradle/integtests/fixtures/instantexecution/InstantExecutionBuildOperationsFixture.groovy similarity index 75% rename from subprojects/instant-execution/src/integTest/groovy/org/gradle/instantexecution/InstantExecutionBuildOperationsFixture.groovy rename to subprojects/internal-integ-testing/src/main/groovy/org/gradle/integtests/fixtures/instantexecution/InstantExecutionBuildOperationsFixture.groovy index e90841416ea2..93859f9bed5a 100644 --- a/subprojects/instant-execution/src/integTest/groovy/org/gradle/instantexecution/InstantExecutionBuildOperationsFixture.groovy +++ b/subprojects/internal-integ-testing/src/main/groovy/org/gradle/integtests/fixtures/instantexecution/InstantExecutionBuildOperationsFixture.groovy @@ -1,5 +1,5 @@ /* - * Copyright 2019 the original author or authors. + * Copyright 2020 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,12 +14,10 @@ * limitations under the License. */ -package org.gradle.instantexecution +package org.gradle.integtests.fixtures.instantexecution -import org.gradle.integtests.fixtures.BuildOperationsFixture -import org.gradle.integtests.fixtures.executer.GradleExecuter +import org.gradle.integtests.fixtures.BuildOperationTreeQueries import org.gradle.internal.operations.trace.BuildOperationRecord -import org.gradle.test.fixtures.file.TestDirectoryProvider import static org.hamcrest.CoreMatchers.notNullValue import static org.hamcrest.CoreMatchers.nullValue @@ -28,10 +26,10 @@ import static org.junit.Assert.assertThat class InstantExecutionBuildOperationsFixture { - final BuildOperationsFixture operations + final BuildOperationTreeQueries operations - InstantExecutionBuildOperationsFixture(GradleExecuter executer, TestDirectoryProvider projectDir) { - operations = new BuildOperationsFixture(executer, projectDir) + InstantExecutionBuildOperationsFixture(BuildOperationTreeQueries operations) { + this.operations = operations } void assertStateLoaded() { From e664fea90776517790a445967a48d18e77869faf Mon Sep 17 00:00:00 2001 From: Paul Merlin Date: Wed, 22 Jan 2020 12:01:11 +0100 Subject: [PATCH 21/39] Let AndroidPluginsSmokeTest assert instant execution behavior Signed-off-by: Paul Merlin --- .../smoketests/AbstractSmokeTest.groovy | 26 ++++++++++++++++++- .../smoketests/AndroidPluginsSmokeTest.groovy | 12 +++++++++ 2 files changed, 37 insertions(+), 1 deletion(-) diff --git a/subprojects/smoke-test/src/smokeTest/groovy/org/gradle/smoketests/AbstractSmokeTest.groovy b/subprojects/smoke-test/src/smokeTest/groovy/org/gradle/smoketests/AbstractSmokeTest.groovy index a7d3ae14c2af..ebf9f03a6b60 100644 --- a/subprojects/smoke-test/src/smokeTest/groovy/org/gradle/smoketests/AbstractSmokeTest.groovy +++ b/subprojects/smoke-test/src/smokeTest/groovy/org/gradle/smoketests/AbstractSmokeTest.groovy @@ -18,12 +18,15 @@ package org.gradle.smoketests import org.apache.commons.io.FileUtils import org.gradle.cache.internal.DefaultGeneratedGradleJarCache +import org.gradle.integtests.fixtures.instantexecution.InstantExecutionBuildOperationsFixture +import org.gradle.integtests.fixtures.BuildOperationTreeFixture import org.gradle.integtests.fixtures.RepoScriptBlockUtil import org.gradle.integtests.fixtures.executer.GradleContextualExecuter import org.gradle.integtests.fixtures.executer.InstantExecutionGradleExecuter import org.gradle.integtests.fixtures.executer.IntegrationTestBuildContext import org.gradle.integtests.fixtures.versions.AndroidGradlePluginVersions import org.gradle.internal.featurelifecycle.LoggingDeprecatedFeatureHandler +import org.gradle.internal.operations.trace.BuildOperationTrace import org.gradle.test.fixtures.file.TestFile import org.gradle.testkit.runner.BuildResult import org.gradle.testkit.runner.GradleRunner @@ -188,10 +191,11 @@ abstract class AbstractSmokeTest extends Specification { ) } - private static List buildContextParameters() { + private List buildContextParameters() { List parameters = [] if (GradleContextualExecuter.isInstant()) { parameters += InstantExecutionGradleExecuter.INSTANT_EXECUTION_ARGS + parameters += ["-D${BuildOperationTrace.SYSPROP}=${buildOperationTracePath()}".toString()] } def generatedApiJarCacheDir = IntegrationTestBuildContext.INSTANCE.gradleGeneratedApiJarCacheDir if (generatedApiJarCacheDir == null) { @@ -217,6 +221,26 @@ abstract class AbstractSmokeTest extends Specification { ] } + protected void assertInstantExecutionStateStored() { + if (GradleContextualExecuter.isInstant()) { + newInstantExecutionBuildOperationsFixture().assertStateStored() + } + } + + protected void assertInstantExecutionStateLoaded() { + if (GradleContextualExecuter.isInstant()) { + newInstantExecutionBuildOperationsFixture().assertStateLoaded() + } + } + + private InstantExecutionBuildOperationsFixture newInstantExecutionBuildOperationsFixture() { + return new InstantExecutionBuildOperationsFixture(new BuildOperationTreeFixture(BuildOperationTrace.read(buildOperationTracePath()))) + } + + private String buildOperationTracePath() { + return file("operations").absolutePath + } + protected void useSample(String sampleDirectory) { def smokeTestDirectory = new File(this.getClass().getResource(sampleDirectory).toURI()) FileUtils.copyDirectory(smokeTestDirectory, testProjectDir.root) diff --git a/subprojects/smoke-test/src/smokeTest/groovy/org/gradle/smoketests/AndroidPluginsSmokeTest.groovy b/subprojects/smoke-test/src/smokeTest/groovy/org/gradle/smoketests/AndroidPluginsSmokeTest.groovy index d6caf764468f..a3aeb8fa2a7c 100644 --- a/subprojects/smoke-test/src/smokeTest/groovy/org/gradle/smoketests/AndroidPluginsSmokeTest.groovy +++ b/subprojects/smoke-test/src/smokeTest/groovy/org/gradle/smoketests/AndroidPluginsSmokeTest.groovy @@ -76,6 +76,9 @@ class AndroidPluginsSmokeTest extends AbstractSmokeTest { expectNoDeprecationWarnings(result) } + and: + assertInstantExecutionStateStored() + when: 'up-to-date build' result = runner.build() @@ -84,6 +87,9 @@ class AndroidPluginsSmokeTest extends AbstractSmokeTest { result.task(':library:assembleDebug').outcome == TaskOutcome.UP_TO_DATE result.task(':app:assembleDebug').outcome == TaskOutcome.UP_TO_DATE + and: + assertInstantExecutionStateLoaded() + when: 'abi change on library' abiChange.run() result = runner.build() @@ -94,6 +100,9 @@ class AndroidPluginsSmokeTest extends AbstractSmokeTest { result.task(':library:assembleDebug').outcome == TaskOutcome.SUCCESS result.task(':app:assembleDebug').outcome == TaskOutcome.SUCCESS + and: + assertInstantExecutionStateLoaded() + when: 'clean re-build' useAgpVersion(agpVersion, this.runner('clean')).build() result = runner.build() @@ -103,6 +112,9 @@ class AndroidPluginsSmokeTest extends AbstractSmokeTest { result.task(':library:assembleDebug').outcome == TaskOutcome.SUCCESS result.task(':app:assembleDebug').outcome == TaskOutcome.SUCCESS + and: + assertInstantExecutionStateLoaded() + where: [agpVersion, ide] << [ TestedVersions.androidGradle.toList(), From 8ed738c9163aec48459245798bd31e6e45b67c6c Mon Sep 17 00:00:00 2001 From: Paul Merlin Date: Wed, 22 Jan 2020 12:02:08 +0100 Subject: [PATCH 22/39] Remove now duplicated InstantExecutionAndroidIntegrationTest Signed-off-by: Paul Merlin --- ...tantExecutionAndroidIntegrationTest.groovy | 89 --------- .../builds/android-3.6-mini/app/build.gradle | 29 --- .../android-3.6-mini/app/proguard-rules.pro | 21 --- .../ExampleInstrumentedTest.java | 27 --- .../app/src/main/AndroidManifest.xml | 21 --- .../instantapplication/MainActivity.java | 14 -- .../drawable-v24/ic_launcher_foreground.xml | 34 ---- .../res/drawable/ic_launcher_background.xml | 170 ------------------ .../app/src/main/res/layout/activity_main.xml | 18 -- .../res/mipmap-anydpi-v26/ic_launcher.xml | 5 - .../mipmap-anydpi-v26/ic_launcher_round.xml | 5 - .../src/main/res/mipmap-hdpi/ic_launcher.png | Bin 2963 -> 0 bytes .../res/mipmap-hdpi/ic_launcher_round.png | Bin 4905 -> 0 bytes .../src/main/res/mipmap-mdpi/ic_launcher.png | Bin 2060 -> 0 bytes .../res/mipmap-mdpi/ic_launcher_round.png | Bin 2783 -> 0 bytes .../src/main/res/mipmap-xhdpi/ic_launcher.png | Bin 4490 -> 0 bytes .../res/mipmap-xhdpi/ic_launcher_round.png | Bin 6895 -> 0 bytes .../main/res/mipmap-xxhdpi/ic_launcher.png | Bin 6387 -> 0 bytes .../res/mipmap-xxhdpi/ic_launcher_round.png | Bin 10413 -> 0 bytes .../main/res/mipmap-xxxhdpi/ic_launcher.png | Bin 9128 -> 0 bytes .../res/mipmap-xxxhdpi/ic_launcher_round.png | Bin 15132 -> 0 bytes .../app/src/main/res/values/colors.xml | 6 - .../app/src/main/res/values/strings.xml | 3 - .../app/src/main/res/values/styles.xml | 11 -- .../instantapplication/ExampleUnitTest.java | 17 -- .../builds/android-3.6-mini/build.gradle | 27 --- .../builds/android-3.6-mini/gradle.properties | 19 -- .../builds/android-3.6-mini/settings.gradle | 3 - 28 files changed, 519 deletions(-) delete mode 100644 subprojects/instant-execution/src/integTest/groovy/org/gradle/instantexecution/InstantExecutionAndroidIntegrationTest.groovy delete mode 100644 subprojects/instant-execution/src/integTest/resources/org/gradle/instantexecution/builds/android-3.6-mini/app/build.gradle delete mode 100644 subprojects/instant-execution/src/integTest/resources/org/gradle/instantexecution/builds/android-3.6-mini/app/proguard-rules.pro delete mode 100644 subprojects/instant-execution/src/integTest/resources/org/gradle/instantexecution/builds/android-3.6-mini/app/src/androidTest/java/com/example/instantapplication/ExampleInstrumentedTest.java delete mode 100644 subprojects/instant-execution/src/integTest/resources/org/gradle/instantexecution/builds/android-3.6-mini/app/src/main/AndroidManifest.xml delete mode 100644 subprojects/instant-execution/src/integTest/resources/org/gradle/instantexecution/builds/android-3.6-mini/app/src/main/java/com/example/instantapplication/MainActivity.java delete mode 100644 subprojects/instant-execution/src/integTest/resources/org/gradle/instantexecution/builds/android-3.6-mini/app/src/main/res/drawable-v24/ic_launcher_foreground.xml delete mode 100644 subprojects/instant-execution/src/integTest/resources/org/gradle/instantexecution/builds/android-3.6-mini/app/src/main/res/drawable/ic_launcher_background.xml delete mode 100644 subprojects/instant-execution/src/integTest/resources/org/gradle/instantexecution/builds/android-3.6-mini/app/src/main/res/layout/activity_main.xml delete mode 100644 subprojects/instant-execution/src/integTest/resources/org/gradle/instantexecution/builds/android-3.6-mini/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml delete mode 100644 subprojects/instant-execution/src/integTest/resources/org/gradle/instantexecution/builds/android-3.6-mini/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml delete mode 100644 subprojects/instant-execution/src/integTest/resources/org/gradle/instantexecution/builds/android-3.6-mini/app/src/main/res/mipmap-hdpi/ic_launcher.png delete mode 100644 subprojects/instant-execution/src/integTest/resources/org/gradle/instantexecution/builds/android-3.6-mini/app/src/main/res/mipmap-hdpi/ic_launcher_round.png delete mode 100644 subprojects/instant-execution/src/integTest/resources/org/gradle/instantexecution/builds/android-3.6-mini/app/src/main/res/mipmap-mdpi/ic_launcher.png delete mode 100644 subprojects/instant-execution/src/integTest/resources/org/gradle/instantexecution/builds/android-3.6-mini/app/src/main/res/mipmap-mdpi/ic_launcher_round.png delete mode 100644 subprojects/instant-execution/src/integTest/resources/org/gradle/instantexecution/builds/android-3.6-mini/app/src/main/res/mipmap-xhdpi/ic_launcher.png delete mode 100644 subprojects/instant-execution/src/integTest/resources/org/gradle/instantexecution/builds/android-3.6-mini/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png delete mode 100644 subprojects/instant-execution/src/integTest/resources/org/gradle/instantexecution/builds/android-3.6-mini/app/src/main/res/mipmap-xxhdpi/ic_launcher.png delete mode 100644 subprojects/instant-execution/src/integTest/resources/org/gradle/instantexecution/builds/android-3.6-mini/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png delete mode 100644 subprojects/instant-execution/src/integTest/resources/org/gradle/instantexecution/builds/android-3.6-mini/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png delete mode 100644 subprojects/instant-execution/src/integTest/resources/org/gradle/instantexecution/builds/android-3.6-mini/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png delete mode 100644 subprojects/instant-execution/src/integTest/resources/org/gradle/instantexecution/builds/android-3.6-mini/app/src/main/res/values/colors.xml delete mode 100644 subprojects/instant-execution/src/integTest/resources/org/gradle/instantexecution/builds/android-3.6-mini/app/src/main/res/values/strings.xml delete mode 100644 subprojects/instant-execution/src/integTest/resources/org/gradle/instantexecution/builds/android-3.6-mini/app/src/main/res/values/styles.xml delete mode 100644 subprojects/instant-execution/src/integTest/resources/org/gradle/instantexecution/builds/android-3.6-mini/app/src/test/java/com/example/instantapplication/ExampleUnitTest.java delete mode 100644 subprojects/instant-execution/src/integTest/resources/org/gradle/instantexecution/builds/android-3.6-mini/build.gradle delete mode 100644 subprojects/instant-execution/src/integTest/resources/org/gradle/instantexecution/builds/android-3.6-mini/gradle.properties delete mode 100644 subprojects/instant-execution/src/integTest/resources/org/gradle/instantexecution/builds/android-3.6-mini/settings.gradle diff --git a/subprojects/instant-execution/src/integTest/groovy/org/gradle/instantexecution/InstantExecutionAndroidIntegrationTest.groovy b/subprojects/instant-execution/src/integTest/groovy/org/gradle/instantexecution/InstantExecutionAndroidIntegrationTest.groovy deleted file mode 100644 index f07a35be3963..000000000000 --- a/subprojects/instant-execution/src/integTest/groovy/org/gradle/instantexecution/InstantExecutionAndroidIntegrationTest.groovy +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Copyright 2019 the original author or authors. - * - * 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.gradle.instantexecution - -import org.gradle.integtests.fixtures.TestResources -import org.gradle.test.fixtures.file.LeaksFileHandles -import org.junit.Rule -import spock.lang.Unroll - -@LeaksFileHandles("TODO: AGP (intentionally) does not get a ‘build finished’ event and so does not close some files") -class InstantExecutionAndroidIntegrationTest extends AbstractInstantExecutionAndroidIntegrationTest { - - @Rule - TestResources resources = new TestResources(temporaryFolder, "builds") - - def instantExecution - - def buildScript = file("android-3.6-mini").file("build.gradle") - - def setup() { - executer.noDeprecationChecks() - executer.withRepositoryMirrors() - - executer.beforeExecute { - inDirectory(buildScript.parentFile) - } - - instantExecution = newInstantExecutionFixture() - } - - @Unroll - def "android minimal build assembleDebug up-to-date (agp=#agpVersion, fromIde=#fromIde)"() { - - given: - usingAgpVersion(buildScript, agpVersion) - - when: - instantRun("assembleDebug", "-Pandroid.injected.invoked.from.ide=$fromIde") - - then: - instantExecution.assertStateStored() - - when: - instantRun("assembleDebug", "-Pandroid.injected.invoked.from.ide=$fromIde") - - then: - instantExecution.assertStateLoaded() - - where: - [agpVersion, fromIde] << [TESTED_AGP_VERSIONS, [false, true]].combinations() - } - - @Unroll - def "android minimal build clean assembleDebug (agp=#agpVersion, fromIde=#fromIde)"() { - - given: - usingAgpVersion(buildScript, agpVersion) - - when: - instantRun("assembleDebug", "-Pandroid.injected.invoked.from.ide=$fromIde") - - then: - instantExecution.assertStateStored() - - when: - run 'clean' - instantRun("assembleDebug", "-Pandroid.injected.invoked.from.ide=$fromIde") - - then: - instantExecution.assertStateLoaded() - - where: - [agpVersion, fromIde] << [TESTED_AGP_VERSIONS, [false, true]].combinations() - } -} diff --git a/subprojects/instant-execution/src/integTest/resources/org/gradle/instantexecution/builds/android-3.6-mini/app/build.gradle b/subprojects/instant-execution/src/integTest/resources/org/gradle/instantexecution/builds/android-3.6-mini/app/build.gradle deleted file mode 100644 index 49fdc4bcdcf2..000000000000 --- a/subprojects/instant-execution/src/integTest/resources/org/gradle/instantexecution/builds/android-3.6-mini/app/build.gradle +++ /dev/null @@ -1,29 +0,0 @@ -apply plugin: 'com.android.application' - -android { - compileSdkVersion 28 - buildToolsVersion "29.0.2" - defaultConfig { - applicationId "com.example.instantapplication" - minSdkVersion 26 - targetSdkVersion 28 - versionCode 1 - versionName "1.0" - testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" - } - buildTypes { - release { - minifyEnabled false - proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' - } - } -} - -dependencies { - implementation fileTree(dir: 'libs', include: ['*.jar']) - implementation 'androidx.appcompat:appcompat:1.0.2' - implementation 'androidx.constraintlayout:constraintlayout:1.1.3' - testImplementation 'junit:junit:4.12' - androidTestImplementation 'androidx.test.ext:junit:1.1.1' - androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' -} diff --git a/subprojects/instant-execution/src/integTest/resources/org/gradle/instantexecution/builds/android-3.6-mini/app/proguard-rules.pro b/subprojects/instant-execution/src/integTest/resources/org/gradle/instantexecution/builds/android-3.6-mini/app/proguard-rules.pro deleted file mode 100644 index f1b424510da5..000000000000 --- a/subprojects/instant-execution/src/integTest/resources/org/gradle/instantexecution/builds/android-3.6-mini/app/proguard-rules.pro +++ /dev/null @@ -1,21 +0,0 @@ -# Add project specific ProGuard rules here. -# You can control the set of applied configuration files using the -# proguardFiles setting in build.gradle. -# -# For more details, see -# http://developer.android.com/guide/developing/tools/proguard.html - -# If your project uses WebView with JS, uncomment the following -# and specify the fully qualified class name to the JavaScript interface -# class: -#-keepclassmembers class fqcn.of.javascript.interface.for.webview { -# public *; -#} - -# Uncomment this to preserve the line number information for -# debugging stack traces. -#-keepattributes SourceFile,LineNumberTable - -# If you keep the line number information, uncomment this to -# hide the original source file name. -#-renamesourcefileattribute SourceFile diff --git a/subprojects/instant-execution/src/integTest/resources/org/gradle/instantexecution/builds/android-3.6-mini/app/src/androidTest/java/com/example/instantapplication/ExampleInstrumentedTest.java b/subprojects/instant-execution/src/integTest/resources/org/gradle/instantexecution/builds/android-3.6-mini/app/src/androidTest/java/com/example/instantapplication/ExampleInstrumentedTest.java deleted file mode 100644 index 1c1af1fc3354..000000000000 --- a/subprojects/instant-execution/src/integTest/resources/org/gradle/instantexecution/builds/android-3.6-mini/app/src/androidTest/java/com/example/instantapplication/ExampleInstrumentedTest.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.example.instantapplication; - -import android.content.Context; - -import androidx.test.platform.app.InstrumentationRegistry; -import androidx.test.ext.junit.runners.AndroidJUnit4; - -import org.junit.Test; -import org.junit.runner.RunWith; - -import static org.junit.Assert.*; - -/** - * Instrumented test, which will execute on an Android device. - * - * @see Testing documentation - */ -@RunWith(AndroidJUnit4.class) -public class ExampleInstrumentedTest { - @Test - public void useAppContext() { - // Context of the app under test. - Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); - - assertEquals("com.example.instantapplication", appContext.getPackageName()); - } -} diff --git a/subprojects/instant-execution/src/integTest/resources/org/gradle/instantexecution/builds/android-3.6-mini/app/src/main/AndroidManifest.xml b/subprojects/instant-execution/src/integTest/resources/org/gradle/instantexecution/builds/android-3.6-mini/app/src/main/AndroidManifest.xml deleted file mode 100644 index 35aa31d8ed1d..000000000000 --- a/subprojects/instant-execution/src/integTest/resources/org/gradle/instantexecution/builds/android-3.6-mini/app/src/main/AndroidManifest.xml +++ /dev/null @@ -1,21 +0,0 @@ - - - - - - - - - - - - - - \ No newline at end of file diff --git a/subprojects/instant-execution/src/integTest/resources/org/gradle/instantexecution/builds/android-3.6-mini/app/src/main/java/com/example/instantapplication/MainActivity.java b/subprojects/instant-execution/src/integTest/resources/org/gradle/instantexecution/builds/android-3.6-mini/app/src/main/java/com/example/instantapplication/MainActivity.java deleted file mode 100644 index 8fe7761be80d..000000000000 --- a/subprojects/instant-execution/src/integTest/resources/org/gradle/instantexecution/builds/android-3.6-mini/app/src/main/java/com/example/instantapplication/MainActivity.java +++ /dev/null @@ -1,14 +0,0 @@ -package com.example.instantapplication; - -import androidx.appcompat.app.AppCompatActivity; - -import android.os.Bundle; - -public class MainActivity extends AppCompatActivity { - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setContentView(R.layout.activity_main); - } -} diff --git a/subprojects/instant-execution/src/integTest/resources/org/gradle/instantexecution/builds/android-3.6-mini/app/src/main/res/drawable-v24/ic_launcher_foreground.xml b/subprojects/instant-execution/src/integTest/resources/org/gradle/instantexecution/builds/android-3.6-mini/app/src/main/res/drawable-v24/ic_launcher_foreground.xml deleted file mode 100644 index 1f6bb290603d..000000000000 --- a/subprojects/instant-execution/src/integTest/resources/org/gradle/instantexecution/builds/android-3.6-mini/app/src/main/res/drawable-v24/ic_launcher_foreground.xml +++ /dev/null @@ -1,34 +0,0 @@ - - - - - - - - - - - diff --git a/subprojects/instant-execution/src/integTest/resources/org/gradle/instantexecution/builds/android-3.6-mini/app/src/main/res/drawable/ic_launcher_background.xml b/subprojects/instant-execution/src/integTest/resources/org/gradle/instantexecution/builds/android-3.6-mini/app/src/main/res/drawable/ic_launcher_background.xml deleted file mode 100644 index 0d025f9bf6b6..000000000000 --- a/subprojects/instant-execution/src/integTest/resources/org/gradle/instantexecution/builds/android-3.6-mini/app/src/main/res/drawable/ic_launcher_background.xml +++ /dev/null @@ -1,170 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/subprojects/instant-execution/src/integTest/resources/org/gradle/instantexecution/builds/android-3.6-mini/app/src/main/res/layout/activity_main.xml b/subprojects/instant-execution/src/integTest/resources/org/gradle/instantexecution/builds/android-3.6-mini/app/src/main/res/layout/activity_main.xml deleted file mode 100644 index 4fc244418b5f..000000000000 --- a/subprojects/instant-execution/src/integTest/resources/org/gradle/instantexecution/builds/android-3.6-mini/app/src/main/res/layout/activity_main.xml +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/subprojects/instant-execution/src/integTest/resources/org/gradle/instantexecution/builds/android-3.6-mini/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml b/subprojects/instant-execution/src/integTest/resources/org/gradle/instantexecution/builds/android-3.6-mini/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml deleted file mode 100644 index eca70cfe52ea..000000000000 --- a/subprojects/instant-execution/src/integTest/resources/org/gradle/instantexecution/builds/android-3.6-mini/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - - - \ No newline at end of file diff --git a/subprojects/instant-execution/src/integTest/resources/org/gradle/instantexecution/builds/android-3.6-mini/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml b/subprojects/instant-execution/src/integTest/resources/org/gradle/instantexecution/builds/android-3.6-mini/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml deleted file mode 100644 index eca70cfe52ea..000000000000 --- a/subprojects/instant-execution/src/integTest/resources/org/gradle/instantexecution/builds/android-3.6-mini/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - - - \ No newline at end of file diff --git a/subprojects/instant-execution/src/integTest/resources/org/gradle/instantexecution/builds/android-3.6-mini/app/src/main/res/mipmap-hdpi/ic_launcher.png b/subprojects/instant-execution/src/integTest/resources/org/gradle/instantexecution/builds/android-3.6-mini/app/src/main/res/mipmap-hdpi/ic_launcher.png deleted file mode 100644 index 898f3ed59ac9f3248734a00e5902736c9367d455..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2963 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 JPDHLkV1g@XpTGbB diff --git a/subprojects/instant-execution/src/integTest/resources/org/gradle/instantexecution/builds/android-3.6-mini/app/src/main/res/mipmap-hdpi/ic_launcher_round.png b/subprojects/instant-execution/src/integTest/resources/org/gradle/instantexecution/builds/android-3.6-mini/app/src/main/res/mipmap-hdpi/ic_launcher_round.png deleted file mode 100644 index dffca3601eba7bf5f409bdd520820e2eb5122c75..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4905 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 lV%Z2*hu);6rydA(}wUDXPCF_W1vnaRBK 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 diff --git a/subprojects/instant-execution/src/integTest/resources/org/gradle/instantexecution/builds/android-3.6-mini/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png b/subprojects/instant-execution/src/integTest/resources/org/gradle/instantexecution/builds/android-3.6-mini/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png deleted file mode 100644 index 14ed0af35023e4f1901cf03487b6c524257b8483..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6895 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 diff --git a/subprojects/instant-execution/src/integTest/resources/org/gradle/instantexecution/builds/android-3.6-mini/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/subprojects/instant-execution/src/integTest/resources/org/gradle/instantexecution/builds/android-3.6-mini/app/src/main/res/mipmap-xxhdpi/ic_launcher.png deleted file mode 100644 index b0907cac3bfd8fbfdc46e1108247f0a1055387ec..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6387 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 diff --git a/subprojects/instant-execution/src/integTest/resources/org/gradle/instantexecution/builds/android-3.6-mini/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png b/subprojects/instant-execution/src/integTest/resources/org/gradle/instantexecution/builds/android-3.6-mini/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png deleted file mode 100644 index d8ae03154975f397f8ed1b84f2d4bf9783ecfa26..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10413 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 XdJ+W}DiIkV00000NkvXXu0mjfKBlg6 diff --git a/subprojects/instant-execution/src/integTest/resources/org/gradle/instantexecution/builds/android-3.6-mini/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/subprojects/instant-execution/src/integTest/resources/org/gradle/instantexecution/builds/android-3.6-mini/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png deleted file mode 100644 index 2c18de9e66108411737e910f5c1972476f03ddbf..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9128 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 I20H400LcNok^lez diff --git a/subprojects/instant-execution/src/integTest/resources/org/gradle/instantexecution/builds/android-3.6-mini/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png b/subprojects/instant-execution/src/integTest/resources/org/gradle/instantexecution/builds/android-3.6-mini/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png deleted file mode 100644 index beed3cdd2c32af5114a7dc70b9ef5b698eb8797e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 15132 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 diff --git a/subprojects/instant-execution/src/integTest/resources/org/gradle/instantexecution/builds/android-3.6-mini/app/src/main/res/values/colors.xml b/subprojects/instant-execution/src/integTest/resources/org/gradle/instantexecution/builds/android-3.6-mini/app/src/main/res/values/colors.xml deleted file mode 100644 index 69b22338c651..000000000000 --- a/subprojects/instant-execution/src/integTest/resources/org/gradle/instantexecution/builds/android-3.6-mini/app/src/main/res/values/colors.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - #008577 - #00574B - #D81B60 - diff --git a/subprojects/instant-execution/src/integTest/resources/org/gradle/instantexecution/builds/android-3.6-mini/app/src/main/res/values/strings.xml b/subprojects/instant-execution/src/integTest/resources/org/gradle/instantexecution/builds/android-3.6-mini/app/src/main/res/values/strings.xml deleted file mode 100644 index 22f17c58dfa4..000000000000 --- a/subprojects/instant-execution/src/integTest/resources/org/gradle/instantexecution/builds/android-3.6-mini/app/src/main/res/values/strings.xml +++ /dev/null @@ -1,3 +0,0 @@ - - InstantApplication - diff --git a/subprojects/instant-execution/src/integTest/resources/org/gradle/instantexecution/builds/android-3.6-mini/app/src/main/res/values/styles.xml b/subprojects/instant-execution/src/integTest/resources/org/gradle/instantexecution/builds/android-3.6-mini/app/src/main/res/values/styles.xml deleted file mode 100644 index 5885930df6d1..000000000000 --- a/subprojects/instant-execution/src/integTest/resources/org/gradle/instantexecution/builds/android-3.6-mini/app/src/main/res/values/styles.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - diff --git a/subprojects/instant-execution/src/integTest/resources/org/gradle/instantexecution/builds/android-3.6-mini/app/src/test/java/com/example/instantapplication/ExampleUnitTest.java b/subprojects/instant-execution/src/integTest/resources/org/gradle/instantexecution/builds/android-3.6-mini/app/src/test/java/com/example/instantapplication/ExampleUnitTest.java deleted file mode 100644 index 469fbf0616e4..000000000000 --- a/subprojects/instant-execution/src/integTest/resources/org/gradle/instantexecution/builds/android-3.6-mini/app/src/test/java/com/example/instantapplication/ExampleUnitTest.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.example.instantapplication; - -import org.junit.Test; - -import static org.junit.Assert.*; - -/** - * Example local unit test, which will execute on the development machine (host). - * - * @see Testing documentation - */ -public class ExampleUnitTest { - @Test - public void addition_isCorrect() { - assertEquals(4, 2 + 2); - } -} \ No newline at end of file diff --git a/subprojects/instant-execution/src/integTest/resources/org/gradle/instantexecution/builds/android-3.6-mini/build.gradle b/subprojects/instant-execution/src/integTest/resources/org/gradle/instantexecution/builds/android-3.6-mini/build.gradle deleted file mode 100644 index ccb7b635afb4..000000000000 --- a/subprojects/instant-execution/src/integTest/resources/org/gradle/instantexecution/builds/android-3.6-mini/build.gradle +++ /dev/null @@ -1,27 +0,0 @@ -// Top-level build file where you can add configuration options common to all sub-projects/modules. - -buildscript { - repositories { - google() - jcenter() - } - dependencies { - // This version is a placeholder replaced by the integration test - // It denotes the Android Studio version used to generate that build - classpath 'com.android.tools.build:gradle:3.6.0-alpha06' - - // NOTE: Do not place your application dependencies here; they belong - // in the individual module build.gradle files - } -} - -allprojects { - repositories { - google() - jcenter() - } -} - -task clean(type: Delete) { - delete rootProject.buildDir -} diff --git a/subprojects/instant-execution/src/integTest/resources/org/gradle/instantexecution/builds/android-3.6-mini/gradle.properties b/subprojects/instant-execution/src/integTest/resources/org/gradle/instantexecution/builds/android-3.6-mini/gradle.properties deleted file mode 100644 index c73d2393ba88..000000000000 --- a/subprojects/instant-execution/src/integTest/resources/org/gradle/instantexecution/builds/android-3.6-mini/gradle.properties +++ /dev/null @@ -1,19 +0,0 @@ -# Project-wide Gradle settings. -# IDE (e.g. Android Studio) users: -# Gradle settings configured through the IDE *will override* -# any settings specified in this file. -# For more details on how to configure your build environment visit -# http://www.gradle.org/docs/current/userguide/build_environment.html -# Specifies the JVM arguments used for the daemon process. -# The setting is particularly useful for tweaking memory settings. -org.gradle.jvmargs=-Xmx1536m -# When configured, Gradle will run in incubating parallel mode. -# This option should only be used with decoupled projects. More details, visit -# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects -# org.gradle.parallel=true -# AndroidX package structure to make it clearer which packages are bundled with the -# Android operating system, and which are packaged with your app's APK -# https://developer.android.com/topic/libraries/support-library/androidx-rn -android.useAndroidX=true -# Automatically convert third-party libraries to use AndroidX -android.enableJetifier=true diff --git a/subprojects/instant-execution/src/integTest/resources/org/gradle/instantexecution/builds/android-3.6-mini/settings.gradle b/subprojects/instant-execution/src/integTest/resources/org/gradle/instantexecution/builds/android-3.6-mini/settings.gradle deleted file mode 100644 index df5cfc3c7f2a..000000000000 --- a/subprojects/instant-execution/src/integTest/resources/org/gradle/instantexecution/builds/android-3.6-mini/settings.gradle +++ /dev/null @@ -1,3 +0,0 @@ -rootProject.name = 'android-3.6-minimal' - -include ':app' From dabbe96c6bb0638911444e8f43f0bd876fa07c0b Mon Sep 17 00:00:00 2001 From: Paul Merlin Date: Wed, 22 Jan 2020 12:02:22 +0100 Subject: [PATCH 23/39] updateAgpVersions Signed-off-by: Paul Merlin --- gradle/dependency-management/agp-versions.properties | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gradle/dependency-management/agp-versions.properties b/gradle/dependency-management/agp-versions.properties index 4f236f90f05e..33ed22bbffe9 100644 --- a/gradle/dependency-management/agp-versions.properties +++ b/gradle/dependency-management/agp-versions.properties @@ -1,3 +1,3 @@ # Generated - Update by running `./gradlew updateAgpVersions` -latests=3.4.2,3.5.3,3.6.0-rc01,4.0.0-alpha08 -nightly=4.0.0-20200118155917+0100 +latests=3.4.2,3.5.3,3.6.0-rc01,4.0.0-alpha09 +nightly=4.0.0-20200121203636+0000 From 7eaf0714fc4ccbba757c2c29986185e76e401058 Mon Sep 17 00:00:00 2001 From: Paul Merlin Date: Wed, 22 Jan 2020 12:19:20 +0100 Subject: [PATCH 24/39] Refine Santa Tracker smoke tests Signed-off-by: Paul Merlin --- ...bstractAndroidSantaTrackerSmokeTest.groovy | 7 +++---- ...oidSantaTrackerJavaCachingSmokeTest.groovy | 2 ++ ...dSantaTrackerKotlinCachingSmokeTest.groovy | 2 ++ .../AndroidSantaTrackerSmokeTest.groovy | 20 +++++++++++++++++-- 4 files changed, 25 insertions(+), 6 deletions(-) diff --git a/subprojects/smoke-test/src/smokeTest/groovy/org/gradle/smoketests/AbstractAndroidSantaTrackerSmokeTest.groovy b/subprojects/smoke-test/src/smokeTest/groovy/org/gradle/smoketests/AbstractAndroidSantaTrackerSmokeTest.groovy index 95ef70fc037a..838d81bbffe2 100644 --- a/subprojects/smoke-test/src/smokeTest/groovy/org/gradle/smoketests/AbstractAndroidSantaTrackerSmokeTest.groovy +++ b/subprojects/smoke-test/src/smokeTest/groovy/org/gradle/smoketests/AbstractAndroidSantaTrackerSmokeTest.groovy @@ -17,7 +17,6 @@ package org.gradle.smoketests import org.gradle.integtests.fixtures.daemon.DaemonLogsAnalyzer -import org.gradle.integtests.fixtures.versions.AndroidGradlePluginVersions import org.gradle.internal.scan.config.fixtures.GradleEnterprisePluginSettingsFixture import org.gradle.test.fixtures.file.TestFile import org.gradle.test.fixtures.file.TestNameTestDirectoryProvider @@ -53,13 +52,13 @@ class AbstractAndroidSantaTrackerSmokeTest extends AbstractSmokeTest { } } - protected BuildResult buildLocation(File projectDir, String agpVersion = null) { + protected BuildResult buildLocation(File projectDir, String agpVersion) { def runner = runner("assembleDebug") .withProjectDir(projectDir) .withTestKitDir(homeDir) .forwardOutput() - if (agpVersion != null && AndroidGradlePluginVersions.isAgpNightly(agpVersion)) { - def init = AndroidGradlePluginVersions.createAgpNightlyRepositoryInitScript() + if (AGP_VERSIONS.isAgpNightly(agpVersion)) { + def init = AGP_VERSIONS.createAgpNightlyRepositoryInitScript() runner.withArguments([runner.arguments, ['-I', init.canonicalPath]].flatten()) } runner.build() diff --git a/subprojects/smoke-test/src/smokeTest/groovy/org/gradle/smoketests/AndroidSantaTrackerJavaCachingSmokeTest.groovy b/subprojects/smoke-test/src/smokeTest/groovy/org/gradle/smoketests/AndroidSantaTrackerJavaCachingSmokeTest.groovy index 803d3b0a2c29..05b0f998e093 100644 --- a/subprojects/smoke-test/src/smokeTest/groovy/org/gradle/smoketests/AndroidSantaTrackerJavaCachingSmokeTest.groovy +++ b/subprojects/smoke-test/src/smokeTest/groovy/org/gradle/smoketests/AndroidSantaTrackerJavaCachingSmokeTest.groovy @@ -43,6 +43,8 @@ class AndroidSantaTrackerJavaCachingSmokeTest extends AbstractAndroidSantaTracke when: buildLocation(originalDir, agpVersion) + + and: BuildResult relocatedResult = buildLocation(relocatedDir, agpVersion) then: diff --git a/subprojects/smoke-test/src/smokeTest/groovy/org/gradle/smoketests/AndroidSantaTrackerKotlinCachingSmokeTest.groovy b/subprojects/smoke-test/src/smokeTest/groovy/org/gradle/smoketests/AndroidSantaTrackerKotlinCachingSmokeTest.groovy index dfdff09a65d9..e3612aba6f32 100644 --- a/subprojects/smoke-test/src/smokeTest/groovy/org/gradle/smoketests/AndroidSantaTrackerKotlinCachingSmokeTest.groovy +++ b/subprojects/smoke-test/src/smokeTest/groovy/org/gradle/smoketests/AndroidSantaTrackerKotlinCachingSmokeTest.groovy @@ -45,6 +45,8 @@ class AndroidSantaTrackerKotlinCachingSmokeTest extends AbstractAndroidSantaTrac when: buildLocation(originalDir, agpVersion) + + and: BuildResult relocatedResult = buildLocation(relocatedDir, agpVersion) then: diff --git a/subprojects/smoke-test/src/smokeTest/groovy/org/gradle/smoketests/AndroidSantaTrackerSmokeTest.groovy b/subprojects/smoke-test/src/smokeTest/groovy/org/gradle/smoketests/AndroidSantaTrackerSmokeTest.groovy index 830758f147c8..fd5e8fbcd342 100644 --- a/subprojects/smoke-test/src/smokeTest/groovy/org/gradle/smoketests/AndroidSantaTrackerSmokeTest.groovy +++ b/subprojects/smoke-test/src/smokeTest/groovy/org/gradle/smoketests/AndroidSantaTrackerSmokeTest.groovy @@ -32,12 +32,15 @@ class AndroidSantaTrackerSmokeTest extends AbstractAndroidSantaTrackerSmokeTest @Unroll @ToBeFixedForInstantExecution def "check deprecation warnings produced by building Santa Tracker Kotlin (agp=#agpVersion)"() { + + given: def checkoutDir = temporaryFolder.createDir("checkout") setupCopyOfSantaTracker(checkoutDir, 'Kotlin', agpVersion) + when: def result = buildLocation(checkoutDir, agpVersion) - expect: + then: expectDeprecationWarnings(result, "The configuration :detachedConfiguration1 was resolved without accessing the project in a safe manner. This may happen when a configuration is resolved from a different project. This behaviour has been deprecated and is scheduled to be removed in Gradle 7.0. See https://docs.gradle.org/${GradleVersion.current().version}/userguide/viewing_debugging_dependencies.html#sub:resolving-unsafe-configuration-resolution-errors for more details.", "The configuration :detachedConfiguration10 was resolved without accessing the project in a safe manner. This may happen when a configuration is resolved from a different project. This behaviour has been deprecated and is scheduled to be removed in Gradle 7.0. See https://docs.gradle.org/${GradleVersion.current().version}/userguide/viewing_debugging_dependencies.html#sub:resolving-unsafe-configuration-resolution-errors for more details.", @@ -62,12 +65,15 @@ class AndroidSantaTrackerSmokeTest extends AbstractAndroidSantaTrackerSmokeTest @Unroll def "check deprecation warnings produced by building Santa Tracker Java (agp=#agpVersion)"() { + + given: def checkoutDir = temporaryFolder.createDir("checkout") setupCopyOfSantaTracker(checkoutDir, 'Java', agpVersion) + when: def result = buildLocation(checkoutDir, agpVersion) - expect: + then: if (agpVersion.startsWith('3.6')) { expectDeprecationWarnings(result, "Internal API constructor DefaultDomainObjectSet(Class) has been deprecated. This is scheduled to be removed in Gradle 7.0. Please use ObjectFactory.domainObjectSet(Class) instead." @@ -83,9 +89,12 @@ class AndroidSantaTrackerSmokeTest extends AbstractAndroidSantaTrackerSmokeTest @Unroll @ToBeFixedForInstantExecution def "incremental Java compilation works for Santa Tracker Kotlin (agp=#agpVersion)"() { + + given: def checkoutDir = temporaryFolder.createDir("checkout") setupCopyOfSantaTracker(checkoutDir, 'Kotlin', agpVersion) + and: def pathToClass = "com/google/android/apps/santatracker/tracker/ui/BottomSheetBehavior" def fileToChange = checkoutDir.file("tracker/src/main/java/${pathToClass}.java") def compiledClassFile = checkoutDir.file("tracker/build/intermediates/javac/debug/classes/${pathToClass}.class") @@ -94,6 +103,7 @@ class AndroidSantaTrackerSmokeTest extends AbstractAndroidSantaTrackerSmokeTest when: def result = buildLocation(checkoutDir, agpVersion) def md5Before = compiledClassFile.md5Hash + then: result.task(":tracker:compileDebugJavaWithJavac").outcome == SUCCESS @@ -101,6 +111,7 @@ class AndroidSantaTrackerSmokeTest extends AbstractAndroidSantaTrackerSmokeTest nonAbiChangeMutator.beforeBuild() buildLocation(checkoutDir, agpVersion) def md5After = compiledClassFile.md5Hash + then: result.task(":tracker:compileDebugJavaWithJavac").outcome == SUCCESS md5After != md5Before @@ -111,9 +122,12 @@ class AndroidSantaTrackerSmokeTest extends AbstractAndroidSantaTrackerSmokeTest @Unroll def "incremental Java compilation works for Santa Tracker Java (agp=#agpVersion)"() { + + given: def checkoutDir = temporaryFolder.createDir("checkout") setupCopyOfSantaTracker(checkoutDir, 'Java', agpVersion) + and: def pathToClass = "com/google/android/apps/santatracker/map/BottomSheetBehavior" def fileToChange = checkoutDir.file("santa-tracker/src/main/java/${pathToClass}.java") def compiledClassFile = checkoutDir.file("santa-tracker/build/intermediates/javac/developmentDebug/classes/${pathToClass}.class") @@ -122,6 +136,7 @@ class AndroidSantaTrackerSmokeTest extends AbstractAndroidSantaTrackerSmokeTest when: def result = buildLocation(checkoutDir, agpVersion) def md5Before = compiledClassFile.md5Hash + then: result.task(":santa-tracker:compileDevelopmentDebugJavaWithJavac").outcome == SUCCESS @@ -129,6 +144,7 @@ class AndroidSantaTrackerSmokeTest extends AbstractAndroidSantaTrackerSmokeTest nonAbiChangeMutator.beforeBuild() buildLocation(checkoutDir, agpVersion) def md5After = compiledClassFile.md5Hash + then: result.task(":santa-tracker:compileDevelopmentDebugJavaWithJavac").outcome == SUCCESS md5After != md5Before From e27d54e4dab9999633f744a5214eaa89047b54c9 Mon Sep 17 00:00:00 2001 From: Paul Merlin Date: Wed, 22 Jan 2020 12:33:45 +0100 Subject: [PATCH 25/39] Add instant execution assertions to Santa Tracker smoke tests Signed-off-by: Paul Merlin --- .../AndroidSantaTrackerJavaCachingSmokeTest.groovy | 8 +++++++- .../AndroidSantaTrackerKotlinCachingSmokeTest.groovy | 8 +++++++- .../gradle/smoketests/AndroidSantaTrackerSmokeTest.groovy | 6 ++++++ 3 files changed, 20 insertions(+), 2 deletions(-) diff --git a/subprojects/smoke-test/src/smokeTest/groovy/org/gradle/smoketests/AndroidSantaTrackerJavaCachingSmokeTest.groovy b/subprojects/smoke-test/src/smokeTest/groovy/org/gradle/smoketests/AndroidSantaTrackerJavaCachingSmokeTest.groovy index 05b0f998e093..b339b08b2b3e 100644 --- a/subprojects/smoke-test/src/smokeTest/groovy/org/gradle/smoketests/AndroidSantaTrackerJavaCachingSmokeTest.groovy +++ b/subprojects/smoke-test/src/smokeTest/groovy/org/gradle/smoketests/AndroidSantaTrackerJavaCachingSmokeTest.groovy @@ -44,10 +44,16 @@ class AndroidSantaTrackerJavaCachingSmokeTest extends AbstractAndroidSantaTracke when: buildLocation(originalDir, agpVersion) - and: + then: + assertInstantExecutionStateStored() + + when: BuildResult relocatedResult = buildLocation(relocatedDir, agpVersion) then: + assertInstantExecutionStateStored() + + and: def expectedResults = agpVersion.startsWith('3.6') ? EXPECTED_RESULTS_3_6 : agpVersion.startsWith('4.0.0-alpha') diff --git a/subprojects/smoke-test/src/smokeTest/groovy/org/gradle/smoketests/AndroidSantaTrackerKotlinCachingSmokeTest.groovy b/subprojects/smoke-test/src/smokeTest/groovy/org/gradle/smoketests/AndroidSantaTrackerKotlinCachingSmokeTest.groovy index e3612aba6f32..25e35b6dae31 100644 --- a/subprojects/smoke-test/src/smokeTest/groovy/org/gradle/smoketests/AndroidSantaTrackerKotlinCachingSmokeTest.groovy +++ b/subprojects/smoke-test/src/smokeTest/groovy/org/gradle/smoketests/AndroidSantaTrackerKotlinCachingSmokeTest.groovy @@ -46,10 +46,16 @@ class AndroidSantaTrackerKotlinCachingSmokeTest extends AbstractAndroidSantaTrac when: buildLocation(originalDir, agpVersion) - and: + then: + assertInstantExecutionStateStored() + + when: BuildResult relocatedResult = buildLocation(relocatedDir, agpVersion) then: + assertInstantExecutionStateStored() + + and: def expectedResults = agpVersion.startsWith('3.6') ? EXPECTED_RESULTS_3_6 : agpVersion.startsWith('4.0.0-alpha') diff --git a/subprojects/smoke-test/src/smokeTest/groovy/org/gradle/smoketests/AndroidSantaTrackerSmokeTest.groovy b/subprojects/smoke-test/src/smokeTest/groovy/org/gradle/smoketests/AndroidSantaTrackerSmokeTest.groovy index fd5e8fbcd342..f05eb497ea64 100644 --- a/subprojects/smoke-test/src/smokeTest/groovy/org/gradle/smoketests/AndroidSantaTrackerSmokeTest.groovy +++ b/subprojects/smoke-test/src/smokeTest/groovy/org/gradle/smoketests/AndroidSantaTrackerSmokeTest.groovy @@ -58,6 +58,7 @@ class AndroidSantaTrackerSmokeTest extends AbstractAndroidSantaTrackerSmokeTest "The configuration :detachedConfiguration8 was resolved without accessing the project in a safe manner. This may happen when a configuration is resolved from a different project. This behaviour has been deprecated and is scheduled to be removed in Gradle 7.0. See https://docs.gradle.org/${GradleVersion.current().version}/userguide/viewing_debugging_dependencies.html#sub:resolving-unsafe-configuration-resolution-errors for more details.", "The configuration :detachedConfiguration9 was resolved without accessing the project in a safe manner. This may happen when a configuration is resolved from a different project. This behaviour has been deprecated and is scheduled to be removed in Gradle 7.0. See https://docs.gradle.org/${GradleVersion.current().version}/userguide/viewing_debugging_dependencies.html#sub:resolving-unsafe-configuration-resolution-errors for more details.", ) + assertInstantExecutionStateStored() where: agpVersion << TESTED_AGP_VERSIONS @@ -81,6 +82,7 @@ class AndroidSantaTrackerSmokeTest extends AbstractAndroidSantaTrackerSmokeTest } else { expectNoDeprecationWarnings(result) } + assertInstantExecutionStateStored() where: agpVersion << TESTED_AGP_VERSIONS @@ -106,6 +108,7 @@ class AndroidSantaTrackerSmokeTest extends AbstractAndroidSantaTrackerSmokeTest then: result.task(":tracker:compileDebugJavaWithJavac").outcome == SUCCESS + assertInstantExecutionStateStored() when: nonAbiChangeMutator.beforeBuild() @@ -114,6 +117,7 @@ class AndroidSantaTrackerSmokeTest extends AbstractAndroidSantaTrackerSmokeTest then: result.task(":tracker:compileDebugJavaWithJavac").outcome == SUCCESS + assertInstantExecutionStateLoaded() md5After != md5Before where: @@ -139,6 +143,7 @@ class AndroidSantaTrackerSmokeTest extends AbstractAndroidSantaTrackerSmokeTest then: result.task(":santa-tracker:compileDevelopmentDebugJavaWithJavac").outcome == SUCCESS + assertInstantExecutionStateStored() when: nonAbiChangeMutator.beforeBuild() @@ -147,6 +152,7 @@ class AndroidSantaTrackerSmokeTest extends AbstractAndroidSantaTrackerSmokeTest then: result.task(":santa-tracker:compileDevelopmentDebugJavaWithJavac").outcome == SUCCESS + assertInstantExecutionStateLoaded() md5After != md5Before where: From 73b8c50242217b19fb1ab294582b679a01140870 Mon Sep 17 00:00:00 2001 From: Paul Merlin Date: Wed, 22 Jan 2020 12:34:39 +0100 Subject: [PATCH 26/39] Limit Santa Tracker & Instant Execution smoke testing to AGP >= 4 Signed-off-by: Paul Merlin --- .../groovy/org/gradle/smoketests/AbstractSmokeTest.groovy | 1 + .../org/gradle/smoketests/AndroidPluginsSmokeTest.groovy | 2 +- .../smoketests/AndroidSantaTrackerJavaCachingSmokeTest.groovy | 2 ++ .../org/gradle/smoketests/AndroidSantaTrackerSmokeTest.groovy | 3 +++ 4 files changed, 7 insertions(+), 1 deletion(-) diff --git a/subprojects/smoke-test/src/smokeTest/groovy/org/gradle/smoketests/AbstractSmokeTest.groovy b/subprojects/smoke-test/src/smokeTest/groovy/org/gradle/smoketests/AbstractSmokeTest.groovy index ebf9f03a6b60..9cf8ae81cb6f 100644 --- a/subprojects/smoke-test/src/smokeTest/groovy/org/gradle/smoketests/AbstractSmokeTest.groovy +++ b/subprojects/smoke-test/src/smokeTest/groovy/org/gradle/smoketests/AbstractSmokeTest.groovy @@ -42,6 +42,7 @@ import static org.gradle.test.fixtures.server.http.MavenHttpPluginRepository.PLU abstract class AbstractSmokeTest extends Specification { protected static final AndroidGradlePluginVersions AGP_VERSIONS = new AndroidGradlePluginVersions() + protected static final String AGP_3_ITERATION_MATCHER = ".*agp=3\\..*" static class TestedVersions { /** diff --git a/subprojects/smoke-test/src/smokeTest/groovy/org/gradle/smoketests/AndroidPluginsSmokeTest.groovy b/subprojects/smoke-test/src/smokeTest/groovy/org/gradle/smoketests/AndroidPluginsSmokeTest.groovy index a3aeb8fa2a7c..a0fc347bca33 100644 --- a/subprojects/smoke-test/src/smokeTest/groovy/org/gradle/smoketests/AndroidPluginsSmokeTest.groovy +++ b/subprojects/smoke-test/src/smokeTest/groovy/org/gradle/smoketests/AndroidPluginsSmokeTest.groovy @@ -42,7 +42,7 @@ class AndroidPluginsSmokeTest extends AbstractSmokeTest { } @Unroll - @UnsupportedWithInstantExecution(iterationMatchers = ".*agp=3\\..*") + @UnsupportedWithInstantExecution(iterationMatchers = AGP_3_ITERATION_MATCHER) def "android library and application APK assembly (agp=#agpVersion, ide=#ide)"( String agpVersion, boolean ide ) { diff --git a/subprojects/smoke-test/src/smokeTest/groovy/org/gradle/smoketests/AndroidSantaTrackerJavaCachingSmokeTest.groovy b/subprojects/smoke-test/src/smokeTest/groovy/org/gradle/smoketests/AndroidSantaTrackerJavaCachingSmokeTest.groovy index b339b08b2b3e..475fd3e0f476 100644 --- a/subprojects/smoke-test/src/smokeTest/groovy/org/gradle/smoketests/AndroidSantaTrackerJavaCachingSmokeTest.groovy +++ b/subprojects/smoke-test/src/smokeTest/groovy/org/gradle/smoketests/AndroidSantaTrackerJavaCachingSmokeTest.groovy @@ -16,6 +16,7 @@ package org.gradle.smoketests +import org.gradle.integtests.fixtures.UnsupportedWithInstantExecution import org.gradle.testkit.runner.BuildResult import org.gradle.util.Requires import org.gradle.util.TestPrecondition @@ -31,6 +32,7 @@ import static org.gradle.testkit.runner.TaskOutcome.UP_TO_DATE class AndroidSantaTrackerJavaCachingSmokeTest extends AbstractAndroidSantaTrackerSmokeTest { @Unroll + @UnsupportedWithInstantExecution(iterationMatchers = AGP_3_ITERATION_MATCHER) def "can cache Santa Tracker Java Android application (agp=#agpVersion)"() { given: diff --git a/subprojects/smoke-test/src/smokeTest/groovy/org/gradle/smoketests/AndroidSantaTrackerSmokeTest.groovy b/subprojects/smoke-test/src/smokeTest/groovy/org/gradle/smoketests/AndroidSantaTrackerSmokeTest.groovy index f05eb497ea64..4ebdc7e32237 100644 --- a/subprojects/smoke-test/src/smokeTest/groovy/org/gradle/smoketests/AndroidSantaTrackerSmokeTest.groovy +++ b/subprojects/smoke-test/src/smokeTest/groovy/org/gradle/smoketests/AndroidSantaTrackerSmokeTest.groovy @@ -17,6 +17,7 @@ package org.gradle.smoketests import org.gradle.integtests.fixtures.ToBeFixedForInstantExecution +import org.gradle.integtests.fixtures.UnsupportedWithInstantExecution import org.gradle.profiler.mutations.ApplyNonAbiChangeToJavaSourceFileMutator import org.gradle.util.GradleVersion import org.gradle.util.Requires @@ -65,6 +66,7 @@ class AndroidSantaTrackerSmokeTest extends AbstractAndroidSantaTrackerSmokeTest } @Unroll + @UnsupportedWithInstantExecution(iterationMatchers = AGP_3_ITERATION_MATCHER) def "check deprecation warnings produced by building Santa Tracker Java (agp=#agpVersion)"() { given: @@ -125,6 +127,7 @@ class AndroidSantaTrackerSmokeTest extends AbstractAndroidSantaTrackerSmokeTest } @Unroll + @UnsupportedWithInstantExecution(iterationMatchers = AGP_3_ITERATION_MATCHER) def "incremental Java compilation works for Santa Tracker Java (agp=#agpVersion)"() { given: From e6e570ad6c54f5077465f8e7b17ee4cee251d487 Mon Sep 17 00:00:00 2001 From: Paul Merlin Date: Wed, 22 Jan 2020 12:37:51 +0100 Subject: [PATCH 27/39] Update expected outcomes for Santa Tracker with 4.0.0-alpha09 Signed-off-by: Paul Merlin --- ...oidSantaTrackerJavaCachingSmokeTest.groovy | 266 --------- ...dSantaTrackerKotlinCachingSmokeTest.groovy | 544 ------------------ 2 files changed, 810 deletions(-) diff --git a/subprojects/smoke-test/src/smokeTest/groovy/org/gradle/smoketests/AndroidSantaTrackerJavaCachingSmokeTest.groovy b/subprojects/smoke-test/src/smokeTest/groovy/org/gradle/smoketests/AndroidSantaTrackerJavaCachingSmokeTest.groovy index 475fd3e0f476..82916f75d48d 100644 --- a/subprojects/smoke-test/src/smokeTest/groovy/org/gradle/smoketests/AndroidSantaTrackerJavaCachingSmokeTest.groovy +++ b/subprojects/smoke-test/src/smokeTest/groovy/org/gradle/smoketests/AndroidSantaTrackerJavaCachingSmokeTest.groovy @@ -58,8 +58,6 @@ class AndroidSantaTrackerJavaCachingSmokeTest extends AbstractAndroidSantaTracke and: def expectedResults = agpVersion.startsWith('3.6') ? EXPECTED_RESULTS_3_6 - : agpVersion.startsWith('4.0.0-alpha') - ? EXPECTED_RESULTS_4_0_ALPHA : EXPECTED_RESULTS verify(relocatedResult, expectedResults) @@ -331,270 +329,6 @@ class AndroidSantaTrackerJavaCachingSmokeTest extends AbstractAndroidSantaTracke ':village:syncDebugLibJars': FROM_CACHE, ] - private static final EXPECTED_RESULTS_4_0_ALPHA = [ - ':common:assembleDebug': SUCCESS, - ':common:bundleDebugAar': SUCCESS, - ':common:bundleLibCompileDebug': FROM_CACHE, - ':common:bundleLibResDebug': FROM_CACHE, - ':common:bundleLibRuntimeDebug': FROM_CACHE, - ':common:compileDebugAidl': NO_SOURCE, - ':common:compileDebugJavaWithJavac': FROM_CACHE, - ':common:compileDebugLibraryResources': SUCCESS, - ':common:compileDebugRenderscript': NO_SOURCE, - ':common:compileDebugShaders': NO_SOURCE, - ':common:compileDebugSources': UP_TO_DATE, - ':common:copyDebugJniLibsProjectAndLocalJars': FROM_CACHE, - ':common:copyDebugJniLibsProjectOnly': FROM_CACHE, - ':common:extractDebugAnnotations': FROM_CACHE, - ':common:extractDeepLinksDebug': FROM_CACHE, - ':common:generateDebugAssets': UP_TO_DATE, - ':common:generateDebugBuildConfig': FROM_CACHE, - ':common:generateDebugRFile': FROM_CACHE, - ':common:generateDebugResValues': FROM_CACHE, - ':common:generateDebugResources': UP_TO_DATE, - ':common:javaPreCompileDebug': FROM_CACHE, - ':common:mergeDebugConsumerProguardFiles': FROM_CACHE, - ':common:mergeDebugGeneratedProguardFiles': FROM_CACHE, - ':common:mergeDebugJavaResource': FROM_CACHE, - ':common:mergeDebugJniLibFolders': FROM_CACHE, - ':common:mergeDebugNativeLibs': FROM_CACHE, - ':common:mergeDebugShaders': FROM_CACHE, - ':common:packageDebugAssets': FROM_CACHE, - ':common:packageDebugRenderscript': NO_SOURCE, - ':common:packageDebugResources': FROM_CACHE, - ':common:parseDebugLocalResources': FROM_CACHE, - ':common:preBuild': UP_TO_DATE, - ':common:preDebugBuild': UP_TO_DATE, - ':common:prepareLintJarForPublish': SUCCESS, - ':common:processDebugJavaRes': NO_SOURCE, - ':common:processDebugManifest': FROM_CACHE, - ':common:stripDebugDebugSymbols': FROM_CACHE, - ':common:syncDebugLibJars': FROM_CACHE, - ':dasherdancer:assembleDebug': SUCCESS, - ':dasherdancer:bundleDebugAar': SUCCESS, - ':dasherdancer:bundleLibCompileDebug': FROM_CACHE, - ':dasherdancer:bundleLibResDebug': FROM_CACHE, - ':dasherdancer:bundleLibRuntimeDebug': FROM_CACHE, - ':dasherdancer:compileDebugAidl': NO_SOURCE, - ':dasherdancer:compileDebugJavaWithJavac': FROM_CACHE, - ':dasherdancer:compileDebugLibraryResources': SUCCESS, - ':dasherdancer:compileDebugRenderscript': NO_SOURCE, - ':dasherdancer:compileDebugShaders': NO_SOURCE, - ':dasherdancer:compileDebugSources': UP_TO_DATE, - ':dasherdancer:copyDebugJniLibsProjectAndLocalJars': FROM_CACHE, - ':dasherdancer:copyDebugJniLibsProjectOnly': FROM_CACHE, - ':dasherdancer:extractDebugAnnotations': FROM_CACHE, - ':dasherdancer:extractDeepLinksDebug': FROM_CACHE, - ':dasherdancer:generateDebugAssets': UP_TO_DATE, - ':dasherdancer:generateDebugBuildConfig': FROM_CACHE, - ':dasherdancer:generateDebugRFile': FROM_CACHE, - ':dasherdancer:generateDebugResValues': FROM_CACHE, - ':dasherdancer:generateDebugResources': UP_TO_DATE, - ':dasherdancer:javaPreCompileDebug': FROM_CACHE, - ':dasherdancer:mergeDebugConsumerProguardFiles': FROM_CACHE, - ':dasherdancer:mergeDebugGeneratedProguardFiles': FROM_CACHE, - ':dasherdancer:mergeDebugJavaResource': FROM_CACHE, - ':dasherdancer:mergeDebugJniLibFolders': FROM_CACHE, - ':dasherdancer:mergeDebugNativeLibs': FROM_CACHE, - ':dasherdancer:mergeDebugShaders': FROM_CACHE, - ':dasherdancer:packageDebugAssets': FROM_CACHE, - ':dasherdancer:packageDebugRenderscript': NO_SOURCE, - ':dasherdancer:packageDebugResources': FROM_CACHE, - ':dasherdancer:parseDebugLocalResources': FROM_CACHE, - ':dasherdancer:preBuild': UP_TO_DATE, - ':dasherdancer:preDebugBuild': UP_TO_DATE, - ':dasherdancer:prepareLintJarForPublish': SUCCESS, - ':dasherdancer:processDebugJavaRes': NO_SOURCE, - ':dasherdancer:processDebugManifest': FROM_CACHE, - ':dasherdancer:stripDebugDebugSymbols': FROM_CACHE, - ':dasherdancer:syncDebugLibJars': FROM_CACHE, - ':doodles:assembleDebug': SUCCESS, - ':doodles:bundleDebugAar': SUCCESS, - ':doodles:bundleLibCompileDebug': FROM_CACHE, - ':doodles:bundleLibResDebug': FROM_CACHE, - ':doodles:bundleLibRuntimeDebug': FROM_CACHE, - ':doodles:compileDebugAidl': NO_SOURCE, - ':doodles:compileDebugJavaWithJavac': FROM_CACHE, - ':doodles:compileDebugLibraryResources': SUCCESS, - ':doodles:compileDebugRenderscript': NO_SOURCE, - ':doodles:compileDebugShaders': NO_SOURCE, - ':doodles:compileDebugSources': UP_TO_DATE, - ':doodles:copyDebugJniLibsProjectAndLocalJars': FROM_CACHE, - ':doodles:copyDebugJniLibsProjectOnly': FROM_CACHE, - ':doodles:extractDebugAnnotations': FROM_CACHE, - ':doodles:extractDeepLinksDebug': FROM_CACHE, - ':doodles:generateDebugAssets': UP_TO_DATE, - ':doodles:generateDebugBuildConfig': FROM_CACHE, - ':doodles:generateDebugRFile': FROM_CACHE, - ':doodles:generateDebugResValues': FROM_CACHE, - ':doodles:generateDebugResources': UP_TO_DATE, - ':doodles:javaPreCompileDebug': FROM_CACHE, - ':doodles:mergeDebugConsumerProguardFiles': FROM_CACHE, - ':doodles:mergeDebugGeneratedProguardFiles': FROM_CACHE, - ':doodles:mergeDebugJavaResource': FROM_CACHE, - ':doodles:mergeDebugJniLibFolders': FROM_CACHE, - ':doodles:mergeDebugNativeLibs': FROM_CACHE, - ':doodles:mergeDebugShaders': FROM_CACHE, - ':doodles:packageDebugAssets': FROM_CACHE, - ':doodles:packageDebugRenderscript': NO_SOURCE, - ':doodles:packageDebugResources': FROM_CACHE, - ':doodles:parseDebugLocalResources': FROM_CACHE, - ':doodles:preBuild': UP_TO_DATE, - ':doodles:preDebugBuild': UP_TO_DATE, - ':doodles:prepareLintJarForPublish': SUCCESS, - ':doodles:processDebugJavaRes': NO_SOURCE, - ':doodles:processDebugManifest': FROM_CACHE, - ':doodles:stripDebugDebugSymbols': FROM_CACHE, - ':doodles:syncDebugLibJars': FROM_CACHE, - ':presentquest:assembleDebug': SUCCESS, - ':presentquest:bundleDebugAar': SUCCESS, - ':presentquest:bundleLibCompileDebug': FROM_CACHE, - ':presentquest:bundleLibResDebug': FROM_CACHE, - ':presentquest:bundleLibRuntimeDebug': FROM_CACHE, - ':presentquest:compileDebugAidl': NO_SOURCE, - ':presentquest:compileDebugJavaWithJavac': FROM_CACHE, - ':presentquest:compileDebugLibraryResources': SUCCESS, - ':presentquest:compileDebugRenderscript': NO_SOURCE, - ':presentquest:compileDebugShaders': NO_SOURCE, - ':presentquest:compileDebugSources': UP_TO_DATE, - ':presentquest:copyDebugJniLibsProjectAndLocalJars': FROM_CACHE, - ':presentquest:copyDebugJniLibsProjectOnly': FROM_CACHE, - ':presentquest:extractDebugAnnotations': FROM_CACHE, - ':presentquest:extractDeepLinksDebug': FROM_CACHE, - ':presentquest:generateDebugAssets': UP_TO_DATE, - ':presentquest:generateDebugBuildConfig': FROM_CACHE, - ':presentquest:generateDebugRFile': FROM_CACHE, - ':presentquest:generateDebugResValues': FROM_CACHE, - ':presentquest:generateDebugResources': UP_TO_DATE, - ':presentquest:javaPreCompileDebug': FROM_CACHE, - ':presentquest:mergeDebugConsumerProguardFiles': FROM_CACHE, - ':presentquest:mergeDebugGeneratedProguardFiles': FROM_CACHE, - ':presentquest:mergeDebugJavaResource': FROM_CACHE, - ':presentquest:mergeDebugJniLibFolders': FROM_CACHE, - ':presentquest:mergeDebugNativeLibs': FROM_CACHE, - ':presentquest:mergeDebugShaders': FROM_CACHE, - ':presentquest:packageDebugAssets': FROM_CACHE, - ':presentquest:packageDebugRenderscript': NO_SOURCE, - ':presentquest:packageDebugResources': FROM_CACHE, - ':presentquest:parseDebugLocalResources': FROM_CACHE, - ':presentquest:preBuild': UP_TO_DATE, - ':presentquest:preDebugBuild': UP_TO_DATE, - ':presentquest:prepareLintJarForPublish': SUCCESS, - ':presentquest:processDebugJavaRes': NO_SOURCE, - ':presentquest:processDebugManifest': FROM_CACHE, - ':presentquest:stripDebugDebugSymbols': FROM_CACHE, - ':presentquest:syncDebugLibJars': FROM_CACHE, - ':rocketsleigh:assembleDebug': SUCCESS, - ':rocketsleigh:bundleDebugAar': SUCCESS, - ':rocketsleigh:bundleLibCompileDebug': FROM_CACHE, - ':rocketsleigh:bundleLibResDebug': FROM_CACHE, - ':rocketsleigh:bundleLibRuntimeDebug': FROM_CACHE, - ':rocketsleigh:compileDebugAidl': NO_SOURCE, - ':rocketsleigh:compileDebugJavaWithJavac': FROM_CACHE, - ':rocketsleigh:compileDebugLibraryResources': SUCCESS, - ':rocketsleigh:compileDebugRenderscript': NO_SOURCE, - ':rocketsleigh:compileDebugShaders': NO_SOURCE, - ':rocketsleigh:compileDebugSources': UP_TO_DATE, - ':rocketsleigh:copyDebugJniLibsProjectAndLocalJars': FROM_CACHE, - ':rocketsleigh:copyDebugJniLibsProjectOnly': FROM_CACHE, - ':rocketsleigh:extractDebugAnnotations': FROM_CACHE, - ':rocketsleigh:extractDeepLinksDebug': FROM_CACHE, - ':rocketsleigh:generateDebugAssets': UP_TO_DATE, - ':rocketsleigh:generateDebugBuildConfig': FROM_CACHE, - ':rocketsleigh:generateDebugRFile': FROM_CACHE, - ':rocketsleigh:generateDebugResValues': FROM_CACHE, - ':rocketsleigh:generateDebugResources': UP_TO_DATE, - ':rocketsleigh:javaPreCompileDebug': FROM_CACHE, - ':rocketsleigh:mergeDebugConsumerProguardFiles': FROM_CACHE, - ':rocketsleigh:mergeDebugGeneratedProguardFiles': FROM_CACHE, - ':rocketsleigh:mergeDebugJavaResource': FROM_CACHE, - ':rocketsleigh:mergeDebugJniLibFolders': FROM_CACHE, - ':rocketsleigh:mergeDebugNativeLibs': FROM_CACHE, - ':rocketsleigh:mergeDebugShaders': FROM_CACHE, - ':rocketsleigh:packageDebugAssets': FROM_CACHE, - ':rocketsleigh:packageDebugRenderscript': NO_SOURCE, - ':rocketsleigh:packageDebugResources': FROM_CACHE, - ':rocketsleigh:parseDebugLocalResources': FROM_CACHE, - ':rocketsleigh:preBuild': UP_TO_DATE, - ':rocketsleigh:preDebugBuild': UP_TO_DATE, - ':rocketsleigh:prepareLintJarForPublish': SUCCESS, - ':rocketsleigh:processDebugJavaRes': NO_SOURCE, - ':rocketsleigh:processDebugManifest': FROM_CACHE, - ':rocketsleigh:stripDebugDebugSymbols': FROM_CACHE, - ':rocketsleigh:syncDebugLibJars': FROM_CACHE, - ':santa-tracker:assembleDebug': SUCCESS, - ':santa-tracker:assembleDevelopmentDebug': SUCCESS, - ':santa-tracker:checkDevelopmentDebugDuplicateClasses': FROM_CACHE, - ':santa-tracker:compileDevelopmentDebugAidl': NO_SOURCE, - ':santa-tracker:compileDevelopmentDebugJavaWithJavac': FROM_CACHE, - ':santa-tracker:compileDevelopmentDebugRenderscript': NO_SOURCE, - ':santa-tracker:compileDevelopmentDebugShaders': NO_SOURCE, - ':santa-tracker:compileDevelopmentDebugSources': UP_TO_DATE, - ':santa-tracker:createDevelopmentDebugCompatibleScreenManifests': FROM_CACHE, - ':santa-tracker:dexBuilderDevelopmentDebug': FROM_CACHE, - ':santa-tracker:extractDeepLinksDevelopmentDebug': FROM_CACHE, - ':santa-tracker:generateDevelopmentDebugAssets': UP_TO_DATE, - ':santa-tracker:generateDevelopmentDebugBuildConfig': FROM_CACHE, - ':santa-tracker:generateDevelopmentDebugResValues': FROM_CACHE, - ':santa-tracker:generateDevelopmentDebugResources': UP_TO_DATE, - ':santa-tracker:javaPreCompileDevelopmentDebug': FROM_CACHE, - ':santa-tracker:mergeDevelopmentDebugAssets': FROM_CACHE, - ':santa-tracker:mergeDevelopmentDebugJavaResource': FROM_CACHE, - ':santa-tracker:mergeDevelopmentDebugJniLibFolders': FROM_CACHE, - ':santa-tracker:mergeDevelopmentDebugNativeLibs': FROM_CACHE, - ':santa-tracker:mergeDevelopmentDebugResources': SUCCESS, - ':santa-tracker:mergeDevelopmentDebugShaders': FROM_CACHE, - ':santa-tracker:mergeExtDexDevelopmentDebug': FROM_CACHE, - ':santa-tracker:mergeLibDexDevelopmentDebug': FROM_CACHE, - ':santa-tracker:mergeProjectDexDevelopmentDebug': FROM_CACHE, - ':santa-tracker:packageDevelopmentDebug': SUCCESS, - ':santa-tracker:preBuild': UP_TO_DATE, - ':santa-tracker:preDevelopmentDebugBuild': UP_TO_DATE, - ':santa-tracker:processDevelopmentDebugJavaRes': NO_SOURCE, - ':santa-tracker:processDevelopmentDebugManifest': FROM_CACHE, - ':santa-tracker:processDevelopmentDebugResources': SUCCESS, - ':santa-tracker:stripDevelopmentDebugDebugSymbols': FROM_CACHE, - ':santa-tracker:validateSigningDevelopmentDebug': FROM_CACHE, - ':village:assembleDebug': SUCCESS, - ':village:bundleDebugAar': SUCCESS, - ':village:bundleLibCompileDebug': FROM_CACHE, - ':village:bundleLibResDebug': FROM_CACHE, - ':village:bundleLibRuntimeDebug': FROM_CACHE, - ':village:compileDebugAidl': NO_SOURCE, - ':village:compileDebugJavaWithJavac': FROM_CACHE, - ':village:compileDebugLibraryResources': SUCCESS, - ':village:compileDebugRenderscript': NO_SOURCE, - ':village:compileDebugShaders': NO_SOURCE, - ':village:compileDebugSources': UP_TO_DATE, - ':village:copyDebugJniLibsProjectAndLocalJars': FROM_CACHE, - ':village:copyDebugJniLibsProjectOnly': FROM_CACHE, - ':village:extractDebugAnnotations': FROM_CACHE, - ':village:extractDeepLinksDebug': FROM_CACHE, - ':village:generateDebugAssets': UP_TO_DATE, - ':village:generateDebugBuildConfig': FROM_CACHE, - ':village:generateDebugRFile': FROM_CACHE, - ':village:generateDebugResValues': FROM_CACHE, - ':village:generateDebugResources': UP_TO_DATE, - ':village:javaPreCompileDebug': FROM_CACHE, - ':village:mergeDebugConsumerProguardFiles': FROM_CACHE, - ':village:mergeDebugGeneratedProguardFiles': FROM_CACHE, - ':village:mergeDebugJavaResource': FROM_CACHE, - ':village:mergeDebugJniLibFolders': FROM_CACHE, - ':village:mergeDebugNativeLibs': FROM_CACHE, - ':village:mergeDebugShaders': FROM_CACHE, - ':village:packageDebugAssets': FROM_CACHE, - ':village:packageDebugRenderscript': NO_SOURCE, - ':village:packageDebugResources': FROM_CACHE, - ':village:parseDebugLocalResources': FROM_CACHE, - ':village:preBuild': UP_TO_DATE, - ':village:preDebugBuild': UP_TO_DATE, - ':village:prepareLintJarForPublish': SUCCESS, - ':village:processDebugJavaRes': NO_SOURCE, - ':village:processDebugManifest': FROM_CACHE, - ':village:stripDebugDebugSymbols': FROM_CACHE, - ':village:syncDebugLibJars': FROM_CACHE, - ] - private static final EXPECTED_RESULTS_3_6 = [ ':common:assembleDebug': SUCCESS, ':common:bundleDebugAar': SUCCESS, diff --git a/subprojects/smoke-test/src/smokeTest/groovy/org/gradle/smoketests/AndroidSantaTrackerKotlinCachingSmokeTest.groovy b/subprojects/smoke-test/src/smokeTest/groovy/org/gradle/smoketests/AndroidSantaTrackerKotlinCachingSmokeTest.groovy index 25e35b6dae31..90d4edaccd06 100644 --- a/subprojects/smoke-test/src/smokeTest/groovy/org/gradle/smoketests/AndroidSantaTrackerKotlinCachingSmokeTest.groovy +++ b/subprojects/smoke-test/src/smokeTest/groovy/org/gradle/smoketests/AndroidSantaTrackerKotlinCachingSmokeTest.groovy @@ -58,8 +58,6 @@ class AndroidSantaTrackerKotlinCachingSmokeTest extends AbstractAndroidSantaTrac and: def expectedResults = agpVersion.startsWith('3.6') ? EXPECTED_RESULTS_3_6 - : agpVersion.startsWith('4.0.0-alpha') - ? EXPECTED_RESULTS_4_0_ALPHA : EXPECTED_RESULTS verify(relocatedResult, expectedResults) @@ -609,548 +607,6 @@ class AndroidSantaTrackerKotlinCachingSmokeTest extends AbstractAndroidSantaTrac ':wearable:validateSigningDebug': FROM_CACHE, ] - private static final EXPECTED_RESULTS_4_0_ALPHA = [ - ':cityquiz:assembleDebug': SUCCESS, - ':cityquiz:checkDebugDuplicateClasses': FROM_CACHE, - ':cityquiz:compileDebugAidl': NO_SOURCE, - ':cityquiz:compileDebugJavaWithJavac': FROM_CACHE, - ':cityquiz:compileDebugKotlin': FROM_CACHE, - ':cityquiz:compileDebugRenderscript': NO_SOURCE, - ':cityquiz:compileDebugShaders': NO_SOURCE, - ':cityquiz:compileDebugSources': UP_TO_DATE, - ':cityquiz:createDebugCompatibleScreenManifests': FROM_CACHE, - ':cityquiz:dexBuilderDebug': FROM_CACHE, - ':cityquiz:extractDeepLinksDebug': FROM_CACHE, - ':cityquiz:featureDebugWriter': SUCCESS, - ':cityquiz:generateDebugAssets': UP_TO_DATE, - ':cityquiz:generateDebugBuildConfig': FROM_CACHE, - ':cityquiz:generateDebugFeatureTransitiveDeps': FROM_CACHE, - ':cityquiz:generateDebugResValues': FROM_CACHE, - ':cityquiz:generateDebugResources': UP_TO_DATE, - ':cityquiz:javaPreCompileDebug': FROM_CACHE, - ':cityquiz:mergeDebugAssets': FROM_CACHE, - ':cityquiz:mergeDebugJavaResource': SUCCESS, - ':cityquiz:mergeDebugJniLibFolders': FROM_CACHE, - ':cityquiz:mergeDebugNativeLibs': FROM_CACHE, - ':cityquiz:mergeDebugResources': SUCCESS, - ':cityquiz:mergeDebugShaders': FROM_CACHE, - ':cityquiz:mergeExtDexDebug': FROM_CACHE, - ':cityquiz:mergeLibDexDebug': FROM_CACHE, - ':cityquiz:mergeProjectDexDebug': FROM_CACHE, - ':cityquiz:packageDebug': SUCCESS, - ':cityquiz:preBuild': UP_TO_DATE, - ':cityquiz:preDebugBuild': UP_TO_DATE, - ':cityquiz:processDebugJavaRes': NO_SOURCE, - ':cityquiz:processDebugManifest': FROM_CACHE, - ':cityquiz:processDebugResources': SUCCESS, - ':cityquiz:stripDebugDebugSymbols': FROM_CACHE, - ':common:assembleDebug': SUCCESS, - ':common:bundleDebugAar': SUCCESS, - ':common:bundleLibCompileDebug': FROM_CACHE, - ':common:bundleLibResDebug': FROM_CACHE, - ':common:bundleLibRuntimeDebug': FROM_CACHE, - ':common:compileDebugAidl': NO_SOURCE, - ':common:compileDebugJavaWithJavac': FROM_CACHE, - ':common:compileDebugKotlin': FROM_CACHE, - ':common:compileDebugLibraryResources': SUCCESS, - ':common:compileDebugRenderscript': NO_SOURCE, - ':common:compileDebugShaders': NO_SOURCE, - ':common:compileDebugSources': UP_TO_DATE, - ':common:copyDebugJniLibsProjectAndLocalJars': FROM_CACHE, - ':common:copyDebugJniLibsProjectOnly': FROM_CACHE, - ':common:createFullJarDebug': FROM_CACHE, - ':common:extractDebugAnnotations': FROM_CACHE, - ':common:extractDeepLinksDebug': FROM_CACHE, - ':common:generateDebugAssets': UP_TO_DATE, - ':common:generateDebugBuildConfig': FROM_CACHE, - ':common:generateDebugRFile': FROM_CACHE, - ':common:generateDebugResValues': FROM_CACHE, - ':common:generateDebugResources': UP_TO_DATE, - ':common:javaPreCompileDebug': FROM_CACHE, - ':common:mergeDebugConsumerProguardFiles': FROM_CACHE, - ':common:mergeDebugGeneratedProguardFiles': FROM_CACHE, - ':common:mergeDebugJavaResource': SUCCESS, - ':common:mergeDebugJniLibFolders': FROM_CACHE, - ':common:mergeDebugNativeLibs': FROM_CACHE, - ':common:mergeDebugShaders': FROM_CACHE, - ':common:packageDebugAssets': FROM_CACHE, - ':common:packageDebugRenderscript': NO_SOURCE, - ':common:packageDebugResources': FROM_CACHE, - ':common:parseDebugLocalResources': FROM_CACHE, - ':common:preBuild': UP_TO_DATE, - ':common:preDebugBuild': UP_TO_DATE, - ':common:prepareLintJarForPublish': SUCCESS, - ':common:processDebugJavaRes': NO_SOURCE, - ':common:processDebugManifest': FROM_CACHE, - ':common:stripDebugDebugSymbols': FROM_CACHE, - ':common:syncDebugLibJars': SUCCESS, - ':dasherdancer:assembleDebug': SUCCESS, - ':dasherdancer:checkDebugDuplicateClasses': FROM_CACHE, - ':dasherdancer:compileDebugAidl': NO_SOURCE, - ':dasherdancer:compileDebugJavaWithJavac': FROM_CACHE, - ':dasherdancer:compileDebugKotlin': FROM_CACHE, - ':dasherdancer:compileDebugRenderscript': NO_SOURCE, - ':dasherdancer:compileDebugShaders': NO_SOURCE, - ':dasherdancer:compileDebugSources': UP_TO_DATE, - ':dasherdancer:createDebugCompatibleScreenManifests': FROM_CACHE, - ':dasherdancer:dexBuilderDebug': FROM_CACHE, - ':dasherdancer:extractDeepLinksDebug': FROM_CACHE, - ':dasherdancer:featureDebugWriter': SUCCESS, - ':dasherdancer:generateDebugAssets': UP_TO_DATE, - ':dasherdancer:generateDebugBuildConfig': FROM_CACHE, - ':dasherdancer:generateDebugFeatureTransitiveDeps': FROM_CACHE, - ':dasherdancer:generateDebugResValues': FROM_CACHE, - ':dasherdancer:generateDebugResources': UP_TO_DATE, - ':dasherdancer:javaPreCompileDebug': FROM_CACHE, - ':dasherdancer:mergeDebugAssets': FROM_CACHE, - ':dasherdancer:mergeDebugJavaResource': SUCCESS, - ':dasherdancer:mergeDebugJniLibFolders': FROM_CACHE, - ':dasherdancer:mergeDebugNativeLibs': FROM_CACHE, - ':dasherdancer:mergeDebugResources': SUCCESS, - ':dasherdancer:mergeDebugShaders': FROM_CACHE, - ':dasherdancer:mergeExtDexDebug': FROM_CACHE, - ':dasherdancer:mergeLibDexDebug': FROM_CACHE, - ':dasherdancer:mergeProjectDexDebug': FROM_CACHE, - ':dasherdancer:packageDebug': SUCCESS, - ':dasherdancer:preBuild': UP_TO_DATE, - ':dasherdancer:preDebugBuild': UP_TO_DATE, - ':dasherdancer:processDebugJavaRes': NO_SOURCE, - ':dasherdancer:processDebugManifest': FROM_CACHE, - ':dasherdancer:processDebugResources': SUCCESS, - ':dasherdancer:stripDebugDebugSymbols': FROM_CACHE, - ':doodles-lib:assembleDebug': SUCCESS, - ':doodles-lib:bundleDebugAar': SUCCESS, - ':doodles-lib:bundleLibCompileDebug': FROM_CACHE, - ':doodles-lib:bundleLibResDebug': FROM_CACHE, - ':doodles-lib:bundleLibRuntimeDebug': FROM_CACHE, - ':doodles-lib:compileDebugAidl': NO_SOURCE, - ':doodles-lib:compileDebugJavaWithJavac': FROM_CACHE, - ':doodles-lib:compileDebugLibraryResources': SUCCESS, - ':doodles-lib:compileDebugRenderscript': NO_SOURCE, - ':doodles-lib:compileDebugShaders': NO_SOURCE, - ':doodles-lib:compileDebugSources': UP_TO_DATE, - ':doodles-lib:copyDebugJniLibsProjectAndLocalJars': FROM_CACHE, - ':doodles-lib:copyDebugJniLibsProjectOnly': FROM_CACHE, - ':doodles-lib:createFullJarDebug': FROM_CACHE, - ':doodles-lib:extractDebugAnnotations': FROM_CACHE, - ':doodles-lib:extractDeepLinksDebug': FROM_CACHE, - ':doodles-lib:generateDebugAssets': UP_TO_DATE, - ':doodles-lib:generateDebugBuildConfig': FROM_CACHE, - ':doodles-lib:generateDebugRFile': FROM_CACHE, - ':doodles-lib:generateDebugResValues': FROM_CACHE, - ':doodles-lib:generateDebugResources': UP_TO_DATE, - ':doodles-lib:javaPreCompileDebug': FROM_CACHE, - ':doodles-lib:mergeDebugConsumerProguardFiles': FROM_CACHE, - ':doodles-lib:mergeDebugGeneratedProguardFiles': FROM_CACHE, - ':doodles-lib:mergeDebugJavaResource': FROM_CACHE, - ':doodles-lib:mergeDebugJniLibFolders': FROM_CACHE, - ':doodles-lib:mergeDebugNativeLibs': FROM_CACHE, - ':doodles-lib:mergeDebugShaders': FROM_CACHE, - ':doodles-lib:packageDebugAssets': FROM_CACHE, - ':doodles-lib:packageDebugRenderscript': NO_SOURCE, - ':doodles-lib:packageDebugResources': FROM_CACHE, - ':doodles-lib:parseDebugLocalResources': FROM_CACHE, - ':doodles-lib:preBuild': UP_TO_DATE, - ':doodles-lib:preDebugBuild': UP_TO_DATE, - ':doodles-lib:prepareLintJarForPublish': SUCCESS, - ':doodles-lib:processDebugJavaRes': NO_SOURCE, - ':doodles-lib:processDebugManifest': FROM_CACHE, - ':doodles-lib:stripDebugDebugSymbols': FROM_CACHE, - ':doodles-lib:syncDebugLibJars': FROM_CACHE, - ':gumball:assembleDebug': SUCCESS, - ':gumball:checkDebugDuplicateClasses': FROM_CACHE, - ':gumball:compileDebugAidl': NO_SOURCE, - ':gumball:compileDebugJavaWithJavac': FROM_CACHE, - ':gumball:compileDebugRenderscript': NO_SOURCE, - ':gumball:compileDebugShaders': NO_SOURCE, - ':gumball:compileDebugSources': UP_TO_DATE, - ':gumball:createDebugCompatibleScreenManifests': FROM_CACHE, - ':gumball:dexBuilderDebug': FROM_CACHE, - ':gumball:extractDeepLinksDebug': FROM_CACHE, - ':gumball:featureDebugWriter': SUCCESS, - ':gumball:generateDebugAssets': UP_TO_DATE, - ':gumball:generateDebugBuildConfig': FROM_CACHE, - ':gumball:generateDebugFeatureTransitiveDeps': FROM_CACHE, - ':gumball:generateDebugResValues': FROM_CACHE, - ':gumball:generateDebugResources': UP_TO_DATE, - ':gumball:javaPreCompileDebug': FROM_CACHE, - ':gumball:mergeDebugAssets': FROM_CACHE, - ':gumball:mergeDebugJavaResource': FROM_CACHE, - ':gumball:mergeDebugJniLibFolders': FROM_CACHE, - ':gumball:mergeDebugNativeLibs': FROM_CACHE, - ':gumball:mergeDebugResources': SUCCESS, - ':gumball:mergeDebugShaders': FROM_CACHE, - ':gumball:mergeExtDexDebug': FROM_CACHE, - ':gumball:mergeLibDexDebug': FROM_CACHE, - ':gumball:mergeProjectDexDebug': FROM_CACHE, - ':gumball:packageDebug': SUCCESS, - ':gumball:preBuild': UP_TO_DATE, - ':gumball:preDebugBuild': UP_TO_DATE, - ':gumball:processDebugJavaRes': NO_SOURCE, - ':gumball:processDebugManifest': FROM_CACHE, - ':gumball:processDebugResources': SUCCESS, - ':gumball:stripDebugDebugSymbols': FROM_CACHE, - ':jetpack:assembleDebug': SUCCESS, - ':jetpack:checkDebugDuplicateClasses': FROM_CACHE, - ':jetpack:compileDebugAidl': NO_SOURCE, - ':jetpack:compileDebugJavaWithJavac': FROM_CACHE, - ':jetpack:compileDebugKotlin': FROM_CACHE, - ':jetpack:compileDebugRenderscript': NO_SOURCE, - ':jetpack:compileDebugShaders': NO_SOURCE, - ':jetpack:compileDebugSources': UP_TO_DATE, - ':jetpack:createDebugCompatibleScreenManifests': FROM_CACHE, - ':jetpack:dexBuilderDebug': FROM_CACHE, - ':jetpack:extractDeepLinksDebug': FROM_CACHE, - ':jetpack:featureDebugWriter': SUCCESS, - ':jetpack:generateDebugAssets': UP_TO_DATE, - ':jetpack:generateDebugBuildConfig': FROM_CACHE, - ':jetpack:generateDebugFeatureTransitiveDeps': FROM_CACHE, - ':jetpack:generateDebugResValues': FROM_CACHE, - ':jetpack:generateDebugResources': UP_TO_DATE, - ':jetpack:javaPreCompileDebug': FROM_CACHE, - ':jetpack:mergeDebugAssets': FROM_CACHE, - ':jetpack:mergeDebugJavaResource': SUCCESS, - ':jetpack:mergeDebugJniLibFolders': FROM_CACHE, - ':jetpack:mergeDebugNativeLibs': FROM_CACHE, - ':jetpack:mergeDebugResources': SUCCESS, - ':jetpack:mergeDebugShaders': FROM_CACHE, - ':jetpack:mergeExtDexDebug': FROM_CACHE, - ':jetpack:mergeLibDexDebug': FROM_CACHE, - ':jetpack:mergeProjectDexDebug': FROM_CACHE, - ':jetpack:packageDebug': SUCCESS, - ':jetpack:preBuild': UP_TO_DATE, - ':jetpack:preDebugBuild': UP_TO_DATE, - ':jetpack:processDebugJavaRes': NO_SOURCE, - ':jetpack:processDebugManifest': FROM_CACHE, - ':jetpack:processDebugResources': SUCCESS, - ':jetpack:stripDebugDebugSymbols': FROM_CACHE, - ':memory:assembleDebug': SUCCESS, - ':memory:checkDebugDuplicateClasses': FROM_CACHE, - ':memory:compileDebugAidl': NO_SOURCE, - ':memory:compileDebugJavaWithJavac': FROM_CACHE, - ':memory:compileDebugRenderscript': NO_SOURCE, - ':memory:compileDebugShaders': NO_SOURCE, - ':memory:compileDebugSources': UP_TO_DATE, - ':memory:createDebugCompatibleScreenManifests': FROM_CACHE, - ':memory:dexBuilderDebug': FROM_CACHE, - ':memory:extractDeepLinksDebug': FROM_CACHE, - ':memory:featureDebugWriter': SUCCESS, - ':memory:generateDebugAssets': UP_TO_DATE, - ':memory:generateDebugBuildConfig': FROM_CACHE, - ':memory:generateDebugFeatureTransitiveDeps': FROM_CACHE, - ':memory:generateDebugResValues': FROM_CACHE, - ':memory:generateDebugResources': UP_TO_DATE, - ':memory:javaPreCompileDebug': FROM_CACHE, - ':memory:mergeDebugAssets': FROM_CACHE, - ':memory:mergeDebugJavaResource': FROM_CACHE, - ':memory:mergeDebugJniLibFolders': FROM_CACHE, - ':memory:mergeDebugNativeLibs': FROM_CACHE, - ':memory:mergeDebugResources': SUCCESS, - ':memory:mergeDebugShaders': FROM_CACHE, - ':memory:mergeExtDexDebug': FROM_CACHE, - ':memory:mergeLibDexDebug': FROM_CACHE, - ':memory:mergeProjectDexDebug': FROM_CACHE, - ':memory:packageDebug': SUCCESS, - ':memory:preBuild': UP_TO_DATE, - ':memory:preDebugBuild': UP_TO_DATE, - ':memory:processDebugJavaRes': NO_SOURCE, - ':memory:processDebugManifest': FROM_CACHE, - ':memory:processDebugResources': SUCCESS, - ':memory:stripDebugDebugSymbols': FROM_CACHE, - ':penguinswim:assembleDebug': SUCCESS, - ':penguinswim:checkDebugDuplicateClasses': FROM_CACHE, - ':penguinswim:compileDebugAidl': NO_SOURCE, - ':penguinswim:compileDebugJavaWithJavac': FROM_CACHE, - ':penguinswim:compileDebugRenderscript': NO_SOURCE, - ':penguinswim:compileDebugShaders': NO_SOURCE, - ':penguinswim:compileDebugSources': UP_TO_DATE, - ':penguinswim:createDebugCompatibleScreenManifests': FROM_CACHE, - ':penguinswim:dexBuilderDebug': FROM_CACHE, - ':penguinswim:extractDeepLinksDebug': FROM_CACHE, - ':penguinswim:featureDebugWriter': SUCCESS, - ':penguinswim:generateDebugAssets': UP_TO_DATE, - ':penguinswim:generateDebugBuildConfig': FROM_CACHE, - ':penguinswim:generateDebugFeatureTransitiveDeps': FROM_CACHE, - ':penguinswim:generateDebugResValues': FROM_CACHE, - ':penguinswim:generateDebugResources': UP_TO_DATE, - ':penguinswim:javaPreCompileDebug': FROM_CACHE, - ':penguinswim:mergeDebugAssets': FROM_CACHE, - ':penguinswim:mergeDebugJavaResource': FROM_CACHE, - ':penguinswim:mergeDebugJniLibFolders': FROM_CACHE, - ':penguinswim:mergeDebugNativeLibs': FROM_CACHE, - ':penguinswim:mergeDebugResources': SUCCESS, - ':penguinswim:mergeDebugShaders': FROM_CACHE, - ':penguinswim:mergeExtDexDebug': FROM_CACHE, - ':penguinswim:mergeLibDexDebug': FROM_CACHE, - ':penguinswim:mergeProjectDexDebug': FROM_CACHE, - ':penguinswim:packageDebug': SUCCESS, - ':penguinswim:preBuild': UP_TO_DATE, - ':penguinswim:preDebugBuild': UP_TO_DATE, - ':penguinswim:processDebugJavaRes': NO_SOURCE, - ':penguinswim:processDebugManifest': FROM_CACHE, - ':penguinswim:processDebugResources': SUCCESS, - ':penguinswim:stripDebugDebugSymbols': FROM_CACHE, - ':playgames:assembleDebug': SUCCESS, - ':playgames:bundleDebugAar': SUCCESS, - ':playgames:bundleLibCompileDebug': FROM_CACHE, - ':playgames:bundleLibResDebug': FROM_CACHE, - ':playgames:bundleLibRuntimeDebug': FROM_CACHE, - ':playgames:compileDebugAidl': NO_SOURCE, - ':playgames:compileDebugJavaWithJavac': FROM_CACHE, - ':playgames:compileDebugLibraryResources': SUCCESS, - ':playgames:compileDebugRenderscript': NO_SOURCE, - ':playgames:compileDebugShaders': NO_SOURCE, - ':playgames:compileDebugSources': UP_TO_DATE, - ':playgames:copyDebugJniLibsProjectAndLocalJars': FROM_CACHE, - ':playgames:copyDebugJniLibsProjectOnly': FROM_CACHE, - ':playgames:createFullJarDebug': FROM_CACHE, - ':playgames:extractDebugAnnotations': FROM_CACHE, - ':playgames:extractDeepLinksDebug': FROM_CACHE, - ':playgames:generateDebugAssets': UP_TO_DATE, - ':playgames:generateDebugBuildConfig': FROM_CACHE, - ':playgames:generateDebugRFile': FROM_CACHE, - ':playgames:generateDebugResValues': FROM_CACHE, - ':playgames:generateDebugResources': UP_TO_DATE, - ':playgames:javaPreCompileDebug': FROM_CACHE, - ':playgames:mergeDebugConsumerProguardFiles': FROM_CACHE, - ':playgames:mergeDebugGeneratedProguardFiles': FROM_CACHE, - ':playgames:mergeDebugJavaResource': FROM_CACHE, - ':playgames:mergeDebugJniLibFolders': FROM_CACHE, - ':playgames:mergeDebugNativeLibs': FROM_CACHE, - ':playgames:mergeDebugShaders': FROM_CACHE, - ':playgames:packageDebugAssets': FROM_CACHE, - ':playgames:packageDebugRenderscript': NO_SOURCE, - ':playgames:packageDebugResources': FROM_CACHE, - ':playgames:parseDebugLocalResources': FROM_CACHE, - ':playgames:preBuild': UP_TO_DATE, - ':playgames:preDebugBuild': UP_TO_DATE, - ':playgames:prepareLintJarForPublish': SUCCESS, - ':playgames:processDebugJavaRes': NO_SOURCE, - ':playgames:processDebugManifest': FROM_CACHE, - ':playgames:stripDebugDebugSymbols': FROM_CACHE, - ':playgames:syncDebugLibJars': FROM_CACHE, - ':presenttoss:assembleDebug': SUCCESS, - ':presenttoss:checkDebugDuplicateClasses': FROM_CACHE, - ':presenttoss:compileDebugAidl': NO_SOURCE, - ':presenttoss:compileDebugJavaWithJavac': FROM_CACHE, - ':presenttoss:compileDebugRenderscript': NO_SOURCE, - ':presenttoss:compileDebugShaders': NO_SOURCE, - ':presenttoss:compileDebugSources': UP_TO_DATE, - ':presenttoss:createDebugCompatibleScreenManifests': FROM_CACHE, - ':presenttoss:dexBuilderDebug': FROM_CACHE, - ':presenttoss:extractDeepLinksDebug': FROM_CACHE, - ':presenttoss:featureDebugWriter': SUCCESS, - ':presenttoss:generateDebugAssets': UP_TO_DATE, - ':presenttoss:generateDebugBuildConfig': FROM_CACHE, - ':presenttoss:generateDebugFeatureTransitiveDeps': FROM_CACHE, - ':presenttoss:generateDebugResValues': FROM_CACHE, - ':presenttoss:generateDebugResources': UP_TO_DATE, - ':presenttoss:javaPreCompileDebug': FROM_CACHE, - ':presenttoss:mergeDebugAssets': FROM_CACHE, - ':presenttoss:mergeDebugJavaResource': FROM_CACHE, - ':presenttoss:mergeDebugJniLibFolders': FROM_CACHE, - ':presenttoss:mergeDebugNativeLibs': FROM_CACHE, - ':presenttoss:mergeDebugResources': SUCCESS, - ':presenttoss:mergeDebugShaders': FROM_CACHE, - ':presenttoss:mergeExtDexDebug': FROM_CACHE, - ':presenttoss:mergeLibDexDebug': FROM_CACHE, - ':presenttoss:mergeProjectDexDebug': FROM_CACHE, - ':presenttoss:packageDebug': SUCCESS, - ':presenttoss:preBuild': UP_TO_DATE, - ':presenttoss:preDebugBuild': UP_TO_DATE, - ':presenttoss:processDebugJavaRes': NO_SOURCE, - ':presenttoss:processDebugManifest': FROM_CACHE, - ':presenttoss:processDebugResources': SUCCESS, - ':presenttoss:stripDebugDebugSymbols': FROM_CACHE, - ':rocketsleigh:assembleDebug': SUCCESS, - ':rocketsleigh:checkDebugDuplicateClasses': FROM_CACHE, - ':rocketsleigh:compileDebugAidl': NO_SOURCE, - ':rocketsleigh:compileDebugJavaWithJavac': FROM_CACHE, - ':rocketsleigh:compileDebugKotlin': FROM_CACHE, - ':rocketsleigh:compileDebugRenderscript': NO_SOURCE, - ':rocketsleigh:compileDebugShaders': NO_SOURCE, - ':rocketsleigh:compileDebugSources': UP_TO_DATE, - ':rocketsleigh:createDebugCompatibleScreenManifests': FROM_CACHE, - ':rocketsleigh:dexBuilderDebug': FROM_CACHE, - ':rocketsleigh:extractDeepLinksDebug': FROM_CACHE, - ':rocketsleigh:featureDebugWriter': SUCCESS, - ':rocketsleigh:generateDebugAssets': UP_TO_DATE, - ':rocketsleigh:generateDebugBuildConfig': FROM_CACHE, - ':rocketsleigh:generateDebugFeatureTransitiveDeps': FROM_CACHE, - ':rocketsleigh:generateDebugResValues': FROM_CACHE, - ':rocketsleigh:generateDebugResources': UP_TO_DATE, - ':rocketsleigh:javaPreCompileDebug': FROM_CACHE, - ':rocketsleigh:mergeDebugAssets': FROM_CACHE, - ':rocketsleigh:mergeDebugJavaResource': SUCCESS, - ':rocketsleigh:mergeDebugJniLibFolders': FROM_CACHE, - ':rocketsleigh:mergeDebugNativeLibs': FROM_CACHE, - ':rocketsleigh:mergeDebugResources': SUCCESS, - ':rocketsleigh:mergeDebugShaders': FROM_CACHE, - ':rocketsleigh:mergeExtDexDebug': FROM_CACHE, - ':rocketsleigh:mergeLibDexDebug': FROM_CACHE, - ':rocketsleigh:mergeProjectDexDebug': FROM_CACHE, - ':rocketsleigh:packageDebug': SUCCESS, - ':rocketsleigh:preBuild': UP_TO_DATE, - ':rocketsleigh:preDebugBuild': UP_TO_DATE, - ':rocketsleigh:processDebugJavaRes': NO_SOURCE, - ':rocketsleigh:processDebugManifest': FROM_CACHE, - ':rocketsleigh:processDebugResources': SUCCESS, - ':rocketsleigh:stripDebugDebugSymbols': FROM_CACHE, - ':santa-tracker:assembleDebug': SUCCESS, - ':santa-tracker:bundleDebugClasses': FROM_CACHE, - ':santa-tracker:checkDebugDuplicateClasses': FROM_CACHE, - ':santa-tracker:checkDebugLibraries': FROM_CACHE, - ':santa-tracker:compileDebugAidl': NO_SOURCE, - ':santa-tracker:compileDebugJavaWithJavac': FROM_CACHE, - ':santa-tracker:compileDebugKotlin': FROM_CACHE, - ':santa-tracker:compileDebugRenderscript': NO_SOURCE, - ':santa-tracker:compileDebugShaders': NO_SOURCE, - ':santa-tracker:compileDebugSources': UP_TO_DATE, - ':santa-tracker:createDebugCompatibleScreenManifests': FROM_CACHE, - ':santa-tracker:dexBuilderDebug': FROM_CACHE, - ':santa-tracker:extractDeepLinksDebug': FROM_CACHE, - ':santa-tracker:generateDebugAssets': UP_TO_DATE, - ':santa-tracker:generateDebugBuildConfig': FROM_CACHE, - ':santa-tracker:generateDebugFeatureMetadata': FROM_CACHE, - ':santa-tracker:generateDebugFeatureTransitiveDeps': FROM_CACHE, - ':santa-tracker:generateDebugResValues': FROM_CACHE, - ':santa-tracker:generateDebugResources': UP_TO_DATE, - ':santa-tracker:handleDebugMicroApk': FROM_CACHE, - ':santa-tracker:javaPreCompileDebug': FROM_CACHE, - ':santa-tracker:kaptDebugKotlin': SUCCESS, - ':santa-tracker:kaptGenerateStubsDebugKotlin': FROM_CACHE, - ':santa-tracker:mergeDebugAssets': FROM_CACHE, - ':santa-tracker:mergeDebugJavaResource': SUCCESS, - ':santa-tracker:mergeDebugJniLibFolders': FROM_CACHE, - ':santa-tracker:mergeDebugNativeLibs': FROM_CACHE, - ':santa-tracker:mergeDebugResources': SUCCESS, - ':santa-tracker:mergeDebugShaders': FROM_CACHE, - ':santa-tracker:mergeExtDexDebug': FROM_CACHE, - ':santa-tracker:mergeLibDexDebug': FROM_CACHE, - ':santa-tracker:mergeProjectDexDebug': FROM_CACHE, - ':santa-tracker:packageDebug': SUCCESS, - ':santa-tracker:preBuild': UP_TO_DATE, - ':santa-tracker:preDebugBuild': FROM_CACHE, - ':santa-tracker:processDebugJavaRes': NO_SOURCE, - ':santa-tracker:processDebugManifest': FROM_CACHE, - ':santa-tracker:processDebugResources': SUCCESS, - ':santa-tracker:signingConfigWriterDebug': FROM_CACHE, - ':santa-tracker:stripDebugDebugSymbols': FROM_CACHE, - ':santa-tracker:validateSigningDebug': FROM_CACHE, - ':santa-tracker:writeDebugModuleMetadata': SUCCESS, - ':snowballrun:assembleDebug': SUCCESS, - ':snowballrun:checkDebugDuplicateClasses': FROM_CACHE, - ':snowballrun:compileDebugAidl': NO_SOURCE, - ':snowballrun:compileDebugJavaWithJavac': FROM_CACHE, - ':snowballrun:compileDebugRenderscript': NO_SOURCE, - ':snowballrun:compileDebugShaders': NO_SOURCE, - ':snowballrun:compileDebugSources': UP_TO_DATE, - ':snowballrun:createDebugCompatibleScreenManifests': FROM_CACHE, - ':snowballrun:dexBuilderDebug': FROM_CACHE, - ':snowballrun:extractDeepLinksDebug': FROM_CACHE, - ':snowballrun:featureDebugWriter': SUCCESS, - ':snowballrun:generateDebugAssets': UP_TO_DATE, - ':snowballrun:generateDebugBuildConfig': FROM_CACHE, - ':snowballrun:generateDebugFeatureTransitiveDeps': FROM_CACHE, - ':snowballrun:generateDebugResValues': FROM_CACHE, - ':snowballrun:generateDebugResources': UP_TO_DATE, - ':snowballrun:javaPreCompileDebug': FROM_CACHE, - ':snowballrun:mergeDebugAssets': FROM_CACHE, - ':snowballrun:mergeDebugJavaResource': FROM_CACHE, - ':snowballrun:mergeDebugJniLibFolders': FROM_CACHE, - ':snowballrun:mergeDebugNativeLibs': FROM_CACHE, - ':snowballrun:mergeDebugResources': SUCCESS, - ':snowballrun:mergeDebugShaders': FROM_CACHE, - ':snowballrun:mergeExtDexDebug': FROM_CACHE, - ':snowballrun:mergeLibDexDebug': FROM_CACHE, - ':snowballrun:mergeProjectDexDebug': FROM_CACHE, - ':snowballrun:packageDebug': SUCCESS, - ':snowballrun:preBuild': UP_TO_DATE, - ':snowballrun:preDebugBuild': UP_TO_DATE, - ':snowballrun:processDebugJavaRes': NO_SOURCE, - ':snowballrun:processDebugManifest': FROM_CACHE, - ':snowballrun:processDebugResources': SUCCESS, - ':snowballrun:stripDebugDebugSymbols': FROM_CACHE, - ':tracker:assembleDebug': SUCCESS, - ':tracker:bundleDebugAar': SUCCESS, - ':tracker:bundleLibCompileDebug': FROM_CACHE, - ':tracker:bundleLibResDebug': FROM_CACHE, - ':tracker:bundleLibRuntimeDebug': FROM_CACHE, - ':tracker:compileDebugAidl': NO_SOURCE, - ':tracker:compileDebugJavaWithJavac': SUCCESS, - ':tracker:compileDebugKotlin': FROM_CACHE, - ':tracker:compileDebugLibraryResources': SUCCESS, - ':tracker:compileDebugRenderscript': NO_SOURCE, - ':tracker:compileDebugShaders': NO_SOURCE, - ':tracker:compileDebugSources': SUCCESS, - ':tracker:copyDebugJniLibsProjectAndLocalJars': FROM_CACHE, - ':tracker:copyDebugJniLibsProjectOnly': FROM_CACHE, - ':tracker:createFullJarDebug': FROM_CACHE, - ':tracker:extractDebugAnnotations': FROM_CACHE, - ':tracker:extractDeepLinksDebug': FROM_CACHE, - ':tracker:generateDebugAssets': UP_TO_DATE, - ':tracker:generateDebugBuildConfig': FROM_CACHE, - ':tracker:generateDebugRFile': FROM_CACHE, - ':tracker:generateDebugResValues': FROM_CACHE, - ':tracker:generateDebugResources': UP_TO_DATE, - ':tracker:javaPreCompileDebug': FROM_CACHE, - ':tracker:kaptDebugKotlin': SUCCESS, - ':tracker:kaptGenerateStubsDebugKotlin': SUCCESS, - ':tracker:mergeDebugConsumerProguardFiles': FROM_CACHE, - ':tracker:mergeDebugGeneratedProguardFiles': FROM_CACHE, - ':tracker:mergeDebugJavaResource': SUCCESS, - ':tracker:mergeDebugJniLibFolders': FROM_CACHE, - ':tracker:mergeDebugNativeLibs': FROM_CACHE, - ':tracker:mergeDebugResources': FROM_CACHE, - ':tracker:mergeDebugShaders': FROM_CACHE, - ':tracker:packageDebugAssets': FROM_CACHE, - ':tracker:packageDebugRenderscript': NO_SOURCE, - ':tracker:packageDebugResources': FROM_CACHE, - ':tracker:parseDebugLocalResources': FROM_CACHE, - ':tracker:preBuild': UP_TO_DATE, - ':tracker:preDebugBuild': UP_TO_DATE, - ':tracker:prepareLintJarForPublish': SUCCESS, - ':tracker:processDebugJavaRes': NO_SOURCE, - ':tracker:processDebugManifest': FROM_CACHE, - ':tracker:stripDebugDebugSymbols': FROM_CACHE, - ':tracker:syncDebugLibJars': SUCCESS, - ':wearable:assembleDebug': SUCCESS, - ':wearable:checkDebugDuplicateClasses': FROM_CACHE, - ':wearable:compileDebugAidl': NO_SOURCE, - ':wearable:compileDebugJavaWithJavac': FROM_CACHE, - ':wearable:compileDebugKotlin': FROM_CACHE, - ':wearable:compileDebugRenderscript': NO_SOURCE, - ':wearable:compileDebugShaders': NO_SOURCE, - ':wearable:compileDebugSources': UP_TO_DATE, - ':wearable:createDebugCompatibleScreenManifests': FROM_CACHE, - ':wearable:dexBuilderDebug': FROM_CACHE, - ':wearable:extractDeepLinksDebug': FROM_CACHE, - ':wearable:generateDebugAssets': UP_TO_DATE, - ':wearable:generateDebugBuildConfig': FROM_CACHE, - ':wearable:generateDebugResValues': FROM_CACHE, - ':wearable:generateDebugResources': UP_TO_DATE, - ':wearable:javaPreCompileDebug': FROM_CACHE, - ':wearable:kaptDebugKotlin': SUCCESS, - ':wearable:kaptGenerateStubsDebugKotlin': FROM_CACHE, - ':wearable:mergeDebugAssets': FROM_CACHE, - ':wearable:mergeDebugJavaResource': SUCCESS, - ':wearable:mergeDebugJniLibFolders': FROM_CACHE, - ':wearable:mergeDebugNativeLibs': FROM_CACHE, - ':wearable:mergeDebugResources': SUCCESS, - ':wearable:mergeDebugShaders': FROM_CACHE, - ':wearable:mergeExtDexDebug': FROM_CACHE, - ':wearable:mergeLibDexDebug': FROM_CACHE, - ':wearable:mergeProjectDexDebug': FROM_CACHE, - ':wearable:packageDebug': SUCCESS, - ':wearable:preBuild': UP_TO_DATE, - ':wearable:preDebugBuild': UP_TO_DATE, - ':wearable:processDebugJavaRes': NO_SOURCE, - ':wearable:processDebugManifest': FROM_CACHE, - ':wearable:processDebugResources': SUCCESS, - ':wearable:stripDebugDebugSymbols': FROM_CACHE, - ':wearable:validateSigningDebug': FROM_CACHE, - ] - private static final EXPECTED_RESULTS_3_6 = [ ':cityquiz:assembleDebug': SUCCESS, ':cityquiz:checkDebugDuplicateClasses': FROM_CACHE, From 8c4ff94a86f76f6f6572c3b9bde10b45c32a02b4 Mon Sep 17 00:00:00 2001 From: Paul Merlin Date: Wed, 22 Jan 2020 14:13:01 +0100 Subject: [PATCH 28/39] Remove now duplicated android tests from :instantExecution Signed-off-by: Paul Merlin --- .../instant-execution.gradle.kts | 41 --------- ...tantExecutionAndroidIntegrationTest.groovy | 54 ------------ ...xecutionSantaTrackerIntegrationTest.groovy | 83 ------------------- subprojects/smoke-test/smoke-test.gradle.kts | 1 - 4 files changed, 179 deletions(-) delete mode 100644 subprojects/instant-execution/src/integTest/groovy/org/gradle/instantexecution/AbstractInstantExecutionAndroidIntegrationTest.groovy delete mode 100644 subprojects/instant-execution/src/integTest/groovy/org/gradle/instantexecution/InstantExecutionSantaTrackerIntegrationTest.groovy diff --git a/subprojects/instant-execution/instant-execution.gradle.kts b/subprojects/instant-execution/instant-execution.gradle.kts index d55f2f094932..cd9d58038798 100644 --- a/subprojects/instant-execution/instant-execution.gradle.kts +++ b/subprojects/instant-execution/instant-execution.gradle.kts @@ -1,8 +1,5 @@ import build.futureKotlin -import org.gradle.gradlebuild.BuildEnvironment -import org.gradle.gradlebuild.test.integrationtests.IntegrationTest import org.gradle.gradlebuild.unittestandcompile.ModuleType -import org.gradle.testing.performance.generator.tasks.RemoteProject plugins { `kotlin-library` @@ -71,44 +68,6 @@ gradlebuildJava { tasks { - - /** - * Santa Tracker git URI. - * - * Note that you can change it to `file:///path/to/your/santa-tracker-clone/.git` - * if you need to iterate quickly on changes to Santa Tracker. - */ - val gitUri = "https://github.com/gradle/santa-tracker-android.git" - - val santaTrackerJava by registering(RemoteProject::class) { - remoteUri.set(gitUri) - // From agp-3.6.0-java branch - ref.set("174705275e434adc843e8e9b28106a5e3ffd6733") - } - - val santaTrackerKotlin by registering(RemoteProject::class) { - remoteUri.set(gitUri) - // From agp-3.6.0 branch - ref.set("3bbbd895de38efafd0dd1789454d4e4cb72d46d5") - } - - if (BuildEnvironment.isCiServer) { - withType().configureEach { - outputs.upToDateWhen { false } - } - } - - withType().configureEach { - dependsOn(santaTrackerJava) - dependsOn(santaTrackerKotlin) - inputs.property("androidHomeIsSet", System.getenv("ANDROID_HOME") != null) - } - - register("cleanRemoteProjects") { - delete(santaTrackerJava.get().outputDirectory) - delete(santaTrackerKotlin.get().outputDirectory) - } - instantIntegTest { enabled = false } diff --git a/subprojects/instant-execution/src/integTest/groovy/org/gradle/instantexecution/AbstractInstantExecutionAndroidIntegrationTest.groovy b/subprojects/instant-execution/src/integTest/groovy/org/gradle/instantexecution/AbstractInstantExecutionAndroidIntegrationTest.groovy deleted file mode 100644 index 91c0394e8da2..000000000000 --- a/subprojects/instant-execution/src/integTest/groovy/org/gradle/instantexecution/AbstractInstantExecutionAndroidIntegrationTest.groovy +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright 2019 the original author or authors. - * - * 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.gradle.instantexecution - -import groovy.transform.CompileStatic -import org.gradle.integtests.fixtures.android.AndroidHome -import org.gradle.integtests.fixtures.versions.AndroidGradlePluginVersions -import org.gradle.internal.scan.config.fixtures.GradleEnterprisePluginSettingsFixture -import org.gradle.test.fixtures.file.TestFile - -import static org.gradle.integtests.fixtures.versions.AndroidGradlePluginVersions.usingAgpVersion - - -/** - * Base Android / Instant execution integration test. - */ -@CompileStatic -abstract class AbstractInstantExecutionAndroidIntegrationTest extends AbstractInstantExecutionIntegrationTest { - - private static final AndroidGradlePluginVersions AGP_VERSIONS = new AndroidGradlePluginVersions() - - protected static final List TESTED_AGP_VERSIONS = AGP_VERSIONS.getLatestsFromMinorPlusNightly("4.0") - - def setup() { - AndroidHome.assumeIsSet() - } - - void copyRemoteProject(String remoteProject) { - new TestFile(new File("build/$remoteProject")).copyTo(testDirectory) - GradleEnterprisePluginSettingsFixture.applyEnterprisePlugin(settingsFile) - } - - void usingAgpVersion(String agpVersion) { - usingAgpVersion(executer, buildFile, agpVersion) - } - - void usingAgpVersion(TestFile buildFile, String agpVersion) { - usingAgpVersion(executer, buildFile, agpVersion) - } -} diff --git a/subprojects/instant-execution/src/integTest/groovy/org/gradle/instantexecution/InstantExecutionSantaTrackerIntegrationTest.groovy b/subprojects/instant-execution/src/integTest/groovy/org/gradle/instantexecution/InstantExecutionSantaTrackerIntegrationTest.groovy deleted file mode 100644 index 38ca3c009dd0..000000000000 --- a/subprojects/instant-execution/src/integTest/groovy/org/gradle/instantexecution/InstantExecutionSantaTrackerIntegrationTest.groovy +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright 2019 the original author or authors. - * - * 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.gradle.instantexecution - -import org.gradle.test.fixtures.file.LeaksFileHandles -import spock.lang.Unroll - - -/** - * Integration test Santa Tracker android app against AGP nightly. - */ -@LeaksFileHandles("TODO: AGP (intentionally) does not get a ‘build finished’ event and so does not close some files") -class InstantExecutionSantaTrackerIntegrationTest extends AbstractInstantExecutionAndroidIntegrationTest { - - def setup() { - executer.beforeExecute { - executer.noDeprecationChecks() - executer.withRepositoryMirrors() - } - } - - @Unroll - def "assembleDebug up-to-date on #remoteProject (agp=#agpVersion, fromIde=#fromIde)"() { - - given: - copyRemoteProject(remoteProject) - usingAgpVersion(agpVersion) - - when: - instantRun("assembleDebug", "--no-build-cache", "-Pandroid.injected.invoked.from.ide=$fromIde") - - then: - instantRun("assembleDebug", "--no-build-cache", "-Pandroid.injected.invoked.from.ide=$fromIde") - - where: - [remoteProject, agpVersion, fromIde] << [ - // TODO:instant-execution Kotlin 1.3.70 - ["santaTrackerJava" /*, "santaTrackerKotlin" */], - TESTED_AGP_VERSIONS, - [false, true] - ].combinations() - } - - @Unroll - def "clean assembleDebug on #remoteProject (agp=#agpVersion, fromIde=#fromIde)"() { - - given: - copyRemoteProject(remoteProject) - usingAgpVersion(agpVersion) - - when: - instantRun("assembleDebug", "--no-build-cache", "-Pandroid.injected.invoked.from.ide=$fromIde") - - and: - run 'clean' - - then: - // Instant execution avoid registering the listener inside Android plugin - instantRun("assembleDebug", "--no-build-cache", "-Pandroid.injected.invoked.from.ide=$fromIde") - - where: - [remoteProject, agpVersion, fromIde] << [ - // TODO:instant-execution Kotlin 1.3.70 - ["santaTrackerJava" /*, "santaTrackerKotlin" */], - TESTED_AGP_VERSIONS, - [false, true] - ].combinations() - } -} diff --git a/subprojects/smoke-test/smoke-test.gradle.kts b/subprojects/smoke-test/smoke-test.gradle.kts index 81cff6d091ae..b7b04dd3325e 100644 --- a/subprojects/smoke-test/smoke-test.gradle.kts +++ b/subprojects/smoke-test/smoke-test.gradle.kts @@ -110,7 +110,6 @@ plugins.withType().configureEach { } } -// TODO Copied from instant-execution.gradle.kts, we should have one place to clone this thing and clone it from there locally when needed tasks { /** From eb06195ac742d78181322b2659e2056ffad47c73 Mon Sep 17 00:00:00 2001 From: Paul Merlin Date: Wed, 22 Jan 2020 14:23:09 +0100 Subject: [PATCH 29/39] Polish build scripts Signed-off-by: Paul Merlin --- subprojects/performance/templates.gradle | 4 +--- subprojects/smoke-test/smoke-test.gradle.kts | 4 ++-- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/subprojects/performance/templates.gradle b/subprojects/performance/templates.gradle index d007a4d9903a..2d6d0c2700b7 100644 --- a/subprojects/performance/templates.gradle +++ b/subprojects/performance/templates.gradle @@ -359,9 +359,7 @@ tasks.register("largeAndroidBuild", RemoteProject) { tasks.register("santaTrackerAndroidBuild", RemoteProject) { remoteUri = 'https://github.com/gradle/santa-tracker-android.git' - // branch agp-3.6.0 - // with AGP 3.6.0-beta-04 - // without licenses plugin + // Pinned from branch agp-3.6.0 ref = '3bbbd895de38efafd0dd1789454d4e4cb72d46d5' doLast { addGoogleServicesJson(outputDirectory) diff --git a/subprojects/smoke-test/smoke-test.gradle.kts b/subprojects/smoke-test/smoke-test.gradle.kts index b7b04dd3325e..eeb91f92fc7b 100644 --- a/subprojects/smoke-test/smoke-test.gradle.kts +++ b/subprojects/smoke-test/smoke-test.gradle.kts @@ -122,13 +122,13 @@ tasks { register("santaTrackerKotlin") { remoteUri.set(santaGitUri) - // From branch agp-3.6.0 + // Pinned from branch agp-3.6.0 ref.set("3bbbd895de38efafd0dd1789454d4e4cb72d46d5") } register("santaTrackerJava") { remoteUri.set(santaGitUri) - // From agp-3.6.0-java branch + // Pinned from branch agp-3.6.0-java ref.set("174705275e434adc843e8e9b28106a5e3ffd6733") } From b7c69a93b17607ef688e122d476156ce5aa6ee05 Mon Sep 17 00:00:00 2001 From: Paul Merlin Date: Wed, 22 Jan 2020 14:49:47 +0100 Subject: [PATCH 30/39] Drop incremental Java compilation works for Santa Tracker Kotlin test keeping the one using the Java variant of Santa Tracker in order to lower the number of tests and shorten the CI feedback loop Signed-off-by: Paul Merlin --- .../AndroidSantaTrackerSmokeTest.groovy | 36 ------------------- 1 file changed, 36 deletions(-) diff --git a/subprojects/smoke-test/src/smokeTest/groovy/org/gradle/smoketests/AndroidSantaTrackerSmokeTest.groovy b/subprojects/smoke-test/src/smokeTest/groovy/org/gradle/smoketests/AndroidSantaTrackerSmokeTest.groovy index 4ebdc7e32237..9fa4932e73a7 100644 --- a/subprojects/smoke-test/src/smokeTest/groovy/org/gradle/smoketests/AndroidSantaTrackerSmokeTest.groovy +++ b/subprojects/smoke-test/src/smokeTest/groovy/org/gradle/smoketests/AndroidSantaTrackerSmokeTest.groovy @@ -90,42 +90,6 @@ class AndroidSantaTrackerSmokeTest extends AbstractAndroidSantaTrackerSmokeTest agpVersion << TESTED_AGP_VERSIONS } - @Unroll - @ToBeFixedForInstantExecution - def "incremental Java compilation works for Santa Tracker Kotlin (agp=#agpVersion)"() { - - given: - def checkoutDir = temporaryFolder.createDir("checkout") - setupCopyOfSantaTracker(checkoutDir, 'Kotlin', agpVersion) - - and: - def pathToClass = "com/google/android/apps/santatracker/tracker/ui/BottomSheetBehavior" - def fileToChange = checkoutDir.file("tracker/src/main/java/${pathToClass}.java") - def compiledClassFile = checkoutDir.file("tracker/build/intermediates/javac/debug/classes/${pathToClass}.class") - def nonAbiChangeMutator = new ApplyNonAbiChangeToJavaSourceFileMutator(fileToChange) - - when: - def result = buildLocation(checkoutDir, agpVersion) - def md5Before = compiledClassFile.md5Hash - - then: - result.task(":tracker:compileDebugJavaWithJavac").outcome == SUCCESS - assertInstantExecutionStateStored() - - when: - nonAbiChangeMutator.beforeBuild() - buildLocation(checkoutDir, agpVersion) - def md5After = compiledClassFile.md5Hash - - then: - result.task(":tracker:compileDebugJavaWithJavac").outcome == SUCCESS - assertInstantExecutionStateLoaded() - md5After != md5Before - - where: - agpVersion << TESTED_AGP_VERSIONS - } - @Unroll @UnsupportedWithInstantExecution(iterationMatchers = AGP_3_ITERATION_MATCHER) def "incremental Java compilation works for Santa Tracker Java (agp=#agpVersion)"() { From 61909e597d5c1f21a4a3935bcc217e7a116e45fc Mon Sep 17 00:00:00 2001 From: Paul Merlin Date: Wed, 22 Jan 2020 14:57:55 +0100 Subject: [PATCH 31/39] Drop Santa Tracker Kotlin deprecation warnings test keeping the one using the Java variant of Santa Tracker and KotlinPluginSmokeTest already assert on deprecations emited by the kotlin plugin in order to lower the number of tests and shorten the CI feedback loop Signed-off-by: Paul Merlin --- .../AndroidSantaTrackerSmokeTest.groovy | 37 ------------------- 1 file changed, 37 deletions(-) diff --git a/subprojects/smoke-test/src/smokeTest/groovy/org/gradle/smoketests/AndroidSantaTrackerSmokeTest.groovy b/subprojects/smoke-test/src/smokeTest/groovy/org/gradle/smoketests/AndroidSantaTrackerSmokeTest.groovy index 9fa4932e73a7..fe0c5001e91a 100644 --- a/subprojects/smoke-test/src/smokeTest/groovy/org/gradle/smoketests/AndroidSantaTrackerSmokeTest.groovy +++ b/subprojects/smoke-test/src/smokeTest/groovy/org/gradle/smoketests/AndroidSantaTrackerSmokeTest.groovy @@ -16,10 +16,8 @@ package org.gradle.smoketests -import org.gradle.integtests.fixtures.ToBeFixedForInstantExecution import org.gradle.integtests.fixtures.UnsupportedWithInstantExecution import org.gradle.profiler.mutations.ApplyNonAbiChangeToJavaSourceFileMutator -import org.gradle.util.GradleVersion import org.gradle.util.Requires import org.gradle.util.TestPrecondition import spock.lang.Unroll @@ -30,41 +28,6 @@ import static org.gradle.testkit.runner.TaskOutcome.SUCCESS @Requires(TestPrecondition.JDK11_OR_EARLIER) class AndroidSantaTrackerSmokeTest extends AbstractAndroidSantaTrackerSmokeTest { - @Unroll - @ToBeFixedForInstantExecution - def "check deprecation warnings produced by building Santa Tracker Kotlin (agp=#agpVersion)"() { - - given: - def checkoutDir = temporaryFolder.createDir("checkout") - setupCopyOfSantaTracker(checkoutDir, 'Kotlin', agpVersion) - - when: - def result = buildLocation(checkoutDir, agpVersion) - - then: - expectDeprecationWarnings(result, - "The configuration :detachedConfiguration1 was resolved without accessing the project in a safe manner. This may happen when a configuration is resolved from a different project. This behaviour has been deprecated and is scheduled to be removed in Gradle 7.0. See https://docs.gradle.org/${GradleVersion.current().version}/userguide/viewing_debugging_dependencies.html#sub:resolving-unsafe-configuration-resolution-errors for more details.", - "The configuration :detachedConfiguration10 was resolved without accessing the project in a safe manner. This may happen when a configuration is resolved from a different project. This behaviour has been deprecated and is scheduled to be removed in Gradle 7.0. See https://docs.gradle.org/${GradleVersion.current().version}/userguide/viewing_debugging_dependencies.html#sub:resolving-unsafe-configuration-resolution-errors for more details.", - "The configuration :detachedConfiguration11 was resolved without accessing the project in a safe manner. This may happen when a configuration is resolved from a different project. This behaviour has been deprecated and is scheduled to be removed in Gradle 7.0. See https://docs.gradle.org/${GradleVersion.current().version}/userguide/viewing_debugging_dependencies.html#sub:resolving-unsafe-configuration-resolution-errors for more details.", - "The configuration :detachedConfiguration12 was resolved without accessing the project in a safe manner. This may happen when a configuration is resolved from a different project. This behaviour has been deprecated and is scheduled to be removed in Gradle 7.0. See https://docs.gradle.org/${GradleVersion.current().version}/userguide/viewing_debugging_dependencies.html#sub:resolving-unsafe-configuration-resolution-errors for more details.", - "The configuration :detachedConfiguration13 was resolved without accessing the project in a safe manner. This may happen when a configuration is resolved from a different project. This behaviour has been deprecated and is scheduled to be removed in Gradle 7.0. See https://docs.gradle.org/${GradleVersion.current().version}/userguide/viewing_debugging_dependencies.html#sub:resolving-unsafe-configuration-resolution-errors for more details.", - "The configuration :detachedConfiguration14 was resolved without accessing the project in a safe manner. This may happen when a configuration is resolved from a different project. This behaviour has been deprecated and is scheduled to be removed in Gradle 7.0. See https://docs.gradle.org/${GradleVersion.current().version}/userguide/viewing_debugging_dependencies.html#sub:resolving-unsafe-configuration-resolution-errors for more details.", - "The configuration :detachedConfiguration15 was resolved without accessing the project in a safe manner. This may happen when a configuration is resolved from a different project. This behaviour has been deprecated and is scheduled to be removed in Gradle 7.0. See https://docs.gradle.org/${GradleVersion.current().version}/userguide/viewing_debugging_dependencies.html#sub:resolving-unsafe-configuration-resolution-errors for more details.", - "The configuration :detachedConfiguration2 was resolved without accessing the project in a safe manner. This may happen when a configuration is resolved from a different project. This behaviour has been deprecated and is scheduled to be removed in Gradle 7.0. See https://docs.gradle.org/${GradleVersion.current().version}/userguide/viewing_debugging_dependencies.html#sub:resolving-unsafe-configuration-resolution-errors for more details.", - "The configuration :detachedConfiguration3 was resolved without accessing the project in a safe manner. This may happen when a configuration is resolved from a different project. This behaviour has been deprecated and is scheduled to be removed in Gradle 7.0. See https://docs.gradle.org/${GradleVersion.current().version}/userguide/viewing_debugging_dependencies.html#sub:resolving-unsafe-configuration-resolution-errors for more details.", - "The configuration :detachedConfiguration4 was resolved without accessing the project in a safe manner. This may happen when a configuration is resolved from a different project. This behaviour has been deprecated and is scheduled to be removed in Gradle 7.0. See https://docs.gradle.org/${GradleVersion.current().version}/userguide/viewing_debugging_dependencies.html#sub:resolving-unsafe-configuration-resolution-errors for more details.", - "The configuration :detachedConfiguration5 was resolved without accessing the project in a safe manner. This may happen when a configuration is resolved from a different project. This behaviour has been deprecated and is scheduled to be removed in Gradle 7.0. See https://docs.gradle.org/${GradleVersion.current().version}/userguide/viewing_debugging_dependencies.html#sub:resolving-unsafe-configuration-resolution-errors for more details.", - "The configuration :detachedConfiguration6 was resolved without accessing the project in a safe manner. This may happen when a configuration is resolved from a different project. This behaviour has been deprecated and is scheduled to be removed in Gradle 7.0. See https://docs.gradle.org/${GradleVersion.current().version}/userguide/viewing_debugging_dependencies.html#sub:resolving-unsafe-configuration-resolution-errors for more details.", - "The configuration :detachedConfiguration7 was resolved without accessing the project in a safe manner. This may happen when a configuration is resolved from a different project. This behaviour has been deprecated and is scheduled to be removed in Gradle 7.0. See https://docs.gradle.org/${GradleVersion.current().version}/userguide/viewing_debugging_dependencies.html#sub:resolving-unsafe-configuration-resolution-errors for more details.", - "The configuration :detachedConfiguration8 was resolved without accessing the project in a safe manner. This may happen when a configuration is resolved from a different project. This behaviour has been deprecated and is scheduled to be removed in Gradle 7.0. See https://docs.gradle.org/${GradleVersion.current().version}/userguide/viewing_debugging_dependencies.html#sub:resolving-unsafe-configuration-resolution-errors for more details.", - "The configuration :detachedConfiguration9 was resolved without accessing the project in a safe manner. This may happen when a configuration is resolved from a different project. This behaviour has been deprecated and is scheduled to be removed in Gradle 7.0. See https://docs.gradle.org/${GradleVersion.current().version}/userguide/viewing_debugging_dependencies.html#sub:resolving-unsafe-configuration-resolution-errors for more details.", - ) - assertInstantExecutionStateStored() - - where: - agpVersion << TESTED_AGP_VERSIONS - } - @Unroll @UnsupportedWithInstantExecution(iterationMatchers = AGP_3_ITERATION_MATCHER) def "check deprecation warnings produced by building Santa Tracker Java (agp=#agpVersion)"() { From 074a82b4a0854ed99114eec5f9a972f9045e4220 Mon Sep 17 00:00:00 2001 From: Cedric Champeau Date: Wed, 22 Jan 2020 12:03:20 +0100 Subject: [PATCH 32/39] Do not read the full file in-memory when computing checksums --- .../org/gradle/internal/hash/ChecksumHasher.java | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/subprojects/core/src/main/java/org/gradle/internal/hash/ChecksumHasher.java b/subprojects/core/src/main/java/org/gradle/internal/hash/ChecksumHasher.java index af73f7ae31a2..a3eddd7ad2b5 100644 --- a/subprojects/core/src/main/java/org/gradle/internal/hash/ChecksumHasher.java +++ b/subprojects/core/src/main/java/org/gradle/internal/hash/ChecksumHasher.java @@ -15,11 +15,12 @@ */ package org.gradle.internal.hash; -import com.google.common.io.Files; import org.gradle.api.UncheckedIOException; import java.io.File; +import java.io.FileInputStream; import java.io.IOException; +import java.io.InputStream; class ChecksumHasher implements FileHasher { @@ -32,7 +33,15 @@ public ChecksumHasher(HashFunction hashFunction) { @Override public HashCode hash(File file) { try { - return hashFunction.hashBytes(Files.toByteArray(file)); + PrimitiveHasher hasher = hashFunction.newPrimitiveHasher(); + byte[] buffer = new byte[4096]; + int len; + try (InputStream in = new FileInputStream(file)) { + while ((len = in.read(buffer)) >= 0) { + hasher.putBytes(buffer, 0, len); + } + } + return hasher.hash(); } catch (IOException e) { throw new UncheckedIOException(e); } From 8bcc1276cae6f1a0d6803ae18b9ae56447d26d04 Mon Sep 17 00:00:00 2001 From: Paul Merlin Date: Wed, 22 Jan 2020 16:49:45 +0100 Subject: [PATCH 33/39] Refine updateAgpVersions task Signed-off-by: Paul Merlin --- .../gradle/gradlebuild/UpdateAgpVersions.kt | 47 ++++++++++++------- 1 file changed, 30 insertions(+), 17 deletions(-) diff --git a/buildSrc/subprojects/plugins/src/main/kotlin/org/gradle/gradlebuild/UpdateAgpVersions.kt b/buildSrc/subprojects/plugins/src/main/kotlin/org/gradle/gradlebuild/UpdateAgpVersions.kt index 1d8ba33a4911..0d2e7044dfad 100644 --- a/buildSrc/subprojects/plugins/src/main/kotlin/org/gradle/gradlebuild/UpdateAgpVersions.kt +++ b/buildSrc/subprojects/plugins/src/main/kotlin/org/gradle/gradlebuild/UpdateAgpVersions.kt @@ -22,8 +22,9 @@ import org.gradle.api.provider.Property import org.gradle.api.tasks.Internal import org.gradle.api.tasks.TaskAction import org.gradle.build.ReproduciblePropertiesWriter -import org.jsoup.Jsoup +import org.w3c.dom.Element import java.util.Properties +import javax.xml.parsers.DocumentBuilderFactory /** @@ -44,22 +45,9 @@ abstract class UpdateAgpVersions : DefaultTask() { @TaskAction fun fetch() { - val minimumSupported = minimumSupportedMinor.get() - - val url = "https://mvnrepository.com/artifact/com.android.tools.build/gradle?repo=google" - val body = Jsoup.connect(url).get().body() - val minorSets = body.select("table.grid.versions tbody") - - var latests = minorSets.map { it.select("a.vbtn").first().text() } - latests = (latests + minimumSupported).sorted() - latests = latests.subList(latests.indexOf(minimumSupported) + 1, latests.size) - - val nightlyUrl = "https://repo.gradle.org/gradle/ext-snapshots-local/com/android/tools/build/gradle/" - val nightly = Jsoup.connect(nightlyUrl).get().body() - .select("a") - .last { it.text().matches(Regex("^[0-9].*")) } - .text().dropLast(1) - + val dbf = DocumentBuilderFactory.newInstance() + val latests = dbf.fetchLatests(minimumSupportedMinor.get()) + val nightly = dbf.fetchNightly() val properties = Properties().apply { setProperty("latests", latests.joinToString(",")) setProperty("nightly", nightly) @@ -70,4 +58,29 @@ abstract class UpdateAgpVersions : DefaultTask() { comment.get() ) } + + private + fun DocumentBuilderFactory.fetchLatests(minimumSupported: String): List { + var latests = fetchVersionsFromMavenMetadata("https://dl.google.com/dl/android/maven2/com/android/tools/build/gradle/maven-metadata.xml") + .groupBy { it.take(3) } + .map { (_, versions) -> versions.first() } + latests = (latests + minimumSupported).sorted() + latests = latests.subList(latests.indexOf(minimumSupported) + 1, latests.size) + return latests + } + + private + fun DocumentBuilderFactory.fetchNightly(): String = + fetchVersionsFromMavenMetadata("https://repo.gradle.org/gradle/ext-snapshots-local/com/android/tools/build/gradle/maven-metadata.xml") + .first() + + private + fun DocumentBuilderFactory.fetchVersionsFromMavenMetadata(url: String): List = + newDocumentBuilder() + .parse(url) + .getElementsByTagName("version").let { versions -> + (0 until versions.length) + .map { idx -> (versions.item(idx) as Element).textContent } + .reversed() + } } From f41bad97e4a88a1fb60e5566cdc455b156f25900 Mon Sep 17 00:00:00 2001 From: Gradleware Git Bot Date: Thu, 23 Jan 2020 01:17:51 +0100 Subject: [PATCH 34/39] Publish 6.1.1-20200123000143+0000 --- released-versions.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/released-versions.json b/released-versions.json index f84fa1d61480..1abe9bf41ee7 100644 --- a/released-versions.json +++ b/released-versions.json @@ -1,7 +1,7 @@ { "latestReleaseSnapshot": { - "version": "6.1.1-20200122000153+0000", - "buildTime": "20200122000153+0000" + "version": "6.1.1-20200123000143+0000", + "buildTime": "20200123000143+0000" }, "latestRc": { "version": "6.1-rc-3", From a7917e26e1138c61769fb71fafe1a656d43a90de Mon Sep 17 00:00:00 2001 From: Adam Murdoch Date: Sat, 4 Jan 2020 10:20:03 +1000 Subject: [PATCH 35/39] When a property has no value, include the chain of properties from which the value is derived in the error message. This is intended to help with diagnostics, as the user can see where the value should have come from. In this change, the diagnostics only works when `Property` instances are connected together directly, stopping at the first `Provider` which is not such a type. --- ...kDependencyInferenceIntegrationTest.groovy | 10 +- .../TaskPropertiesIntegrationTest.groovy | 52 +++---- .../DefaultNamedDomainObjectCollection.java | 4 +- .../internal/BuildServiceProvider.java | 4 +- .../AbstractElementSourceTest.groovy | 7 +- .../collections/ListElementSourceTest.groovy | 5 +- .../model/DefaultObjectFactoryTest.groovy | 2 +- .../file/DefaultFilePropertyFactory.java | 4 +- .../DefaultFilePropertyFactoryTest.groovy | 10 +- .../api/tasks/compile/AbstractCompile.java | 4 +- .../internal/DefaultBinaryCollection.java | 4 +- .../DefaultBinaryCollectionTest.groovy | 8 +- .../DefaultSwiftApplicationTest.groovy | 2 +- .../internal/DefaultSwiftLibraryTest.groovy | 2 +- .../internal/logging/text/TreeFormatter.java | 23 ++-- .../logging/text/TreeFormatterTest.groovy | 4 +- .../provider/PropertyIntegrationTest.groovy | 128 +++++++++++++----- .../provider/AbstractCombiningProvider.java | 2 +- .../provider/AbstractMinimalProvider.java | 27 ++-- .../internal/provider/DefaultMapProperty.java | 2 +- .../internal/provider/DefaultProperty.java | 54 +++++--- .../internal/provider/DefaultProvider.java | 2 +- .../DefaultValueSourceProviderFactory.java | 2 +- .../api/internal/provider/MapCollectors.java | 4 +- ...ovider.java => MissingValueException.java} | 23 ++-- .../api/internal/provider/Providers.java | 36 +++-- .../api/internal/provider/ScalarSupplier.java | 118 +++++++++++++++- .../provider/AbstractProviderTest.groovy | 4 +- .../provider/CollectionPropertySpec.groovy | 4 +- .../provider/DefaultPropertyTest.groovy | 8 +- .../provider/DefaultProviderTest.groovy | 4 +- .../api/internal/provider/PropertySpec.groovy | 16 +-- .../api/internal/provider/ProviderSpec.groovy | 12 +- ...aLibraryDistributionIntegrationTest.groovy | 2 +- .../DefaultArtifactPublicationSet.java | 4 +- 35 files changed, 402 insertions(+), 195 deletions(-) rename subprojects/model-core/src/main/java/org/gradle/api/internal/provider/{AbstractReadOnlyProvider.java => MissingValueException.java} (52%) diff --git a/subprojects/core/src/integTest/groovy/org/gradle/api/tasks/TaskDependencyInferenceIntegrationTest.groovy b/subprojects/core/src/integTest/groovy/org/gradle/api/tasks/TaskDependencyInferenceIntegrationTest.groovy index 0b3ee572f8e4..41319e038aad 100644 --- a/subprojects/core/src/integTest/groovy/org/gradle/api/tasks/TaskDependencyInferenceIntegrationTest.groovy +++ b/subprojects/core/src/integTest/groovy/org/gradle/api/tasks/TaskDependencyInferenceIntegrationTest.groovy @@ -113,7 +113,7 @@ class TaskDependencyInferenceIntegrationTest extends AbstractIntegrationSpec imp buildFile << """ def task = tasks.create("a", FileProducer) { output = file("a.txt") - } + } tasks.register("b") { dependsOn task.output.map { throw new RuntimeException() } } @@ -488,7 +488,7 @@ The following types/formats are supported: then: failure.assertHasDescription("Could not determine the dependencies of task ':a'.") - failure.assertHasCause("No value has been specified for this property.") + failure.assertHasCause("Cannot query the value of this property because it has no value available.") } def "input file collection containing task provider implies dependency on all outputs of the task"() { @@ -563,7 +563,7 @@ The following types/formats are supported: buildFile << """ def taskA = tasks.create("a", FileProducer) { output = file("a.txt") - content = "a" + content = "a" } def taskB = tasks.create("b", FileProducer) { output = file("b.txt") @@ -589,7 +589,7 @@ The following types/formats are supported: buildFile << """ def taskA = tasks.create("a", FileProducer) { output = file("a.txt") - content = "a" + content = "a" } tasks.register("c", InputFileTask) { inFile = taskA.output.orElse(file("b.txt")) @@ -779,7 +779,7 @@ The following types/formats are supported: } configurations { thing } dependencies { thing a.outputs.files } - + tasks.register("b", InputFilesTask) { inFiles.from configurations.named('thing') outFile = file("out.txt") diff --git a/subprojects/core/src/integTest/groovy/org/gradle/api/tasks/TaskPropertiesIntegrationTest.groovy b/subprojects/core/src/integTest/groovy/org/gradle/api/tasks/TaskPropertiesIntegrationTest.groovy index 7990b18702e3..95458094e59d 100644 --- a/subprojects/core/src/integTest/groovy/org/gradle/api/tasks/TaskPropertiesIntegrationTest.groovy +++ b/subprojects/core/src/integTest/groovy/org/gradle/api/tasks/TaskPropertiesIntegrationTest.groovy @@ -25,13 +25,13 @@ class TaskPropertiesIntegrationTest extends AbstractIntegrationSpec { abstract class MyTask extends DefaultTask { @Internal abstract Property getCount() - + @TaskAction void go() { println("count = \${count.get()}") } } - + tasks.create("thing", MyTask) { println("property = \$count") count = 12 @@ -52,13 +52,13 @@ class TaskPropertiesIntegrationTest extends AbstractIntegrationSpec { abstract class MyTask extends DefaultTask { @Internal abstract Property getCount() - + @TaskAction void go() { println("count = \${count.get()}") } } - + tasks.create("thing", MyTask) { } """ @@ -67,7 +67,7 @@ class TaskPropertiesIntegrationTest extends AbstractIntegrationSpec { fails("thing") then: - failure.assertHasCause("No value has been specified for task ':thing' property 'count'") + failure.assertHasCause("Cannot query the value of task ':thing' property 'count' because it has no value available.") } def "reports failure to query read-only unmanaged Property with final getter"() { @@ -76,13 +76,13 @@ class TaskPropertiesIntegrationTest extends AbstractIntegrationSpec { abstract class MyTask extends DefaultTask { @Internal final Property count = project.objects.property(Integer) - + @TaskAction void go() { println("count = \${count.get()}") } } - + tasks.create("thing", MyTask) { println("property = \$count") } @@ -93,7 +93,7 @@ class TaskPropertiesIntegrationTest extends AbstractIntegrationSpec { then: outputContains("property = task ':thing' property 'count'") - failure.assertHasCause("No value has been specified for task ':thing' property 'count'") + failure.assertHasCause("Cannot query the value of task ':thing' property 'count' because it has no value available.") } def "reports failure to query read-only unmanaged Property"() { @@ -105,7 +105,7 @@ class TaskPropertiesIntegrationTest extends AbstractIntegrationSpec { public abstract class MyTask extends DefaultTask { private final Property count = getProject().getObjects().property(Integer.class); - + @Internal public Property getCount() { return count; @@ -118,7 +118,7 @@ class TaskPropertiesIntegrationTest extends AbstractIntegrationSpec { } """ - buildFile << """ + buildFile << """ tasks.create("thing", MyTask) { println("property = \$count") } @@ -129,7 +129,7 @@ class TaskPropertiesIntegrationTest extends AbstractIntegrationSpec { then: outputContains("property = task ':thing' property 'count'") - failure.assertHasCause("No value has been specified for task ':thing' property 'count'") + failure.assertHasCause("Cannot query the value of task ':thing' property 'count' because it has no value available.") } def "can define task with abstract read-only ConfigurableFileCollection property"() { @@ -138,13 +138,13 @@ class TaskPropertiesIntegrationTest extends AbstractIntegrationSpec { abstract class MyTask extends DefaultTask { @InputFiles abstract ConfigurableFileCollection getSource() - + @TaskAction void go() { println("files = \${source.files.name}") } } - + tasks.create("thing", MyTask) { source.from("a", "b", "c") } @@ -163,13 +163,13 @@ class TaskPropertiesIntegrationTest extends AbstractIntegrationSpec { abstract class MyTask extends DefaultTask { @InputFiles abstract ConfigurableFileTree getSource() - + @TaskAction void go() { println("files = \${source.files.name.sort()}") } } - + tasks.create("thing", MyTask) { source.from("dir") } @@ -197,17 +197,17 @@ class TaskPropertiesIntegrationTest extends AbstractIntegrationSpec { this.name = name } } - + abstract class MyTask extends DefaultTask { @Nested abstract NamedDomainObjectContainer getBeans() - + @TaskAction void go() { println("beans = \${beans.collect { it.prop.get() } }") } } - + tasks.create("thing", MyTask) { beans { one { prop = '1' } @@ -230,17 +230,17 @@ class TaskPropertiesIntegrationTest extends AbstractIntegrationSpec { @Input String prop } - + abstract class MyTask extends DefaultTask { @Nested abstract DomainObjectSet getBeans() - + @TaskAction void go() { println("beans = \${beans.collect { it.prop } }") } } - + tasks.create("thing", MyTask) { beans.add(new Bean(prop: '1')) beans.add(new Bean(prop: '2')) @@ -264,13 +264,13 @@ class TaskPropertiesIntegrationTest extends AbstractIntegrationSpec { abstract class MyTask extends DefaultTask { @Nested abstract Params getParams() - + @TaskAction void go() { println("count = \${params.count.get()}") } } - + tasks.create("thing", MyTask) { println("params = \$params") println("params.count = \$params.count") @@ -293,17 +293,17 @@ class TaskPropertiesIntegrationTest extends AbstractIntegrationSpec { abstract class MyTask extends DefaultTask { @Internal abstract Property getParam() - + MyTask() { param.convention("from convention") } - + @TaskAction void go() { println("param = \${param.get()}") } } - + tasks.create("thing", MyTask) { param.set("from configuration") } diff --git a/subprojects/core/src/main/java/org/gradle/api/internal/DefaultNamedDomainObjectCollection.java b/subprojects/core/src/main/java/org/gradle/api/internal/DefaultNamedDomainObjectCollection.java index 3f80227307f1..c25f3dd032b8 100644 --- a/subprojects/core/src/main/java/org/gradle/api/internal/DefaultNamedDomainObjectCollection.java +++ b/subprojects/core/src/main/java/org/gradle/api/internal/DefaultNamedDomainObjectCollection.java @@ -32,7 +32,7 @@ import org.gradle.api.internal.collections.CollectionFilter; import org.gradle.api.internal.collections.ElementSource; import org.gradle.api.internal.plugins.DslObject; -import org.gradle.api.internal.provider.AbstractReadOnlyProvider; +import org.gradle.api.internal.provider.AbstractMinimalProvider; import org.gradle.api.internal.provider.ProviderInternal; import org.gradle.api.internal.provider.Providers; import org.gradle.api.provider.Provider; @@ -808,7 +808,7 @@ protected NamedDomainObjectProvider createExistingProvider(String n return Cast.uncheckedCast(getInstantiator().newInstance(ExistingNamedDomainObjectProvider.class, this, name, new DslObject(object).getDeclaredType())); } - protected abstract class AbstractNamedDomainObjectProvider extends AbstractReadOnlyProvider implements Named, NamedDomainObjectProvider { + protected abstract class AbstractNamedDomainObjectProvider extends AbstractMinimalProvider implements Named, NamedDomainObjectProvider { private final String name; private final Class type; diff --git a/subprojects/core/src/main/java/org/gradle/api/services/internal/BuildServiceProvider.java b/subprojects/core/src/main/java/org/gradle/api/services/internal/BuildServiceProvider.java index 2fd50a90cc7f..d50fa2439405 100644 --- a/subprojects/core/src/main/java/org/gradle/api/services/internal/BuildServiceProvider.java +++ b/subprojects/core/src/main/java/org/gradle/api/services/internal/BuildServiceProvider.java @@ -16,7 +16,7 @@ package org.gradle.api.services.internal; -import org.gradle.api.internal.provider.AbstractReadOnlyProvider; +import org.gradle.api.internal.provider.AbstractMinimalProvider; import org.gradle.api.services.BuildService; import org.gradle.api.services.BuildServiceParameters; import org.gradle.internal.Try; @@ -30,7 +30,7 @@ import javax.annotation.Nullable; // TODO - complain when used at configuration time, except when opted in to this -public class BuildServiceProvider, P extends BuildServiceParameters> extends AbstractReadOnlyProvider implements Managed { +public class BuildServiceProvider, P extends BuildServiceParameters> extends AbstractMinimalProvider implements Managed { private final String name; private final Class implementationType; private final IsolationScheme isolationScheme; diff --git a/subprojects/core/src/test/groovy/org/gradle/api/internal/collections/AbstractElementSourceTest.groovy b/subprojects/core/src/test/groovy/org/gradle/api/internal/collections/AbstractElementSourceTest.groovy index 16c26d0dc7dd..5da3c2e0cb51 100644 --- a/subprojects/core/src/test/groovy/org/gradle/api/internal/collections/AbstractElementSourceTest.groovy +++ b/subprojects/core/src/test/groovy/org/gradle/api/internal/collections/AbstractElementSourceTest.groovy @@ -17,7 +17,8 @@ package org.gradle.api.internal.collections import org.gradle.api.Action -import org.gradle.api.internal.provider.AbstractReadOnlyProvider +import org.gradle.api.internal.provider.AbstractMinimalProvider + import org.gradle.api.internal.provider.ChangingValue import org.gradle.api.internal.provider.ChangingValueHandler import org.gradle.api.internal.provider.CollectionProviderInternal @@ -275,7 +276,7 @@ abstract class AbstractElementSourceTest extends Specification { return new TypedProviderOfSet(StringBuffer, values as LinkedHashSet) } - private static class TypedProvider extends AbstractReadOnlyProvider implements ChangingValue { + private static class TypedProvider extends AbstractMinimalProvider implements ChangingValue { final Class type T value final ChangingValueHandler changingValue = new ChangingValueHandler() @@ -307,7 +308,7 @@ abstract class AbstractElementSourceTest extends Specification { } } - private static class TypedProviderOfSet extends AbstractReadOnlyProvider> implements CollectionProviderInternal>, ChangingValue> { + private static class TypedProviderOfSet extends AbstractMinimalProvider> implements CollectionProviderInternal>, ChangingValue> { final Class type Set value final ChangingValueHandler> changingValue = new ChangingValueHandler>() diff --git a/subprojects/core/src/test/groovy/org/gradle/api/internal/collections/ListElementSourceTest.groovy b/subprojects/core/src/test/groovy/org/gradle/api/internal/collections/ListElementSourceTest.groovy index 38a36c316c7c..197e65c1e8e1 100644 --- a/subprojects/core/src/test/groovy/org/gradle/api/internal/collections/ListElementSourceTest.groovy +++ b/subprojects/core/src/test/groovy/org/gradle/api/internal/collections/ListElementSourceTest.groovy @@ -16,10 +16,9 @@ package org.gradle.api.internal.collections -import org.gradle.api.internal.provider.AbstractReadOnlyProvider +import org.gradle.api.internal.provider.AbstractMinimalProvider import org.gradle.api.internal.provider.CollectionProviderInternal - class ListElementSourceTest extends AbstractIterationOrderRetainingElementSourceTest { ListElementSource source = new ListElementSource<>() @@ -477,7 +476,7 @@ class ListElementSourceTest extends AbstractIterationOrderRetainingElementSource return new TypedProviderOfList(StringBuffer, values as List) } - private static class TypedProviderOfList extends AbstractReadOnlyProvider> implements CollectionProviderInternal> { + private static class TypedProviderOfList extends AbstractMinimalProvider> implements CollectionProviderInternal> { final Class type final List value diff --git a/subprojects/core/src/test/groovy/org/gradle/api/internal/model/DefaultObjectFactoryTest.groovy b/subprojects/core/src/test/groovy/org/gradle/api/internal/model/DefaultObjectFactoryTest.groovy index aa8590207fde..ba342e13fc47 100644 --- a/subprojects/core/src/test/groovy/org/gradle/api/internal/model/DefaultObjectFactoryTest.groovy +++ b/subprojects/core/src/test/groovy/org/gradle/api/internal/model/DefaultObjectFactoryTest.groovy @@ -39,7 +39,7 @@ class DefaultObjectFactoryTest extends Specification { then: def e = thrown(IllegalStateException) - e.message == 'No value has been specified for this property.' + e.message == 'Cannot query the value of this property because it has no value available.' } def "cannot create property for null value"() { diff --git a/subprojects/file-collections/src/main/java/org/gradle/api/internal/file/DefaultFilePropertyFactory.java b/subprojects/file-collections/src/main/java/org/gradle/api/internal/file/DefaultFilePropertyFactory.java index 30e82fa5f56a..25d3d41b921e 100644 --- a/subprojects/file-collections/src/main/java/org/gradle/api/internal/file/DefaultFilePropertyFactory.java +++ b/subprojects/file-collections/src/main/java/org/gradle/api/internal/file/DefaultFilePropertyFactory.java @@ -26,7 +26,7 @@ import org.gradle.api.file.RegularFileProperty; import org.gradle.api.internal.provider.AbstractCombiningProvider; import org.gradle.api.internal.provider.AbstractMappingProvider; -import org.gradle.api.internal.provider.AbstractReadOnlyProvider; +import org.gradle.api.internal.provider.AbstractMinimalProvider; import org.gradle.api.internal.provider.DefaultProperty; import org.gradle.api.internal.provider.ProviderInternal; import org.gradle.api.internal.provider.Providers; @@ -241,7 +241,7 @@ public THIS convention(Provider valueProvider) { @Override public Provider getLocationOnly() { - return new AbstractReadOnlyProvider() { + return new AbstractMinimalProvider() { @Nullable @Override public Class getType() { diff --git a/subprojects/file-collections/src/test/groovy/org/gradle/api/internal/file/DefaultFilePropertyFactoryTest.groovy b/subprojects/file-collections/src/test/groovy/org/gradle/api/internal/file/DefaultFilePropertyFactoryTest.groovy index 826c935b6cb7..1ef2b9986c45 100644 --- a/subprojects/file-collections/src/test/groovy/org/gradle/api/internal/file/DefaultFilePropertyFactoryTest.groovy +++ b/subprojects/file-collections/src/test/groovy/org/gradle/api/internal/file/DefaultFilePropertyFactoryTest.groovy @@ -205,35 +205,35 @@ class DefaultFilePropertyFactoryTest extends Specification { then: def e = thrown(IllegalStateException) - e.message == 'No value has been specified for this property.' + e.message == 'Cannot query the value of this property because it has no value available.' when: fileProvider.get() then: def e2 = thrown(IllegalStateException) - e2.message == 'No value has been specified for this property.' + e2.message == 'Cannot query the value of this property because it has no value available.' when: dir.get() then: def e3 = thrown(IllegalStateException) - e3.message == 'No value has been specified for this property.' + e3.message == 'Cannot query the value of this property because it has no value available.' when: file.get() then: def e4 = thrown(IllegalStateException) - e4.message == 'No value has been specified for this property.' + e4.message == 'Cannot query the value of this property because it has no value available.' when: tree.files then: def e5 = thrown(IllegalStateException) - e5.message == 'No value has been specified for this property.' + e5.message == 'Cannot query the value of this property because it has no value available.' } @SuppressWarnings("GroovyAssignabilityCheck") diff --git a/subprojects/language-jvm/src/main/java/org/gradle/api/tasks/compile/AbstractCompile.java b/subprojects/language-jvm/src/main/java/org/gradle/api/tasks/compile/AbstractCompile.java index ce12b4a5b2fe..aa145cb09470 100644 --- a/subprojects/language-jvm/src/main/java/org/gradle/api/tasks/compile/AbstractCompile.java +++ b/subprojects/language-jvm/src/main/java/org/gradle/api/tasks/compile/AbstractCompile.java @@ -19,7 +19,7 @@ import org.gradle.api.file.Directory; import org.gradle.api.file.DirectoryProperty; import org.gradle.api.file.FileCollection; -import org.gradle.api.internal.provider.AbstractReadOnlyProvider; +import org.gradle.api.internal.provider.AbstractMinimalProvider; import org.gradle.api.model.ReplacedBy; import org.gradle.api.provider.Provider; import org.gradle.api.tasks.Classpath; @@ -146,7 +146,7 @@ public void setTargetCompatibility(String targetCompatibility) { /** * Convention to fall back to the 'destinationDir' output for backwards compatibility with plugins that extend AbstractCompile and override the deprecated methods. */ - private class BackwardCompatibilityOutputDirectoryConvention extends AbstractReadOnlyProvider { + private class BackwardCompatibilityOutputDirectoryConvention extends AbstractMinimalProvider { private boolean recursiveCall; @Override diff --git a/subprojects/language-native/src/main/java/org/gradle/language/internal/DefaultBinaryCollection.java b/subprojects/language-native/src/main/java/org/gradle/language/internal/DefaultBinaryCollection.java index e4aa62ac12c7..a3a2fbbb3485 100644 --- a/subprojects/language-native/src/main/java/org/gradle/language/internal/DefaultBinaryCollection.java +++ b/subprojects/language-native/src/main/java/org/gradle/language/internal/DefaultBinaryCollection.java @@ -20,7 +20,7 @@ import groovy.lang.Closure; import org.gradle.api.Action; import org.gradle.api.component.SoftwareComponent; -import org.gradle.api.internal.provider.AbstractReadOnlyProvider; +import org.gradle.api.internal.provider.AbstractMinimalProvider; import org.gradle.api.provider.ProviderFactory; import org.gradle.api.specs.Spec; import org.gradle.internal.ImmutableActionSet; @@ -170,7 +170,7 @@ public Set get() { return ImmutableSet.copyOf(elements); } - private class SingleElementProvider extends AbstractReadOnlyProvider implements BinaryProvider { + private class SingleElementProvider extends AbstractMinimalProvider implements BinaryProvider { private final Class type; private Spec spec; private S match; diff --git a/subprojects/language-native/src/test/groovy/org/gradle/language/internal/DefaultBinaryCollectionTest.groovy b/subprojects/language-native/src/test/groovy/org/gradle/language/internal/DefaultBinaryCollectionTest.groovy index 8d885c95d826..002813df4fbb 100644 --- a/subprojects/language-native/src/test/groovy/org/gradle/language/internal/DefaultBinaryCollectionTest.groovy +++ b/subprojects/language-native/src/test/groovy/org/gradle/language/internal/DefaultBinaryCollectionTest.groovy @@ -307,7 +307,7 @@ class DefaultBinaryCollectionTest extends Specification { then: def e = thrown(IllegalStateException) - e.message == 'No value has been specified for this provider.' + e.message == 'Cannot query the value of this provider because it has no value available.' } def "querying the result of get by name fails when no element present"() { @@ -320,7 +320,7 @@ class DefaultBinaryCollectionTest extends Specification { then: def e = thrown(IllegalStateException) - e.message == 'No value has been specified for this provider.' + e.message == 'Cannot query the value of this provider because it has no value available.' } def "querying the result of get by name fails when multiple elements present"() { @@ -601,7 +601,7 @@ class DefaultBinaryCollectionTest extends Specification { then: def e = thrown(IllegalStateException) - e.message == 'No value has been specified for this provider.' + e.message == 'Cannot query the value of this provider because it has no value available.' } def "querying the result of get by spec fails when no matching element present"() { @@ -619,7 +619,7 @@ class DefaultBinaryCollectionTest extends Specification { then: def e = thrown(IllegalStateException) - e.message == 'No value has been specified for this provider.' + e.message == 'Cannot query the value of this provider because it has no value available.' } def "querying the result of get by spec fails when multiple matching elements present"() { diff --git a/subprojects/language-native/src/test/groovy/org/gradle/language/swift/internal/DefaultSwiftApplicationTest.groovy b/subprojects/language-native/src/test/groovy/org/gradle/language/swift/internal/DefaultSwiftApplicationTest.groovy index 3f38eaa50304..6eb96ba8dd2d 100644 --- a/subprojects/language-native/src/test/groovy/org/gradle/language/swift/internal/DefaultSwiftApplicationTest.groovy +++ b/subprojects/language-native/src/test/groovy/org/gradle/language/swift/internal/DefaultSwiftApplicationTest.groovy @@ -73,7 +73,7 @@ class DefaultSwiftApplicationTest extends Specification { then: def ex = thrown(IllegalStateException) - ex.message == "No value has been specified for Swift application 'main' property 'developmentBinary'." + ex.message == "Cannot query the value of Swift application 'main' property 'developmentBinary' because it has no value available." } private NativeVariantIdentity getIdentity() { diff --git a/subprojects/language-native/src/test/groovy/org/gradle/language/swift/internal/DefaultSwiftLibraryTest.groovy b/subprojects/language-native/src/test/groovy/org/gradle/language/swift/internal/DefaultSwiftLibraryTest.groovy index 7c42af2fc515..177624948f76 100644 --- a/subprojects/language-native/src/test/groovy/org/gradle/language/swift/internal/DefaultSwiftLibraryTest.groovy +++ b/subprojects/language-native/src/test/groovy/org/gradle/language/swift/internal/DefaultSwiftLibraryTest.groovy @@ -103,7 +103,7 @@ class DefaultSwiftLibraryTest extends Specification { then: def ex = thrown(IllegalStateException) - ex.message == "No value has been specified for Swift library 'main' property 'developmentBinary'." + ex.message == "Cannot query the value of Swift library 'main' property 'developmentBinary' because it has no value available." } private NativeVariantIdentity getIdentity() { diff --git a/subprojects/logging/src/main/java/org/gradle/internal/logging/text/TreeFormatter.java b/subprojects/logging/src/main/java/org/gradle/internal/logging/text/TreeFormatter.java index 2093e37db4e6..976e6de04990 100644 --- a/subprojects/logging/src/main/java/org/gradle/internal/logging/text/TreeFormatter.java +++ b/subprojects/logging/src/main/java/org/gradle/internal/logging/text/TreeFormatter.java @@ -80,7 +80,7 @@ public void blankLine() { /** * Starts a new node with the given type name. */ - public void node(Class type) { + public TreeFormatter node(Class type) { // Implementation is currently dumb, can be made smarter if (type.isInterface()) { node("Interface "); @@ -88,26 +88,28 @@ public void node(Class type) { node("Class "); } appendType(type); + return this; } /** * Appends text to the current node. */ - public void append(CharSequence text) { + public TreeFormatter append(CharSequence text) { if (current.state == State.CollectValue) { current.value.append(text); if (current.valueWritten) { original.append(text); } } else { - throw new IllegalStateException("Cannot append text to node."); + throw new IllegalStateException("Cannot append text as there is no current node."); } + return this; } /** * Appends a type name to the current node. */ - public void appendType(Type type) { + public TreeFormatter appendType(Type type) { // Implementation is currently dumb, can be made smarter if (type instanceof Class) { Class classType = GeneratedSubclasses.unpack((Class) type); @@ -129,6 +131,7 @@ public void appendType(Type type) { } else { append(type.toString()); } + return this; } private void appendOuter(Class type) { @@ -143,25 +146,27 @@ private void appendOuter(Class type) { /** * Appends an annotation name to the current node. */ - public void appendAnnotation(Class type) { + public TreeFormatter appendAnnotation(Class type) { append("@" + type.getSimpleName()); + return this; } /** * Appends a method name to the current node. */ - public void appendMethod(Method method) { + public TreeFormatter appendMethod(Method method) { // Implementation is currently dumb, can be made smarter append(method.getDeclaringClass().getSimpleName()); append("."); append(method.getName()); append("()"); + return this; } /** * Appends some user provided value to the current node. */ - public void appendValue(@Nullable Object value) { + public TreeFormatter appendValue(@Nullable Object value) { // Implementation is currently dumb, can be made smarter if (value == null) { append("null"); @@ -174,12 +179,13 @@ public void appendValue(@Nullable Object value) { } else { append(value.toString()); } + return this; } /** * Appends some user provided values to the current node. */ - public void appendValues(T[] values) { + public TreeFormatter appendValues(T[] values) { // Implementation is currently dumb, can be made smarter append("["); for (int i = 0; i < values.length; i++) { @@ -190,6 +196,7 @@ public void appendValues(T[] values) { appendValue(value); } append("]"); + return this; } @Override diff --git a/subprojects/logging/src/test/groovy/org/gradle/internal/logging/text/TreeFormatterTest.groovy b/subprojects/logging/src/test/groovy/org/gradle/internal/logging/text/TreeFormatterTest.groovy index 8b5f25e2fdf6..4761b92cd9a1 100644 --- a/subprojects/logging/src/test/groovy/org/gradle/internal/logging/text/TreeFormatterTest.groovy +++ b/subprojects/logging/src/test/groovy/org/gradle/internal/logging/text/TreeFormatterTest.groovy @@ -420,7 +420,7 @@ Some thing.''') then: def e = thrown(IllegalStateException) - e.message == 'Cannot append text to node.' + e.message == 'Cannot append text as there is no current node.' } def "cannot append after children finished"() { @@ -433,7 +433,7 @@ Some thing.''') then: def e = thrown(IllegalStateException) - e.message == 'Cannot append text to node.' + e.message == 'Cannot append text as there is no current node.' } interface Thing extends List, Map> { diff --git a/subprojects/model-core/src/integTest/groovy/org/gradle/api/provider/PropertyIntegrationTest.groovy b/subprojects/model-core/src/integTest/groovy/org/gradle/api/provider/PropertyIntegrationTest.groovy index 5b71d9e3821b..2b4265240266 100644 --- a/subprojects/model-core/src/integTest/groovy/org/gradle/api/provider/PropertyIntegrationTest.groovy +++ b/subprojects/model-core/src/integTest/groovy/org/gradle/api/provider/PropertyIntegrationTest.groovy @@ -75,13 +75,13 @@ task thing(type: SomeTask) { abstract class MyTask extends DefaultTask { @Input abstract Property<$type> getProp() - + @TaskAction void go() { println("prop = \${prop.get()}") } } - + tasks.create("thing", MyTask) { prop = $value } @@ -110,17 +110,17 @@ task thing(type: SomeTask) { abstract class MyTask extends DefaultTask { @Nested abstract NestedType getNested() - + void nested(Action action) { action.execute(nested) } - + @TaskAction void go() { println("prop = \${nested.prop.get()}") } } - + tasks.create("thing", MyTask) { nested { prop = "value" @@ -135,6 +135,70 @@ task thing(type: SomeTask) { outputContains("prop = value") } + def "fails when property with no value is queried"() { + given: + buildFile << """ + abstract class SomeTask extends DefaultTask { + @Internal + abstract Property getProp() + + @TaskAction + def go() { + prop.get() + } + } + + tasks.register('thing', SomeTask) { + prop + } + """ + + when: + fails("thing") + + then: + failure.assertHasDescription("Execution failed for task ':thing'.") + failure.assertHasCause("Cannot query the value of task ':thing' property 'prop' because it has no value available.") + } + + def "fails when property with no value because source property has no value is queried"() { + given: + buildFile << """ + interface SomeExtension { + Property getSource() + } + + abstract class SomeTask extends DefaultTask { + @Internal + abstract Property getProp() + + @TaskAction + def go() { + prop.get() + } + } + + def custom1 = extensions.create('custom1', SomeExtension) + + def custom2 = extensions.create('custom2', SomeExtension) + custom2.source = custom1.source + + tasks.register('thing', SomeTask) { + prop = custom2.source + } + """ + + when: + fails("thing") + + then: + failure.assertHasDescription("Execution failed for task ':thing'.") + failure.assertHasCause("""Cannot query the value of task ':thing' property 'prop' because it has no value available. +The value of this property is derived from: + - extension 'custom2' property 'source' + - extension 'custom1' property 'source'""") + } + def "can finalize the value of a property using API"() { given: buildFile << """ @@ -144,16 +208,16 @@ def provider = providers.provider { ++counter } def property = objects.property(Integer) property.set(provider) -assert property.get() == 1 -assert property.get() == 2 +assert property.get() == 1 +assert property.get() == 2 property.finalizeValue() assert counter == 3 // is eager -assert property.get() == 3 +assert property.get() == 3 counter = 45 -assert property.get() == 3 +assert property.get() == 3 property.set(12) """ @@ -174,16 +238,16 @@ def provider = providers.provider { ++counter } def property = objects.property(Integer) property.set(provider) -assert property.get() == 1 -assert property.get() == 2 +assert property.get() == 1 +assert property.get() == 2 property.finalizeValueOnRead() assert counter == 2 // is lazy assert property.get() == 3 - + counter = 45 -assert property.get() == 3 +assert property.get() == 3 property.set(12) """ @@ -204,11 +268,11 @@ def provider = providers.provider { ++counter } def property = objects.property(Integer) property.set(provider) -assert property.get() == 1 -assert property.get() == 2 +assert property.get() == 1 +assert property.get() == 2 property.disallowChanges() assert property.get() == 3 -assert property.get() == 4 +assert property.get() == 4 property.set(12) """ @@ -226,10 +290,10 @@ property.set(12) class SomeTask extends DefaultTask { @Input final Property prop = project.objects.property(String) - + @OutputFile final Property outputFile = project.objects.fileProperty() - + @TaskAction void go() { outputFile.get().asFile.text = prop.get() @@ -318,7 +382,7 @@ task thing(type: SomeTask) { prop = providers.provider { throw new RuntimeException("broken") } outputFile = layout.buildDirectory.file("out.txt") } - + """ when: @@ -335,13 +399,13 @@ task thing(type: SomeTask) { buildFile << """ task thing(type: SomeTask) { - prop = providers.provider { + prop = providers.provider { println("calculating value") return "value" } outputFile = layout.buildDirectory.file("out.txt") } - + """ when: @@ -370,21 +434,21 @@ task thing(type: SomeTask) { class SomeTask extends DefaultTask { @Input final Property prop = project.objects.property(String) - + @InputFiles @SkipWhenEmpty final SetProperty outputFile = project.objects.setProperty(RegularFile) - + @TaskAction void go() { } } task thing(type: SomeTask) { - prop = providers.provider { + prop = providers.provider { throw new RuntimeException("should not be called") } } - + """ when: @@ -399,7 +463,7 @@ task thing(type: SomeTask) { buildFile << """ class SomeExtension { final Property prop - + @javax.inject.Inject SomeExtension(ObjectFactory objects) { prop = objects.property(String) @@ -436,7 +500,7 @@ assert tasks.t.prop.get() == "changed" buildFile << """ class SomeExtension { final Property prop - + @javax.inject.Inject SomeExtension(ObjectFactory objects) { prop = objects.property(String) @@ -467,7 +531,7 @@ assert custom.prop.get() == "value 4" buildFile << """ class SomeExtension { final Property prop - + @javax.inject.Inject SomeExtension(ObjectFactory objects) { prop = objects.property(String) @@ -598,8 +662,8 @@ class SomeExtension { $prop = objects.property($type) } } - -project.extensions.create("some", SomeExtension) + +project.extensions.create("some", SomeExtension) """ when: @@ -622,10 +686,10 @@ project.extensions.create("some", SomeExtension) class SomeTask extends DefaultTask { @Input final Property prop = project.objects.property(String) - + @OutputFile final Property outputFile = project.objects.fileProperty() - + @TaskAction void go() { outputFile.get().asFile.text = prop.get() diff --git a/subprojects/model-core/src/main/java/org/gradle/api/internal/provider/AbstractCombiningProvider.java b/subprojects/model-core/src/main/java/org/gradle/api/internal/provider/AbstractCombiningProvider.java index 2bece24ba530..ee3fe7c1d16c 100644 --- a/subprojects/model-core/src/main/java/org/gradle/api/internal/provider/AbstractCombiningProvider.java +++ b/subprojects/model-core/src/main/java/org/gradle/api/internal/provider/AbstractCombiningProvider.java @@ -20,7 +20,7 @@ import javax.annotation.Nullable; -public abstract class AbstractCombiningProvider extends AbstractReadOnlyProvider { +public abstract class AbstractCombiningProvider extends AbstractMinimalProvider { private final Class type; private final Provider base; private final Provider provider; diff --git a/subprojects/model-core/src/main/java/org/gradle/api/internal/provider/AbstractMinimalProvider.java b/subprojects/model-core/src/main/java/org/gradle/api/internal/provider/AbstractMinimalProvider.java index 507c963954d1..a230e8b37494 100644 --- a/subprojects/model-core/src/main/java/org/gradle/api/internal/provider/AbstractMinimalProvider.java +++ b/subprojects/model-core/src/main/java/org/gradle/api/internal/provider/AbstractMinimalProvider.java @@ -29,7 +29,7 @@ import javax.annotation.Nullable; /** - * A partial {@link Provider} implementation. + * A partial {@link Provider} implementation. Subclasses need to implement {@link ProviderInternal#getType()} and {@link Provider#getOrNull()}. */ public abstract class AbstractMinimalProvider implements ProviderInternal, ScalarSupplier, Managed { @Override @@ -44,21 +44,28 @@ public Provider flatMap(final Transformer @Override public boolean isPresent() { - return getOrNull() != null; + return !calculateValue().isMissing(); } @Override - public T get(DisplayName owner) throws IllegalStateException { - return get(); + public T get() { + Value value = calculateValue(); + if (value.isMissing()) { + throw new MissingValueException(Providers.NULL_VALUE); + } + return value.get(); + } + + // This is here as a migration step. It would be better for each subclass to provide an implementation of this method and implement + // getOrNull() based on the result, rather than implementing this method based on getOrNull() + @Override + public Value calculateValue() { + return Value.ofNullable(getOrNull()); } @Override public T getOrElse(T defaultValue) { - T value = getOrNull(); - if (value == null) { - return defaultValue; - } - return value; + return calculateValue().orElse(defaultValue); } @Override @@ -229,7 +236,7 @@ public T get() { } } - private static class OrElseProvider extends AbstractReadOnlyProvider { + private static class OrElseProvider extends AbstractMinimalProvider { private final ProviderInternal left; private final ProviderInternal right; diff --git a/subprojects/model-core/src/main/java/org/gradle/api/internal/provider/DefaultMapProperty.java b/subprojects/model-core/src/main/java/org/gradle/api/internal/provider/DefaultMapProperty.java index 385814a5f4ef..a2c533b05db9 100644 --- a/subprojects/model-core/src/main/java/org/gradle/api/internal/provider/DefaultMapProperty.java +++ b/subprojects/model-core/src/main/java/org/gradle/api/internal/provider/DefaultMapProperty.java @@ -334,7 +334,7 @@ protected void makeFinal() { } } - private class KeySetProvider extends AbstractReadOnlyProvider> { + private class KeySetProvider extends AbstractMinimalProvider> { @Nullable @Override diff --git a/subprojects/model-core/src/main/java/org/gradle/api/internal/provider/DefaultProperty.java b/subprojects/model-core/src/main/java/org/gradle/api/internal/provider/DefaultProperty.java index 05339a4cf0f0..4173e7a24df3 100644 --- a/subprojects/model-core/src/main/java/org/gradle/api/internal/provider/DefaultProperty.java +++ b/subprojects/model-core/src/main/java/org/gradle/api/internal/provider/DefaultProperty.java @@ -18,6 +18,8 @@ import org.gradle.api.provider.Property; import org.gradle.api.provider.Provider; +import org.gradle.internal.DisplayName; +import org.gradle.internal.logging.text.TreeFormatter; import javax.annotation.Nullable; @@ -25,7 +27,7 @@ public class DefaultProperty extends AbstractProperty implements Property< private final Class type; private final ValueSanitizer sanitizer; private ScalarSupplier convention = Providers.noValue(); - private ScalarSupplier value; + private ScalarSupplier valueSupplier; public DefaultProperty(Class type) { applyDefaultValue(); @@ -35,7 +37,7 @@ public DefaultProperty(Class type) { @Override protected ValueSupplier getSupplier() { - return value; + return valueSupplier; } @Override @@ -71,13 +73,13 @@ public void setFromAnyValue(Object object) { public void set(T value) { if (value == null) { if (beforeReset()) { - this.value = convention; + this.valueSupplier = convention; } return; } if (beforeMutate()) { - this.value = Providers.fixedValue(getValidationDisplayName(), value, type, sanitizer); + this.valueSupplier = Providers.fixedValue(getValidationDisplayName(), value, type, sanitizer); } } @@ -94,7 +96,7 @@ public Property value(Provider provider) { } public ProviderInternal getProvider() { - return value.asProvider(); + return valueSupplier.asProvider(); } public DefaultProperty provider(Provider provider) { @@ -111,7 +113,7 @@ public void set(Provider provider) { throw new IllegalArgumentException("Cannot set the value of a property using a null provider."); } ProviderInternal p = Providers.internal(provider); - this.value = p.asSupplier(getValidationDisplayName(), type, sanitizer); + this.valueSupplier = p.asSupplier(getValidationDisplayName(), type, sanitizer); } @Override @@ -134,53 +136,69 @@ public Property convention(Provider valueProvider) { private void applyConvention(ScalarSupplier conventionSupplier) { if (shouldApplyConvention()) { - this.value = conventionSupplier; + this.valueSupplier = conventionSupplier; } this.convention = conventionSupplier; } @Override protected void applyDefaultValue() { - value = Providers.noValue(); + valueSupplier = Providers.noValue(); } @Override protected void makeFinal() { - value = value.withFinalValue(); + valueSupplier = valueSupplier.withFinalValue(); convention = Providers.noValue(); } @Override public T get() { beforeRead(); - return value.get(getDisplayName()); + Value value = valueSupplier.calculateValue(); + if (value.isMissing()) { + TreeFormatter formatter = new TreeFormatter(); + formatter.node("Cannot query the value of ").append(getDisplayName().getDisplayName()).append(" because it has no value available."); + if (!value.getPathToOrigin().isEmpty()) { + formatter.node("The value of this property is derived from"); + formatter.startChildren(); + for (DisplayName displayName : value.getPathToOrigin()) { + formatter.node(displayName.getDisplayName()); + } + formatter.endChildren(); + } + throw new MissingValueException(formatter.toString()); + } + return value.get(); + } + + @Override + public Value calculateValue() { + beforeRead(); + return valueSupplier.calculateValue().pushWhenMissing(getDisplayName()); } @Override public T getOrNull() { beforeRead(); - return value.getOrNull(); + return valueSupplier.calculateValue().orNull(); } @Override public T getOrElse(T defaultValue) { beforeRead(); - T t = value.getOrNull(); - if (t == null) { - return defaultValue; - } - return t; + return valueSupplier.calculateValue().orElse(defaultValue); } @Override public boolean isPresent() { beforeRead(); - return value.isPresent(); + return valueSupplier.isPresent(); } @Override protected String describeContents() { // NOTE: Do not realize the value of the Provider in toString(). The debugger will try to call this method and make debugging really frustrating. - return String.format("property(%s, %s)", type, value); + return String.format("property(%s, %s)", type, valueSupplier); } } diff --git a/subprojects/model-core/src/main/java/org/gradle/api/internal/provider/DefaultProvider.java b/subprojects/model-core/src/main/java/org/gradle/api/internal/provider/DefaultProvider.java index 14742b9015c8..bbcc0308a604 100644 --- a/subprojects/model-core/src/main/java/org/gradle/api/internal/provider/DefaultProvider.java +++ b/subprojects/model-core/src/main/java/org/gradle/api/internal/provider/DefaultProvider.java @@ -21,7 +21,7 @@ import javax.annotation.Nullable; import java.util.concurrent.Callable; -public class DefaultProvider extends AbstractReadOnlyProvider { +public class DefaultProvider extends AbstractMinimalProvider { private final Callable value; public DefaultProvider(Callable value) { diff --git a/subprojects/model-core/src/main/java/org/gradle/api/internal/provider/DefaultValueSourceProviderFactory.java b/subprojects/model-core/src/main/java/org/gradle/api/internal/provider/DefaultValueSourceProviderFactory.java index 23e7434ef041..e7968328ff1c 100644 --- a/subprojects/model-core/src/main/java/org/gradle/api/internal/provider/DefaultValueSourceProviderFactory.java +++ b/subprojects/model-core/src/main/java/org/gradle/api/internal/provider/DefaultValueSourceProviderFactory.java @@ -137,7 +137,7 @@ public void parameters(Action configureAction) { } } - public class ValueSourceProvider extends AbstractReadOnlyProvider { + public class ValueSourceProvider extends AbstractMinimalProvider { private final Class> valueSourceType; private final Class

parametersType; diff --git a/subprojects/model-core/src/main/java/org/gradle/api/internal/provider/MapCollectors.java b/subprojects/model-core/src/main/java/org/gradle/api/internal/provider/MapCollectors.java index c82dcb492bd0..04c05ffb7920 100644 --- a/subprojects/model-core/src/main/java/org/gradle/api/internal/provider/MapCollectors.java +++ b/subprojects/model-core/src/main/java/org/gradle/api/internal/provider/MapCollectors.java @@ -183,7 +183,7 @@ public void collectKeysInto(ValueCollector collector, Collection dest) { if (providerOfValue.isPresent()) { collector.add(key, dest); } else { - throw new IllegalStateException(Providers.NULL_VALUE); + throw new MissingValueException(Providers.NULL_VALUE); } } @@ -358,7 +358,7 @@ public boolean maybeCollectInto(MapEntryCollector collector, Map @Override public void collectKeysInto(ValueCollector collector, Collection dest) { - throw new IllegalStateException(Providers.NULL_VALUE); + throw new MissingValueException(Providers.NULL_VALUE); } @Override diff --git a/subprojects/model-core/src/main/java/org/gradle/api/internal/provider/AbstractReadOnlyProvider.java b/subprojects/model-core/src/main/java/org/gradle/api/internal/provider/MissingValueException.java similarity index 52% rename from subprojects/model-core/src/main/java/org/gradle/api/internal/provider/AbstractReadOnlyProvider.java rename to subprojects/model-core/src/main/java/org/gradle/api/internal/provider/MissingValueException.java index 16efc696a93f..f224e4c82f12 100644 --- a/subprojects/model-core/src/main/java/org/gradle/api/internal/provider/AbstractReadOnlyProvider.java +++ b/subprojects/model-core/src/main/java/org/gradle/api/internal/provider/MissingValueException.java @@ -1,5 +1,5 @@ /* - * Copyright 2017 the original author or authors. + * Copyright 2020 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,18 +16,15 @@ package org.gradle.api.internal.provider; -import static org.gradle.api.internal.provider.Providers.NULL_VALUE; +import org.gradle.internal.exceptions.Contextual; -/** - * A basic {@link org.gradle.api.provider.Provider} implementation. Subclasses need to provide a {@link #getOrNull()} implementation. - */ -public abstract class AbstractReadOnlyProvider extends AbstractMinimalProvider { - @Override - public T get() { - T evaluatedValue = getOrNull(); - if (evaluatedValue == null) { - throw new IllegalStateException(NULL_VALUE); - } - return evaluatedValue; +@Contextual +public class MissingValueException extends IllegalStateException { + public MissingValueException(String message) { + super(message); + } + + public MissingValueException(String message, Throwable cause) { + super(message, cause); } } diff --git a/subprojects/model-core/src/main/java/org/gradle/api/internal/provider/Providers.java b/subprojects/model-core/src/main/java/org/gradle/api/internal/provider/Providers.java index d335d5a81fca..b947f2ed47b6 100644 --- a/subprojects/model-core/src/main/java/org/gradle/api/internal/provider/Providers.java +++ b/subprojects/model-core/src/main/java/org/gradle/api/internal/provider/Providers.java @@ -26,7 +26,7 @@ public class Providers { public static final String NULL_TRANSFORMER_RESULT = "Transformer for this provider returned a null value."; - public static final String NULL_VALUE = "No value has been specified for this provider."; + public static final String NULL_VALUE = "Cannot query the value of this provider because it has no value available."; private static final NoValueProvider NULL_PROVIDER = new NoValueProvider(); @@ -38,7 +38,7 @@ public static ScalarSupplier noValue() { } public static ScalarSupplier fixedValue(T value) { - return new FixedValueProvider(value); + return new FixedValueProvider<>(value); } public static ScalarSupplier fixedValue(DisplayName owner, T value, Class targetType, ValueSanitizer sanitizer) { @@ -46,7 +46,7 @@ public static ScalarSupplier fixedValue(DisplayName owner, T value, Class if (!targetType.isInstance(value)) { throw new IllegalArgumentException(String.format("Cannot set the value of %s of type %s using an instance of type %s.", owner.getDisplayName(), targetType.getName(), value.getClass().getName())); } - return new FixedValueProvider(value); + return new FixedValueProvider<>(value); } public static ScalarSupplier nullableValue(@Nullable T value) { @@ -62,7 +62,7 @@ public static ProviderInternal notDefined() { } public static ProviderInternal of(T value) { - return new FixedValueProvider(value); + return new FixedValueProvider<>(value); } public static ProviderInternal internal(final Provider value) { @@ -77,8 +77,8 @@ public static ProviderInternal ofNullable(@Nullable T value) { } } - public static IllegalStateException nullValue(Describable owner) { - return new IllegalStateException(String.format("No value has been specified for %s.", owner.getDisplayName())); + public static MissingValueException nullValue(Describable owner) { + return new MissingValueException(String.format("Cannot query the value of %s because it has no value available.", owner.getDisplayName())); } public static class FixedValueProvider extends AbstractProviderWithValue implements ScalarSupplier { @@ -100,7 +100,17 @@ public T get() { } @Override - public T get(DisplayName owner) throws IllegalStateException { + public Value calculateValue() { + return new Success<>(value); + } + + @Override + public T getOrNull() { + return value; + } + + @Override + public T getOrElse(T defaultValue) { return value; } @@ -116,7 +126,7 @@ public ScalarSupplier withFinalValue() { @Override public ProviderInternal map(final Transformer transformer) { - return new MappedFixedValueProvider(transformer, this); + return new MappedFixedValueProvider<>(transformer, this); } @Override @@ -173,13 +183,13 @@ public S getOrNull() { @Override public ProviderInternal map(Transformer transformer) { - return new MappedFixedValueProvider(transformer, this); + return new MappedFixedValueProvider<>(transformer, this); } @Override public String toString() { if (value == null) { - return String.format("transform(not calculated)"); + return "transform(not calculated)"; } return String.format("transform(%s, %s)", getType(), value); } @@ -188,12 +198,12 @@ public String toString() { private static class NoValueProvider extends AbstractMinimalProvider implements ScalarSupplier { @Override public Object get() { - throw new IllegalStateException(NULL_VALUE); + throw new MissingValueException(NULL_VALUE); } @Override - public Object get(DisplayName owner) throws IllegalStateException { - throw nullValue(owner); + public Value calculateValue() { + return new Missing<>(); } @Override diff --git a/subprojects/model-core/src/main/java/org/gradle/api/internal/provider/ScalarSupplier.java b/subprojects/model-core/src/main/java/org/gradle/api/internal/provider/ScalarSupplier.java index 0a4e73f18b5a..a05575535953 100644 --- a/subprojects/model-core/src/main/java/org/gradle/api/internal/provider/ScalarSupplier.java +++ b/subprojects/model-core/src/main/java/org/gradle/api/internal/provider/ScalarSupplier.java @@ -16,9 +16,12 @@ package org.gradle.api.internal.provider; +import com.google.common.collect.ImmutableList; +import org.gradle.internal.Cast; import org.gradle.internal.DisplayName; import javax.annotation.Nullable; +import java.util.List; /** * Supplies zero or one value of type {@link T}. @@ -27,16 +30,117 @@ public interface ScalarSupplier extends ValueSupplier { boolean isPresent(); /** - * Returns the value of this supplier or fails. - * - * @param owner A display name that can be used in error messages. + * Calculates the value of this supplier. */ - T get(DisplayName owner) throws IllegalStateException; - - @Nullable - T getOrNull(); + Value calculateValue(); ProviderInternal asProvider(); ScalarSupplier withFinalValue(); + + interface Value { + static Value ofNullable(@Nullable T value) { + if (value == null) { + return new Missing(); + } + return new Success(value); + } + + T get() throws IllegalStateException; + + // Only populated when value is missing + List getPathToOrigin(); + + boolean isMissing(); + + Value pushWhenMissing(DisplayName displayName); + + @Nullable + T orNull(); + + S orElse(S defaultValue); + } + + class Success implements Value { + private final T result; + + public Success(T result) { + this.result = result; + } + + @Override + public boolean isMissing() { + return false; + } + + @Override + public T get() throws IllegalStateException { + return result; + } + + @Override + public T orNull() { + return result; + } + + @Override + public S orElse(S defaultValue) { + return Cast.uncheckedCast(result); + } + + @Override + public Value pushWhenMissing(DisplayName displayName) { + return this; + } + + @Override + public List getPathToOrigin() { + throw new IllegalStateException(); + } + } + + class Missing implements Value { + private final List path; + + public Missing() { + this.path = ImmutableList.of(); + } + + public Missing(List path) { + this.path = path; + } + + @Override + public boolean isMissing() { + return true; + } + + @Override + public T get() throws IllegalStateException { + throw new IllegalStateException(); + } + + @Override + public T orNull() { + return null; + } + + @Override + public S orElse(S defaultValue) { + return defaultValue; + } + + @Override + public List getPathToOrigin() { + return path; + } + + @Override + public Value pushWhenMissing(DisplayName displayName) { + ImmutableList.Builder builder = ImmutableList.builderWithExpectedSize(path.size() + 1); + builder.add(displayName); + builder.addAll(path); + return new Missing(builder.build()); + } + } } diff --git a/subprojects/model-core/src/test/groovy/org/gradle/api/internal/provider/AbstractProviderTest.groovy b/subprojects/model-core/src/test/groovy/org/gradle/api/internal/provider/AbstractProviderTest.groovy index a5aef35656d8..e8e3ad31fdd8 100644 --- a/subprojects/model-core/src/test/groovy/org/gradle/api/internal/provider/AbstractProviderTest.groovy +++ b/subprojects/model-core/src/test/groovy/org/gradle/api/internal/provider/AbstractProviderTest.groovy @@ -110,10 +110,10 @@ class AbstractProviderTest extends ProviderSpec { then: def e = thrown(IllegalStateException) - e.message == 'No value has been specified for this provider.' + e.message == 'Cannot query the value of this provider because it has no value available.' } - static class TestProvider extends AbstractReadOnlyProvider { + static class TestProvider extends AbstractMinimalProvider { String value void value(String s) { diff --git a/subprojects/model-core/src/test/groovy/org/gradle/api/internal/provider/CollectionPropertySpec.groovy b/subprojects/model-core/src/test/groovy/org/gradle/api/internal/provider/CollectionPropertySpec.groovy index d9c7eb38c168..731369fd6056 100644 --- a/subprojects/model-core/src/test/groovy/org/gradle/api/internal/provider/CollectionPropertySpec.groovy +++ b/subprojects/model-core/src/test/groovy/org/gradle/api/internal/provider/CollectionPropertySpec.groovy @@ -404,8 +404,8 @@ abstract class CollectionPropertySpec> extends Prop property.get() then: - def e = thrown(IllegalStateException) - e.message == "No value has been specified for this property." + def e = thrown(MissingValueException) + e.message == "Cannot query the value of ${displayName} because it has no value available." } def "property has no value when set to provider with no value and other values appended"() { diff --git a/subprojects/model-core/src/test/groovy/org/gradle/api/internal/provider/DefaultPropertyTest.groovy b/subprojects/model-core/src/test/groovy/org/gradle/api/internal/provider/DefaultPropertyTest.groovy index c53f05b27d79..8cb79f7e040a 100644 --- a/subprojects/model-core/src/test/groovy/org/gradle/api/internal/provider/DefaultPropertyTest.groovy +++ b/subprojects/model-core/src/test/groovy/org/gradle/api/internal/provider/DefaultPropertyTest.groovy @@ -72,15 +72,15 @@ class DefaultPropertyTest extends PropertySpec { property.get() then: - def e = thrown(IllegalStateException) - e.message == "No value has been specified for ${displayName}." + def e = thrown(MissingValueException) + e.message == "Cannot query the value of ${displayName} because it has no value available." } def "toString() does not realize value"() { given: def propertyWithBadValue = property() propertyWithBadValue.set(new DefaultProvider({ - assert false : "never called" + assert false: "never called" })) expect: @@ -136,7 +136,7 @@ class DefaultPropertyTest extends PropertySpec { given: provider.asSupplier(_, _, _) >> supplier - supplier.get(_) >>> [1, 2, 3] + supplier.calculateValue() >>> [1, 2, 3].collect { ScalarSupplier.Value.ofNullable(it) } def property = new DefaultProperty(Number) diff --git a/subprojects/model-core/src/test/groovy/org/gradle/api/internal/provider/DefaultProviderTest.groovy b/subprojects/model-core/src/test/groovy/org/gradle/api/internal/provider/DefaultProviderTest.groovy index 59b174febec3..d24ded0d0f3e 100644 --- a/subprojects/model-core/src/test/groovy/org/gradle/api/internal/provider/DefaultProviderTest.groovy +++ b/subprojects/model-core/src/test/groovy/org/gradle/api/internal/provider/DefaultProviderTest.groovy @@ -64,7 +64,7 @@ class DefaultProviderTest extends ProviderSpec { then: def t = thrown(IllegalStateException) - t.message == "No value has been specified for this provider." + t.message == "Cannot query the value of this provider because it has no value available." when: provider = createProvider(null) @@ -72,7 +72,7 @@ class DefaultProviderTest extends ProviderSpec { then: t = thrown(IllegalStateException) - t.message == "No value has been specified for this provider." + t.message == "Cannot query the value of this provider because it has no value available." when: provider = createProvider(true) diff --git a/subprojects/model-core/src/testFixtures/groovy/org/gradle/api/internal/provider/PropertySpec.groovy b/subprojects/model-core/src/testFixtures/groovy/org/gradle/api/internal/provider/PropertySpec.groovy index 83c246511dea..998342884cd4 100644 --- a/subprojects/model-core/src/testFixtures/groovy/org/gradle/api/internal/provider/PropertySpec.groovy +++ b/subprojects/model-core/src/testFixtures/groovy/org/gradle/api/internal/provider/PropertySpec.groovy @@ -68,16 +68,16 @@ abstract class PropertySpec extends ProviderSpec { property.get() then: - def t = thrown(IllegalStateException) - t.message == "No value has been specified for ${displayName}." + def t = thrown(MissingValueException) + t.message == "Cannot query the value of ${displayName} because it has no value available." when: property.attachDisplayName(Describables.of("")) property.get() then: - def t2 = thrown(IllegalStateException) - t2.message == "No value has been specified for ." + def t2 = thrown(MissingValueException) + t2.message == "Cannot query the value of because it has no value available." when: property.set(someValue()) @@ -427,8 +427,8 @@ abstract class PropertySpec extends ProviderSpec { provider.get() then: - def e = thrown(IllegalStateException) - e.message == "No value has been specified for ${displayName}." + def e = thrown(MissingValueException) + e.message == "Cannot query the value of ${displayName} because it has no value available." } def "can finalize value when no value defined"() { @@ -1700,7 +1700,7 @@ abstract class PropertySpec extends ProviderSpec { } ProviderInternal broken() { - return new AbstractReadOnlyProvider() { + return new AbstractMinimalProvider() { @Override Class getType() { return PropertySpec.this.type() @@ -1728,7 +1728,7 @@ abstract class PropertySpec extends ProviderSpec { return new TestProvider(type(), [], producer) } - class TestProvider extends AbstractReadOnlyProvider { + class TestProvider extends AbstractMinimalProvider { final Class type final Iterator values final Object producer diff --git a/subprojects/model-core/src/testFixtures/groovy/org/gradle/api/internal/provider/ProviderSpec.groovy b/subprojects/model-core/src/testFixtures/groovy/org/gradle/api/internal/provider/ProviderSpec.groovy index e251a5df3eb7..bd4be000e687 100644 --- a/subprojects/model-core/src/testFixtures/groovy/org/gradle/api/internal/provider/ProviderSpec.groovy +++ b/subprojects/model-core/src/testFixtures/groovy/org/gradle/api/internal/provider/ProviderSpec.groovy @@ -172,8 +172,8 @@ abstract class ProviderSpec extends Specification { provider.get() then: - def t = thrown(IllegalStateException) - t.message == "No value has been specified for ${displayName}." + def t = thrown(MissingValueException) + t.message == "Cannot query the value of ${displayName} because it has no value available." } def "mapped provider with no value does not use transformer"() { @@ -192,8 +192,8 @@ abstract class ProviderSpec extends Specification { mapped.get() then: - def t = thrown(IllegalStateException) - t.message == "No value has been specified for ${displayName}." + def t = thrown(MissingValueException) + t.message == "Cannot query the value of ${displayName} because it has no value available." } def "flat mapped provider with no value does not use transformer"() { @@ -212,8 +212,8 @@ abstract class ProviderSpec extends Specification { mapped.get() then: - def t = thrown(IllegalStateException) - t.message == "No value has been specified for ${displayName}." + def t = thrown(MissingValueException) + t.message == "Cannot query the value of ${displayName} because it has no value available." } def "can map to provider that uses value if present or a default value"() { diff --git a/subprojects/plugins/src/integTest/groovy/org/gradle/api/plugins/JavaLibraryDistributionIntegrationTest.groovy b/subprojects/plugins/src/integTest/groovy/org/gradle/api/plugins/JavaLibraryDistributionIntegrationTest.groovy index 139833cfb4b6..b97c30ff2414 100755 --- a/subprojects/plugins/src/integTest/groovy/org/gradle/api/plugins/JavaLibraryDistributionIntegrationTest.groovy +++ b/subprojects/plugins/src/integTest/groovy/org/gradle/api/plugins/JavaLibraryDistributionIntegrationTest.groovy @@ -139,7 +139,7 @@ class JavaLibraryDistributionIntegrationTest extends WellBehavedPluginTest { expect: executer.noDeprecationChecks() runAndFail 'distZip' - failure.assertHasCause "No value has been specified for property 'distributionBaseName'." + failure.assertHasCause "Cannot query the value of property 'distributionBaseName' because it has no value available." } def "compile only dependencies are not included in distribution"() { diff --git a/subprojects/plugins/src/main/java/org/gradle/api/internal/plugins/DefaultArtifactPublicationSet.java b/subprojects/plugins/src/main/java/org/gradle/api/internal/plugins/DefaultArtifactPublicationSet.java index 3f7d91319721..155d892416b4 100644 --- a/subprojects/plugins/src/main/java/org/gradle/api/internal/plugins/DefaultArtifactPublicationSet.java +++ b/subprojects/plugins/src/main/java/org/gradle/api/internal/plugins/DefaultArtifactPublicationSet.java @@ -19,7 +19,7 @@ import org.gradle.api.Action; import org.gradle.api.artifacts.PublishArtifact; import org.gradle.api.artifacts.PublishArtifactSet; -import org.gradle.api.internal.provider.AbstractReadOnlyProvider; +import org.gradle.api.internal.provider.AbstractMinimalProvider; import org.gradle.api.internal.provider.ChangingValue; import org.gradle.api.internal.provider.ChangingValueHandler; import org.gradle.api.internal.provider.CollectionProviderInternal; @@ -46,7 +46,7 @@ public void addCandidate(PublishArtifact artifact) { defaultArtifactProvider.addArtifact(artifact); } - private static class DefaultArtifactProvider extends AbstractReadOnlyProvider> implements CollectionProviderInternal>, ChangingValue> { + private static class DefaultArtifactProvider extends AbstractMinimalProvider> implements CollectionProviderInternal>, ChangingValue> { private Set defaultArtifacts; private Set artifacts; private PublishArtifact currentDefault; From ec6681873be40392d415b1e822ddaf0f304b13d5 Mon Sep 17 00:00:00 2001 From: Adam Murdoch Date: Wed, 22 Jan 2020 12:32:17 +1000 Subject: [PATCH 36/39] Report the chain of properties from which the value of a `ListProperty`, `SetProperty` and `MapProperty` come from, when the value is missing. --- .../AbstractDomainObjectCollectionSpec.groovy | 244 +++++++++++------- .../DefaultDomainObjectCollectionTest.groovy | 2 +- .../DefaultPendingSourceTest.groovy | 6 +- .../CollectionPropertyIntegrationTest.groovy | 46 +++- .../MapPropertyIntegrationTest.groovy | 109 +++++--- .../provider/PropertyIntegrationTest.groovy | 4 +- .../provider/AbstractCollectionProperty.java | 49 ++-- .../internal/provider/AbstractProperty.java | 44 ++++ .../api/internal/provider/Collector.java | 8 +- .../api/internal/provider/Collectors.java | 102 +++----- .../internal/provider/DefaultMapProperty.java | 82 +++--- .../internal/provider/DefaultProperty.java | 37 +-- .../api/internal/provider/MapCollector.java | 12 +- .../api/internal/provider/MapCollectors.java | 138 +++------- .../internal/provider/ProviderInternal.java | 5 + .../api/internal/provider/Providers.java | 2 +- .../api/internal/provider/ScalarSupplier.java | 115 --------- .../api/internal/provider/ValueSupplier.java | 144 +++++++++++ .../provider/CollectionPropertySpec.groovy | 22 +- .../provider/DefaultPropertyTest.groovy | 2 +- .../internal/provider/MapPropertySpec.groovy | 22 +- .../api/internal/provider/PropertySpec.groovy | 39 ++- 22 files changed, 627 insertions(+), 607 deletions(-) diff --git a/subprojects/core/src/test/groovy/org/gradle/api/internal/AbstractDomainObjectCollectionSpec.groovy b/subprojects/core/src/test/groovy/org/gradle/api/internal/AbstractDomainObjectCollectionSpec.groovy index 2f59da595747..a957227ff313 100644 --- a/subprojects/core/src/test/groovy/org/gradle/api/internal/AbstractDomainObjectCollectionSpec.groovy +++ b/subprojects/core/src/test/groovy/org/gradle/api/internal/AbstractDomainObjectCollectionSpec.groovy @@ -16,11 +16,13 @@ package org.gradle.api.internal + import org.gradle.api.Action import org.gradle.api.DomainObjectCollection import org.gradle.api.internal.plugins.DslObject import org.gradle.api.internal.provider.CollectionProviderInternal import org.gradle.api.internal.provider.ProviderInternal +import org.gradle.api.internal.provider.ValueSupplier import org.gradle.configuration.internal.DefaultUserCodeApplicationContext import org.gradle.configuration.internal.UserCodeApplicationContext import org.gradle.configuration.internal.UserCodeApplicationId @@ -219,7 +221,8 @@ abstract class AbstractDomainObjectCollectionSpec extends Specification { !result and: - 1 * provider.get() >> a + 1 * provider.getOrNull() >> a + 0 * _ } def "provider for iterable of elements is queried when membership checked"() { @@ -237,7 +240,9 @@ abstract class AbstractDomainObjectCollectionSpec extends Specification { !result and: - 1 * provider.get() >> [a, d] + _ * provider.size() >> 2 + 1 * provider.calculateValue() >> ValueSupplier.Value.of([a, d]) + 0 * _ } def "can get all domain objects ordered by order added"() { @@ -283,8 +288,8 @@ abstract class AbstractDomainObjectCollectionSpec extends Specification { result == iterationOrder(b, a, d, c) and: - 1 * provider1.get() >> a - 1 * provider2.get() >> d + 1 * provider1.getOrNull() >> a + 1 * provider2.getOrNull() >> d 0 * _ } @@ -305,7 +310,7 @@ abstract class AbstractDomainObjectCollectionSpec extends Specification { and: _ * provider1.size() >> 2 - 1 * provider1.get() >> [a, d] + 1 * provider1.calculateValue() >> ValueSupplier.Value.of([a, d]) 0 * _ } @@ -417,7 +422,7 @@ abstract class AbstractDomainObjectCollectionSpec extends Specification { then: 1 * action.execute(c) _ * provider1.type >> type - 1 * provider1.get() >> c + 1 * provider1.getOrNull() >> c 0 * _ when: @@ -444,7 +449,7 @@ abstract class AbstractDomainObjectCollectionSpec extends Specification { then: 1 * action.execute(c) _ * provider1.elementType >> type - 1 * provider1.get() >> [c] + 1 * provider1.calculateValue() >> ValueSupplier.Value.of([c]) _ * provider1.size() >> 1 0 * _ @@ -489,15 +494,15 @@ abstract class AbstractDomainObjectCollectionSpec extends Specification { then: result == iterationOrder(c, a) _ * provider.type >> type - 1 * provider.get() >> a - 0 * provider._ + 1 * provider.getOrNull() >> a + 0 * _ when: def result2 = toList(container) then: result2 == iterationOrder(c, a, d) - 0 * provider._ + 0 * _ } def "provider for iterable of elements is queried when filtered collection with matching type created"() { @@ -521,15 +526,15 @@ abstract class AbstractDomainObjectCollectionSpec extends Specification { then: result == iterationOrder(c, a, b) _ * provider.size() >> 2 - 1 * provider.get() >> [a, b] - 0 * provider._ + 1 * provider.calculateValue() >> ValueSupplier.Value.of([a, b]) + 0 * _ when: def result2 = toList(container) then: result2 == iterationOrder(c, a, b, d) - 0 * provider._ + 0 * _ } def "provider for element is not queried when filtered collection with non matching type created"() { @@ -545,22 +550,22 @@ abstract class AbstractDomainObjectCollectionSpec extends Specification { def filtered = container.withType(otherType) then: - 0 * provider._ + 0 * _ when: def result = toList(filtered) then: result == iterationOrder(d) - 0 * provider._ + 0 * _ when: def result2 = toList(container) then: result2 == iterationOrder(c, a, d) - 1 * provider.get() >> a - 0 * provider._ + 1 * provider.getOrNull() >> a + 0 * _ } def "provider for iterable of elements is not queried when filtered collection with non matching type created"() { @@ -592,8 +597,8 @@ abstract class AbstractDomainObjectCollectionSpec extends Specification { then: result2 == iterationOrder(c, a, b, d) _ * provider.size() >> 2 - 1 * provider.get() >> [a, b] - 0 * provider._ + 1 * provider.calculateValue() >> ValueSupplier.Value.of([a, b]) + 0 * _ } def "can execute action for all elements in a type filtered collection"() { @@ -670,7 +675,7 @@ abstract class AbstractDomainObjectCollectionSpec extends Specification { then: _ * provider1.type >> type - 1 * provider1.get() >> c + 1 * provider1.getOrNull() >> c 1 * action.execute(c) 0 * _ @@ -699,7 +704,7 @@ abstract class AbstractDomainObjectCollectionSpec extends Specification { then: _ * provider1.elementType >> type _ * provider1.size() >> 1 - 1 * provider1.get() >> [c] + 1 * provider1.calculateValue() >> ValueSupplier.Value.of([c]) 1 * action.execute(c) 0 * _ @@ -785,7 +790,7 @@ abstract class AbstractDomainObjectCollectionSpec extends Specification { toList(container) then: - 1 * provider1.get() >> a + 1 * provider1.getOrNull() >> a 1 * action.execute(a) 0 * _ @@ -800,7 +805,7 @@ abstract class AbstractDomainObjectCollectionSpec extends Specification { toList(container) then: - 1 * provider2.get() >> c + 1 * provider2.getOrNull() >> c 1 * action.execute(c) 0 * _ @@ -816,7 +821,7 @@ abstract class AbstractDomainObjectCollectionSpec extends Specification { then: _ * provider3.size() >> 2 - 1 * provider3.get() >> [b, d] + 1 * provider3.calculateValue() >> ValueSupplier.Value.of([b, d]) 1 * action.execute(b) 1 * action.execute(d) 0 * _ @@ -829,8 +834,8 @@ abstract class AbstractDomainObjectCollectionSpec extends Specification { def providerOfIterable = Mock(CollectionProviderInternal) given: - _ * provider.get() >> a - _ * providerOfIterable.get() >> [b, c] + _ * provider.getOrNull() >> a + _ * providerOfIterable.calculateValue() >> ValueSupplier.Value.of([b, c]) container.addLater(provider) container.addAllLater(providerOfIterable) toList(container) @@ -883,10 +888,10 @@ abstract class AbstractDomainObjectCollectionSpec extends Specification { then: _ * provider1.type >> type - 1 * provider1.get() >> a + 1 * provider1.getOrNull() >> a 1 * action.execute(a) _ * provider2.type >> otherType - 1 * provider2.get() >> d + 1 * provider2.getOrNull() >> d 0 * _ when: @@ -920,12 +925,12 @@ abstract class AbstractDomainObjectCollectionSpec extends Specification { then: _ * provider1.elementType >> type _ * provider1.size() >> 2 - 1 * provider1.get() >> [a, c] + 1 * provider1.calculateValue() >> ValueSupplier.Value.of([a, c]) 1 * action.execute(a) 1 * action.execute(c) _ * provider2.elementType >> otherType _ * provider2.size() >> 1 - 1 * provider2.get() >> [d] + 1 * provider2.calculateValue() >> ValueSupplier.Value.of([d]) 0 * _ when: @@ -952,16 +957,17 @@ abstract class AbstractDomainObjectCollectionSpec extends Specification { filtered.configureEach(action) then: - 0 * provider1.get() - 0 * provider2.get() - 0 * action.execute(_) + 0 * _ when: def result = toList(filtered) then: - 1 * provider1.get() >> a - 1 * provider2.get() >> b + 1 * provider1.getOrNull() >> a + 1 * provider2.getOrNull() >> b + 0 * _ + + and: result == iterationOrder(a, b) and: @@ -986,9 +992,9 @@ abstract class AbstractDomainObjectCollectionSpec extends Specification { filtered.configureEach(action) then: - 0 * provider1.get() - 0 * provider2.get() - 0 * action.execute(_) + _ * provider1.size() >> 1 + _ * provider2.size() >> 2 + 0 * _ when: def result = toList(filtered) @@ -996,8 +1002,11 @@ abstract class AbstractDomainObjectCollectionSpec extends Specification { then: _ * provider1.size() >> 1 _ * provider2.size() >> 2 - 1 * provider1.get() >> [a] - 1 * provider2.get() >> [c, b] + 1 * provider1.calculateValue() >> ValueSupplier.Value.of([a]) + 1 * provider2.calculateValue() >> ValueSupplier.Value.of([c, b]) + 0 * _ + + and: result == iterationOrder(a, c, b) and: @@ -1023,16 +1032,17 @@ abstract class AbstractDomainObjectCollectionSpec extends Specification { filtered.configureEach(action) then: - 0 * provider1.get() - 0 * provider2.get() - 0 * action.execute(_) + 0 * _ when: def result = toList(filtered) then: 0 * provider1.get() >> a - 1 * provider2.get() >> b + 1 * provider2.getOrNull() >> b + 0 * _ + + and: result == iterationOrder(b) and: @@ -1057,9 +1067,9 @@ abstract class AbstractDomainObjectCollectionSpec extends Specification { filtered.configureEach(action) then: - 0 * provider1.get() - 0 * provider2.get() - 0 * action.execute(_) + _ * provider1.size() >> 1 + _ * provider2.size() >> 2 + 0 * _ when: def result = toList(filtered) @@ -1067,8 +1077,11 @@ abstract class AbstractDomainObjectCollectionSpec extends Specification { then: _ * provider1.size() >> 1 _ * provider2.size() >> 2 - 0 * provider1.get() >> [a] - 1 * provider2.get() >> [b, c] + 0 * provider1.get() + 1 * provider2.calculateValue() >> ValueSupplier.Value.of([b, c]) + 0 * _ + + and: result == iterationOrder(b, c) and: @@ -1094,15 +1107,17 @@ abstract class AbstractDomainObjectCollectionSpec extends Specification { filtered.configureEach(action) then: - 0 * provider1.get() - 0 * provider2.get() + 0 * _ when: def result = toList(filtered) then: - 1 * provider1.get() >> a - 1 * provider2.get() >> b + 1 * provider1.getOrNull() >> a + 1 * provider2.getOrNull() >> b + 0 * _ + + and: result == iterationOrder(b) and: @@ -1128,15 +1143,17 @@ abstract class AbstractDomainObjectCollectionSpec extends Specification { didRemoved and: - 0 * provider1.get() - 0 * provider2.get() + 0 * _ when: def result = toList(container) then: - 0 * provider1.get() - 1 * provider2.get() >> b + 0 * provider1.getOrNull() + 1 * provider2.getOrNull() >> b + 0 * _ + + and: result == iterationOrder(b) } @@ -1157,7 +1174,8 @@ abstract class AbstractDomainObjectCollectionSpec extends Specification { toList(container) == [] and: - 0 * provider1.get() + _ * provider1.type >> type + 0 * _ when: def didRemovedSecondTime = container.remove(provider1) @@ -1167,8 +1185,9 @@ abstract class AbstractDomainObjectCollectionSpec extends Specification { toList(container) == [] and: + _ * provider1.type >> type 1 * provider1.present >> false - 0 * provider1.get() + 0 * _ } def "can remove realized external providers without realizing more providers"() { @@ -1179,10 +1198,10 @@ abstract class AbstractDomainObjectCollectionSpec extends Specification { given: _ * provider1.type >> type - _ * provider1.get() >> a + _ * provider1.getOrNull() >> a _ * provider1.present >> true _ * provider2.type >> type - _ * provider2.get() >> b + _ * provider2.getOrNull() >> b _ * provider2.present >> true _ * provider3.type >> otherType container.addLater(provider1) @@ -1199,9 +1218,10 @@ abstract class AbstractDomainObjectCollectionSpec extends Specification { didRemoved1 and: + _ * provider1.type >> type + 1 * provider1.present >> true 1 * provider1.get() >> a - 0 * provider2.get() - 0 * provider3.get() + 0 * _ when: def didRemoved2 = container.remove(provider2) @@ -1210,9 +1230,10 @@ abstract class AbstractDomainObjectCollectionSpec extends Specification { didRemoved2 and: - 0 * provider1.get() + _ * provider2.type >> type + 1 * provider2.present >> true 1 * provider2.get() >> b - 0 * provider3.get() + 0 * _ } def "can remove realized external elements via instance"() { @@ -1222,7 +1243,7 @@ abstract class AbstractDomainObjectCollectionSpec extends Specification { given: _ * provider1.type >> type - _ * provider1.get() >> a + _ * provider1.getOrNull() >> a _ * provider2.type >> otherType container.addLater(provider1) container.addLater(provider2) @@ -1237,8 +1258,7 @@ abstract class AbstractDomainObjectCollectionSpec extends Specification { didRemoved and: - 0 * provider1.get() - 0 * provider2.get() + 0 * _ } def "will execute remove action when removing external provider only for realized elements"() { @@ -1249,6 +1269,7 @@ abstract class AbstractDomainObjectCollectionSpec extends Specification { given: _ * provider1.type >> type + _ * provider1.getOrNull() >> a _ * provider1.get() >> a _ * provider1.present >> true _ * provider2.type >> otherType @@ -1265,9 +1286,14 @@ abstract class AbstractDomainObjectCollectionSpec extends Specification { then: didRemoved1 + and: + _ * provider1.type >> type + 1 * provider1.present >> true + 1 * provider1.get() >> a + and: 1 * action.execute(a) - 0 * action.execute(_) + 0 * _ when: def didRemoved2 = container.remove(provider2) @@ -1276,7 +1302,7 @@ abstract class AbstractDomainObjectCollectionSpec extends Specification { didRemoved2 and: - 0 * action.execute(_) + 0 * _ } def "will execute remove action when clearing the container only for realized external providers"() { @@ -1287,7 +1313,7 @@ abstract class AbstractDomainObjectCollectionSpec extends Specification { given: _ * provider1.type >> type - _ * provider1.get() >> a + _ * provider1.getOrNull() >> a _ * provider2.type >> otherType container.addLater(provider1) container.addLater(provider2) @@ -1301,7 +1327,7 @@ abstract class AbstractDomainObjectCollectionSpec extends Specification { then: 1 * action.execute(a) - 0 * action.execute(_) + 0 * _ when: def result = toList(container) @@ -1325,15 +1351,15 @@ abstract class AbstractDomainObjectCollectionSpec extends Specification { container.clear() then: - 0 * provider1.get() - 0 * provider2.get() + 0 * _ when: def result = toList(container) then: - 0 * provider1.get() - 0 * provider2.get() + 0 * _ + + and: result == iterationOrder() } @@ -1345,9 +1371,9 @@ abstract class AbstractDomainObjectCollectionSpec extends Specification { given: _ * provider1.type >> type - _ * provider1.get() >> a + _ * provider1.getOrNull() >> a _ * provider2.type >> otherType - _ * provider2.get() >> d + _ * provider2.getOrNull() >> d container.addLater(provider1) container.addLater(provider2) container.whenObjectRemoved(action) @@ -1362,15 +1388,19 @@ abstract class AbstractDomainObjectCollectionSpec extends Specification { didRetained and: + 1 * provider2.getOrNull() >> d 1 * action.execute(a) 1 * action.execute(d) - 0 * action.execute(_) + 0 * _ when: def result = toList(container) then: result == iterationOrder() + + and: + 0 * _ } def "will query external providers when not retaining them"() { @@ -1391,15 +1421,17 @@ abstract class AbstractDomainObjectCollectionSpec extends Specification { didRetained and: - 1 * provider1.get() >> a - 1 * provider2.get() >> b + 1 * provider1.getOrNull() >> a + 1 * provider2.getOrNull() >> b + 0 * _ when: def result = toList(container) then: - 0 * provider1.get() - 0 * provider2.get() + 0 * _ + + and: result == iterationOrder(b) } @@ -1410,9 +1442,9 @@ abstract class AbstractDomainObjectCollectionSpec extends Specification { given: _ * provider1.type >> type - _ * provider1.get() >> a + _ * provider1.getOrNull() >> a _ * provider2.type >> otherType - _ * provider2.get() >> d + _ * provider2.getOrNull() >> d container.addLater(provider1) container.addLater(provider2) @@ -1426,13 +1458,16 @@ abstract class AbstractDomainObjectCollectionSpec extends Specification { didRetained and: - 0 * provider1.get() - 1 * provider2.get() >> d + 1 * provider2.getOrNull() >> d + 0 * _ when: def result = toList(container) then: + 0 * _ + + and: result == iterationOrder(a) } @@ -1453,8 +1488,9 @@ abstract class AbstractDomainObjectCollectionSpec extends Specification { filtered.configureEach(action) then: - 0 * provider1.get() - 0 * provider2.get() + _ * provider1.size() >> 1 + _ * provider2.size() >> 2 + 0 * _ when: def result = toList(filtered) @@ -1462,8 +1498,11 @@ abstract class AbstractDomainObjectCollectionSpec extends Specification { then: _ * provider1.size() >> 1 _ * provider2.size() >> 2 - 1 * provider1.get() >> [a] - 1 * provider2.get() >> [b, c] + 1 * provider1.calculateValue() >> ValueSupplier.Value.of([a]) + 1 * provider2.calculateValue() >> ValueSupplier.Value.of([b, c]) + 0 * _ + + and: result == iterationOrder(b) and: @@ -1487,15 +1526,18 @@ abstract class AbstractDomainObjectCollectionSpec extends Specification { container.withType(type).iterator() then: - 1 * provider1.get() >> a - 0 * provider2.get() + 1 * provider1.getOrNull() >> a + 0 * _ when: def result = toList(container) then: 0 * provider1.get() - 1 * provider2.get() >> b + 1 * provider2.getOrNull() >> b + 0 * _ + + and: result == iterationOrder(a, b) } @@ -1507,9 +1549,9 @@ abstract class AbstractDomainObjectCollectionSpec extends Specification { given: _ * provider1.type >> type - _ * provider1.get() >> a + _ * provider1.getOrNull() >> a _ * provider2.type >> type - _ * provider2.get() >> b + _ * provider2.getOrNull() >> b container.addLater(provider1) container.addLater(provider2) container.whenObjectRemoved(action) @@ -1524,8 +1566,10 @@ abstract class AbstractDomainObjectCollectionSpec extends Specification { result == iterationOrder(b) and: + 1 * provider1.getOrNull() >> a + 1 * provider2.getOrNull() >> b 1 * action.execute(a) - 0 * action.execute(_) + 0 * _ } def "will execute remove action when removing a collection of external provider only for realized elements"() { @@ -1536,6 +1580,7 @@ abstract class AbstractDomainObjectCollectionSpec extends Specification { given: _ * provider1.type >> type + _ * provider1.getOrNull() >> a _ * provider1.get() >> a _ * provider1.present >> true _ * provider2.type >> otherType @@ -1554,8 +1599,11 @@ abstract class AbstractDomainObjectCollectionSpec extends Specification { container.empty and: + _ * provider1.type >> type + 1 * provider1.present >> true + 1 * provider1.get() >> a 1 * action.execute(a) - 0 * action.execute(_) + 0 * _ } void setupContainerDefaults() {} diff --git a/subprojects/core/src/test/groovy/org/gradle/api/internal/DefaultDomainObjectCollectionTest.groovy b/subprojects/core/src/test/groovy/org/gradle/api/internal/DefaultDomainObjectCollectionTest.groovy index 3307831aad11..6e1146457824 100644 --- a/subprojects/core/src/test/groovy/org/gradle/api/internal/DefaultDomainObjectCollectionTest.groovy +++ b/subprojects/core/src/test/groovy/org/gradle/api/internal/DefaultDomainObjectCollectionTest.groovy @@ -298,7 +298,7 @@ class DefaultDomainObjectCollectionTest extends AbstractDomainObjectCollectionSp def callsRemoveActionWhenObjectRemovedUsingIteratorNoFlushAndLastElementIsUnrealized() { def action = Mock(Action) def provider = Mock(ProviderInternal) - _ * provider.get() >> "c" + _ * provider.getOrNull() >> "c" container.whenObjectRemoved(action) container.add("a") diff --git a/subprojects/core/src/test/groovy/org/gradle/api/internal/collections/DefaultPendingSourceTest.groovy b/subprojects/core/src/test/groovy/org/gradle/api/internal/collections/DefaultPendingSourceTest.groovy index 0becc0b2d60d..afcbca60939b 100644 --- a/subprojects/core/src/test/groovy/org/gradle/api/internal/collections/DefaultPendingSourceTest.groovy +++ b/subprojects/core/src/test/groovy/org/gradle/api/internal/collections/DefaultPendingSourceTest.groovy @@ -29,9 +29,9 @@ class DefaultPendingSourceTest extends Specification { def setup() { pending.onRealize(realize) - _ * provider1.get() >> "provider1" - _ * provider2.get() >> "provider2" - _ * provider3.get() >> "provider3" + _ * provider1.getOrNull() >> "provider1" + _ * provider2.getOrNull() >> "provider2" + _ * provider3.getOrNull() >> "provider3" } def "realizes pending elements on flush"() { diff --git a/subprojects/model-core/src/integTest/groovy/org/gradle/api/provider/CollectionPropertyIntegrationTest.groovy b/subprojects/model-core/src/integTest/groovy/org/gradle/api/provider/CollectionPropertyIntegrationTest.groovy index ffaba19e4028..5280f33193c9 100644 --- a/subprojects/model-core/src/integTest/groovy/org/gradle/api/provider/CollectionPropertyIntegrationTest.groovy +++ b/subprojects/model-core/src/integTest/groovy/org/gradle/api/provider/CollectionPropertyIntegrationTest.groovy @@ -27,7 +27,7 @@ class CollectionPropertyIntegrationTest extends AbstractIntegrationSpec { final ListProperty prop = project.objects.listProperty(String) @Internal List expected = [] - + @TaskAction void validate() { def actual = prop.getOrNull() @@ -37,7 +37,7 @@ class CollectionPropertyIntegrationTest extends AbstractIntegrationSpec { actual.each { assert it instanceof String } } } - + task verify(type: MyTask) """ } @@ -54,13 +54,13 @@ class CollectionPropertyIntegrationTest extends AbstractIntegrationSpec { abstract class ATask extends DefaultTask { @Input abstract ListProperty<$type> getProp() - + @TaskAction void go() { println("prop = \${prop.get()}") } } - + tasks.create("thing", ATask) { prop = $value } @@ -87,8 +87,8 @@ def provider = providers.provider { [++counter, ++counter] } def property = objects.listProperty(Integer) property.set(provider) -assert property.get() == [1, 2] -assert property.get() == [3, 4] +assert property.get() == [1, 2] +assert property.get() == [3, 4] property.finalizeValue() assert property.get() == [5, 6] assert property.get() == [5, 6] @@ -112,8 +112,8 @@ def provider = providers.provider { [++counter, ++counter] } def property = objects.listProperty(Integer) property.set(provider) -assert property.get() == [1, 2] -assert property.get() == [3, 4] +assert property.get() == [1, 2] +assert property.get() == [3, 4] property.disallowChanges() assert property.get() == [5, 6] assert property.get() == [7, 8] @@ -134,10 +134,10 @@ property.set([1]) class SomeTask extends DefaultTask { @Input final ListProperty prop = project.objects.listProperty(String) - + @OutputFile final Property outputFile = project.objects.fileProperty() - + @TaskAction void go() { outputFile.get().asFile.text = prop.get() @@ -453,4 +453,30 @@ task wrongPropertyElementTypeApi { expect: succeeds("verify") } + + def "fails when property with no value is queried"() { + given: + buildFile << """ + abstract class SomeTask extends DefaultTask { + @Internal + abstract ListProperty getProp() + + @TaskAction + def go() { + prop.set((Iterable)null) + prop.get() + } + } + + tasks.register('thing', SomeTask) + """ + + when: + fails("thing") + + then: + failure.assertHasDescription("Execution failed for task ':thing'.") + failure.assertHasCause("Cannot query the value of task ':thing' property 'prop' because it has no value available.") + } + } diff --git a/subprojects/model-core/src/integTest/groovy/org/gradle/api/provider/MapPropertyIntegrationTest.groovy b/subprojects/model-core/src/integTest/groovy/org/gradle/api/provider/MapPropertyIntegrationTest.groovy index 2915415acc5c..d351a6650ff2 100644 --- a/subprojects/model-core/src/integTest/groovy/org/gradle/api/provider/MapPropertyIntegrationTest.groovy +++ b/subprojects/model-core/src/integTest/groovy/org/gradle/api/provider/MapPropertyIntegrationTest.groovy @@ -32,13 +32,13 @@ class MapPropertyIntegrationTest extends AbstractIntegrationSpec { final Class keyType @Internal final Class valueType - + AbstractVerificationTask(Class keyType, Class valueType) { this.keyType = keyType this.valueType = valueType prop = project.objects.mapProperty(keyType, valueType) } - + @TaskAction void validate() { def actual = prop.getOrNull() @@ -49,17 +49,17 @@ class MapPropertyIntegrationTest extends AbstractIntegrationSpec { assert keyType.isInstance(it.key) assert valueType.isInstance(it.value) } - } + } } class StringVerificationTask extends AbstractVerificationTask { StringVerificationTask() { super(String, String) } } - + class IntegerVerificationTask extends AbstractVerificationTask { IntegerVerificationTask() { super(Integer, Integer) } } - + task verify(type: StringVerificationTask) task verifyInt(type: IntegerVerificationTask) ''' @@ -77,17 +77,17 @@ class MapPropertyIntegrationTest extends AbstractIntegrationSpec { abstract class MyTask extends DefaultTask { @Input abstract MapProperty<$keyType, $valueType> getProp() - + @TaskAction void go() { println("prop = \${prop.get()}") } } - + def key = new Param(display: 'a') def map = [:] map[key] = new Param(display: 12) - + tasks.create("thing", MyTask) { prop = $value } @@ -110,16 +110,16 @@ class MapPropertyIntegrationTest extends AbstractIntegrationSpec { buildFile << ''' int counter = 0 def provider = providers.provider { [(++counter): ++counter] } - + def property = objects.mapProperty(Integer, Integer) property.set(provider) - + assert property.get() == [1: 2] assert property.get() == [3: 4] property.finalizeValue() assert property.get() == [5: 6] assert property.get() == [5: 6] - + property.set([1: 2]) '''.stripIndent() @@ -135,16 +135,16 @@ class MapPropertyIntegrationTest extends AbstractIntegrationSpec { buildFile << ''' int counter = 0 def provider = providers.provider { [(++counter): ++counter] } - + def property = objects.mapProperty(Integer, Integer) property.set(provider) - + assert property.get() == [1: 2] assert property.get() == [3: 4] property.disallowChanges() assert property.get() == [5: 6] assert property.get() == [7: 8] - + property.set([1: 2]) '''.stripIndent() @@ -161,16 +161,16 @@ class MapPropertyIntegrationTest extends AbstractIntegrationSpec { class SomeTask extends DefaultTask { @Input final MapProperty prop = project.objects.mapProperty(String, String) - + @OutputFile final Property outputFile = project.objects.fileProperty() - + @TaskAction void go() { outputFile.get().asFile.text = prop.get() } } - + task thing(type: SomeTask) { prop = ['key1': 'value1'] outputFile = layout.buildDirectory.file('out.txt') @@ -178,11 +178,11 @@ class MapPropertyIntegrationTest extends AbstractIntegrationSpec { prop.set(['ignoredKey': 'ignoredValue']) } } - + afterEvaluate { thing.prop = ['key2': 'value2'] } - + task before { doLast { thing.prop = providers.provider { ['finalKey': 'finalValue'] } @@ -203,7 +203,7 @@ class MapPropertyIntegrationTest extends AbstractIntegrationSpec { given: buildFile << ''' def prop = project.objects.mapProperty(String, String) - + task thing { inputs.property('prop', prop) prop.set(['key1': 'value1']) @@ -250,7 +250,7 @@ task thing { buildFile << """ verify { prop = ${value} - expected = ['key1': 'value1', 'key2': 'value2'] + expected = ['key1': 'value1', 'key2': 'value2'] } """.stripIndent() @@ -271,7 +271,7 @@ task thing { prop.empty() prop['key1'] = 'value1' prop['key2'] = project.provider { 'value2' } - expected = ['key1': 'value1', 'key2': 'value2'] + expected = ['key1': 'value1', 'key2': 'value2'] } '''.stripIndent() @@ -286,7 +286,7 @@ task thing { prop.empty() prop[1] = 111 prop[2] = project.provider { 222 } - expected = [1: 111, 2: 222] + expected = [1: 111, 2: 222] } '''.stripIndent() @@ -301,7 +301,7 @@ task thing { def str = "aBc" verify { prop = ${value} - expected = ['a': 'b'] + expected = ['a': 'b'] } """.stripIndent() @@ -324,7 +324,7 @@ task thing { prop.putAll(['key4': 'value4']) prop.putAll(project.provider { ['key5': 'value5'] }) expected = ['key1': 'value1', 'key2': 'value2', 'key3': 'value3', 'key4': 'value4', 'key5': 'value5'] - } + } '''.stripIndent() } @@ -338,7 +338,7 @@ task thing { prop.putAll(['key3': 'value3']) prop.putAll(project.provider { ['key4': 'value4'] }) expected = ['key1': 'value1', 'key2': 'value2', 'key3': 'value3', 'key4': 'value4'] - } + } '''.stripIndent() expect: @@ -354,7 +354,7 @@ task thing { prop = ['key': 'value'] prop.putAll(${value}) expected = ['key': 'value', 'b': 'c'] - } + } """.stripIndent() expect: @@ -375,7 +375,7 @@ task thing { prop = ['key': 'value'] prop.put(${key}, ${value}) expected = ['key': 'value', 'a': 'b'] - } + } """.stripIndent() expect: @@ -395,51 +395,51 @@ task thing { verify.prop = 123 } } - + task wrongRuntimeKeyType { doLast { verify.prop = [123: 'value'] verify.prop.get() } } - + task wrongRuntimeValueType { doLast { verify.prop = ['key': 123] verify.prop.get() } } - + task wrongPropertyTypeDsl { doLast { verify.prop = objects.property(Integer) } } - + task wrongPropertyTypeApi { doLast { verify.prop.set(objects.property(Integer)) } } - + task wrongRuntimeKeyTypeDsl { doLast { verify.prop = objects.mapProperty(Integer, String) } } - + task wrongRuntimeValueTypeDsl { doLast { verify.prop = objects.mapProperty(String, Integer) } } - + task wrongRuntimeKeyTypeApi { doLast { verify.prop.set(objects.mapProperty(Integer, String)) } } - + task wrongRuntimeValueTypeApi { doLast { verify.prop.set(objects.mapProperty(String, Integer)) @@ -513,21 +513,21 @@ task thing { verify.expected = ['key': 'newValue'] } } - + task replacingPutWithProvider { doLast { verify.prop.put('key', project.provider { 'newValue' }) verify.expected = ['key': 'newValue'] } } - + task replacingPutAll { doLast { verify.prop.putAll(['key': 'newValue', 'otherKey': 'otherValue']) verify.expected = ['key': 'newValue', 'otherKey': 'otherValue'] } } - + task replacingPutAllWithProvider { doLast { verify.prop.putAll(project.provider { ['key': 'newValue', 'otherKey': 'otherValue'] }) @@ -556,7 +556,7 @@ task thing { prop.putAll(['key3': 'value3']) prop.putAll(project.provider { ['key4': 'value4'] }) expected = null - } + } '''.stripIndent() expect: @@ -595,7 +595,7 @@ task thing { verify { prop.put('key', project.provider { null }) expected = null - } + } '''.stripIndent() expect: @@ -608,10 +608,35 @@ task thing { verify { prop.putAll(project.provider { null }) expected = null - } + } '''.stripIndent() expect: succeeds('verify') } + + def "fails when property with no value is queried"() { + given: + buildFile << """ + abstract class SomeTask extends DefaultTask { + @Internal + abstract MapProperty getProp() + + @TaskAction + def go() { + prop.set((Map)null) + prop.get() + } + } + + tasks.register('thing', SomeTask) + """ + + when: + fails("thing") + + then: + failure.assertHasDescription("Execution failed for task ':thing'.") + failure.assertHasCause("Cannot query the value of task ':thing' property 'prop' because it has no value available.") + } } diff --git a/subprojects/model-core/src/integTest/groovy/org/gradle/api/provider/PropertyIntegrationTest.groovy b/subprojects/model-core/src/integTest/groovy/org/gradle/api/provider/PropertyIntegrationTest.groovy index 2b4265240266..d58e9e63417c 100644 --- a/subprojects/model-core/src/integTest/groovy/org/gradle/api/provider/PropertyIntegrationTest.groovy +++ b/subprojects/model-core/src/integTest/groovy/org/gradle/api/provider/PropertyIntegrationTest.groovy @@ -148,9 +148,7 @@ task thing(type: SomeTask) { } } - tasks.register('thing', SomeTask) { - prop - } + tasks.register('thing', SomeTask) """ when: diff --git a/subprojects/model-core/src/main/java/org/gradle/api/internal/provider/AbstractCollectionProperty.java b/subprojects/model-core/src/main/java/org/gradle/api/internal/provider/AbstractCollectionProperty.java index 3156b484ff55..ec74ee4957f7 100644 --- a/subprojects/model-core/src/main/java/org/gradle/api/internal/provider/AbstractCollectionProperty.java +++ b/subprojects/model-core/src/main/java/org/gradle/api/internal/provider/AbstractCollectionProperty.java @@ -29,7 +29,6 @@ import org.gradle.api.internal.tasks.TaskDependencyResolveContext; import org.gradle.api.provider.HasMultipleValues; import org.gradle.api.provider.Provider; -import org.gradle.internal.DisplayName; import javax.annotation.Nullable; import java.util.ArrayList; @@ -144,31 +143,22 @@ public void providers(List>> pr @Override public boolean isPresent() { beforeRead(); - return value.present(); + return value.isPresent(); } @Override - public C get() { + protected Value calculateOwnValue() { beforeRead(); - List values = new ArrayList(); - value.collectInto(getDisplayName(), valueCollector, values); - return fromValue(values); + return doCalculateOwnValue(); } - @Nullable - @Override - public C getOrNull() { - beforeRead(); - return doGetOrNull(); - } - - @Nullable - private C doGetOrNull() { - List values = new ArrayList(); - if (!value.maybeCollectInto(valueCollector, values)) { - return null; + private Value doCalculateOwnValue() { + List values = new ArrayList<>(); + Value result = value.maybeCollectInto(valueCollector, values); + if (result.isMissing()) { + return result.asType(); } - return fromValue(values); + return Value.of(fromValue(values)); } @Override @@ -246,7 +236,7 @@ protected void applyDefaultValue() { @Override protected void makeFinal() { - C collection = doGetOrNull(); + C collection = doCalculateOwnValue().orNull(); if (collection != null) { set(new ElementsFromCollection(collection)); } else { @@ -293,8 +283,8 @@ public PlusCollector(Collector left, Collector right) { } @Override - public boolean present() { - return left.present() && right.present(); + public boolean isPresent() { + return left.isPresent() && right.isPresent(); } @Override @@ -303,17 +293,12 @@ public int size() { } @Override - public void collectInto(DisplayName owner, ValueCollector collector, Collection dest) { - left.collectInto(owner, collector, dest); - right.collectInto(owner, collector, dest); - } - - @Override - public boolean maybeCollectInto(ValueCollector collector, Collection dest) { - if (left.maybeCollectInto(collector, dest)) { - return right.maybeCollectInto(collector, dest); + public Value maybeCollectInto(ValueCollector collector, Collection dest) { + Value value = left.maybeCollectInto(collector, dest); + if (value.isMissing()) { + return value; } - return false; + return right.maybeCollectInto(collector, dest); } @Override diff --git a/subprojects/model-core/src/main/java/org/gradle/api/internal/provider/AbstractProperty.java b/subprojects/model-core/src/main/java/org/gradle/api/internal/provider/AbstractProperty.java index 2f474d330260..9baa1f73af5d 100644 --- a/subprojects/model-core/src/main/java/org/gradle/api/internal/provider/AbstractProperty.java +++ b/subprojects/model-core/src/main/java/org/gradle/api/internal/provider/AbstractProperty.java @@ -21,6 +21,9 @@ import org.gradle.api.internal.tasks.TaskDependencyResolveContext; import org.gradle.internal.Describables; import org.gradle.internal.DisplayName; +import org.gradle.internal.logging.text.TreeFormatter; + +import javax.annotation.Nullable; public abstract class AbstractProperty extends AbstractMinimalProvider implements PropertyInternal { private enum State { @@ -41,6 +44,11 @@ public void attachDisplayName(DisplayName displayName) { this.displayName = displayName; } + @Nullable + protected DisplayName getDeclaredDisplayName() { + return displayName; + } + protected DisplayName getDisplayName() { if (displayName == null) { return DEFAULT_DISPLAY_NAME; @@ -80,6 +88,42 @@ public final String toString() { } } + protected abstract ScalarSupplier.Value calculateOwnValue(); + + @Override + public Value calculateValue() { + return calculateOwnValue().pushWhenMissing(getDeclaredDisplayName()); + } + + @Override + public T get() { + Value value = calculateOwnValue(); + if (value.isMissing()) { + TreeFormatter formatter = new TreeFormatter(); + formatter.node("Cannot query the value of ").append(getDisplayName().getDisplayName()).append(" because it has no value available."); + if (!value.getPathToOrigin().isEmpty()) { + formatter.node("The value of this property is derived from"); + formatter.startChildren(); + for (DisplayName displayName : value.getPathToOrigin()) { + formatter.node(displayName.getDisplayName()); + } + formatter.endChildren(); + } + throw new MissingValueException(formatter.toString()); + } + return value.get(); + } + + @Override + public T getOrNull() { + return calculateOwnValue().orNull(); + } + + @Override + public T getOrElse(T defaultValue) { + return calculateOwnValue().orElse(defaultValue); + } + @Override public void visitProducerTasks(Action visitor) { if (producer != null) { diff --git a/subprojects/model-core/src/main/java/org/gradle/api/internal/provider/Collector.java b/subprojects/model-core/src/main/java/org/gradle/api/internal/provider/Collector.java index 203666aa9057..443ebec50576 100644 --- a/subprojects/model-core/src/main/java/org/gradle/api/internal/provider/Collector.java +++ b/subprojects/model-core/src/main/java/org/gradle/api/internal/provider/Collector.java @@ -16,8 +16,6 @@ package org.gradle.api.internal.provider; -import org.gradle.internal.DisplayName; - import java.util.Collection; import java.util.List; @@ -25,11 +23,7 @@ * A supplier of zero or more values of type {@link T}. */ public interface Collector extends ValueSupplier { - boolean present(); - - void collectInto(DisplayName owner, ValueCollector collector, Collection dest); - - boolean maybeCollectInto(ValueCollector collector, Collection dest); + Value maybeCollectInto(ValueCollector collector, Collection dest); int size(); diff --git a/subprojects/model-core/src/main/java/org/gradle/api/internal/provider/Collectors.java b/subprojects/model-core/src/main/java/org/gradle/api/internal/provider/Collectors.java index 7cb49a949be8..7905fb532cc7 100644 --- a/subprojects/model-core/src/main/java/org/gradle/api/internal/provider/Collectors.java +++ b/subprojects/model-core/src/main/java/org/gradle/api/internal/provider/Collectors.java @@ -23,7 +23,6 @@ import org.gradle.api.Task; import org.gradle.api.internal.tasks.TaskDependencyResolveContext; import org.gradle.api.provider.Provider; -import org.gradle.internal.DisplayName; import javax.annotation.Nullable; import java.util.Collection; @@ -36,17 +35,13 @@ public interface ProvidedCollector extends Collector { public static class EmptyCollection implements Collector { @Override - public boolean present() { + public boolean isPresent() { return true; } @Override - public boolean maybeCollectInto(ValueCollector collector, Collection collection) { - return true; - } - - @Override - public void collectInto(DisplayName owner, ValueCollector collector, Collection dest) { + public Value maybeCollectInto(ValueCollector collector, Collection collection) { + return Value.present(); } @Override @@ -81,19 +76,14 @@ public SingleElement(T element) { } @Override - public boolean present() { + public boolean isPresent() { return true; } @Override - public void collectInto(DisplayName owner, ValueCollector collector, Collection collection) { - collector.add(element, collection); - } - - @Override - public boolean maybeCollectInto(ValueCollector collector, Collection collection) { + public Value maybeCollectInto(ValueCollector collector, Collection collection) { collector.add(element, collection); - return true; + return Value.present(); } @Override @@ -146,24 +136,18 @@ public ElementFromProvider(ProviderInternal providerOfElement) { } @Override - public boolean present() { + public boolean isPresent() { return providerOfElement.isPresent(); } @Override - public void collectInto(DisplayName owner, ValueCollector collector, Collection collection) { - T value = providerOfElement.get(); - collector.add(value, collection); - } - - @Override - public boolean maybeCollectInto(ValueCollector collector, Collection collection) { + public Value maybeCollectInto(ValueCollector collector, Collection collection) { T value = providerOfElement.getOrNull(); if (value == null) { - return false; + return Value.missing(); } collector.add(value, collection); - return true; + return Value.present(); } @Override @@ -222,19 +206,14 @@ public ElementsFromCollection(Iterable value) { } @Override - public boolean present() { + public boolean isPresent() { return true; } @Override - public void collectInto(DisplayName owner, ValueCollector collector, Collection collection) { + public Value maybeCollectInto(ValueCollector collector, Collection collection) { collector.addAll(value, collection); - } - - @Override - public boolean maybeCollectInto(ValueCollector collector, Collection collection) { - collector.addAll(value, collection); - return true; + return Value.present(); } @Override @@ -287,24 +266,18 @@ public ElementsFromCollectionProvider(ProviderInternal collector, Collection collection) { - Iterable value = provider.get(); - collector.addAll(value, collection); - } - - @Override - public boolean maybeCollectInto(ValueCollector collector, Collection collection) { - Iterable value = provider.getOrNull(); - if (value == null) { - return false; + public Value maybeCollectInto(ValueCollector collector, Collection collection) { + Value> value = provider.calculateValue(); + if (value.isMissing()) { + return value.asType(); } - collector.addAll(value, collection); - return true; + collector.addAll(value.get(), collection); + return Value.present(); } @Override @@ -361,18 +334,13 @@ public int size() { public static class NoValueCollector implements Collector { @Override - public boolean present() { + public boolean isPresent() { return false; } @Override - public void collectInto(DisplayName owner, ValueCollector collector, Collection dest) { - throw Providers.nullValue(owner); - } - - @Override - public boolean maybeCollectInto(ValueCollector collector, Collection collection) { - return false; + public Value maybeCollectInto(ValueCollector collector, Collection collection) { + return Value.missing(); } @Override @@ -407,21 +375,16 @@ public static class ElementsFromArray implements Collector { } @Override - public boolean present() { + public boolean isPresent() { return true; } @Override - public void collectInto(DisplayName owner, ValueCollector collector, Collection dest) { + public Value maybeCollectInto(ValueCollector collector, Collection dest) { for (T t : value) { collector.add(t, dest); } - } - - @Override - public boolean maybeCollectInto(ValueCollector collector, Collection dest) { - collectInto(null, collector, dest); - return true; + return Value.present(); } @Override @@ -466,21 +429,16 @@ public Class getType() { } @Override - public boolean present() { - return delegate.present(); + public boolean isPresent() { + return delegate.isPresent(); } public void collectInto(Collection collection) { - delegate.collectInto(null, valueCollector, collection); - } - - @Override - public void collectInto(DisplayName owner, ValueCollector collector, Collection dest) { - delegate.collectInto(owner, collector, dest); + maybeCollectInto(valueCollector, collection); } @Override - public boolean maybeCollectInto(ValueCollector collector, Collection dest) { + public Value maybeCollectInto(ValueCollector collector, Collection dest) { return delegate.maybeCollectInto(collector, dest); } diff --git a/subprojects/model-core/src/main/java/org/gradle/api/internal/provider/DefaultMapProperty.java b/subprojects/model-core/src/main/java/org/gradle/api/internal/provider/DefaultMapProperty.java index a2c533b05db9..b5dbc03a9de2 100644 --- a/subprojects/model-core/src/main/java/org/gradle/api/internal/provider/DefaultMapProperty.java +++ b/subprojects/model-core/src/main/java/org/gradle/api/internal/provider/DefaultMapProperty.java @@ -25,7 +25,7 @@ import org.gradle.api.provider.MapProperty; import org.gradle.api.provider.Provider; import org.gradle.internal.Cast; -import org.gradle.internal.DisplayName; +import org.jetbrains.annotations.NotNull; import javax.annotation.Nullable; import java.util.ArrayList; @@ -96,31 +96,23 @@ public int getFactoryId() { @Override public boolean isPresent() { beforeRead(); - return value.present(); + return value.isPresent(); } @Override - public Map get() { + protected Value> calculateOwnValue() { beforeRead(); - Map entries = new LinkedHashMap<>(); - value.collectInto(getDisplayName(), entryCollector, entries); - return ImmutableMap.copyOf(entries); - } - - @Nullable - @Override - public Map getOrNull() { - beforeRead(); - return doGetOrNull(); + return doCalculateOwnValue(); } - @Nullable - private Map doGetOrNull() { + @NotNull + private Value> doCalculateOwnValue() { Map entries = new LinkedHashMap<>(); - if (!value.maybeCollectInto(entryCollector, entries)) { - return null; + Value result = value.maybeCollectInto(entryCollector, entries); + if (result.isMissing()) { + return result.asType(); } - return ImmutableMap.copyOf(entries); + return Value.of(ImmutableMap.copyOf(entries)); } @Override @@ -131,10 +123,11 @@ public Provider getting(final K key) { public V call() { beforeRead(); Map dest = new LinkedHashMap<>(); - if (value.maybeCollectInto(entryCollector, dest)) { - return dest.get(key); + Value result = value.maybeCollectInto(entryCollector, dest); + if (result.isMissing()) { + return null; } - return null; + return dest.get(key); } }); } @@ -322,7 +315,7 @@ protected void applyDefaultValue() { @Override @SuppressWarnings("unchecked") protected void makeFinal() { - Map entries = doGetOrNull(); + Map entries = doCalculateOwnValue().orNull(); if (entries != null) { if (entries.isEmpty()) { set((MapCollector) EMPTY_MAP); @@ -343,20 +336,13 @@ public Class> getType() { return (Class) Set.class; } - @Override - public Set get() { - beforeRead(); - Set keys = new LinkedHashSet<>(); - value.collectKeysInto(keyCollector, keys); - return ImmutableSet.copyOf(keys); - } - @Nullable @Override public Set getOrNull() { beforeRead(); Set keys = new LinkedHashSet<>(); - if (!value.maybeCollectKeysInto(keyCollector, keys)) { + Value result = value.maybeCollectKeysInto(keyCollector, keys); + if (result.isMissing()) { return null; } return ImmutableSet.copyOf(keys); @@ -373,36 +359,26 @@ public PlusCollector(MapCollector left, MapCollector right) { } @Override - public boolean present() { - return left.present() && right.present(); - } - - @Override - public void collectInto(DisplayName owner, MapEntryCollector collector, Map dest) { - left.collectInto(owner, collector, dest); - right.collectInto(owner, collector, dest); + public boolean isPresent() { + return left.isPresent() && right.isPresent(); } @Override - public boolean maybeCollectInto(MapEntryCollector collector, Map dest) { - if (left.maybeCollectInto(collector, dest)) { - return right.maybeCollectInto(collector, dest); + public Value maybeCollectInto(MapEntryCollector collector, Map dest) { + Value result = left.maybeCollectInto(collector, dest); + if (result.isMissing()) { + return result; } - return false; + return right.maybeCollectInto(collector, dest); } @Override - public void collectKeysInto(ValueCollector collector, Collection dest) { - left.collectKeysInto(collector, dest); - right.collectKeysInto(collector, dest); - } - - @Override - public boolean maybeCollectKeysInto(ValueCollector collector, Collection dest) { - if (left.maybeCollectKeysInto(collector, dest)) { - return right.maybeCollectKeysInto(collector, dest); + public Value maybeCollectKeysInto(ValueCollector collector, Collection dest) { + Value result = left.maybeCollectKeysInto(collector, dest); + if (result.isMissing()) { + return result; } - return false; + return right.maybeCollectKeysInto(collector, dest); } @Override diff --git a/subprojects/model-core/src/main/java/org/gradle/api/internal/provider/DefaultProperty.java b/subprojects/model-core/src/main/java/org/gradle/api/internal/provider/DefaultProperty.java index 4173e7a24df3..53b6a3621069 100644 --- a/subprojects/model-core/src/main/java/org/gradle/api/internal/provider/DefaultProperty.java +++ b/subprojects/model-core/src/main/java/org/gradle/api/internal/provider/DefaultProperty.java @@ -18,8 +18,6 @@ import org.gradle.api.provider.Property; import org.gradle.api.provider.Provider; -import org.gradle.internal.DisplayName; -import org.gradle.internal.logging.text.TreeFormatter; import javax.annotation.Nullable; @@ -152,42 +150,11 @@ protected void makeFinal() { convention = Providers.noValue(); } - @Override - public T get() { - beforeRead(); - Value value = valueSupplier.calculateValue(); - if (value.isMissing()) { - TreeFormatter formatter = new TreeFormatter(); - formatter.node("Cannot query the value of ").append(getDisplayName().getDisplayName()).append(" because it has no value available."); - if (!value.getPathToOrigin().isEmpty()) { - formatter.node("The value of this property is derived from"); - formatter.startChildren(); - for (DisplayName displayName : value.getPathToOrigin()) { - formatter.node(displayName.getDisplayName()); - } - formatter.endChildren(); - } - throw new MissingValueException(formatter.toString()); - } - return value.get(); - } - - @Override - public Value calculateValue() { - beforeRead(); - return valueSupplier.calculateValue().pushWhenMissing(getDisplayName()); - } - - @Override - public T getOrNull() { - beforeRead(); - return valueSupplier.calculateValue().orNull(); - } @Override - public T getOrElse(T defaultValue) { + protected Value calculateOwnValue() { beforeRead(); - return valueSupplier.calculateValue().orElse(defaultValue); + return valueSupplier.calculateValue(); } @Override diff --git a/subprojects/model-core/src/main/java/org/gradle/api/internal/provider/MapCollector.java b/subprojects/model-core/src/main/java/org/gradle/api/internal/provider/MapCollector.java index fd44dd222398..192175233e75 100644 --- a/subprojects/model-core/src/main/java/org/gradle/api/internal/provider/MapCollector.java +++ b/subprojects/model-core/src/main/java/org/gradle/api/internal/provider/MapCollector.java @@ -16,8 +16,6 @@ package org.gradle.api.internal.provider; -import org.gradle.internal.DisplayName; - import java.util.Collection; import java.util.List; import java.util.Map; @@ -27,15 +25,9 @@ */ public interface MapCollector extends ValueSupplier { - boolean present(); - - void collectInto(DisplayName owner, MapEntryCollector collector, Map dest); - - boolean maybeCollectInto(MapEntryCollector collector, Map dest); - - void collectKeysInto(ValueCollector collector, Collection dest); + Value maybeCollectInto(MapEntryCollector collector, Map dest); - boolean maybeCollectKeysInto(ValueCollector collector, Collection dest); + Value maybeCollectKeysInto(ValueCollector collector, Collection dest); void visit(List>> sources); } diff --git a/subprojects/model-core/src/main/java/org/gradle/api/internal/provider/MapCollectors.java b/subprojects/model-core/src/main/java/org/gradle/api/internal/provider/MapCollectors.java index 04c05ffb7920..3006fb1baeec 100644 --- a/subprojects/model-core/src/main/java/org/gradle/api/internal/provider/MapCollectors.java +++ b/subprojects/model-core/src/main/java/org/gradle/api/internal/provider/MapCollectors.java @@ -21,7 +21,6 @@ import org.gradle.api.Action; import org.gradle.api.Task; import org.gradle.api.internal.tasks.TaskDependencyResolveContext; -import org.gradle.internal.DisplayName; import java.util.Collection; import java.util.List; @@ -32,26 +31,18 @@ public class MapCollectors { public static class EmptyMap implements MapCollector { @Override - public boolean present() { + public boolean isPresent() { return true; } @Override - public void collectInto(DisplayName owner, MapEntryCollector collector, Map dest) { + public Value maybeCollectInto(MapEntryCollector collector, Map dest) { + return Value.present(); } @Override - public boolean maybeCollectInto(MapEntryCollector collector, Map dest) { - return true; - } - - @Override - public void collectKeysInto(ValueCollector collector, Collection dest) { - } - - @Override - public boolean maybeCollectKeysInto(ValueCollector collector, Collection dest) { - return true; + public Value maybeCollectKeysInto(ValueCollector collector, Collection dest) { + return Value.present(); } @Override @@ -84,30 +75,20 @@ public SingleEntry(K key, V value) { } @Override - public boolean present() { + public boolean isPresent() { return true; } @Override - public void collectInto(DisplayName owner, MapEntryCollector collector, Map dest) { - maybeCollectInto(collector, dest); - } - - @Override - public boolean maybeCollectInto(MapEntryCollector collector, Map dest) { + public Value maybeCollectInto(MapEntryCollector collector, Map dest) { collector.add(key, value, dest); - return true; + return Value.present(); } @Override - public void collectKeysInto(ValueCollector collector, Collection dest) { + public Value maybeCollectKeysInto(ValueCollector collector, Collection dest) { collector.add(key, dest); - } - - @Override - public boolean maybeCollectKeysInto(ValueCollector collector, Collection dest) { - collectKeysInto(collector, dest); - return true; + return Value.present(); } @Override @@ -158,42 +139,28 @@ public EntryWithValueFromProvider(K key, ProviderInternal providerO } @Override - public boolean present() { + public boolean isPresent() { return providerOfValue.isPresent(); } @Override - public void collectInto(DisplayName owner, MapEntryCollector collector, Map dest) { - collector.add(key, providerOfValue.get(), dest); - } - - @Override - public boolean maybeCollectInto(MapEntryCollector collector, Map dest) { + public Value maybeCollectInto(MapEntryCollector collector, Map dest) { V value = providerOfValue.getOrNull(); if (value != null) { collector.add(key, value, dest); - return true; + return Value.present(); } else { - return false; + return Value.missing(); } } @Override - public void collectKeysInto(ValueCollector collector, Collection dest) { + public Value maybeCollectKeysInto(ValueCollector collector, Collection dest) { if (providerOfValue.isPresent()) { collector.add(key, dest); + return Value.present(); } else { - throw new MissingValueException(Providers.NULL_VALUE); - } - } - - @Override - public boolean maybeCollectKeysInto(ValueCollector collector, Collection dest) { - if (providerOfValue.isPresent()) { - collector.add(key, dest); - return true; - } else { - return false; + return Value.missing(); } } @@ -227,30 +194,20 @@ public EntriesFromMap(Map entries) { } @Override - public boolean present() { + public boolean isPresent() { return true; } @Override - public void collectInto(DisplayName owner, MapEntryCollector collector, Map dest) { - maybeCollectInto(collector, dest); - } - - @Override - public boolean maybeCollectInto(MapEntryCollector collector, Map dest) { + public Value maybeCollectInto(MapEntryCollector collector, Map dest) { collector.addAll(entries.entrySet(), dest); - return true; + return Value.present(); } @Override - public void collectKeysInto(ValueCollector collector, Collection dest) { + public Value maybeCollectKeysInto(ValueCollector collector, Collection dest) { collector.addAll(entries.keySet(), dest); - } - - @Override - public boolean maybeCollectKeysInto(ValueCollector collector, Collection dest) { - collectKeysInto(collector, dest); - return true; + return Value.present(); } @Override @@ -282,39 +239,28 @@ public EntriesFromMapProvider(ProviderInternal collector, Map dest) { - collector.addAll(providerOfEntries.get().entrySet(), dest); - } - - @Override - public boolean maybeCollectInto(MapEntryCollector collector, Map dest) { - Map entries = providerOfEntries.getOrNull(); - if (entries != null) { - collector.addAll(entries.entrySet(), dest); - return true; - } else { - return false; + public Value maybeCollectInto(MapEntryCollector collector, Map dest) { + Value> value = providerOfEntries.calculateValue(); + if (value.isMissing()) { + return value.asType(); } + collector.addAll(value.get().entrySet(), dest); + return Value.present(); } @Override - public void collectKeysInto(ValueCollector collector, Collection dest) { - collector.addAll(providerOfEntries.get().keySet(), dest); - } - - @Override - public boolean maybeCollectKeysInto(ValueCollector collector, Collection dest) { + public Value maybeCollectKeysInto(ValueCollector collector, Collection dest) { Map entries = providerOfEntries.getOrNull(); if (entries != null) { collector.addAll(entries.keySet(), dest); - return true; + return Value.present(); } else { - return false; + return Value.missing(); } } @@ -342,28 +288,18 @@ public boolean isValueProducedByTask() { public static class NoValue implements MapCollector { @Override - public boolean present() { - return false; - } - - @Override - public void collectInto(DisplayName owner, MapEntryCollector collector, Map dest) { - throw Providers.nullValue(owner); - } - - @Override - public boolean maybeCollectInto(MapEntryCollector collector, Map dest) { + public boolean isPresent() { return false; } @Override - public void collectKeysInto(ValueCollector collector, Collection dest) { - throw new MissingValueException(Providers.NULL_VALUE); + public Value maybeCollectInto(MapEntryCollector collector, Map dest) { + return Value.missing(); } @Override - public boolean maybeCollectKeysInto(ValueCollector collector, Collection dest) { - return false; + public Value maybeCollectKeysInto(ValueCollector collector, Collection dest) { + return Value.missing(); } @Override diff --git a/subprojects/model-core/src/main/java/org/gradle/api/internal/provider/ProviderInternal.java b/subprojects/model-core/src/main/java/org/gradle/api/internal/provider/ProviderInternal.java index 8d5e72dfb65e..e8eb0fb2de79 100644 --- a/subprojects/model-core/src/main/java/org/gradle/api/internal/provider/ProviderInternal.java +++ b/subprojects/model-core/src/main/java/org/gradle/api/internal/provider/ProviderInternal.java @@ -62,6 +62,11 @@ public interface ProviderInternal extends Provider, TaskDependencyContaine @Override ProviderInternal map(Transformer transformer); + /** + * Calculates the value of this supplier. + */ + ValueSupplier.Value calculateValue(); + /** * Returns a view of this provider that can be used to supply a value to a {@link org.gradle.api.provider.Property} instance. */ diff --git a/subprojects/model-core/src/main/java/org/gradle/api/internal/provider/Providers.java b/subprojects/model-core/src/main/java/org/gradle/api/internal/provider/Providers.java index b947f2ed47b6..25a5289722b9 100644 --- a/subprojects/model-core/src/main/java/org/gradle/api/internal/provider/Providers.java +++ b/subprojects/model-core/src/main/java/org/gradle/api/internal/provider/Providers.java @@ -101,7 +101,7 @@ public T get() { @Override public Value calculateValue() { - return new Success<>(value); + return new Present<>(value); } @Override diff --git a/subprojects/model-core/src/main/java/org/gradle/api/internal/provider/ScalarSupplier.java b/subprojects/model-core/src/main/java/org/gradle/api/internal/provider/ScalarSupplier.java index a05575535953..6f0f245d9d9e 100644 --- a/subprojects/model-core/src/main/java/org/gradle/api/internal/provider/ScalarSupplier.java +++ b/subprojects/model-core/src/main/java/org/gradle/api/internal/provider/ScalarSupplier.java @@ -16,19 +16,10 @@ package org.gradle.api.internal.provider; -import com.google.common.collect.ImmutableList; -import org.gradle.internal.Cast; -import org.gradle.internal.DisplayName; - -import javax.annotation.Nullable; -import java.util.List; - /** * Supplies zero or one value of type {@link T}. */ public interface ScalarSupplier extends ValueSupplier { - boolean isPresent(); - /** * Calculates the value of this supplier. */ @@ -37,110 +28,4 @@ public interface ScalarSupplier extends ValueSupplier { ProviderInternal asProvider(); ScalarSupplier withFinalValue(); - - interface Value { - static Value ofNullable(@Nullable T value) { - if (value == null) { - return new Missing(); - } - return new Success(value); - } - - T get() throws IllegalStateException; - - // Only populated when value is missing - List getPathToOrigin(); - - boolean isMissing(); - - Value pushWhenMissing(DisplayName displayName); - - @Nullable - T orNull(); - - S orElse(S defaultValue); - } - - class Success implements Value { - private final T result; - - public Success(T result) { - this.result = result; - } - - @Override - public boolean isMissing() { - return false; - } - - @Override - public T get() throws IllegalStateException { - return result; - } - - @Override - public T orNull() { - return result; - } - - @Override - public S orElse(S defaultValue) { - return Cast.uncheckedCast(result); - } - - @Override - public Value pushWhenMissing(DisplayName displayName) { - return this; - } - - @Override - public List getPathToOrigin() { - throw new IllegalStateException(); - } - } - - class Missing implements Value { - private final List path; - - public Missing() { - this.path = ImmutableList.of(); - } - - public Missing(List path) { - this.path = path; - } - - @Override - public boolean isMissing() { - return true; - } - - @Override - public T get() throws IllegalStateException { - throw new IllegalStateException(); - } - - @Override - public T orNull() { - return null; - } - - @Override - public S orElse(S defaultValue) { - return defaultValue; - } - - @Override - public List getPathToOrigin() { - return path; - } - - @Override - public Value pushWhenMissing(DisplayName displayName) { - ImmutableList.Builder builder = ImmutableList.builderWithExpectedSize(path.size() + 1); - builder.add(displayName); - builder.addAll(path); - return new Missing(builder.build()); - } - } } diff --git a/subprojects/model-core/src/main/java/org/gradle/api/internal/provider/ValueSupplier.java b/subprojects/model-core/src/main/java/org/gradle/api/internal/provider/ValueSupplier.java index 1b19b40e3f7e..3125904e1e86 100644 --- a/subprojects/model-core/src/main/java/org/gradle/api/internal/provider/ValueSupplier.java +++ b/subprojects/model-core/src/main/java/org/gradle/api/internal/provider/ValueSupplier.java @@ -16,9 +16,15 @@ package org.gradle.api.internal.provider; +import com.google.common.collect.ImmutableList; import org.gradle.api.Action; import org.gradle.api.Task; import org.gradle.api.internal.tasks.TaskDependencyResolveContext; +import org.gradle.internal.Cast; +import org.gradle.internal.DisplayName; + +import javax.annotation.Nullable; +import java.util.List; public interface ValueSupplier { /** @@ -35,4 +41,142 @@ public interface ValueSupplier { * See {@link ProviderInternal#isValueProducedByTask()}. */ boolean isValueProducedByTask(); + + boolean isPresent(); + + interface Value { + Value MISSING = new ScalarSupplier.Missing<>(); + Value SUCCESS = new Present<>(null); + + static Value ofNullable(@Nullable T value) { + if (value == null) { + return MISSING.asType(); + } + return new Present(value); + } + + static Value missing() { + return MISSING.asType(); + } + + static Value of(T value) { + return new Present<>(value); + } + + static Value present() { + return SUCCESS; + } + + T get() throws IllegalStateException; + + @Nullable + T orNull(); + + S orElse(S defaultValue); + + // Only populated when value is missing + List getPathToOrigin(); + + boolean isMissing(); + + Value pushWhenMissing(@Nullable DisplayName displayName); + + Value asType(); + } + + class Present implements Value { + private final T result; + + public Present(T result) { + this.result = result; + } + + @Override + public boolean isMissing() { + return false; + } + + @Override + public T get() throws IllegalStateException { + return result; + } + + @Override + public T orNull() { + return result; + } + + @Override + public S orElse(S defaultValue) { + return Cast.uncheckedCast(result); + } + + @Override + public Value pushWhenMissing(@Nullable DisplayName displayName) { + return this; + } + + @Override + public Value asType() { + throw new IllegalStateException(); + } + + @Override + public List getPathToOrigin() { + throw new IllegalStateException(); + } + } + + class Missing implements Value { + private final List path; + + public Missing() { + this.path = ImmutableList.of(); + } + + public Missing(List path) { + this.path = path; + } + + @Override + public boolean isMissing() { + return true; + } + + @Override + public T get() throws IllegalStateException { + throw new IllegalStateException(); + } + + @Override + public T orNull() { + return null; + } + + @Override + public S orElse(S defaultValue) { + return defaultValue; + } + + @Override + public List getPathToOrigin() { + return path; + } + + @Override + public Value asType() { + return Cast.uncheckedCast(this); + } + + @Override + public Value pushWhenMissing(@Nullable DisplayName displayName) { + if (displayName == null) { + return this; + } + ImmutableList.Builder builder = ImmutableList.builderWithExpectedSize(path.size() + 1); + builder.add(displayName); + builder.addAll(path); + return new Missing(builder.build()); + } + } } diff --git a/subprojects/model-core/src/test/groovy/org/gradle/api/internal/provider/CollectionPropertySpec.groovy b/subprojects/model-core/src/test/groovy/org/gradle/api/internal/provider/CollectionPropertySpec.groovy index 731369fd6056..1f1a1342fad8 100644 --- a/subprojects/model-core/src/test/groovy/org/gradle/api/internal/provider/CollectionPropertySpec.groovy +++ b/subprojects/model-core/src/test/groovy/org/gradle/api/internal/provider/CollectionPropertySpec.groovy @@ -144,7 +144,7 @@ abstract class CollectionPropertySpec> extends Prop def "can set untyped from provider"() { def provider = Stub(ProviderInternal) provider.type >> null - provider.get() >>> [["1"], ["2"]] + provider.calculateValue() >>> [["1"], ["2"]].collect { ValueSupplier.Value.of(it) } expect: property.setFromAnyValue(provider) @@ -174,7 +174,7 @@ abstract class CollectionPropertySpec> extends Prop def "queries underlying provider for every call to get()"() { def provider = Stub(ProviderInternal) provider.type >> List - provider.get() >>> [["123"], ["abc"]] + provider.calculateValue() >>> [["123"], ["abc"]].collect { ValueSupplier.Value.of(it) } provider.present >> true expect: @@ -279,7 +279,7 @@ abstract class CollectionPropertySpec> extends Prop def "queries values of provider on every call to get()"() { def provider = Stub(ProviderInternal) _ * provider.present >> true - _ * provider.get() >>> [["abc"], ["def"]] + _ * provider.calculateValue() >>> [["abc"], ["def"]].collect { ValueSupplier.Value.of(it) } expect: property.addAll(provider) @@ -352,18 +352,18 @@ abstract class CollectionPropertySpec> extends Prop property.get() then: - 1 * valueProvider.get() >> ["1"] - 1 * addProvider.get() >> "2" - 1 * addAllProvider.get() >> ["3"] + 1 * valueProvider.calculateValue() >> ValueSupplier.Value.of(["1"]) + 1 * addProvider.getOrNull() >> "2" + 1 * addAllProvider.calculateValue() >> ValueSupplier.Value.of(["3"]) 0 * _ when: property.getOrNull() then: - 1 * valueProvider.getOrNull() >> ["1"] + 1 * valueProvider.calculateValue() >> ValueSupplier.Value.of(["1"]) 1 * addProvider.getOrNull() >> "2" - 1 * addAllProvider.getOrNull() >> ["3"] + 1 * addAllProvider.calculateValue() >> ValueSupplier.Value.of(["3"]) 0 * _ } @@ -428,7 +428,7 @@ abstract class CollectionPropertySpec> extends Prop then: def e = thrown(IllegalStateException) - e.message == Providers.NULL_VALUE + e.message == "Cannot query the value of ${displayName} because it has no value available." } def "property has no value when adding an element provider with no value"() { @@ -447,7 +447,7 @@ abstract class CollectionPropertySpec> extends Prop then: def e = thrown(IllegalStateException) - e.message == Providers.NULL_VALUE + e.message == "Cannot query the value of ${displayName} because it has no value available." } def "property has no value when adding an collection provider with no value"() { @@ -466,7 +466,7 @@ abstract class CollectionPropertySpec> extends Prop then: def e = thrown(IllegalStateException) - e.message == Providers.NULL_VALUE + e.message == "Cannot query the value of ${displayName} because it has no value available." } def "can set to null value to discard value"() { diff --git a/subprojects/model-core/src/test/groovy/org/gradle/api/internal/provider/DefaultPropertyTest.groovy b/subprojects/model-core/src/test/groovy/org/gradle/api/internal/provider/DefaultPropertyTest.groovy index 8cb79f7e040a..e9892bd60789 100644 --- a/subprojects/model-core/src/test/groovy/org/gradle/api/internal/provider/DefaultPropertyTest.groovy +++ b/subprojects/model-core/src/test/groovy/org/gradle/api/internal/provider/DefaultPropertyTest.groovy @@ -136,7 +136,7 @@ class DefaultPropertyTest extends PropertySpec { given: provider.asSupplier(_, _, _) >> supplier - supplier.calculateValue() >>> [1, 2, 3].collect { ScalarSupplier.Value.ofNullable(it) } + supplier.calculateValue() >>> [1, 2, 3].collect { ValueSupplier.Value.ofNullable(it) } def property = new DefaultProperty(Number) diff --git a/subprojects/model-core/src/test/groovy/org/gradle/api/internal/provider/MapPropertySpec.groovy b/subprojects/model-core/src/test/groovy/org/gradle/api/internal/provider/MapPropertySpec.groovy index a6f0b3c44e95..8babd4f0dd02 100644 --- a/subprojects/model-core/src/test/groovy/org/gradle/api/internal/provider/MapPropertySpec.groovy +++ b/subprojects/model-core/src/test/groovy/org/gradle/api/internal/provider/MapPropertySpec.groovy @@ -103,7 +103,7 @@ class MapPropertySpec extends PropertySpec> { given: def provider = Stub(ProviderInternal) provider.type >> null - provider.get() >>> [['k1': 'v1'], ['k2': 'v2']] + provider.calculateValue() >>> [['k1': 'v1'], ['k2': 'v2']].collect { ValueSupplier.Value.of(it) } when: property.setFromAnyValue(provider) @@ -132,7 +132,7 @@ class MapPropertySpec extends PropertySpec> { given: def provider = Stub(ProviderInternal) provider.type >> Map - provider.get() >>> [['k1': 'v1'], ['k2': 'v2']] + provider.calculateValue() >>> [['k1': 'v1'], ['k2': 'v2']].collect { ValueSupplier.Value.of(it) } provider.present >> true and: property.set(provider) @@ -229,7 +229,7 @@ class MapPropertySpec extends PropertySpec> { def provider = Stub(ProviderInternal) _ * provider.type >> Map _ * provider.present >> true - _ * provider.get() >>> [['k1': 'v1'], ['k2': 'v2']] + _ * provider.calculateValue() >>> [['k1': 'v1'], ['k2': 'v2']].collect { ValueSupplier.Value.of(it) } and: property.putAll(provider) @@ -274,17 +274,17 @@ class MapPropertySpec extends PropertySpec> { when: property.get() then: - 1 * valueProvider.get() >> ['k1': 'v1'] - 1 * putProvider.get() >> 'v2' - 1 * putAllProvider.get() >> ['k3': 'v3'] + 1 * valueProvider.calculateValue() >> ValueSupplier.Value.of(['k1': 'v1']) + 1 * putProvider.getOrNull() >> 'v2' + 1 * putAllProvider.calculateValue() >> ValueSupplier.Value.of(['k3': 'v3']) 0 * _ when: property.getOrNull() then: - 1 * valueProvider.getOrNull() >> ['k1': 'v1'] + 1 * valueProvider.calculateValue() >> ValueSupplier.Value.of(['k1': 'v1']) 1 * putProvider.getOrNull() >> 'v2' - 1 * putAllProvider.getOrNull() >> ['k3': 'v3'] + 1 * putAllProvider.calculateValue() >> ValueSupplier.Value.of(['k3': 'v3']) 0 * _ } @@ -317,7 +317,7 @@ class MapPropertySpec extends PropertySpec> { property.get() then: def e = thrown(IllegalStateException) - e.message == Providers.NULL_VALUE + e.message == "Cannot query the value of ${displayName} because it has no value available." } def "property has no value when adding a value provider with no value"() { @@ -335,7 +335,7 @@ class MapPropertySpec extends PropertySpec> { property.get() then: def e = thrown(IllegalStateException) - e.message == Providers.NULL_VALUE + e.message == "Cannot query the value of ${displayName} because it has no value available." } def "property has no value when adding a map provider with no value"() { @@ -353,7 +353,7 @@ class MapPropertySpec extends PropertySpec> { property.get() then: def e = thrown(IllegalStateException) - e.message == Providers.NULL_VALUE + e.message == "Cannot query the value of ${displayName} because it has no value available." } def "can set to null value to discard value"() { diff --git a/subprojects/model-core/src/testFixtures/groovy/org/gradle/api/internal/provider/PropertySpec.groovy b/subprojects/model-core/src/testFixtures/groovy/org/gradle/api/internal/provider/PropertySpec.groovy index 998342884cd4..cd8bec73a3fd 100644 --- a/subprojects/model-core/src/testFixtures/groovy/org/gradle/api/internal/provider/PropertySpec.groovy +++ b/subprojects/model-core/src/testFixtures/groovy/org/gradle/api/internal/provider/PropertySpec.groovy @@ -124,7 +124,7 @@ abstract class PropertySpec extends ProviderSpec { property.getOrNull() == null } - def "can set value using provider and chaining method"() { + def "can set value using provider with chaining method"() { given: def property = propertyWithNoValue() property.value(Providers.of(someValue())) @@ -1547,6 +1547,43 @@ abstract class PropertySpec extends ProviderSpec { e2.message == 'The value for cannot be changed any further.' } + def "reports the source of the property's value when value is missing and source is known"() { + given: + def a = propertyWithNoValue() + def b = propertyWithNoValue() + def c = propertyWithNoValue() + a.attachDisplayName(Describables.of("")) + a.set(b) + b.set(c) + + when: + a.get() + + then: + def e = thrown(MissingValueException) + e.message == "Cannot query the value of because it has no value available." + + when: + c.attachDisplayName(Describables.of("")) + a.get() + + then: + def e2 = thrown(MissingValueException) + e2.message == """Cannot query the value of because it has no value available. +The value of this property is derived from: """ + + when: + b.attachDisplayName(Describables.of("")) + a.get() + + then: + def e3 = thrown(MissingValueException) + e3.message == """Cannot query the value of because it has no value available. +The value of this property is derived from: + - + - """ + } + def "producer task for a property is not known by default"() { def context = Mock(TaskDependencyResolveContext) def property = propertyWithNoValue() From afa7f3eff423cef525a450f0f3371a7790f75641 Mon Sep 17 00:00:00 2001 From: Adam Murdoch Date: Wed, 22 Jan 2020 16:28:29 +1000 Subject: [PATCH 37/39] Report the chain of properties from which an element of a `ListProperty`, `SetProperty` or entry of a `MapProperty` come from, when the value is missing. --- .../AbstractDomainObjectCollectionSpec.groovy | 77 +++++++++-------- .../DefaultDomainObjectCollectionTest.groovy | 3 +- .../DefaultPendingSourceTest.groovy | 7 +- .../api/internal/provider/Collectors.java | 8 +- .../api/internal/provider/MapCollectors.java | 11 ++- .../provider/CollectionPropertySpec.groovy | 37 ++++++++- .../internal/provider/MapPropertySpec.groovy | 58 +++++++++++-- .../api/internal/provider/PropertySpec.groovy | 83 ++++++++++++++++++- 8 files changed, 219 insertions(+), 65 deletions(-) diff --git a/subprojects/core/src/test/groovy/org/gradle/api/internal/AbstractDomainObjectCollectionSpec.groovy b/subprojects/core/src/test/groovy/org/gradle/api/internal/AbstractDomainObjectCollectionSpec.groovy index a957227ff313..f9728d4012a7 100644 --- a/subprojects/core/src/test/groovy/org/gradle/api/internal/AbstractDomainObjectCollectionSpec.groovy +++ b/subprojects/core/src/test/groovy/org/gradle/api/internal/AbstractDomainObjectCollectionSpec.groovy @@ -221,7 +221,7 @@ abstract class AbstractDomainObjectCollectionSpec extends Specification { !result and: - 1 * provider.getOrNull() >> a + 1 * provider.calculateValue() >> ValueSupplier.Value.of(a) 0 * _ } @@ -288,8 +288,8 @@ abstract class AbstractDomainObjectCollectionSpec extends Specification { result == iterationOrder(b, a, d, c) and: - 1 * provider1.getOrNull() >> a - 1 * provider2.getOrNull() >> d + 1 * provider1.calculateValue() >> ValueSupplier.Value.of(a) + 1 * provider2.calculateValue() >> ValueSupplier.Value.of(d) 0 * _ } @@ -422,7 +422,7 @@ abstract class AbstractDomainObjectCollectionSpec extends Specification { then: 1 * action.execute(c) _ * provider1.type >> type - 1 * provider1.getOrNull() >> c + 1 * provider1.calculateValue() >> ValueSupplier.Value.of(c) 0 * _ when: @@ -494,7 +494,7 @@ abstract class AbstractDomainObjectCollectionSpec extends Specification { then: result == iterationOrder(c, a) _ * provider.type >> type - 1 * provider.getOrNull() >> a + 1 * provider.calculateValue() >> ValueSupplier.Value.of(a) 0 * _ when: @@ -564,7 +564,7 @@ abstract class AbstractDomainObjectCollectionSpec extends Specification { then: result2 == iterationOrder(c, a, d) - 1 * provider.getOrNull() >> a + 1 * provider.calculateValue() >> ValueSupplier.Value.of(a) 0 * _ } @@ -675,7 +675,7 @@ abstract class AbstractDomainObjectCollectionSpec extends Specification { then: _ * provider1.type >> type - 1 * provider1.getOrNull() >> c + 1 * provider1.calculateValue() >> ValueSupplier.Value.of(c) 1 * action.execute(c) 0 * _ @@ -790,7 +790,7 @@ abstract class AbstractDomainObjectCollectionSpec extends Specification { toList(container) then: - 1 * provider1.getOrNull() >> a + 1 * provider1.calculateValue() >> ValueSupplier.Value.of(a) 1 * action.execute(a) 0 * _ @@ -805,7 +805,7 @@ abstract class AbstractDomainObjectCollectionSpec extends Specification { toList(container) then: - 1 * provider2.getOrNull() >> c + 1 * provider2.calculateValue() >> ValueSupplier.Value.of(c) 1 * action.execute(c) 0 * _ @@ -834,7 +834,7 @@ abstract class AbstractDomainObjectCollectionSpec extends Specification { def providerOfIterable = Mock(CollectionProviderInternal) given: - _ * provider.getOrNull() >> a + _ * provider.calculateValue() >> ValueSupplier.Value.of(a) _ * providerOfIterable.calculateValue() >> ValueSupplier.Value.of([b, c]) container.addLater(provider) container.addAllLater(providerOfIterable) @@ -888,10 +888,10 @@ abstract class AbstractDomainObjectCollectionSpec extends Specification { then: _ * provider1.type >> type - 1 * provider1.getOrNull() >> a + 1 * provider1.calculateValue() >> ValueSupplier.Value.of(a) 1 * action.execute(a) _ * provider2.type >> otherType - 1 * provider2.getOrNull() >> d + 1 * provider2.calculateValue() >> ValueSupplier.Value.of(d) 0 * _ when: @@ -963,8 +963,8 @@ abstract class AbstractDomainObjectCollectionSpec extends Specification { def result = toList(filtered) then: - 1 * provider1.getOrNull() >> a - 1 * provider2.getOrNull() >> b + 1 * provider1.calculateValue() >> ValueSupplier.Value.of(a) + 1 * provider2.calculateValue() >> ValueSupplier.Value.of(b) 0 * _ and: @@ -1039,7 +1039,7 @@ abstract class AbstractDomainObjectCollectionSpec extends Specification { then: 0 * provider1.get() >> a - 1 * provider2.getOrNull() >> b + 1 * provider2.calculateValue() >> ValueSupplier.Value.of(b) 0 * _ and: @@ -1113,8 +1113,8 @@ abstract class AbstractDomainObjectCollectionSpec extends Specification { def result = toList(filtered) then: - 1 * provider1.getOrNull() >> a - 1 * provider2.getOrNull() >> b + 1 * provider1.calculateValue() >> ValueSupplier.Value.of(a) + 1 * provider2.calculateValue() >> ValueSupplier.Value.of(b) 0 * _ and: @@ -1149,8 +1149,7 @@ abstract class AbstractDomainObjectCollectionSpec extends Specification { def result = toList(container) then: - 0 * provider1.getOrNull() - 1 * provider2.getOrNull() >> b + 1 * provider2.calculateValue() >> ValueSupplier.Value.of(b) 0 * _ and: @@ -1198,10 +1197,10 @@ abstract class AbstractDomainObjectCollectionSpec extends Specification { given: _ * provider1.type >> type - _ * provider1.getOrNull() >> a + _ * provider1.calculateValue() >> ValueSupplier.Value.of(a) _ * provider1.present >> true _ * provider2.type >> type - _ * provider2.getOrNull() >> b + _ * provider2.calculateValue() >> ValueSupplier.Value.of(b) _ * provider2.present >> true _ * provider3.type >> otherType container.addLater(provider1) @@ -1243,7 +1242,7 @@ abstract class AbstractDomainObjectCollectionSpec extends Specification { given: _ * provider1.type >> type - _ * provider1.getOrNull() >> a + _ * provider1.calculateValue() >> ValueSupplier.Value.of(a) _ * provider2.type >> otherType container.addLater(provider1) container.addLater(provider2) @@ -1269,7 +1268,7 @@ abstract class AbstractDomainObjectCollectionSpec extends Specification { given: _ * provider1.type >> type - _ * provider1.getOrNull() >> a + _ * provider1.calculateValue() >> ValueSupplier.Value.of(a) _ * provider1.get() >> a _ * provider1.present >> true _ * provider2.type >> otherType @@ -1313,7 +1312,7 @@ abstract class AbstractDomainObjectCollectionSpec extends Specification { given: _ * provider1.type >> type - _ * provider1.getOrNull() >> a + _ * provider1.calculateValue() >> ValueSupplier.Value.of(a) _ * provider2.type >> otherType container.addLater(provider1) container.addLater(provider2) @@ -1371,9 +1370,9 @@ abstract class AbstractDomainObjectCollectionSpec extends Specification { given: _ * provider1.type >> type - _ * provider1.getOrNull() >> a + _ * provider1.calculateValue() >> ValueSupplier.Value.of(a) _ * provider2.type >> otherType - _ * provider2.getOrNull() >> d + _ * provider2.calculateValue() >> ValueSupplier.Value.of(d) container.addLater(provider1) container.addLater(provider2) container.whenObjectRemoved(action) @@ -1388,7 +1387,7 @@ abstract class AbstractDomainObjectCollectionSpec extends Specification { didRetained and: - 1 * provider2.getOrNull() >> d + 1 * provider2.calculateValue() >> ValueSupplier.Value.of(d) 1 * action.execute(a) 1 * action.execute(d) 0 * _ @@ -1421,8 +1420,8 @@ abstract class AbstractDomainObjectCollectionSpec extends Specification { didRetained and: - 1 * provider1.getOrNull() >> a - 1 * provider2.getOrNull() >> b + 1 * provider1.calculateValue() >> ValueSupplier.Value.of(a) + 1 * provider2.calculateValue() >> ValueSupplier.Value.of(b) 0 * _ when: @@ -1442,9 +1441,9 @@ abstract class AbstractDomainObjectCollectionSpec extends Specification { given: _ * provider1.type >> type - _ * provider1.getOrNull() >> a + _ * provider1.calculateValue() >> ValueSupplier.Value.of(a) _ * provider2.type >> otherType - _ * provider2.getOrNull() >> d + _ * provider2.calculateValue() >> ValueSupplier.Value.of(d) container.addLater(provider1) container.addLater(provider2) @@ -1458,7 +1457,7 @@ abstract class AbstractDomainObjectCollectionSpec extends Specification { didRetained and: - 1 * provider2.getOrNull() >> d + 1 * provider2.calculateValue() >> ValueSupplier.Value.of(d) 0 * _ when: @@ -1526,7 +1525,7 @@ abstract class AbstractDomainObjectCollectionSpec extends Specification { container.withType(type).iterator() then: - 1 * provider1.getOrNull() >> a + 1 * provider1.calculateValue() >> ValueSupplier.Value.of(a) 0 * _ when: @@ -1534,7 +1533,7 @@ abstract class AbstractDomainObjectCollectionSpec extends Specification { then: 0 * provider1.get() - 1 * provider2.getOrNull() >> b + 1 * provider2.calculateValue() >> ValueSupplier.Value.of(b) 0 * _ and: @@ -1549,9 +1548,9 @@ abstract class AbstractDomainObjectCollectionSpec extends Specification { given: _ * provider1.type >> type - _ * provider1.getOrNull() >> a + _ * provider1.calculateValue() >> ValueSupplier.Value.of(a) _ * provider2.type >> type - _ * provider2.getOrNull() >> b + _ * provider2.calculateValue() >> ValueSupplier.Value.of(b) container.addLater(provider1) container.addLater(provider2) container.whenObjectRemoved(action) @@ -1566,8 +1565,8 @@ abstract class AbstractDomainObjectCollectionSpec extends Specification { result == iterationOrder(b) and: - 1 * provider1.getOrNull() >> a - 1 * provider2.getOrNull() >> b + 1 * provider1.calculateValue() >> ValueSupplier.Value.of(a) + 1 * provider2.calculateValue() >> ValueSupplier.Value.of(b) 1 * action.execute(a) 0 * _ } @@ -1580,7 +1579,7 @@ abstract class AbstractDomainObjectCollectionSpec extends Specification { given: _ * provider1.type >> type - _ * provider1.getOrNull() >> a + _ * provider1.calculateValue() >> ValueSupplier.Value.of(a) _ * provider1.get() >> a _ * provider1.present >> true _ * provider2.type >> otherType diff --git a/subprojects/core/src/test/groovy/org/gradle/api/internal/DefaultDomainObjectCollectionTest.groovy b/subprojects/core/src/test/groovy/org/gradle/api/internal/DefaultDomainObjectCollectionTest.groovy index 6e1146457824..d1891d47de24 100644 --- a/subprojects/core/src/test/groovy/org/gradle/api/internal/DefaultDomainObjectCollectionTest.groovy +++ b/subprojects/core/src/test/groovy/org/gradle/api/internal/DefaultDomainObjectCollectionTest.groovy @@ -19,6 +19,7 @@ package org.gradle.api.internal import org.gradle.api.Action import org.gradle.api.internal.collections.IterationOrderRetainingSetElementSource import org.gradle.api.internal.provider.ProviderInternal +import org.gradle.api.internal.provider.ValueSupplier import org.gradle.api.specs.Spec import static org.gradle.util.WrapUtil.toList @@ -298,7 +299,7 @@ class DefaultDomainObjectCollectionTest extends AbstractDomainObjectCollectionSp def callsRemoveActionWhenObjectRemovedUsingIteratorNoFlushAndLastElementIsUnrealized() { def action = Mock(Action) def provider = Mock(ProviderInternal) - _ * provider.getOrNull() >> "c" + _ * provider.calculateValue() >> ValueSupplier.Value.of("c") container.whenObjectRemoved(action) container.add("a") diff --git a/subprojects/core/src/test/groovy/org/gradle/api/internal/collections/DefaultPendingSourceTest.groovy b/subprojects/core/src/test/groovy/org/gradle/api/internal/collections/DefaultPendingSourceTest.groovy index afcbca60939b..005016457916 100644 --- a/subprojects/core/src/test/groovy/org/gradle/api/internal/collections/DefaultPendingSourceTest.groovy +++ b/subprojects/core/src/test/groovy/org/gradle/api/internal/collections/DefaultPendingSourceTest.groovy @@ -18,6 +18,7 @@ package org.gradle.api.internal.collections import org.gradle.api.Action import org.gradle.api.internal.provider.ProviderInternal +import org.gradle.api.internal.provider.ValueSupplier import spock.lang.Specification class DefaultPendingSourceTest extends Specification { @@ -29,9 +30,9 @@ class DefaultPendingSourceTest extends Specification { def setup() { pending.onRealize(realize) - _ * provider1.getOrNull() >> "provider1" - _ * provider2.getOrNull() >> "provider2" - _ * provider3.getOrNull() >> "provider3" + _ * provider1.calculateValue() >> ValueSupplier.Value.of("provider1") + _ * provider2.calculateValue() >> ValueSupplier.Value.of("provider2") + _ * provider3.calculateValue() >> ValueSupplier.Value.of("provider3") } def "realizes pending elements on flush"() { diff --git a/subprojects/model-core/src/main/java/org/gradle/api/internal/provider/Collectors.java b/subprojects/model-core/src/main/java/org/gradle/api/internal/provider/Collectors.java index 7905fb532cc7..a6ffc7921cea 100644 --- a/subprojects/model-core/src/main/java/org/gradle/api/internal/provider/Collectors.java +++ b/subprojects/model-core/src/main/java/org/gradle/api/internal/provider/Collectors.java @@ -142,11 +142,11 @@ public boolean isPresent() { @Override public Value maybeCollectInto(ValueCollector collector, Collection collection) { - T value = providerOfElement.getOrNull(); - if (value == null) { - return Value.missing(); + Value value = providerOfElement.calculateValue(); + if (value.isMissing()) { + return value.asType(); } - collector.add(value, collection); + collector.add(value.get(), collection); return Value.present(); } diff --git a/subprojects/model-core/src/main/java/org/gradle/api/internal/provider/MapCollectors.java b/subprojects/model-core/src/main/java/org/gradle/api/internal/provider/MapCollectors.java index 3006fb1baeec..f679c2abc4e9 100644 --- a/subprojects/model-core/src/main/java/org/gradle/api/internal/provider/MapCollectors.java +++ b/subprojects/model-core/src/main/java/org/gradle/api/internal/provider/MapCollectors.java @@ -145,13 +145,12 @@ public boolean isPresent() { @Override public Value maybeCollectInto(MapEntryCollector collector, Map dest) { - V value = providerOfValue.getOrNull(); - if (value != null) { - collector.add(key, value, dest); - return Value.present(); - } else { - return Value.missing(); + Value value = providerOfValue.calculateValue(); + if (value.isMissing()) { + return value.asType(); } + collector.add(key, value.get(), dest); + return Value.present(); } @Override diff --git a/subprojects/model-core/src/test/groovy/org/gradle/api/internal/provider/CollectionPropertySpec.groovy b/subprojects/model-core/src/test/groovy/org/gradle/api/internal/provider/CollectionPropertySpec.groovy index 1f1a1342fad8..74dcc2779abc 100644 --- a/subprojects/model-core/src/test/groovy/org/gradle/api/internal/provider/CollectionPropertySpec.groovy +++ b/subprojects/model-core/src/test/groovy/org/gradle/api/internal/provider/CollectionPropertySpec.groovy @@ -19,6 +19,8 @@ package org.gradle.api.internal.provider import com.google.common.collect.ImmutableCollection import org.gradle.api.Transformer import org.gradle.api.provider.Provider +import org.gradle.internal.Describables +import org.gradle.util.TextUtil import spock.lang.Unroll abstract class CollectionPropertySpec> extends PropertySpec { @@ -87,6 +89,7 @@ abstract class CollectionPropertySpec> extends Prop } def "can change value to empty collection"() { + property.set(["abc"]) property.empty() expect: @@ -353,7 +356,7 @@ abstract class CollectionPropertySpec> extends Prop then: 1 * valueProvider.calculateValue() >> ValueSupplier.Value.of(["1"]) - 1 * addProvider.getOrNull() >> "2" + 1 * addProvider.calculateValue() >> ValueSupplier.Value.of("2") 1 * addAllProvider.calculateValue() >> ValueSupplier.Value.of(["3"]) 0 * _ @@ -362,7 +365,7 @@ abstract class CollectionPropertySpec> extends Prop then: 1 * valueProvider.calculateValue() >> ValueSupplier.Value.of(["1"]) - 1 * addProvider.getOrNull() >> "2" + 1 * addProvider.calculateValue() >> ValueSupplier.Value.of("2") 1 * addAllProvider.calculateValue() >> ValueSupplier.Value.of(["3"]) 0 * _ } @@ -450,6 +453,21 @@ abstract class CollectionPropertySpec> extends Prop e.message == "Cannot query the value of ${displayName} because it has no value available." } + def "reports the source of element provider when value is missing and source is known"() { + given: + def elementProvider = sourceWithNoValue(Describables.of("")) + property.set(toMutable(["123"])) + property.add(elementProvider) + + when: + property.get() + + then: + def e = thrown(IllegalStateException) + e.message == TextUtil.toPlatformLineSeparators("""Cannot query the value of ${displayName} because it has no value available. +The value of this property is derived from: """) + } + def "property has no value when adding an collection provider with no value"() { given: property.set(toMutable(["123"])) @@ -469,6 +487,21 @@ abstract class CollectionPropertySpec> extends Prop e.message == "Cannot query the value of ${displayName} because it has no value available." } + def "reports the source of collection provider when value is missing and source is known"() { + given: + def elementsProvider = sourceWithNoValue(Describables.of("")) + property.set(toMutable(["123"])) + property.addAll(elementsProvider) + + when: + property.get() + + then: + def e = thrown(IllegalStateException) + e.message == TextUtil.toPlatformLineSeparators("""Cannot query the value of ${displayName} because it has no value available. +The value of this property is derived from: """) + } + def "can set to null value to discard value"() { given: def property = property() diff --git a/subprojects/model-core/src/test/groovy/org/gradle/api/internal/provider/MapPropertySpec.groovy b/subprojects/model-core/src/test/groovy/org/gradle/api/internal/provider/MapPropertySpec.groovy index 8babd4f0dd02..a40ac6325376 100644 --- a/subprojects/model-core/src/test/groovy/org/gradle/api/internal/provider/MapPropertySpec.groovy +++ b/subprojects/model-core/src/test/groovy/org/gradle/api/internal/provider/MapPropertySpec.groovy @@ -17,7 +17,9 @@ package org.gradle.api.internal.provider import com.google.common.collect.ImmutableMap +import org.gradle.internal.Describables import org.gradle.internal.state.ManagedFactory +import org.gradle.util.TextUtil import org.spockframework.util.Assert class MapPropertySpec extends PropertySpec> { @@ -275,7 +277,7 @@ class MapPropertySpec extends PropertySpec> { property.get() then: 1 * valueProvider.calculateValue() >> ValueSupplier.Value.of(['k1': 'v1']) - 1 * putProvider.getOrNull() >> 'v2' + 1 * putProvider.calculateValue() >> ValueSupplier.Value.of('v2') 1 * putAllProvider.calculateValue() >> ValueSupplier.Value.of(['k3': 'v3']) 0 * _ @@ -283,7 +285,7 @@ class MapPropertySpec extends PropertySpec> { property.getOrNull() then: 1 * valueProvider.calculateValue() >> ValueSupplier.Value.of(['k1': 'v1']) - 1 * putProvider.getOrNull() >> 'v2' + 1 * putProvider.calculateValue() >> ValueSupplier.Value.of('v2') 1 * putAllProvider.calculateValue() >> ValueSupplier.Value.of(['k3': 'v3']) 0 * _ } @@ -338,6 +340,22 @@ class MapPropertySpec extends PropertySpec> { e.message == "Cannot query the value of ${displayName} because it has no value available." } + def "reports the source of value provider when value is missing and source is known"() { + given: + def provider = sourceWithNoValue(String, Describables.of("")) + property.set(['k1': 'v1']) + property.put('k2', 'v2') + property.put('k3', provider) + + when: + property.get() + + then: + def e = thrown(IllegalStateException) + e.message == TextUtil.toPlatformLineSeparators("""Cannot query the value of ${displayName} because it has no value available. +The value of this property is derived from: """) + } + def "property has no value when adding a map provider with no value"() { given: property.set(['k1': 'v1']) @@ -356,6 +374,22 @@ class MapPropertySpec extends PropertySpec> { e.message == "Cannot query the value of ${displayName} because it has no value available." } + def "reports the source of map provider when value is missing and source is known"() { + given: + def provider = sourceWithNoValue(Describables.of("")) + property.set(['k1': 'v1']) + property.put('k2', 'v2') + property.putAll(provider) + + when: + property.get() + + then: + def e = thrown(IllegalStateException) + e.message == TextUtil.toPlatformLineSeparators("""Cannot query the value of ${displayName} because it has no value available. +The value of this property is derived from: """) + } + def "can set to null value to discard value"() { given: property.set(someValue()) @@ -617,8 +651,10 @@ class MapPropertySpec extends PropertySpec> { when: entryProvider.get() + then: - thrown IllegalStateException + def e = thrown(MissingValueException) + e.message == "Cannot query the value of this provider because it has no value available." } def "entry provider has no value when key is not in map"() { @@ -632,8 +668,10 @@ class MapPropertySpec extends PropertySpec> { when: entryProvider.get() + then: - thrown IllegalStateException + def e = thrown(MissingValueException) + e.message == "Cannot query the value of this provider because it has no value available." } def "entry provider tracks value of property"() { @@ -653,6 +691,12 @@ class MapPropertySpec extends PropertySpec> { entryProvider.present entryProvider.get() == 'v2' entryProvider.getOrNull() == 'v2' + + when: + property.set(Providers.of([:])) + then: + !entryProvider.present + entryProvider.getOrNull() == null } def "entry provider tracks value of last added entry"() { @@ -699,8 +743,10 @@ class MapPropertySpec extends PropertySpec> { when: keySetProvider.get() + then: - thrown IllegalStateException + def e = thrown(MissingValueException) + e.message == "Cannot query the value of this provider because it has no value available." } def "keySet provider tracks value of property"() { @@ -772,7 +818,7 @@ class MapPropertySpec extends PropertySpec> { def result2 = property.get() then: - 1 * provider.getOrNull() >> "value" + 1 * provider.calculateValue() >> ValueSupplier.Value.of("value") 0 * _ and: diff --git a/subprojects/model-core/src/testFixtures/groovy/org/gradle/api/internal/provider/PropertySpec.groovy b/subprojects/model-core/src/testFixtures/groovy/org/gradle/api/internal/provider/PropertySpec.groovy index cd8bec73a3fd..259e357c9221 100644 --- a/subprojects/model-core/src/testFixtures/groovy/org/gradle/api/internal/provider/PropertySpec.groovy +++ b/subprojects/model-core/src/testFixtures/groovy/org/gradle/api/internal/provider/PropertySpec.groovy @@ -22,7 +22,9 @@ import org.gradle.api.Transformer import org.gradle.api.internal.tasks.TaskDependencyResolveContext import org.gradle.api.provider.Provider import org.gradle.internal.Describables +import org.gradle.internal.DisplayName import org.gradle.internal.state.Managed +import org.gradle.util.TextUtil import java.util.concurrent.Callable @@ -226,6 +228,40 @@ abstract class PropertySpec extends ProviderSpec { property.get() == someOtherValue() } + def "property has no value when convention provider has no value"() { + def provider = provider() + def property = propertyWithDefaultValue() + + when: + property.convention(provider) + + then: + !property.present + + when: + property.get() + + then: + def e = thrown(MissingValueException) + e.message == "Cannot query the value of ${displayName} because it has no value available." + } + + def "reports the source of convention provider when value is missing and source is known"() { + def provider = sourceWithNoValue(Describables.of("")) + def property = propertyWithDefaultValue() + + given: + property.convention(provider) + + when: + property.get() + + then: + def e = thrown(IllegalStateException) + e.message == TextUtil.toPlatformLineSeparators("""Cannot query the value of ${displayName} because it has no value available. +The value of this property is derived from: """) + } + def "can replace convention value before value has been set"() { def provider = provider(someOtherValue()) def property = propertyWithDefaultValue() @@ -1569,8 +1605,8 @@ abstract class PropertySpec extends ProviderSpec { then: def e2 = thrown(MissingValueException) - e2.message == """Cannot query the value of because it has no value available. -The value of this property is derived from: """ + e2.message == TextUtil.toPlatformLineSeparators("""Cannot query the value of because it has no value available. +The value of this property is derived from: """) when: b.attachDisplayName(Describables.of("")) @@ -1578,10 +1614,10 @@ The value of this property is derived from: """ then: def e3 = thrown(MissingValueException) - e3.message == """Cannot query the value of because it has no value available. + e3.message == TextUtil.toPlatformLineSeparators("""Cannot query the value of because it has no value available. The value of this property is derived from: - - - """ + - """) } def "producer task for a property is not known by default"() { @@ -1750,6 +1786,20 @@ The value of this property is derived from: } } + /** + * A provider with no value and the given display name + */ + ProviderInternal sourceWithNoValue(DisplayName displayName) { + return new NoValueProvider(type(), displayName) + } + + /** + * A provider with no value and the given display name + */ + ProviderInternal sourceWithNoValue(Class type, DisplayName displayName) { + return new NoValueProvider(type, displayName) + } + /** * A provider that provides one of given values each time it is queried, in the order given. */ @@ -1765,6 +1815,31 @@ The value of this property is derived from: return new TestProvider(type(), [], producer) } + class NoValueProvider extends AbstractMinimalProvider { + private final Class type + private final DisplayName displayName + + NoValueProvider(Class type, DisplayName displayName) { + this.displayName = displayName + this.type = type + } + + @Override + Class getType() { + return type + } + + @Override + T getOrNull() { + return null + } + + @Override + Value calculateValue() { + return Value.missing().pushWhenMissing(displayName) + } + } + class TestProvider extends AbstractMinimalProvider { final Class type final Iterator values From eb55a885af363f8a2981034d5cdd4a0eeb300b47 Mon Sep 17 00:00:00 2001 From: Adam Murdoch Date: Thu, 23 Jan 2020 07:38:32 +1000 Subject: [PATCH 38/39] Report the chain of properties from which a mapped `Provider` has come from, when the value is missing. --- .../org/gradle/api/provider/Property.java | 4 +- .../DefaultNamedDomainObjectCollection.java | 10 +- .../internal/BuildServiceProvider.java | 5 +- ...aultNamedDomainObjectCollectionTest.groovy | 1 - .../AbstractElementSourceTest.groovy | 11 +- .../collections/ListElementSourceTest.groovy | 14 +- .../file/DefaultProjectLayoutTest.groovy | 47 ++-- .../internal/file/AbstractFileCollection.java | 5 +- .../file/DefaultFilePropertyFactory.java | 9 +- .../DefaultFilePropertyFactoryTest.groovy | 6 +- .../api/tasks/compile/AbstractCompile.java | 25 +- .../internal/DefaultBinaryCollection.java | 49 ++-- .../DefaultBinaryCollectionTest.groovy | 3 +- .../plugins/NativeBasePluginTest.groovy | 6 +- .../provider/AbstractCombiningProvider.java | 29 +-- .../provider/AbstractMappingProvider.java | 16 +- .../provider/AbstractMinimalProvider.java | 98 +++++--- .../internal/provider/AbstractProperty.java | 45 +--- .../provider/AbstractProviderWithValue.java | 8 + .../internal/provider/DefaultMapProperty.java | 7 +- .../internal/provider/DefaultProvider.java | 4 +- .../DefaultValueSourceProviderFactory.java | 5 +- .../api/internal/provider/Providers.java | 39 +--- .../api/internal/provider/ValueSupplier.java | 31 ++- .../provider/AbstractProviderTest.groovy | 13 +- .../provider/CollectionPropertySpec.groovy | 4 +- .../provider/DefaultPropertyTest.groovy | 2 +- .../internal/provider/MapPropertySpec.groovy | 4 +- .../api/internal/provider/PropertySpec.groovy | 219 ++++++++++++------ .../api/internal/provider/ProviderSpec.groovy | 37 ++- .../internal/provider/ProviderTestUtil.java | 85 +++++++ .../DefaultArtifactPublicationSet.java | 5 +- 32 files changed, 493 insertions(+), 353 deletions(-) create mode 100644 subprojects/model-core/src/testFixtures/groovy/org/gradle/api/internal/provider/ProviderTestUtil.java diff --git a/subprojects/core-api/src/main/java/org/gradle/api/provider/Property.java b/subprojects/core-api/src/main/java/org/gradle/api/provider/Property.java index 76194482206c..5e8cb963dfa2 100644 --- a/subprojects/core-api/src/main/java/org/gradle/api/provider/Property.java +++ b/subprojects/core-api/src/main/java/org/gradle/api/provider/Property.java @@ -83,12 +83,12 @@ public interface Property extends Provider, HasConfigurableValue { /** * Specifies the value to use as the convention for this property. The convention is used when no value has been set for this property. * - * @param value The value. + * @param value The value, or null if the convention is that the property should have no value. * @return this * @since 5.1 */ @Incubating - Property convention(T value); + Property convention(@Nullable T value); /** * Specifies the provider of the value to use as the convention for this property. The convention is used when no value has been set for this property. diff --git a/subprojects/core/src/main/java/org/gradle/api/internal/DefaultNamedDomainObjectCollection.java b/subprojects/core/src/main/java/org/gradle/api/internal/DefaultNamedDomainObjectCollection.java index c25f3dd032b8..8acb8739d4aa 100644 --- a/subprojects/core/src/main/java/org/gradle/api/internal/DefaultNamedDomainObjectCollection.java +++ b/subprojects/core/src/main/java/org/gradle/api/internal/DefaultNamedDomainObjectCollection.java @@ -865,8 +865,8 @@ public I get() { } @Override - public I getOrNull() { - return Cast.uncheckedCast(findByNameWithoutRules(getName())); + protected Value calculateOwnValue() { + return Value.ofNullable(Cast.uncheckedCast(findByNameWithoutRules(getName()))); } } @@ -914,9 +914,9 @@ public I get() { } @Override - public I getOrNull() { + protected Value calculateOwnValue() { if (wasElementRemoved()) { - return null; + return Value.missing(); } if (failure != null) { throw failure; @@ -927,7 +927,7 @@ public I getOrNull() { tryCreate(); } } - return object; + return Value.of(object); } protected void tryCreate() { diff --git a/subprojects/core/src/main/java/org/gradle/api/services/internal/BuildServiceProvider.java b/subprojects/core/src/main/java/org/gradle/api/services/internal/BuildServiceProvider.java index d50fa2439405..36a1ec9d9417 100644 --- a/subprojects/core/src/main/java/org/gradle/api/services/internal/BuildServiceProvider.java +++ b/subprojects/core/src/main/java/org/gradle/api/services/internal/BuildServiceProvider.java @@ -90,9 +90,8 @@ public boolean isValueProducedByTask() { return true; } - @Nullable @Override - public T getOrNull() { + protected Value calculateOwnValue() { synchronized (this) { if (instance == null) { // TODO - extract some shared infrastructure to take care of instantiation (eg which services are visible, strict vs lenient, decorated or not?) @@ -106,7 +105,7 @@ public T getOrNull() { instance = Try.failure(new ServiceLifecycleException("Failed to create service '" + name + "'.", e)); } } - return instance.get(); + return Value.of(instance.get()); } } diff --git a/subprojects/core/src/test/groovy/org/gradle/api/internal/DefaultNamedDomainObjectCollectionTest.groovy b/subprojects/core/src/test/groovy/org/gradle/api/internal/DefaultNamedDomainObjectCollectionTest.groovy index 4fa5a9c8fb35..040f3ba88b0f 100644 --- a/subprojects/core/src/test/groovy/org/gradle/api/internal/DefaultNamedDomainObjectCollectionTest.groovy +++ b/subprojects/core/src/test/groovy/org/gradle/api/internal/DefaultNamedDomainObjectCollectionTest.groovy @@ -30,7 +30,6 @@ class DefaultNamedDomainObjectCollectionTest extends AbstractNamedDomainObjectCo }; Instantiator instantiator = TestUtil.instantiatorFactory().decorateLenient() - Set store final DefaultNamedDomainObjectCollection container = new DefaultNamedDomainObjectCollection(Bean, new IterationOrderRetainingSetElementSource(), instantiator, namer, callbackActionDecorator) final Bean a = new BeanSub1("a") diff --git a/subprojects/core/src/test/groovy/org/gradle/api/internal/collections/AbstractElementSourceTest.groovy b/subprojects/core/src/test/groovy/org/gradle/api/internal/collections/AbstractElementSourceTest.groovy index 5da3c2e0cb51..65425b4c92b1 100644 --- a/subprojects/core/src/test/groovy/org/gradle/api/internal/collections/AbstractElementSourceTest.groovy +++ b/subprojects/core/src/test/groovy/org/gradle/api/internal/collections/AbstractElementSourceTest.groovy @@ -18,7 +18,6 @@ package org.gradle.api.internal.collections import org.gradle.api.Action import org.gradle.api.internal.provider.AbstractMinimalProvider - import org.gradle.api.internal.provider.ChangingValue import org.gradle.api.internal.provider.ChangingValueHandler import org.gradle.api.internal.provider.CollectionProviderInternal @@ -210,7 +209,7 @@ abstract class AbstractElementSourceTest extends Specification { source.iterator().collect() == iterationOrder("foo", "baz", "fooz", "fizz") } - def "comodification with iterator causes an exception" () { + def "comodification with iterator causes an exception"() { given: def provider = provider("baz") def providerOfSet = setProvider("fuzz", "buzz") @@ -292,8 +291,8 @@ abstract class AbstractElementSourceTest extends Specification { } @Override - T getOrNull() { - return value + protected Value calculateOwnValue() { + return Value.of(value) } void setValue(T value) { @@ -324,8 +323,8 @@ abstract class AbstractElementSourceTest extends Specification { } @Override - Set getOrNull() { - return value + protected Value> calculateOwnValue() { + return Value.of(value) } @Override diff --git a/subprojects/core/src/test/groovy/org/gradle/api/internal/collections/ListElementSourceTest.groovy b/subprojects/core/src/test/groovy/org/gradle/api/internal/collections/ListElementSourceTest.groovy index 197e65c1e8e1..ab6178497e77 100644 --- a/subprojects/core/src/test/groovy/org/gradle/api/internal/collections/ListElementSourceTest.groovy +++ b/subprojects/core/src/test/groovy/org/gradle/api/internal/collections/ListElementSourceTest.groovy @@ -239,7 +239,9 @@ class ListElementSourceTest extends AbstractIterationOrderRetainingElementSource when: iterator = source.listIterator() - while(iterator.hasNext()) { iterator.next() } + while (iterator.hasNext()) { + iterator.next() + } iterator.add("buzz") then: @@ -247,7 +249,9 @@ class ListElementSourceTest extends AbstractIterationOrderRetainingElementSource when: iterator = source.listIterator() - while(iterator.hasNext()) { iterator.next() } + while (iterator.hasNext()) { + iterator.next() + } iterator.previous() iterator.add("bazz") @@ -486,13 +490,13 @@ class ListElementSourceTest extends AbstractIterationOrderRetainingElementSource } @Override - Class getElementType() { + Class getElementType() { return type } @Override - List getOrNull() { - return value + protected Value> calculateOwnValue() { + return Value.of(value) } @Override diff --git a/subprojects/core/src/test/groovy/org/gradle/api/internal/file/DefaultProjectLayoutTest.groovy b/subprojects/core/src/test/groovy/org/gradle/api/internal/file/DefaultProjectLayoutTest.groovy index 3114901bf99b..8823d157d7dd 100644 --- a/subprojects/core/src/test/groovy/org/gradle/api/internal/file/DefaultProjectLayoutTest.groovy +++ b/subprojects/core/src/test/groovy/org/gradle/api/internal/file/DefaultProjectLayoutTest.groovy @@ -16,14 +16,15 @@ package org.gradle.api.internal.file -import org.gradle.api.internal.provider.ProviderInternal + import org.gradle.api.internal.tasks.TaskDependencyFactory -import org.gradle.api.provider.Provider import org.gradle.test.fixtures.file.TestFile import org.gradle.test.fixtures.file.TestNameTestDirectoryProvider import org.junit.Rule import spock.lang.Specification +import static org.gradle.api.internal.provider.ProviderTestUtil.withNoValue +import static org.gradle.api.internal.provider.ProviderTestUtil.withValues import static org.gradle.util.Matchers.strictlyEquals class DefaultProjectLayoutTest extends Specification { @@ -43,9 +44,7 @@ class DefaultProjectLayoutTest extends Specification { } def "can resolve directory relative to project directory"() { - def pathProvider = Stub(ProviderInternal) - _ * pathProvider.get() >>> ["a", "b"] - _ * pathProvider.present >> true + def pathProvider = withValues("a", "b") expect: def dir = layout.projectDirectory.dir("sub-dir") @@ -65,9 +64,7 @@ class DefaultProjectLayoutTest extends Specification { } def "can resolve regular file relative to project directory"() { - def pathProvider = Stub(ProviderInternal) - _ * pathProvider.get() >>> ["a", "b"] - _ * pathProvider.present >> true + def pathProvider = withValues("a", "b") expect: def file = layout.projectDirectory.file("child") @@ -87,9 +84,7 @@ class DefaultProjectLayoutTest extends Specification { } def "directory is not present when path provider is not present"() { - def pathProvider = Stub(ProviderInternal) - _ * pathProvider.present >> false - _ * pathProvider.getOrNull() >> null + def pathProvider = withNoValue() expect: def provider = layout.projectDirectory.dir(pathProvider) @@ -98,9 +93,7 @@ class DefaultProjectLayoutTest extends Specification { } def "regular file is not present when path provider is not present"() { - def pathProvider = Stub(ProviderInternal) - _ * pathProvider.present >> false - _ * pathProvider.getOrNull() >> null + def pathProvider = withNoValue() expect: def provider = layout.projectDirectory.file(pathProvider) @@ -183,9 +176,7 @@ class DefaultProjectLayoutTest extends Specification { } def "can resolve directory relative to build directory"() { - def pathProvider = Stub(Provider) - _ * pathProvider.get() >>> ["a", "b"] - _ * pathProvider.present >> true + def pathProvider = withValues("a", "b") expect: def dir = layout.buildDirectory.dir("sub-dir") @@ -206,9 +197,7 @@ class DefaultProjectLayoutTest extends Specification { } def "can resolve regular file relative to build directory"() { - def pathProvider = Stub(Provider) - _ * pathProvider.get() >>> ["a", "b"] - _ * pathProvider.present >> true + def pathProvider = withValues("a", "b") expect: def file = layout.buildDirectory.file("child") @@ -249,12 +238,9 @@ class DefaultProjectLayoutTest extends Specification { } def "can map File provider to regular file provider"() { - def fileProvider = Stub(ProviderInternal) def file1 = projectDir.file("file1") def file2 = projectDir.file("file2") - - _ * fileProvider.present >> true - _ * fileProvider.get() >>> [file1, file2] + def fileProvider = withValues(file1, file2) expect: def provider = layout.file(fileProvider) @@ -265,12 +251,9 @@ class DefaultProjectLayoutTest extends Specification { } def "can map File provider to directory provider"() { - def fileProvider = Stub(ProviderInternal) def file1 = projectDir.file("file1") def file2 = projectDir.file("file2") - - _ * fileProvider.present >> true - _ * fileProvider.get() >>> [file1, file2] + def fileProvider = withValues(file1, file2) expect: def provider = layout.dir(fileProvider) @@ -281,12 +264,10 @@ class DefaultProjectLayoutTest extends Specification { } def "resolves relative file given by File provider"() { - def fileProvider = Stub(ProviderInternal) def file1 = projectDir.file("file1") def file2 = projectDir.file("file2") - _ * fileProvider.present >> true - _ * fileProvider.get() >>> [new File("file1"), new File("file2")] + def fileProvider = withValues(new File("file1"), new File("file2")) expect: def provider = layout.file(fileProvider) @@ -297,12 +278,10 @@ class DefaultProjectLayoutTest extends Specification { } def "resolves relative dir given by File provider"() { - def dirProvider = Stub(ProviderInternal) def dir1 = projectDir.file("dir1") def dir2 = projectDir.file("dir2") - _ * dirProvider.present >> true - _ * dirProvider.get() >>> [new File("dir1"), new File("dir2")] + def dirProvider = withValues(new File("dir1"), new File("dir2")) expect: def provider = layout.dir(dirProvider) diff --git a/subprojects/file-collections/src/main/java/org/gradle/api/internal/file/AbstractFileCollection.java b/subprojects/file-collections/src/main/java/org/gradle/api/internal/file/AbstractFileCollection.java index 9a4893d90835..0490212e6d2a 100644 --- a/subprojects/file-collections/src/main/java/org/gradle/api/internal/file/AbstractFileCollection.java +++ b/subprojects/file-collections/src/main/java/org/gradle/api/internal/file/AbstractFileCollection.java @@ -33,10 +33,10 @@ import org.gradle.api.specs.Spec; import org.gradle.api.specs.Specs; import org.gradle.api.tasks.TaskDependency; +import org.gradle.internal.Cast; import org.gradle.util.CollectionUtils; import org.gradle.util.GUtil; -import javax.annotation.Nullable; import java.io.File; import java.util.ArrayList; import java.util.Collection; @@ -115,10 +115,9 @@ public FileCollection plus(FileCollection collection) { @Override public Provider> getElements() { return new AbstractProviderWithValue>() { - @Nullable @Override public Class> getType() { - return null; + return Cast.uncheckedCast(Set.class); } @Override diff --git a/subprojects/file-collections/src/main/java/org/gradle/api/internal/file/DefaultFilePropertyFactory.java b/subprojects/file-collections/src/main/java/org/gradle/api/internal/file/DefaultFilePropertyFactory.java index 25d3d41b921e..7b495f1801ca 100644 --- a/subprojects/file-collections/src/main/java/org/gradle/api/internal/file/DefaultFilePropertyFactory.java +++ b/subprojects/file-collections/src/main/java/org/gradle/api/internal/file/DefaultFilePropertyFactory.java @@ -248,10 +248,9 @@ public Class getType() { return AbstractFileVar.this.getType(); } - @Nullable @Override - public T getOrNull() { - return AbstractFileVar.this.getOrNull(); + protected Value calculateOwnValue() { + return AbstractFileVar.this.calculateOwnValue(); } }; } @@ -356,7 +355,7 @@ protected Directory mapValue(Directory dir) { @Override public Provider dir(final Provider path) { - return new AbstractCombiningProvider(Directory.class, this, path) { + return new AbstractCombiningProvider(Directory.class, this, Providers.internal(path)) { @Override protected Directory map(Directory b, CharSequence v) { return b.dir(v.toString()); @@ -376,7 +375,7 @@ protected RegularFile mapValue(Directory dir) { @Override public Provider file(final Provider path) { - return new AbstractCombiningProvider(RegularFile.class, this, path) { + return new AbstractCombiningProvider(RegularFile.class, this, Providers.internal(path)) { @Override protected RegularFile map(Directory b, CharSequence v) { return b.file(v.toString()); diff --git a/subprojects/file-collections/src/test/groovy/org/gradle/api/internal/file/DefaultFilePropertyFactoryTest.groovy b/subprojects/file-collections/src/test/groovy/org/gradle/api/internal/file/DefaultFilePropertyFactoryTest.groovy index 1ef2b9986c45..4c594b27cefe 100644 --- a/subprojects/file-collections/src/test/groovy/org/gradle/api/internal/file/DefaultFilePropertyFactoryTest.groovy +++ b/subprojects/file-collections/src/test/groovy/org/gradle/api/internal/file/DefaultFilePropertyFactoryTest.groovy @@ -212,21 +212,21 @@ class DefaultFilePropertyFactoryTest extends Specification { then: def e2 = thrown(IllegalStateException) - e2.message == 'Cannot query the value of this property because it has no value available.' + e2.message == 'Cannot query the value of this provider because it has no value available.' when: dir.get() then: def e3 = thrown(IllegalStateException) - e3.message == 'Cannot query the value of this property because it has no value available.' + e3.message == 'Cannot query the value of this provider because it has no value available.' when: file.get() then: def e4 = thrown(IllegalStateException) - e4.message == 'Cannot query the value of this property because it has no value available.' + e4.message == 'Cannot query the value of this provider because it has no value available.' when: tree.files diff --git a/subprojects/language-jvm/src/main/java/org/gradle/api/tasks/compile/AbstractCompile.java b/subprojects/language-jvm/src/main/java/org/gradle/api/tasks/compile/AbstractCompile.java index aa145cb09470..fd0d63567b54 100644 --- a/subprojects/language-jvm/src/main/java/org/gradle/api/tasks/compile/AbstractCompile.java +++ b/subprojects/language-jvm/src/main/java/org/gradle/api/tasks/compile/AbstractCompile.java @@ -27,7 +27,6 @@ import org.gradle.api.tasks.OutputDirectory; import org.gradle.api.tasks.SourceTask; -import javax.annotation.Nullable; import java.io.File; /** @@ -98,7 +97,6 @@ public void setDestinationDir(File destinationDir) { * Sets the directory to generate the {@code .class} files into. * * @param destinationDir The destination directory. Must not be null. - * * @since 4.0 */ public void setDestinationDir(Provider destinationDir) { @@ -154,23 +152,26 @@ public Class getType() { return Directory.class; } - @Nullable @Override - public Directory getOrNull() { + protected Value calculateOwnValue() { if (recursiveCall) { - // getOrNull() was called by AbstractCompile.getDestinationDirectory() and not by a subclass implementation of that method. + // Already quering AbstractCompile.getDestinationDirectory() and not by a subclass implementation of that method. // In that case, this convention should not be used. - return null; + return Value.missing(); } recursiveCall = true; - // If we are not in an error case, this will most likely call a subclass implementation of getDestinationDir(). - // In the Kotlin plugin, the subclass manages it's own field which will be used here. - File legacyValue = getDestinationDir(); - recursiveCall = false; + File legacyValue; + try { + // If we are not in an error case, this will most likely call a subclass implementation of getDestinationDir(). + // In the Kotlin plugin, the subclass manages it's own field which will be used here. + legacyValue = getDestinationDir(); + } finally { + recursiveCall = false; + } if (legacyValue == null) { - return null; + return Value.missing(); } else { - return getProject().getLayout().dir(getProject().provider(() -> legacyValue)).get(); + return Value.of(getProject().getLayout().getProjectDirectory().dir(legacyValue.getAbsolutePath())); } } } diff --git a/subprojects/language-native/src/main/java/org/gradle/language/internal/DefaultBinaryCollection.java b/subprojects/language-native/src/main/java/org/gradle/language/internal/DefaultBinaryCollection.java index a3a2fbbb3485..137c6446b759 100644 --- a/subprojects/language-native/src/main/java/org/gradle/language/internal/DefaultBinaryCollection.java +++ b/subprojects/language-native/src/main/java/org/gradle/language/internal/DefaultBinaryCollection.java @@ -21,7 +21,6 @@ import org.gradle.api.Action; import org.gradle.api.component.SoftwareComponent; import org.gradle.api.internal.provider.AbstractMinimalProvider; -import org.gradle.api.provider.ProviderFactory; import org.gradle.api.specs.Spec; import org.gradle.internal.ImmutableActionSet; import org.gradle.language.BinaryCollection; @@ -43,23 +42,21 @@ private enum State { } private final Class elementType; - private final ProviderFactory providerFactory; - private final Set elements = new LinkedHashSet(); - private List> pending = new LinkedList>(); + private final Set elements = new LinkedHashSet<>(); + private List> pending = new LinkedList<>(); private State state = State.Collecting; private ImmutableActionSet knownActions = ImmutableActionSet.empty(); private ImmutableActionSet configureActions = ImmutableActionSet.empty(); private ImmutableActionSet finalizeActions = ImmutableActionSet.empty(); @Inject - public DefaultBinaryCollection(Class elementType, ProviderFactory providerFactory) { + public DefaultBinaryCollection(Class elementType) { this.elementType = elementType; - this.providerFactory = providerFactory; } @Override public BinaryProvider get(final Class type, final Spec spec) { - SingleElementProvider provider = new SingleElementProvider(type, spec); + SingleElementProvider provider = new SingleElementProvider<>(type, spec); if (state == State.Collecting) { pending.add(provider); } else { @@ -70,12 +67,7 @@ public BinaryProvider get(final Class type, final Spec spec @Override public BinaryProvider getByName(final String name) { - return get(elementType, new Spec() { - @Override - public boolean isSatisfiedBy(T element) { - return element.getName().equals(name); - } - }); + return get(elementType, element -> element.getName().equals(name)); } @Override @@ -93,7 +85,7 @@ public void whenElementKnown(Action action) { @Override public void whenElementKnown(final Class type, final Action action) { - whenElementKnown(new TypeFilteringAction(type, action)); + whenElementKnown(new TypeFilteringAction<>(type, action)); } @Override @@ -109,7 +101,7 @@ public void whenElementFinalized(Action action) { @Override public void whenElementFinalized(Class type, Action action) { - whenElementFinalized(new TypeFilteringAction(type, action)); + whenElementFinalized(new TypeFilteringAction<>(type, action)); } @Override @@ -122,7 +114,7 @@ public void configureEach(Action action) { @Override public void configureEach(Class type, Action action) { - configureEach(new TypeFilteringAction(type, action)); + configureEach(new TypeFilteringAction<>(type, action)); } public void add(T element) { @@ -203,40 +195,33 @@ public Class getType() { // Mix in some Groovy DSL support. Should decorate instead public void configure(Closure closure) { - configure(ConfigureUtil.configureUsing(closure)); + configure(ConfigureUtil.configureUsing(closure)); } @Override public void configure(final Action action) { - configureEach(new Action() { - @Override - public void execute(T t) { - if (match == t) { - action.execute(match); - } + configureEach(t -> { + if (match == t) { + action.execute(match); } }); } @Override public void whenFinalized(final Action action) { - whenElementFinalized(new Action() { - @Override - public void execute(T t) { - if (match == t) { - action.execute(match); - } + whenElementFinalized(t -> { + if (match == t) { + action.execute(match); } }); } - @Nullable @Override - public S getOrNull() { + protected Value calculateOwnValue() { if (ambiguous) { throw new IllegalStateException("Found multiple elements"); } - return match; + return Value.ofNullable(match); } } diff --git a/subprojects/language-native/src/test/groovy/org/gradle/language/internal/DefaultBinaryCollectionTest.groovy b/subprojects/language-native/src/test/groovy/org/gradle/language/internal/DefaultBinaryCollectionTest.groovy index 002813df4fbb..0e4d2ff2736d 100644 --- a/subprojects/language-native/src/test/groovy/org/gradle/language/internal/DefaultBinaryCollectionTest.groovy +++ b/subprojects/language-native/src/test/groovy/org/gradle/language/internal/DefaultBinaryCollectionTest.groovy @@ -17,7 +17,6 @@ package org.gradle.language.internal import org.gradle.api.Action -import org.gradle.api.internal.provider.DefaultProviderFactory import org.gradle.api.specs.Spec import org.gradle.language.cpp.CppBinary import org.gradle.language.swift.SwiftBinary @@ -25,7 +24,7 @@ import org.gradle.language.swift.SwiftSharedLibrary import spock.lang.Specification class DefaultBinaryCollectionTest extends Specification { - def container = new DefaultBinaryCollection(SwiftBinary, new DefaultProviderFactory()) + def container = new DefaultBinaryCollection(SwiftBinary) def "can query elements when realized"() { def binary1 = Stub(SwiftBinary) diff --git a/subprojects/language-native/src/test/groovy/org/gradle/language/plugins/NativeBasePluginTest.groovy b/subprojects/language-native/src/test/groovy/org/gradle/language/plugins/NativeBasePluginTest.groovy index 1af310484f58..8d32b0088332 100644 --- a/subprojects/language-native/src/test/groovy/org/gradle/language/plugins/NativeBasePluginTest.groovy +++ b/subprojects/language-native/src/test/groovy/org/gradle/language/plugins/NativeBasePluginTest.groovy @@ -69,7 +69,7 @@ class NativeBasePluginTest extends Specification { def b2 = Stub(SoftwareComponent) b2.name >> "b2" def component = Stub(ComponentWithBinaries) - def binaries = new DefaultBinaryCollection(SoftwareComponent, null) + def binaries = new DefaultBinaryCollection(SoftwareComponent) component.binaries >> binaries given: @@ -109,7 +109,7 @@ class NativeBasePluginTest extends Specification { def "assemble task builds outputs of development binary of main component"() { def binary1 = binary('debug', 'debugInstall') def binary2 = binary('release', 'releaseInstall') - def binaries = new DefaultBinaryCollection(SoftwareComponent, null) + def binaries = new DefaultBinaryCollection(SoftwareComponent) binaries.add(binary1) binaries.add(binary2) def component = Stub(TestComponent) @@ -130,7 +130,7 @@ class NativeBasePluginTest extends Specification { def "adds assemble task for each binary of main component"() { def binary1 = binary('debug', 'installDebug') def binary2 = binary('release', 'installRelease') - def binaries = new DefaultBinaryCollection(SoftwareComponent, null) + def binaries = new DefaultBinaryCollection(SoftwareComponent) binaries.add(binary1) binaries.add(binary2) def component = Stub(TestComponent) diff --git a/subprojects/model-core/src/main/java/org/gradle/api/internal/provider/AbstractCombiningProvider.java b/subprojects/model-core/src/main/java/org/gradle/api/internal/provider/AbstractCombiningProvider.java index ee3fe7c1d16c..1eb389cdb2ca 100644 --- a/subprojects/model-core/src/main/java/org/gradle/api/internal/provider/AbstractCombiningProvider.java +++ b/subprojects/model-core/src/main/java/org/gradle/api/internal/provider/AbstractCombiningProvider.java @@ -16,19 +16,17 @@ package org.gradle.api.internal.provider; -import org.gradle.api.provider.Provider; - import javax.annotation.Nullable; public abstract class AbstractCombiningProvider extends AbstractMinimalProvider { private final Class type; - private final Provider base; - private final Provider provider; + private final ProviderInternal left; + private final ProviderInternal right; - public AbstractCombiningProvider(Class type, Provider base, Provider provider) { + public AbstractCombiningProvider(Class type, ProviderInternal left, ProviderInternal right) { this.type = type; - this.base = base; - this.provider = provider; + this.left = left; + this.right = right; } @Nullable @@ -39,21 +37,26 @@ public Class getType() { @Override public boolean isPresent() { - return base.isPresent() && provider.isPresent(); + return left.isPresent() && right.isPresent(); } @Override - public OUT getOrNull() { - if (base.isPresent() && provider.isPresent()) { - return map(base.get(), provider.get()); + protected Value calculateOwnValue() { + Value leftValue = left.calculateValue(); + if (leftValue.isMissing()) { + return leftValue.asType(); + } + Value rightValue = right.calculateValue(); + if (rightValue.isMissing()) { + return rightValue.asType(); } - return null; + return Value.of(map(leftValue.get(), rightValue.get())); } protected abstract OUT map(BASE b, IN v); @Override public String toString() { - return String.format("combine(%s, %s)", base, provider); + return String.format("combine(%s, %s)", left, right); } } diff --git a/subprojects/model-core/src/main/java/org/gradle/api/internal/provider/AbstractMappingProvider.java b/subprojects/model-core/src/main/java/org/gradle/api/internal/provider/AbstractMappingProvider.java index 053454604407..1a956f904c76 100644 --- a/subprojects/model-core/src/main/java/org/gradle/api/internal/provider/AbstractMappingProvider.java +++ b/subprojects/model-core/src/main/java/org/gradle/api/internal/provider/AbstractMappingProvider.java @@ -61,19 +61,13 @@ public boolean isPresent() { } @Override - public OUT get() { + protected Value calculateOwnValue() { beforeRead(); - return mapValue(provider.get()); - } - - @Override - public OUT getOrNull() { - beforeRead(); - IN value = provider.getOrNull(); - if (value != null) { - return mapValue(value); + Value value = provider.calculateValue(); + if (value.isMissing()) { + return value.asType(); } - return null; + return Value.of(mapValue(value.get())); } protected abstract OUT mapValue(IN v); diff --git a/subprojects/model-core/src/main/java/org/gradle/api/internal/provider/AbstractMinimalProvider.java b/subprojects/model-core/src/main/java/org/gradle/api/internal/provider/AbstractMinimalProvider.java index a230e8b37494..c35726bf532c 100644 --- a/subprojects/model-core/src/main/java/org/gradle/api/internal/provider/AbstractMinimalProvider.java +++ b/subprojects/model-core/src/main/java/org/gradle/api/internal/provider/AbstractMinimalProvider.java @@ -22,16 +22,20 @@ import org.gradle.api.internal.tasks.TaskDependencyResolveContext; import org.gradle.api.provider.Provider; import org.gradle.internal.Cast; +import org.gradle.internal.Describables; import org.gradle.internal.DisplayName; +import org.gradle.internal.logging.text.TreeFormatter; import org.gradle.internal.state.Managed; import org.gradle.util.GUtil; import javax.annotation.Nullable; /** - * A partial {@link Provider} implementation. Subclasses need to implement {@link ProviderInternal#getType()} and {@link Provider#getOrNull()}. + * A partial {@link Provider} implementation. Subclasses need to implement {@link ProviderInternal#getType()} and {@link AbstractMinimalProvider#calculateOwnValue()}. */ public abstract class AbstractMinimalProvider implements ProviderInternal, ScalarSupplier, Managed { + private static final DisplayName DEFAULT_DISPLAY_NAME = Describables.of("this provider"); + @Override public ProviderInternal map(final Transformer transformer) { return new TransformBackedProvider<>(transformer, this); @@ -42,30 +46,68 @@ public Provider flatMap(final Transformer return new FlatMapProvider<>(this, transformer); } + /** + * Returns the human consumable display name for this provider, or null if this is not known. + */ + @Nullable + protected DisplayName getDeclaredDisplayName() { + return null; + } + + /** + * Returns a display name for this provider, using a default if this is not known. + */ + protected DisplayName getDisplayName() { + DisplayName displayName = getDeclaredDisplayName(); + if (displayName == null) { + return DEFAULT_DISPLAY_NAME; + } + return displayName; + } + + protected DisplayName getTypedDisplayName() { + return DEFAULT_DISPLAY_NAME; + } + + protected abstract ScalarSupplier.Value calculateOwnValue(); + @Override public boolean isPresent() { - return !calculateValue().isMissing(); + return !calculateOwnValue().isMissing(); } @Override public T get() { - Value value = calculateValue(); + Value value = calculateOwnValue(); if (value.isMissing()) { - throw new MissingValueException(Providers.NULL_VALUE); + TreeFormatter formatter = new TreeFormatter(); + formatter.node("Cannot query the value of ").append(getDisplayName().getDisplayName()).append(" because it has no value available."); + if (!value.getPathToOrigin().isEmpty()) { + formatter.node("The value of ").append(getTypedDisplayName().getDisplayName()).append(" is derived from"); + formatter.startChildren(); + for (DisplayName displayName : value.getPathToOrigin()) { + formatter.node(displayName.getDisplayName()); + } + formatter.endChildren(); + } + throw new MissingValueException(formatter.toString()); } return value.get(); } - // This is here as a migration step. It would be better for each subclass to provide an implementation of this method and implement - // getOrNull() based on the result, rather than implementing this method based on getOrNull() @Override - public Value calculateValue() { - return Value.ofNullable(getOrNull()); + public T getOrNull() { + return calculateOwnValue().orNull(); } @Override public T getOrElse(T defaultValue) { - return calculateValue().orElse(defaultValue); + return calculateOwnValue().orElse(defaultValue); + } + + @Override + public Value calculateValue() { + return calculateOwnValue().pushWhenMissing(getDeclaredDisplayName()); } @Override @@ -147,7 +189,7 @@ public int getFactoryId() { } private static class FlatMapProvider extends AbstractMinimalProvider { - private final Provider provider; + private final ProviderInternal provider; private final Transformer, ? super T> transformer; FlatMapProvider(ProviderInternal provider, Transformer, ? super T> transformer) { @@ -171,27 +213,20 @@ public boolean isPresent() { } @Override - public S get() { - T value = provider.get(); - return map(value).get(); - } - - @Nullable - @Override - public S getOrNull() { - T value = provider.getOrNull(); - if (value == null) { - return null; + protected Value calculateOwnValue() { + Value value = provider.calculateValue(); + if (value.isMissing()) { + return value.asType(); } - return map(value).getOrNull(); + return map(value.get()).calculateValue(); } - private Provider map(T value) { + private ProviderInternal map(T value) { Provider result = transformer.transform(value); if (result == null) { throw new IllegalStateException(Providers.NULL_TRANSFORMER_RESULT); } - return result; + return Providers.internal(result); } @Override @@ -265,14 +300,17 @@ public boolean isPresent() { return left.isPresent() || right.isPresent(); } - @Nullable @Override - public T getOrNull() { - T value = left.getOrNull(); - if (value == null) { - value = right.getOrNull(); + protected Value calculateOwnValue() { + Value leftValue = left.calculateValue(); + if (!leftValue.isMissing()) { + return leftValue; + } + Value rightValue = right.calculateValue(); + if (!rightValue.isMissing()) { + return rightValue; } - return value; + return leftValue.addPathsFrom(rightValue); } } diff --git a/subprojects/model-core/src/main/java/org/gradle/api/internal/provider/AbstractProperty.java b/subprojects/model-core/src/main/java/org/gradle/api/internal/provider/AbstractProperty.java index 9baa1f73af5d..5eb8dff24366 100644 --- a/subprojects/model-core/src/main/java/org/gradle/api/internal/provider/AbstractProperty.java +++ b/subprojects/model-core/src/main/java/org/gradle/api/internal/provider/AbstractProperty.java @@ -21,7 +21,6 @@ import org.gradle.api.internal.tasks.TaskDependencyResolveContext; import org.gradle.internal.Describables; import org.gradle.internal.DisplayName; -import org.gradle.internal.logging.text.TreeFormatter; import javax.annotation.Nullable; @@ -44,11 +43,17 @@ public void attachDisplayName(DisplayName displayName) { this.displayName = displayName; } - @Nullable + @Nullable @Override protected DisplayName getDeclaredDisplayName() { return displayName; } + @Override + protected DisplayName getTypedDisplayName() { + return DEFAULT_DISPLAY_NAME; + } + + @Override protected DisplayName getDisplayName() { if (displayName == null) { return DEFAULT_DISPLAY_NAME; @@ -88,42 +93,6 @@ public final String toString() { } } - protected abstract ScalarSupplier.Value calculateOwnValue(); - - @Override - public Value calculateValue() { - return calculateOwnValue().pushWhenMissing(getDeclaredDisplayName()); - } - - @Override - public T get() { - Value value = calculateOwnValue(); - if (value.isMissing()) { - TreeFormatter formatter = new TreeFormatter(); - formatter.node("Cannot query the value of ").append(getDisplayName().getDisplayName()).append(" because it has no value available."); - if (!value.getPathToOrigin().isEmpty()) { - formatter.node("The value of this property is derived from"); - formatter.startChildren(); - for (DisplayName displayName : value.getPathToOrigin()) { - formatter.node(displayName.getDisplayName()); - } - formatter.endChildren(); - } - throw new MissingValueException(formatter.toString()); - } - return value.get(); - } - - @Override - public T getOrNull() { - return calculateOwnValue().orNull(); - } - - @Override - public T getOrElse(T defaultValue) { - return calculateOwnValue().orElse(defaultValue); - } - @Override public void visitProducerTasks(Action visitor) { if (producer != null) { diff --git a/subprojects/model-core/src/main/java/org/gradle/api/internal/provider/AbstractProviderWithValue.java b/subprojects/model-core/src/main/java/org/gradle/api/internal/provider/AbstractProviderWithValue.java index 3a70ae413255..5ed7c94dc592 100644 --- a/subprojects/model-core/src/main/java/org/gradle/api/internal/provider/AbstractProviderWithValue.java +++ b/subprojects/model-core/src/main/java/org/gradle/api/internal/provider/AbstractProviderWithValue.java @@ -22,6 +22,14 @@ * A {@link org.gradle.api.provider.Provider} that always has a value defined. The value may not necessarily be final. */ public abstract class AbstractProviderWithValue extends AbstractMinimalProvider { + @Override + protected Value calculateOwnValue() { + return Value.of(get()); + } + + @Override + public abstract T get(); + @Override public T getOrNull() { return get(); diff --git a/subprojects/model-core/src/main/java/org/gradle/api/internal/provider/DefaultMapProperty.java b/subprojects/model-core/src/main/java/org/gradle/api/internal/provider/DefaultMapProperty.java index b5dbc03a9de2..59f141f22988 100644 --- a/subprojects/model-core/src/main/java/org/gradle/api/internal/provider/DefaultMapProperty.java +++ b/subprojects/model-core/src/main/java/org/gradle/api/internal/provider/DefaultMapProperty.java @@ -336,16 +336,15 @@ public Class> getType() { return (Class) Set.class; } - @Nullable @Override - public Set getOrNull() { + protected Value> calculateOwnValue() { beforeRead(); Set keys = new LinkedHashSet<>(); Value result = value.maybeCollectKeysInto(keyCollector, keys); if (result.isMissing()) { - return null; + return result.asType(); } - return ImmutableSet.copyOf(keys); + return Value.of(ImmutableSet.copyOf(keys)); } } diff --git a/subprojects/model-core/src/main/java/org/gradle/api/internal/provider/DefaultProvider.java b/subprojects/model-core/src/main/java/org/gradle/api/internal/provider/DefaultProvider.java index bbcc0308a604..9a3796367c44 100644 --- a/subprojects/model-core/src/main/java/org/gradle/api/internal/provider/DefaultProvider.java +++ b/subprojects/model-core/src/main/java/org/gradle/api/internal/provider/DefaultProvider.java @@ -36,9 +36,9 @@ public Class getType() { } @Override - public T getOrNull() { + protected Value calculateOwnValue() { try { - return value.call(); + return Value.ofNullable(value.call()); } catch (Exception e) { throw UncheckedException.throwAsUncheckedException(e); } diff --git a/subprojects/model-core/src/main/java/org/gradle/api/internal/provider/DefaultValueSourceProviderFactory.java b/subprojects/model-core/src/main/java/org/gradle/api/internal/provider/DefaultValueSourceProviderFactory.java index e7968328ff1c..e82ec86d192a 100644 --- a/subprojects/model-core/src/main/java/org/gradle/api/internal/provider/DefaultValueSourceProviderFactory.java +++ b/subprojects/model-core/src/main/java/org/gradle/api/internal/provider/DefaultValueSourceProviderFactory.java @@ -189,9 +189,8 @@ public Class getType() { return null; } - @Nullable @Override - public T getOrNull() { + protected Value calculateOwnValue() { synchronized (this) { if (value == null) { @@ -200,7 +199,7 @@ public T getOrNull() { onValueObtained(); } - return value.get(); + return Value.ofNullable(value.get()); } } diff --git a/subprojects/model-core/src/main/java/org/gradle/api/internal/provider/Providers.java b/subprojects/model-core/src/main/java/org/gradle/api/internal/provider/Providers.java index 25a5289722b9..32e6a49ced0c 100644 --- a/subprojects/model-core/src/main/java/org/gradle/api/internal/provider/Providers.java +++ b/subprojects/model-core/src/main/java/org/gradle/api/internal/provider/Providers.java @@ -16,7 +16,6 @@ package org.gradle.api.internal.provider; -import org.gradle.api.Describable; import org.gradle.api.Transformer; import org.gradle.api.provider.Provider; import org.gradle.internal.Cast; @@ -26,7 +25,6 @@ public class Providers { public static final String NULL_TRANSFORMER_RESULT = "Transformer for this provider returned a null value."; - public static final String NULL_VALUE = "Cannot query the value of this provider because it has no value available."; private static final NoValueProvider NULL_PROVIDER = new NoValueProvider(); @@ -77,10 +75,6 @@ public static ProviderInternal ofNullable(@Nullable T value) { } } - public static MissingValueException nullValue(Describable owner) { - return new MissingValueException(String.format("Cannot query the value of %s because it has no value available.", owner.getDisplayName())); - } - public static class FixedValueProvider extends AbstractProviderWithValue implements ScalarSupplier { private final T value; @@ -99,21 +93,6 @@ public T get() { return value; } - @Override - public Value calculateValue() { - return new Present<>(value); - } - - @Override - public T getOrNull() { - return value; - } - - @Override - public T getOrElse(T defaultValue) { - return value; - } - @Override public ProviderInternal asProvider() { return this; @@ -160,14 +139,14 @@ public boolean isPresent() { } @Override - public S get() { + protected Value calculateOwnValue() { if (value == null) { value = transformer.transform(provider.get()); if (value == null) { throw new IllegalStateException(NULL_TRANSFORMER_RESULT); } } - return value; + return Value.of(value); } @Override @@ -196,11 +175,6 @@ public String toString() { } private static class NoValueProvider extends AbstractMinimalProvider implements ScalarSupplier { - @Override - public Object get() { - throw new MissingValueException(NULL_VALUE); - } - @Override public Value calculateValue() { return new Missing<>(); @@ -218,13 +192,8 @@ public Class getType() { } @Override - public Object getOrNull() { - return null; - } - - @Override - public Object getOrElse(Object defaultValue) { - return defaultValue; + protected Value calculateOwnValue() { + return Value.missing(); } @Override diff --git a/subprojects/model-core/src/main/java/org/gradle/api/internal/provider/ValueSupplier.java b/subprojects/model-core/src/main/java/org/gradle/api/internal/provider/ValueSupplier.java index 3125904e1e86..aea23ed2575a 100644 --- a/subprojects/model-core/src/main/java/org/gradle/api/internal/provider/ValueSupplier.java +++ b/subprojects/model-core/src/main/java/org/gradle/api/internal/provider/ValueSupplier.java @@ -48,11 +48,11 @@ interface Value { Value MISSING = new ScalarSupplier.Missing<>(); Value SUCCESS = new Present<>(null); - static Value ofNullable(@Nullable T value) { + static Value ofNullable(@Nullable T value) { if (value == null) { return MISSING.asType(); } - return new Present(value); + return new Present<>(value); } static Value missing() { @@ -60,6 +60,7 @@ static Value missing() { } static Value of(T value) { + assert value != null; return new Present<>(value); } @@ -79,9 +80,11 @@ static Value present() { boolean isMissing(); + Value asType(); + Value pushWhenMissing(@Nullable DisplayName displayName); - Value asType(); + Value addPathsFrom(Value rightValue); } class Present implements Value { @@ -125,6 +128,11 @@ public Value asType() { public List getPathToOrigin() { throw new IllegalStateException(); } + + @Override + public Value addPathsFrom(Value rightValue) { + throw new IllegalStateException(); + } } class Missing implements Value { @@ -176,7 +184,22 @@ public Value pushWhenMissing(@Nullable DisplayName displayName) { ImmutableList.Builder builder = ImmutableList.builderWithExpectedSize(path.size() + 1); builder.add(displayName); builder.addAll(path); - return new Missing(builder.build()); + return new Missing<>(builder.build()); + } + + @Override + public Value addPathsFrom(Value rightValue) { + if (path.isEmpty()) { + return rightValue.asType(); + } + Missing other = (Missing) rightValue; + if (other.path.isEmpty()) { + return this; + } + ImmutableList.Builder builder = ImmutableList.builderWithExpectedSize(path.size() + other.path.size()); + builder.addAll(path); + builder.addAll(other.path); + return new Missing<>(builder.build()); } } } diff --git a/subprojects/model-core/src/test/groovy/org/gradle/api/internal/provider/AbstractProviderTest.groovy b/subprojects/model-core/src/test/groovy/org/gradle/api/internal/provider/AbstractProviderTest.groovy index e8e3ad31fdd8..cc17ddfb6a71 100644 --- a/subprojects/model-core/src/test/groovy/org/gradle/api/internal/provider/AbstractProviderTest.groovy +++ b/subprojects/model-core/src/test/groovy/org/gradle/api/internal/provider/AbstractProviderTest.groovy @@ -19,6 +19,8 @@ package org.gradle.api.internal.provider import org.gradle.api.Transformer import org.gradle.internal.state.ManagedFactory +import javax.annotation.Nullable + class AbstractProviderTest extends ProviderSpec { TestProvider provider = new TestProvider() @@ -64,7 +66,7 @@ class AbstractProviderTest extends ProviderSpec { def "mapped provider is live"() { def transformer = Stub(Transformer) - transformer.transform(_) >> {String s -> "[$s]" } + transformer.transform(_) >> { String s -> "[$s]" } expect: def mapped = provider.map(transformer) @@ -86,9 +88,9 @@ class AbstractProviderTest extends ProviderSpec { def "can chain mapped providers"() { def transformer1 = Stub(Transformer) - transformer1.transform(_) >> {String s -> "[$s]" as String } + transformer1.transform(_) >> { String s -> "[$s]" as String } def transformer2 = Stub(Transformer) - transformer2.transform(_) >> {String s -> "-$s-" as String } + transformer2.transform(_) >> { String s -> "-$s-" as String } expect: def mapped = provider.map(transformer1).map(transformer2) @@ -114,6 +116,7 @@ class AbstractProviderTest extends ProviderSpec { } static class TestProvider extends AbstractMinimalProvider { + @Nullable String value void value(String s) { @@ -126,8 +129,8 @@ class AbstractProviderTest extends ProviderSpec { } @Override - Object getOrNull() { - return value + protected Value calculateOwnValue() { + return Value.ofNullable(value) } } } diff --git a/subprojects/model-core/src/test/groovy/org/gradle/api/internal/provider/CollectionPropertySpec.groovy b/subprojects/model-core/src/test/groovy/org/gradle/api/internal/provider/CollectionPropertySpec.groovy index 74dcc2779abc..e08476d243b2 100644 --- a/subprojects/model-core/src/test/groovy/org/gradle/api/internal/provider/CollectionPropertySpec.groovy +++ b/subprojects/model-core/src/test/groovy/org/gradle/api/internal/provider/CollectionPropertySpec.groovy @@ -455,7 +455,7 @@ abstract class CollectionPropertySpec> extends Prop def "reports the source of element provider when value is missing and source is known"() { given: - def elementProvider = sourceWithNoValue(Describables.of("")) + def elementProvider = supplierWithNoValue(Describables.of("")) property.set(toMutable(["123"])) property.add(elementProvider) @@ -489,7 +489,7 @@ The value of this property is derived from: """) def "reports the source of collection provider when value is missing and source is known"() { given: - def elementsProvider = sourceWithNoValue(Describables.of("")) + def elementsProvider = supplierWithNoValue(Describables.of("")) property.set(toMutable(["123"])) property.addAll(elementsProvider) diff --git a/subprojects/model-core/src/test/groovy/org/gradle/api/internal/provider/DefaultPropertyTest.groovy b/subprojects/model-core/src/test/groovy/org/gradle/api/internal/provider/DefaultPropertyTest.groovy index e9892bd60789..48d9aa08eba2 100644 --- a/subprojects/model-core/src/test/groovy/org/gradle/api/internal/provider/DefaultPropertyTest.groovy +++ b/subprojects/model-core/src/test/groovy/org/gradle/api/internal/provider/DefaultPropertyTest.groovy @@ -217,7 +217,7 @@ class DefaultPropertyTest extends PropertySpec { def "mapped provider is live"() { def transformer = Mock(Transformer) - def provider = provider("abc") + def provider = supplierWithValues("abc") def property = new DefaultProperty(String) diff --git a/subprojects/model-core/src/test/groovy/org/gradle/api/internal/provider/MapPropertySpec.groovy b/subprojects/model-core/src/test/groovy/org/gradle/api/internal/provider/MapPropertySpec.groovy index a40ac6325376..bc3342dd1b59 100644 --- a/subprojects/model-core/src/test/groovy/org/gradle/api/internal/provider/MapPropertySpec.groovy +++ b/subprojects/model-core/src/test/groovy/org/gradle/api/internal/provider/MapPropertySpec.groovy @@ -342,7 +342,7 @@ class MapPropertySpec extends PropertySpec> { def "reports the source of value provider when value is missing and source is known"() { given: - def provider = sourceWithNoValue(String, Describables.of("")) + def provider = supplierWithNoValue(String, Describables.of("")) property.set(['k1': 'v1']) property.put('k2', 'v2') property.put('k3', provider) @@ -376,7 +376,7 @@ The value of this property is derived from: """) def "reports the source of map provider when value is missing and source is known"() { given: - def provider = sourceWithNoValue(Describables.of("")) + def provider = supplierWithNoValue(Describables.of("")) property.set(['k1': 'v1']) property.put('k2', 'v2') property.putAll(provider) diff --git a/subprojects/model-core/src/testFixtures/groovy/org/gradle/api/internal/provider/PropertySpec.groovy b/subprojects/model-core/src/testFixtures/groovy/org/gradle/api/internal/provider/PropertySpec.groovy index 259e357c9221..6e9a78858e89 100644 --- a/subprojects/model-core/src/testFixtures/groovy/org/gradle/api/internal/provider/PropertySpec.groovy +++ b/subprojects/model-core/src/testFixtures/groovy/org/gradle/api/internal/provider/PropertySpec.groovy @@ -16,7 +16,7 @@ package org.gradle.api.internal.provider -import org.gradle.api.Action + import org.gradle.api.Task import org.gradle.api.Transformer import org.gradle.api.internal.tasks.TaskDependencyResolveContext @@ -112,7 +112,7 @@ abstract class PropertySpec extends ProviderSpec { } def "can set value using provider"() { - def provider = provider(someValue(), someValue(), someOtherValue(), someValue()) + def provider = supplierWithValues(someValue(), someOtherValue(), someValue()) given: def property = propertyWithNoValue() @@ -183,7 +183,7 @@ abstract class PropertySpec extends ProviderSpec { } def "can set untyped using provider"() { - def provider = provider(someValue(), someValue()) + def provider = supplierWithValues(someValue(), someValue()) given: def property = propertyWithNoValue() @@ -209,7 +209,7 @@ abstract class PropertySpec extends ProviderSpec { } def "convention provider is used before value has been set"() { - def provider = provider(someValue(), someOtherValue(), someValue()) + def provider = supplierWithValues(someOtherValue(), someValue(), someValue()) def property = propertyWithDefaultValue() when: @@ -229,7 +229,7 @@ abstract class PropertySpec extends ProviderSpec { } def "property has no value when convention provider has no value"() { - def provider = provider() + def provider = supplierWithNoValue() def property = propertyWithDefaultValue() when: @@ -247,7 +247,7 @@ abstract class PropertySpec extends ProviderSpec { } def "reports the source of convention provider when value is missing and source is known"() { - def provider = sourceWithNoValue(Describables.of("")) + def provider = supplierWithNoValue(Describables.of("")) def property = propertyWithDefaultValue() given: @@ -263,7 +263,7 @@ The value of this property is derived from: """) } def "can replace convention value before value has been set"() { - def provider = provider(someOtherValue()) + def provider = supplierWithValues(someOtherValue()) def property = propertyWithDefaultValue() when: @@ -301,7 +301,7 @@ The value of this property is derived from: """) } def "convention provider ignored after value has been set"() { - def provider = broken() + def provider = brokenSupplier() def property = propertyWithDefaultValue() property.set(someValue()) @@ -327,7 +327,7 @@ The value of this property is derived from: """) } def "convention provider is used after value has been set to null"() { - def provider = provider(someOtherValue(), someOtherValue()) + def provider = supplierWithValues(someOtherValue(), someOtherValue()) def property = propertyWithDefaultValue() property.convention(provider) @@ -350,7 +350,7 @@ The value of this property is derived from: """) } def "convention provider ignored after value has been set using provider with no value"() { - def provider = broken() + def provider = brokenSupplier() def property = propertyWithDefaultValue() property.set(Providers.notDefined()) @@ -464,7 +464,77 @@ The value of this property is derived from: """) then: def e = thrown(MissingValueException) - e.message == "Cannot query the value of ${displayName} because it has no value available." + e.message == "Cannot query the value of this provider because it has no value available." + } + + def "reports the source of mapped provider when value is missing and source is known"() { + def transformer = Mock(Transformer) + def property = propertyWithNoValue() + property.attachDisplayName(Describables.of("")) + + def provider = property.map(transformer) + + when: + provider.get() + + then: + def e = thrown(MissingValueException) + e.message == TextUtil.toPlatformLineSeparators("""Cannot query the value of this provider because it has no value available. +The value of this provider is derived from: """) + } + + def "reports the source of flat mapped provider when value is missing and source is known"() { + def transformer = Mock(Transformer) + def property = propertyWithNoValue() + property.attachDisplayName(Describables.of("")) + + def provider = property.flatMap(transformer) + + when: + provider.get() + + then: + def e = thrown(MissingValueException) + e.message == TextUtil.toPlatformLineSeparators("""Cannot query the value of this provider because it has no value available. +The value of this provider is derived from: """) + } + + def "reports the source of flat mapped provider when mapped value is missing and its source is known"() { + def property = propertyWithNoValue() + property.set(someValue()) + + def other = propertyWithNoValue() + other.attachDisplayName(Describables.of("")) + + def provider = property.flatMap { other } + + when: + provider.get() + + then: + def e = thrown(MissingValueException) + e.message == TextUtil.toPlatformLineSeparators("""Cannot query the value of this provider because it has no value available. +The value of this provider is derived from: """) + } + + def "reports the source of orElse provider when both values are missing and its source is known"() { + def property = propertyWithNoValue() + property.attachDisplayName(Describables.of("")) + + def other = propertyWithNoValue() + other.attachDisplayName(Describables.of("")) + + def provider = property.orElse(other) + + when: + provider.get() + + then: + def e = thrown(MissingValueException) + e.message == TextUtil.toPlatformLineSeparators("""Cannot query the value of this provider because it has no value available. +The value of this provider is derived from: + - + - """) } def "can finalize value when no value defined"() { @@ -1583,7 +1653,7 @@ The value of this property is derived from: """) e2.message == 'The value for cannot be changed any further.' } - def "reports the source of the property's value when value is missing and source is known"() { + def "reports the source of property value when value is missing and source is known"() { given: def a = propertyWithNoValue() def b = propertyWithNoValue() @@ -1616,6 +1686,48 @@ The value of this property is derived from: """) def e3 = thrown(MissingValueException) e3.message == TextUtil.toPlatformLineSeparators("""Cannot query the value of because it has no value available. The value of this property is derived from: + - + - """) + } + + def "reports the source of mapped property value when value is missing and source is known"() { + given: + def a = propertyWithNoValue() + def b = propertyWithNoValue() + def c = propertyWithNoValue() + a.attachDisplayName(Describables.of("")) + a.set(b.map { it }) + b.set(c.map { it }) + def provider = a.map { it } + + when: + provider.get() + + then: + def e = thrown(MissingValueException) + e.message == TextUtil.toPlatformLineSeparators("""Cannot query the value of this provider because it has no value available. +The value of this provider is derived from: """) + + when: + c.attachDisplayName(Describables.of("")) + provider.get() + + then: + def e2 = thrown(MissingValueException) + e2.message == TextUtil.toPlatformLineSeparators("""Cannot query the value of this provider because it has no value available. +The value of this provider is derived from: + - + - """) + + when: + b.attachDisplayName(Describables.of("")) + provider.get() + + then: + def e3 = thrown(MissingValueException) + e3.message == TextUtil.toPlatformLineSeparators("""Cannot query the value of this provider because it has no value available. +The value of this provider is derived from: + - - - """) } @@ -1651,7 +1763,7 @@ The value of this property is derived from: def "has build dependencies when value is provider with producer task"() { def producer = "some task" - def provider = withProducer(producer) + def provider = supplierWithProducer(producer) def context = Mock(TaskDependencyResolveContext) def property = propertyWithNoValue() property.set(provider) @@ -1681,7 +1793,7 @@ The value of this property is derived from: def "has content producer when value is provider with content producer"() { def task = Mock(Task) - def provider = contentProducedByTask(task) + def provider = supplierWithProducer(task) def property = propertyWithNoValue() property.set(provider) @@ -1723,7 +1835,7 @@ The value of this property is derived from: def "mapped value has value producer when value is provider with content producer"() { def task = Mock(Task) - def provider = contentProducedByTask(task) + def provider = supplierWithProducer(task) def property = propertyWithNoValue() property.set(provider) @@ -1772,47 +1884,36 @@ The value of this property is derived from: assert producers == [task] } - ProviderInternal broken() { - return new AbstractMinimalProvider() { - @Override - Class getType() { - return PropertySpec.this.type() - } - - @Override - T getOrNull() { - throw new RuntimeException("broken!") - } - } + /** + * A dummy provider with no value. + */ + ProviderInternal supplierWithNoValue() { + return new NoValueProvider(type(), null) } /** - * A provider with no value and the given display name + * A dummy provider with no value and the given display name */ - ProviderInternal sourceWithNoValue(DisplayName displayName) { + ProviderInternal supplierWithNoValue(DisplayName displayName) { return new NoValueProvider(type(), displayName) } /** - * A provider with no value and the given display name + * A dummy provider with no value and the given display name */ - ProviderInternal sourceWithNoValue(Class type, DisplayName displayName) { + ProviderInternal supplierWithNoValue(Class type, DisplayName displayName) { return new NoValueProvider(type, displayName) } /** - * A provider that provides one of given values each time it is queried, in the order given. + * A dummy provider that provides one of given values each time it is queried, in the order given. */ - ProviderInternal provider(T... values) { - return new TestProvider(type(), values as List, null) - } - - ProviderInternal withProducer(Object value) { - return new TestProvider(type(), [], value) + ProviderInternal supplierWithValues(T... values) { + return ProviderTestUtil.withValues(values) } - ProviderInternal contentProducedByTask(Task producer) { - return new TestProvider(type(), [], producer) + ProviderInternal supplierWithProducer(Object producer) { + return ProviderTestUtil.withProducer(type(), producer) } class NoValueProvider extends AbstractMinimalProvider { @@ -1830,8 +1931,8 @@ The value of this property is derived from: } @Override - T getOrNull() { - return null + protected Value calculateOwnValue() { + return Value.missing() } @Override @@ -1840,39 +1941,5 @@ The value of this property is derived from: } } - class TestProvider extends AbstractMinimalProvider { - final Class type - final Iterator values - final Object producer - - TestProvider(Class type, List values, Object producer) { - this.producer = producer - this.values = values.iterator() - this.type = type - } - - @Override - void visitProducerTasks(Action visitor) { - if (producer != null) { - visitor.execute(producer) - } - } - - @Override - boolean maybeVisitBuildDependencies(TaskDependencyResolveContext context) { - if (producer != null) { - context.add(producer) - return true - } else { - return false - } - } - - @Override - T getOrNull() { - return values.hasNext() ? values.next() : null - } - } - static class Thing {} } diff --git a/subprojects/model-core/src/testFixtures/groovy/org/gradle/api/internal/provider/ProviderSpec.groovy b/subprojects/model-core/src/testFixtures/groovy/org/gradle/api/internal/provider/ProviderSpec.groovy index bd4be000e687..934c7772f059 100644 --- a/subprojects/model-core/src/testFixtures/groovy/org/gradle/api/internal/provider/ProviderSpec.groovy +++ b/subprojects/model-core/src/testFixtures/groovy/org/gradle/api/internal/provider/ProviderSpec.groovy @@ -193,7 +193,7 @@ abstract class ProviderSpec extends Specification { then: def t = thrown(MissingValueException) - t.message == "Cannot query the value of ${displayName} because it has no value available." + t.message == "Cannot query the value of this provider because it has no value available." } def "flat mapped provider with no value does not use transformer"() { @@ -213,7 +213,7 @@ abstract class ProviderSpec extends Specification { then: def t = thrown(MissingValueException) - t.message == "Cannot query the value of ${displayName} because it has no value available." + t.message == "Cannot query the value of this provider because it has no value available." } def "can map to provider that uses value if present or a default value"() { @@ -231,10 +231,11 @@ abstract class ProviderSpec extends Specification { def "can map to provider that uses value if present or a default value from another provider"() { expect: + def broken = brokenSupplier() def supplier = Providers.of(someOtherValue()) def present = providerWithValue(someValue()) - def usesValue = present.orElse(supplier) + def usesValue = present.orElse(broken) usesValue.present usesValue.get() == someValue() @@ -250,15 +251,17 @@ abstract class ProviderSpec extends Specification { expect: def supplier = Providers.notDefined() - def present = providerWithValue(someValue()) - def usesValue = present.orElse(supplier) - usesValue.present - usesValue.get() == someValue() - def notPresent = providerWithNoValue() def usesDefaultValue = notPresent.orElse(supplier) !usesDefaultValue.present usesDefaultValue.getOrNull() == null + + when: + notPresent.get() + + then: + def e = thrown(MissingValueException) + e.message == "Cannot query the value of ${displayName} because it has no value available." } def "can chain orElse"() { @@ -300,4 +303,22 @@ abstract class ProviderSpec extends Specification { copy.present copy.getOrNull() == someValue() } + + /** + * A test provider that always fails. + */ + ProviderInternal brokenSupplier() { + return new AbstractMinimalProvider() { + @Override + Class getType() { + return ProviderSpec.this.type() + } + + @Override + protected ValueSupplier.Value calculateOwnValue() { + throw new RuntimeException("broken!") + } + } + } + } diff --git a/subprojects/model-core/src/testFixtures/groovy/org/gradle/api/internal/provider/ProviderTestUtil.java b/subprojects/model-core/src/testFixtures/groovy/org/gradle/api/internal/provider/ProviderTestUtil.java new file mode 100644 index 000000000000..22dee001c5a8 --- /dev/null +++ b/subprojects/model-core/src/testFixtures/groovy/org/gradle/api/internal/provider/ProviderTestUtil.java @@ -0,0 +1,85 @@ +/* + * Copyright 2020 the original author or authors. + * + * 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.gradle.api.internal.provider; + +import org.gradle.api.Action; +import org.gradle.api.Task; +import org.gradle.api.internal.tasks.TaskDependencyResolveContext; + +import java.util.Arrays; +import java.util.Collections; +import java.util.Iterator; +import java.util.List; + +public class ProviderTestUtil { + public static ProviderInternal withNoValue() { + return Providers.notDefined(); + } + + public static ProviderInternal withValues(T... values) { + assert values.length > 0; + return new TestProvider<>((Class) values[0].getClass(), Arrays.asList(values), null); + } + + public static ProviderInternal withProducer(Class type, Object producer) { + return new TestProvider<>(type, Collections.emptyList(), producer); + } + + private static class TestProvider extends AbstractMinimalProvider { + final Class type; + final Iterator values; + final Object producer; + + TestProvider(Class type, List values, Object producer) { + this.producer = producer; + this.values = values.iterator(); + this.type = type; + } + + @Override + public Class getType() { + return type; + } + + @Override + public void visitProducerTasks(Action visitor) { + if (producer != null) { + visitor.execute((Task) producer); + } + } + + @Override + public boolean maybeVisitBuildDependencies(TaskDependencyResolveContext context) { + if (producer != null) { + context.add(producer); + return true; + } else { + return false; + } + } + + @Override + public boolean isPresent() { + return values.hasNext(); + } + + @Override + protected Value calculateOwnValue() { + return values.hasNext() ? Value.of(values.next()) : Value.missing(); + } + } +} diff --git a/subprojects/plugins/src/main/java/org/gradle/api/internal/plugins/DefaultArtifactPublicationSet.java b/subprojects/plugins/src/main/java/org/gradle/api/internal/plugins/DefaultArtifactPublicationSet.java index 155d892416b4..082d3f033b37 100644 --- a/subprojects/plugins/src/main/java/org/gradle/api/internal/plugins/DefaultArtifactPublicationSet.java +++ b/subprojects/plugins/src/main/java/org/gradle/api/internal/plugins/DefaultArtifactPublicationSet.java @@ -80,9 +80,8 @@ public Class> getType() { return null; } - @Nullable @Override - public Set getOrNull() { + protected Value> calculateOwnValue() { if (defaultArtifacts == null) { defaultArtifacts = Sets.newLinkedHashSet(); currentDefault = null; @@ -108,7 +107,7 @@ public Set getOrNull() { } } } - return defaultArtifacts; + return Value.of(defaultArtifacts); } void replaceCurrent(PublishArtifact artifact) { From ea25260bcba92cf4121bb473b2e19db90ef08cd9 Mon Sep 17 00:00:00 2001 From: Gradleware Git Bot Date: Fri, 24 Jan 2020 01:16:40 +0100 Subject: [PATCH 39/39] Publish 6.1.1-20200124000049+0000 --- released-versions.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/released-versions.json b/released-versions.json index 1abe9bf41ee7..60a2d7776336 100644 --- a/released-versions.json +++ b/released-versions.json @@ -1,7 +1,7 @@ { "latestReleaseSnapshot": { - "version": "6.1.1-20200123000143+0000", - "buildTime": "20200123000143+0000" + "version": "6.1.1-20200124000049+0000", + "buildTime": "20200124000049+0000" }, "latestRc": { "version": "6.1-rc-3",