mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
Sort generated plugin file content by plugin name (#65509)
This commit is contained in:
parent
5b76b350b6
commit
bcd0959ac3
@ -1161,6 +1161,8 @@ Future<void> refreshPluginsList(FlutterProject project, {bool checkProjects = fa
|
||||
/// Assumes [refreshPluginsList] has been called since last change to `pubspec.yaml`.
|
||||
Future<void> injectPlugins(FlutterProject project, {bool checkProjects = false}) async {
|
||||
final List<Plugin> plugins = await findPlugins(project);
|
||||
// Sort the plugins by name to keep ordering stable in generated files.
|
||||
plugins.sort((Plugin left, Plugin right) => left.name.compareTo(right.name));
|
||||
if ((checkProjects && project.android.existsSync()) || !checkProjects) {
|
||||
await _writeAndroidPluginRegistrant(project, plugins);
|
||||
}
|
||||
|
||||
@ -8,6 +8,7 @@ import 'package:file/file.dart';
|
||||
import 'package:file/memory.dart';
|
||||
import 'package:file_testing/file_testing.dart';
|
||||
import 'package:flutter_tools/src/base/time.dart';
|
||||
import 'package:flutter_tools/src/base/utils.dart';
|
||||
import 'package:flutter_tools/src/features.dart';
|
||||
import 'package:flutter_tools/src/globals.dart' as globals;
|
||||
import 'package:flutter_tools/src/ios/xcodeproj.dart';
|
||||
@ -122,37 +123,57 @@ void main() {
|
||||
);
|
||||
});
|
||||
|
||||
const String _pluginYaml = '''
|
||||
// Makes fake plugin packages for each plugin, adds them to flutterProject,
|
||||
// and returns their directories.
|
||||
//
|
||||
// If an entry contains a path separator, it will be treated as a path for
|
||||
// the location of the package, with the name being the last component.
|
||||
// Otherwise it will be treated as a name, and put in a default location
|
||||
// (a fake pub cache).
|
||||
List<Directory> createFakePlugins(FileSystem fileSystem, List<String> pluginNamesOrPaths) {
|
||||
const String pluginYamlTemplate = '''
|
||||
flutter:
|
||||
plugin:
|
||||
platforms:
|
||||
ios:
|
||||
pluginClass: SomePlugin
|
||||
pluginClass: PLUGIN_CLASS
|
||||
macos:
|
||||
pluginClass: SomePlugin
|
||||
pluginClass: PLUGIN_CLASS
|
||||
windows:
|
||||
pluginClass: SomePlugin
|
||||
pluginClass: PLUGIN_CLASS
|
||||
linux:
|
||||
pluginClass: SomePlugin
|
||||
pluginClass: PLUGIN_CLASS
|
||||
web:
|
||||
pluginClass: SomePlugin
|
||||
fileName: lib/SomeFile.dart
|
||||
pluginClass: PLUGIN_CLASS
|
||||
fileName: lib/PLUGIN_CLASS.dart
|
||||
android:
|
||||
pluginClass: SomePlugin
|
||||
pluginClass: PLUGIN_CLASS
|
||||
package: AndroidPackage
|
||||
''';
|
||||
|
||||
final List<Directory> directories = <Directory>[];
|
||||
final Directory fakePubCache = fileSystem.systemTempDirectory.childDirectory('cache');
|
||||
final File packagesFile = flutterProject.directory.childFile('.packages')
|
||||
..createSync(recursive: true);
|
||||
for (final String nameOrPath in pluginNamesOrPaths) {
|
||||
final String name = fileSystem.path.basename(nameOrPath);
|
||||
final Directory pluginDirectory = (nameOrPath == name)
|
||||
? fakePubCache.childDirectory(name)
|
||||
: fileSystem.directory(nameOrPath);
|
||||
packagesFile.writeAsStringSync(
|
||||
'$name:file://${pluginDirectory.childFile('lib').uri}\n',
|
||||
mode: FileMode.writeOnlyAppend);
|
||||
pluginDirectory.childFile('pubspec.yaml')
|
||||
..createSync(recursive: true)
|
||||
..writeAsStringSync(pluginYamlTemplate.replaceAll('PLUGIN_CLASS', toTitleCase(camelCase(name))));
|
||||
directories.add(pluginDirectory);
|
||||
}
|
||||
return directories;
|
||||
}
|
||||
|
||||
// Makes a fake plugin package, adds it to flutterProject, and returns its directory.
|
||||
Directory createFakePlugin(FileSystem fileSystem) {
|
||||
const String name = 'apackage';
|
||||
final Directory packageDirectory = fileSystem.systemTempDirectory.childDirectory('cache').childDirectory(name);
|
||||
flutterProject.directory.childFile('.packages')
|
||||
..createSync(recursive: true)
|
||||
..writeAsStringSync('$name:file://${packageDirectory.childFile('lib').uri}\n');
|
||||
packageDirectory.childFile('pubspec.yaml')
|
||||
..createSync(recursive: true)
|
||||
..writeAsStringSync(_pluginYaml);
|
||||
return packageDirectory;
|
||||
return createFakePlugins(fileSystem, <String>['some_plugin'])[0];
|
||||
}
|
||||
|
||||
void createNewJavaPlugin1() {
|
||||
@ -1034,7 +1055,7 @@ flutter:
|
||||
|
||||
expect(pluginMakefile.existsSync(), isTrue);
|
||||
final String contents = pluginMakefile.readAsStringSync();
|
||||
expect(contents, contains('apackage'));
|
||||
expect(contents, contains('some_plugin'));
|
||||
expect(contents, contains('target_link_libraries(\${BINARY_NAME} PRIVATE \${plugin}_plugin)'));
|
||||
expect(contents, contains('list(APPEND PLUGIN_BUNDLED_LIBRARIES \$<TARGET_FILE:\${plugin}_plugin>)'));
|
||||
expect(contents, contains('list(APPEND PLUGIN_BUNDLED_LIBRARIES \${\${plugin}_bundled_libraries})'));
|
||||
@ -1044,6 +1065,32 @@ flutter:
|
||||
FeatureFlags: () => featureFlags,
|
||||
});
|
||||
|
||||
testUsingContext('Generated Linux plugin files sorts by plugin name', () async {
|
||||
when(linuxProject.existsSync()).thenReturn(true);
|
||||
when(featureFlags.isLinuxEnabled).thenReturn(true);
|
||||
when(flutterProject.isModule).thenReturn(false);
|
||||
createFakePlugins(fs, <String>[
|
||||
'plugin_d',
|
||||
'plugin_a',
|
||||
'/local_plugins/plugin_c',
|
||||
'/local_plugins/plugin_b'
|
||||
]);
|
||||
|
||||
await injectPlugins(flutterProject, checkProjects: true);
|
||||
|
||||
final File pluginCmakeFile = linuxProject.generatedPluginCmakeFile;
|
||||
final File pluginRegistrant = linuxProject.managedDirectory.childFile('generated_plugin_registrant.cc');
|
||||
for (final File file in <File>[pluginCmakeFile, pluginRegistrant]) {
|
||||
final String contents = file.readAsStringSync();
|
||||
expect(contents.indexOf('plugin_a'), lessThan(contents.indexOf('plugin_b')));
|
||||
expect(contents.indexOf('plugin_b'), lessThan(contents.indexOf('plugin_c')));
|
||||
expect(contents.indexOf('plugin_c'), lessThan(contents.indexOf('plugin_d')));
|
||||
}
|
||||
}, overrides: <Type, Generator>{
|
||||
FileSystem: () => fs,
|
||||
ProcessManager: () => FakeProcessManager.any(),
|
||||
FeatureFlags: () => featureFlags,
|
||||
});
|
||||
|
||||
testUsingContext('Injecting creates generated Windows registrant', () async {
|
||||
when(windowsProject.existsSync()).thenReturn(true);
|
||||
@ -1119,22 +1166,27 @@ flutter:
|
||||
FeatureFlags: () => featureFlags,
|
||||
});
|
||||
|
||||
testUsingContext('Injecting creates generated Windows plugin CMake file', () async {
|
||||
testUsingContext('Generated Windows plugin files sorts by plugin name', () async {
|
||||
when(windowsProject.existsSync()).thenReturn(true);
|
||||
when(featureFlags.isWindowsEnabled).thenReturn(true);
|
||||
when(flutterProject.isModule).thenReturn(false);
|
||||
createFakePlugin(fs);
|
||||
createFakePlugins(fs, <String>[
|
||||
'plugin_d',
|
||||
'plugin_a',
|
||||
'/local_plugins/plugin_c',
|
||||
'/local_plugins/plugin_b'
|
||||
]);
|
||||
|
||||
await injectPlugins(flutterProject, checkProjects: true);
|
||||
|
||||
final File pluginMakefile = windowsProject.generatedPluginCmakeFile;
|
||||
|
||||
expect(pluginMakefile.existsSync(), isTrue);
|
||||
final String contents = pluginMakefile.readAsStringSync();
|
||||
expect(contents, contains('apackage'));
|
||||
expect(contents, contains('target_link_libraries(\${BINARY_NAME} PRIVATE \${plugin}_plugin)'));
|
||||
expect(contents, contains('list(APPEND PLUGIN_BUNDLED_LIBRARIES \$<TARGET_FILE:\${plugin}_plugin>)'));
|
||||
expect(contents, contains('list(APPEND PLUGIN_BUNDLED_LIBRARIES \${\${plugin}_bundled_libraries})'));
|
||||
final File pluginCmakeFile = windowsProject.generatedPluginCmakeFile;
|
||||
final File pluginRegistrant = windowsProject.managedDirectory.childFile('generated_plugin_registrant.cc');
|
||||
for (final File file in <File>[pluginCmakeFile, pluginRegistrant]) {
|
||||
final String contents = file.readAsStringSync();
|
||||
expect(contents.indexOf('plugin_a'), lessThan(contents.indexOf('plugin_b')));
|
||||
expect(contents.indexOf('plugin_b'), lessThan(contents.indexOf('plugin_c')));
|
||||
expect(contents.indexOf('plugin_c'), lessThan(contents.indexOf('plugin_d')));
|
||||
}
|
||||
}, overrides: <Type, Generator>{
|
||||
FileSystem: () => fs,
|
||||
ProcessManager: () => FakeProcessManager.any(),
|
||||
@ -1183,7 +1235,7 @@ flutter:
|
||||
// refreshPluginsList should call createPluginSymlinks.
|
||||
await refreshPluginsList(flutterProject);
|
||||
|
||||
expect(linuxProject.pluginSymlinkDirectory.childLink('apackage').existsSync(), true);
|
||||
expect(linuxProject.pluginSymlinkDirectory.childLink('some_plugin').existsSync(), true);
|
||||
}, overrides: <Type, Generator>{
|
||||
FileSystem: () => fs,
|
||||
ProcessManager: () => FakeProcessManager.any(),
|
||||
@ -1196,7 +1248,7 @@ flutter:
|
||||
// refreshPluginsList should call createPluginSymlinks.
|
||||
await refreshPluginsList(flutterProject);
|
||||
|
||||
expect(windowsProject.pluginSymlinkDirectory.childLink('apackage').existsSync(), true);
|
||||
expect(windowsProject.pluginSymlinkDirectory.childLink('some_plugin').existsSync(), true);
|
||||
}, overrides: <Type, Generator>{
|
||||
FileSystem: () => fs,
|
||||
ProcessManager: () => FakeProcessManager.any(),
|
||||
@ -1282,8 +1334,8 @@ flutter:
|
||||
await refreshPluginsList(flutterProject);
|
||||
|
||||
final List<Link> links = <Link>[
|
||||
linuxProject.pluginSymlinkDirectory.childLink('apackage'),
|
||||
windowsProject.pluginSymlinkDirectory.childLink('apackage'),
|
||||
linuxProject.pluginSymlinkDirectory.childLink('some_plugin'),
|
||||
windowsProject.pluginSymlinkDirectory.childLink('some_plugin'),
|
||||
];
|
||||
for (final Link link in links) {
|
||||
link.deleteSync();
|
||||
@ -1318,7 +1370,26 @@ flutter:
|
||||
}
|
||||
|
||||
test('validatePubspecForPlugin works', () async {
|
||||
_createPubspecFile(_pluginYaml);
|
||||
const String pluginYaml = '''
|
||||
flutter:
|
||||
plugin:
|
||||
platforms:
|
||||
ios:
|
||||
pluginClass: SomePlugin
|
||||
macos:
|
||||
pluginClass: SomePlugin
|
||||
windows:
|
||||
pluginClass: SomePlugin
|
||||
linux:
|
||||
pluginClass: SomePlugin
|
||||
web:
|
||||
pluginClass: SomePlugin
|
||||
fileName: lib/SomeFile.dart
|
||||
android:
|
||||
pluginClass: SomePlugin
|
||||
package: AndroidPackage
|
||||
''';
|
||||
_createPubspecFile(pluginYaml);
|
||||
validatePubspecForPlugin(projectDir: projectDir.absolute.path, pluginClass: 'SomePlugin', expectedPlatforms: <String>[
|
||||
'ios', 'macos', 'windows', 'linux', 'android', 'web'
|
||||
], androidIdentifier: 'AndroidPackage', webFileName: 'lib/SomeFile.dart');
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user