Skip to content

Commit 3ee3873

Browse files
authored
Merge pull request #1031 from thefrontside/tm/no-sigterm-windows
Do not bind SIGTERM in Windows
2 parents c6a57bc + 9e96b4b commit 3ee3873

File tree

7 files changed

+94
-34
lines changed

7 files changed

+94
-34
lines changed

.gitattributes

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
# Set default line ending behavior
2+
* text=auto
3+
4+
# Explicitly set line endings for text files
5+
*.ts text eol=lf
6+
*.mjs text eol=lf
7+
*.js text eol=lf
8+
*.json text eol=lf
9+
*.md text eol=lf
10+
*.yml text eol=lf
11+
*.yaml text eol=lf
12+
13+
# Binary files
14+
*.png binary
15+
*.jpg binary
16+
*.jpeg binary
17+
*.gif binary
18+
*.ico binary
19+
*.woff binary
20+
*.woff2 binary

.github/workflows/verify.yaml

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,11 @@ permissions:
1111

1212
jobs:
1313
test:
14-
runs-on: ubuntu-latest
14+
strategy:
15+
matrix:
16+
os: [ubuntu-latest, macos-latest, windows-latest]
17+
18+
runs-on: ${{ matrix.os }}
1519

1620
steps:
1721
- name: checkout
@@ -34,7 +38,14 @@ jobs:
3438
- name: lint
3539
run: deno lint
3640

37-
- name: test
41+
- name: test (Windows)
42+
if: runner.os == 'Windows'
43+
run: deno task test
44+
shell: cmd
45+
46+
- name: test (Unix)
47+
if: runner.os != 'Windows'
3848
run: deno task test
49+
3950
- name: test:node
4051
run: deno task test:node

deno.json

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
},
88
"lock": false,
99
"tasks": {
10-
"test": "deno test --allow-run=deno",
10+
"test": "deno test --allow-run --allow-ffi",
1111
"test:node": "deno task build:npm 0.0.0 && node test/main/node.mjs hello world",
1212
"build:jsr": "deno run -A tasks/build-jsr.ts",
1313
"build:npm": "deno run -A tasks/build-npm.ts"
@@ -20,7 +20,8 @@
2020
"build",
2121
"website",
2222
"www",
23-
"packages"
23+
"packages",
24+
"docs/*.ts"
2425
]
2526
},
2627
"fmt": {
@@ -46,5 +47,12 @@
4647
"dom",
4748
"dom.iterable"
4849
]
50+
},
51+
"imports": {
52+
"@deno/dnt": "jsr:@deno/[email protected]",
53+
"ctrlc-windows": "npm:[email protected]",
54+
"@std/testing": "jsr:@std/testing@^1",
55+
"@std/expect": "jsr:@std/expect@^1",
56+
"ts-expect": "npm:[email protected]"
4957
}
5058
}

lib/main.ts

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -83,11 +83,18 @@ export async function main(
8383
hardexit = (status) => Deno.exit(status);
8484
try {
8585
Deno.addSignalListener("SIGINT", interrupt.SIGINT);
86-
Deno.addSignalListener("SIGTERM", interrupt.SIGTERM);
86+
/**
87+
* Windows only supports ctrl-c (SIGINT), ctrl-break (SIGBREAK), and ctrl-close (SIGUP)
88+
*/
89+
if (Deno.build.os !== "windows") {
90+
Deno.addSignalListener("SIGTERM", interrupt.SIGTERM);
91+
}
8792
yield* body(Deno.args.slice());
8893
} finally {
8994
Deno.removeSignalListener("SIGINT", interrupt.SIGINT);
90-
Deno.removeSignalListener("SIGTERM", interrupt.SIGTERM);
95+
if (Deno.build.os !== "windows") {
96+
Deno.removeSignalListener("SIGTERM", interrupt.SIGTERM);
97+
}
9198
}
9299
},
93100
*node() {
@@ -99,11 +106,15 @@ export async function main(
99106
hardexit = (status) => process.exit(status);
100107
try {
101108
process.on("SIGINT", interrupt.SIGINT);
102-
process.on("SIGTERM", interrupt.SIGTERM);
109+
if (process.platform !== "win32") {
110+
process.on("SIGTERM", interrupt.SIGTERM);
111+
}
103112
yield* body(process.argv.slice(2));
104113
} finally {
105114
process.off("SIGINT", interrupt.SIGINT);
106-
process.off("SIGTERM", interrupt.SIGINT);
115+
if (process.platform !== "win32") {
116+
process.off("SIGTERM", interrupt.SIGINT);
117+
}
107118
}
108119
},
109120
*browser() {

tasks/build-npm.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { build, emptyDir } from "jsr:@deno/dnt@0.41.3";
1+
import { build, emptyDir } from "@deno/dnt";
22

33
const outDir = "./build/npm";
44

test/main.test.ts

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -21,24 +21,26 @@ describe("main", () => {
2121
});
2222
});
2323

