Skip to content

Commit 8962739

Browse files
authored
fix(cli-hooks): stop app process if the start hook exits (#2474)
1 parent 0de0777 commit 8962739

File tree

3 files changed

+77
-0
lines changed

3 files changed

+77
-0
lines changed

.changeset/neat-toys-wonder.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
"@slack/cli-hooks": patch
3+
---
4+
5+
fix(cli-hooks): stop app process if the start hook exits
6+
7+
Fixes a CLI [issue](https://github.com/slackapi/slack-cli/issues/128) where daemon app processes were spawned if the CLI was exited without being interrupted.

packages/cli-hooks/src/start.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,17 @@ export default function start(cwd) {
3535
app.on('close', (code) => {
3636
process.exit(code);
3737
});
38+
process.on('exit', () => {
39+
app.kill();
40+
});
41+
process.on('SIGINT', () => {
42+
app.kill('SIGINT');
43+
process.exit();
44+
});
45+
process.on('SIGTERM', () => {
46+
app.kill('SIGTERM');
47+
process.exit();
48+
});
3849
}
3950

4051
/**

packages/cli-hooks/src/start.spec.js

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import start from './start.js';
1818
* @property {MockStreams} stdout - Output logged to standard output streams.
1919
* @property {MockStreams} stderr - Output logged to standard error streams.
2020
* @property {sinon.SinonStub} on - A fallback event to mock the spawn closure.
21+
* @property {sinon.SinonStub} [kill] - Forced exit code of a spawned process.
2122
*/
2223

2324
describe('start implementation', async () => {
@@ -41,6 +42,7 @@ describe('start implementation', async () => {
4142
stdout: { on: sinon.stub(), setEncoding: () => {} },
4243
stderr: { on: sinon.stub() },
4344
on: sinon.stub(),
45+
kill: sinon.stub(),
4446
};
4547
spawnStub = sinon.stub(childProcess, 'spawn').returns(/** @type {any} */ (mockSpawnProcess));
4648
process.env.SLACK_CLI_XAPP = 'xapp-example';
@@ -126,4 +128,61 @@ describe('start implementation', async () => {
126128
});
127129
});
128130
});
131+
132+
describe('stops the app process', () => {
133+
/** @type {sinon.SinonStub} */
134+
let processStub;
135+
/** @type {sinon.SinonStub} */
136+
let exitStub;
137+
/** @type {MockSpawnProcess} */
138+
let mockSpawnProcess;
139+
/** @type {sinon.SinonStub} */
140+
let spawnStub;
141+
142+
beforeEach(() => {
143+
process.env.SLACK_CLI_CUSTOM_FILE_PATH = 'app.js';
144+
processStub = sinon.stub(process, 'on');
145+
exitStub = sinon.stub(process, 'exit');
146+
mockSpawnProcess = {
147+
stdout: { on: sinon.stub(), setEncoding: () => {} },
148+
stderr: { on: sinon.stub() },
149+
on: sinon.stub(),
150+
kill: sinon.stub(),
151+
};
152+
spawnStub = sinon.stub(childProcess, 'spawn').returns(/** @type {any} */ (mockSpawnProcess));
153+
});
154+
155+
afterEach(() => {
156+
sinon.restore();
157+
process.env.SLACK_CLI_CUSTOM_FILE_PATH = undefined;
158+
});
159+
160+
it('stops app process on hook exit', () => {
161+
start('./');
162+
assert.ok(spawnStub.called);
163+
assert.ok(spawnStub.calledWith('node', [path.resolve('app.js')]));
164+
const handler = processStub.getCalls().find((call) => call.args[0] === 'exit')?.args[1];
165+
assert.ok(handler, 'exit handler should be registered');
166+
handler();
167+
assert.ok(mockSpawnProcess.kill?.called);
168+
});
169+
170+
it('stops app process on hook SIGINT', () => {
171+
start('./');
172+
const handler = processStub.getCalls().find((call) => call.args[0] === 'SIGINT')?.args[1];
173+
assert.ok(handler, 'SIGINT handler should be registered');
174+
handler();
175+
assert.ok(mockSpawnProcess.kill?.calledWith('SIGINT'));
176+
assert.ok(exitStub.called);
177+
});
178+
179+
it('stops app process on hook SIGTERM', () => {
180+
start('./');
181+
const handler = processStub.getCalls().find((call) => call.args[0] === 'SIGTERM')?.args[1];
182+
assert.ok(handler, 'SIGTERM handler should be registered');
183+
handler();
184+
assert.ok(mockSpawnProcess.kill?.calledWith('SIGTERM'));
185+
assert.ok(exitStub.called);
186+
});
187+
});
129188
});

0 commit comments

Comments
 (0)