Reland "Identify and re-throw our dependency checking errors in flutter.groovy" (#150128)
The original approach in https://github.com/flutter/flutter/pull/149609 didn't work when the Flutter Gradle plugin was applied using the deprecated script apply - the kotlin portion couldn't resolve the custom exception defined in `flutter.groovy`:
```
e: /Users/mackall/development/flutter/flutter/packages/flutter_tools/gradle/src/main/kotlin/dependency_version_checker.gradle.kts:238:23: Unresolved reference: DependencyValidationException
e: /Users/mackall/development/flutter/flutter/packages/flutter_tools/gradle/src/main/kotlin/dependency_version_checker.gradle.kts:263:23: Unresolved reference: DependencyValidationException
e: /Users/mackall/development/flutter/flutter/packages/flutter_tools/gradle/src/main/kotlin/dependency_version_checker.gradle.kts:288:23: Unresolved reference: DependencyValidationException
e: /Users/mackall/development/flutter/flutter/packages/flutter_tools/gradle/src/main/kotlin/dependency_version_checker.gradle.kts:313:23: Unresolved reference: DependencyValidationException
Warning: Flutter was unable to detect project Gradle, Java, AGP, and KGP versions. Skipping dependency version checking. Error was: org.gradle.internal.exceptions.LocationAwareException: Script '/Users/mackall/development/flutter/flutter/packages/flutter_tools/gradle/src/main/kotlin/dependency_version_checker.gradle.kts' line: 238
Script compilation errors:
Line 238: throw DependencyValidationException(errorMessage)
^ Unresolved reference: DependencyValidationException
Line 263: throw DependencyValidationException(errorMessage)
^ Unresolved reference: DependencyValidationException
Line 288: throw DependencyValidationException(errorMessage)
^ Unresolved reference: DependencyValidationException
Line 313: throw DependencyValidationException(errorMessage)
^ Unresolved reference: DependencyValidationException
```
This new approach of setting one of the [`extra` properties](https://docs.gradle.org/current/dsl/org.gradle.api.Project.html#N14FF7) works in both cases (tested with the `camera_android` example app, which uses the script apply, and a freshly created counter app).
It also removes some brittleness in that we don't have to unwrap the exception anymore, and aren't subject to breaking if Gradle decides one day to wrap our custom exception 1 layer deeper in additional exceptions.
diff --git a/packages/flutter_tools/gradle/src/main/groovy/flutter.groovy b/packages/flutter_tools/gradle/src/main/groovy/flutter.groovy
index 8c759c6..a89958c 100644
--- a/packages/flutter_tools/gradle/src/main/groovy/flutter.groovy
+++ b/packages/flutter_tools/gradle/src/main/groovy/flutter.groovy
@@ -98,7 +98,6 @@
return flutterVersionName
}
-
}
// This buildscript block supplies dependencies for this file's own import
@@ -340,10 +339,18 @@
"packages", "flutter_tools", "gradle", "src", "main", "kotlin",
"dependency_version_checker.gradle.kts")
project.apply from: dependencyCheckerPluginPath
- } catch (Exception ignored) {
- project.logger.error("Warning: Flutter was unable to detect project Gradle, Java, " +
- "AGP, and KGP versions. Skipping dependency version checking. Error was: "
- + ignored)
+ } catch (Exception e) {
+ if (!project.usesUnsupportedDependencyVersions) {
+ // Possible bug in dependency checking code - warn and do not block build.
+ project.logger.error("Warning: Flutter was unable to detect project Gradle, Java, " +
+ "AGP, and KGP versions. Skipping dependency version checking. Error was: "
+ + e)
+ }
+ else {
+ // If usesUnsupportedDependencyVersions is set, the exception was thrown by us
+ // in the dependency version checker plugin so re-throw it here.
+ throw e
+ }
}
}
diff --git a/packages/flutter_tools/gradle/src/main/kotlin/dependency_version_checker.gradle.kts b/packages/flutter_tools/gradle/src/main/kotlin/dependency_version_checker.gradle.kts
index 08650a6..720c634 100644
--- a/packages/flutter_tools/gradle/src/main/kotlin/dependency_version_checker.gradle.kts
+++ b/packages/flutter_tools/gradle/src/main/kotlin/dependency_version_checker.gradle.kts
@@ -40,6 +40,11 @@
private const val AGP_NAME: String = "Android Gradle Plugin"
private const val KGP_NAME: String = "Kotlin"
+ // String constant that defines the name of the Gradle extra property that we set when
+ // detecting that the project is using versions outside of Flutter's support range.
+ // https://docs.gradle.org/current/kotlin-dsl/gradle/org.gradle.api/-project/index.html#-2107180640%2FProperties%2F-1867656071.
+ private const val OUT_OF_SUPPORT_RANGE_PROPERTY = "usesUnsupportedDependencyVersions"
+
// The following messages represent best effort guesses at where a Flutter developer should
// look to upgrade a dependency that is below the corresponding threshold. Developers can
// change some of these locations, so they are not guaranteed to be accurate.
@@ -104,6 +109,7 @@
* we treat it as within the range for the purpose of this check.
*/
fun checkDependencyVersions(project: Project) {
+ project.extra.set(OUT_OF_SUPPORT_RANGE_PROPERTY, false)
var agpVersion: Version?
var kgpVersion: Version?
@@ -235,7 +241,8 @@
errorGradleVersion.toString(),
getPotentialGradleFix(project.getRootDir().getPath())
)
- throw GradleException(errorMessage)
+ project.extra.set(OUT_OF_SUPPORT_RANGE_PROPERTY, true)
+ throw DependencyValidationException(errorMessage)
} else if (version < warnGradleVersion) {
val warnMessage: String =
getWarnMessage(
@@ -260,7 +267,8 @@
errorJavaVersion.toString(),
POTENTIAL_JAVA_FIX
)
- throw GradleException(errorMessage)
+ project.extra.set(OUT_OF_SUPPORT_RANGE_PROPERTY, true)
+ throw DependencyValidationException(errorMessage)
} else if (version < warnJavaVersion) {
val warnMessage: String =
getWarnMessage(
@@ -285,7 +293,8 @@
errorAGPVersion.toString(),
getPotentialAGPFix(project.getRootDir().getPath())
)
- throw GradleException(errorMessage)
+ project.extra.set(OUT_OF_SUPPORT_RANGE_PROPERTY, true)
+ throw DependencyValidationException(errorMessage)
} else if (version < warnAGPVersion) {
val warnMessage: String =
getWarnMessage(
@@ -310,7 +319,8 @@
errorKGPVersion.toString(),
getPotentialKGPFix(project.getRootDir().getPath())
)
- throw GradleException(errorMessage)
+ project.extra.set(OUT_OF_SUPPORT_RANGE_PROPERTY, true)
+ throw DependencyValidationException(errorMessage)
} else if (version < warnKGPVersion) {
val warnMessage: String =
getWarnMessage(
@@ -359,3 +369,9 @@
return major.toString() + "." + minor.toString() + "." + patch.toString()
}
}
+
+// Custom error for when the dependency_version_checker.kts script finds a dependency out of
+// the defined support range.
+class DependencyValidationException(message: String? = null, cause: Throwable? = null) : Exception(message, cause) {
+ constructor(cause: Throwable) : this(null, cause)
+}