Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 23 additions & 23 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

16 changes: 7 additions & 9 deletions src/shared/utils/ddev-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -83,10 +83,7 @@ export class DdevUtils {
*/
public static isToolInstalled(toolName: string, workspacePath: string): boolean {
try {
execSync(`ddev exec ${toolName} --version`, {
cwd: workspacePath,
stdio: 'ignore'
});
this.execDdev(`${toolName} --version`, workspacePath);
return true;
} catch (error) {
return false;
Expand All @@ -112,10 +109,7 @@ export class DdevUtils {

// Try to run the tool
try {
execSync(`ddev exec ${toolName} --version`, {
cwd: workspacePath,
stdio: 'ignore'
});
this.execDdev(`${toolName} --version`, workspacePath);

return {
isValid: true
Expand Down Expand Up @@ -188,7 +182,11 @@ export class DdevUtils {
*/
public static execDdev(command: string, workspacePath: string, allowedExitCodes: number[] = [0]): string {
try {
return execSync(`ddev exec ${command}`, {
// Wrap command in bash -c to allow setting environment variables (specifically disabling Xdebug)
// This fixes issues where Xdebug causes the command to hang or run slowly
// We use single quotes for the bash command and escape any single quotes in the original command
const escapedCommand = command.replace(/'/g, "'\\''");
return execSync(`ddev exec bash -c 'XDEBUG_MODE=off ${escapedCommand}'`, {
cwd: workspacePath,
encoding: 'utf-8'
});
Expand Down
24 changes: 24 additions & 0 deletions src/test/ddev-utils.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -138,4 +138,28 @@ suite('DdevUtils Test Suite', () => {
assert.ok(result.userMessage?.includes('phpstan is not installed'));
assert.ok(result.userMessage?.includes('phpstan/phpstan'));
});

test('execDdev wraps command with XDEBUG_MODE=off', () => {
execSyncStub.returns('output');

const result = DdevUtils.execDdev('phpstan analyze', '/test/workspace');

assert.strictEqual(result, 'output');
assert.strictEqual(execSyncStub.calledOnce, true);
const callArgs = execSyncStub.firstCall.args;
assert.ok(callArgs[0].includes("XDEBUG_MODE=off"));
assert.ok(callArgs[0].includes("bash -c"));
assert.ok(callArgs[0].includes("'XDEBUG_MODE=off phpstan analyze'"));
});

test('execDdev escapes single quotes in command', () => {
execSyncStub.returns('output');

const result = DdevUtils.execDdev("echo 'hello'", '/test/workspace');

assert.strictEqual(result, 'output');
const callArgs = execSyncStub.firstCall.args;
// Should be: ddev exec bash -c 'XDEBUG_MODE=off echo '\''hello'\'''
assert.ok(callArgs[0].includes("'XDEBUG_MODE=off echo '\\''hello'\\'''"));
});
});