Skip to content
Closed
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
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,9 @@ The `server` command supports the following optional arguments:
- `--blueprint=<path>`: The path to a JSON Blueprint file to execute.
- `--blueprint-may-read-adjacent-files`: Consent flag: Allow "bundled" resources in a local blueprint to read files in the same directory as the blueprint file.
- `--login`: Automatically log the user in as an administrator.
- `--skip-wordpress-setup`: Do not download or install WordPress. Useful if you are mounting a full WordPress directory.
- `--skip-wordpress-download`: Skip downloading and unzipping WordPress. Useful if you mount a `/wordpress` directory that already contains core files.
- `--skip-wordpress-install`: Skip running the WordPress installer. Useful when your mounted `/wordpress` directory is already installed.
- `--skip-wordpress-setup`: **Deprecated.** Use `--skip-wordpress-download` and/or `--skip-wordpress-install` instead.
- `--skip-sqlite-setup`: Do not set up the SQLite database integration.
- `--verbosity`: Output logs and progress messages. Choices are "quiet", "normal" or "debug". Defaults to "normal".
- `--debug`: Print the PHP error log if an error occurs during boot.
Expand Down
4 changes: 3 additions & 1 deletion packages/playground/cli/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,9 @@ The `server` command supports the following optional arguments:
- `--blueprint=<path>`: The path to a JSON Blueprint file to execute.
- `--blueprint-may-read-adjacent-files`: Consent flag: Allow "bundled" resources in a local blueprint to read files in the same directory as the blueprint file.
- `--login`: Automatically log the user in as an administrator.
- `--skip-wordpress-setup`: Do not download or install WordPress. Useful if you are mounting a full WordPress directory.
- `--skip-wordpress-download`: Skip downloading and unzipping WordPress. Useful when the `/wordpress` directory already contains the core files.
- `--skip-wordpress-install`: Skip running the WordPress installer. Useful when the mounted `/wordpress` site is already installed.
- `--skip-wordpress-setup`: **Deprecated.** Use `--skip-wordpress-download` and/or `--skip-wordpress-install` instead.
- `--skip-sqlite-setup`: Do not set up the SQLite database integration.
- `--verbosity`: Output logs and progress messages (choices: "quiet", "normal", "debug"). Defaults to "normal".

