From 8b924fbf5a9656da7d630b4885f043f2b0155226 Mon Sep 17 00:00:00 2001 From: Christopher Allford <6451942+ObliviousHarmony@users.noreply.github.com> Date: Fri, 21 Apr 2023 08:17:11 -0700 Subject: [PATCH 01/10] Added `postInstall` Configuration Option While at the moment this doesn't do anything, it does, however, exist. You can also override it with the `WP_ENV_POST_INSTALL` environment variable. --- packages/env/CHANGELOG.md | 5 +++++ packages/env/README.md | 21 ++++++++++--------- packages/env/lib/config/config.js | 12 +++++++++-- packages/env/lib/config/parse-config.js | 1 + .../config/test/__snapshots__/config.js.snap | 2 ++ packages/env/lib/config/validate-config.js | 9 ++++++++ 6 files changed, 38 insertions(+), 12 deletions(-) diff --git a/packages/env/CHANGELOG.md b/packages/env/CHANGELOG.md index 602530c541d4fd..77058f5ad73971 100644 --- a/packages/env/CHANGELOG.md +++ b/packages/env/CHANGELOG.md @@ -8,6 +8,11 @@ - Automatically add the environment's port to `WP_TESTS_DOMAIN`. - `run` command now has a `--env-cwd` option to set the working directory in the container for the command to execute from. +### New feature + +- Create a `postInstall` property in `.wp-env.json` files for setting arbitrary commands to run after configuring WordPress. +- Add a `WP_ENV_POST_INSTALL` environment variable to override the current `postInstall` configuration. + ## 5.16.0 (2023-04-12) ## 5.15.0 (2023-03-29) diff --git a/packages/env/README.md b/packages/env/README.md index 7a22dfe88428cf..69a99ac76e3fad 100644 --- a/packages/env/README.md +++ b/packages/env/README.md @@ -461,16 +461,17 @@ You can customize the WordPress installation, plugins and themes that the develo `.wp-env.json` supports fields for options applicable to both the tests and development instances. -| Field | Type | Default | Description | -| -------------- | -------------- | -------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------- | -| `"core"` | `string\|null` | `null` | The WordPress installation to use. If `null` is specified, `wp-env` will use the latest production release of WordPress. | -| `"phpVersion"` | `string\|null` | `null` | The PHP version to use. If `null` is specified, `wp-env` will use the default version used with production release of WordPress. | -| `"plugins"` | `string[]` | `[]` | A list of plugins to install and activate in the environment. | -| `"themes"` | `string[]` | `[]` | A list of themes to install in the environment. | -| `"port"` | `integer` | `8888` (`8889` for the tests instance) | The primary port number to use for the installation. You'll access the instance through the port: 'http://localhost:8888'. | -| `"testsPort"` | `integer` | `8889` | The port number for the test site. You'll access the instance through the port: 'http://localhost:8889'. | -| `"config"` | `Object` | See below. | Mapping of wp-config.php constants to their desired values. | -| `"mappings"` | `Object` | `"{}"` | Mapping of WordPress directories to local directories to be mounted in the WordPress instance. | +| Field | Type | Default | Description | +| --------------- | -------------- | -------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------- | +| `"core"` | `string\|null` | `null` | The WordPress installation to use. If `null` is specified, `wp-env` will use the latest production release of WordPress. | +| `"phpVersion"` | `string\|null` | `null` | The PHP version to use. If `null` is specified, `wp-env` will use the default version used with production release of WordPress. | +| `"plugins"` | `string[]` | `[]` | A list of plugins to install and activate in the environment. | +| `"themes"` | `string[]` | `[]` | A list of themes to install in the environment. | +| `"port"` | `integer` | `8888` (`8889` for the tests instance) | The primary port number to use for the installation. You'll access the instance through the port: 'http://localhost:8888'. | +| `"testsPort"` | `integer` | `8889` | The port number for the test site. You'll access the instance through the port: 'http://localhost:8889'. | +| `"config"` | `Object` | See below. | Mapping of wp-config.php constants to their desired values. | +| `"mappings"` | `Object` | `"{}"` | Mapping of WordPress directories to local directories to be mounted in the WordPress instance. | +| `"postInstall"` | `string\|null` | `null` | The command(s) that should be executed after configuring WordPress. | _Note: the port number environment variables (`WP_ENV_PORT` and `WP_ENV_TESTS_PORT`) take precedent over the .wp-env.json values._ diff --git a/packages/env/lib/config/config.js b/packages/env/lib/config/config.js index 4018830f853a01..476a45d52176e7 100644 --- a/packages/env/lib/config/config.js +++ b/packages/env/lib/config/config.js @@ -34,13 +34,15 @@ const md5 = require( '../md5' ); * Base-level config for any particular environment. (development/tests/etc) * * @typedef WPServiceConfig + * @property {number} port The port to use. + * @property {string} phpVersion Version of PHP to use in the environments, of the format 0.0. + * * @property {WPSource} coreSource The WordPress installation to load in the environment. * @property {WPSource[]} pluginSources Plugins to load in the environment. * @property {WPSource[]} themeSources Themes to load in the environment. - * @property {number} port The port to use. * @property {Object} config Mapping of wp-config.php constants to their desired values. * @property {Object.} mappings Mapping of WordPress directories to local directories which should be mounted. - * @property {string} phpVersion Version of PHP to use in the environments, of the format 0.0. + * @property {string|null} postInstall The command(s) to run after configuring WordPress. */ /** @@ -104,6 +106,7 @@ module.exports = async function readConfig( configPath ) { WP_SITEURL: 'http://localhost', WP_HOME: 'http://localhost', }, + postInstall: null, env: { development: {}, // No overrides needed, but it should exist. tests: { @@ -293,6 +296,11 @@ function withOverrides( config ) { addConfigPort( 'WP_SITEURL' ); addConfigPort( 'WP_HOME' ); + if ( process.env.WP_ENV_POST_INSTALL ) { + config.env.development.postInstall = process.env.WP_ENV_POST_INSTALL; + config.env.tests.postInstall = process.env.WP_ENV_POST_INSTALL; + } + return config; } diff --git a/packages/env/lib/config/parse-config.js b/packages/env/lib/config/parse-config.js index 9528ac8b3528c1..a5724bacdb145a 100644 --- a/packages/env/lib/config/parse-config.js +++ b/packages/env/lib/config/parse-config.js @@ -56,6 +56,7 @@ module.exports = async function parseConfig( config, options ) { }, {} ), + postInstall: config.postInstall, }; }; diff --git a/packages/env/lib/config/test/__snapshots__/config.js.snap b/packages/env/lib/config/test/__snapshots__/config.js.snap index c7bcdbd94d7ffe..217482f6747ee5 100644 --- a/packages/env/lib/config/test/__snapshots__/config.js.snap +++ b/packages/env/lib/config/test/__snapshots__/config.js.snap @@ -25,6 +25,7 @@ exports[`readConfig config file should match snapshot 1`] = ` "phpVersion": null, "pluginSources": [], "port": 2000, + "postInstall": null, "themeSources": [], }, "tests": { @@ -47,6 +48,7 @@ exports[`readConfig config file should match snapshot 1`] = ` "phpVersion": null, "pluginSources": [], "port": 1000, + "postInstall": null, "themeSources": [], }, }, diff --git a/packages/env/lib/config/validate-config.js b/packages/env/lib/config/validate-config.js index 74a5fb79b5deb3..583eb753d02387 100644 --- a/packages/env/lib/config/validate-config.js +++ b/packages/env/lib/config/validate-config.js @@ -86,6 +86,15 @@ function validateConfig( config, envLocation ) { checkValidURL( envPrefix, config.config, 'WP_SITEURL' ); checkValidURL( envPrefix, config.config, 'WP_HOME' ); + if ( + config.postInstall !== null && + typeof config.postInstall !== 'string' + ) { + throw new ValidationError( + `Invalid .wp-env.json: "${ envPrefix }postInstall" must be null or a string.` + ); + } + return config; } From 9ea741aa8d887cf4423a4880642dbc61126e07df Mon Sep 17 00:00:00 2001 From: Christopher Allford <6451942+ObliviousHarmony@users.noreply.github.com> Date: Fri, 21 Apr 2023 08:55:22 -0700 Subject: [PATCH 02/10] Execute `postInstall` On `start` This commit adds support for executing the post-install script when the user runs `wp-env start` and it re-configured WordPress. --- packages/env/CHANGELOG.md | 1 + packages/env/lib/commands/clean.js | 4 ++-- packages/env/lib/commands/start.js | 24 +++++++++++++++----- packages/env/lib/wordpress.js | 35 ++++++++++++++++++++++++++---- 4 files changed, 52 insertions(+), 12 deletions(-) diff --git a/packages/env/CHANGELOG.md b/packages/env/CHANGELOG.md index 77058f5ad73971..4f5c477fb18841 100644 --- a/packages/env/CHANGELOG.md +++ b/packages/env/CHANGELOG.md @@ -12,6 +12,7 @@ - Create a `postInstall` property in `.wp-env.json` files for setting arbitrary commands to run after configuring WordPress. - Add a `WP_ENV_POST_INSTALL` environment variable to override the current `postInstall` configuration. +- Run the `postInstall` command on `wp-env start` when WordPress is being configures due to cache invalidation or the `--update` option. ## 5.16.0 (2023-04-12) diff --git a/packages/env/lib/commands/clean.js b/packages/env/lib/commands/clean.js index adde9d072d9eb0..26963849f0f142 100644 --- a/packages/env/lib/commands/clean.js +++ b/packages/env/lib/commands/clean.js @@ -42,7 +42,7 @@ module.exports = async function clean( { environment, spinner, debug } ) { if ( environment === 'all' || environment === 'development' ) { tasks.push( resetDatabase( 'development', config ) - .then( () => configureWordPress( 'development', config ) ) + .then( () => configureWordPress( 'development', config, null ) ) .catch( () => {} ) ); } @@ -50,7 +50,7 @@ module.exports = async function clean( { environment, spinner, debug } ) { if ( environment === 'all' || environment === 'tests' ) { tasks.push( resetDatabase( 'tests', config ) - .then( () => configureWordPress( 'tests', config ) ) + .then( () => configureWordPress( 'tests', config, null ) ) .catch( () => {} ) ); } diff --git a/packages/env/lib/commands/start.js b/packages/env/lib/commands/start.js index a217d5492d2b48..8cd22fb68edfea 100644 --- a/packages/env/lib/commands/start.js +++ b/packages/env/lib/commands/start.js @@ -178,12 +178,24 @@ module.exports = async function start( { spinner, debug, update, xdebug } ) { // Retry WordPress installation in case MySQL *still* wasn't ready. await Promise.all( [ - retry( () => configureWordPress( 'development', config, spinner ), { - times: 2, - } ), - retry( () => configureWordPress( 'tests', config, spinner ), { - times: 2, - } ), + retry( + () => + configureWordPress( + 'development', + config, + 'start', + spinner + ), + { + times: 2, + } + ), + retry( + () => configureWordPress( 'tests', config, 'start', spinner ), + { + times: 2, + } + ), ] ); // Set the cache key once everything has been configured. diff --git a/packages/env/lib/wordpress.js b/packages/env/lib/wordpress.js index fc8f6db5670777..30bbd230ddc99c 100644 --- a/packages/env/lib/wordpress.js +++ b/packages/env/lib/wordpress.js @@ -6,6 +6,7 @@ const util = require( 'util' ); const fs = require( 'fs' ).promises; const path = require( 'path' ); const got = require( 'got' ); +const { execSync } = require( 'child_process' ); /** * Promisified dependencies @@ -39,11 +40,17 @@ async function checkDatabaseConnection( { dockerComposeConfigPath, debug } ) { * activating all plugins, and activating the first theme. These steps are * performed sequentially so as to not overload the WordPress instance. * - * @param {WPEnvironment} environment The environment to configure. Either 'development' or 'tests'. - * @param {WPConfig} config The wp-env config object. - * @param {Object} spinner A CLI spinner which indicates progress. + * @param {WPEnvironment} environment The environment to configure. Either 'development' or 'tests'. + * @param {WPConfig} config The wp-env config object. + * @param {string|null} postInstallContext The context that will be set when executing postInstall command(s). When null, postInstall won't run. + * @param {Object} spinner A CLI spinner which indicates progress. */ -async function configureWordPress( environment, config, spinner ) { +async function configureWordPress( + environment, + config, + postInstallContext, + spinner +) { const installCommand = `wp core install --url="${ config.env[ environment ].config.WP_SITEURL }" --title="${ config.name }" --admin_user=admin --admin_password=password --admin_email=wordpress@example.com --skip-email`; // -eo pipefail exits the command as soon as anything fails in bash. @@ -105,6 +112,26 @@ async function configureWordPress( environment, config, spinner ) { log: config.debug, } ); + + // At this point, WordPress has been configured and the environment should be ready. + // We're going to support a "postInstall" configuration option so that users can + // have the environment arbitrarily execute command(s) for additional setup. + if ( postInstallContext && config.env[ environment ].postInstall ) { + try { + execSync( config.env[ environment ].postInstall, { + encoding: 'utf-8', + // We're going to let the script decide what it wants to output. + stdio: [ 'ignore', 'inherit', 'pipe' ], + env: { + ...process.env, + WP_ENV_POST_INSTALL_CONTEXT: postInstallContext, + WP_ENV_POST_INSTALL_ENVIRONMENT: environment, + }, + } ); + } catch ( e ) { + throw new Error( `${ environment } postInstall: ${ e.stderr }` ); + } + } } /** From 6c866239e13ecf8e42a6d6c672fc02cc3475aaaa Mon Sep 17 00:00:00 2001 From: Christopher Allford <6451942+ObliviousHarmony@users.noreply.github.com> Date: Fri, 21 Apr 2023 09:35:09 -0700 Subject: [PATCH 03/10] Execute `postInstall` On `clean` This adds an optional flag for executing the post-install commands when the environment is cleaned. --- packages/env/CHANGELOG.md | 1 + packages/env/lib/cli.js | 12 ++++++++++++ packages/env/lib/commands/clean.js | 24 +++++++++++++++++++++--- packages/env/lib/commands/start.js | 27 ++++++++++++++++++++------- 4 files changed, 54 insertions(+), 10 deletions(-) diff --git a/packages/env/CHANGELOG.md b/packages/env/CHANGELOG.md index 4f5c477fb18841..4e8620957fac6d 100644 --- a/packages/env/CHANGELOG.md +++ b/packages/env/CHANGELOG.md @@ -13,6 +13,7 @@ - Create a `postInstall` property in `.wp-env.json` files for setting arbitrary commands to run after configuring WordPress. - Add a `WP_ENV_POST_INSTALL` environment variable to override the current `postInstall` configuration. - Run the `postInstall` command on `wp-env start` when WordPress is being configures due to cache invalidation or the `--update` option. +- Run the `postInstall` command on `wp-env clean` when given the `--post-install` option. ## 5.16.0 (2023-04-12) diff --git a/packages/env/lib/cli.js b/packages/env/lib/cli.js index 68316855c6bede..62770a7cc727d4 100644 --- a/packages/env/lib/cli.js +++ b/packages/env/lib/cli.js @@ -112,6 +112,12 @@ module.exports = function cli() { ) }} (override with WP_ENV_TESTS_PORT). The current working directory must be a WordPress installation, a plugin, a theme, or contain a .wp-env.json file. After first install, use the '--update' flag to download updates to mapped sources and to re-apply WordPress configuration options.` ), ( args ) => { + args.option( 'post-install', { + type: 'boolean', + describe: + 'Execute any configured post-install command(s) when configuring WordPress.', + default: true, + } ); args.option( 'update', { type: 'boolean', describe: @@ -145,6 +151,12 @@ module.exports = function cli() { choices: [ 'all', 'development', 'tests' ], default: 'tests', } ); + args.option( 'post-install', { + type: 'boolean', + describe: + "Execute the environment's configured post-install command(s) if configured.", + default: false, + } ); }, withSpinner( env.clean ) ); diff --git a/packages/env/lib/commands/clean.js b/packages/env/lib/commands/clean.js index 26963849f0f142..4da7bdfcc97569 100644 --- a/packages/env/lib/commands/clean.js +++ b/packages/env/lib/commands/clean.js @@ -19,10 +19,16 @@ const { configureWordPress, resetDatabase } = require( '../wordpress' ); * * @param {Object} options * @param {WPEnvironmentSelection} options.environment The environment to clean. Either 'development', 'tests', or 'all'. + * @param {boolean} options.postInstall Indicates whether or not we should run post-install command(s). * @param {Object} options.spinner A CLI spinner which indicates progress. * @param {boolean} options.debug True if debug mode is enabled. */ -module.exports = async function clean( { environment, spinner, debug } ) { +module.exports = async function clean( { + environment, + postInstall, + spinner, + debug, +} ) { const config = await initConfig( { spinner, debug } ); const description = `${ environment } environment${ @@ -42,7 +48,13 @@ module.exports = async function clean( { environment, spinner, debug } ) { if ( environment === 'all' || environment === 'development' ) { tasks.push( resetDatabase( 'development', config ) - .then( () => configureWordPress( 'development', config, null ) ) + .then( () => + configureWordPress( + 'development', + config, + postInstall ? 'clean' : null + ) + ) .catch( () => {} ) ); } @@ -50,7 +62,13 @@ module.exports = async function clean( { environment, spinner, debug } ) { if ( environment === 'all' || environment === 'tests' ) { tasks.push( resetDatabase( 'tests', config ) - .then( () => configureWordPress( 'tests', config, null ) ) + .then( () => + configureWordPress( + 'tests', + config, + postInstall ? 'clean' : null + ) + ) .catch( () => {} ) ); } diff --git a/packages/env/lib/commands/start.js b/packages/env/lib/commands/start.js index 8cd22fb68edfea..38ba306c2f2fd7 100644 --- a/packages/env/lib/commands/start.js +++ b/packages/env/lib/commands/start.js @@ -40,12 +40,19 @@ const CONFIG_CACHE_KEY = 'config_checksum'; * Starts the development server. * * @param {Object} options - * @param {Object} options.spinner A CLI spinner which indicates progress. - * @param {boolean} options.debug True if debug mode is enabled. - * @param {boolean} options.update If true, update sources. - * @param {string} options.xdebug The Xdebug mode to set. + * @param {boolean} options.postInstall Indicates whether or not we should skip the post-install command(s). + * @param {Object} options.spinner A CLI spinner which indicates progress. + * @param {boolean} options.debug True if debug mode is enabled. + * @param {boolean} options.update If true, update sources. + * @param {string} options.xdebug The Xdebug mode to set. */ -module.exports = async function start( { spinner, debug, update, xdebug } ) { +module.exports = async function start( { + spinner, + postInstall, + debug, + update, + xdebug, +} ) { spinner.text = 'Reading configuration.'; await checkForLegacyInstall( spinner ); @@ -183,7 +190,7 @@ module.exports = async function start( { spinner, debug, update, xdebug } ) { configureWordPress( 'development', config, - 'start', + postInstall ? 'start' : null, spinner ), { @@ -191,7 +198,13 @@ module.exports = async function start( { spinner, debug, update, xdebug } ) { } ), retry( - () => configureWordPress( 'tests', config, 'start', spinner ), + () => + configureWordPress( + 'tests', + config, + postInstall ? 'start' : null, + spinner + ), { times: 2, } From ce028106741ef59a5af7d33790d3ebcf3101fc64 Mon Sep 17 00:00:00 2001 From: Christopher Allford <6451942+ObliviousHarmony@users.noreply.github.com> Date: Fri, 21 Apr 2023 09:55:13 -0700 Subject: [PATCH 04/10] Documented `postInstall` Functionality --- packages/env/README.md | 58 ++++++++++++++++++++++-------- packages/env/lib/cli.js | 4 +-- packages/env/lib/commands/clean.js | 2 +- packages/env/lib/commands/start.js | 2 +- packages/env/lib/config/config.js | 2 +- packages/env/lib/wordpress.js | 4 +-- 6 files changed, 50 insertions(+), 22 deletions(-) diff --git a/packages/env/README.md b/packages/env/README.md index 69a99ac76e3fad..b9ab7821392369 100644 --- a/packages/env/README.md +++ b/packages/env/README.md @@ -270,23 +270,27 @@ The start command installs and initializes the WordPress environment, which incl ```sh wp-env start -Starts WordPress for development on port 8888 (override with WP_ENV_PORT) and -tests on port 8889 (override with WP_ENV_TESTS_PORT). The current working -directory must be a WordPress installation, a plugin, a theme, or contain a -.wp-env.json file. After first install, use the '--update' flag to download -updates to mapped sources and to re-apply WordPress configuration options. +Starts WordPress for development on port 8888 (​http://localhost:8888​) +(override with WP_ENV_PORT) and tests on port 8889 (​http://localhost:8889​) +(override with WP_ENV_TESTS_PORT). The current working directory must be a +WordPress installation, a plugin, a theme, or contain a .wp-env.json file. After +first install, use the '--update' flag to download updates to mapped sources and +to re-apply WordPress configuration options. Options: - --help Show help [boolean] - --version Show version number [boolean] - --debug Enable debug output. [boolean] [default: false] - --update Download source updates and apply WordPress configuration. + --help Show help [boolean] + --version Show version number [boolean] + --debug Enable debug output. [boolean] [default: false] + --post-install Execute any configured post-install command when configuring + WordPress. [boolean] [default: true] + --update Download source updates and apply WordPress configuration. [boolean] [default: false] - --xdebug Enables Xdebug. If not passed, Xdebug is turned off. If no modes - are set, uses "debug". You may set multiple Xdebug modes by passing - them in a comma-separated list: `--xdebug=develop,coverage`. See - https://xdebug.org/docs/all_settings#mode for information about - Xdebug modes. [string] + --xdebug Enables Xdebug. If not passed, Xdebug is turned off. If no + modes are set, uses "debug". You may set multiple Xdebug modes + by passing them in a comma-separated list: + `--xdebug=develop,coverage`. See + https://xdebug.org/docs/all_settings#mode for information + about Xdebug modes. [string] ``` ### `wp-env stop` @@ -307,6 +311,13 @@ Cleans the WordPress databases. Positionals: environment Which environments' databases to clean. [string] [choices: "all", "development", "tests"] [default: "tests"] + +Options: + --help Show help [boolean] + --version Show version number [boolean] + --debug Enable debug output. [boolean] [default: false] + --post-install Execute the environments' configured post-install command if + configured. [boolean] [default: false] ``` ### `wp-env run [container] [command]` @@ -471,7 +482,7 @@ You can customize the WordPress installation, plugins and themes that the develo | `"testsPort"` | `integer` | `8889` | The port number for the test site. You'll access the instance through the port: 'http://localhost:8889'. | | `"config"` | `Object` | See below. | Mapping of wp-config.php constants to their desired values. | | `"mappings"` | `Object` | `"{}"` | Mapping of WordPress directories to local directories to be mounted in the WordPress instance. | -| `"postInstall"` | `string\|null` | `null` | The command(s) that should be executed after configuring WordPress. | +| `"postInstall"` | `string\|null` | `null` | The command that should be executed after configuring WordPress. | _Note: the port number environment variables (`WP_ENV_PORT` and `WP_ENV_TESTS_PORT`) take precedent over the .wp-env.json values._ @@ -669,6 +680,23 @@ You can tell `wp-env` to use a specific PHP version for compatibility and testin } ``` +#### Post-Install Command + +You can define a command for `wp-env` to run after configuring WordPress. This will happen the first time you run `wp-env start`, whenever you change the configuration, +and when you use the `--update` option. You can also instruct `wp-env` to run the command on `wp-env clean` with the `--post-install` option. +The `WP_ENV_POST_INSTALL` environment variable can be used to override the configured command. + +```json +{ + "postInstall": "echo 'Running Post-Install'" +} +``` + +Additional environment variables are given to the command to provide context about the execution: + +- `WP_ENV_POST_INSTALL_CONTEXT` contains the command that triggered the execution, either `start` or `clean`. +- `WP_ENV_POST_INSTALL_ENVIRONMENT` contains the environment that the command is being executed for, such as `development` or `tests`. + ## Contributing to this package This is an individual package that's part of the Gutenberg project. The project is organized as a monorepo. It's made up of multiple self-contained software packages, each with a specific purpose. The packages in this monorepo are published to [npm](https://www.npmjs.com/) and used by [WordPress](https://make.wordpress.org/core/) as well as other software projects. diff --git a/packages/env/lib/cli.js b/packages/env/lib/cli.js index 62770a7cc727d4..a705e633e70222 100644 --- a/packages/env/lib/cli.js +++ b/packages/env/lib/cli.js @@ -115,7 +115,7 @@ module.exports = function cli() { args.option( 'post-install', { type: 'boolean', describe: - 'Execute any configured post-install command(s) when configuring WordPress.', + 'Execute any configured post-install command when configuring WordPress.', default: true, } ); args.option( 'update', { @@ -154,7 +154,7 @@ module.exports = function cli() { args.option( 'post-install', { type: 'boolean', describe: - "Execute the environment's configured post-install command(s) if configured.", + "Execute the environments' configured post-install command if configured.", default: false, } ); }, diff --git a/packages/env/lib/commands/clean.js b/packages/env/lib/commands/clean.js index 4da7bdfcc97569..85e103aeafe6d7 100644 --- a/packages/env/lib/commands/clean.js +++ b/packages/env/lib/commands/clean.js @@ -19,7 +19,7 @@ const { configureWordPress, resetDatabase } = require( '../wordpress' ); * * @param {Object} options * @param {WPEnvironmentSelection} options.environment The environment to clean. Either 'development', 'tests', or 'all'. - * @param {boolean} options.postInstall Indicates whether or not we should run post-install command(s). + * @param {boolean} options.postInstall Indicates whether or not we should run the post-install command. * @param {Object} options.spinner A CLI spinner which indicates progress. * @param {boolean} options.debug True if debug mode is enabled. */ diff --git a/packages/env/lib/commands/start.js b/packages/env/lib/commands/start.js index 38ba306c2f2fd7..c0002864088a98 100644 --- a/packages/env/lib/commands/start.js +++ b/packages/env/lib/commands/start.js @@ -40,7 +40,7 @@ const CONFIG_CACHE_KEY = 'config_checksum'; * Starts the development server. * * @param {Object} options - * @param {boolean} options.postInstall Indicates whether or not we should skip the post-install command(s). + * @param {boolean} options.postInstall Indicates whether or not we should skip the post-install command. * @param {Object} options.spinner A CLI spinner which indicates progress. * @param {boolean} options.debug True if debug mode is enabled. * @param {boolean} options.update If true, update sources. diff --git a/packages/env/lib/config/config.js b/packages/env/lib/config/config.js index 476a45d52176e7..8c0aa7f1836eee 100644 --- a/packages/env/lib/config/config.js +++ b/packages/env/lib/config/config.js @@ -42,7 +42,7 @@ const md5 = require( '../md5' ); * @property {WPSource[]} themeSources Themes to load in the environment. * @property {Object} config Mapping of wp-config.php constants to their desired values. * @property {Object.} mappings Mapping of WordPress directories to local directories which should be mounted. - * @property {string|null} postInstall The command(s) to run after configuring WordPress. + * @property {string|null} postInstall The command to run after configuring WordPress. */ /** diff --git a/packages/env/lib/wordpress.js b/packages/env/lib/wordpress.js index 30bbd230ddc99c..a5fc7e83d11b54 100644 --- a/packages/env/lib/wordpress.js +++ b/packages/env/lib/wordpress.js @@ -42,7 +42,7 @@ async function checkDatabaseConnection( { dockerComposeConfigPath, debug } ) { * * @param {WPEnvironment} environment The environment to configure. Either 'development' or 'tests'. * @param {WPConfig} config The wp-env config object. - * @param {string|null} postInstallContext The context that will be set when executing postInstall command(s). When null, postInstall won't run. + * @param {string|null} postInstallContext The context that will be set when executing postInstall command. When null, postInstall won't run. * @param {Object} spinner A CLI spinner which indicates progress. */ async function configureWordPress( @@ -115,7 +115,7 @@ async function configureWordPress( // At this point, WordPress has been configured and the environment should be ready. // We're going to support a "postInstall" configuration option so that users can - // have the environment arbitrarily execute command(s) for additional setup. + // have the environment arbitrarily execute command for additional setup. if ( postInstallContext && config.env[ environment ].postInstall ) { try { execSync( config.env[ environment ].postInstall, { From 9234d22a30a082630642439d7f6b5f47817a730d Mon Sep 17 00:00:00 2001 From: Christopher Allford <6451942+ObliviousHarmony@users.noreply.github.com> Date: Fri, 21 Apr 2023 10:16:20 -0700 Subject: [PATCH 05/10] Added Post-Install Debug Variable --- packages/env/README.md | 1 + packages/env/lib/wordpress.js | 1 + 2 files changed, 2 insertions(+) diff --git a/packages/env/README.md b/packages/env/README.md index b9ab7821392369..d01367a2c32d84 100644 --- a/packages/env/README.md +++ b/packages/env/README.md @@ -696,6 +696,7 @@ Additional environment variables are given to the command to provide context abo - `WP_ENV_POST_INSTALL_CONTEXT` contains the command that triggered the execution, either `start` or `clean`. - `WP_ENV_POST_INSTALL_ENVIRONMENT` contains the environment that the command is being executed for, such as `development` or `tests`. +- `WP_ENV_POST_INSTALL_DEBUG` contains a boolean indicating whether or not `wp-env` is in debug mode. ## Contributing to this package diff --git a/packages/env/lib/wordpress.js b/packages/env/lib/wordpress.js index a5fc7e83d11b54..c43483c42431e4 100644 --- a/packages/env/lib/wordpress.js +++ b/packages/env/lib/wordpress.js @@ -126,6 +126,7 @@ async function configureWordPress( ...process.env, WP_ENV_POST_INSTALL_CONTEXT: postInstallContext, WP_ENV_POST_INSTALL_ENVIRONMENT: environment, + WP_ENV_POST_INSTALL_DEBUG: config.debug, }, } ); } catch ( e ) { From b9dff638d01738fd1eb68339affeca5d0a550e87 Mon Sep 17 00:00:00 2001 From: Christopher Allford <6451942+ObliviousHarmony@users.noreply.github.com> Date: Fri, 21 Apr 2023 10:41:32 -0700 Subject: [PATCH 06/10] Prettified Post-Install Output/Errors --- packages/env/README.md | 2 ++ packages/env/lib/cli.js | 4 ++++ packages/env/lib/env.js | 4 +++- packages/env/lib/wordpress.js | 24 ++++++++++++++++++++---- 4 files changed, 29 insertions(+), 5 deletions(-) diff --git a/packages/env/README.md b/packages/env/README.md index d01367a2c32d84..26bceafdd7b017 100644 --- a/packages/env/README.md +++ b/packages/env/README.md @@ -698,6 +698,8 @@ Additional environment variables are given to the command to provide context abo - `WP_ENV_POST_INSTALL_ENVIRONMENT` contains the environment that the command is being executed for, such as `development` or `tests`. - `WP_ENV_POST_INSTALL_DEBUG` contains a boolean indicating whether or not `wp-env` is in debug mode. +> **Warning:** This command will not always be executed on a fresh environment. It should be resilient and not fail if a step has already been completed. + ## Contributing to this package This is an individual package that's part of the Gutenberg project. The project is organized as a monorepo. It's made up of multiple self-contained software packages, each with a specific purpose. The packages in this monorepo are published to [npm](https://www.npmjs.com/) and used by [WordPress](https://make.wordpress.org/core/) as well as other software projects. diff --git a/packages/env/lib/cli.js b/packages/env/lib/cli.js index a705e633e70222..27b087b1709d49 100644 --- a/packages/env/lib/cli.js +++ b/packages/env/lib/cli.js @@ -43,6 +43,10 @@ const withSpinner = // Error is a validation error. That means the user did something wrong. spinner.fail( error.message ); process.exit( 1 ); + } else if ( error instanceof env.PostInstallError ) { + // Error is a post-install command error. This means their command failed and they should be notified. + spinner.fail( error.message ); + process.exit( 1 ); } else if ( error && typeof error === 'object' && diff --git a/packages/env/lib/env.js b/packages/env/lib/env.js index 3942a307109377..0f0f5459f9bab1 100644 --- a/packages/env/lib/env.js +++ b/packages/env/lib/env.js @@ -2,10 +2,12 @@ /** * Internal dependencies */ -const { ValidationError } = require( './config' ); const commands = require( './commands' ); +const { ValidationError } = require( './config' ); +const { PostInstallError } = require( './wordpress' ); module.exports = { ...commands, ValidationError, + PostInstallError, }; diff --git a/packages/env/lib/wordpress.js b/packages/env/lib/wordpress.js index c43483c42431e4..133af5a49651d7 100644 --- a/packages/env/lib/wordpress.js +++ b/packages/env/lib/wordpress.js @@ -21,6 +21,12 @@ const copyDir = util.promisify( require( 'copy-dir' ) ); * @typedef {'development'|'tests'|'all'} WPEnvironmentSelection */ +/** + * Error subtype which indicates that an expected validation erorr occurred + * while reading wp-env configuration. + */ +class PostInstallError extends Error {} + /** * Checks a WordPress database connection. An error is thrown if the test is * unsuccessful. @@ -118,10 +124,9 @@ async function configureWordPress( // have the environment arbitrarily execute command for additional setup. if ( postInstallContext && config.env[ environment ].postInstall ) { try { - execSync( config.env[ environment ].postInstall, { + let output = execSync( config.env[ environment ].postInstall, { encoding: 'utf-8', - // We're going to let the script decide what it wants to output. - stdio: [ 'ignore', 'inherit', 'pipe' ], + stdio: 'pipe', env: { ...process.env, WP_ENV_POST_INSTALL_CONTEXT: postInstallContext, @@ -129,8 +134,18 @@ async function configureWordPress( WP_ENV_POST_INSTALL_DEBUG: config.debug, }, } ); + + // Remove any trailing whitespace for nicer output. + output = output.trimRight(); + + // We don't need to bother with any output if there isn't any! + if ( output ) { + spinner.info( `${ environment } Post-Install:\n${ output }` ); + } } catch ( e ) { - throw new Error( `${ environment } postInstall: ${ e.stderr }` ); + throw new PostInstallError( + `${ environment } Post-Install:\n${ e.stderr }` + ); } } } @@ -312,6 +327,7 @@ async function getLatestWordPressVersion() { } module.exports = { + PostInstallError, hasSameCoreSource, checkDatabaseConnection, configureWordPress, From a8bd9aa7c295d734fab6554959a430f41da7a4ac Mon Sep 17 00:00:00 2001 From: Christopher Allford <6451942+ObliviousHarmony@users.noreply.github.com> Date: Fri, 21 Apr 2023 14:17:21 -0700 Subject: [PATCH 07/10] Update packages/env/CHANGELOG.md Co-authored-by: Noah Allen --- packages/env/CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/env/CHANGELOG.md b/packages/env/CHANGELOG.md index 4e8620957fac6d..b70e8fdd0dd12b 100644 --- a/packages/env/CHANGELOG.md +++ b/packages/env/CHANGELOG.md @@ -12,7 +12,7 @@ - Create a `postInstall` property in `.wp-env.json` files for setting arbitrary commands to run after configuring WordPress. - Add a `WP_ENV_POST_INSTALL` environment variable to override the current `postInstall` configuration. -- Run the `postInstall` command on `wp-env start` when WordPress is being configures due to cache invalidation or the `--update` option. +- Run the `postInstall` command on `wp-env start` when WordPress is being configured. This can happen when your config changes, WordPress updates, or you pass the `--update` flag. - Run the `postInstall` command on `wp-env clean` when given the `--post-install` option. ## 5.16.0 (2023-04-12) From 925d788ceaca95e69010e62dc08da7f78455f968 Mon Sep 17 00:00:00 2001 From: Christopher Allford <6451942+ObliviousHarmony@users.noreply.github.com> Date: Fri, 21 Apr 2023 14:17:45 -0700 Subject: [PATCH 08/10] Update packages/env/README.md Co-authored-by: Noah Allen --- packages/env/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/env/README.md b/packages/env/README.md index 26bceafdd7b017..815117b9bdf516 100644 --- a/packages/env/README.md +++ b/packages/env/README.md @@ -695,7 +695,7 @@ The `WP_ENV_POST_INSTALL` environment variable can be used to override the confi Additional environment variables are given to the command to provide context about the execution: - `WP_ENV_POST_INSTALL_CONTEXT` contains the command that triggered the execution, either `start` or `clean`. -- `WP_ENV_POST_INSTALL_ENVIRONMENT` contains the environment that the command is being executed for, such as `development` or `tests`. +- `WP_ENV_POST_INSTALL_ENVIRONMENT` contains the WordPress environment that the command is being executed for, such as `development` or `tests`. - `WP_ENV_POST_INSTALL_DEBUG` contains a boolean indicating whether or not `wp-env` is in debug mode. > **Warning:** This command will not always be executed on a fresh environment. It should be resilient and not fail if a step has already been completed. From 8a2121f45fc2fde6e12aa7c0ef7e3e72ebffb8c6 Mon Sep 17 00:00:00 2001 From: Christopher Allford <6451942+ObliviousHarmony@users.noreply.github.com> Date: Fri, 21 Apr 2023 14:18:03 -0700 Subject: [PATCH 09/10] Update packages/env/README.md Co-authored-by: Noah Allen --- packages/env/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/env/README.md b/packages/env/README.md index 815117b9bdf516..8c223fe60a5fa3 100644 --- a/packages/env/README.md +++ b/packages/env/README.md @@ -698,7 +698,7 @@ Additional environment variables are given to the command to provide context abo - `WP_ENV_POST_INSTALL_ENVIRONMENT` contains the WordPress environment that the command is being executed for, such as `development` or `tests`. - `WP_ENV_POST_INSTALL_DEBUG` contains a boolean indicating whether or not `wp-env` is in debug mode. -> **Warning:** This command will not always be executed on a fresh environment. It should be resilient and not fail if a step has already been completed. +> **Warning:** This command can be executed frequently. It should be resilient and not fail if a step has already been completed. For example, you should take care not to add data to the database if it was already done. ## Contributing to this package From 1b12628c348123725972d5c95300baa0ab4fb770 Mon Sep 17 00:00:00 2001 From: Christopher Allford <6451942+ObliviousHarmony@users.noreply.github.com> Date: Fri, 21 Apr 2023 14:18:43 -0700 Subject: [PATCH 10/10] Update packages/env/lib/wordpress.js Co-authored-by: Noah Allen --- packages/env/lib/wordpress.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/env/lib/wordpress.js b/packages/env/lib/wordpress.js index 133af5a49651d7..4c2ef059765a4d 100644 --- a/packages/env/lib/wordpress.js +++ b/packages/env/lib/wordpress.js @@ -22,8 +22,7 @@ const copyDir = util.promisify( require( 'copy-dir' ) ); */ /** - * Error subtype which indicates that an expected validation erorr occurred - * while reading wp-env configuration. + * Error subtype which indicates that the post install command failed. */ class PostInstallError extends Error {}