Skip to content

Commit 65f7c00

Browse files
committed
Add XDebug path mappings in PHP.wasm CLI
1 parent 48e2fcf commit 65f7c00

File tree

5 files changed

+1601
-14
lines changed

5 files changed

+1601
-14
lines changed

packages/php-wasm/cli/src/main.ts

Lines changed: 115 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,19 +9,32 @@ import {
99
LatestSupportedPHPVersion,
1010
SupportedPHPVersionsList,
1111
} from '@php-wasm/universal';
12+
/* eslint-disable no-console */
1213
import type { SupportedPHPVersion } from '@php-wasm/universal';
13-
1414
import { FileLockManagerForNode } from '@php-wasm/node';
1515
import { PHP } from '@php-wasm/universal';
1616
import { loadNodeRuntime, useHostFilesystem } from '@php-wasm/node';
1717
import { startBridge } from '@php-wasm/xdebug-bridge';
18+
import {
19+
addXdebugIDEConfig,
20+
clearXdebugIDEConfig,
21+
} from './xdebug-path-mappings';
1822
import path from 'path';
1923

2024
let args = process.argv.slice(2);
2125
if (!args.length) {
2226
args = ['--help'];
2327
}
2428

29+
const bold = (text: string) =>
30+
process.stdout.isTTY ? '\x1b[1m' + text + '\x1b[0m' : text;
31+
32+
const italic = (text: string) =>
33+
process.stdout.isTTY ? `\x1b[3m${text}\x1b[0m` : text;
34+
35+
const highlight = (text: string) =>
36+
process.stdout.isTTY ? `\x1b[33m${text}\x1b[0m` : text;
37+
2538
const baseUrl = (import.meta || {}).url;
2639

2740
// Write the ca-bundle.crt file to disk so that PHP can find it.
@@ -51,6 +64,23 @@ async function run() {
5164
args = args.filter((arg) => arg !== '--experimental-devtools');
5265
}
5366

67+
const experimentalUnsafeIDEIntegrationOptions =
68+
args
69+
.filter((arg) =>
70+
arg.startsWith('--experimental-unsafe-ide-integration')
71+
)
72+
.map((arg) => {
73+
const value = arg.split('=')[1];
74+
if (value === undefined) return ['vscode', 'phpstorm'];
75+
if (value.includes(',')) return value.split(',');
76+
return [value];
77+
})[0] ?? false;
78+
if (experimentalUnsafeIDEIntegrationOptions) {
79+
args = args.filter(
80+
(arg) => !arg.startsWith('--experimental-unsafe-ide-integration')
81+
);
82+
}
83+
5484
// npm scripts set the TMPDIR env variable
5585
// PHP accepts a TMPDIR env variable and expects it to
5686
// be a writable directory within the PHP filesystem.
@@ -105,7 +135,90 @@ ${process.argv[0]} ${process.execArgv.join(' ')} ${process.argv[1]}
105135

106136
useHostFilesystem(php);
107137

108-
if (hasDevtoolsOption && hasXdebugOption) {
138+
// If xdebug, and experimental IDE are enabled,
139+
// recreate the symlink pointing to the temporary
140+
// directory and add the new IDE config.
141+
if (hasXdebugOption && experimentalUnsafeIDEIntegrationOptions) {
142+
try {
143+
const IDEConfigName = 'PHP.wasm CLI - Listen for Xdebug';
144+
const ides = experimentalUnsafeIDEIntegrationOptions;
145+
146+
// NOTE: Both the 'clear' and 'add' operations can throw errors.
147+
await clearXdebugIDEConfig(IDEConfigName, process.cwd());
148+
149+
const modifiedConfig = await addXdebugIDEConfig({
150+
name: IDEConfigName,
151+
host: 'example.com',
152+
port: 443,
153+
ides: ides,
154+
cwd: process.cwd(),
155+
});
156+
157+
// Display IDE-specific instructions
158+
const hasVSCode = ides.includes('vscode');
159+
const hasPhpStorm = ides.includes('phpstorm');
160+
161+
console.log('');
162+
163+
if (modifiedConfig.length > 0) {
164+
console.log(bold(`Xdebug configured successfully`));
165+
console.log(
166+
highlight(`Updated IDE config: `) + modifiedConfig.join(' ')
167+
);
168+
} else {
169+
console.log(bold(`Xdebug configuration failed.`));
170+
console.log(
171+
'No IDE-specific project settings directory was found in the current working directory.'
172+
);
173+
}
174+
175+
console.log('');
176+
177+
if (hasVSCode) {
178+
console.log(bold('VS Code / Cursor instructions:'));
179+
console.log(
180+
' 1. Ensure you have installed an IDE extension for PHP Debugging'
181+
);
182+
console.log(
183+
` (The ${bold('PHP Debug')} extension by ${bold(
184+
'Xdebug'
185+
)} has been a solid option)`
186+
);
187+
console.log(
188+
' 2. Open the Run and Debug panel on the left sidebar'
189+
);
190+
console.log(
191+
` 3. Select "${italic(IDEConfigName)}" from the dropdown`
192+
);
193+
console.log(' 3. Click "start debugging"');
194+
console.log(' 5. Set a breakpoint.');
195+
console.log(' 6. Run your command with PHP.wasm CLI.');
196+
if (hasPhpStorm) {
197+
console.log('');
198+
}
199+
}
200+
201+
if (hasPhpStorm) {
202+
console.log(bold('PhpStorm instructions:'));
203+
console.log(
204+
` 1. Choose "${italic(
205+
IDEConfigName
206+
)}" debug configuration in the toolbar`
207+
);
208+
console.log(' 2. Click the debug button (bug icon)`');
209+
console.log(' 3. Set a breakpoint.');
210+
console.log(' 4. Run your command with PHP.wasm CLI.');
211+
}
212+
213+
console.log('');
214+
} catch (error) {
215+
throw new Error('Could not configure Xdebug', {
216+
cause: error,
217+
});
218+
}
219+
}
220+
221+
if (hasXdebugOption && hasDevtoolsOption) {
109222
const bridge = await startBridge({ breakOnFirstLine: true });
110223

111224
bridge.start();

0 commit comments

Comments
 (0)