Expand Down
28 changes: 25 additions & 3 deletions packages/playground/cli/src/blueprints-v1/blueprints-v1-handler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,10 @@ import {
import { RecommendedPHPVersion, zipDirectory } from '@wp-playground/common';
import fs from 'fs';
import path from 'path';
import { resolveWordPressRelease } from '@wp-playground/wordpress';
import {
resolveWordPressRelease,
type InstallationMode,
} from '@wp-playground/wordpress';
import {
CACHE_FOLDER,
cachedDownload,
Expand Down Expand Up @@ -62,11 +65,18 @@ export class BlueprintsV1Handler {
fileLockManagerPort: NodeMessagePort,
nativeInternalDirPath: string
) {
const skipWordPressDownload =
this.args.skipWordPressDownload === true ||
this.args.skipWordPressSetup === true;
const skipWordPressInstall =
this.args.skipWordPressInstall === true ||
this.args.skipWordPressSetup === true;

let wpDetails: any = undefined;
// @TODO: Rename to FetchProgressMonitor. There's nothing Emscripten
// about that class anymore.
const monitor = new EmscriptenDownloadMonitor();
if (!this.args.skipWordPressSetup) {
if (!skipWordPressDownload) {
let progressReached100 = false;
monitor.addEventListener('progress', ((
e: CustomEvent<ProgressEvent & { finished: boolean }>
Expand Down Expand Up @@ -135,8 +145,19 @@ export class BlueprintsV1Handler {
this.getEffectiveBlueprint()
);
await playground.useFileLockManager(fileLockManagerPort);
let installationMode: InstallationMode | undefined;
if (skipWordPressInstall) {
installationMode = false;
} else if (skipWordPressDownload) {
installationMode = 'wp-installer';
}
const resolvedPhpVersion =
runtimeConfiguration.phpVersion ??
this.args.php ??
RecommendedPHPVersion;
this.phpVersion = resolvedPhpVersion;
await playground.bootAsPrimaryWorker({
phpVersion: runtimeConfiguration.phpVersion,
phpVersion: resolvedPhpVersion,
wpVersion: runtimeConfiguration.wpVersion,
siteUrl: this.siteUrl,
mountsBeforeWpInstall,
Expand All @@ -151,6 +172,7 @@ export class BlueprintsV1Handler {
internalCookieStore: this.args.internalCookieStore,
withXdebug: this.args.xdebug,
nativeInternalDirPath,
installationMode,
});

if (
Expand Down
4 changes: 4 additions & 0 deletions packages/playground/cli/src/blueprints-v1/worker-thread-v1.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import { RecommendedPHPVersion } from '@wp-playground/common';
import {
bootRequestHandler,
bootWordPressAndRequestHandler,
type InstallationMode,
} from '@wp-playground/wordpress';
import { rootCertificates } from 'tls';
import { jspi } from 'wasm-feature-detect';
Expand Down Expand Up @@ -52,6 +53,7 @@ export type PrimaryWorkerBootOptions = WorkerBootOptions & {
wordPressZip?: ArrayBuffer;
sqliteIntegrationPluginZip?: ArrayBuffer;
dataSqlPath?: string;
installationMode?: InstallationMode;
};

interface WorkerBootRequestHandlerOptions {
Expand Down Expand Up @@ -138,6 +140,7 @@ export class PlaygroundCliBlueprintV1Worker extends PHPWorker {
internalCookieStore,
withXdebug,
nativeInternalDirPath,
installationMode,
}: PrimaryWorkerBootOptions) {
if (this.booted) {
throw new Error('Playground already booted');
Expand Down Expand Up @@ -202,6 +205,7 @@ export class PlaygroundCliBlueprintV1Worker extends PHPWorker {
},
cookieStore: internalCookieStore ? undefined : false,
dataSqlPath,
installationMode,
spawnHandler: sandboxedSpawnHandlerFactory,
async onPHPInstanceCreated(php) {
await mountResources(php, mountsBeforeWpInstall);
Expand Down
77 changes: 69 additions & 8 deletions packages/playground/cli/src/run-cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,20 @@ export async function parseOptionsAndRunCLI() {
})
.option('skip-wordpress-setup', {
describe:
'Do not download, unzip, and install WordPress. Useful for mounting a pre-configured WordPress directory at /wordpress.',
'[DEPRECATED] Do not download, unzip, and install WordPress. Use --skip-wordpress-download and/or --skip-wordpress-install instead.',
type: 'boolean',
default: false,
hidden: true,
})
.option('skip-wordpress-download', {
describe:
'Skip downloading and unzipping WordPress. Use when the /wordpress directory is already populated.',
type: 'boolean',
default: false,
})
.option('skip-wordpress-install', {
describe:
'Skip running the WordPress installer. Use when the mounted /wordpress site is already installed.',
type: 'boolean',
default: false,
})
Expand Down Expand Up @@ -250,10 +263,17 @@ export async function parseOptionsAndRunCLI() {
.strictOptions()
.check(async (args) => {
// Support multiple spellings of "WordPress"
if (
args['skip-wordpress-setup'] ||
args['skipWordpressSetup']
) {
const skipWordPressSetup =
args['skip-wordpress-setup'] === true ||
args['skipWordpressSetup'] === true;
const skipWordPressDownload =
args['skip-wordpress-download'] === true ||
args['skipWordpressDownload'] === true;
const skipWordPressInstall =
args['skip-wordpress-install'] === true ||
args['skipWordpressInstall'] === true;

if (skipWordPressSetup) {
args['skipWordPressSetup'] = true;
}

Expand Down Expand Up @@ -304,9 +324,13 @@ export async function parseOptionsAndRunCLI() {

if (args['experimental-blueprints-v2-runner'] === true) {
if (args['mode'] !== undefined) {
if ('skip-wordpress-setup' in args) {
if (
skipWordPressSetup ||
skipWordPressDownload ||
skipWordPressInstall
) {
throw new Error(
'The --skipWordPressSetup option cannot be used with the --mode option. Use one or the other.'
'The WordPress lifecycle skip options cannot be used with the --mode option. Use one or the other.'
);
}
if ('skip-sqlite-setup' in args) {
Expand All @@ -321,7 +345,11 @@ export async function parseOptionsAndRunCLI() {
}
} else {
// Support the legacy v1 runner options
if (args['skip-wordpress-setup'] === true) {
if (
skipWordPressSetup ||
skipWordPressDownload ||
skipWordPressInstall
) {
args['mode'] = 'apply-to-existing-site';
} else {
args['mode'] = 'create-new-site';
Expand Down Expand Up @@ -354,6 +382,20 @@ export async function parseOptionsAndRunCLI() {
yargsObject.wrap(yargsObject.terminalWidth());
const args = await yargsObject.argv;

const parsedSkipWordPressSetup = args['skipWordPressSetup'] === true;
const parsedSkipWordPressDownload =
args['skipWordPressDownload'] === true ||
args['skip-wordpress-download'] === true;
const parsedSkipWordPressInstall =
args['skipWordPressInstall'] === true ||
args['skip-wordpress-install'] === true;

args['skipWordPressSetup'] = parsedSkipWordPressSetup;
args['skipWordPressDownload'] =
parsedSkipWordPressSetup || parsedSkipWordPressDownload;
args['skipWordPressInstall'] =
parsedSkipWordPressSetup || parsedSkipWordPressInstall;

const command = args._[0] as string;

if (!['run-blueprint', 'server', 'build-snapshot'].includes(command)) {
Expand Down Expand Up @@ -422,6 +464,8 @@ export interface RunCLIArgs {
'experimental-blueprints-v2-runner'?: boolean;

// --------- Blueprint V1 args -----------
skipWordPressDownload?: boolean;
skipWordPressInstall?: boolean;
skipWordPressSetup?: boolean;
skipSqliteSetup?: boolean;
followSymlinks?: boolean;
Expand Down Expand Up @@ -463,6 +507,23 @@ export async function runCLI(args: RunCLIArgs): Promise<RunCLIServer> {
worker: Worker;
}[] = [];

if (args.skipWordPressSetup) {
logger.warn(
'The skipWordPressSetup option is deprecated. Use skipWordPressDownload and skipWordPressInstall instead.'
);
args = {
...args,
skipWordPressDownload: true,
skipWordPressInstall: true,
};
}

args = {
...args,
skipWordPressDownload: args.skipWordPressDownload === true,
skipWordPressInstall: args.skipWordPressInstall === true,
};

/**
* Expand auto-mounts to include the necessary mounts and steps
* when running in auto-mount mode.
Expand Down
9 changes: 6 additions & 3 deletions packages/playground/cli/tests/run-cli.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,8 @@ describe.each(blueprintVersions)(
php: '8.0',
// Let's skip the cost of WordPress setup because it is
// irrelevant for this test.
skipWordPressSetup: true,
skipWordPressDownload: true,
skipWordPressInstall: true,
skipSqliteSetup: true,
blueprint: undefined,
});
Expand Down Expand Up @@ -643,7 +644,8 @@ describe('other run-cli behaviors', () => {
test('should clear old auto-login cookie', async () => {
cliServer = await runCLI({
command: 'server',
skipWordPressSetup: true,
skipWordPressDownload: true,
skipWordPressInstall: true,
skipSqliteSetup: true,
blueprint: undefined,
});
Expand Down Expand Up @@ -677,7 +679,8 @@ describe('other run-cli behaviors', () => {
test('should return 500 when the request handler throws an error', async () => {
cliServer = await runCLI({
command: 'server',
skipWordPressSetup: true,
skipWordPressDownload: true,
skipWordPressInstall: true,
blueprint: undefined,
});

Expand Down
19 changes: 18 additions & 1 deletion packages/playground/wordpress/src/boot.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ export type PHPInstanceCreatedHook = (
) => Promise<void>;

export type DatabaseType = 'sqlite' | 'mysql' | 'custom';
export type InstallationMode = 'wp-installer' | 'sql-dump' | false;

export async function bootWordPressAndRequestHandler(
options: BootRequestHandlerOptions & BootWordPressOptions
Expand Down Expand Up @@ -137,6 +138,8 @@ export interface BootWordPressOptions {
* and WP_SITEURL constants in WordPress.
*/
siteUrl: string;
/** Override automatic installation behavior. */
installationMode?: InstallationMode;
}

/**
Expand Down Expand Up @@ -201,7 +204,21 @@ export async function bootWordPress(
);
}

if (options.wordPressZip && !options.dataSqlPath) {
const installationMode =
options.installationMode ??
(options.dataSqlPath
? 'sql-dump'
: options.wordPressZip
? 'wp-installer'
: false);

if (installationMode === 'sql-dump' && !options.dataSqlPath) {
throw new Error(
'The "sql-dump" installation mode requires a dataSqlPath to be provided.'
);
}

if (installationMode === 'wp-installer') {
if (!(await isWordPressInstalled(php))) {
// Install WordPress if it's not installed.
await installWordPress(php);
Expand Down
6 changes: 5 additions & 1 deletion packages/playground/wordpress/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,11 @@ export {
bootRequestHandler,
getFileNotFoundActionForWordPress,
} from './boot';
export type { PhpIniOptions, PHPInstanceCreatedHook } from './boot';
export type {
PhpIniOptions,
PHPInstanceCreatedHook,
InstallationMode,
} from './boot';
export { defineWpConfigConstants, ensureWpConfig } from './rewrite-wp-config';
export { getLoadedWordPressVersion } from './version-detect';

Expand Down