diff --git a/packages/flutter_tools/lib/src/base/error_handling_io.dart b/packages/flutter_tools/lib/src/base/error_handling_io.dart index d158748d17..eb3202951b 100644 --- a/packages/flutter_tools/lib/src/base/error_handling_io.dart +++ b/packages/flutter_tools/lib/src/base/error_handling_io.dart @@ -289,10 +289,7 @@ class ErrorHandlingFile // Next check if the destination file can be written. If not, bail through // error handling. _runSync( - () { - resultFile.createSync(recursive: true); - resultFile.openSync(mode: FileMode.writeOnly).closeSync(); - }, + () => resultFile.createSync(recursive: true), platform: _platform, failureMessage: 'Flutter failed to copy $path to $newPath due to destination location error' ); diff --git a/packages/flutter_tools/test/general.shard/base/error_handling_io_test.dart b/packages/flutter_tools/test/general.shard/base/error_handling_io_test.dart index af3e16631c..67615e4a7d 100644 --- a/packages/flutter_tools/test/general.shard/base/error_handling_io_test.dart +++ b/packages/flutter_tools/test/general.shard/base/error_handling_io_test.dart @@ -817,12 +817,12 @@ void main() { expect(() => fileSystem.file('source').copySync('dest'), throwsToolExit()); }); - testWithoutContext('copySync handles error if openSync on destination file fails', () { + testWithoutContext('copySync handles error if createSync on destination file fails', () { final MockFile source = MockFile(); final MockFile dest = MockFile(); when(source.openSync(mode: anyNamed('mode'))) .thenReturn(MockRandomAccessFile()); - when(dest.openSync(mode: anyNamed('mode'))) + when(dest.createSync(recursive: anyNamed('recursive'))) .thenThrow(const FileSystemException('', '', OSError('', eaccess))); when(mockFileSystem.file('source')).thenReturn(source); when(mockFileSystem.file('dest')).thenReturn(dest); @@ -830,6 +830,24 @@ void main() { expect(() => fileSystem.file('source').copySync('dest'), throwsToolExit()); }); + // dart:io is able to clobber read-only files. + testWithoutContext('copySync will copySync even if the destination is not writable', () { + final MockFile source = MockFile(); + final MockFile dest = MockFile(); + + when(source.copySync(any)).thenReturn(dest); + when(mockFileSystem.file('source')).thenReturn(source); + when(source.openSync(mode: anyNamed('mode'))) + .thenReturn(MockRandomAccessFile()); + when(mockFileSystem.file('dest')).thenReturn(dest); + when(dest.openSync(mode: FileMode.writeOnly)) + .thenThrow(const FileSystemException('', '', OSError('', eaccess))); + + fileSystem.file('source').copySync('dest'); + + verify(source.copySync('dest')).called(1); + }); + testWithoutContext('copySync will copySync if there are no exceptions', () { final MockFile source = MockFile(); final MockFile dest = MockFile();