diff --git a/packages/flutter_tools/lib/src/commands/clean.dart b/packages/flutter_tools/lib/src/commands/clean.dart index be698a9eaed..791e2c1d67d 100644 --- a/packages/flutter_tools/lib/src/commands/clean.dart +++ b/packages/flutter_tools/lib/src/commands/clean.dart @@ -83,7 +83,13 @@ class CleanCommand extends FlutterCommand { @visibleForTesting void deleteFile(FileSystemEntity file) { - if (!file.existsSync()) { + // This will throw a FileSystemException if the directory is missing permissions. + try { + if (!file.existsSync()) { + return; + } + } on FileSystemException catch (err) { + printError('Cannot clean ${file.path}.\n$err'); return; } final Status deletionStatus = logger.startProgress('Deleting ${file.basename}...', timeout: timeoutConfiguration.fastOperation); diff --git a/packages/flutter_tools/test/commands.shard/hermetic/clean_test.dart b/packages/flutter_tools/test/commands.shard/hermetic/clean_test.dart index 188f5dc2c05..59c4ce5f39d 100644 --- a/packages/flutter_tools/test/commands.shard/hermetic/clean_test.dart +++ b/packages/flutter_tools/test/commands.shard/hermetic/clean_test.dart @@ -80,6 +80,24 @@ void main() { Logger: () => BufferLogger(), Xcode: () => mockXcode, }); + + testUsingContext('$CleanCommand handles missing permissions;', () async { + when(mockXcode.isInstalledAndMeetsVersionCheck).thenReturn(false); + + final MockFile mockFile = MockFile(); + when(mockFile.existsSync()).thenThrow(const FileSystemException('OS error: Access Denied')); + when(mockFile.path).thenReturn('foo.dart'); + + final BufferLogger logger = context.get(); + final CleanCommand command = CleanCommand(); + command.deleteFile(mockFile); + expect(logger.errorText, contains('Cannot clean foo.dart')); + verifyNever(mockFile.deleteSync(recursive: true)); + }, overrides: { + Platform: () => windowsPlatform, + Logger: () => BufferLogger(), + Xcode: () => mockXcode, + }); } test1();