diff --git a/cli/util/file_watcher.rs b/cli/util/file_watcher.rs index d80664dfa1f6da..2df445840c3c8e 100644 --- a/cli/util/file_watcher.rs +++ b/cli/util/file_watcher.rs @@ -15,6 +15,7 @@ use deno_core::futures::FutureExt; use deno_core::parking_lot::Mutex; use deno_lib::util::result::js_error_downcast_ref; use deno_runtime::fmt_errors::format_js_error; +use deno_signals; use log::info; use notify::Error as NotifyError; use notify::RecommendedWatcher; @@ -374,6 +375,9 @@ where select! { _ = receiver_future => {}, + _ = deno_signals::ctrl_c() => { + return Ok(()); + }, _ = restart_rx.recv() => { print_after_restart(); continue; @@ -407,6 +411,9 @@ where // watched paths has changed. select! { _ = receiver_future => {}, + _ = deno_signals::ctrl_c() => { + return Ok(()); + }, _ = restart_rx.recv() => { print_after_restart(); continue; diff --git a/tests/unit/process_test.ts b/tests/unit/process_test.ts index 17589d8581413f..7b82fe5ba782f5 100644 --- a/tests/unit/process_test.ts +++ b/tests/unit/process_test.ts @@ -583,7 +583,7 @@ Deno.test( permissions: { run: true, read: true, write: true }, ignore: Deno.build.os === "windows", }, - async function non_existent_cwd(): Promise { + async function nonExistentCwd(): Promise { // @ts-ignore `Deno.run()` was soft-removed in Deno 2. const p = Deno.run({ cmd: [ @@ -610,3 +610,70 @@ Deno.test( assertStringIncludes(stderr, "failed resolving cwd:"); }, ); + +Deno.test( + { + permissions: { run: true, read: true, write: true }, + ignore: Deno.build.os === "windows", + }, + async function runWatchAndSigint(): Promise { + const tempDir = await Deno.makeTempDir(); + const tempFile = `${tempDir}/temp_watch_file.ts`; + await Deno.writeTextFile(tempFile, "console.log('watch test');"); + + // @ts-ignore `Deno.run()` was soft-removed in Deno 2. + const p = Deno.run({ + cmd: ["deno", "run", "--watch", tempFile], + stdout: "piped", + stderr: "null", + }); + + Deno.kill(p.pid, "SIGINT"); + const data = new Uint8Array(10); + const out = await p.stdout.read(data); + assertEquals(out, null); + p.stdout.close(); + p.close(); + + await Deno.remove(tempFile); + await Deno.remove(tempDir); + }, +); + +Deno.test( + { + permissions: { run: true, read: true, write: true }, + ignore: Deno.build.os === "windows", + }, + async function runWatchWaitForSigint(): Promise { + const tempDir = await Deno.makeTempDir(); + const tempFile = `${tempDir}/temp_watch_file.ts`; + await Deno.writeTextFile( + tempFile, + `Deno.addSignalListener("SIGINT", () => { + console.log("SIGINT"); + ac.abort(); +}); + +Deno.serve({ signal: ac.signal }, () => new Response("Hello World")); +`, + ); + + // @ts-ignore `Deno.run()` was soft-removed in Deno 2. + const p = Deno.run({ + cmd: ["deno", "run", "--watch", tempFile], + stdout: "piped", + stderr: "null", + }); + + Deno.kill(p.pid, "SIGINT"); + const data = new Uint8Array(10); + const out = await p.stdout.read(data); + assertEquals(out, null); + p.stdout.close(); + p.close(); + + await Deno.remove(tempFile); + await Deno.remove(tempDir); + }, +);