Unverified Commit c12488a7 authored by gmackall's avatar gmackall Committed by GitHub

[Reland] Add migrator to upgrade gradle version when conflict with Android...

[Reland] Add migrator to upgrade gradle version when conflict with Android Studio bundled Java version is detected (#125836)

This is an attempt to reland https://github.com/flutter/flutter/pull/124085.

Differences from this attempt and the last: 
1. Adds a check for null android studio versions and a test for this case.
2. Wraps the migrate code in a try-catch [per the suggestion here](https://github.com/flutter/flutter/pull/125728/files#r1181747899).

Old PR description:
This PR adds an android project migrator that checks the version of android studio and the version of gradle for conflicts, and upgrades to 7.4 if a conflict is detected. For more detail about the particular conflict, see https://github.com/flutter/flutter/issues/122376.

The PR also upgrades older gradle versions being used in integration testing to 7.4.

Fixes/related to: https://github.com/flutter/flutter/issues/122376 and https://github.com/flutter/flutter/issues/123636
parent 4bd9bcd7
...@@ -2,4 +2,4 @@ distributionBase=GRADLE_USER_HOME ...@@ -2,4 +2,4 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.7-all.zip distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.1-all.zip
...@@ -2,4 +2,4 @@ distributionBase=GRADLE_USER_HOME ...@@ -2,4 +2,4 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.7-all.zip distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.1-all.zip
...@@ -2,4 +2,4 @@ distributionBase=GRADLE_USER_HOME ...@@ -2,4 +2,4 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.7-all.zip distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.1-all.zip
...@@ -2,4 +2,4 @@ distributionBase=GRADLE_USER_HOME ...@@ -2,4 +2,4 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.7-all.zip distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.1-all.zip
...@@ -2,4 +2,4 @@ distributionBase=GRADLE_USER_HOME ...@@ -2,4 +2,4 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.7-all.zip distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.1-all.zip
...@@ -2,4 +2,4 @@ distributionBase=GRADLE_USER_HOME ...@@ -2,4 +2,4 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.7-all.zip distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.1-all.zip
...@@ -2,4 +2,4 @@ distributionBase=GRADLE_USER_HOME ...@@ -2,4 +2,4 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.7-all.zip distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.1-all.zip
...@@ -2,4 +2,4 @@ distributionBase=GRADLE_USER_HOME ...@@ -2,4 +2,4 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.7-all.zip distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.1-all.zip
...@@ -2,4 +2,4 @@ distributionBase=GRADLE_USER_HOME ...@@ -2,4 +2,4 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.7-all.zip distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.1-all.zip
...@@ -2,4 +2,4 @@ distributionBase=GRADLE_USER_HOME ...@@ -2,4 +2,4 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.7-all.zip distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.1-all.zip
...@@ -2,4 +2,4 @@ distributionBase=GRADLE_USER_HOME ...@@ -2,4 +2,4 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.7-all.zip distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.1-all.zip
...@@ -2,4 +2,4 @@ distributionBase=GRADLE_USER_HOME ...@@ -2,4 +2,4 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.7-all.zip distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.1-all.zip
...@@ -2,4 +2,4 @@ distributionBase=GRADLE_USER_HOME ...@@ -2,4 +2,4 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.7-all.zip distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.1-all.zip
...@@ -2,4 +2,4 @@ distributionBase=GRADLE_USER_HOME ...@@ -2,4 +2,4 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.7-all.zip distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.1-all.zip
...@@ -31,8 +31,10 @@ import '../project.dart'; ...@@ -31,8 +31,10 @@ import '../project.dart';
import '../reporting/reporting.dart'; import '../reporting/reporting.dart';
import 'android_builder.dart'; import 'android_builder.dart';
import 'android_sdk.dart'; import 'android_sdk.dart';
import 'android_studio.dart';
import 'gradle_errors.dart'; import 'gradle_errors.dart';
import 'gradle_utils.dart'; import 'gradle_utils.dart';
import 'migrations/android_studio_java_gradle_conflict_migration.dart';
import 'migrations/top_level_gradle_build_file_migration.dart'; import 'migrations/top_level_gradle_build_file_migration.dart';
import 'multidex.dart'; import 'multidex.dart';
...@@ -137,13 +139,16 @@ class AndroidGradleBuilder implements AndroidBuilder { ...@@ -137,13 +139,16 @@ class AndroidGradleBuilder implements AndroidBuilder {
required Usage usage, required Usage usage,
required GradleUtils gradleUtils, required GradleUtils gradleUtils,
required Platform platform, required Platform platform,
required AndroidStudio? androidStudio,
}) : _logger = logger, }) : _logger = logger,
_fileSystem = fileSystem, _fileSystem = fileSystem,
_artifacts = artifacts, _artifacts = artifacts,
_usage = usage, _usage = usage,
_gradleUtils = gradleUtils, _gradleUtils = gradleUtils,
_androidStudio = androidStudio,
_fileSystemUtils = FileSystemUtils(fileSystem: fileSystem, platform: platform), _fileSystemUtils = FileSystemUtils(fileSystem: fileSystem, platform: platform),
_processUtils = ProcessUtils(logger: logger, processManager: processManager); _processUtils = ProcessUtils(logger: logger, processManager: processManager),
_platform = platform;
final Logger _logger; final Logger _logger;
final ProcessUtils _processUtils; final ProcessUtils _processUtils;
...@@ -152,6 +157,8 @@ class AndroidGradleBuilder implements AndroidBuilder { ...@@ -152,6 +157,8 @@ class AndroidGradleBuilder implements AndroidBuilder {
final Usage _usage; final Usage _usage;
final GradleUtils _gradleUtils; final GradleUtils _gradleUtils;
final FileSystemUtils _fileSystemUtils; final FileSystemUtils _fileSystemUtils;
final AndroidStudio? _androidStudio;
final Platform _platform;
/// Builds the AAR and POM files for the current Flutter module or plugin. /// Builds the AAR and POM files for the current Flutter module or plugin.
@override @override
...@@ -258,6 +265,15 @@ class AndroidGradleBuilder implements AndroidBuilder { ...@@ -258,6 +265,15 @@ class AndroidGradleBuilder implements AndroidBuilder {
final List<ProjectMigrator> migrators = <ProjectMigrator>[ final List<ProjectMigrator> migrators = <ProjectMigrator>[
TopLevelGradleBuildFileMigration(project.android, _logger), TopLevelGradleBuildFileMigration(project.android, _logger),
AndroidStudioJavaGradleConflictMigration(_logger,
project: project.android,
androidStudio: _androidStudio,
fileSystem: _fileSystem,
processUtils: _processUtils,
platform: _platform,
os: globals.os,
androidSdk: globals.androidSdk)
,
]; ];
final ProjectMigration migration = ProjectMigration(migrators); final ProjectMigration migration = ProjectMigration(migrators);
......
...@@ -59,6 +59,22 @@ const String maxKnownAgpVersion = '8.1'; ...@@ -59,6 +59,22 @@ const String maxKnownAgpVersion = '8.1';
final RegExp _androidGradlePluginRegExp = final RegExp _androidGradlePluginRegExp =
RegExp(r'com\.android\.tools\.build:gradle:(\d+\.\d+\.\d+)'); RegExp(r'com\.android\.tools\.build:gradle:(\d+\.\d+\.\d+)');
// Expected content format (with lines above and below).
// Version can have 2 or 3 numbers.
// 'distributionUrl=https\://services.gradle.org/distributions/gradle-7.4.2-all.zip'
// '^\s*' protects against commented out lines.
final RegExp distributionUrlRegex =
RegExp(r'^\s*distributionUrl\s*=\s*.*\.zip', multiLine: true);
// Modified version of the gradle distribution url match designed to only match
// gradle.org urls so that we can guarantee any modifications to the url
// still points to a hosted zip.
final RegExp gradleOrgVersionMatch =
RegExp(
r'^\s*distributionUrl\s*=\s*https\\://services\.gradle\.org/distributions/gradle-((?:\d|\.)+)-(.*)\.zip',
multiLine: true
);
// From https://docs.gradle.org/current/userguide/command_line_interface.html#command_line_interface // From https://docs.gradle.org/current/userguide/command_line_interface.html#command_line_interface
const String gradleVersionFlag = r'--version'; const String gradleVersionFlag = r'--version';
...@@ -169,42 +185,49 @@ String getGradleVersionForAndroidPlugin(Directory directory, Logger logger) { ...@@ -169,42 +185,49 @@ String getGradleVersionForAndroidPlugin(Directory directory, Logger logger) {
return getGradleVersionFor(androidPluginVersion ?? 'unknown'); return getGradleVersionFor(androidPluginVersion ?? 'unknown');
} }
/// Returns the gradle file from the top level directory.
/// The returned file is not guaranteed to be present.
File getGradleWrapperFile(Directory directory) {
return directory.childDirectory(gradleDirectoryName)
.childDirectory(gradleWrapperDirectoryName)
.childFile(gradleWrapperPropertiesFilename);
}
/// Parses the gradle wrapper distribution url to return a string containing
/// the version number.
///
/// Expected input is of the form '...gradle-7.4.2-all.zip', and the output
/// would be of the form '7.4.2'.
String? parseGradleVersionFromDistributionUrl(String? distributionUrl) {
if (distributionUrl == null) {
return null;
}
final List<String> zipParts = distributionUrl.split('-');
if (zipParts.length < 2) {
return null;
}
return zipParts[1];
}
/// Returns either the gradle-wrapper.properties value from the passed in /// Returns either the gradle-wrapper.properties value from the passed in
/// [directory] or if not present the version available in local path. /// [directory] or if not present the version available in local path.
/// ///
/// If gradle version is not found null is returned. /// If gradle version is not found null is returned.
/// [directory] should be and android directory with a build.gradle file. /// [directory] should be an android directory with a build.gradle file.
Future<String?> getGradleVersion( Future<String?> getGradleVersion(
Directory directory, Logger logger, ProcessManager processManager) async { Directory directory, Logger logger, ProcessManager processManager) async {
final File propertiesFile = directory final File propertiesFile = getGradleWrapperFile(directory);
.childDirectory(gradleDirectoryName)
.childDirectory(gradleWrapperDirectoryName)
.childFile(gradleWrapperPropertiesFilename);
if (propertiesFile.existsSync()) { if (propertiesFile.existsSync()) {
final String wrapperFileContent = propertiesFile.readAsStringSync(); final String wrapperFileContent = propertiesFile.readAsStringSync();
// Expected content format (with lines above and below).
// Version can have 2 or 3 numbers.
// 'distributionUrl=https\://services.gradle.org/distributions/gradle-7.4.2-all.zip'
// '^\s*' protects against commented out lines.
final RegExp distributionUrlRegex =
RegExp(r'^\s*distributionUrl\s?=\s?.*\.zip', multiLine: true);
final RegExpMatch? distributionUrl = final RegExpMatch? distributionUrl =
distributionUrlRegex.firstMatch(wrapperFileContent); distributionUrlRegex.firstMatch(wrapperFileContent);
if (distributionUrl != null) { if (distributionUrl != null) {
// Expected content: 'gradle-7.4.2-all.zip' final String? gradleVersion =
final String? gradleZip = distributionUrl.group(0); parseGradleVersionFromDistributionUrl(distributionUrl.group(0));
if (gradleZip != null) { if (gradleVersion != null) {
final List<String> zipParts = gradleZip.split('-'); return gradleVersion;
if (zipParts.length > 2) {
final String gradleVersion = zipParts[1];
return gradleVersion;
} else {
// Did not find gradle zip url. Likely this is a bug in our parsing.
logger.printWarning(_formatParseWarning(wrapperFileContent));
}
} else { } else {
// Did not find gradle zip url. Likely this is a bug in our parsing. // Did not find gradle zip url. Likely this is a bug in our parsing.
logger.printWarning(_formatParseWarning(wrapperFileContent)); logger.printWarning(_formatParseWarning(wrapperFileContent));
...@@ -248,7 +271,7 @@ OS: Mac OS X 13.2.1 aarch64 ...@@ -248,7 +271,7 @@ OS: Mac OS X 13.2.1 aarch64
final RegExpMatch? version = final RegExpMatch? version =
gradleVersionRegex.firstMatch(gradleVersionVerbose); gradleVersionRegex.firstMatch(gradleVersionVerbose);
if (version == null) { if (version == null) {
// Most likley a bug in our parse implementation/regex. // Most likely a bug in our parse implementation/regex.
logger.printWarning(_formatParseWarning(gradleVersionVerbose)); logger.printWarning(_formatParseWarning(gradleVersionVerbose));
return null; return null;
} }
...@@ -300,7 +323,7 @@ String _formatParseWarning(String content) { ...@@ -300,7 +323,7 @@ String _formatParseWarning(String content) {
// //
// Source of truth found here: // Source of truth found here:
// https://developer.android.com/studio/releases/gradle-plugin#updating-gradle // https://developer.android.com/studio/releases/gradle-plugin#updating-gradle
// AGP has a minimim version of gradle required but no max starting at // AGP has a minimum version of gradle required but no max starting at
// AGP version 2.3.0+. // AGP version 2.3.0+.
bool validateGradleAndAgp(Logger logger, bool validateGradleAndAgp(Logger logger,
{required String? gradleV, required String? agpV}) { {required String? gradleV, required String? agpV}) {
......
// Copyright 2014 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'package:meta/meta.dart';
import '../../base/file_system.dart';
import '../../base/os.dart';
import '../../base/platform.dart';
import '../../base/process.dart';
import '../../base/project_migrator.dart';
import '../../base/version.dart';
import '../../project.dart';
import '../android_sdk.dart';
import '../android_studio.dart';
import '../gradle_utils.dart';
// Android Studio 2022.2 "Flamingo" is the first to bundle a Java 17 JDK.
// Previous versions bundled a Java 11 JDK.
@visibleForTesting
final Version androidStudioFlamingo = Version(2022, 2, 0);
@visibleForTesting
const String gradleVersion7_6_1 = r'7.6.1';
// String that can be placed in the gradle-wrapper.properties to opt out of this
// migrator.
@visibleForTesting
const String optOutFlag = 'NoFlutterGradleWrapperUpgrade';
// Only the major version matters.
final Version flamingoBundledJava = Version(17, 0, 0);
// These gradle versions were chosen because they
// 1. Were output by 'flutter create' at some point in flutter's history and
// 2. Are less than 7.3, the lowest supported gradle version for JDK 17
const List<String> gradleVersionsToUpgradeFrom =
<String>['5.6.2', '6.7'];
// Define log messages as constants to re-use in testing.
@visibleForTesting
const String gradleWrapperNotFound =
'gradle-wrapper.properties not found, skipping Gradle-Java version compatibility check.';
@visibleForTesting
const String androidStudioNotFound =
'Android Studio version could not be detected, '
'skipping Gradle-Java version compatibility check.';
@visibleForTesting
const String androidStudioVersionBelowFlamingo =
'Version of Android Studio is less than Flamingo (the first impacted version),'
' no migration attempted.';
@visibleForTesting
const String javaVersionNot17 =
'Version of Java is different than impacted version, no migration attempted.';
@visibleForTesting
const String javaVersionNotFound =
'Version of Java not found, no migration attempted.';
@visibleForTesting
const String conflictDetected = 'Conflict detected between versions of Android Studio '
'and Gradle, upgrading Gradle version from current to 7.4';
@visibleForTesting
const String gradleVersionNotFound = 'Failed to parse Gradle version from distribution url, '
'skipping Gradle-Java version compatibility check.';
@visibleForTesting
const String optOutFlagEnabled = 'Skipping Android Studio Java-Gradle compatibility '
"because opt out flag: '$optOutFlag' is enabled in gradle-wrapper.properties file.";
@visibleForTesting
const String errorWhileMigrating = 'Encountered an error while attempting Gradle-Java '
'version compatibility check, skipping migration attempt. Error was: ';
/// Migrate to a newer version of Gradle when the existing one does not support
/// the version of Java provided by the detected Android Studio version.
///
/// For more info see the Gradle-Java compatibility matrix:
/// https://docs.gradle.org/current/userguide/compatibility.html
class AndroidStudioJavaGradleConflictMigration extends ProjectMigrator {
AndroidStudioJavaGradleConflictMigration(
super.logger,
{required AndroidProject project,
AndroidStudio? androidStudio,
required FileSystem fileSystem,
required ProcessUtils processUtils,
required Platform platform,
required OperatingSystemUtils os,
AndroidSdk? androidSdk,
}) : _gradleWrapperPropertiesFile = getGradleWrapperFile(project.hostAppGradleRoot),
_androidStudio = androidStudio,
_fileSystem = fileSystem,
_processUtils = processUtils,
_platform = platform,
_os = os,
_androidSdk = androidSdk;
final File _gradleWrapperPropertiesFile;
final AndroidStudio? _androidStudio;
final FileSystem _fileSystem;
final ProcessUtils _processUtils;
final Platform _platform;
final OperatingSystemUtils _os;
final AndroidSdk? _androidSdk;
@override
void migrate() {
try {
if (!_gradleWrapperPropertiesFile.existsSync()) {
logger.printTrace(gradleWrapperNotFound);
return;
}
if (_androidStudio == null || _androidStudio!.version == null) {
logger.printTrace(androidStudioNotFound);
return;
} else if (_androidStudio!.version!.major < androidStudioFlamingo.major) {
logger.printTrace(androidStudioVersionBelowFlamingo);
return;
}
final String? javaVersionString = _androidSdk?.getJavaVersion(
androidStudio: _androidStudio,
fileSystem: _fileSystem,
operatingSystemUtils: _os,
platform: _platform,
processUtils: _processUtils,
);
final Version? javaVersion = Version.parse(javaVersionString);
if (javaVersion == null) {
logger.printTrace(javaVersionNotFound);
return;
}
if (javaVersion.major != flamingoBundledJava.major) {
logger.printTrace(javaVersionNot17);
return;
}
processFileLines(_gradleWrapperPropertiesFile);
} on Exception catch (e) {
logger.printTrace(errorWhileMigrating + e.toString());
} on Error catch (e) {
logger.printTrace(errorWhileMigrating + e.toString());
}
}
@override
String migrateFileContents(String fileContents) {
if (fileContents.contains(optOutFlag)) {
logger.printTrace(optOutFlagEnabled);
return fileContents;
}
final RegExpMatch? gradleDistributionUrl = gradleOrgVersionMatch.firstMatch(fileContents);
if (gradleDistributionUrl == null
|| gradleDistributionUrl.groupCount < 1
|| gradleDistributionUrl[1] == null) {
logger.printTrace(gradleVersionNotFound);
return fileContents;
}
final String existingVersionString = gradleDistributionUrl[1]!;
if (gradleVersionsToUpgradeFrom.contains(existingVersionString)) {
logger.printStatus('Conflict detected between Android Studio Java version and Gradle version, '
'upgrading Gradle version from $existingVersionString to $gradleVersion7_6_1.');
final String? gradleDistributionUrlString = gradleDistributionUrl.group(0);
if (gradleDistributionUrlString != null) {
final String upgradedDistributionUrl =
gradleDistributionUrlString.replaceAll(existingVersionString, gradleVersion7_6_1);
fileContents = fileContents.replaceFirst(gradleOrgVersionMatch, upgradedDistributionUrl);
} else {
logger.printTrace(gradleVersionNotFound);
}
}
return fileContents;
}
}
...@@ -94,6 +94,7 @@ Future<T> runInContext<T>( ...@@ -94,6 +94,7 @@ Future<T> runInContext<T>(
usage: globals.flutterUsage, usage: globals.flutterUsage,
gradleUtils: globals.gradleUtils!, gradleUtils: globals.gradleUtils!,
platform: globals.platform, platform: globals.platform,
androidStudio: globals.androidStudio,
), ),
AndroidLicenseValidator: () => AndroidLicenseValidator( AndroidLicenseValidator: () => AndroidLicenseValidator(
operatingSystemUtils: globals.os, operatingSystemUtils: globals.os,
......
...@@ -8,6 +8,7 @@ import 'package:flutter_tools/src/android/android_sdk.dart'; ...@@ -8,6 +8,7 @@ import 'package:flutter_tools/src/android/android_sdk.dart';
import 'package:flutter_tools/src/android/android_studio.dart'; import 'package:flutter_tools/src/android/android_studio.dart';
import 'package:flutter_tools/src/base/file_system.dart'; import 'package:flutter_tools/src/base/file_system.dart';
import 'package:flutter_tools/src/base/logger.dart'; import 'package:flutter_tools/src/base/logger.dart';
import 'package:flutter_tools/src/base/version.dart';
import 'package:flutter_tools/src/cache.dart'; import 'package:flutter_tools/src/cache.dart';
import 'package:flutter_tools/src/commands/build_apk.dart'; import 'package:flutter_tools/src/commands/build_apk.dart';
import 'package:flutter_tools/src/globals.dart' as globals; import 'package:flutter_tools/src/globals.dart' as globals;
...@@ -454,4 +455,7 @@ class FakeAndroidSdk extends Fake implements AndroidSdk { ...@@ -454,4 +455,7 @@ class FakeAndroidSdk extends Fake implements AndroidSdk {
class FakeAndroidStudio extends Fake implements AndroidStudio { class FakeAndroidStudio extends Fake implements AndroidStudio {
@override @override
String get javaPath => 'java'; String get javaPath => 'java';
@override
Version get version => Version(2021, 3, 1);
} }
...@@ -53,6 +53,7 @@ void main() { ...@@ -53,6 +53,7 @@ void main() {
usage: testUsage, usage: testUsage,
gradleUtils: FakeGradleUtils(), gradleUtils: FakeGradleUtils(),
platform: FakePlatform(), platform: FakePlatform(),
androidStudio: FakeAndroidStudio(),
); );
processManager.addCommand(const FakeCommand( processManager.addCommand(const FakeCommand(
command: <String>[ command: <String>[
...@@ -144,6 +145,7 @@ void main() { ...@@ -144,6 +145,7 @@ void main() {
usage: testUsage, usage: testUsage,
gradleUtils: FakeGradleUtils(), gradleUtils: FakeGradleUtils(),
platform: FakePlatform(), platform: FakePlatform(),
androidStudio: FakeAndroidStudio(),
); );
processManager.addCommand(const FakeCommand( processManager.addCommand(const FakeCommand(
command: <String>[ command: <String>[
...@@ -210,6 +212,7 @@ void main() { ...@@ -210,6 +212,7 @@ void main() {
usage: testUsage, usage: testUsage,
gradleUtils: FakeGradleUtils(), gradleUtils: FakeGradleUtils(),
platform: FakePlatform(), platform: FakePlatform(),
androidStudio: FakeAndroidStudio(),
); );
const FakeCommand fakeCmd = FakeCommand( const FakeCommand fakeCmd = FakeCommand(
...@@ -314,6 +317,7 @@ void main() { ...@@ -314,6 +317,7 @@ void main() {
usage: testUsage, usage: testUsage,
gradleUtils: FakeGradleUtils(), gradleUtils: FakeGradleUtils(),
platform: FakePlatform(), platform: FakePlatform(),
androidStudio: FakeAndroidStudio(),
); );
processManager.addCommand(const FakeCommand( processManager.addCommand(const FakeCommand(
command: <String>[ command: <String>[
...@@ -405,6 +409,7 @@ void main() { ...@@ -405,6 +409,7 @@ void main() {
usage: testUsage, usage: testUsage,
gradleUtils: FakeGradleUtils(), gradleUtils: FakeGradleUtils(),
platform: FakePlatform(), platform: FakePlatform(),
androidStudio: FakeAndroidStudio(),
); );
processManager.addCommand(FakeCommand( processManager.addCommand(FakeCommand(
command: const <String>[ command: const <String>[
...@@ -468,6 +473,7 @@ void main() { ...@@ -468,6 +473,7 @@ void main() {
usage: testUsage, usage: testUsage,
gradleUtils: FakeGradleUtils(), gradleUtils: FakeGradleUtils(),
platform: FakePlatform(), platform: FakePlatform(),
androidStudio: FakeAndroidStudio(),
); );
processManager.addCommand(const FakeCommand( processManager.addCommand(const FakeCommand(
command: <String>[ command: <String>[
...@@ -574,6 +580,7 @@ void main() { ...@@ -574,6 +580,7 @@ void main() {
'HOME': '/home', 'HOME': '/home',
}, },
), ),
androidStudio: FakeAndroidStudio(),
); );
processManager.addCommand(const FakeCommand( processManager.addCommand(const FakeCommand(
command: <String>[ command: <String>[
...@@ -670,6 +677,7 @@ void main() { ...@@ -670,6 +677,7 @@ void main() {
usage: testUsage, usage: testUsage,
gradleUtils: FakeGradleUtils(), gradleUtils: FakeGradleUtils(),
platform: FakePlatform(), platform: FakePlatform(),
androidStudio: FakeAndroidStudio(),
); );
processManager.addCommand(const FakeCommand( processManager.addCommand(const FakeCommand(
command: <String>[ command: <String>[
...@@ -796,6 +804,7 @@ android { ...@@ -796,6 +804,7 @@ android {
usage: testUsage, usage: testUsage,
gradleUtils: FakeGradleUtils(), gradleUtils: FakeGradleUtils(),
platform: FakePlatform(), platform: FakePlatform(),
androidStudio: FakeAndroidStudio(),
); );
processManager.addCommand(const FakeCommand( processManager.addCommand(const FakeCommand(
command: <String>[ command: <String>[
...@@ -829,6 +838,7 @@ BuildVariant: paidProfile ...@@ -829,6 +838,7 @@ BuildVariant: paidProfile
usage: testUsage, usage: testUsage,
gradleUtils: FakeGradleUtils(), gradleUtils: FakeGradleUtils(),
platform: FakePlatform(), platform: FakePlatform(),
androidStudio: FakeAndroidStudio(),
); );
processManager.addCommand(const FakeCommand( processManager.addCommand(const FakeCommand(
command: <String>[ command: <String>[
...@@ -858,6 +868,7 @@ Gradle Crashed ...@@ -858,6 +868,7 @@ Gradle Crashed
usage: testUsage, usage: testUsage,
gradleUtils: FakeGradleUtils(), gradleUtils: FakeGradleUtils(),
platform: FakePlatform(), platform: FakePlatform(),
androidStudio: FakeAndroidStudio(),
); );
processManager.addCommand(const FakeCommand( processManager.addCommand(const FakeCommand(
command: <String>[ command: <String>[
...@@ -922,6 +933,7 @@ Gradle Crashed ...@@ -922,6 +933,7 @@ Gradle Crashed
usage: testUsage, usage: testUsage,
gradleUtils: FakeGradleUtils(), gradleUtils: FakeGradleUtils(),
platform: FakePlatform(), platform: FakePlatform(),
androidStudio: FakeAndroidStudio(),
); );
processManager.addCommand(const FakeCommand( processManager.addCommand(const FakeCommand(
command: <String>[ command: <String>[
...@@ -979,6 +991,7 @@ Gradle Crashed ...@@ -979,6 +991,7 @@ Gradle Crashed
usage: testUsage, usage: testUsage,
gradleUtils: FakeGradleUtils(), gradleUtils: FakeGradleUtils(),
platform: FakePlatform(), platform: FakePlatform(),
androidStudio: FakeAndroidStudio(),
); );
processManager.addCommand(const FakeCommand( processManager.addCommand(const FakeCommand(
command: <String>[ command: <String>[
...@@ -1037,6 +1050,7 @@ Gradle Crashed ...@@ -1037,6 +1050,7 @@ Gradle Crashed
usage: testUsage, usage: testUsage,
gradleUtils: FakeGradleUtils(), gradleUtils: FakeGradleUtils(),
platform: FakePlatform(), platform: FakePlatform(),
androidStudio: FakeAndroidStudio(),
); );
processManager.addCommand(const FakeCommand( processManager.addCommand(const FakeCommand(
command: <String>[ command: <String>[
...@@ -1114,6 +1128,7 @@ Gradle Crashed ...@@ -1114,6 +1128,7 @@ Gradle Crashed
usage: testUsage, usage: testUsage,
gradleUtils: FakeGradleUtils(), gradleUtils: FakeGradleUtils(),
platform: FakePlatform(), platform: FakePlatform(),
androidStudio: FakeAndroidStudio(),
); );
processManager.addCommand(const FakeCommand( processManager.addCommand(const FakeCommand(
command: <String>[ command: <String>[
...@@ -1191,6 +1206,7 @@ Gradle Crashed ...@@ -1191,6 +1206,7 @@ Gradle Crashed
usage: testUsage, usage: testUsage,
gradleUtils: FakeGradleUtils(), gradleUtils: FakeGradleUtils(),
platform: FakePlatform(), platform: FakePlatform(),
androidStudio: FakeAndroidStudio(),
); );
processManager.addCommand(const FakeCommand( processManager.addCommand(const FakeCommand(
command: <String>[ command: <String>[
...@@ -1268,6 +1284,7 @@ Gradle Crashed ...@@ -1268,6 +1284,7 @@ Gradle Crashed
usage: testUsage, usage: testUsage,
gradleUtils: FakeGradleUtils(), gradleUtils: FakeGradleUtils(),
platform: FakePlatform(), platform: FakePlatform(),
androidStudio: FakeAndroidStudio(),
); );
processManager.addCommand(const FakeCommand( processManager.addCommand(const FakeCommand(
command: <String>[ command: <String>[
...@@ -1346,6 +1363,7 @@ Gradle Crashed ...@@ -1346,6 +1363,7 @@ Gradle Crashed
usage: testUsage, usage: testUsage,
gradleUtils: FakeGradleUtils(), gradleUtils: FakeGradleUtils(),
platform: FakePlatform(), platform: FakePlatform(),
androidStudio: FakeAndroidStudio(),
); );
processManager.addCommand( processManager.addCommand(
const FakeCommand(command: <String>[ const FakeCommand(command: <String>[
...@@ -1405,6 +1423,7 @@ Gradle Crashed ...@@ -1405,6 +1423,7 @@ Gradle Crashed
usage: testUsage, usage: testUsage,
gradleUtils: FakeGradleUtils(), gradleUtils: FakeGradleUtils(),
platform: FakePlatform(), platform: FakePlatform(),
androidStudio: FakeAndroidStudio(),
); );
processManager.addCommand(const FakeCommand( processManager.addCommand(const FakeCommand(
command: <String>[ command: <String>[
...@@ -1491,6 +1510,7 @@ Gradle Crashed ...@@ -1491,6 +1510,7 @@ Gradle Crashed
usage: testUsage, usage: testUsage,
gradleUtils: FakeGradleUtils(), gradleUtils: FakeGradleUtils(),
platform: FakePlatform(), platform: FakePlatform(),
androidStudio: FakeAndroidStudio(),
); );
processManager.addCommand(const FakeCommand( processManager.addCommand(const FakeCommand(
command: <String>[ command: <String>[
...@@ -1577,6 +1597,7 @@ Gradle Crashed ...@@ -1577,6 +1597,7 @@ Gradle Crashed
usage: testUsage, usage: testUsage,
gradleUtils: FakeGradleUtils(), gradleUtils: FakeGradleUtils(),
platform: FakePlatform(), platform: FakePlatform(),
androidStudio: FakeAndroidStudio(),
); );
processManager.addCommand(const FakeCommand( processManager.addCommand(const FakeCommand(
command: <String>[ command: <String>[
...@@ -1663,6 +1684,7 @@ Gradle Crashed ...@@ -1663,6 +1684,7 @@ Gradle Crashed
usage: testUsage, usage: testUsage,
gradleUtils: FakeGradleUtils(), gradleUtils: FakeGradleUtils(),
platform: FakePlatform(), platform: FakePlatform(),
androidStudio: FakeAndroidStudio(),
); );
processManager.addCommand(const FakeCommand( processManager.addCommand(const FakeCommand(
command: <String>[ command: <String>[
......
...@@ -216,6 +216,20 @@ void main() { ...@@ -216,6 +216,20 @@ void main() {
expect(getGradlewFileName(windowsPlatform), 'gradlew.bat'); expect(getGradlewFileName(windowsPlatform), 'gradlew.bat');
}); });
testWithoutContext('returns the gradle properties file', () async {
final Directory androidDirectory = fileSystem.directory('/android')
..createSync();
final Directory wrapperDirectory = androidDirectory
.childDirectory(gradleDirectoryName)
.childDirectory(gradleWrapperDirectoryName)
..createSync(recursive: true);
final File expectedFile = await wrapperDirectory
.childFile(gradleWrapperPropertiesFilename)
.create();
final File gradleWrapperFile = getGradleWrapperFile(androidDirectory);
expect(gradleWrapperFile.path, expectedFile.path);
});
testWithoutContext('returns the gradle wrapper version', () async { testWithoutContext('returns the gradle wrapper version', () async {
const String expectedVersion = '7.4.2'; const String expectedVersion = '7.4.2';
final Directory androidDirectory = fileSystem.directory('/android') final Directory androidDirectory = fileSystem.directory('/android')
...@@ -535,6 +549,32 @@ allprojects { ...@@ -535,6 +549,32 @@ allprojects {
} }
}); });
group('Parse gradle version from distribution url', () {
testWithoutContext('null distribution url returns null version', () {
expect(parseGradleVersionFromDistributionUrl(null), null);
});
testWithoutContext('unparseable format returns null', () {
const String distributionUrl = 'aString';
expect(parseGradleVersionFromDistributionUrl(distributionUrl), null);
});
testWithoutContext("recognizable 'all' format returns correct version", () {
const String distributionUrl = r'distributionUrl=https\://services.gradle.org/distributions/gradle-6.7-all.zip';
expect(parseGradleVersionFromDistributionUrl(distributionUrl), '6.7');
});
testWithoutContext("recognizable 'bin' format returns correct version", () {
const String distributionUrl = r'distributionUrl=https\://services.gradle.org/distributions/gradle-6.7-bin.zip';
expect(parseGradleVersionFromDistributionUrl(distributionUrl), '6.7');
});
testWithoutContext("recognizable 'rc' format returns correct version", () {
const String distributionUrl = r'distributionUrl=https\://services.gradle.org/distributions/gradle-8.1-rc-3-all.zip';
expect(parseGradleVersionFromDistributionUrl(distributionUrl), '8.1');
});
});
group('validates java/gradle versions', () { group('validates java/gradle versions', () {
final List<JavaGradleTestData> testData = <JavaGradleTestData>[ final List<JavaGradleTestData> testData = <JavaGradleTestData>[
// Values too new *these need to update* when // Values too new *these need to update* when
......
...@@ -2,4 +2,4 @@ distributionBase=GRADLE_USER_HOME ...@@ -2,4 +2,4 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.7-all.zip distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.1-all.zip
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment