waitForChange method
Implementation
Future<({bool exit})> waitForChange() async {
final (configPath, exitCode) = await getConfigPath();
if (exitCode != null) {
return (exit: true);
} else if (configPath == null) {
return (exit: true);
}
final settings = await getSettings(configPath);
final barrels = await getBarrels(settings);
final directories = barrels.map((e) => e.dirSettings.dirPath).toSet();
final events = {
FileSystemEvent.delete,
FileSystemEvent.create,
FileSystemEvent.move
};
String eventType(int event) {
switch (event) {
case FileSystemEvent.create:
return 'create';
case FileSystemEvent.delete:
return 'delete';
case FileSystemEvent.move:
return 'move';
case FileSystemEvent.modify:
return 'modify';
case FileSystemEvent.all:
return 'all';
default:
return 'unknown';
}
}
final barrelPaths = barrels.map((e) => e.barrelFile).toSet();
final fileModifications = directories.map((dir) {
StreamSubscription<void>? subscription;
final controller = StreamController<void>.broadcast(
onCancel: () async {
await subscription?.cancel();
},
);
final watcher =
fs.directory(dir).watch(recursive: true, events: FileSystemEvent.all);
subscription = watcher.listen((event) {
logger.detail('\n');
logger.detail('File event: ${eventType(event.type)}');
logger.detail('File changed: ${event.path}');
if (barrelPaths.contains(event.path)) {
return;
}
if (!events.contains(event.type)) {
return;
}
controller.add(null);
});
return controller.stream;
}).toList();
void writeWaitingMessage() {
final waitingMessage = '''
${yellow.wrap('Waiting for changes...')}
${darkGray.wrap('Press `Ctrl+C` or `q` to exit')}
${darkGray.wrap('Press `r` to rebuild')}
''';
logger.write(waitingMessage);
}
final fileChangeCompleter = Completer<({bool exit})?>();
final input = keyPressListener?.listenToKeystrokes(
onExit: () {
fileChangeCompleter.complete((exit: true));
},
onRebuild: () {
fileChangeCompleter.complete();
},
onEscape: writeWaitingMessage,
);
StreamSubscription<void>? inputSubscription;
inputSubscription = input?.listen((_) {});
final fileChangeListener = StreamGroup(fileModifications)
.merge()
.listen((_) => fileChangeCompleter.complete());
writeWaitingMessage();
final result = await fileChangeCompleter.future;
await fileChangeListener.cancel();
inputSubscription?.cancel();
final shouldExit = result?.exit ?? false;
if (shouldExit) {
return (exit: true);
}
final changeMessage = '''
${yellow.wrap('Changes detected')}
''';
logger.write(changeMessage);
return (exit: false);
}