mirror of
https://github.com/flutter/flutter
synced 2024-10-13 03:32:55 +00:00
[flutter_tools] check for Runner.sln when parsing for plugins (#57392)
Throw a toolExit if the windows plugin logic runs on an invalid windows project. Update the supported project check to validate the existence of a Runner.sln file
This commit is contained in:
parent
6294dd59bb
commit
b19b744bb7
|
@ -1084,7 +1084,7 @@ Future<void> injectPlugins(FlutterProject project, {bool checkProjects = false})
|
|||
if (featureFlags.isWindowsEnabled && project.windows.existsSync()) {
|
||||
await _writeWindowsPluginFiles(project, plugins);
|
||||
|
||||
final List<Plugin>nativePlugins = _filterNativePlugins(plugins, WindowsPlugin.kConfigKey);
|
||||
final List<Plugin> nativePlugins = _filterNativePlugins(plugins, WindowsPlugin.kConfigKey);
|
||||
await VisualStudioSolutionUtils(project: project.windows, fileSystem: globals.fs).updatePlugins(nativePlugins);
|
||||
}
|
||||
for (final XcodeBasedProject subproject in <XcodeBasedProject>[project.ios, project.macos]) {
|
||||
|
|
|
@ -1006,7 +1006,7 @@ class WindowsProject extends FlutterProjectPlatform {
|
|||
String get pluginConfigKey => WindowsPlugin.kConfigKey;
|
||||
|
||||
@override
|
||||
bool existsSync() => _editableDirectory.existsSync();
|
||||
bool existsSync() => _editableDirectory.existsSync() && solutionFile.existsSync();
|
||||
|
||||
Directory get _editableDirectory => project.directory.childDirectory('windows');
|
||||
|
||||
|
|
|
@ -66,6 +66,12 @@ class VisualStudioSolutionUtils {
|
|||
/// dependencies to include [plugins], removing any previous plugins from the
|
||||
/// solution.
|
||||
Future<void> updatePlugins(List<Plugin> plugins) async {
|
||||
if (!_project.solutionFile.existsSync()) {
|
||||
throwToolExit(
|
||||
'Attempted to update Windows plugins on a project that does not '
|
||||
'support Windows.',
|
||||
);
|
||||
}
|
||||
final String solutionContent = await _project.solutionFile.readAsString();
|
||||
|
||||
// Map of GUID to name for the current plugin list.
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
// found in the LICENSE file.
|
||||
|
||||
import 'package:file/memory.dart';
|
||||
import 'package:file_testing/file_testing.dart';
|
||||
import 'package:flutter_tools/src/base/file_system.dart';
|
||||
import 'package:flutter_tools/src/convert.dart';
|
||||
import 'package:flutter_tools/src/plugins.dart';
|
||||
|
@ -26,15 +27,15 @@ void main() {
|
|||
const String pluginCGuid = '8E010714-28FF-416A-BC6F-9CDE336A02A7';
|
||||
const String pluginDGuid = '304F1860-7E8B-4C99-8E1D-F5E55259F5C3';
|
||||
|
||||
FileSystem fs;
|
||||
FileSystem fileSystem;
|
||||
MockWindowsProject project;
|
||||
|
||||
setUp(() async {
|
||||
fs = MemoryFileSystem(style: FileSystemStyle.windows);
|
||||
fileSystem = MemoryFileSystem.test(style: FileSystemStyle.windows);
|
||||
|
||||
project = MockWindowsProject();
|
||||
when(project.pluginConfigKey).thenReturn('windows');
|
||||
final Directory windowsManagedDirectory = fs.directory('C:').childDirectory('windows').childDirectory('flutter');
|
||||
final Directory windowsManagedDirectory = fileSystem.directory('C:').childDirectory('windows').childDirectory('flutter');
|
||||
when(project.solutionFile).thenReturn(windowsManagedDirectory.parent.childFile('Runner.sln'));
|
||||
when(project.vcprojFile).thenReturn(windowsManagedDirectory.parent.childFile('Runner.vcxproj'));
|
||||
when(project.pluginSymlinkDirectory).thenReturn(windowsManagedDirectory.childDirectory('ephemeral').childDirectory('.plugin_symlinks'));
|
||||
|
@ -239,13 +240,13 @@ EndGlobal''');
|
|||
final List<Plugin> plugins = <Plugin>[
|
||||
getMockPlugin('plugin_a', pluginAGuid),
|
||||
];
|
||||
await VisualStudioSolutionUtils(project: project, fileSystem: fs).updatePlugins(plugins);
|
||||
await VisualStudioSolutionUtils(project: project, fileSystem: fileSystem).updatePlugins(plugins);
|
||||
|
||||
final String newSolutionContents = project.solutionFile.readAsStringSync();
|
||||
|
||||
// Check for:
|
||||
// - Plugin project.
|
||||
final String pluginSubpath = fs.path.join('Flutter', 'ephemeral', '.plugin_symlinks', 'plugin_a', 'windows', 'plugin.vcxproj');
|
||||
final String pluginSubpath = fileSystem.path.join('Flutter', 'ephemeral', '.plugin_symlinks', 'plugin_a', 'windows', 'plugin.vcxproj');
|
||||
expect(newSolutionContents, contains('Project("{$solutionTypeGuidVcxproj}") = "plugin_a", "$pluginSubpath", "{$pluginAGuid}"'));
|
||||
// - A dependency on the plugin project (from the Runner).
|
||||
expect(newSolutionContents, contains('{$pluginAGuid} = {$pluginAGuid}'));
|
||||
|
@ -268,7 +269,7 @@ EndGlobal''');
|
|||
getMockPlugin('plugin_a', pluginAGuid),
|
||||
getMockPlugin('plugin_c', pluginCGuid),
|
||||
];
|
||||
await VisualStudioSolutionUtils(project: project, fileSystem: fs).updatePlugins(plugins);
|
||||
await VisualStudioSolutionUtils(project: project, fileSystem: fileSystem).updatePlugins(plugins);
|
||||
|
||||
final String newSolutionContents = project.solutionFile.readAsStringSync();
|
||||
|
||||
|
@ -289,7 +290,7 @@ EndGlobal''');
|
|||
|
||||
final List<Plugin> plugins = <Plugin>[
|
||||
];
|
||||
await VisualStudioSolutionUtils(project: project, fileSystem: fs).updatePlugins( plugins);
|
||||
await VisualStudioSolutionUtils(project: project, fileSystem: fileSystem).updatePlugins( plugins);
|
||||
|
||||
final String newSolutionContents = project.solutionFile.readAsStringSync();
|
||||
|
||||
|
@ -309,7 +310,7 @@ EndGlobal''');
|
|||
getMockPlugin('plugin_c', pluginCGuid),
|
||||
getMockPlugin('plugin_d', pluginDGuid),
|
||||
];
|
||||
await VisualStudioSolutionUtils(project: project, fileSystem: fs).updatePlugins(plugins);
|
||||
await VisualStudioSolutionUtils(project: project, fileSystem: fileSystem).updatePlugins(plugins);
|
||||
|
||||
final String newSolutionContents = project.solutionFile.readAsStringSync();
|
||||
|
||||
|
@ -326,7 +327,7 @@ EndGlobal''');
|
|||
|
||||
// All the plugin D values should be added:
|
||||
// - Plugin project.
|
||||
final String pluginSubpath = fs.path.join('Flutter', 'ephemeral', '.plugin_symlinks', 'plugin_d', 'windows', 'plugin.vcxproj');
|
||||
final String pluginSubpath = fileSystem.path.join('Flutter', 'ephemeral', '.plugin_symlinks', 'plugin_d', 'windows', 'plugin.vcxproj');
|
||||
expect(newSolutionContents, contains('Project("{$solutionTypeGuidVcxproj}") = "plugin_d", "$pluginSubpath", "{$pluginDGuid}"'));
|
||||
// - A dependency on the plugin project (from the Runner).
|
||||
expect(newSolutionContents, contains('{$pluginDGuid} = {$pluginDGuid}'));
|
||||
|
@ -350,7 +351,7 @@ EndGlobal''');
|
|||
getMockPlugin('plugin_c', pluginCGuid),
|
||||
getMockPlugin('plugin_d', pluginDGuid),
|
||||
];
|
||||
await VisualStudioSolutionUtils(project: project, fileSystem: fs).updatePlugins(plugins);
|
||||
await VisualStudioSolutionUtils(project: project, fileSystem: fileSystem).updatePlugins(plugins);
|
||||
|
||||
final String newSolutionContents = project.solutionFile.readAsStringSync();
|
||||
// There should only be:
|
||||
|
@ -375,7 +376,7 @@ EndGlobal''');
|
|||
getMockPlugin('plugin_c', pluginCGuid),
|
||||
getMockPlugin('plugin_d', pluginDGuid),
|
||||
];
|
||||
await VisualStudioSolutionUtils(project: project, fileSystem: fs).updatePlugins(plugins);
|
||||
await VisualStudioSolutionUtils(project: project, fileSystem: fileSystem).updatePlugins(plugins);
|
||||
|
||||
final String newSolutionContents = project.solutionFile.readAsStringSync();
|
||||
// Plugin A should still be before Flutter Build in the Runner dependencies.
|
||||
|
@ -393,7 +394,7 @@ EndGlobal''');
|
|||
writeSolutionWithPlugins();
|
||||
|
||||
final List<Plugin> plugins = <Plugin>[];
|
||||
await VisualStudioSolutionUtils(project: project, fileSystem: fs).updatePlugins(plugins);
|
||||
await VisualStudioSolutionUtils(project: project, fileSystem: fileSystem).updatePlugins(plugins);
|
||||
|
||||
// Visual Studio expects sln files to start with a BOM.
|
||||
final List<int> solutionStartingBytes = project.solutionFile.readAsBytesSync().take(3).toList();
|
||||
|
@ -408,7 +409,7 @@ EndGlobal''');
|
|||
getMockPlugin('plugin_a', pluginAGuid),
|
||||
getMockPlugin('plugin_b', pluginBGuid),
|
||||
];
|
||||
await VisualStudioSolutionUtils(project: project, fileSystem: fs).updatePlugins(plugins);
|
||||
await VisualStudioSolutionUtils(project: project, fileSystem: fileSystem).updatePlugins(plugins);
|
||||
|
||||
final String newSolutionContents = project.solutionFile.readAsStringSync();
|
||||
// Project, EndProject, Global, and EndGlobal should be at the start of
|
||||
|
@ -431,9 +432,21 @@ EndGlobal''');
|
|||
final List<Plugin> plugins = <Plugin>[
|
||||
getMockPlugin('plugin_a', pluginAGuid, createProject: false),
|
||||
];
|
||||
expect(() => VisualStudioSolutionUtils(project: project, fileSystem: fs).updatePlugins(plugins),
|
||||
expect(() => VisualStudioSolutionUtils(project: project, fileSystem: fileSystem).updatePlugins(plugins),
|
||||
throwsToolExit());
|
||||
});
|
||||
|
||||
test('A Windows project with a missing Runner.sln file throws a ToolExit', () async {
|
||||
final MockWindowsProject windowsProject = MockWindowsProject();
|
||||
final File file = fileSystem.file('does_not_exist');
|
||||
|
||||
expect(file, isNot(exists));
|
||||
|
||||
when(windowsProject.solutionFile).thenReturn(file);
|
||||
|
||||
expect(() async => await VisualStudioSolutionUtils(project: project, fileSystem: fileSystem)
|
||||
.updatePlugins(<Plugin>[]), throwsToolExit());
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -66,6 +66,7 @@ void main() {
|
|||
globals.fs.file('pubspec.yaml').createSync();
|
||||
globals.fs.file('.packages').createSync();
|
||||
globals.fs.directory('windows').createSync();
|
||||
globals.fs.file(globals.fs.path.join('windows', 'Runner.sln')).createSync();
|
||||
final FlutterProject flutterProject = FlutterProject.current();
|
||||
|
||||
expect(WindowsDevice().isSupportedForProject(flutterProject), true);
|
||||
|
@ -85,6 +86,18 @@ void main() {
|
|||
ProcessManager: () => FakeProcessManager.any(),
|
||||
});
|
||||
|
||||
testUsingContext('isSupportedForProject is false with no Runner.sln', () async {
|
||||
globals.fs.file('pubspec.yaml').createSync();
|
||||
globals.fs.file('.packages').createSync();
|
||||
globals.fs.directory('windows').createSync();
|
||||
final FlutterProject flutterProject = FlutterProject.current();
|
||||
|
||||
expect(WindowsDevice().isSupportedForProject(flutterProject), false);
|
||||
}, overrides: <Type, Generator>{
|
||||
FileSystem: () => MemoryFileSystem(),
|
||||
ProcessManager: () => FakeProcessManager.any(),
|
||||
});
|
||||
|
||||
testUsingContext('executablePathForDevice uses the correct package executable', () async {
|
||||
final MockWindowsApp mockApp = MockWindowsApp();
|
||||
const String debugPath = 'debug/executable';
|
||||
|
|
Loading…
Reference in a new issue