summaryrefslogtreecommitdiff
path: root/packages/core/src
diff options
context:
space:
mode:
authorTommaso Sciortino <[email protected]>2025-07-31 17:27:07 -0700
committerGitHub <[email protected]>2025-08-01 00:27:07 +0000
commita3a432e3cf5d2de084cecb684229b14ccd4969ac (patch)
tree4df9837a8f74b05d019564922dd3e57684967e86 /packages/core/src
parent6f7beb414cae67df59aea3f8a3e99389c3a82aec (diff)
Fix bug executing commands in windows whose flags contain spaces (#5317)
Diffstat (limited to 'packages/core/src')
-rw-r--r--packages/core/src/services/shellExecutionService.test.ts30
-rw-r--r--packages/core/src/services/shellExecutionService.ts11
2 files changed, 26 insertions, 15 deletions
diff --git a/packages/core/src/services/shellExecutionService.test.ts b/packages/core/src/services/shellExecutionService.test.ts
index 4d1655a2..cfce08d2 100644
--- a/packages/core/src/services/shellExecutionService.test.ts
+++ b/packages/core/src/services/shellExecutionService.test.ts
@@ -91,9 +91,9 @@ describe('ShellExecutionService', () => {
});
expect(mockSpawn).toHaveBeenCalledWith(
- 'bash',
- ['-c', 'ls -l'],
- expect.any(Object),
+ 'ls -l',
+ [],
+ expect.objectContaining({ shell: 'bash' }),
);
expect(result.exitCode).toBe(0);
expect(result.signal).toBeNull();
@@ -334,23 +334,31 @@ describe('ShellExecutionService', () => {
describe('Platform-Specific Behavior', () => {
it('should use cmd.exe on Windows', async () => {
mockPlatform.mockReturnValue('win32');
- await simulateExecution('dir', (cp) => cp.emit('exit', 0, null));
+ await simulateExecution('dir "foo bar"', (cp) =>
+ cp.emit('exit', 0, null),
+ );
expect(mockSpawn).toHaveBeenCalledWith(
- 'cmd.exe',
- ['/c', 'dir'],
- expect.objectContaining({ detached: false }),
+ 'dir "foo bar"',
+ [],
+ expect.objectContaining({
+ shell: true,
+ detached: false,
+ }),
);
});
it('should use bash and detached process group on Linux', async () => {
mockPlatform.mockReturnValue('linux');
- await simulateExecution('ls', (cp) => cp.emit('exit', 0, null));
+ await simulateExecution('ls "foo bar"', (cp) => cp.emit('exit', 0, null));
expect(mockSpawn).toHaveBeenCalledWith(
- 'bash',
- ['-c', 'ls'],
- expect.objectContaining({ detached: true }),
+ 'ls "foo bar"',
+ [],
+ expect.objectContaining({
+ shell: 'bash',
+ detached: true,
+ }),
);
});
});
diff --git a/packages/core/src/services/shellExecutionService.ts b/packages/core/src/services/shellExecutionService.ts
index 0f0002cd..d1126a7d 100644
--- a/packages/core/src/services/shellExecutionService.ts
+++ b/packages/core/src/services/shellExecutionService.ts
@@ -89,13 +89,16 @@ export class ShellExecutionService {
abortSignal: AbortSignal,
): ShellExecutionHandle {
const isWindows = os.platform() === 'win32';
- const shell = isWindows ? 'cmd.exe' : 'bash';
- const shellArgs = [isWindows ? '/c' : '-c', commandToExecute];
- const child = spawn(shell, shellArgs, {
+ const child = spawn(commandToExecute, [], {
cwd,
stdio: ['ignore', 'pipe', 'pipe'],
- detached: !isWindows, // Use process groups on non-Windows for robust killing
+ // Use bash unless in Windows (since it doesn't support bash).
+ // For windows, just use the default.
+ shell: isWindows ? true : 'bash',
+ // Use process groups on non-Windows for robust killing.
+ // Windows process termination is handled by `taskkill /t`.
+ detached: !isWindows,
env: {
...process.env,
GEMINI_CLI: '1',