mirror of
https://github.com/flutter/flutter.git
synced 2025-06-03 00:51:18 +00:00
Add .flutter-plugins-dependencies
to the project, which contains the app's plugin dependency graph (#45379)
This commit is contained in:
parent
161e4dfb04
commit
b6e92003c8
1
.gitignore
vendored
1
.gitignore
vendored
@ -44,6 +44,7 @@ version
|
|||||||
**/doc/api/
|
**/doc/api/
|
||||||
.dart_tool/
|
.dart_tool/
|
||||||
.flutter-plugins
|
.flutter-plugins
|
||||||
|
.flutter-plugins-dependencies
|
||||||
.packages
|
.packages
|
||||||
.pub-cache/
|
.pub-cache/
|
||||||
.pub/
|
.pub/
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
**/doc/api/
|
**/doc/api/
|
||||||
.dart_tool/
|
.dart_tool/
|
||||||
.flutter-plugins
|
.flutter-plugins
|
||||||
|
.flutter-plugins-dependencies
|
||||||
.packages
|
.packages
|
||||||
.pub-cache/
|
.pub-cache/
|
||||||
.pub/
|
.pub/
|
||||||
|
@ -27,6 +27,7 @@
|
|||||||
**/doc/api/
|
**/doc/api/
|
||||||
.dart_tool/
|
.dart_tool/
|
||||||
.flutter-plugins
|
.flutter-plugins
|
||||||
|
.flutter-plugins-dependencies
|
||||||
.packages
|
.packages
|
||||||
.pub-cache/
|
.pub-cache/
|
||||||
.pub/
|
.pub/
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
**/doc/api/
|
**/doc/api/
|
||||||
.dart_tool/
|
.dart_tool/
|
||||||
.flutter-plugins
|
.flutter-plugins
|
||||||
|
.flutter-plugins-dependencies
|
||||||
.packages
|
.packages
|
||||||
.pub-cache/
|
.pub-cache/
|
||||||
.pub/
|
.pub/
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
**/doc/api/
|
**/doc/api/
|
||||||
.dart_tool/
|
.dart_tool/
|
||||||
.flutter-plugins
|
.flutter-plugins
|
||||||
|
.flutter-plugins-dependencies
|
||||||
.packages
|
.packages
|
||||||
.pub-cache/
|
.pub-cache/
|
||||||
.pub/
|
.pub/
|
||||||
|
@ -39,3 +39,4 @@ build/
|
|||||||
.android/
|
.android/
|
||||||
.ios/
|
.ios/
|
||||||
.flutter-plugins
|
.flutter-plugins
|
||||||
|
.flutter-plugins-dependencies
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
**/doc/api/
|
**/doc/api/
|
||||||
.dart_tool/
|
.dart_tool/
|
||||||
.flutter-plugins
|
.flutter-plugins
|
||||||
|
.flutter-plugins-dependencies
|
||||||
.packages
|
.packages
|
||||||
.pub-cache/
|
.pub-cache/
|
||||||
.pub/
|
.pub/
|
||||||
|
@ -6,6 +6,7 @@ import static groovy.io.FileType.FILES
|
|||||||
|
|
||||||
import com.android.builder.model.AndroidProject
|
import com.android.builder.model.AndroidProject
|
||||||
import com.android.build.OutputFile
|
import com.android.build.OutputFile
|
||||||
|
import groovy.json.JsonSlurper
|
||||||
import java.nio.file.Path
|
import java.nio.file.Path
|
||||||
import java.nio.file.Paths
|
import java.nio.file.Paths
|
||||||
import java.util.regex.Matcher
|
import java.util.regex.Matcher
|
||||||
@ -253,6 +254,7 @@ class FlutterPlugin implements Plugin<Project> {
|
|||||||
private void configurePlugins() {
|
private void configurePlugins() {
|
||||||
if (!buildPluginAsAar()) {
|
if (!buildPluginAsAar()) {
|
||||||
getPluginList().each this.&configurePluginProject
|
getPluginList().each this.&configurePluginProject
|
||||||
|
getPluginDependencies().each this.&configurePluginDependencies
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
project.repositories {
|
project.repositories {
|
||||||
@ -298,19 +300,15 @@ class FlutterPlugin implements Plugin<Project> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Adds the plugin project dependency to the app project .
|
// Adds the plugin project dependency to the app project .
|
||||||
private void configurePluginProject(String name, String _) {
|
private void configurePluginProject(String pluginName, String _) {
|
||||||
Project pluginProject = project.rootProject.findProject(":$name")
|
Project pluginProject = project.rootProject.findProject(":$pluginName")
|
||||||
if (pluginProject == null) {
|
if (pluginProject == null) {
|
||||||
project.logger.error("Plugin project :$name not found. Please update settings.gradle.")
|
project.logger.error("Plugin project :$pluginName not found. Please update settings.gradle.")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// Add plugin dependency to the app project.
|
// Add plugin dependency to the app project.
|
||||||
project.dependencies {
|
project.dependencies {
|
||||||
if (project.getConfigurations().findByName("implementation")) {
|
implementation pluginProject
|
||||||
implementation pluginProject
|
|
||||||
} else {
|
|
||||||
compile pluginProject
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
Closure addEmbeddingCompileOnlyDependency = { buildType ->
|
Closure addEmbeddingCompileOnlyDependency = { buildType ->
|
||||||
String flutterBuildMode = buildModeFor(buildType)
|
String flutterBuildMode = buildModeFor(buildType)
|
||||||
@ -337,6 +335,36 @@ class FlutterPlugin implements Plugin<Project> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Add the dependencies on other plugin projects to the plugin project.
|
||||||
|
// A plugin A can depend on plugin B. As a result, this dependency must be surfaced by
|
||||||
|
// making the Gradle plugin project A depend on the Gradle plugin project B.
|
||||||
|
private void configurePluginDependencies(Object dependencyObject) {
|
||||||
|
assert dependencyObject.name instanceof String
|
||||||
|
Project pluginProject = project.rootProject.findProject(":${dependencyObject.name}")
|
||||||
|
if (pluginProject == null) {
|
||||||
|
// Ignore plugins that don't have a project since most likely they don't
|
||||||
|
// have an android/ directory.
|
||||||
|
return
|
||||||
|
}
|
||||||
|
assert dependencyObject.dependencies instanceof List
|
||||||
|
dependencyObject.dependencies.each { pluginDependencyName ->
|
||||||
|
assert pluginDependencyName instanceof String
|
||||||
|
if (pluginDependencyName.empty) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
Project dependencyProject = project.rootProject.findProject(":$pluginDependencyName")
|
||||||
|
if (dependencyProject == null) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// Wait for the Android plugin to load and add the dependency to the plugin project.
|
||||||
|
pluginProject.afterEvaluate {
|
||||||
|
pluginProject.dependencies {
|
||||||
|
implementation dependencyProject
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
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')
|
||||||
Properties allPlugins = readPropertiesIfExist(pluginsFile)
|
Properties allPlugins = readPropertiesIfExist(pluginsFile)
|
||||||
@ -353,6 +381,39 @@ class FlutterPlugin implements Plugin<Project> {
|
|||||||
return androidPlugins
|
return androidPlugins
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Gets the plugins dependencies from `.flutter-plugins-dependencies`.
|
||||||
|
private List getPluginDependencies() {
|
||||||
|
// Consider a `.flutter-plugins-dependencies` file with the following content:
|
||||||
|
// {
|
||||||
|
// "dependencyGraph": [
|
||||||
|
// {
|
||||||
|
// "name": "plugin-a",
|
||||||
|
// "dependencies": ["plugin-b","plugin-c"]
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// "name": "plugin-b",
|
||||||
|
// "dependencies": ["plugin-c"]
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// "name": "plugin-c",
|
||||||
|
// "dependencies": []'
|
||||||
|
// }
|
||||||
|
// ]
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// This means, `plugin-a` depends on `plugin-b` and `plugin-c`.
|
||||||
|
// `plugin-b` depends on `plugin-c`.
|
||||||
|
// `plugin-c` doesn't depend on anything.
|
||||||
|
File pluginsDependencyFile = new File(project.projectDir.parentFile.parentFile, '.flutter-plugins-dependencies')
|
||||||
|
if (pluginsDependencyFile.exists()) {
|
||||||
|
def object = new JsonSlurper().parseText(pluginsDependencyFile.text)
|
||||||
|
assert object instanceof Map
|
||||||
|
assert object.dependencyGraph instanceof List
|
||||||
|
return object.dependencyGraph
|
||||||
|
}
|
||||||
|
return []
|
||||||
|
}
|
||||||
|
|
||||||
private static String toCammelCase(List<String> parts) {
|
private static String toCammelCase(List<String> parts) {
|
||||||
if (parts.empty) {
|
if (parts.empty) {
|
||||||
return ""
|
return ""
|
||||||
|
@ -4,12 +4,14 @@
|
|||||||
|
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
|
||||||
|
import 'package:meta/meta.dart';
|
||||||
import 'package:mustache/mustache.dart' as mustache;
|
import 'package:mustache/mustache.dart' as mustache;
|
||||||
import 'package:yaml/yaml.dart';
|
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 'convert.dart';
|
||||||
import 'dart/package_map.dart';
|
import 'dart/package_map.dart';
|
||||||
import 'features.dart';
|
import 'features.dart';
|
||||||
import 'globals.dart';
|
import 'globals.dart';
|
||||||
@ -27,10 +29,14 @@ void _renderTemplateToFile(String template, dynamic context, String filePath) {
|
|||||||
|
|
||||||
class Plugin {
|
class Plugin {
|
||||||
Plugin({
|
Plugin({
|
||||||
this.name,
|
@required this.name,
|
||||||
this.path,
|
@required this.path,
|
||||||
this.platforms,
|
@required this.platforms,
|
||||||
});
|
@required this.dependencies,
|
||||||
|
}) : assert(name != null),
|
||||||
|
assert(path != null),
|
||||||
|
assert(platforms != null),
|
||||||
|
assert(dependencies != null);
|
||||||
|
|
||||||
/// Parses [Plugin] specification from the provided pluginYaml.
|
/// Parses [Plugin] specification from the provided pluginYaml.
|
||||||
///
|
///
|
||||||
@ -60,18 +66,28 @@ class Plugin {
|
|||||||
/// pluginClass: SamplePlugin
|
/// pluginClass: SamplePlugin
|
||||||
/// windows:
|
/// windows:
|
||||||
/// pluginClass: SamplePlugin
|
/// pluginClass: SamplePlugin
|
||||||
factory Plugin.fromYaml(String name, String path, YamlMap pluginYaml) {
|
factory Plugin.fromYaml(
|
||||||
|
String name,
|
||||||
|
String path,
|
||||||
|
YamlMap pluginYaml,
|
||||||
|
List<String> dependencies,
|
||||||
|
) {
|
||||||
final List<String> errors = validatePluginYaml(pluginYaml);
|
final List<String> errors = validatePluginYaml(pluginYaml);
|
||||||
if (errors.isNotEmpty) {
|
if (errors.isNotEmpty) {
|
||||||
throwToolExit('Invalid plugin specification.\n${errors.join('\n')}');
|
throwToolExit('Invalid plugin specification.\n${errors.join('\n')}');
|
||||||
}
|
}
|
||||||
if (pluginYaml != null && pluginYaml['platforms'] != null) {
|
if (pluginYaml != null && pluginYaml['platforms'] != null) {
|
||||||
return Plugin._fromMultiPlatformYaml(name, path, pluginYaml);
|
return Plugin._fromMultiPlatformYaml(name, path, pluginYaml, dependencies);
|
||||||
}
|
}
|
||||||
return Plugin._fromLegacyYaml(name, path, pluginYaml);
|
return Plugin._fromLegacyYaml(name, path, pluginYaml, dependencies);
|
||||||
}
|
}
|
||||||
|
|
||||||
factory Plugin._fromMultiPlatformYaml(String name, String path, dynamic pluginYaml) {
|
factory Plugin._fromMultiPlatformYaml(
|
||||||
|
String name,
|
||||||
|
String path,
|
||||||
|
dynamic pluginYaml,
|
||||||
|
List<String> dependencies,
|
||||||
|
) {
|
||||||
assert (pluginYaml != null && pluginYaml['platforms'] != null,
|
assert (pluginYaml != null && pluginYaml['platforms'] != null,
|
||||||
'Invalid multi-platform plugin specification.');
|
'Invalid multi-platform plugin specification.');
|
||||||
final YamlMap platformsYaml = pluginYaml['platforms'] as YamlMap;
|
final YamlMap platformsYaml = pluginYaml['platforms'] as YamlMap;
|
||||||
@ -118,10 +134,16 @@ class Plugin {
|
|||||||
name: name,
|
name: name,
|
||||||
path: path,
|
path: path,
|
||||||
platforms: platforms,
|
platforms: platforms,
|
||||||
|
dependencies: dependencies,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
factory Plugin._fromLegacyYaml(String name, String path, dynamic pluginYaml) {
|
factory Plugin._fromLegacyYaml(
|
||||||
|
String name,
|
||||||
|
String path,
|
||||||
|
dynamic pluginYaml,
|
||||||
|
List<String> dependencies,
|
||||||
|
) {
|
||||||
final Map<String, PluginPlatform> platforms = <String, PluginPlatform>{};
|
final Map<String, PluginPlatform> platforms = <String, PluginPlatform>{};
|
||||||
final String pluginClass = pluginYaml['pluginClass'] as String;
|
final String pluginClass = pluginYaml['pluginClass'] as String;
|
||||||
if (pluginYaml != null && pluginClass != null) {
|
if (pluginYaml != null && pluginClass != null) {
|
||||||
@ -147,6 +169,7 @@ class Plugin {
|
|||||||
name: name,
|
name: name,
|
||||||
path: path,
|
path: path,
|
||||||
platforms: platforms,
|
platforms: platforms,
|
||||||
|
dependencies: dependencies,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -232,6 +255,9 @@ class Plugin {
|
|||||||
final String name;
|
final String name;
|
||||||
final String path;
|
final String path;
|
||||||
|
|
||||||
|
/// The name of the packages this plugin depends on.
|
||||||
|
final List<String> dependencies;
|
||||||
|
|
||||||
/// This is a mapping from platform config key to the plugin platform spec.
|
/// This is a mapping from platform config key to the plugin platform spec.
|
||||||
final Map<String, PluginPlatform> platforms;
|
final Map<String, PluginPlatform> platforms;
|
||||||
}
|
}
|
||||||
@ -250,11 +276,13 @@ Plugin _pluginFromPubspec(String name, Uri packageRoot) {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
final String packageRootPath = fs.path.fromUri(packageRoot);
|
final String packageRootPath = fs.path.fromUri(packageRoot);
|
||||||
|
final YamlMap dependencies = pubspec['dependencies'];
|
||||||
printTrace('Found plugin $name at $packageRootPath');
|
printTrace('Found plugin $name at $packageRootPath');
|
||||||
return Plugin.fromYaml(
|
return Plugin.fromYaml(
|
||||||
name,
|
name,
|
||||||
packageRootPath,
|
packageRootPath,
|
||||||
flutterConfig['plugin'] as YamlMap,
|
flutterConfig['plugin'] as YamlMap,
|
||||||
|
dependencies == null ? <String>[] : <String>[...dependencies.keys],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -281,29 +309,58 @@ List<Plugin> findPlugins(FlutterProject project) {
|
|||||||
return plugins;
|
return plugins;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns true if .flutter-plugins has changed, otherwise returns false.
|
/// Writes the .flutter-plugins and .flutter-plugins-dependencies 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 or .flutter-plugins-dependencies have changed,
|
||||||
|
/// otherwise returns [false].
|
||||||
bool _writeFlutterPluginsList(FlutterProject project, List<Plugin> plugins) {
|
bool _writeFlutterPluginsList(FlutterProject project, List<Plugin> plugins) {
|
||||||
|
final List<dynamic> directAppDependencies = <dynamic>[];
|
||||||
|
final StringBuffer flutterPluginsBuffer = StringBuffer();
|
||||||
|
|
||||||
|
final Set<String> pluginNames = <String>{};
|
||||||
|
for (Plugin plugin in plugins) {
|
||||||
|
pluginNames.add(plugin.name);
|
||||||
|
}
|
||||||
|
for (Plugin plugin in plugins) {
|
||||||
|
flutterPluginsBuffer.write('${plugin.name}=${escapePath(plugin.path)}\n');
|
||||||
|
directAppDependencies.add(<String, dynamic>{
|
||||||
|
'name': plugin.name,
|
||||||
|
// Extract the plugin dependencies which happen to be plugins.
|
||||||
|
'dependencies': <String>[...plugin.dependencies.where(pluginNames.contains)],
|
||||||
|
});
|
||||||
|
}
|
||||||
final File pluginsFile = project.flutterPluginsFile;
|
final File pluginsFile = project.flutterPluginsFile;
|
||||||
final String oldContents = _readFlutterPluginsList(project);
|
final String oldPluginFileContent = _readFileContent(pluginsFile);
|
||||||
final String pluginManifest =
|
final String pluginFileContent = flutterPluginsBuffer.toString();
|
||||||
plugins.map<String>((Plugin p) => '${p.name}=${escapePath(p.path)}').join('\n');
|
if (pluginFileContent.isNotEmpty) {
|
||||||
if (pluginManifest.isNotEmpty) {
|
pluginsFile.writeAsStringSync(pluginFileContent, flush: true);
|
||||||
pluginsFile.writeAsStringSync('$pluginManifest\n', flush: true);
|
|
||||||
} else {
|
} else {
|
||||||
if (pluginsFile.existsSync()) {
|
if (pluginsFile.existsSync()) {
|
||||||
pluginsFile.deleteSync();
|
pluginsFile.deleteSync();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
final String newContents = _readFlutterPluginsList(project);
|
|
||||||
return oldContents != newContents;
|
final File dependenciesFile = project.flutterPluginsDependenciesFile;
|
||||||
|
final String oldDependenciesFileContent = _readFileContent(dependenciesFile);
|
||||||
|
final String dependenciesFileContent = json.encode(<String, dynamic>{
|
||||||
|
'dependencyGraph': directAppDependencies,
|
||||||
|
});
|
||||||
|
if (pluginFileContent.isNotEmpty) {
|
||||||
|
dependenciesFile.writeAsStringSync(dependenciesFileContent, flush: true);
|
||||||
|
} else {
|
||||||
|
if (dependenciesFile.existsSync()) {
|
||||||
|
dependenciesFile.deleteSync();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return oldPluginFileContent != _readFileContent(pluginsFile)
|
||||||
|
|| oldDependenciesFileContent != _readFileContent(dependenciesFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the contents of the `.flutter-plugins` file in [project], or
|
/// Returns the contents of [File] or [null] if that file does not exist.
|
||||||
/// null if that file does not exist.
|
String _readFileContent(File file) {
|
||||||
String _readFlutterPluginsList(FlutterProject project) {
|
return file.existsSync() ? file.readAsStringSync() : null;
|
||||||
return project.flutterPluginsFile.existsSync()
|
|
||||||
? project.flutterPluginsFile.readAsStringSync()
|
|
||||||
: null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const String _androidPluginRegistryTemplateOldEmbedding = '''package io.flutter.plugins;
|
const String _androidPluginRegistryTemplateOldEmbedding = '''package io.flutter.plugins;
|
||||||
@ -782,5 +839,5 @@ Future<void> injectPlugins(FlutterProject project, {bool checkProjects = false})
|
|||||||
///
|
///
|
||||||
/// Assumes [refreshPluginsList] has been called since last change to `pubspec.yaml`.
|
/// Assumes [refreshPluginsList] has been called since last change to `pubspec.yaml`.
|
||||||
bool hasPlugins(FlutterProject project) {
|
bool hasPlugins(FlutterProject project) {
|
||||||
return _readFlutterPluginsList(project) != null;
|
return _readFileContent(project.flutterPluginsFile) != null;
|
||||||
}
|
}
|
||||||
|
@ -146,6 +146,10 @@ class FlutterProject {
|
|||||||
/// The `.flutter-plugins` file of this project.
|
/// The `.flutter-plugins` file of this project.
|
||||||
File get flutterPluginsFile => directory.childFile('.flutter-plugins');
|
File get flutterPluginsFile => directory.childFile('.flutter-plugins');
|
||||||
|
|
||||||
|
/// The `.flutter-plugins-dependencies` file of this project,
|
||||||
|
/// which contains the dependencies each plugin depends on.
|
||||||
|
File get flutterPluginsDependenciesFile => directory.childFile('.flutter-plugins-dependencies');
|
||||||
|
|
||||||
/// The `.dart-tool` directory of this project.
|
/// The `.dart-tool` directory of this project.
|
||||||
Directory get dartTool => directory.childDirectory('.dart_tool');
|
Directory get dartTool => directory.childDirectory('.dart_tool');
|
||||||
|
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
**/doc/api/
|
**/doc/api/
|
||||||
.dart_tool/
|
.dart_tool/
|
||||||
.flutter-plugins
|
.flutter-plugins
|
||||||
|
.flutter-plugins-dependencies
|
||||||
.packages
|
.packages
|
||||||
.pub-cache/
|
.pub-cache/
|
||||||
.pub/
|
.pub/
|
||||||
|
@ -39,3 +39,4 @@ build/
|
|||||||
.android/
|
.android/
|
||||||
.ios/
|
.ios/
|
||||||
.flutter-plugins
|
.flutter-plugins
|
||||||
|
.flutter-plugins-dependencies
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
**/doc/api/
|
**/doc/api/
|
||||||
.dart_tool/
|
.dart_tool/
|
||||||
.flutter-plugins
|
.flutter-plugins
|
||||||
|
.flutter-plugins-dependencies
|
||||||
.packages
|
.packages
|
||||||
.pub-cache/
|
.pub-cache/
|
||||||
.pub/
|
.pub/
|
||||||
|
@ -20,7 +20,7 @@ void main() {
|
|||||||
|
|
||||||
final dynamic pluginYaml = loadYaml(pluginYamlRaw);
|
final dynamic pluginYaml = loadYaml(pluginYamlRaw);
|
||||||
final Plugin plugin =
|
final Plugin plugin =
|
||||||
Plugin.fromYaml(_kTestPluginName, _kTestPluginPath, pluginYaml);
|
Plugin.fromYaml(_kTestPluginName, _kTestPluginPath, pluginYaml, const <String>[]);
|
||||||
|
|
||||||
final AndroidPlugin androidPlugin =
|
final AndroidPlugin androidPlugin =
|
||||||
plugin.platforms[AndroidPlugin.kConfigKey];
|
plugin.platforms[AndroidPlugin.kConfigKey];
|
||||||
@ -53,7 +53,7 @@ void main() {
|
|||||||
|
|
||||||
final dynamic pluginYaml = loadYaml(pluginYamlRaw);
|
final dynamic pluginYaml = loadYaml(pluginYamlRaw);
|
||||||
final Plugin plugin =
|
final Plugin plugin =
|
||||||
Plugin.fromYaml(_kTestPluginName, _kTestPluginPath, pluginYaml);
|
Plugin.fromYaml(_kTestPluginName, _kTestPluginPath, pluginYaml, const <String>[]);
|
||||||
|
|
||||||
final AndroidPlugin androidPlugin =
|
final AndroidPlugin androidPlugin =
|
||||||
plugin.platforms[AndroidPlugin.kConfigKey];
|
plugin.platforms[AndroidPlugin.kConfigKey];
|
||||||
@ -100,7 +100,7 @@ void main() {
|
|||||||
|
|
||||||
final dynamic pluginYaml = loadYaml(pluginYamlRaw);
|
final dynamic pluginYaml = loadYaml(pluginYamlRaw);
|
||||||
final Plugin plugin =
|
final Plugin plugin =
|
||||||
Plugin.fromYaml(_kTestPluginName, _kTestPluginPath, pluginYaml);
|
Plugin.fromYaml(_kTestPluginName, _kTestPluginPath, pluginYaml, const <String>[]);
|
||||||
|
|
||||||
final AndroidPlugin androidPlugin =
|
final AndroidPlugin androidPlugin =
|
||||||
plugin.platforms[AndroidPlugin.kConfigKey];
|
plugin.platforms[AndroidPlugin.kConfigKey];
|
||||||
@ -144,7 +144,7 @@ void main() {
|
|||||||
|
|
||||||
final dynamic pluginYaml = loadYaml(pluginYamlRaw);
|
final dynamic pluginYaml = loadYaml(pluginYamlRaw);
|
||||||
final Plugin plugin =
|
final Plugin plugin =
|
||||||
Plugin.fromYaml(_kTestPluginName, _kTestPluginPath, pluginYaml);
|
Plugin.fromYaml(_kTestPluginName, _kTestPluginPath, pluginYaml, const <String>[]);
|
||||||
|
|
||||||
expect(plugin.platforms, <String, PluginPlatform> {});
|
expect(plugin.platforms, <String, PluginPlatform> {});
|
||||||
});
|
});
|
||||||
|
@ -9,7 +9,7 @@ import 'package:flutter_tools/src/features.dart';
|
|||||||
import 'package:flutter_tools/src/ios/xcodeproj.dart';
|
import 'package:flutter_tools/src/ios/xcodeproj.dart';
|
||||||
import 'package:flutter_tools/src/plugins.dart';
|
import 'package:flutter_tools/src/plugins.dart';
|
||||||
import 'package:flutter_tools/src/project.dart';
|
import 'package:flutter_tools/src/project.dart';
|
||||||
|
import 'package:meta/meta.dart';
|
||||||
import 'package:mockito/mockito.dart';
|
import 'package:mockito/mockito.dart';
|
||||||
|
|
||||||
import '../src/common.dart';
|
import '../src/common.dart';
|
||||||
@ -32,7 +32,8 @@ void main() {
|
|||||||
// Add basic properties to the Flutter project and subprojects
|
// Add basic properties to the Flutter project and subprojects
|
||||||
flutterProject = MockFlutterProject();
|
flutterProject = MockFlutterProject();
|
||||||
when(flutterProject.directory).thenReturn(fs.directory('/'));
|
when(flutterProject.directory).thenReturn(fs.directory('/'));
|
||||||
when(flutterProject.flutterPluginsFile).thenReturn(flutterProject.directory.childFile('.plugins'));
|
when(flutterProject.flutterPluginsFile).thenReturn(flutterProject.directory.childFile('.flutter-plugins'));
|
||||||
|
when(flutterProject.flutterPluginsDependenciesFile).thenReturn(flutterProject.directory.childFile('.flutter-plugins-dependencies'));
|
||||||
iosProject = MockIosProject();
|
iosProject = MockIosProject();
|
||||||
when(flutterProject.ios).thenReturn(iosProject);
|
when(flutterProject.ios).thenReturn(iosProject);
|
||||||
when(iosProject.pluginRegistrantHost).thenReturn(flutterProject.directory.childDirectory('Runner'));
|
when(iosProject.pluginRegistrantHost).thenReturn(flutterProject.directory.childDirectory('Runner'));
|
||||||
@ -189,6 +190,37 @@ flutter:
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void createPluginWithDependencies({
|
||||||
|
@required String name,
|
||||||
|
@required List<String> dependencies,
|
||||||
|
}) {
|
||||||
|
assert(name != null);
|
||||||
|
assert(dependencies != null);
|
||||||
|
|
||||||
|
final Directory pluginDirectory = fs.systemTempDirectory.createTempSync('plugin.');
|
||||||
|
pluginDirectory
|
||||||
|
.childFile('pubspec.yaml')
|
||||||
|
.writeAsStringSync('''
|
||||||
|
name: $name
|
||||||
|
flutter:
|
||||||
|
plugin:
|
||||||
|
androidPackage: plugin2
|
||||||
|
pluginClass: UseNewEmbedding
|
||||||
|
dependencies:
|
||||||
|
''');
|
||||||
|
for (String dependency in dependencies) {
|
||||||
|
pluginDirectory
|
||||||
|
.childFile('pubspec.yaml')
|
||||||
|
.writeAsStringSync(' $dependency:\n', mode: FileMode.append);
|
||||||
|
}
|
||||||
|
flutterProject.directory
|
||||||
|
.childFile('.packages')
|
||||||
|
.writeAsStringSync(
|
||||||
|
'$name:${pluginDirectory.childDirectory('lib').uri.toString()}\n',
|
||||||
|
mode: FileMode.append,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
// Creates the files that would indicate that pod install has run for the
|
// Creates the files that would indicate that pod install has run for the
|
||||||
// given project.
|
// given project.
|
||||||
void simulatePodInstallRun(XcodeBasedProject project) {
|
void simulatePodInstallRun(XcodeBasedProject project) {
|
||||||
@ -199,6 +231,7 @@ flutter:
|
|||||||
testUsingContext('Refreshing the plugin list is a no-op when the plugins list stays empty', () {
|
testUsingContext('Refreshing the plugin list is a no-op when the plugins list stays empty', () {
|
||||||
refreshPluginsList(flutterProject);
|
refreshPluginsList(flutterProject);
|
||||||
expect(flutterProject.flutterPluginsFile.existsSync(), false);
|
expect(flutterProject.flutterPluginsFile.existsSync(), false);
|
||||||
|
expect(flutterProject.flutterPluginsDependenciesFile.existsSync(), false);
|
||||||
}, overrides: <Type, Generator>{
|
}, overrides: <Type, Generator>{
|
||||||
FileSystem: () => fs,
|
FileSystem: () => fs,
|
||||||
ProcessManager: () => FakeProcessManager.any(),
|
ProcessManager: () => FakeProcessManager.any(),
|
||||||
@ -210,6 +243,7 @@ flutter:
|
|||||||
when(macosProject.existsSync()).thenReturn(false);
|
when(macosProject.existsSync()).thenReturn(false);
|
||||||
refreshPluginsList(flutterProject);
|
refreshPluginsList(flutterProject);
|
||||||
expect(flutterProject.flutterPluginsFile.existsSync(), false);
|
expect(flutterProject.flutterPluginsFile.existsSync(), false);
|
||||||
|
expect(flutterProject.flutterPluginsDependenciesFile.existsSync(), false);
|
||||||
}, overrides: <Type, Generator>{
|
}, overrides: <Type, Generator>{
|
||||||
FileSystem: () => fs,
|
FileSystem: () => fs,
|
||||||
ProcessManager: () => FakeProcessManager.any(),
|
ProcessManager: () => FakeProcessManager.any(),
|
||||||
@ -221,6 +255,47 @@ flutter:
|
|||||||
when(macosProject.existsSync()).thenReturn(false);
|
when(macosProject.existsSync()).thenReturn(false);
|
||||||
refreshPluginsList(flutterProject);
|
refreshPluginsList(flutterProject);
|
||||||
expect(flutterProject.flutterPluginsFile.existsSync(), true);
|
expect(flutterProject.flutterPluginsFile.existsSync(), true);
|
||||||
|
expect(flutterProject.flutterPluginsDependenciesFile.existsSync(), true);
|
||||||
|
}, overrides: <Type, Generator>{
|
||||||
|
FileSystem: () => fs,
|
||||||
|
ProcessManager: () => FakeProcessManager.any(),
|
||||||
|
});
|
||||||
|
|
||||||
|
testUsingContext('Refreshing the plugin list modifies .flutter-plugins and .flutter-plugins-dependencies when there are plugins', () {
|
||||||
|
createPluginWithDependencies(name: 'plugin-a', dependencies: const <String>['plugin-b', 'plugin-c', 'random-package']);
|
||||||
|
createPluginWithDependencies(name: 'plugin-b', dependencies: const <String>['plugin-c']);
|
||||||
|
createPluginWithDependencies(name: 'plugin-c', dependencies: const <String>[]);
|
||||||
|
when(iosProject.existsSync()).thenReturn(false);
|
||||||
|
when(macosProject.existsSync()).thenReturn(false);
|
||||||
|
|
||||||
|
refreshPluginsList(flutterProject);
|
||||||
|
|
||||||
|
expect(flutterProject.flutterPluginsFile.existsSync(), true);
|
||||||
|
expect(flutterProject.flutterPluginsDependenciesFile.existsSync(), true);
|
||||||
|
expect(flutterProject.flutterPluginsFile.readAsStringSync(),
|
||||||
|
'plugin-a=/.tmp_rand0/plugin.rand0/\n'
|
||||||
|
'plugin-b=/.tmp_rand0/plugin.rand1/\n'
|
||||||
|
'plugin-c=/.tmp_rand0/plugin.rand2/\n'
|
||||||
|
''
|
||||||
|
);
|
||||||
|
expect(flutterProject.flutterPluginsDependenciesFile.readAsStringSync(),
|
||||||
|
'{'
|
||||||
|
'"dependencyGraph":['
|
||||||
|
'{'
|
||||||
|
'"name":"plugin-a",'
|
||||||
|
'"dependencies":["plugin-b","plugin-c"]'
|
||||||
|
'},'
|
||||||
|
'{'
|
||||||
|
'"name":"plugin-b",'
|
||||||
|
'"dependencies":["plugin-c"]'
|
||||||
|
'},'
|
||||||
|
'{'
|
||||||
|
'"name":"plugin-c",'
|
||||||
|
'"dependencies":[]'
|
||||||
|
'}'
|
||||||
|
']'
|
||||||
|
'}'
|
||||||
|
);
|
||||||
}, overrides: <Type, Generator>{
|
}, overrides: <Type, Generator>{
|
||||||
FileSystem: () => fs,
|
FileSystem: () => fs,
|
||||||
ProcessManager: () => FakeProcessManager.any(),
|
ProcessManager: () => FakeProcessManager.any(),
|
||||||
|
Loading…
Reference in New Issue
Block a user