diff --git a/packages/docs/site/docs/developers/05-local-development/04-wp-playground-cli.md b/packages/docs/site/docs/developers/05-local-development/04-wp-playground-cli.md index 12cc1c1883..7e0311a1de 100644 --- a/packages/docs/site/docs/developers/05-local-development/04-wp-playground-cli.md +++ b/packages/docs/site/docs/developers/05-local-development/04-wp-playground-cli.md @@ -1,24 +1,24 @@ --- title: Playground CLI slug: /developers/local-development/wp-playground-cli +description: A command-line tool for WordPress development and testing with quick setup, flexible configuration, and minimal dependencies. --- # Playground CLI -[@wp-playground/cli](https://www.npmjs.com/package/@wp-playground/cli) is a command-line tool that simplifies the WordPress development and testing flow. -Playground CLI supports auto-mounting a directory with a plugin, theme, or WordPress installation. But if you need flexibility, the CLI supports mounting commands to personalize your local environment. +[@wp-playground/cli](https://www.npmjs.com/package/@wp-playground/cli) is a command-line tool that simplifies the WordPress development and testing flow. The Playground CLI also includes a set of flags to personalize the developer environment to meet developers' needs. **Key features:** -- **Quick Setup**: Set up a local WordPress environment in seconds. +- **Quick setup**: Set up a local WordPress environment in seconds. - **Flexibility**: Allows for configuration to adapt to different scenarios. -- **Simple Environment**: No extra configuration, just a compatible Node version, and you are ready to use it. +- **Simple environment**: No extra configuration, just a compatible Node version, and you are ready to use it. ## Requirements The Playground CLI requires Node.js 20.18 or higher, which is the recommended Long-Term Support (LTS) version. You can download it from the [Node.js website](https://nodejs.org/en/download). -## Quickstart +## Quick start To run the Playground CLI, open a command line and use the following command: @@ -28,37 +28,44 @@ npx @wp-playground/cli@latest server ![Playground CLI in Action](@site/static/img/developers/npx-wp-playground-server.gif) -With the previous command, you only get a fresh WordPress instance to test. Most developers will want to test their own work. To test a plugin or a theme, navigate to your project folder and run the CLI with the `--auto-mount` flag: +With the previous command, you only get a fresh WordPress instance to test. Most developers will want to test their own work. To test a plugin or a theme, navigate to your project folder and run the CLI with the `--auto-mount` flag. + +The `--auto-mount` flag analyzes the directory structure and automatically determines whether you're working with a plugin, theme, wp-content directory, full WordPress installation, or static HTML/PHP files. It then mounts your project to the correct path in the virtual WordPress environment, so you can start developing immediately without manual configuration. ```bash -cd my-plugin-or-theme-directory +cd my-plugin npx @wp-playground/cli@latest server --auto-mount ``` -### Choosing a WordPress and PHP Version +### Choose a WordPress and PHP version -By default, the CLI loads the latest stable version of WordPress and PHP 8.3 due to its improved performance. To specify your preferred versions, you can use the flag `--wp=` and `--php=`: +By default, the CLI loads PHP 8.3 and the latest stable version of WordPress. You can specify different versions using the `--wp=` and `--php=` flags. This is particularly useful when you need to test your plugin or theme for compatibility across different WordPress and PHP versions, ensuring your code works correctly for users running older installations. ```bash -npx @wp-playground/cli@latest server --wp=6.8 --php=8.3 +npx @wp-playground/cli@latest server --wp=6.4 --php=8.0 ``` -### Loading Blueprints +### Setting a custom site URL + +Configure a custom site URL for your local development environment, which is useful for testing domain-specific functionality or simulating production environments: -One way to take your Playground CLI development experience to the next level is to integrate with [Blueprints](/blueprints/getting-started/). For those unfamiliar with this technology, it allows developers to configure the initial state for their WordPress Playground instances. +```bash +npx @wp-playground/cli@latest server --site-url=https://my-local-dev.test +``` -Using the `--blueprint=` flag, developers can run a Playground with a custom initial state. We’ll use the example below to do this. +### Loading blueprints + +[Blueprints](/blueprints/getting-started/) configure your Playground instance's initial state. They install plugins, set options, and define landing pages. + +Using the `--blueprint=` flag, Playground can run with a custom initial state. We'll use the example below to do this. **(my-blueprint.json)** -```bash +```json { - "landingPage": "/wp-admin/options-general.php?page=akismet-key-config", - "login": true, - "plugins": [ - "hello-dolly", - "https://raw.githubusercontent.com/adamziel/blueprints/trunk/docs/assets/hello-from-the-dashboard.zip" - ] + "landingPage": "/wp-admin/options-general.php?page=akismet-key-config", + "login": true, + "plugins": ["hello-dolly", "https://raw.githubusercontent.com/adamziel/blueprints/trunk/docs/assets/hello-from-the-dashboard.zip"] } ``` @@ -70,25 +77,74 @@ npx @wp-playground/cli@latest server --blueprint=my-blueprint.json ### Mounting folders manually -Some projects have a specific structure that requires a custom configuration; for example, your repository contains all the files in the `/wp-content/` folder. So in this scenario, you can specify to the Playground CLI that it will mount your project from that folder using the `--mount` flag. +Some projects have a specific structure that requires a custom configuration; for example, your repository contains all the files in the `/wp-content/` folder. So in this scenario, you can specify to the Playground CLI that it will mount your project from that folder using the `--mount-dir` flag. ```bash -npx @wp-playground/cli@latest server --mount=.:/wordpress/wp-content/plugins/MY-PLUGIN-DIRECTORY +npx @wp-playground/cli@latest server --mount-dir . /wordpress/wp-content/plugins/MY-PLUGIN-DIRECTORY +``` + +:::info +On Windows, the path format used by `--mount`, for example, `/host/path:/vfs/path`, can clash with the system path format, e.g. to the machine, it's unclear which `:` separates the paths in `--mount=C:\plugin:/wordpress/wp-content/plugin`. To resolve this, use `--mount-dir` and `--mount-dir-before-install` instead. These flags let you specify host and virtual file system paths in a space-separated format: `--mount-dir "/host/path"` `"/vfs/path"`. +::: + +**Multiple mounts:** + +You can mount multiple directories at once: + +```bash +npx @wp-playground/cli@latest server \ + --mount-dir ./my-plugin /wordpress/wp-content/plugins/my-plugin \ + --mount-dir ./my-theme /wordpress/wp-content/themes/my-theme ``` ### Mounting before WordPress installation -Consider mounting your WordPress project files before the WordPress installation begins. This approach is beneficial if you want to override the Playground boot process, as it can help connect Playground with `WP-CLI`. The `--mount-before-install` flag supports this process. +When you have a local WordPress site, you can run it in Playground CLI as well. Here's one way to do it: ```bash -npx @wp-playground/cli@latest server --mount-before-install=.:/wordpress/ +npx @wp-playground/cli@latest server \ + --mount-dir-before-install ./wordpress-path-on-host /wordpress/ \ + --wordpress-install-mode=do-not-attempt-installing ``` -:::info -On Windows, the path format `/host/path:/vfs/path` can cause issues. To resolve this, use the flags `--mount-dir` and `--mount-dir-before-install`. These flags let you specify host and virtual file system paths in an alternative format: `"/host/path"` `"/vfs/path"`. +To unpack it, that command mounted the entire WordPress site you already had on your disk using the `--mount-dir-before-install` flag. That mount happened before Playground had a chance to download another WordPress version and unzip it in `/wordpress`. Then, we've told Playground CLI to skip running the WordPress installer. That site was already installed, so why would we? + +With this workflow, you can store your WordPress site directly in the filesystem, retain it across multiple Playground CLI executions, and use the usual WordPress tools with it, e.g. `WP-CLI`. + +You can also use the `--mount-dir-before-install` flag to populate a local directory with a newly created WordPress site: + +```bash +npx @wp-playground/cli@latest server \ + --mount-dir-before-install ./wordpress-path-on-host /wordpress/ +``` + +Since we did not skip the installer, Playground CLI runs the site setup as usual, only this time the `/wordpress` directory is connected to your local directory. At the end of the command, the new site files are stored in `./wordpress-path-on-host` in your local filesystem! To run that site again, use the `--wordpress-install-mode` flag discussed above. + +### Symlink support for monorepos + +Sometimes you're working with a complex project structure where directories are symlinked to another location on the disk, e.g.: + +``` +/home/alex/my-project +└── wp-content + └── plugins + ├── hello-dolly/ # regular directory + └── secret-plugin → /home/www/plugins/secret-plugin +``` + +By default, Playground CLI only accesses the directories you explicitly mount and won't load any files from `/home/www/plugins/secret-plugin`. You can, however, explicitly instruct Playground CLI to follow that, and other, symlinks with the `--follow-symlink` option: + +```bash +npx @wp-playground/cli@latest server \ + --follow-symlinks \ + --mount-dir-before-install ./packages/my-plugin /wordpress/wp-content/plugins/my-plugin +``` + +:::caution +Using `--follow-symlinks` can expose files outside mounted directories to Playground and could be a security risk. Avoid using this flag with untrusted code or when mounting directories you didn't create yourself. ::: -### Understanding Data Persistence and SQLite Location +### Understanding data persistence and SQLite location By default, Playground CLI stores WordPress files and the SQLite database in **temporary directories on your operating system**: @@ -99,7 +155,7 @@ By default, Playground CLI stores WordPress files and the SQLite database in **t └── tmp/ # Temporary PHP files ``` -**Finding Your Temp Directory:** +**Finding your temp directory:** The actual location depends on your OS (these are examples or common possibilities): @@ -125,7 +181,7 @@ Mount before WP install: /wordpress -> /private/var/folders/c8/mwz12ycx4s509056kby3hk180000gn/T/node-playground-cli-site-62926--62926-yQNOdvJVIgYC/wordpress ``` -**Where is the SQLite Database Stored?** +**Where is the SQLite database stored?** The database location depends on what you mount: @@ -141,10 +197,10 @@ The database location depends on what you mount: - **Custom mounts**: Database location follows your mount configuration -**Automatic Cleanup:** +**Automatic cleanup:** Playground CLI automatically removes temp directories that are: -- Older than 2 days +- Older than two days - No longer associated with a running process **Recommendation:** To persist both your code and database when developing plugins or themes, mount the entire `wp-content` directory instead of just the plugin/theme folder. @@ -154,12 +210,26 @@ Playground CLI automatically removes temp directories that are: ```bash # Mount your entire wp-content directory cd my-wordpress-project -npx @wp-playground/cli@latest server --mount=./wp-content:/wordpress/wp-content +npx @wp-playground/cli@latest server --mount-dir=./wp-content /wordpress/wp-content ``` -## Command and Arguments +## Verbosity and debugging + +The CLI supports different output verbosity levels for `quiet`, `normal` (default) and `debug` mode. Sometimes you want to hide all the stdout output, e.g. in a script or a CI automation. You can do that using the `--verbosity=quiet` option: + +```bash +npx @wp-playground/cli@latest server --verbosity=quiet +``` -Playground CLI is simple, configurable, and unopinionated. You can set it up according +Get detailed logging information for troubleshooting, with `debug` mode: + +```bash +npx @wp-playground/cli@latest server --verbosity=debug +``` + +## Commands and arguments + +The Playground CLI is simple, configurable, and unopinionated. You can set it up according to your unique WordPress setup. With the Playground CLI, you can use the following top-level commands: - **`server`**: (Default) Starts a local WordPress server. @@ -190,11 +260,8 @@ The `server` command supports the following optional arguments: - `--internal-cookie-store`: Enable internal cookie handling. When enabled, Playground will manage cookies internally using an HttpCookieStore that persists cookies across requests. When disabled, cookies are handled externally (e.g., by a browser in Node.js environments). Defaults to false. - `--xdebug`: Enable Xdebug. Defaults to false. - `--experimental-devtools`: Enable experimental browser development tools. Defaults to false. -- `--experimental-multi-worker=`: Enable experimental multi-worker support which requires a `/wordpress` directory backed by a real filesystem. Pass a positive number to specify the number of workers to use. Otherwise, defaults to the number of CPUs minus 1. - -:::caution -With the flag `--follow-symlinks`, the following symlinks will expose files outside mounted directories to Playground and could be a security risk. -::: +- `--experimental-unsafe-ide-integration=`: Set up the Xdebug integration on VS Code(`vscode`) and PhpStorm(`phpstorm`). +- `--experimental-multi-worker=`: Enable experimental multi-worker support which requires a `/wordpress` directory backed by a real file system. Pass a positive number to specify the number of workers to use. Otherwise, defaults to the number of CPUs minus one. ## Need some help with the CLI? @@ -204,7 +271,7 @@ With the Playground CLI, you can use the `--help` flag to get the full list of a npx @wp-playground/cli@latest --help ``` -## Programmatic Usage with JavaScript +## Programmatic usage with JavaScript The Playground CLI can also be controlled programmatically from your JavaScript/TypeScript code using the `runCLI` function. This gives you direct access to all CLI functionalities within your code, which is useful for automating end-to-end tests. Let's cover the basics of using `runCLI`. @@ -213,21 +280,60 @@ The Playground CLI can also be controlled programmatically from your JavaScript/ Using the `runCLI` function, you can specify options like the PHP and WordPress versions. In the example below, we request PHP 8.3, the latest version of WordPress, and to be automatically logged in. All supported arguments are defined in the `RunCLIArgs` type. ```TypeScript -import { runCLI, RunCLIArgs, RunCLIServer } from "@wp-playground/cli"; +import { runCLI, RunCLIArgs} from "@wp-playground/cli"; -let cliServer: RunCLIServer; +const cliServer = await runCLI({ + command: 'server', + php: '8.3', + wp: 'latest', + login: true, +} as RunCLIArgs); +``` -cliServer = await runCLI({ +Run the code above using your preferred TypeScript runtime, e.g. `tsx`: + +```sh +npx tsx my-script.ts +``` + +### Setting a custom site URL programmatically + +```TypeScript +import { runCLI } from "@wp-playground/cli"; + +const cliServer = await runCLI({ command: 'server', - php: '8.3', - wp: 'latest', - login: true -} as RunCLIArgs); + 'site-url': 'https://my-staging.example.com', + port: 9500 + }); + + // Verify site URL is set correctly + await cliServer.playground.writeFile( + '/wordpress/check-url.php', + '' + ); + + const checkUrl = new URL('/check-url.php', cliServer.serverUrl); + const response = await fetch(checkUrl); + console.log('Site URL:', await response.text()); ``` -To execute the code above, the developer can set their preferred method. A simple way to execute this code is to save it as a `.ts` file and run it with a tool like `tsx`. For example: `tsx my-script.ts` +### Controlling verbosity programmatically -### Setting a Blueprint +```TypeScript +import { runCLI } from "@wp-playground/cli"; +import { logger } from '@php-wasm/logger'; + +const cliServer = await runCLI({ + command: 'server', + verbosity: 'debug' // or 'quiet' or 'normal' +}); + +// Add custom logging +logger.debug('Custom debug message'); +``` + +### Setting a blueprint You can provide a blueprint in two ways: either as an object literal directly passed to the `blueprint` property, or as a string containing the path to an external `.json` file. @@ -277,25 +383,41 @@ const myBlueprint: BlueprintDeclaration = { ### Mounting a plugin programmatically -It is possible to mount local directories programmatically using `runCLI`. The options `mount` and `mount-before-install` are available. The `hostPath` property expects a path to a directory on your local machine. This path should be relative to where your script is being executed. +You can mount local directories programmatically using `runCLI`. The options `mount` and `mount-before-install` are available. The `hostPath` property expects a path to a directory on your local machine. This path should be relative to where your script is being executed. ```TypeScript - cliServer = await runCLI({ - command: 'server', - login: true, - 'mount-before-install': [ - { - hostPath: './[my-plugin-local-path]', - vfsPath: '/wordpress/wp-content/plugins/my-plugin', - }, - ], - }); +cliServer = await runCLI({ + command: 'server', + login: true, + 'mount-before-install': [ + { + hostPath: './[my-plugin-local-path]', + vfsPath: '/wordpress/wp-content/plugins/my-plugin', + }, + ], +}); ``` -With those options we can combine mounting parts of the project with blueprints, for example: +**Auto-mounting programmatically:** ```TypeScript +import { runCLI } from "@wp-playground/cli"; +import process from 'node:process'; + +// Change to your project directory +process.chdir('./my-plugin'); + +const cliServer = await runCLI({ + command: 'server', + autoMount: '' // Empty string triggers auto-detection +}); +``` + +### Combining mounts with blueprints +You can combine mounting parts of the project with blueprints, for example: + +```TypeScript import { runCLI, RunCLIArgs, RunCLIServer } from "@wp-playground/cli"; let cliServer: RunCLIServer; @@ -321,3 +443,243 @@ cliServer = await runCLI({ } } as RunCLIArgs); ``` + +**Multiple mounts with blueprints:** + +```TypeScript +const cliServer = await runCLI({ + command: 'server', + mount: [ + { + hostPath: './my-plugin', + vfsPath: '/wordpress/wp-content/plugins/my-plugin' + }, + { + hostPath: './my-theme', + vfsPath: '/wordpress/wp-content/themes/my-theme' + } + ], + blueprint: { + steps: [ + { + step: 'activatePlugin', + pluginPath: '/wordpress/wp-content/plugins/my-plugin/plugin.php' + }, + { + step: 'activateTheme', + themeFolderName: 'my-theme' + } + ] + } +}); +``` + +**Complex blueprint with multiple configurations:** + +```TypeScript +const cliServer = await runCLI({ + command: 'server', + php: '8.3', + wp: 'latest', + login: true, + mount: [ + { + hostPath: './my-plugin', + vfsPath: '/wordpress/wp-content/plugins/my-plugin' + } + ], + blueprint: { + landingPage: '/wp-admin/plugins.php', + steps: [ + { + step: 'activatePlugin', + pluginPath: '/wordpress/wp-content/plugins/my-plugin/plugin.php' + }, + { + step: 'setSiteOptions', + options: { + blogname: 'Plugin Test Site', + permalink_structure: '/%postname%/' + } + }, + { + step: 'runPHP', + code: '' + } + ] + } +}); +``` + +## Automated testing + +### Integration testing with Vitest + +The programmatic API is excellent for automated testing. Here's a complete example using Vitest: + +```TypeScript +import { describe, test, expect, afterEach } from 'vitest'; +import { runCLI, RunCLIServer } from "@wp-playground/cli"; + +describe('My Plugin Tests', () => { + let cliServer: RunCLIServer; + + afterEach(async () => { + if (cliServer) { + await cliServer[Symbol.asyncDispose](); + } + }); + + test('plugin activates successfully', async () => { + cliServer = await runCLI({ + command: 'server', + mount: [ + { + hostPath: './my-plugin', + vfsPath: '/wordpress/wp-content/plugins/my-plugin' + } + ], + blueprint: { + steps: [ + { + step: 'activatePlugin', + pluginPath: '/wordpress/wp-content/plugins/my-plugin/plugin.php' + } + ] + } + }); + + const homeUrl = new URL('/', cliServer.serverUrl); + const response = await fetch(homeUrl); + + expect(response.status).toBe(200); + const html = await response.text(); + expect(html).toContain('My Plugin'); + }); + + test('plugin settings page loads', async () => { + cliServer = await runCLI({ + command: 'server', + login: true, // Auto-login as admin + mount: [ + { + hostPath: './my-plugin', + vfsPath: '/wordpress/wp-content/plugins/my-plugin' + } + ], + blueprint: { + steps: [ + { + step: 'activatePlugin', + pluginPath: '/wordpress/wp-content/plugins/my-plugin/plugin.php' + } + ] + } + }); + + const settingsUrl = new URL( + '/wp-admin/options-general.php?page=my-plugin', + cliServer.serverUrl + ); + const response = await fetch(settingsUrl); + + expect(response.status).toBe(200); + }); +}); +``` + +### Testing a plugin with different WordPress/PHP versions + +```TypeScript +test('plugin works with WordPress 6.4 and PHP 8.0', async () => { + cliServer = await runCLI({ + command: 'server', + php: '8.3', + wp: '6.4', + mount: [ + { + hostPath: './my-plugin', + vfsPath: '/wordpress/wp-content/plugins/my-plugin' + } + ], + blueprint: { + steps: [ + { + step: 'activatePlugin', + pluginPath: '/wordpress/wp-content/plugins/my-plugin/plugin.php' + } + ] + } + }); + + const homeUrl = new URL('/', cliServer.serverUrl); + const response = await fetch(homeUrl); + + expect(response.status).toBe(200); +}); +``` + +## Advanced configuration + +### Skip WordPress and SQLite setup + +When you only need to test PHP code without WordPress, you can skip the setup for faster testing: + +```TypeScript +import { runCLI } from "@wp-playground/cli"; + +const cliServer = await runCLI({ + command: 'server', + php: '8.3', + wordpressInstallMode: 'do-not-attempt-installing', + skipSqliteSetup: true, +}); + +// Test PHP version +await cliServer.playground.writeFile( + '/wordpress/version.php', + '' +); + +const versionUrl = new URL('/version.php', cliServer.serverUrl); +const response = await fetch(versionUrl); +const version = await response.text(); +console.log('PHP Version:', version); // Outputs: 8.3.x +``` + +### Error handling + +```TypeScript +import { runCLI } from "@wp-playground/cli"; + +try { + const cliServer = await runCLI({ + command: 'server', + debug: true // Enable PHP error logging + }); + + // Your test code here + +} catch (error) { + console.error('Server failed to start:', error); +} +``` + +### Following symlinks programmatically + +```TypeScript +const cliServer = await runCLI({ + command: 'server', + followSymlinks: true, + 'mount-before-install': [ + { + hostPath: './symlinked-directory', + vfsPath: '/wordpress/wp-content/plugins/my-plugin' + } + ] +}); +``` + +:::caution +Using symlinks can expose files outside mounted directories. Only enable this feature when you trust the symlink targets. +::: diff --git a/packages/docs/site/i18n/es/docusaurus-plugin-content-docs/current/developers/05-local-development/04-wp-playground-cli.md b/packages/docs/site/i18n/es/docusaurus-plugin-content-docs/current/developers/05-local-development/04-wp-playground-cli.md index 41ef16ff49..465d4ccf5a 100644 --- a/packages/docs/site/i18n/es/docusaurus-plugin-content-docs/current/developers/05-local-development/04-wp-playground-cli.md +++ b/packages/docs/site/i18n/es/docusaurus-plugin-content-docs/current/developers/05-local-development/04-wp-playground-cli.md @@ -1,25 +1,43 @@ --- title: Playground CLI slug: /developers/local-development/wp-playground-cli +description: Una herramienta de línea de comandos para desarrollo y pruebas de WordPress con configuración rápida, configuración flexible y dependencias mínimas. --- + + # Playground CLI -[@wp-playground/cli](https://www.npmjs.com/package/@wp-playground/cli) es una herramienta de línea de comandos que simplifica el flujo de desarrollo y pruebas de WordPress. -Playground CLI soporta el montaje automático de un directorio con un plugin, tema o instalación de WordPress. Pero si necesitas flexibilidad, el CLI soporta comandos de montaje para personalizar tu entorno local. + + +[@wp-playground/cli](https://www.npmjs.com/package/@wp-playground/cli) es una herramienta de línea de comandos que simplifica el flujo de desarrollo y pruebas de WordPress. Puedes usar Playground CLI para auto-montar un directorio con un plugin, tema o instalación de WordPress. Si necesitas flexibilidad, puedes usar comandos de montaje para personalizar tu entorno local. + + **Características principales:** + + + + - **Configuración Rápida**: Configura un entorno WordPress local en segundos. - **Flexibilidad**: Permite la configuración para adaptarse a diferentes escenarios. - **Entorno Simple**: Sin configuración extra, solo una versión compatible de Node, y estás listo para usarlo. + + ## Requisitos + + El Playground CLI requiere Node.js 20.18 o superior, que es la versión recomendada de Soporte a Largo Plazo (LTS). Puedes descargarlo desde el [sitio web de Node.js](https://nodejs.org/en/download). + + ## Inicio Rápido + + Para ejecutar el Playground CLI, abre una línea de comandos y usa el siguiente comando: ```bash @@ -28,68 +46,138 @@ npx @wp-playground/cli@latest server ![Playground CLI en Acción](@site/static/img/developers/npx-wp-playground-server.gif) -Con el comando anterior, solo obtienes una instancia fresca de WordPress para probar. La mayoría de los desarrolladores querrán probar su propio trabajo. Para probar un plugin o un tema, navega a la carpeta de tu proyecto y ejecuta el CLI con la bandera `--auto-mount`: + + +Con el comando anterior, solo obtienes una instancia fresca de WordPress para probar. La mayoría de los desarrolladores querrán probar su propio trabajo. Para probar un plugin o un tema, navega a la carpeta de tu proyecto y ejecuta el CLI con la bandera `--auto-mount`. + + + +La bandera `--auto-mount` detecta inteligentemente tu tipo de proyecto y lo monta en la ubicación apropiada en WordPress. Cuando ejecutas el comando desde tu directorio de proyecto, Playground CLI analiza la estructura del directorio y determina automáticamente si estás trabajando con un plugin, tema, directorio wp-content, instalación completa de WordPress o archivos estáticos HTML/PHP. Luego monta tu proyecto en la ruta correcta en el entorno WordPress virtual, para que puedas comenzar a desarrollar inmediatamente sin configuración manual. ```bash -cd my-plugin-or-theme-directory +cd my-plugin npx @wp-playground/cli@latest server --auto-mount ``` + + ### Elegir una Versión de WordPress y PHP -Por defecto, el CLI carga la última versión estable de WordPress y PHP 8.3 debido a su rendimiento mejorado. Para especificar tus versiones preferidas, puedes usar las banderas `--wp=` y `--php=`: + + +Por defecto, el CLI carga la última versión estable de WordPress y PHP 8.3 debido a su rendimiento mejorado. Puedes especificar versiones diferentes usando las banderas `--wp=` y `--php=`. Esto es particularmente útil cuando necesitas probar tu plugin o tema para compatibilidad en diferentes versiones de WordPress y PHP, asegurando que tu código funcione correctamente para usuarios ejecutando instalaciones más antiguas. + +```bash +npx @wp-playground/cli@latest server --wp=6.4 --php=8.0 +``` + + + +### Configurar una URL de sitio personalizada + + + +Puedes configurar una URL de sitio personalizada para tu entorno de desarrollo, lo cual es útil para probar funcionalidad específica de dominio o simular entornos de producción: ```bash -npx @wp-playground/cli@latest server --wp=6.8 --php=8.3 +npx @wp-playground/cli@latest server --site-url=https://my-local-dev.test ``` + + ### Cargar Blueprints + + Una forma de llevar tu experiencia de desarrollo con Playground CLI al siguiente nivel es integrar con [Blueprints](/blueprints/getting-started/). Para aquellos que no estén familiarizados con esta tecnología, permite a los desarrolladores configurar el estado inicial para sus instancias de WordPress Playground. + + Usando la bandera `--blueprint=`, los desarrolladores pueden ejecutar un Playground con un estado inicial personalizado. Usaremos el ejemplo a continuación para hacer esto. **(my-blueprint.json)** -```bash +```json { - "landingPage": "/wp-admin/options-general.php?page=akismet-key-config", - "login": true, - "plugins": [ - "hello-dolly", - "https://raw.githubusercontent.com/adamziel/blueprints/trunk/docs/assets/hello-from-the-dashboard.zip" - ] + "landingPage": "/wp-admin/options-general.php?page=akismet-key-config", + "login": true, + "plugins": ["hello-dolly", "https://raw.githubusercontent.com/adamziel/blueprints/trunk/docs/assets/hello-from-the-dashboard.zip"] } ``` + + Comando CLI cargando un blueprint: ```bash npx @wp-playground/cli@latest server --blueprint=my-blueprint.json ``` + + ### Montar carpetas manualmente + + Algunos proyectos tienen una estructura específica que requiere una configuración personalizada; por ejemplo, tu repositorio contiene todos los archivos en la carpeta `/wp-content/`. Entonces en este escenario, puedes especificar al Playground CLI que montará tu proyecto desde esa carpeta usando la bandera `--mount`. ```bash npx @wp-playground/cli@latest server --mount=.:/wordpress/wp-content/plugins/MY-PLUGIN-DIRECTORY ``` + + +**Múltiples montajes:** + + + +Puedes montar múltiples directorios a la vez: + +```bash +npx @wp-playground/cli@latest server \ + --mount=./my-plugin:/wordpress/wp-content/plugins/my-plugin \ + --mount=./my-theme:/wordpress/wp-content/themes/my-theme +``` + + + ### Montar antes de la instalación de WordPress + + Considera montar tus archivos de proyecto de WordPress antes de que comience la instalación de WordPress. Este enfoque es beneficioso si quieres sobrescribir el proceso de arranque de Playground, ya que puede ayudar a conectar Playground con `WP-CLI`. La bandera `--mount-before-install` soporta este proceso. ```bash npx @wp-playground/cli@latest server --mount-before-install=.:/wordpress/ ``` -:::info -En Windows, el formato de ruta `/host/path:/vfs/path` puede causar problemas. Para resolver esto, usa las banderas `--mount-dir` y `--mount-dir-before-install`. Estas banderas te permiten especificar rutas del host y del sistema de archivos virtual en un formato alternativo `"/host/path"` `"/vfs/path"`. + + +### Soporte de enlaces simbólicos para monorepos + + + +Si estás trabajando en un monorepo o estructura de proyecto compleja donde los paquetes están enlazados simbólicamente, puedes habilitar el seguimiento de enlaces simbólicos: + +```bash +npx @wp-playground/cli@latest server \ + --follow-symlinks \ + --mount-before-install=./packages/my-plugin:/wordpress/wp-content/plugins/my-plugin +``` + +:::caution + + + +Usar `--follow-symlinks` puede exponer archivos fuera de los directorios montados a Playground y podría ser un riesgo de seguridad. Solo usa esta bandera cuando confíes en los destinos de los enlaces simbólicos. ::: + + ### Entender la Persistencia de Datos y Ubicación de SQLite + + Por defecto, Playground CLI almacena archivos de WordPress y la base de datos SQLite en **directorios temporales en tu sistema operativo**: ``` @@ -99,19 +187,30 @@ Por defecto, Playground CLI almacena archivos de WordPress y la base de datos SQ └── tmp/ # Archivos temporales PHP ``` + + **Encontrar tu Directorio Temporal:** + + La ubicación real depende de tu SO (estos son ejemplos o posibilidades comunes): + + + - **macOS/Linux**: Puede estar bajo `/tmp/` o `/private/var/folders/` (varía según el sistema) - **Windows**: `C:\Users\\AppData\Local\Temp\` + + Para ver la ruta exacta del directorio temporal que se está usando, ejecuta el CLI con la bandera `--verbosity=debug`: ```bash npx @wp-playground/cli@latest server --verbosity=debug ``` + + Esto mostrará algo como: ``` @@ -125,30 +224,56 @@ Mount before WP install: /wordpress -> /private/var/folders/c8/mwz12ycx4s509056kby3hk180000gn/T/node-playground-cli-site-62926--62926-yQNOdvJVIgYC/wordpress ``` + + **¿Dónde se Almacena la Base de Datos SQLite?** + + La ubicación de la base de datos depende de lo que montes: + + + + - **Montaje automático de wp-content o WordPress completo**: - Base de datos: `/wp-content/database/.ht.sqlite` - ✅ **Persistido localmente** en la carpeta de tu proyecto + + + + - **Montaje automático solo de plugin/tema**: - Base de datos: `/playground-/wordpress/wp-content/database/.ht.sqlite` - ⚠️ **Perdido cuando el servidor se detiene** (los directorios temporales se limpian) + + - **Montajes personalizados**: La ubicación de la base de datos sigue tu configuración de montaje + + **Limpieza Automática:** + + + Playground CLI elimina automáticamente los directorios temporales que son: -- Más antiguos de 2 días + + + +- Más antiguos de dos días - Ya no están asociados con un proceso en ejecución + + **Recomendación:** Para persistir tanto tu código como la base de datos al desarrollar plugins o temas, monta el directorio `wp-content` completo en lugar de solo la carpeta del plugin/tema. + + **Ejemplo: Montar wp-content para persistencia** ```bash @@ -157,15 +282,44 @@ cd my-wordpress-project npx @wp-playground/cli@latest server --mount=./wp-content:/wordpress/wp-content ``` + + +## Verbosidad y depuración + + + +El CLI soporta diferentes niveles de verbosidad para controlar la salida, para los modos `quiet`, `normal` y `debug`. El modo por defecto es `normal`. Para el modo silencioso, ejecuta el servidor sin salida (útil para scripts y automatización): + +```bash +npx @wp-playground/cli@latest server --verbosity=quiet +``` + + + +Obtén información de registro detallada para solucionar problemas, con el modo `debug`: + +```bash +npx @wp-playground/cli@latest server --verbosity=debug +``` + + + ## Comandos y Argumentos -Playground CLI es simple, configurable y sin opiniones. Puedes configurarlo de acuerdo -a tu configuración única de WordPress. Con el Playground CLI, puedes usar los siguientes comandos de nivel superior: + + +Playground CLI es simple, configurable y sin opiniones. Puedes configurarlo de acuerdo a tu configuración única de WordPress. Con el Playground CLI, puedes usar los siguientes comandos de nivel superior: + + + + - **`server`**: (Por defecto) Inicia un servidor WordPress local. - **`run-blueprint`**: Ejecuta un archivo Blueprint sin iniciar un servidor web. - **`build-snapshot`**: Construye una instantánea ZIP de un sitio WordPress basado en un Blueprint. + + El comando `server` soporta los siguientes argumentos opcionales: - `--port=`: El número de puerto para que el servidor escuche. Por defecto es 9400. @@ -190,27 +344,42 @@ El comando `server` soporta los siguientes argumentos opcionales: - `--internal-cookie-store`: Habilitar manejo interno de cookies. Cuando está habilitado, Playground administrará cookies internamente usando un HttpCookieStore que persiste cookies entre solicitudes. Cuando está deshabilitado, las cookies se manejan externamente (por ejemplo, por un navegador en entornos Node.js). Por defecto es false. - `--xdebug`: Habilitar Xdebug. Por defecto es false. - `--experimental-devtools`: Habilitar herramientas de desarrollo experimentales del navegador. Por defecto es false. -- `--experimental-multi-worker=`: Habilitar soporte experimental multi-worker que requiere un directorio `/wordpress` respaldado por un sistema de archivos real. Pasa un número positivo para especificar el número de workers a usar. De lo contrario, por defecto es el número de CPUs menos 1. +- `--experimental-multi-worker=`: Habilitar soporte experimental multi-worker que requiere un directorio `/wordpress` respaldado por un sistema de archivos real. Pasa un número positivo para especificar el número de workers a usar. De lo contrario, por defecto es el número de CPUs menos uno. -:::caution -Con la bandera `--follow-symlinks`, los siguientes enlaces simbólicos expondrán archivos fuera de los directorios montados a Playground y podrían ser un riesgo de seguridad. +:::info + + + +En Windows, el formato de ruta `/host/path:/vfs/path` puede causar problemas. Para resolver esto, usa las banderas `--mount-dir` y `--mount-dir-before-install`. Estas banderas te permiten especificar rutas del host y del sistema de archivos virtual en un formato alternativo `"/host/path"` `"/vfs/path"`. ::: + + ## ¿Necesitas ayuda con el CLI? + + Con el Playground CLI, puedes usar la bandera `--help` para obtener la lista completa de comandos y argumentos disponibles. ```bash npx @wp-playground/cli@latest --help ``` + + ## Uso Programático con JavaScript + + El Playground CLI también puede ser controlado programáticamente desde tu código JavaScript/TypeScript usando la función `runCLI`. Esto te da acceso directo a todas las funcionalidades del CLI dentro de tu código, lo cual es útil para automatizar pruebas end-to-end. Cubramos los conceptos básicos del uso de `runCLI`. + + ### Ejecutar una instancia de WordPress con una versión específica -Usando la función `runCLI`, puedes especificar opciones como las versiones de PHP y WordPress. En el ejemplo a continuación, solicitamos PHP 8.3, la última versión de WordPress, y iniciar sesión automáticamente. Todos los argumentos soportados están definidos en el tipo `RunCLIArgs`. + + +Usando la función `runCLI`, puedes especificar opciones como las versiones de PHP y WordPress. En el ejemplo a continuación, solicitamos PHP 8.3, la última versión de WordPress, y ser automáticamente conectado. Todos los argumentos soportados están definidos en el tipo `RunCLIArgs`. ```TypeScript import { runCLI, RunCLIArgs, RunCLIServer } from "@wp-playground/cli"; @@ -225,10 +394,81 @@ cliServer = await runCLI({ } as RunCLIArgs); ``` -Para ejecutar el código anterior, el desarrollador puede establecer su método preferido. Una forma simple de ejecutar este código es guardarlo como un archivo `.ts` y ejecutarlo con una herramienta como `tsx`. Por ejemplo: `tsx my-script.ts` + + +Para ejecutar el código anterior, puedes establecer tu método preferido. Una forma simple de ejecutar este código es guardarlo como un archivo `.ts` y ejecutarlo con una herramienta como `tsx`. Por ejemplo: `tsx my-script.ts` + + + +**Probando con versiones específicas de PHP:** + +```TypeScript +import { runCLI } from "@wp-playground/cli"; + +const cliServer = await runCLI({ + command: 'server', + php: '8.0', + skipWordPressSetup: true, + skipSqliteSetup: true, +}); + +// Probar versión de PHP +await cliServer.playground.writeFile( + '/wordpress/version.php', + '' +); + +const versionUrl = new URL('/version.php', cliServer.serverUrl); +const response = await fetch(versionUrl); +const version = await response.text(); +console.log('Versión de PHP:', version); // Salida: 8.0.x +``` + + + +### Configurar una URL de sitio personalizada programáticamente + +```TypeScript +const cliServer = await runCLI({ + command: 'server', + 'site-url': 'https://my-staging.example.com', + port: 9500 +}); + +// Verificar que la URL del sitio está configurada correctamente +await cliServer.playground.writeFile( + '/wordpress/check-url.php', + '' +); + +const checkUrl = new URL('/check-url.php', cliServer.serverUrl); +const response = await fetch(checkUrl); +console.log('URL del sitio:', await response.text()); +``` + + + +### Controlar la verbosidad programáticamente + +```TypeScript +import { runCLI } from "@wp-playground/cli"; +import { logger } from '@php-wasm/logger'; + +const cliServer = await runCLI({ + command: 'server', + verbosity: 'debug' // o 'quiet' o 'normal' +}); + +// Agregar registro personalizado +logger.debug('Mensaje de depuración personalizado'); +``` + + ### Configurar un Blueprint + + Puedes proporcionar un blueprint de dos maneras: ya sea como un objeto literal pasado directamente a la propiedad `blueprint`, o como una cadena que contiene la ruta a un archivo `.json` externo. ```TypeScript @@ -244,8 +484,8 @@ cliServer = await runCLI({ { "step": "setSiteOptions", "options": { - "blogname": "Blueprint Title", - "blogdescription": "A great blog description" + "blogname": "Título del Blueprint", + "blogdescription": "Una gran descripción de blog" } } ], @@ -253,6 +493,8 @@ cliServer = await runCLI({ }); ``` + + Para una seguridad de tipos completa al definir tu objeto blueprint, puedes importar y usar el tipo `BlueprintDeclaration` del paquete `@wp-playground/blueprints`: ```TypeScript @@ -275,27 +517,53 @@ const myBlueprint: BlueprintDeclaration = { }; ``` + + ### Montar un plugin programáticamente -Es posible montar directorios locales programáticamente usando `runCLI`. Las opciones `mount` y `mount-before-install` están disponibles. La propiedad `hostPath` espera una ruta a un directorio en tu máquina local. Esta ruta debe ser relativa a donde se está ejecutando tu script. + + +Puedes montar directorios locales programáticamente usando `runCLI`. Las opciones `mount` y `mount-before-install` están disponibles. La propiedad `hostPath` espera una ruta a un directorio en tu máquina local. Esta ruta debe ser relativa a donde se está ejecutando tu script. ```TypeScript - cliServer = await runCLI({ - command: 'server', - login: true, - 'mount-before-install': [ - { - hostPath: './[my-plugin-local-path]', - vfsPath: '/wordpress/wp-content/plugins/my-plugin', - }, - ], - }); +cliServer = await runCLI({ + command: 'server', + login: true, + 'mount-before-install': [ + { + hostPath: './[my-plugin-local-path]', + vfsPath: '/wordpress/wp-content/plugins/my-plugin', + }, + ], +}); ``` -Con esas opciones podemos combinar el montaje de partes del proyecto con blueprints, por ejemplo: + + +**Auto-montaje programático:** ```TypeScript +import { runCLI } from "@wp-playground/cli"; +import process from 'node:process'; + +// Cambiar a tu directorio de proyecto +process.chdir('./my-plugin'); +const cliServer = await runCLI({ + command: 'server', + autoMount: '' // Cadena vacía activa la detección automática +}); +``` + + + +### Combinar montajes con blueprints + + + +Puedes combinar el montaje de partes del proyecto con blueprints, por ejemplo: + +```TypeScript import { runCLI, RunCLIArgs, RunCLIServer } from "@wp-playground/cli"; let cliServer: RunCLIServer; @@ -321,3 +589,360 @@ cliServer = await runCLI({ } } as RunCLIArgs); ``` + + + +**Múltiples montajes con blueprints:** + +```TypeScript +const cliServer = await runCLI({ + command: 'server', + mount: [ + { + hostPath: './my-plugin', + vfsPath: '/wordpress/wp-content/plugins/my-plugin' + }, + { + hostPath: './my-theme', + vfsPath: '/wordpress/wp-content/themes/my-theme' + } + ], + blueprint: { + steps: [ + { + step: 'activatePlugin', + pluginPath: '/wordpress/wp-content/plugins/my-plugin/plugin.php' + }, + { + step: 'activateTheme', + themeFolderName: 'my-theme' + } + ] + } +}); +``` + + + +**Blueprint complejo con múltiples configuraciones:** + +```TypeScript +const cliServer = await runCLI({ + command: 'server', + php: '8.3', + wp: 'latest', + login: true, + mount: [ + { + hostPath: './my-plugin', + vfsPath: '/wordpress/wp-content/plugins/my-plugin' + } + ], + blueprint: { + landingPage: '/wp-admin/plugins.php', + steps: [ + { + step: 'activatePlugin', + pluginPath: '/wordpress/wp-content/plugins/my-plugin/plugin.php' + }, + { + step: 'setSiteOptions', + options: { + blogname: 'Sitio de Prueba de Plugin', + permalink_structure: '/%postname%/' + } + }, + { + step: 'runPHP', + code: '' + } + ] + } +}); +``` + + + +### Selección de modo (Blueprint v2) + + + +Puedes especificar diferentes modos cuando trabajas con Blueprint v2: + + + +**Crear un nuevo sitio:** + +```TypeScript +import { runCLI } from "@wp-playground/cli"; + +const cliServer = await runCLI({ + command: 'server', + 'experimental-blueprints-v2-runner': true, + mode: 'create-new-site', + 'mount-before-install': [ + { + hostPath: './my-new-site', + vfsPath: '/wordpress' + } + ] +}); +``` + + + +**Aplicar a un sitio existente:** + +```TypeScript +const cliServer = await runCLI({ + command: 'server', + 'experimental-blueprints-v2-runner': true, + mode: 'apply-to-existing-site', + 'mount-before-install': [ + { + hostPath: './existing-wordpress', + vfsPath: '/wordpress' + } + ], + blueprint: { + steps: [ + { + step: 'setSiteOptions', + options: { + blogname: 'Nombre de Sitio Actualizado' + } + } + ] + } +}); +``` + + + +## Pruebas automatizadas + + + +### Pruebas de integración con Vitest + + + +La API programática es excelente para pruebas automatizadas. Aquí hay un ejemplo completo usando Vitest: + +```TypeScript +import { describe, test, expect, afterEach } from 'vitest'; +import { runCLI, RunCLIServer } from "@wp-playground/cli"; + +describe('Pruebas de Mi Plugin', () => { + let cliServer: RunCLIServer; + + afterEach(async () => { + if (cliServer) { + await cliServer[Symbol.asyncDispose](); + } + }); + + test('el plugin se activa con éxito', async () => { + cliServer = await runCLI({ + command: 'server', + mount: [ + { + hostPath: './my-plugin', + vfsPath: '/wordpress/wp-content/plugins/my-plugin' + } + ], + blueprint: { + steps: [ + { + step: 'activatePlugin', + pluginPath: '/wordpress/wp-content/plugins/my-plugin/plugin.php' + } + ] + } + }); + + const homeUrl = new URL('/', cliServer.serverUrl); + const response = await fetch(homeUrl); + + expect(response.status).toBe(200); + const html = await response.text(); + expect(html).toContain('Mi Plugin'); + }); + + test('la página de configuración del plugin se carga', async () => { + cliServer = await runCLI({ + command: 'server', + login: true, // Auto-login como admin + mount: [ + { + hostPath: './my-plugin', + vfsPath: '/wordpress/wp-content/plugins/my-plugin' + } + ], + blueprint: { + steps: [ + { + step: 'activatePlugin', + pluginPath: '/wordpress/wp-content/plugins/my-plugin/plugin.php' + } + ] + } + }); + + const settingsUrl = new URL( + '/wp-admin/options-general.php?page=my-plugin', + cliServer.serverUrl + ); + const response = await fetch(settingsUrl); + + expect(response.status).toBe(200); + }); +}); +``` + + + +### Probar personalizaciones de temas + +```TypeScript +test('el tema muestra encabezado personalizado', async () => { + cliServer = await runCLI({ + command: 'server', + mount: [ + { + hostPath: './my-theme', + vfsPath: '/wordpress/wp-content/themes/my-theme' + } + ], + blueprint: { + steps: [ + { + step: 'installTheme', + themeData: { + resource: 'vfs', + path: '/wordpress/wp-content/themes/my-theme' + } + }, + { + step: 'activateTheme', + themeFolderName: 'my-theme' + } + ] + } + }); + + const homeUrl = new URL('/', cliServer.serverUrl); + const response = await fetch(homeUrl); + const html = await response.text(); + + expect(html).toContain('