findChanges method
Find all changes if a FileCollection has been modified since the last time someone checked with this method.
The key
argument is used to consider whether changes have happened
since last time the check was made with the exact same key.
Returns an empty Stream if the FileCollection is empty.
Implementation
Stream<FileChange> findChanges(FileCollection fileCollection,
{String key = ''}) async* {
logger.finest(
() => 'Checking if $fileCollection with key="$key" has changed');
if (fileCollection.isEmpty) return;
// if the cache is empty, avoid checking anything and report everything as added
if (await isEmptyDir(_hashesDir)) {
logger.fine('No hashes in the cache '
'(${path.join(Directory.current.path, _hashesDir)}), '
'reporting all as changed');
yield* _reportAllAdded(fileCollection);
return;
}
Set<String> visitedEntities = {};
// visit all entities that currently exist
await for (final entity in fileCollection.resolve()) {
if (visitedEntities.add(entity.path)) {
final changes = await entity.use((file) async* {
final change = await _hasFileChanged(file, key: key);
if (change != null) yield FileChange(file, change);
}, (dir, children) async* {
final dirChange = await _hasDirChanged(dir, children, key: key);
if (dirChange != null && dirChange.kind == ChangeKind.modified) {
// file additions/modifications are reported elsehwere,
// but only here can we find deleted files.
yield* _deletedFiles(
dirChange.newContents!, dirChange.oldContents!);
}
if (dirChange != null) {
yield FileChange(dir, dirChange.kind);
}
});
yield* changes;
}
}
// visit entities that do not exist but may have existed before
for (final file in fileCollection.files.where(visitedEntities.add)) {
final fileEntity = File(file);
final change = await _hasFileChanged(fileEntity, key: key);
if (change != null) {
yield FileChange(fileEntity, change);
}
}
for (final dir in fileCollection.directories
.map((e) => e.path)
.where(visitedEntities.add)) {
// this dir doesn't exist, otherwise it would've been visited earlier
final dirEntity = Directory(dir);
final change = await _hasDirChanged(dirEntity, const [], key: key);
if (change != null) {
yield FileChange(dirEntity, change.kind);
}
}
}