Unverified Commit b225cb8d authored by Jenn Magder's avatar Jenn Magder Committed by GitHub

Revert "[flutter_tools] Removes the need of a no-op plugin implementations (#48614)" (#49005)

This reverts commit 5eb394e0.
parent 01f19ee6
...@@ -3,7 +3,6 @@ ...@@ -3,7 +3,6 @@
// found in the LICENSE file. // found in the LICENSE file.
import 'dart:async'; import 'dart:async';
import 'dart:convert';
import 'dart:io'; import 'dart:io';
import 'package:flutter_devicelab/framework/framework.dart'; import 'package:flutter_devicelab/framework/framework.dart';
...@@ -75,6 +74,10 @@ Future<void> main() async { ...@@ -75,6 +74,10 @@ Future<void> main() async {
); );
}); });
// https://github.com/flutter/flutter/issues/46898
// https://github.com/flutter/flutter/issues/39657
File(path.join(pluginCDirectory.path, 'android', 'build.gradle')).deleteSync();
final File pluginCpubspec = File(path.join(pluginCDirectory.path, 'pubspec.yaml')); final File pluginCpubspec = File(path.join(pluginCDirectory.path, 'pubspec.yaml'));
await pluginCpubspec.writeAsString(''' await pluginCpubspec.writeAsString('''
name: plugin_c name: plugin_c
...@@ -174,14 +177,10 @@ public class DummyPluginAClass { ...@@ -174,14 +177,10 @@ public class DummyPluginAClass {
} }
final String flutterPluginsDependenciesFileContent = flutterPluginsDependenciesFile.readAsStringSync(); final String flutterPluginsDependenciesFileContent = flutterPluginsDependenciesFile.readAsStringSync();
final Map<String, dynamic> jsonContent = json.decode(flutterPluginsDependenciesFileContent) as Map<String, dynamic>;
// Verify the dependencyGraph object is valid. The rest of the contents of this file are not relevant to the
// dependency graph and are tested by unit tests.
final List<dynamic> dependencyGraph = jsonContent['dependencyGraph'] as List<dynamic>;
const String kExpectedPluginsDependenciesContent = const String kExpectedPluginsDependenciesContent =
'[' '{'
'\"_info\":\"// This is a generated file; do not edit or check into version control.\",'
'\"dependencyGraph\":['
'{' '{'
'\"name\":\"plugin_a\",' '\"name\":\"plugin_a\",'
'\"dependencies\":[\"plugin_b\",\"plugin_c\"]' '\"dependencies\":[\"plugin_b\",\"plugin_c\"]'
...@@ -194,12 +193,14 @@ public class DummyPluginAClass { ...@@ -194,12 +193,14 @@ public class DummyPluginAClass {
'\"name\":\"plugin_c\",' '\"name\":\"plugin_c\",'
'\"dependencies\":[]' '\"dependencies\":[]'
'}' '}'
']'; ']'
final String graphString = json.encode(dependencyGraph); '}';
if (graphString != kExpectedPluginsDependenciesContent) {
if (flutterPluginsDependenciesFileContent != kExpectedPluginsDependenciesContent) {
return TaskResult.failure( return TaskResult.failure(
'Unexpected file content in ${flutterPluginsDependenciesFile.path}: ' 'Unexpected file content in ${flutterPluginsDependenciesFile.path}: '
'Found "$graphString" instead of "$kExpectedPluginsDependenciesContent"' 'Found "$flutterPluginsDependenciesFileContent" instead of '
'"$kExpectedPluginsDependenciesContent"'
); );
} }
......
...@@ -11,7 +11,6 @@ import 'package:yaml/yaml.dart'; ...@@ -11,7 +11,6 @@ import 'package:yaml/yaml.dart';
import 'android/gradle.dart'; import 'android/gradle.dart';
import 'base/common.dart'; import 'base/common.dart';
import 'base/file_system.dart'; import 'base/file_system.dart';
import 'base/time.dart';
import 'convert.dart'; import 'convert.dart';
import 'dart/package_map.dart'; import 'dart/package_map.dart';
import 'features.dart'; import 'features.dart';
...@@ -19,7 +18,6 @@ import 'globals.dart' as globals; ...@@ -19,7 +18,6 @@ import 'globals.dart' as globals;
import 'macos/cocoapods.dart'; import 'macos/cocoapods.dart';
import 'platform_plugins.dart'; import 'platform_plugins.dart';
import 'project.dart'; import 'project.dart';
import 'version.dart';
void _renderTemplateToFile(String template, dynamic context, String filePath) { void _renderTemplateToFile(String template, dynamic context, String filePath) {
final String renderedTemplate = final String renderedTemplate =
...@@ -265,7 +263,7 @@ class Plugin { ...@@ -265,7 +263,7 @@ class Plugin {
final Map<String, PluginPlatform> platforms; final Map<String, PluginPlatform> platforms;
} }
Plugin _pluginFromPackage(String name, Uri packageRoot) { Plugin _pluginFromPubspec(String name, Uri packageRoot) {
final String pubspecPath = globals.fs.path.fromUri(packageRoot.resolve('pubspec.yaml')); final String pubspecPath = globals.fs.path.fromUri(packageRoot.resolve('pubspec.yaml'));
if (!globals.fs.isFileSync(pubspecPath)) { if (!globals.fs.isFileSync(pubspecPath)) {
return null; return null;
...@@ -304,7 +302,7 @@ List<Plugin> findPlugins(FlutterProject project) { ...@@ -304,7 +302,7 @@ List<Plugin> findPlugins(FlutterProject project) {
} }
packages.forEach((String name, Uri uri) { packages.forEach((String name, Uri uri) {
final Uri packageRoot = uri.resolve('..'); final Uri packageRoot = uri.resolve('..');
final Plugin plugin = _pluginFromPackage(name, packageRoot); final Plugin plugin = _pluginFromPubspec(name, packageRoot);
if (plugin != null) { if (plugin != null) {
plugins.add(plugin); plugins.add(plugin);
} }
...@@ -312,159 +310,55 @@ List<Plugin> findPlugins(FlutterProject project) { ...@@ -312,159 +310,55 @@ List<Plugin> findPlugins(FlutterProject project) {
return plugins; return plugins;
} }
/// Filters [plugins] to those supported by [platformKey]. /// Writes the .flutter-plugins and .flutter-plugins-dependencies files based on the list of plugins.
List<Map<String, dynamic>> _filterPluginsByPlatform(List<Plugin>plugins, String platformKey) { /// If there aren't any plugins, then the files aren't written to disk.
final Iterable<Plugin> platformPlugins = plugins.where((Plugin p) {
return p.platforms.containsKey(platformKey);
});
final Set<String> pluginNames = platformPlugins.map((Plugin plugin) => plugin.name).toSet();
final List<Map<String, dynamic>> list = <Map<String, dynamic>>[];
for (final Plugin plugin in platformPlugins) {
list.add(<String, dynamic>{
'name': plugin.name,
'path': fsUtils.escapePath(plugin.path),
'dependencies': <String>[...plugin.dependencies.where(pluginNames.contains)],
});
}
return list;
}
/// Writes the .flutter-plugins-dependencies file based on the list of plugins.
/// If there aren't any plugins, then the files aren't written to disk. The resulting
/// file looks something like this (order of keys is not guaranteed):
/// {
/// "info": "This is a generated file; do not edit or check into version control.",
/// "plugins": {
/// "ios": [
/// {
/// "name": "test",
/// "path": "test_path",
/// "dependencies": [
/// "plugin-a",
/// "plugin-b"
/// ]
/// }
/// ],
/// "android": [],
/// "macos": [],
/// "linux": [],
/// "windows": [],
/// "web": []
/// },
/// "dependencyGraph": [
/// {
/// "name": "plugin-a",
/// "dependencies": [
/// "plugin-b",
/// "plugin-c"
/// ]
/// },
/// {
/// "name": "plugin-b",
/// "dependencies": [
/// "plugin-c"
/// ]
/// },
/// {
/// "name": "plugin-c",
/// "dependencies": []
/// }
/// ],
/// "date_created": "1970-01-01 00:00:00.000",
/// "version": "0.0.0-unknown"
/// }
///
/// ///
/// Finally, returns [true] if .flutter-plugins-dependencies has changed, /// Finally, returns [true] if .flutter-plugins or .flutter-plugins-dependencies have changed,
/// otherwise returns [false]. /// otherwise returns [false].
bool _writeFlutterPluginsList(FlutterProject project, List<Plugin> plugins) { bool _writeFlutterPluginsList(FlutterProject project, List<Plugin> plugins) {
final File pluginsFile = project.flutterPluginsDependenciesFile;
if (plugins.isEmpty) {
if (pluginsFile.existsSync()) {
pluginsFile.deleteSync();
return true;
}
return false;
}
final String iosKey = project.ios.pluginConfigKey;
final String androidKey = project.android.pluginConfigKey;
final String macosKey = project.macos.pluginConfigKey;
final String linuxKey = project.linux.pluginConfigKey;
final String windowsKey = project.windows.pluginConfigKey;
final String webKey = project.web.pluginConfigKey;
final Map<String, dynamic> pluginsMap = <String, dynamic>{};
pluginsMap[iosKey] = _filterPluginsByPlatform(plugins, iosKey);
pluginsMap[androidKey] = _filterPluginsByPlatform(plugins, androidKey);
pluginsMap[macosKey] = _filterPluginsByPlatform(plugins, macosKey);
pluginsMap[linuxKey] = _filterPluginsByPlatform(plugins, linuxKey);
pluginsMap[windowsKey] = _filterPluginsByPlatform(plugins, windowsKey);
pluginsMap[webKey] = _filterPluginsByPlatform(plugins, webKey);
final Map<String, dynamic> result = <String, dynamic> {};
result['info'] = 'This is a generated file; do not edit or check into version control.';
result['plugins'] = pluginsMap;
/// The dependencyGraph object is kept for backwards compatibility, but
/// should be removed once migration is complete.
/// https://github.com/flutter/flutter/issues/48918
result['dependencyGraph'] = _createPluginLegacyDependencyGraph(plugins);
result['date_created'] = systemClock.now().toString();
result['version'] = flutterVersion.frameworkVersion;
final String oldPluginFileContent = _readFileContent(pluginsFile);
final String pluginFileContent = json.encode(result);
pluginsFile.writeAsStringSync(pluginFileContent, flush: true);
return oldPluginFileContent != pluginFileContent;
}
List<dynamic> _createPluginLegacyDependencyGraph(List<Plugin> plugins) {
final List<dynamic> directAppDependencies = <dynamic>[]; final List<dynamic> directAppDependencies = <dynamic>[];
const String info = 'This is a generated file; do not edit or check into version control.';
final StringBuffer flutterPluginsBuffer = StringBuffer('# $info\n');
final Set<String> pluginNames = plugins.map((Plugin plugin) => plugin.name).toSet(); final Set<String> pluginNames = <String>{};
for (final Plugin plugin in plugins) { for (final Plugin plugin in plugins) {
pluginNames.add(plugin.name);
}
for (final Plugin plugin in plugins) {
flutterPluginsBuffer.write('${plugin.name}=${fsUtils.escapePath(plugin.path)}\n');
directAppDependencies.add(<String, dynamic>{ directAppDependencies.add(<String, dynamic>{
'name': plugin.name, 'name': plugin.name,
// Extract the plugin dependencies which happen to be plugins. // Extract the plugin dependencies which happen to be plugins.
'dependencies': <String>[...plugin.dependencies.where(pluginNames.contains)], 'dependencies': <String>[...plugin.dependencies.where(pluginNames.contains)],
}); });
} }
return directAppDependencies;
}
// The .flutter-plugins file will be DEPRECATED in favor of .flutter-plugins-dependencies.
// TODO(franciscojma): Remove this method once deprecated.
// https://github.com/flutter/flutter/issues/48918
//
/// Writes the .flutter-plugins files based on the list of plugins.
/// If there aren't any plugins, then the files aren't written to disk.
///
/// Finally, returns [true] if .flutter-plugins has changed, otherwise returns [false].
bool _writeFlutterPluginsListLegacy(FlutterProject project, List<Plugin> plugins) {
final File pluginsFile = project.flutterPluginsFile; final File pluginsFile = project.flutterPluginsFile;
if (plugins.isEmpty) { final String oldPluginFileContent = _readFileContent(pluginsFile);
final String pluginFileContent = flutterPluginsBuffer.toString();
if (pluginNames.isNotEmpty) {
pluginsFile.writeAsStringSync(pluginFileContent, flush: true);
} else {
if (pluginsFile.existsSync()) { if (pluginsFile.existsSync()) {
pluginsFile.deleteSync(); pluginsFile.deleteSync();
return true;
} }
return false;
} }
const String info = 'This is a generated file; do not edit or check into version control.'; final File dependenciesFile = project.flutterPluginsDependenciesFile;
final StringBuffer flutterPluginsBuffer = StringBuffer('# $info\n'); final String oldDependenciesFileContent = _readFileContent(dependenciesFile);
final String dependenciesFileContent = json.encode(<String, dynamic>{
for (final Plugin plugin in plugins) { '_info': '// $info',
flutterPluginsBuffer.write('${plugin.name}=${fsUtils.escapePath(plugin.path)}\n'); 'dependencyGraph': directAppDependencies,
});
if (pluginNames.isNotEmpty) {
dependenciesFile.writeAsStringSync(dependenciesFileContent, flush: true);
} else {
if (dependenciesFile.existsSync()) {
dependenciesFile.deleteSync();
}
} }
final String oldPluginFileContent = _readFileContent(pluginsFile);
final String pluginFileContent = flutterPluginsBuffer.toString();
pluginsFile.writeAsStringSync(pluginFileContent, flush: true);
return oldPluginFileContent != _readFileContent(pluginsFile); return oldPluginFileContent != _readFileContent(pluginsFile)
|| oldDependenciesFileContent != _readFileContent(dependenciesFile);
} }
/// Returns the contents of [File] or [null] if that file does not exist. /// Returns the contents of [File] or [null] if that file does not exist.
...@@ -888,13 +782,8 @@ Future<void> _writeWebPluginRegistrant(FlutterProject project, List<Plugin> plug ...@@ -888,13 +782,8 @@ Future<void> _writeWebPluginRegistrant(FlutterProject project, List<Plugin> plug
/// Assumes `pub get` has been executed since last change to `pubspec.yaml`. /// Assumes `pub get` has been executed since last change to `pubspec.yaml`.
void refreshPluginsList(FlutterProject project, {bool checkProjects = false}) { void refreshPluginsList(FlutterProject project, {bool checkProjects = false}) {
final List<Plugin> plugins = findPlugins(project); final List<Plugin> plugins = findPlugins(project);
// TODO(franciscojma): Remove once migration is complete.
// Write the legacy plugin files to avoid breaking existing apps.
final bool legacyChanged = _writeFlutterPluginsListLegacy(project, plugins);
final bool changed = _writeFlutterPluginsList(project, plugins); final bool changed = _writeFlutterPluginsList(project, plugins);
if (changed || legacyChanged) { if (changed) {
if (!checkProjects || project.ios.existsSync()) { if (!checkProjects || project.ios.existsSync()) {
cocoaPods.invalidatePodInstallOutput(project.ios); cocoaPods.invalidatePodInstallOutput(project.ios);
} }
......
...@@ -20,7 +20,6 @@ import 'flutter_manifest.dart'; ...@@ -20,7 +20,6 @@ import 'flutter_manifest.dart';
import 'globals.dart' as globals; import 'globals.dart' as globals;
import 'ios/plist_parser.dart'; import 'ios/plist_parser.dart';
import 'ios/xcodeproj.dart' as xcode; import 'ios/xcodeproj.dart' as xcode;
import 'platform_plugins.dart';
import 'plugins.dart'; import 'plugins.dart';
import 'template.dart'; import 'template.dart';
...@@ -252,16 +251,6 @@ class FlutterProject { ...@@ -252,16 +251,6 @@ class FlutterProject {
} }
} }
/// Base class for projects per platform.
abstract class FlutterProjectPlatform {
/// Plugin's platform config key, e.g., "macos", "ios".
String get pluginConfigKey;
/// Whether the platform exists in the project.
bool existsSync();
}
/// Represents an Xcode-based sub-project. /// Represents an Xcode-based sub-project.
/// ///
/// This defines interfaces common to iOS and macOS projects. /// This defines interfaces common to iOS and macOS projects.
...@@ -311,15 +300,12 @@ abstract class XcodeBasedProject { ...@@ -311,15 +300,12 @@ abstract class XcodeBasedProject {
/// ///
/// Instances will reflect the contents of the `ios/` sub-folder of /// Instances will reflect the contents of the `ios/` sub-folder of
/// Flutter applications and the `.ios/` sub-folder of Flutter module projects. /// Flutter applications and the `.ios/` sub-folder of Flutter module projects.
class IosProject extends FlutterProjectPlatform implements XcodeBasedProject { class IosProject implements XcodeBasedProject {
IosProject.fromFlutter(this.parent); IosProject.fromFlutter(this.parent);
@override @override
final FlutterProject parent; final FlutterProject parent;
@override
String get pluginConfigKey => IOSPlugin.kConfigKey;
static final RegExp _productBundleIdPattern = RegExp(r'''^\s*PRODUCT_BUNDLE_IDENTIFIER\s*=\s*(["']?)(.*?)\1;\s*$'''); static final RegExp _productBundleIdPattern = RegExp(r'''^\s*PRODUCT_BUNDLE_IDENTIFIER\s*=\s*(["']?)(.*?)\1;\s*$''');
static const String _productBundleIdVariable = r'$(PRODUCT_BUNDLE_IDENTIFIER)'; static const String _productBundleIdVariable = r'$(PRODUCT_BUNDLE_IDENTIFIER)';
static const String _hostAppBundleName = 'Runner'; static const String _hostAppBundleName = 'Runner';
...@@ -588,15 +574,12 @@ class IosProject extends FlutterProjectPlatform implements XcodeBasedProject { ...@@ -588,15 +574,12 @@ class IosProject extends FlutterProjectPlatform implements XcodeBasedProject {
/// ///
/// Instances will reflect the contents of the `android/` sub-folder of /// Instances will reflect the contents of the `android/` sub-folder of
/// Flutter applications and the `.android/` sub-folder of Flutter module projects. /// Flutter applications and the `.android/` sub-folder of Flutter module projects.
class AndroidProject extends FlutterProjectPlatform { class AndroidProject {
AndroidProject._(this.parent); AndroidProject._(this.parent);
/// The parent of this project. /// The parent of this project.
final FlutterProject parent; final FlutterProject parent;
@override
String get pluginConfigKey => AndroidPlugin.kConfigKey;
static final RegExp _applicationIdPattern = RegExp('^\\s*applicationId\\s+[\'\"](.*)[\'\"]\\s*\$'); static final RegExp _applicationIdPattern = RegExp('^\\s*applicationId\\s+[\'\"](.*)[\'\"]\\s*\$');
static final RegExp _kotlinPluginPattern = RegExp('^\\s*apply plugin\:\\s+[\'\"]kotlin-android[\'\"]\\s*\$'); static final RegExp _kotlinPluginPattern = RegExp('^\\s*apply plugin\:\\s+[\'\"]kotlin-android[\'\"]\\s*\$');
static final RegExp _groupPattern = RegExp('^\\s*group\\s+[\'\"](.*)[\'\"]\\s*\$'); static final RegExp _groupPattern = RegExp('^\\s*group\\s+[\'\"](.*)[\'\"]\\s*\$');
...@@ -644,7 +627,6 @@ class AndroidProject extends FlutterProjectPlatform { ...@@ -644,7 +627,6 @@ class AndroidProject extends FlutterProjectPlatform {
} }
/// Whether the current flutter project has an Android sub-project. /// Whether the current flutter project has an Android sub-project.
@override
bool existsSync() { bool existsSync() {
return parent.isModule || _editableHostAppDirectory.existsSync(); return parent.isModule || _editableHostAppDirectory.existsSync();
} }
...@@ -778,16 +760,12 @@ enum AndroidEmbeddingVersion { ...@@ -778,16 +760,12 @@ enum AndroidEmbeddingVersion {
} }
/// Represents the web sub-project of a Flutter project. /// Represents the web sub-project of a Flutter project.
class WebProject extends FlutterProjectPlatform { class WebProject {
WebProject._(this.parent); WebProject._(this.parent);
final FlutterProject parent; final FlutterProject parent;
@override
String get pluginConfigKey => WebPlugin.kConfigKey;
/// Whether this flutter project has a web sub-project. /// Whether this flutter project has a web sub-project.
@override
bool existsSync() { bool existsSync() {
return parent.directory.childDirectory('web').existsSync() return parent.directory.childDirectory('web').existsSync()
&& indexFile.existsSync(); && indexFile.existsSync();
...@@ -832,15 +810,12 @@ Match _firstMatchInFile(File file, RegExp regExp) { ...@@ -832,15 +810,12 @@ Match _firstMatchInFile(File file, RegExp regExp) {
} }
/// The macOS sub project. /// The macOS sub project.
class MacOSProject extends FlutterProjectPlatform implements XcodeBasedProject { class MacOSProject implements XcodeBasedProject {
MacOSProject._(this.parent); MacOSProject._(this.parent);
@override @override
final FlutterProject parent; final FlutterProject parent;
@override
String get pluginConfigKey => MacOSPlugin.kConfigKey;
static const String _hostAppBundleName = 'Runner'; static const String _hostAppBundleName = 'Runner';
@override @override
...@@ -920,15 +895,11 @@ class MacOSProject extends FlutterProjectPlatform implements XcodeBasedProject { ...@@ -920,15 +895,11 @@ class MacOSProject extends FlutterProjectPlatform implements XcodeBasedProject {
} }
/// The Windows sub project /// The Windows sub project
class WindowsProject extends FlutterProjectPlatform { class WindowsProject {
WindowsProject._(this.project); WindowsProject._(this.project);
final FlutterProject project; final FlutterProject project;
@override
String get pluginConfigKey => WindowsPlugin.kConfigKey;
@override
bool existsSync() => _editableDirectory.existsSync(); bool existsSync() => _editableDirectory.existsSync();
Directory get _editableDirectory => project.directory.childDirectory('windows'); Directory get _editableDirectory => project.directory.childDirectory('windows');
...@@ -962,14 +933,11 @@ class WindowsProject extends FlutterProjectPlatform { ...@@ -962,14 +933,11 @@ class WindowsProject extends FlutterProjectPlatform {
} }
/// The Linux sub project. /// The Linux sub project.
class LinuxProject extends FlutterProjectPlatform { class LinuxProject {
LinuxProject._(this.project); LinuxProject._(this.project);
final FlutterProject project; final FlutterProject project;
@override
String get pluginConfigKey => LinuxPlugin.kConfigKey;
Directory get _editableDirectory => project.directory.childDirectory('linux'); Directory get _editableDirectory => project.directory.childDirectory('linux');
/// The directory in the project that is managed by Flutter. As much as /// The directory in the project that is managed by Flutter. As much as
...@@ -982,7 +950,6 @@ class LinuxProject extends FlutterProjectPlatform { ...@@ -982,7 +950,6 @@ class LinuxProject extends FlutterProjectPlatform {
/// checked in should live here. /// checked in should live here.
Directory get ephemeralDirectory => managedDirectory.childDirectory('ephemeral'); Directory get ephemeralDirectory => managedDirectory.childDirectory('ephemeral');
@override
bool existsSync() => _editableDirectory.existsSync(); bool existsSync() => _editableDirectory.existsSync();
/// The Linux project makefile. /// The Linux project makefile.
......
...@@ -16,8 +16,6 @@ import 'cache.dart'; ...@@ -16,8 +16,6 @@ import 'cache.dart';
import 'convert.dart'; import 'convert.dart';
import 'globals.dart' as globals; import 'globals.dart' as globals;
FlutterVersion get flutterVersion => context.get<FlutterVersion>();
class FlutterVersion { class FlutterVersion {
FlutterVersion([this._clock = const SystemClock()]) { FlutterVersion([this._clock = const SystemClock()]) {
_frameworkRevision = _runGit(gitLog(<String>['-n', '1', '--pretty=format:%H']).join(' ')); _frameworkRevision = _runGit(gitLog(<String>['-n', '1', '--pretty=format:%H']).join(' '));
......
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