Use ErrorHandlingFileSystem.deleteIfExists when deleting .plugin_symlinks (#151073)

Fixes https://github.com/flutter/flutter/issues/137168.
This commit is contained in:
Andrew Kolos 2024-07-02 11:46:22 -07:00 committed by GitHub
parent acb41f3174
commit af913a75b5
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 75 additions and 6 deletions

View File

@ -95,9 +95,9 @@ class ErrorHandlingFileSystem extends ForwardingFileSystem {
}
if (entity.existsSync()) {
throwToolExit(
'The Flutter tool tried to delete the file or directory ${entity.path} but was '
"unable to. This may be due to the file and/or project's location on a read-only "
'volume. Consider relocating the project and trying again',
'Unable to delete file or directory at "${entity.path}". '
'This may be due to the project being in a read-only '
'volume. Consider relocating the project and trying again.',
);
}
}

View File

@ -966,9 +966,9 @@ void handleSymlinkException(FileSystemException e, {
///
/// If [force] is true, the directory will be created only if missing.
void _createPlatformPluginSymlinks(Directory symlinkDirectory, List<Object?>? platformPlugins, {bool force = false}) {
if (force && symlinkDirectory.existsSync()) {
if (force) {
// Start fresh to avoid stale links.
symlinkDirectory.deleteSync(recursive: true);
ErrorHandlingFileSystem.deleteIfExists(symlinkDirectory, recursive: true);
}
symlinkDirectory.createSync(recursive: true);
if (platformPlugins == null) {

View File

@ -909,7 +909,7 @@ void main() {
handler.addError(webCacheDirectory, FileSystemOp.delete, const FileSystemException('', '', OSError('', 2)));
await expectLater(() => webSdk.updateInner(artifactUpdater, fileSystem, FakeOperatingSystemUtils()), throwsToolExit(
message: RegExp('The Flutter tool tried to delete the file or directory cache/bin/cache/flutter_web_sdk but was unable to'),
message: RegExp('Unable to delete file or directory at "cache/bin/cache/flutter_web_sdk"'),
));
});

View File

@ -3,10 +3,12 @@
// found in the LICENSE file.
import 'dart:convert';
import 'dart:io';
import 'package:file/file.dart';
import 'package:file/memory.dart';
import 'package:file_testing/file_testing.dart';
import 'package:flutter_tools/src/base/error_handling_io.dart';
import 'package:flutter_tools/src/base/os.dart';
import 'package:flutter_tools/src/base/platform.dart';
import 'package:flutter_tools/src/base/time.dart';
@ -1752,6 +1754,73 @@ The Flutter Preview device does not support the following plugins from your pubs
);
});
});
testUsingContext('exits tool when deleting .plugin_symlinks fails', () async {
final FakeFlutterProject flutterProject = FakeFlutterProject()
..directory = globals.fs.currentDirectory.childDirectory('app');
final FakeFlutterManifest flutterManifest = FakeFlutterManifest();
final Directory windowsManagedDirectory = flutterProject.directory
.childDirectory('windows')
.childDirectory('flutter');
final FakeWindowsProject windowsProject = FakeWindowsProject()
..managedDirectory = windowsManagedDirectory
..cmakeFile = windowsManagedDirectory.parent.childFile('CMakeLists.txt')
..generatedPluginCmakeFile =
windowsManagedDirectory.childFile('generated_plugins.mk')
..pluginSymlinkDirectory = windowsManagedDirectory
.childDirectory('ephemeral')
.childDirectory('.plugin_symlinks')
..exists = true;
flutterProject
..manifest = flutterManifest
..flutterPluginsFile =
flutterProject.directory.childFile('.flutter-plugins')
..flutterPluginsDependenciesFile =
flutterProject.directory.childFile('.flutter-plugins-dependencies')
..windows = windowsProject;
flutterProject.directory.childFile('.packages').createSync(recursive: true);
createPluginSymlinks(
flutterProject,
force: true,
featureFlagsOverride: TestFeatureFlags(isWindowsEnabled: true),
);
expect(
() => createPluginSymlinks(
flutterProject,
force: true,
featureFlagsOverride: TestFeatureFlags(isWindowsEnabled: true),
),
throwsToolExit(
message: RegExp('Unable to delete file or directory at '
r'"C:\\app\\windows\\flutter\\ephemeral\\\.plugin_symlinks"')),
);
}, overrides: <Type, Generator>{
FileSystem: () {
final FileExceptionHandler handle = FileExceptionHandler();
final ErrorHandlingFileSystem fileSystem = ErrorHandlingFileSystem(
platform: FakePlatform(),
delegate: MemoryFileSystem.test(
style: FileSystemStyle.windows,
opHandle: handle.opHandle,
),
);
const String symlinkDirectoryPath = r'C:\app\windows\flutter\ephemeral\.plugin_symlinks';
handle.addError(
fileSystem.directory(symlinkDirectoryPath),
FileSystemOp.delete,
const PathNotFoundException(
symlinkDirectoryPath,
OSError('The system cannot find the path specified.', 3),
),
);
return fileSystem;
},
ProcessManager: () => FakeProcessManager.empty(),
});
}
class FakeFlutterManifest extends Fake implements FlutterManifest {