Skip to content

Conversation

mho22
Copy link
Collaborator

@mho22 mho22 commented Oct 14, 2025

Motivation for the change, related issues

Based on issue #2763

The current pain we have when we run a Playground CLI command with Xdebug enabled is the absence of the files located in the VFS in our IDE.

This pull request gives visibility to the VFS files with the help of a .playground symlink and the generation of path mappings inside the developer's IDE.

Only the mounts from inside the current working directory are mapped.

Implementation details

  1. Symlinking > .playground
  • It first removes a possibly existing symlink with name .playground in the current working directory.
  • If --xdebug and --experimental-ide options are present, we symlink the temporary playground cli directory inside the current working directory.
  1. Path mapping in IDEs
  • It first clears all the configs named WP Playground CLI - Listen for Xdebug in VSCode and PHPStorm config files.
  • If --xdebug and --experimental-ide options are present, we add IDE configs and path mappings in the related configs.
  • PHPStorm : it adds a new server with name WP Playground CLI - Listen for Xdebug in .idea/workspace.xml.
  • VSCode : it adds a new configuration with name WP Playground CLI - Listen for Xdebug in .vscode/launch.json.

Next

  • Add tests

Testing Instructions (or ideally a Blueprint)

CI

@mho22 mho22 changed the title [ xdebug ] Add --experimental-ide option to set xdebug path mappings [ xdebug ] Add --experimental-ide option in Playground CLI Oct 14, 2025
@mho22 mho22 mentioned this pull request Oct 14, 2025
9 tasks
@adamziel
Copy link
Collaborator

Let's support an optional explicit value, e.g. --experimental-ide=vscode just in case I work in multiple IDEs and only want to debug in one of them.

Also, this is the top of my vscode.json file:

{
    // Use IntelliSense to learn about possible attributes.
    // Hover to view descriptions of existing attributes.
    // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
    "version": "0.2.0",

It means we cannot trivially use JSON.parse() :( These files are JSONC (JSON with comments) and we need a JSONC parser and serializer to work with them. Perhaps this one from Microsoft would work, maybe it's even the one used by VS Code.

try {
config = JSON.parse(fs.readFileSync(configFilePath, 'utf-8'));
} catch {
logger.warn(
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a big deal, let's display it in red and kill the process at this point. Otherwise, when things don't work, the user will scratch their head and think "oh that option doesn't work?"

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I used jsonc-parser as suggested in your comment, and it became easier to manipulate JSON.

Now I parse the file and if it finds errors, it logs an error and exits with process.exit(1).

My question is, should I use the process.exit() function inside the xdebug-path-mappings file or should I return to the run-cli file to centralize process.exit functions ?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good question! Would throw new Error() suffice? AFAIR CLI has an error handler that already calls exit()

// Then, if xdebug, and experimental IDE are enabled,
// recreate the symlink pointing to the temporary
// directory and add the new IDE config.
if (args.xdebug && args.experimentalIde) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cc @brandonpayton for reviews

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@brandonpayton and @adamziel, your reviews are warmly welcomed in this pull request, since I am not sure I will list all the use cases.

@adamziel
Copy link
Collaborator

Some problems identifying the debug configuration:

CleanShot 2025-10-15 at 17 31 45@2x

Also, it's weird how the host is 127.0.0.1:9400 and port is 80.

(c: { $: { name: string } }) => c.$.name === name
);
if (!servers) {
component.servers[0].server.push(server);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this line keep failing for me, every part of this expression may be missing (like it was in my config).

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I had this same experience and believe I've fixed it now.

);
if (!component) {
config.project.component = [];
config.project.component.push({
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should we set component to the pushed element?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be fixed now.

@adamziel
Copy link
Collaborator

XDebug is running even during the Blueprint execution – how cool! Also, that's likely only useful for code developers. Let's set some php.ini option to disable xdebug until WordPress fully boots.

@adamziel
Copy link
Collaborator

We're definitely getting there! 🎉

CleanShot 2025-10-15 at 17 40 11@2x

@brandonpayton
Copy link
Member

I've been testing and reviewing the code and made some adjustments. The server host an port are now explicitly configured based on CLI's host and port.

I've seen PhpStorm report an Xdebug connection but haven't been able to hit any breakpoints yet.

@brandonpayton
Copy link
Member

brandonpayton commented Oct 18, 2025

I've been testing with an auto-mounted WordPress dir nested under the Playground repo like:
~/src/playground/wp-plugin-test-wordpress% node --experimental-strip-types --experimental-transform-types --disable-warning=ExperimentalWarning --import ../packages/meta/src/node-es-module-loader/register.mts ../packages/playground/cli/src/cli.ts server --auto-mount=. --verbosity=debug --skip-wordpress-setup --xdebug --experimental-ide

@brandonpayton
Copy link
Member

brandonpayton commented Oct 18, 2025

@adamziel is there any additional step in PhpStorm that I should have to do to tell PhpStorm to be able to hit breakpoints? Or should it just work if you have PhpStorm open and Playground CLI started with Xdebug support?

@adamziel
Copy link
Collaborator

adamziel commented Oct 18, 2025

I typically check "stop on first line" and set breakpoints from there @brandonpayton. And you need to turn on the "accept debug connections" toggle

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants