Skip to content

Commit 70207ed

Browse files
authored
[Blueprints] Rewrite paths in the wp-cli step. Improve error reporting. (#2406)
## Motivation for the change, related issues Playground have recently changed cwd from / to /wordpress to mimic what nginx, apache, and other webservers do. Unfortunately, many Blueprints use root-based relative paths in the `wp-cli` step. This PR detects them, rewrites them as absolute paths, and explains the problem in an error message. This PR follows up on #2268 ## Testing Instructions (or ideally a Blueprint) Confirm the following behavior: **Before this PR:** ``` $ node --experimental-wasm-jspi --loader=./packages/meta/src/node-es-module-loader/loader.mts ./packages/playground/cli/src/cli.ts server -blueprint=https://raw.githubusercontent.com/wordpress/blueprints/refs/heads/trunk/blueprints/wpcli-post-with-image/blueprint.json Starting a PHP server... Setting up WordPress latest Resolved WordPress release URL: https://downloads.w.org/release/wordpress-6.8.2.zip Fetching SQLite integration plugin... Booting WordPress... Booted! Running the Blueprint... Downloading wp-cli.phar – 83%PHP.run() output was: #!/usr/bin/env php PHPExecutionFailureError: PHP.run() failed with exit code 1 and the following output: Warning: Unable to import file 'wordpress/wp-content/Select-storage-method.png'. Reason: File doesn't exist. ``` **After this PR:** ``` $ Starting a PHP server... Resolved WordPress release URL: https://downloads.w.org/release/wordpress-6.8.2.zip Fetching SQLite integration plugin... Booting WordPress... Booted! Running the Blueprint... Downloading wp-cli.phar – 66%The wp-cli step in your Blueprint refers to a relative path. Playground recently changed the working directory from '/' to '/wordpress' to better mimic how real web servers work. This means relative paths that used to work may no longer point to the correct location. Playground automatically updated the path for you, but at one point path rewriting will be removed. Please update your code to use an absolute path instead: Instead of: { "step": "wp-cli", "command": "wp media import wordpress/wp-content/Select-storage-method.png --post_id=4 --title='Select your storage method' --featured_image" } Use: { "step": "wp-cli", "command": "wp media import /wordpress/wp-content/Select-storage-method.png --post_id=4 --title='Select your storage method' --featured_image" } This will ensure your code works reliably regardless of the current working directory. Downloading wp-cli.phar – 100% Logging in – 100% Finished running the blueprint WordPress is running on http://127.0.0.1:9400 ``` Also, the error reporting was improved so, without the path rewriting, the error message would now be: ``` Error when executing the blueprint step #4 ({"step":"wp-cli","command":"wp media import wordpress/wp-content/Select-storage-method.png --post_id=4 --title='Select your storage method' --featured_image"}) : Comlink method call failed > caused by > Comlink method call failed > caused by > PHP.run() failed with exit code 1. === Stdout === #!/usr/bin/env php === Stderr === Warning: Unable to import file 'wordpress/wp-content/Select-storage-method.png'. Reason: File doesn't exist. Error: No images imported. ```
1 parent fe5586f commit 70207ed

File tree

2 files changed

+62
-5
lines changed

2 files changed

+62
-5
lines changed

packages/playground/blueprints/src/lib/steps/wp-cli.ts

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import type { PHPResponse, UniversalPHP } from '@php-wasm/universal';
22
import type { StepHandler } from '.';
33
import { joinPaths, phpVar } from '@php-wasm/util';
44
import type { FileReference } from '../resources';
5+
import { logger } from '@php-wasm/logger';
56

67
export const defaultWpCliPath = '/tmp/wp-cli.phar';
78
export const defaultWpCliResource: FileReference = {
@@ -77,6 +78,46 @@ export const wpCLI: StepHandler<WPCLIStep, Promise<PHPResponse>> = async (
7778
throw new Error(`The first argument must be "wp".`);
7879
}
7980

81+
let rewrotePaths = false;
82+
const argsWithRewrittenPaths = args.map((arg) => {
83+
if (arg.startsWith('wordpress/')) {
84+
rewrotePaths = true;
85+
return `/${arg}`;
86+
}
87+
return arg;
88+
});
89+
90+
if (rewrotePaths) {
91+
logger.error(
92+
`
93+
The wp-cli step in your Blueprint refers to a relative path.
94+
95+
Playground recently changed the working directory from '/' to '/wordpress' to better mimic
96+
how real web servers work. This means relative paths that used to work may no longer
97+
point to the correct location.
98+
99+
Playground automatically updated the path for you, but at one point path rewriting will be removed. Please
100+
update your code to use an absolute path instead:
101+
102+
Instead of:
103+
104+
{
105+
"step": "wp-cli",
106+
"command": "wp media import wordpress/wp-content/Select-storage-method.png --post_id=4 --title='Select your storage method' --featured_image"
107+
}
108+
109+
Use:
110+
111+
{
112+
"step": "wp-cli",
113+
"command": "wp media import /wordpress/wp-content/Select-storage-method.png --post_id=4 --title='Select your storage method' --featured_image"
114+
}
115+
116+
This will ensure your code works reliably regardless of the current working directory.
117+
`.trim()
118+
);
119+
}
120+
80121
const documentRoot = await playground.documentRoot;
81122

82123
await playground.writeFile('/tmp/stdout', '');
@@ -96,7 +137,7 @@ export const wpCLI: StepHandler<WPCLIStep, Promise<PHPResponse>> = async (
96137
$GLOBALS['argv'] = array_merge([
97138
"/tmp/wp-cli.phar",
98139
"--path=${documentRoot}"
99-
], ${phpVar(args)});
140+
], ${phpVar(argsWithRewrittenPaths)});
100141
101142
// Provide stdin, stdout, stderr streams outside of
102143
// the CLI SAPI.

packages/playground/cli/src/run-cli.ts

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,12 @@ import type {
44
RemoteAPI,
55
SupportedPHPVersion,
66
} from '@php-wasm/universal';
7-
import { PHPResponse, exposeAPI, exposeSyncAPI } from '@php-wasm/universal';
7+
import {
8+
PHPResponse,
9+
exposeAPI,
10+
exposeSyncAPI,
11+
printDebugDetails,
12+
} from '@php-wasm/universal';
813
import type {
914
BlueprintBundle,
1015
BlueprintDeclaration,
@@ -261,9 +266,17 @@ export async function parseOptionsAndRunCLI() {
261266
}
262267
const debug = process.argv.includes('--debug');
263268
if (debug) {
264-
console.error(e);
269+
printDebugDetails(e);
265270
} else {
266-
console.error(e.message);
271+
const messageChain = [];
272+
let currentError = e;
273+
do {
274+
messageChain.push(currentError.message);
275+
currentError = currentError.cause as Error;
276+
} while (currentError instanceof Error);
277+
console.error(
278+
'\x1b[1m' + messageChain.join(' caused by ') + '\x1b[0m'
279+
);
267280
}
268281
process.exit(1);
269282
}
@@ -541,7 +554,10 @@ export async function runCLI(args: RunCLIArgs): Promise<RunCLIServer> {
541554
if (!args.debug) {
542555
throw error;
543556
}
544-
const phpLogs = await playground.readFileAsText(errorLogPath);
557+
let phpLogs = '';
558+
if (await playground.fileExists(errorLogPath)) {
559+
phpLogs = await playground.readFileAsText(errorLogPath);
560+
}
545561
throw new Error(phpLogs, { cause: error });
546562
}
547563
},

0 commit comments

Comments
 (0)