Unverified Commit e031613a authored by Jason Simmons's avatar Jason Simmons Committed by GitHub

Use "gradle tasks --all" to query build variants (#21761)

Previously flutter_tools had used "gradle properties" to find the build types
and flavors supported by the Gradle project.  Tasks should work more reliably
across different versions of the Android Gradle plugin.

Fixes https://github.com/flutter/flutter/issues/20781
parent d340e2f2
...@@ -24,7 +24,7 @@ import 'android_sdk.dart'; ...@@ -24,7 +24,7 @@ import 'android_sdk.dart';
import 'android_studio.dart'; import 'android_studio.dart';
const String gradleVersion = '4.4'; const String gradleVersion = '4.4';
final RegExp _assembleTaskPattern = RegExp(r'assemble([^:]+): task '); final RegExp _assembleTaskPattern = RegExp(r'assemble(\S+)');
GradleProject _cachedGradleProject; GradleProject _cachedGradleProject;
String _cachedGradleExecutable; String _cachedGradleExecutable;
...@@ -97,18 +97,22 @@ Future<GradleProject> _readGradleProject() async { ...@@ -97,18 +97,22 @@ Future<GradleProject> _readGradleProject() async {
final Status status = logger.startProgress('Resolving dependencies...', expectSlowOperation: true); final Status status = logger.startProgress('Resolving dependencies...', expectSlowOperation: true);
GradleProject project; GradleProject project;
try { try {
final RunResult runResult = await runCheckedAsync( final RunResult propertiesRunResult = await runCheckedAsync(
<String>[gradle, 'app:properties'], <String>[gradle, 'app:properties'],
workingDirectory: flutterProject.android.hostAppGradleRoot.path, workingDirectory: flutterProject.android.hostAppGradleRoot.path,
environment: _gradleEnv, environment: _gradleEnv,
); );
final String properties = runResult.stdout.trim(); final RunResult tasksRunResult = await runCheckedAsync(
project = GradleProject.fromAppProperties(properties); <String>[gradle, 'app:tasks', '--all'],
workingDirectory: flutterProject.android.hostAppGradleRoot.path,
environment: _gradleEnv,
);
project = GradleProject.fromAppProperties(propertiesRunResult.stdout, tasksRunResult.stdout);
} catch (exception) { } catch (exception) {
if (getFlutterPluginVersion(flutterProject.android) == FlutterPluginVersion.managed) { if (getFlutterPluginVersion(flutterProject.android) == FlutterPluginVersion.managed) {
status.cancel(); status.cancel();
// Handle known exceptions. This will exit if handled. // Handle known exceptions. This will exit if handled.
handleKnownGradleExceptions(exception); handleKnownGradleExceptions(exception.toString());
// Print a general Gradle error and exit. // Print a general Gradle error and exit.
printError('* Error running Gradle:\n$exception\n'); printError('* Error running Gradle:\n$exception\n');
...@@ -445,7 +449,7 @@ Map<String, String> get _gradleEnv { ...@@ -445,7 +449,7 @@ Map<String, String> get _gradleEnv {
class GradleProject { class GradleProject {
GradleProject(this.buildTypes, this.productFlavors, this.apkDirectory); GradleProject(this.buildTypes, this.productFlavors, this.apkDirectory);
factory GradleProject.fromAppProperties(String properties) { factory GradleProject.fromAppProperties(String properties, String tasks) {
// Extract build directory. // Extract build directory.
final String buildDir = properties final String buildDir = properties
.split('\n') .split('\n')
...@@ -455,7 +459,7 @@ class GradleProject { ...@@ -455,7 +459,7 @@ class GradleProject {
// Extract build types and product flavors. // Extract build types and product flavors.
final Set<String> variants = Set<String>(); final Set<String> variants = Set<String>();
for (String s in properties.split('\n')) { for (String s in tasks.split('\n')) {
final Match match = _assembleTaskPattern.matchAsPrefix(s); final Match match = _assembleTaskPattern.matchAsPrefix(s);
if (match != null) { if (match != null) {
final String variant = match.group(1).toLowerCase(); final String variant = match.group(1).toLowerCase();
......
...@@ -63,53 +63,51 @@ void main() { ...@@ -63,53 +63,51 @@ void main() {
}); });
group('gradle project', () { group('gradle project', () {
GradleProject projectFrom(String properties) => GradleProject.fromAppProperties(properties); GradleProject projectFrom(String properties, String tasks) => GradleProject.fromAppProperties(properties, tasks);
test('should extract build directory from app properties', () { test('should extract build directory from app properties', () {
final GradleProject project = projectFrom(''' final GradleProject project = projectFrom('''
someProperty: someValue someProperty: someValue
buildDir: /Users/some/apps/hello/build/app buildDir: /Users/some/apps/hello/build/app
someOtherProperty: someOtherValue someOtherProperty: someOtherValue
'''); ''', '');
expect( expect(
fs.path.normalize(project.apkDirectory.path), fs.path.normalize(project.apkDirectory.path),
fs.path.normalize('/Users/some/apps/hello/build/app/outputs/apk'), fs.path.normalize('/Users/some/apps/hello/build/app/outputs/apk'),
); );
}); });
test('should extract default build variants from app properties', () { test('should extract default build variants from app properties', () {
final GradleProject project = projectFrom(''' final GradleProject project = projectFrom('buildDir: /Users/some/apps/hello/build/app', '''
someProperty: someValue someTask
assemble: task ':app:assemble' assemble
assembleAndroidTest: task ':app:assembleAndroidTest' assembleAndroidTest
assembleDebug: task ':app:assembleDebug' assembleDebug
assembleProfile: task ':app:assembleProfile' assembleProfile
assembleRelease: task ':app:assembleRelease' assembleRelease
buildDir: /Users/some/apps/hello/build/app someOtherTask
someOtherProperty: someOtherValue
'''); ''');
expect(project.buildTypes, <String>['debug', 'profile', 'release']); expect(project.buildTypes, <String>['debug', 'profile', 'release']);
expect(project.productFlavors, isEmpty); expect(project.productFlavors, isEmpty);
}); });
test('should extract custom build variants from app properties', () { test('should extract custom build variants from app properties', () {
final GradleProject project = projectFrom(''' final GradleProject project = projectFrom('buildDir: /Users/some/apps/hello/build/app', '''
someProperty: someValue someTask
assemble: task ':app:assemble' assemble
assembleAndroidTest: task ':app:assembleAndroidTest' assembleAndroidTest
assembleDebug: task ':app:assembleDebug' assembleDebug
assembleFree: task ':app:assembleFree' assembleFree
assembleFreeAndroidTest: task ':app:assembleFreeAndroidTest' assembleFreeAndroidTest
assembleFreeDebug: task ':app:assembleFreeDebug' assembleFreeDebug
assembleFreeProfile: task ':app:assembleFreeProfile' assembleFreeProfile
assembleFreeRelease: task ':app:assembleFreeRelease' assembleFreeRelease
assemblePaid: task ':app:assemblePaid' assemblePaid
assemblePaidAndroidTest: task ':app:assemblePaidAndroidTest' assemblePaidAndroidTest
assemblePaidDebug: task ':app:assemblePaidDebug' assemblePaidDebug
assemblePaidProfile: task ':app:assemblePaidProfile' assemblePaidProfile
assemblePaidRelease: task ':app:assemblePaidRelease' assemblePaidRelease
assembleProfile: task ':app:assembleProfile' assembleProfile
assembleRelease: task ':app:assembleRelease' assembleRelease
buildDir: /Users/some/apps/hello/build/app someOtherTask
someOtherProperty: someOtherValue
'''); ''');
expect(project.buildTypes, <String>['debug', 'profile', 'release']); expect(project.buildTypes, <String>['debug', 'profile', 'release']);
expect(project.productFlavors, <String>['free', 'paid']); expect(project.productFlavors, <String>['free', 'paid']);
......
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