Unverified Commit 485ed2f6 authored by Greg Spencer's avatar Greg Spencer Committed by GitHub

Fix DevFS to understand missing files in _stat() (#22844)

Fixes #22451
parent fb7a5937
...@@ -83,20 +83,32 @@ class DevFSFileContent extends DevFSContent { ...@@ -83,20 +83,32 @@ class DevFSFileContent extends DevFSContent {
void _stat() { void _stat() {
if (_linkTarget != null) { if (_linkTarget != null) {
// Stat the cached symlink target. // Stat the cached symlink target.
_fileStat = _linkTarget.statSync(); final FileStat fileStat = _linkTarget.statSync();
return; if (fileStat.type == FileSystemEntityType.notFound) {
_linkTarget = null;
} else {
_fileStat = fileStat;
return;
}
} }
_fileStat = file.statSync(); final FileStat fileStat = file.statSync();
if (_fileStat.type == FileSystemEntityType.link) { _fileStat = fileStat.type == FileSystemEntityType.notFound ? null : fileStat;
if (_fileStat != null && _fileStat.type == FileSystemEntityType.link) {
// Resolve, stat, and maybe cache the symlink target. // Resolve, stat, and maybe cache the symlink target.
final String resolved = file.resolveSymbolicLinksSync(); final String resolved = file.resolveSymbolicLinksSync();
final FileSystemEntity linkTarget = fs.file(resolved); final FileSystemEntity linkTarget = fs.file(resolved);
// Stat the link target. // Stat the link target.
_fileStat = linkTarget.statSync(); final FileStat fileStat = linkTarget.statSync();
if (devFSConfig.cacheSymlinks) { if (fileStat.type == FileSystemEntityType.notFound) {
_fileStat = null;
_linkTarget = null;
} else if (devFSConfig.cacheSymlinks) {
_linkTarget = linkTarget; _linkTarget = linkTarget;
} }
} }
if (_fileStat == null) {
printError('Unable to get status of file "${file.path}": file not found.');
}
} }
@override @override
...@@ -106,21 +118,29 @@ class DevFSFileContent extends DevFSContent { ...@@ -106,21 +118,29 @@ class DevFSFileContent extends DevFSContent {
bool get isModified { bool get isModified {
final FileStat _oldFileStat = _fileStat; final FileStat _oldFileStat = _fileStat;
_stat(); _stat();
return _oldFileStat == null || _fileStat.modified.isAfter(_oldFileStat.modified); if (_oldFileStat == null && _fileStat == null)
return false;
return _oldFileStat == null || _fileStat == null || _fileStat.modified.isAfter(_oldFileStat.modified);
} }
@override @override
bool isModifiedAfter(DateTime time) { bool isModifiedAfter(DateTime time) {
final FileStat _oldFileStat = _fileStat; final FileStat _oldFileStat = _fileStat;
_stat(); _stat();
return _oldFileStat == null || time == null || _fileStat.modified.isAfter(time); if (_oldFileStat == null && _fileStat == null)
return false;
return time == null
|| _oldFileStat == null
|| _fileStat == null
|| _fileStat.modified.isAfter(time);
} }
@override @override
int get size { int get size {
if (_fileStat == null) if (_fileStat == null)
_stat(); _stat();
return _fileStat.size; // Can still be null if the file wasn't found.
return _fileStat?.size ?? 0;
} }
@override @override
......
...@@ -62,6 +62,36 @@ void main() { ...@@ -62,6 +62,36 @@ void main() {
expect(content.isModified, isTrue); expect(content.isModified, isTrue);
expect(content.isModified, isFalse); expect(content.isModified, isFalse);
}); });
testUsingContext('file', () async {
final File file = fs.file(filePath);
final DevFSFileContent content = DevFSFileContent(file);
expect(content.isModified, isFalse);
expect(content.isModified, isFalse);
file.parent.createSync(recursive: true);
file.writeAsBytesSync(<int>[1, 2, 3]);
final DateTime fiveSecondsAgo = DateTime.now().subtract(Duration(seconds:5));
expect(content.isModifiedAfter(fiveSecondsAgo), isTrue);
expect(content.isModifiedAfter(fiveSecondsAgo), isTrue);
expect(content.isModifiedAfter(null), isTrue);
file.writeAsBytesSync(<int>[2, 3, 4]);
expect(content.fileDependencies, <String>[filePath]);
expect(content.isModified, isTrue);
expect(content.isModified, isFalse);
expect(await content.contentsAsBytes(), <int>[2, 3, 4]);
updateFileModificationTime(file.path, fiveSecondsAgo, 0);
expect(content.isModified, isFalse);
expect(content.isModified, isFalse);
file.deleteSync();
expect(content.isModified, isTrue);
expect(content.isModified, isFalse);
expect(content.isModified, isFalse);
}, overrides: <Type, Generator>{
FileSystem: () => fs,
});
}); });
group('devfs local', () { group('devfs local', () {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment