Skip to content

Commit

Permalink
Merge pull request #180 from gradle/gh/7.0experimental
Browse files Browse the repository at this point in the history
Change CompileLibraryResourcesWorkaround to warn when experimental flags are not used
  • Loading branch information
ghale authored Jul 30, 2021
2 parents 4fa1fa8 + 39ca807 commit b8cc54d
Show file tree
Hide file tree
Showing 8 changed files with 179 additions and 36 deletions.
39 changes: 12 additions & 27 deletions src/main/groovy/org/gradle/android/AndroidCacheFixPlugin.groovy
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package org.gradle.android

import com.android.builder.model.Version
import com.google.common.collect.ImmutableList
import groovy.transform.CompileStatic
import org.gradle.android.workarounds.CompileLibraryResourcesWorkaround_4_0
Expand All @@ -17,22 +16,17 @@ import org.gradle.android.workarounds.Workaround
import org.gradle.android.workarounds.WorkaroundContext
import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.util.GradleVersion
import org.gradle.util.VersionNumber
import org.slf4j.Logger
import org.slf4j.LoggerFactory

import java.util.concurrent.atomic.AtomicBoolean

import static org.gradle.android.Versions.SUPPORTED_ANDROID_VERSIONS
import static org.gradle.android.Versions.android
import static org.gradle.android.Versions.*

