Automatically wire dependencies for native plugins (#8891)
Go through all packages brought in by pub, and write the name and path of every one that is a flutter plugin into .flutter-plugins.
In android/settings.gradle and ios/Podfile, read in .flutter-plugins, if that file exists. The Android / iOS code from the plugins is automatically added as dependencies of the native code of the app.
diff --git a/packages/flutter_tools/lib/src/android/gradle.dart b/packages/flutter_tools/lib/src/android/gradle.dart
index 5e5984b..48e3e8d 100644
--- a/packages/flutter_tools/lib/src/android/gradle.dart
+++ b/packages/flutter_tools/lib/src/android/gradle.dart
@@ -15,6 +15,7 @@
import '../build_info.dart';
import '../cache.dart';
import '../globals.dart';
+import '../plugins.dart';
import 'android_sdk.dart';
import 'android_studio.dart';
@@ -154,6 +155,8 @@
settings.values['flutter.buildMode'] = buildModeName;
settings.writeContents(localProperties);
+ writeFlutterPluginsList();
+
final String gradle = ensureGradle();
switch (flutterPluginVersion) {
diff --git a/packages/flutter_tools/lib/src/ios/mac.dart b/packages/flutter_tools/lib/src/ios/mac.dart
index e20e793..e26e0d7 100644
--- a/packages/flutter_tools/lib/src/ios/mac.dart
+++ b/packages/flutter_tools/lib/src/ios/mac.dart
@@ -19,6 +19,7 @@
import '../doctor.dart';
import '../flx.dart' as flx;
import '../globals.dart';
+import '../plugins.dart';
import '../services.dart';
import 'xcodeproj.dart';
@@ -127,6 +128,7 @@
// copied over to a location that is suitable for Xcodebuild to find them.
final Directory appDirectory = fs.directory(app.appDirectory);
await _addServicesToBundle(appDirectory);
+ writeFlutterPluginsList();
_runPodInstall(appDirectory, flutterFrameworkDir(mode));
diff --git a/packages/flutter_tools/lib/src/plugins.dart b/packages/flutter_tools/lib/src/plugins.dart
new file mode 100644
index 0000000..0df1721
--- /dev/null
+++ b/packages/flutter_tools/lib/src/plugins.dart
@@ -0,0 +1,52 @@
+// Copyright 2017 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 'package:yaml/yaml.dart';
+
+import 'base/file_system.dart';
+import 'dart/package_map.dart';
+import 'globals.dart';
+
+dynamic _loadYamlFile(String path) {
+ if (!fs.isFileSync(path))
+ return null;
+ final String manifestString = fs.file(path).readAsStringSync();
+ return loadYaml(manifestString);
+}
+
+String _generatePluginManifest() {
+ Map<String, Uri> packages;
+ try {
+ packages = new PackageMap(PackageMap.globalPackagesPath).map;
+ } on FormatException catch(e) {
+ printTrace('Invalid .packages file: $e');
+ return '';
+ }
+ final List<String> plugins = <String>[];
+ packages.forEach((String name, Uri uri) {
+ final Uri packageRoot = uri.resolve('..');
+ final dynamic packageConfig = _loadYamlFile(packageRoot.resolve('pubspec.yaml').path);
+ if (packageConfig != null) {
+ final dynamic flutterConfig = packageConfig['flutter'];
+ if (flutterConfig != null && flutterConfig.containsKey('plugin')) {
+ printTrace('Found plugin $name at ${packageRoot.path}');
+ plugins.add('$name=${packageRoot.path}');
+ }
+ }
+ });
+ return plugins.join('\n');
+}
+
+void writeFlutterPluginsList() {
+ final File pluginsProperties = fs.file('.flutter-plugins');
+
+ final String pluginManifest = _generatePluginManifest();
+ if (pluginManifest.isNotEmpty) {
+ pluginsProperties.writeAsStringSync('$pluginManifest\n');
+ } else {
+ if (pluginsProperties.existsSync()) {
+ pluginsProperties.deleteSync();
+ }
+ }
+}