refactor: Replace exec with spawn (#8510)

This commit is contained in:
Gal Zahavi
2025-09-16 12:03:17 -07:00
committed by GitHub
parent a015ea203f
commit 986b9fe7e9
11 changed files with 330 additions and 295 deletions
+33 -46
View File
@@ -4,7 +4,7 @@
* SPDX-License-Identifier: Apache-2.0
*/
import { execSync, spawn } from 'node:child_process';
import { execSync, spawn, spawnSync } from 'node:child_process';
export type EditorType =
| 'vscode'
@@ -173,57 +173,44 @@ export async function openDiff(
}
try {
switch (editor) {
case 'vscode':
case 'vscodium':
case 'windsurf':
case 'cursor':
case 'zed':
// Use spawn for GUI-based editors to avoid blocking the entire process
return new Promise((resolve, reject) => {
const childProcess = spawn(diffCommand.command, diffCommand.args, {
stdio: 'inherit',
shell: true,
});
const isTerminalEditor = ['vim', 'emacs', 'neovim'].includes(editor);
childProcess.on('close', (code) => {
if (code === 0) {
resolve();
} else {
reject(new Error(`${editor} exited with code ${code}`));
}
});
childProcess.on('error', (error) => {
reject(error);
});
if (isTerminalEditor) {
try {
const result = spawnSync(diffCommand.command, diffCommand.args, {
stdio: 'inherit',
});
case 'vim':
case 'emacs':
case 'neovim': {
// Use execSync for terminal-based editors
const command =
process.platform === 'win32'
? `${diffCommand.command} ${diffCommand.args.join(' ')}`
: `${diffCommand.command} ${diffCommand.args.map((arg) => `"${arg}"`).join(' ')}`;
try {
execSync(command, {
stdio: 'inherit',
encoding: 'utf8',
});
} catch (e) {
console.error('Error in onEditorClose callback:', e);
} finally {
onEditorClose();
if (result.error) {
throw result.error;
}
break;
if (result.status !== 0) {
throw new Error(`${editor} exited with code ${result.status}`);
}
} finally {
onEditorClose();
}
default:
throw new Error(`Unsupported editor: ${editor}`);
return;
}
return new Promise<void>((resolve, reject) => {
const childProcess = spawn(diffCommand.command, diffCommand.args, {
stdio: 'inherit',
});
childProcess.on('close', (code) => {
if (code === 0) {
resolve();
} else {
reject(new Error(`${editor} exited with code ${code}`));
}
});
childProcess.on('error', (error) => {
reject(error);
});
});
} catch (error) {
console.error(error);
throw error;
}
}