24-
it("gracefully shuts down on SIGTERM", async () => {
25-
await run(function* () {
26-
let daemon = yield* useCommand("deno", {
27-
stdout: "piped",
28-
args: ["run", "test/main/ok.daemon.ts"],
29-
});
30-
let stdout = yield* buffer(daemon.stdout);
31-
yield* detect(stdout, "started");
24+
if (Deno.build.os !== "windows") {
25+
it("gracefully shuts down on SIGTERM", async () => {
26+
await run(function* () {
27+
let daemon = yield* useCommand("deno", {
28+
stdout: "piped",
29+
args: ["run", "test/main/ok.daemon.ts"],
30+
});
31+
let stdout = yield* buffer(daemon.stdout);
32+
yield* detect(stdout, "started");
3233

33-
daemon.kill("SIGTERM");
34+
daemon.kill("SIGTERM");
3435

35-
let status = yield* daemon.status;
36+
let status = yield* daemon.status;
3637

37-
expect(status.code).toBe(143);
38+
expect(status.code).toBe(143);
3839

39-
yield* detect(stdout, "gracefully stopped");
40+
yield* detect(stdout, "gracefully stopped");
41+
});
4042
});
41-
});
43+
}
4244

4345
it("exits gracefully on explicit exit()", async () => {
4446
await run(function* () {

test/suite.ts

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,9 @@
1-
export * from "https://deno.land/[email protected]/testing/bdd.ts";
2-
export { expect } from "jsr:@std/expect";
3-
export { expectType } from "https://esm.sh/ts-expect@1.3.0?pin=v123";
1+
export * from "@std/testing/bdd";
2+
export { expect } from "@std/expect";
3+
export { expectType } from "ts-expect";
44

5-
import {
6-
action,
7-
call,
8-
type Operation,
9-
resource,
10-
sleep,
11-
spawn,
12-
} from "../mod.ts";
5+
import { ctrlc } from "ctrlc-windows";
6+
import { action, type Operation, resource, sleep, spawn } from "../mod.ts";
137

148
declare global {
159
interface Promise<T> extends Operation<T> {}
@@ -83,12 +77,26 @@ export function useCommand(
8377
return resource(function* (provide) {
8478
let command = new Deno.Command(cmd, options);
8579
let process = command.spawn();
80+
81+
if (Deno.build.os === "windows") {
82+
// Wrap the kill method to use ctrlc-windows on Windows
83+
// See: https://github.com/denoland/deno/issues/29599
84+
const originalKill = process.kill.bind(process);
85+
process.kill = (signal) => {
86+
if (signal === "SIGINT") {
87+
ctrlc(process.pid);
88+
} else {
89+
originalKill(signal);
90+
}
91+
};
92+
}
93+
8694
try {
8795
yield* provide(process);
8896
} finally {
8997
try {
9098
process.kill("SIGINT");
91-
yield* call(process.status);
99+
yield* process.status;
92100
} catch (error) {
93101
// if the process already quit, then this error is expected.
94102
// unfortunately there is no way (I know of) to check this

0 commit comments

Comments
 (0)