From 11ca0f1ada94c98ba6ceefddaba78a30ec11d44c Mon Sep 17 00:00:00 2001 From: John McCutchan Date: Thu, 10 Nov 2016 08:31:11 -0800 Subject: [PATCH] Support caching host filesystem symlink targets to speedup DevFS updates (#6798) --- packages/flutter_tools/lib/executable.dart | 2 ++ packages/flutter_tools/lib/src/devfs.dart | 32 ++++++++++++++++++---- 2 files changed, 28 insertions(+), 6 deletions(-) diff --git a/packages/flutter_tools/lib/executable.dart b/packages/flutter_tools/lib/executable.dart index bdcfc302910..54e0c81ae27 100644 --- a/packages/flutter_tools/lib/executable.dart +++ b/packages/flutter_tools/lib/executable.dart @@ -35,6 +35,7 @@ import 'src/commands/test.dart'; import 'src/commands/trace.dart'; import 'src/commands/update_packages.dart'; import 'src/commands/upgrade.dart'; +import 'src/devfs.dart'; import 'src/device.dart'; import 'src/doctor.dart'; import 'src/globals.dart'; @@ -83,6 +84,7 @@ Future main(List args) async { // Initialize globals. context[Logger] = new StdoutLogger(); context[DeviceManager] = new DeviceManager(); + context[DevFSConfig] = new DevFSConfig(); Doctor.initGlobal(); dynamic result = await runner.run(args); diff --git a/packages/flutter_tools/lib/src/devfs.dart b/packages/flutter_tools/lib/src/devfs.dart index 10012326a9d..02490750d55 100644 --- a/packages/flutter_tools/lib/src/devfs.dart +++ b/packages/flutter_tools/lib/src/devfs.dart @@ -8,6 +8,7 @@ import 'dart:io'; import 'package:path/path.dart' as path; +import 'base/context.dart'; import 'build_info.dart'; import 'dart/package_map.dart'; import 'asset.dart'; @@ -16,6 +17,13 @@ import 'vmservice.dart'; typedef void DevFSProgressReporter(int progress, int max); +class DevFSConfig { + /// Should DevFS assume that symlink targets are stable? + bool cacheSymlinks = false; +} + +DevFSConfig get devFSConfig => context[DevFSConfig]; + // A file that has been added to a DevFS. class DevFSEntry { DevFSEntry(this.devicePath, this.file) @@ -30,10 +38,13 @@ class DevFSEntry { String get assetPath => bundleEntry.archivePath; final FileSystemEntity file; + FileSystemEntity _linkTarget; FileStat _fileStat; // When we scanned for files, did this still exist? bool _exists = false; DateTime get lastModified => _fileStat?.modified; + bool get _isSourceEntry => file == null; + bool get _isAssetEntry => bundleEntry != null; bool get stillExists { if (_isSourceEntry) return true; @@ -67,19 +78,28 @@ class DevFSEntry { void _stat() { if (_isSourceEntry) return; + if (_linkTarget != null) { + // Stat the cached symlink target. + _fileStat = _linkTarget.statSync(); + return; + } _fileStat = file.statSync(); if (_fileStat.type == FileSystemEntityType.LINK) { - // Stat the link target. + // Resolve, stat, and maybe cache the symlink target. String resolved = file.resolveSymbolicLinksSync(); - _fileStat = FileStat.statSync(resolved); + FileSystemEntity linkTarget = new File(resolved); + // Stat the link target. + _fileStat = linkTarget.statSync(); + if (devFSConfig.cacheSymlinks) { + _linkTarget = linkTarget; + } } } - bool get _isSourceEntry => file == null; - - bool get _isAssetEntry => bundleEntry != null; - File _getFile() { + if (_linkTarget != null) { + return _linkTarget; + } if (file is Link) { // The link target. return new File(file.resolveSymbolicLinksSync());