Unverified Commit 4e108b6f authored by Amir Hardon's avatar Amir Hardon Committed by GitHub

Exclude non Android plugins from Gradle build (#40640)

Before this change, having an Android app depend on a plugin that has no android implementation resulted in a Gradle build failure.

This scenario is likely to become more common if we're enabling federated plugins, as the package implementing just the desktop implementation of a plugin won't have an Android implementation.

This changes the Gradle plugin to not try to build any plugins that doesn't have an android/build.gradle file.
parent d1e71cd8
...@@ -1021,6 +1021,7 @@ Future<void> _androidGradleTests(String subShard) async { ...@@ -1021,6 +1021,7 @@ Future<void> _androidGradleTests(String subShard) async {
await _runDevicelabTest('gradle_plugin_light_apk_test', env: env); await _runDevicelabTest('gradle_plugin_light_apk_test', env: env);
await _runDevicelabTest('gradle_plugin_fat_apk_test', env: env); await _runDevicelabTest('gradle_plugin_fat_apk_test', env: env);
await _runDevicelabTest('gradle_r8_test', env: env); await _runDevicelabTest('gradle_r8_test', env: env);
await _runDevicelabTest('gradle_non_android_plugin_test', env: env);
} }
if (subShard == 'gradle2') { if (subShard == 'gradle2') {
await _runDevicelabTest('gradle_plugin_bundle_test', env: env); await _runDevicelabTest('gradle_plugin_bundle_test', env: env);
......
// Copyright (c) 2019 The Chromium 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 'dart:async';
import 'dart:io';
import 'package:flutter_devicelab/framework/framework.dart';
import 'package:flutter_devicelab/framework/utils.dart';
import 'package:path/path.dart' as path;
/// Tests that a flutter app that depends on a non-Android plugin
/// (an iOS only plugin in this case) can still build for Android.
Future<void> main() async {
await task(() async {
section('Find Java');
final String javaHome = await findJavaHome();
if (javaHome == null)
return TaskResult.failure('Could not find Java');
print('\nUsing JAVA_HOME=$javaHome');
section('Create Flutter plugin project');
final Directory tempDir = Directory.systemTemp.createTempSync('flutter_plugin_test.');
final Directory projectDir = Directory(path.join(tempDir.path, 'ios_only'));
try {
await inDirectory(tempDir, () async {
await flutter(
'create',
options: <String>[
'--org', 'io.flutter.devicelab',
'-t', 'plugin',
'ios_only',
],
);
});
section('Delete plugin\'s Android folder');
final File androidFolder = File(path.join(
projectDir.path,
'android',
));
androidFolder.deleteSync(recursive: true);
section('Update pubspec.yaml to iOS only plugin');
final File pubspecFile = File(path.join(projectDir.path, 'pubspec.yaml'));
final String pubspecString = pubspecFile.readAsStringSync();
final StringBuffer iosOnlyPubspec = StringBuffer();
for (String line in pubspecString.split('\n')) {
if (line.startsWith(' androidPackage:')) {
continue;
}
if (line.startsWith(' pluginClass:')) {
iosOnlyPubspec.write(' platforms:\n');
iosOnlyPubspec.write(' ios:\n');
iosOnlyPubspec.write(' pluginClass: IosOnlyPlugin\n');
continue;
}
iosOnlyPubspec.write('$line\n');
}
pubspecFile.writeAsStringSync(iosOnlyPubspec.toString());
section('Build example APK');
final StringBuffer stderr = StringBuffer();
final Directory exampleDir = Directory(path.join(projectDir.path, 'example'));
await inDirectory(exampleDir, () async {
await evalFlutter(
'build',
options: <String>[
'apk',
'--target-platform', 'android-arm',
'--verbose',
],
canFail: true,
stderr: stderr,
);
});
section('Check that the example APK was built');
final String exampleAppApk = path.join(
exampleDir.path,
'build',
'app',
'outputs',
'apk',
'release',
'app-release.apk',
);
if (!exists(File(exampleAppApk))) {
return TaskResult.failure('Failed to build example app');
}
return TaskResult.success(null);
} catch (e) {
return TaskResult.failure(e.toString());
} finally {
rmTree(tempDir);
}
});
}
...@@ -329,7 +329,18 @@ class FlutterPlugin implements Plugin<Project> { ...@@ -329,7 +329,18 @@ class FlutterPlugin implements Plugin<Project> {
private Properties getPluginList() { private Properties getPluginList() {
File pluginsFile = new File(project.projectDir.parentFile.parentFile, '.flutter-plugins') File pluginsFile = new File(project.projectDir.parentFile.parentFile, '.flutter-plugins')
return readPropertiesIfExist(pluginsFile) Properties allPlugins = readPropertiesIfExist(pluginsFile)
Properties androidPlugins = new Properties()
allPlugins.each { name, path ->
File editableAndroidProject = new File(path, 'android' + File.separator + 'build.gradle')
if (editableAndroidProject.exists()) {
androidPlugins.setProperty(name, path)
}
// TODO(amirh): log an error if this plugin was specified to be an Android
// plugin according to the new schema, and was missing a build.gradle file.
// https://github.com/flutter/flutter/issues/40784
}
return androidPlugins
} }
private void addPluginTasks() { private void addPluginTasks() {
......
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