From 4553a835c6c014455a57dcaf7b0eadd414ad2e57 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gergely=20Cs=C3=A9csey?= Date: Fri, 27 Feb 2026 16:29:12 +0000 Subject: [PATCH] Always kill PM2 daemon when running site stop --all When no sites are running, the daemon should still be killed to prevent stale processes from persisting, particularly in development where the daemon may retain hardcoded paths to node_modules that become invalid. --- apps/cli/commands/site/stop.ts | 4 +++- apps/cli/commands/site/tests/stop.test.ts | 10 ++++------ package-lock.json | 10 ---------- 3 files changed, 7 insertions(+), 17 deletions(-) diff --git a/apps/cli/commands/site/stop.ts b/apps/cli/commands/site/stop.ts index dcab8a32be..323ed339bc 100644 --- a/apps/cli/commands/site/stop.ts +++ b/apps/cli/commands/site/stop.ts @@ -73,7 +73,9 @@ export async function runCommand( } if ( ! runningSites.length ) { - logger.reportSuccess( __( 'No sites are currently running' ) ); + await killDaemonAndChildrenAndExitProcess( () => { + logger.reportSuccess( __( 'No sites are currently running' ) ); + } ); return; } diff --git a/apps/cli/commands/site/tests/stop.test.ts b/apps/cli/commands/site/tests/stop.test.ts index 849c7d7de7..83d930928b 100644 --- a/apps/cli/commands/site/tests/stop.test.ts +++ b/apps/cli/commands/site/tests/stop.test.ts @@ -256,17 +256,16 @@ describe( 'CLI: studio site stop --all', () => { } ); describe( 'Success Cases', () => { - it( 'should handle empty sites list', async () => { + it( 'should kill daemon even with empty sites list', async () => { vi.mocked( readAppdata ).mockResolvedValue( { sites: [], snapshots: [] } ); await runCommand( Mode.STOP_ALL_SITES, undefined, false ); expect( connect ).toHaveBeenCalled(); - expect( killDaemonAndChildrenAndExitProcess ).not.toHaveBeenCalled(); - expect( disconnect ).toHaveBeenCalled(); + expect( killDaemonAndChildrenAndExitProcess ).toHaveBeenCalledTimes( 1 ); } ); - it( 'should skip if no sites are running', async () => { + it( 'should kill daemon even if no sites are running', async () => { vi.mocked( readAppdata ).mockResolvedValue( { sites: testSites, snapshots: [] } ); vi.mocked( isServerRunning ).mockResolvedValue( undefined ); @@ -275,9 +274,8 @@ describe( 'CLI: studio site stop --all', () => { expect( connect ).toHaveBeenCalled(); expect( isServerRunning ).toHaveBeenCalledTimes( 3 ); - expect( killDaemonAndChildrenAndExitProcess ).not.toHaveBeenCalled(); + expect( killDaemonAndChildrenAndExitProcess ).toHaveBeenCalledTimes( 1 ); expect( clearSiteLatestCliPid ).not.toHaveBeenCalled(); - expect( disconnect ).toHaveBeenCalled(); } ); it( 'should handle single site', async () => { diff --git a/package-lock.json b/package-lock.json index 26db054a6d..4185fc6e5b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9159,7 +9159,6 @@ "os": [ "darwin" ], - "peer": true, "engines": { "node": ">=10" } @@ -9176,7 +9175,6 @@ "os": [ "darwin" ], - "peer": true, "engines": { "node": ">=10" } @@ -9193,7 +9191,6 @@ "os": [ "linux" ], - "peer": true, "engines": { "node": ">=10" } @@ -9210,7 +9207,6 @@ "os": [ "linux" ], - "peer": true, "engines": { "node": ">=10" } @@ -9227,7 +9223,6 @@ "os": [ "linux" ], - "peer": true, "engines": { "node": ">=10" } @@ -9244,7 +9239,6 @@ "os": [ "linux" ], - "peer": true, "engines": { "node": ">=10" } @@ -9261,7 +9255,6 @@ "os": [ "linux" ], - "peer": true, "engines": { "node": ">=10" } @@ -9278,7 +9271,6 @@ "os": [ "win32" ], - "peer": true, "engines": { "node": ">=10" } @@ -9295,7 +9287,6 @@ "os": [ "win32" ], - "peer": true, "engines": { "node": ">=10" } @@ -9312,7 +9303,6 @@ "os": [ "win32" ], - "peer": true, "engines": { "node": ">=10" }