[devFS] Use URI to represent paths on device (#8446) * [devFS] Use URI to represent paths on device Previosuly, regular file paths in the format of the host platform were used to represent paths on device. That works when host and device share the same (POSIX) file path format. With a Windows host, this breaks. URIs are the solution as they are platform independent and the VM service on the device already interpreted the file paths as URIs anyways. * review comments * switch to file paths * fix tests on Windows * review comments
diff --git a/packages/flutter_tools/test/devfs_test.dart b/packages/flutter_tools/test/devfs_test.dart index 25c168b..1b90421 100644 --- a/packages/flutter_tools/test/devfs_test.dart +++ b/packages/flutter_tools/test/devfs_test.dart
@@ -4,7 +4,6 @@ import 'dart:async'; import 'dart:convert'; -import 'dart:io' as io; import 'package:flutter_tools/src/asset.dart'; import 'package:flutter_tools/src/base/io.dart'; @@ -70,7 +69,7 @@ File file = fs.file(fs.path.join(basePath, filePath)); await file.parent.create(recursive: true); file.writeAsBytesSync(<int>[1, 2, 3]); - _packages['my_project'] = 'lib'; + _packages['my_project'] = fs.path.toUri('lib'); // simulate package await _createPackage('somepkg', 'somefile.txt'); @@ -82,20 +81,20 @@ int bytes = await devFS.update(); devFSOperations.expectMessages(<String>[ - 'writeFile test ${fs.path.join('lib', 'foo.txt')}', - 'writeFile test ${fs.path.join('packages', 'somepkg', 'somefile.txt')}', 'writeFile test .packages', + 'writeFile test lib/foo.txt', + 'writeFile test packages/somepkg/somefile.txt', ]); expect(devFS.assetPathsToEvict, isEmpty); List<String> packageSpecOnDevice = LineSplitter.split(UTF8.decode( - await devFSOperations.devicePathToContent['.packages'].contentsAsBytes() + await devFSOperations.devicePathToContent[fs.path.toUri('.packages')].contentsAsBytes() )).toList(); expect(packageSpecOnDevice, - unorderedEquals(<String>['my_project:lib', 'somepkg:packages/somepkg']) + unorderedEquals(<String>['my_project:lib/', 'somepkg:packages/somepkg/']) ); - expect(bytes, 46); + expect(bytes, 48); }); testUsingContext('add new file to local file system', () async { File file = fs.file(fs.path.join(basePath, filePath2)); @@ -103,7 +102,7 @@ file.writeAsBytesSync(<int>[1, 2, 3, 4, 5, 6, 7]); int bytes = await devFS.update(); devFSOperations.expectMessages(<String>[ - 'writeFile test ${fs.path.join('foo', 'bar.txt')}', + 'writeFile test foo/bar.txt', ]); expect(devFS.assetPathsToEvict, isEmpty); expect(bytes, 7); @@ -120,7 +119,7 @@ await file.writeAsBytes(<int>[1, 2, 3, 4, 5, 6]); bytes = await devFS.update(); devFSOperations.expectMessages(<String>[ - 'writeFile test ${fs.path.join('lib', 'foo.txt')}', + 'writeFile test lib/foo.txt', ]); expect(devFS.assetPathsToEvict, isEmpty); expect(bytes, 6); @@ -130,7 +129,7 @@ await file.delete(); int bytes = await devFS.update(); devFSOperations.expectMessages(<String>[ - 'deleteFile test ${fs.path.join('lib', 'foo.txt')}', + 'deleteFile test lib/foo.txt', ]); expect(devFS.assetPathsToEvict, isEmpty); expect(bytes, 0); @@ -140,10 +139,10 @@ int bytes = await devFS.update(); devFSOperations.expectMessages(<String>[ 'writeFile test .packages', - 'writeFile test ${fs.path.join('packages', 'newpkg', 'anotherfile.txt')}', + 'writeFile test packages/newpkg/anotherfile.txt', ]); expect(devFS.assetPathsToEvict, isEmpty); - expect(bytes, 66); + expect(bytes, 69); }); testUsingContext('add an asset bundle', () async { assetBundle.entries['a.txt'] = new DevFSStringContent('abc'); @@ -207,7 +206,7 @@ devFSOperations.expectMessages(<String>['destroy test']); expect(devFS.assetPathsToEvict, isEmpty); }); - }, skip: io.Platform.isWindows); + }); group('devfs remote', () { MockVMService vmService; @@ -240,11 +239,11 @@ int bytes = await devFS.update(); vmService.expectMessages(<String>[ 'writeFile test .packages', - 'writeFile test ${fs.path.join('lib', 'foo.txt')}', - 'writeFile test ${fs.path.join('packages', 'somepkg', 'somefile.txt')}', + 'writeFile test lib/foo.txt', + 'writeFile test packages/somepkg/somefile.txt', ]); expect(devFS.assetPathsToEvict, isEmpty); - expect(bytes, 46); + expect(bytes, 48); }, timeout: const Timeout(const Duration(seconds: 5))); testUsingContext('delete dev file system', () async { @@ -252,7 +251,7 @@ vmService.expectMessages(<String>['_deleteDevFS {fsName: test}']); expect(devFS.assetPathsToEvict, isEmpty); }); - }, skip: io.Platform.isWindows); + }); } class MockVMService extends BasicMock implements VMService { @@ -321,7 +320,7 @@ final List<Directory> _tempDirs = <Directory>[]; -final Map <String, String> _packages = <String, String>{}; +final Map <String, Uri> _packages = <String, Uri>{}; Directory _newTempDir() { Directory tempDir = fs.systemTempDirectory.createTempSync('devfs${_tempDirs.length}'); @@ -340,12 +339,14 @@ File pkgFile = fs.file(fs.path.join(pkgTempDir.path, pkgName, 'lib', pkgFileName)); await pkgFile.parent.create(recursive: true); pkgFile.writeAsBytesSync(<int>[11, 12, 13]); - _packages[pkgName] = pkgFile.parent.path; + _packages[pkgName] = fs.path.toUri(pkgFile.parent.path); StringBuffer sb = new StringBuffer(); - _packages.forEach((String pkgName, String pkgPath) { - sb.writeln('$pkgName:$pkgPath'); + _packages.forEach((String pkgName, Uri pkgUri) { + sb.writeln('$pkgName:$pkgUri'); }); fs.file(fs.path.join(_tempDirs[0].path, '.packages')).writeAsStringSync(sb.toString()); } -String _inAssetBuildDirectory(String filename) => fs.path.join(getAssetBuildDirectory(), filename); +String _inAssetBuildDirectory(String filename) { + return '${fs.path.toUri(getAssetBuildDirectory()).path}/$filename'; +}