diff --git a/packages/flutter_tools/lib/src/android/gradle_errors.dart b/packages/flutter_tools/lib/src/android/gradle_errors.dart index e6428d0cefd9..903f76346090 100644 --- a/packages/flutter_tools/lib/src/android/gradle_errors.dart +++ b/packages/flutter_tools/lib/src/android/gradle_errors.dart @@ -12,6 +12,7 @@ import '../globals.dart' as globals; import '../project.dart'; import '../reporting/reporting.dart'; import 'android_studio.dart'; +import 'gradle_utils.dart'; import 'multidex.dart'; typedef GradleErrorTest = bool Function(String); @@ -78,6 +79,7 @@ final List gradleErrors = [ incompatibleKotlinVersionHandler, minCompileSdkVersionHandler, jvm11RequiredHandler, + outdatedGradleHandler, ]; const String _boxTitle = 'Flutter Fix'; @@ -487,7 +489,7 @@ final GradleHandledError lockFileDepMissingHandler = GradleHandledError( @visibleForTesting final GradleHandledError incompatibleKotlinVersionHandler = GradleHandledError( test: _lineMatcher(const [ - 'Module was compiled with an incompatible version of Kotlin', + 'was compiled with an incompatible version of Kotlin', ]), handler: ({ required String line, @@ -509,6 +511,41 @@ final GradleHandledError incompatibleKotlinVersionHandler = GradleHandledError( eventLabel: 'incompatible-kotlin-version', ); +final RegExp _outdatedGradlePattern = RegExp(r'The current Gradle version (.+) is not compatible with the Kotlin Gradle plugin'); + +@visibleForTesting +final GradleHandledError outdatedGradleHandler = GradleHandledError( + test: _outdatedGradlePattern.hasMatch, + handler: ({ + required String line, + required FlutterProject project, + required bool usesAndroidX, + required bool multidexEnabled, + }) async { + final File gradleFile = project.directory + .childDirectory('android') + .childFile('build.gradle'); + final File gradlePropertiesFile = project.directory + .childDirectory('android') + .childDirectory('gradle') + .childDirectory('wrapper') + .childFile('gradle-wrapper.properties'); + globals.printBox( + '${globals.logger.terminal.warningMark} Your project needs to upgrade Gradle and the Android Gradle plugin.\n\n' + 'To fix this issue, replace the following content:\n' + '${gradleFile.path}:\n' + ' ${globals.terminal.color("- classpath 'com.android.tools.build:gradle:'", TerminalColor.red)}\n' + ' ${globals.terminal.color("+ classpath 'com.android.tools.build:gradle:$templateAndroidGradlePluginVersion'", TerminalColor.green)}\n' + '${gradlePropertiesFile.path}:\n' + ' ${globals.terminal.color('- https://services.gradle.org/distributions/gradle--all.zip', TerminalColor.red)}\n' + ' ${globals.terminal.color('+ https://services.gradle.org/distributions/gradle-$templateDefaultGradleVersion-all.zip', TerminalColor.green)}', + title: _boxTitle, + ); + return GradleBuildStatus.exit; + }, + eventLabel: 'outdated-gradle-version', +); + final RegExp _minCompileSdkVersionPattern = RegExp(r'The minCompileSdk \(([0-9]+)\) specified in a'); @visibleForTesting diff --git a/packages/flutter_tools/test/general.shard/android/gradle_errors_test.dart b/packages/flutter_tools/test/general.shard/android/gradle_errors_test.dart index 219c94597424..81aa5205e2ee 100644 --- a/packages/flutter_tools/test/general.shard/android/gradle_errors_test.dart +++ b/packages/flutter_tools/test/general.shard/android/gradle_errors_test.dart @@ -36,6 +36,7 @@ void main() { incompatibleKotlinVersionHandler, minCompileSdkVersionHandler, jvm11RequiredHandler, + outdatedGradleHandler, ]) ); }); @@ -877,6 +878,10 @@ Execution failed for task ':app:generateDebugFeatureTransitiveDeps'. incompatibleKotlinVersionHandler.test('Module was compiled with an incompatible version of Kotlin. The binary version of its metadata is 1.5.1, expected version is 1.1.15.'), isTrue, ); + expect( + incompatibleKotlinVersionHandler.test("class 'kotlin.Unit' was compiled with an incompatible version of Kotlin."), + isTrue, + ); }); testUsingContext('suggestion', () async { @@ -904,6 +909,51 @@ Execution failed for task ':app:generateDebugFeatureTransitiveDeps'. }); }); + group('Bump Gradle', () { + const String errorMessage = ''' +A problem occurred evaluating project ':app'. +> Failed to apply plugin [id 'kotlin-android'] + > The current Gradle version 4.10.2 is not compatible with the Kotlin Gradle plugin. Please use Gradle 6.1.1 or newer, or the previous version of the Kotlin plugin. +'''; + + testWithoutContext('pattern', () { + expect( + outdatedGradleHandler.test(errorMessage), + isTrue, + ); + }); + + testUsingContext('suggestion', () async { + await outdatedGradleHandler.handler( + line: errorMessage, + project: FlutterProject.fromDirectoryTest(globals.fs.currentDirectory), + ); + + expect( + testLogger.statusText, + contains( + '\n' + '┌─ Flutter Fix ────────────────────────────────────────────────────────────────────┐\n' + '│ [!] Your project needs to upgrade Gradle and the Android Gradle plugin. │\n' + '│ │\n' + '│ To fix this issue, replace the following content: │\n' + '│ /android/build.gradle: │\n' + "│ - classpath 'com.android.tools.build:gradle:' │\n" + "│ + classpath 'com.android.tools.build:gradle:7.1.2' │\n" + '│ /android/gradle/wrapper/gradle-wrapper.properties: │\n' + '│ - https://services.gradle.org/distributions/gradle--all.zip │\n' + '│ + https://services.gradle.org/distributions/gradle-7.4-all.zip │\n' + '└──────────────────────────────────────────────────────────────────────────────────┘\n' + ) + ); + }, overrides: { + GradleUtils: () => FakeGradleUtils(), + Platform: () => fakePlatform('android'), + FileSystem: () => MemoryFileSystem.test(), + ProcessManager: () => FakeProcessManager.empty(), + }); + }); + group('Required compileSdkVersion', () { const String errorMessage = ''' Execution failed for task ':app:checkDebugAarMetadata'.