Skip to content

Commit fbf63c9

Browse files
authored
fix(dart_frog_cli): kill process on windows on sigint (#222)
1 parent 1570c72 commit fbf63c9

File tree

2 files changed

+66
-6
lines changed

2 files changed

+66
-6
lines changed

packages/dart_frog_cli/lib/src/commands/dev/dev.dart

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -161,14 +161,14 @@ class DevCommand extends DartFrogCommand {
161161
}
162162

163163
Future<void> _killProcess(io.Process process) async {
164-
process.kill();
165164
if (_isWindows) {
166165
final result = await _runProcess(
167166
'taskkill',
168167
['/F', '/T', '/PID', '${process.pid}'],
169168
);
170-
_exit(result.exitCode);
169+
return _exit(result.exitCode);
171170
}
171+
process.kill();
172172
}
173173
}
174174

packages/dart_frog_cli/test/src/commands/dev/dev_test.dart

Lines changed: 64 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -420,7 +420,6 @@ void main() {
420420
when(() => process.stdout).thenAnswer((_) => const Stream.empty());
421421
when(() => process.stderr).thenAnswer((_) => const Stream.empty());
422422
when(() => process.pid).thenReturn(processId);
423-
when(() => process.kill()).thenReturn(true);
424423
when(() => processResult.exitCode).thenReturn(ExitCode.success.code);
425424
when(
426425
() => directoryWatcher.events,
@@ -454,10 +453,12 @@ void main() {
454453
['taskkill', '/F', '/T', '/PID', '$processId']
455454
]),
456455
);
457-
verify(() => process.kill()).called(1);
456+
verifyNever(() => process.kill());
458457
});
459458

460-
test('kills process if error occurs before hotreload is enabled', () async {
459+
test(
460+
'kills process if error occurs before '
461+
'hotreload is enabled on windows', () async {
461462
const processId = 42;
462463
final generatorHooks = _MockGeneratorHooks();
463464
final processRunCalls = <List<String>>[];
@@ -487,7 +488,6 @@ void main() {
487488
(_) => Stream.value(utf8.encode('oops')),
488489
);
489490
when(() => process.pid).thenReturn(processId);
490-
when(() => process.kill()).thenReturn(true);
491491
when(() => processResult.exitCode).thenReturn(ExitCode.success.code);
492492
when(
493493
() => directoryWatcher.events,
@@ -521,6 +521,66 @@ void main() {
521521
['taskkill', '/F', '/T', '/PID', '$processId']
522522
]),
523523
);
524+
verifyNever(() => process.kill());
525+
});
526+
527+
test(
528+
'kills process if error occurs before '
529+
'hotreload is enabled on non-windows', () async {
530+
final generatorHooks = _MockGeneratorHooks();
531+
final processRunCalls = <List<String>>[];
532+
int? exitCode;
533+
when(
534+
() => generatorHooks.preGen(
535+
vars: any(named: 'vars'),
536+
workingDirectory: any(named: 'workingDirectory'),
537+
onVarsChanged: any(named: 'onVarsChanged'),
538+
),
539+
).thenAnswer((invocation) async {
540+
(invocation.namedArguments[const Symbol('onVarsChanged')] as Function(
541+
Map<String, dynamic> vars,
542+
))
543+
.call(<String, dynamic>{});
544+
});
545+
when(
546+
() => generator.generate(
547+
any(),
548+
vars: any(named: 'vars'),
549+
fileConflictResolution: FileConflictResolution.overwrite,
550+
),
551+
).thenAnswer((_) async => []);
552+
when(() => generator.hooks).thenReturn(generatorHooks);
553+
when(() => process.stdout).thenAnswer((_) => const Stream.empty());
554+
when(() => process.stderr).thenAnswer(
555+
(_) => Stream.value(utf8.encode('oops')),
556+
);
557+
when(() => process.kill()).thenReturn(true);
558+
when(
559+
() => directoryWatcher.events,
560+
).thenAnswer((_) => StreamController<WatchEvent>().stream);
561+
when(() => sigint.watch()).thenAnswer((_) => const Stream.empty());
562+
command = DevCommand(
563+
logger: logger,
564+
directoryWatcher: (_) => directoryWatcher,
565+
generator: (_) async => generator,
566+
exit: (code) => exitCode = code,
567+
runProcess: (String executable, List<String> arguments) async {
568+
processRunCalls.add([executable, ...arguments]);
569+
return processResult;
570+
},
571+
startProcess: (
572+
String executable,
573+
List<String> arguments, {
574+
bool runInShell = false,
575+
}) async {
576+
return process;
577+
},
578+
sigint: sigint,
579+
)..testArgResults = argResults;
580+
command.run().ignore();
581+
await untilCalled(() => process.kill());
582+
expect(exitCode, equals(1));
583+
expect(processRunCalls, isEmpty);
524584
verify(() => process.kill()).called(1);
525585
});
526586
});

0 commit comments

Comments
 (0)