@CompileStatic
class AndroidCacheFixPlugin implements Plugin<Project> {
private static final Logger LOGGER = LoggerFactory.getLogger(AndroidCacheFixPlugin)

static final String IGNORE_VERSION_CHECK_PROPERTY = "org.gradle.android.cache-fix.ignoreVersionCheck"
public static final VersionNumber CURRENT_ANDROID_VERSION = android(Version.ANDROID_GRADLE_PLUGIN_VERSION)

private final List<Workaround> workarounds = [] as List<Workaround>

private static boolean isSupportedAndroidVersion(Project project) {
Expand All @@ -42,8 +36,8 @@ class AndroidCacheFixPlugin implements Plugin<Project> {

private static boolean isMaybeSupportedAndroidVersion(Project project) {
return SystemPropertiesCompat.getBoolean(IGNORE_VERSION_CHECK_PROPERTY, project) ||
(CURRENT_ANDROID_VERSION <= Versions.latestAndroidVersion() &&
CURRENT_ANDROID_VERSION >= Versions.earliestMaybeSupportedAndroidVersion())
(CURRENT_ANDROID_VERSION <= latestAndroidVersion() &&
CURRENT_ANDROID_VERSION >= earliestMaybeSupportedAndroidVersion())
}

static List<Workaround> initializeWorkarounds(Project project) {
Expand Down Expand Up @@ -86,6 +80,14 @@ class AndroidCacheFixPlugin implements Plugin<Project> {
workaround.apply(context)
appliedWorkarounds += workaround.getClass().simpleName - "Workaround"
}

if (GradleVersion.current() >= GradleVersion.version('6.1')) {
project.gradle.sharedServices.registerIfAbsent("warnings", WarningsService.class) {}.get()
} else {
project.gradle.buildFinished {
Warnings.resetAll()
}
}
}

static List<Workaround> getWorkaroundsToApply(
Expand Down Expand Up @@ -118,21 +120,4 @@ class AndroidCacheFixPlugin implements Plugin<Project> {
}
workaroundsBuilder.build()
}

private enum Warnings {
MAYBE_SUPPORTED_ANDROID_VERSION("WARNING: Android plugin ${CURRENT_ANDROID_VERSION} has not been tested with this version of the Android cache fix plugin, although it may work. We test against only the latest patch release versions of Android Gradle plugin: ${SUPPORTED_ANDROID_VERSIONS.join(", ")}. If ${CURRENT_ANDROID_VERSION} is newly released, we may not have had a chance to release a version tested against it yet. Proceed with caution. You can suppress this warning with with -D${IGNORE_VERSION_CHECK_PROPERTY}=true.")

private final String warning
private final AtomicBoolean warned = new AtomicBoolean()

Warnings(String warning) {
this.warning = warning
}

void warnOnce(org.gradle.api.logging.Logger logger) {
if (!warned.getAndSet(true)) {
logger.warn(warning)
}
}
}
}
5 changes: 5 additions & 0 deletions src/main/groovy/org/gradle/android/Versions.groovy
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package org.gradle.android

import com.android.builder.model.Version
import com.google.common.collect.ImmutableMultimap
import com.google.common.collect.ImmutableSortedSet
import com.google.common.collect.Multimap
Expand All @@ -15,6 +16,8 @@ class Versions {
static final Set<GradleVersion> SUPPORTED_GRADLE_VERSIONS
static final Set<VersionNumber> SUPPORTED_ANDROID_VERSIONS
static final Multimap<VersionNumber, GradleVersion> SUPPORTED_VERSIONS_MATRIX
static final VersionNumber CURRENT_ANDROID_VERSION
static final String IGNORE_VERSION_CHECK_PROPERTY = "org.gradle.android.cache-fix.ignoreVersionCheck"

static {
def versions = new JsonSlurper().parse(AndroidCacheFixPlugin.classLoader.getResource("versions.json"))
Expand All @@ -29,6 +32,8 @@ class Versions {
SUPPORTED_VERSIONS_MATRIX = matrix
SUPPORTED_ANDROID_VERSIONS = ImmutableSortedSet.copyOf(matrix.keySet())
SUPPORTED_GRADLE_VERSIONS = ImmutableSortedSet.copyOf(matrix.values())

CURRENT_ANDROID_VERSION = android(Version.ANDROID_GRADLE_PLUGIN_VERSION)
}

static VersionNumber android(String version) {
Expand Down
31 changes: 31 additions & 0 deletions src/main/groovy/org/gradle/android/Warnings.groovy
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package org.gradle.android

import org.gradle.android.workarounds.CompileLibraryResourcesWorkaround_7_0

import java.util.concurrent.atomic.AtomicBoolean

enum Warnings {
MAYBE_SUPPORTED_ANDROID_VERSION("WARNING: Android plugin ${Versions.CURRENT_ANDROID_VERSION} has not been tested with this version of the Android cache fix plugin, although it may work. We test against only the latest patch release versions of Android Gradle plugin: ${Versions.SUPPORTED_ANDROID_VERSIONS.join(", ")}. If ${Versions.CURRENT_ANDROID_VERSION} is newly released, we may not have had a chance to release a version tested against it yet. Proceed with caution. You can suppress this warning with with -D${Versions.IGNORE_VERSION_CHECK_PROPERTY}=true."),
USE_COMPILE_LIBRARY_RESOURCES_EXPERIMENTAL("WARNING: Android plugin ${Versions.CURRENT_ANDROID_VERSION} has experimental support for using relative path sensitivity with CompileLibraryResourcesTask inputs which will provide more build cache hits and improve build speed. Set '${CompileLibraryResourcesWorkaround_7_0.CACHE_COMPILE_LIB_RESOURCES}=true' and '${CompileLibraryResourcesWorkaround_7_0.ENABLE_SOURCE_SET_PATHS_MAP}=true' in gradle.properties to enable this support.")

final String warning
private final AtomicBoolean warned = new AtomicBoolean()

Warnings(String warning) {
this.warning = warning
}

void warnOnce(org.gradle.api.logging.Logger logger) {
if (!warned.getAndSet(true)) {
logger.warn(warning)
}
}

void reset() {
warned.set(false)
}

static void resetAll() {
values().each {it.reset() }
}
}
11 changes: 11 additions & 0 deletions src/main/groovy/org/gradle/android/WarningsService.groovy
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package org.gradle.android

import org.gradle.api.services.BuildService
import org.gradle.api.services.BuildServiceParameters

abstract class WarningsService implements BuildService<BuildServiceParameters.None>, AutoCloseable {
@Override
void close() throws Exception {
Warnings.resetAll()
}
}
Original file line number Diff line number Diff line change
@@ -1,17 +1,30 @@
package org.gradle.android.workarounds

import org.gradle.android.AndroidIssue
import org.gradle.android.Warnings
import org.gradle.api.Project

/**
* Fixes the cacheability issue with CompileLibraryResourcesWorkaround where the inputDirectories field is
* treated as an input with absolute path sensitivity.
* This is the same as the {@link CompileLibraryResourcesWorkaround_4_0} but the field was renamed with a new type
* in 4.2.0-alpha09.
* Warns if the user is not using experimental support for relative path sensitivity that was added
* with 7.0.0-alpha09.
*/
@AndroidIssue(introducedIn = "7.0.0-alpha09", fixedIn = [], link = "https://issuetracker.google.com/issues/155218379")
class CompileLibraryResourcesWorkaround_7_0 extends AbstractCompileLibraryResourcesWorkaround_4_2_orHigher {
class CompileLibraryResourcesWorkaround_7_0 implements Workaround {
public static final String ENABLE_SOURCE_SET_PATHS_MAP = "android.experimental.enableSourceSetPathsMap"
public static final String CACHE_COMPILE_LIB_RESOURCES = "android.experimental.cacheCompileLibResources"

@Override
void apply(WorkaroundContext context) {
boolean enableSourceSetPathsMap = Boolean.valueOf(context.project.findProperty(ENABLE_SOURCE_SET_PATHS_MAP) as String)
boolean cacheCompileLibResources = Boolean.valueOf(context.project.findProperty(CACHE_COMPILE_LIB_RESOURCES) as String)

if (!(enableSourceSetPathsMap && cacheCompileLibResources)) {
Warnings.USE_COMPILE_LIBRARY_RESOURCES_EXPERIMENTAL.warnOnce(context.project.logger)
}
}

@Override
String getPropertyName() {
return "inputDirectoriesAsAbsolute"
boolean canBeApplied(Project project) {
return true
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
package org.gradle.android

import org.gradle.android.workarounds.CompileLibraryResourcesWorkaround_7_0
import org.junit.Assume

@MultiVersionTest
class CompileLibraryResourcesWorkaround_7_0Test extends AbstractTest {
def "warns when experimental flags are not provided"() {
Assume.assumeTrue(TestVersions.latestAndroidVersionForCurrentJDK() >= Versions.android("7.0.0-alpha09"))

SimpleAndroidApp.builder(temporaryFolder.root, cacheDir)
.withAndroidVersion(TestVersions.latestAndroidVersionForCurrentJDK())
.withKotlinDisabled()
.build()
.writeProject()

when:
def result = withGradleVersion(TestVersions.latestGradleVersion().version)
.withProjectDir(temporaryFolder.root)
.withArguments(
"-P${CompileLibraryResourcesWorkaround_7_0.ENABLE_SOURCE_SET_PATHS_MAP}=false",
"-P${CompileLibraryResourcesWorkaround_7_0.CACHE_COMPILE_LIB_RESOURCES}=false",
'assembleDebug'
)
.build()

then:
result.output.count(warningForAndroidVersion(TestVersions.latestAndroidVersionForCurrentJDK().toString())) == 1

when:
result = withGradleVersion(TestVersions.latestGradleVersion().version)
.withProjectDir(temporaryFolder.root)
.withArguments(
"-P${CompileLibraryResourcesWorkaround_7_0.ENABLE_SOURCE_SET_PATHS_MAP}=false",
"-P${CompileLibraryResourcesWorkaround_7_0.CACHE_COMPILE_LIB_RESOURCES}=false",
'assembleDebug'
)
.build()

then:
result.output.count(warningForAndroidVersion(TestVersions.latestAndroidVersionForCurrentJDK().toString())) == 1
}

def "does not warn when experimental flags are provided"() {
Assume.assumeTrue(TestVersions.latestAndroidVersionForCurrentJDK() >= Versions.android("7.0.0-alpha09"))

SimpleAndroidApp.builder(temporaryFolder.root, cacheDir)
.withAndroidVersion(TestVersions.latestAndroidVersionForCurrentJDK())
.withKotlinDisabled()
.build()
.writeProject()

when:
def result = withGradleVersion(TestVersions.latestGradleVersion().version)
.withProjectDir(temporaryFolder.root)
.withArguments(
"-P${CompileLibraryResourcesWorkaround_7_0.ENABLE_SOURCE_SET_PATHS_MAP}=true",
"-P${CompileLibraryResourcesWorkaround_7_0.CACHE_COMPILE_LIB_RESOURCES}=true",
'assembleDebug'
)
.build()

then:
result.output.count(warningForAndroidVersion(TestVersions.latestAndroidVersionForCurrentJDK().toString())) == 0
}

def "does not warn for versions that do not support experimental flag"() {
Assume.assumeTrue(TestVersions.latestAndroidVersionForCurrentJDK() < Versions.android("7.0.0-alpha09"))

SimpleAndroidApp.builder(temporaryFolder.root, cacheDir)
.withAndroidVersion(TestVersions.latestAndroidVersionForCurrentJDK())
.withKotlinDisabled()
.build()
.writeProject()

when:
def result = withGradleVersion(TestVersions.latestGradleVersion().version)
.withProjectDir(temporaryFolder.root)
.withArguments(
"-P${CompileLibraryResourcesWorkaround_7_0.ENABLE_SOURCE_SET_PATHS_MAP}=false",
"-P${CompileLibraryResourcesWorkaround_7_0.CACHE_COMPILE_LIB_RESOURCES}=false",
'assembleDebug'
)
.build()

then:
result.output.count(warningForAndroidVersion(TestVersions.latestAndroidVersionForCurrentJDK().toString())) == 0
}

private static String warningForAndroidVersion(String androidVersion) {
return Warnings.USE_COMPILE_LIBRARY_RESOURCES_EXPERIMENTAL.warning.replaceAll('Android plugin [^\\s]+', "Android plugin ${androidVersion}")
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -541,15 +541,18 @@ class CrossVersionOutcomeAndRelocationTest extends AbstractTest {
builder.expect(':app:desugarDebugFileDependencies', FROM_CACHE)
builder.expect(':app:desugarReleaseFileDependencies', FROM_CACHE)
builder.expect(':app:extractReleaseNativeSymbolTables', NO_SOURCE)
builder.expect(':app:mapDebugSourceSetPaths', SUCCESS)
builder.expect(':app:mapReleaseSourceSetPaths', SUCCESS)
builder.expect(':app:mergeDebugNativeLibs', NO_SOURCE)
builder.expect(':app:mergeReleaseNativeLibs', NO_SOURCE)
builder.expect(':app:mergeDebugResources', SUCCESS)
builder.expect(':app:mergeReleaseResources', SUCCESS)
builder.expect(':app:processDebugResources', SUCCESS)
builder.expect(':app:processReleaseResources', SUCCESS)
builder.expect(':app:processDebugResources', FROM_CACHE)
builder.expect(':app:processReleaseResources', FROM_CACHE)
// New tasks in 7.0.0-beta04
builder.expect(':library:javaPreCompileDebug', FROM_CACHE)
builder.expect(':library:javaPreCompileRelease', FROM_CACHE)
builder.expect(':library:mapReleaseSourceSetPaths', SUCCESS)
builder.expect(':app:javaPreCompileDebug', FROM_CACHE)
builder.expect(':app:javaPreCompileRelease', FROM_CACHE)
// New non-cacheable tasks in 7.0.0-beta05
Expand Down
2 changes: 2 additions & 0 deletions src/test/groovy/org/gradle/android/SimpleAndroidApp.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,8 @@ class SimpleAndroidApp {
android.useAndroidX=true
org.gradle.jvmargs=-Xmx2048m
kapt.use.worker.api=${kaptWorkersEnabled}
android.experimental.enableSourceSetPathsMap=true
android.experimental.cacheCompileLibResources=true
""".stripIndent()

configureAndroidSdkHome()
Expand Down

0 comments on commit b8cc54d

Please sign in to comment.