diff options
Diffstat (limited to 'tools/local-env/scripts')
-rw-r--r-- | tools/local-env/scripts/docker.js | 33 | ||||
-rw-r--r-- | tools/local-env/scripts/install.js | 37 | ||||
-rw-r--r-- | tools/local-env/scripts/start.js | 61 | ||||
-rw-r--r-- | tools/local-env/scripts/utils.js | 10 |
4 files changed, 106 insertions, 35 deletions
diff --git a/tools/local-env/scripts/docker.js b/tools/local-env/scripts/docker.js index c1dc2b27e1..e39b42a812 100644 --- a/tools/local-env/scripts/docker.js +++ b/tools/local-env/scripts/docker.js @@ -1,21 +1,36 @@ -const dotenv = require( 'dotenv' ); +/* jshint node:true */ + +const dotenv = require( 'dotenv' ); const dotenvExpand = require( 'dotenv-expand' ); -const { execSync } = require( 'child_process' ); +const { spawnSync } = require( 'child_process' ); const local_env_utils = require( './utils' ); dotenvExpand.expand( dotenv.config() ); const composeFiles = local_env_utils.get_compose_files(); -if (process.argv.includes('--coverage-html')) { +if ( process.argv.includes( '--coverage-html' ) ) { process.env.LOCAL_PHP_XDEBUG = 'true'; process.env.LOCAL_PHP_XDEBUG_MODE = 'coverage'; } -// This try-catch prevents the superfluous Node.js debugging information from being shown if the command fails. -try { - // Execute any Docker compose command passed to this script. - execSync( 'docker compose ' + composeFiles + ' ' + process.argv.slice( 2 ).join( ' ' ), { stdio: 'inherit' } ); -} catch ( error ) { - process.exit( 1 ); +// Add --no-TTY (-T) arg after exec and run commands when STDIN is not a TTY. +const dockerCommand = process.argv.slice( 2 ); +if ( [ 'exec', 'run' ].includes( dockerCommand[0] ) && ! process.stdin.isTTY ) { + dockerCommand.splice( 1, 0, '--no-TTY' ); } + +// Execute any Docker compose command passed to this script. +const returns = spawnSync( + 'docker', + [ + 'compose', + ...composeFiles + .map( ( composeFile ) => [ '-f', composeFile ] ) + .flat(), + ...dockerCommand, + ], + { stdio: 'inherit' } +); + +process.exit( returns.status ); diff --git a/tools/local-env/scripts/install.js b/tools/local-env/scripts/install.js index f205047a5a..19a0f46e08 100644 --- a/tools/local-env/scripts/install.js +++ b/tools/local-env/scripts/install.js @@ -1,9 +1,10 @@ +/* jshint node:true */ + const dotenv = require( 'dotenv' ); const dotenvExpand = require( 'dotenv-expand' ); const wait_on = require( 'wait-on' ); const { execSync } = require( 'child_process' ); -const { renameSync, readFileSync, writeFileSync } = require( 'fs' ); -const { utils } = require( './utils.js' ); +const { readFileSync, writeFileSync } = require( 'fs' ); const local_env_utils = require( './utils' ); dotenvExpand.expand( dotenv.config() ); @@ -12,7 +13,10 @@ dotenvExpand.expand( dotenv.config() ); local_env_utils.determine_auth_option(); // Create wp-config.php. -wp_cli( 'config create --dbname=wordpress_develop --dbuser=root --dbpass=password --dbhost=mysql --force' ); +wp_cli( `config create --dbname=wordpress_develop --dbuser=root --dbpass=password --dbhost=mysql --force --config-file="wp-config.php"` ); + +// Since WP-CLI runs as root, the wp-config.php created above will be read-only. This needs to be writable for the sake of E2E tests. +execSync( 'node ./tools/local-env/scripts/docker.js exec cli chmod 666 wp-config.php' ); // Add the debug settings to wp-config.php. // Windows requires this to be done as an additional step, rather than using the --extra-php option in the previous step. @@ -23,26 +27,35 @@ wp_cli( `config set SCRIPT_DEBUG ${process.env.LOCAL_SCRIPT_DEBUG} --raw --type= wp_cli( `config set WP_ENVIRONMENT_TYPE ${process.env.LOCAL_WP_ENVIRONMENT_TYPE} --type=constant` ); wp_cli( `config set WP_DEVELOPMENT_MODE ${process.env.LOCAL_WP_DEVELOPMENT_MODE} --type=constant` ); -// Move wp-config.php to the base directory, so it doesn't get mixed up in the src or build directories. -renameSync( `${process.env.LOCAL_DIR}/wp-config.php`, 'wp-config.php' ); - // Read in wp-tests-config-sample.php, edit it to work with our config, then write it to wp-tests-config.php. const testConfig = readFileSync( 'wp-tests-config-sample.php', 'utf8' ) .replace( 'youremptytestdbnamehere', 'wordpress_develop_tests' ) .replace( 'yourusernamehere', 'root' ) .replace( 'yourpasswordhere', 'password' ) .replace( 'localhost', 'mysql' ) - .replace( "'WP_TESTS_DOMAIN', 'example.org'", `'WP_TESTS_DOMAIN', '${process.env.LOCAL_WP_TESTS_DOMAIN}'` ) - .concat( "\ndefine( 'FS_METHOD', 'direct' );\n" ); + .replace( `'WP_TESTS_DOMAIN', 'example.org'`, `'WP_TESTS_DOMAIN', '${process.env.LOCAL_WP_TESTS_DOMAIN}'` ) + .concat( `\ndefine( 'FS_METHOD', 'direct' );\n` ); writeFileSync( 'wp-tests-config.php', testConfig ); // Once the site is available, install WordPress! -wait_on( { resources: [ `tcp:localhost:${process.env.LOCAL_PORT}`] } ) +wait_on( { + resources: [ `tcp:localhost:${process.env.LOCAL_PORT}`], + timeout: 3000, +} ) + .catch( err => { + console.error( `Error: It appears the development environment has not been started. Message: ${ err.message }` ); + console.error( `Did you forget to do 'npm run env:start'?` ); + process.exit( 1 ); + } ) .then( () => { wp_cli( 'db reset --yes' ); const installCommand = process.env.LOCAL_MULTISITE === 'true' ? 'multisite-install' : 'install'; - wp_cli( `core ${ installCommand } --title="WordPress Develop" --admin_user=admin --admin_password=password --admin_email=test@test.com --skip-email --url=http://localhost:${process.env.LOCAL_PORT}` ); + wp_cli( `core ${ installCommand } --title="WordPress Develop" --admin_user=admin --admin_password=password --admin_email=test@example.com --skip-email --url=http://localhost:${process.env.LOCAL_PORT}` ); + } ) + .catch( err => { + console.error( `Error: Unable to reset DB and install WordPress. Message: ${ err.message }` ); + process.exit( 1 ); } ); /** @@ -51,7 +64,5 @@ wait_on( { resources: [ `tcp:localhost:${process.env.LOCAL_PORT}`] } ) * @param {string} cmd The WP-CLI command to run. */ function wp_cli( cmd ) { - const composeFiles = local_env_utils.get_compose_files(); - - execSync( `docker compose ${composeFiles} run --quiet-pull --rm cli ${cmd} --path=/var/www/${process.env.LOCAL_DIR}`, { stdio: 'inherit' } ); + execSync( `npm --silent run env:cli -- ${cmd} --path=/var/www/${process.env.LOCAL_DIR}`, { stdio: 'inherit' } ); } diff --git a/tools/local-env/scripts/start.js b/tools/local-env/scripts/start.js index 0dc8b95700..b0389b2fb0 100644 --- a/tools/local-env/scripts/start.js +++ b/tools/local-env/scripts/start.js @@ -1,11 +1,13 @@ +/* jshint node:true */ + const dotenv = require( 'dotenv' ); const dotenvExpand = require( 'dotenv-expand' ); -const { execSync } = require( 'child_process' ); +const { execSync, spawnSync } = require( 'child_process' ); const local_env_utils = require( './utils' ); const { constants, copyFile } = require( 'node:fs' ); // Copy the default .env file when one is not present. -copyFile( '.env.example', '.env', constants.COPYFILE_EXCL, (e) => { +copyFile( '.env.example', '.env', constants.COPYFILE_EXCL, () => { console.log( '.env file already exists. .env.example was not copied.' ); }); @@ -28,18 +30,38 @@ try { } // Start the local-env containers. -const containers = ( process.env.LOCAL_PHP_MEMCACHED === 'true' ) - ? 'wordpress-develop memcached' - : 'wordpress-develop'; -execSync( `docker compose ${composeFiles} up --quiet-pull -d ${containers}`, { stdio: 'inherit' } ); +const containers = [ 'wordpress-develop', 'cli' ]; +if ( process.env.LOCAL_PHP_MEMCACHED === 'true' ) { + containers.push( 'memcached' ); +} + +spawnSync( + 'docker', + [ + 'compose', + ...composeFiles.map( ( composeFile ) => [ '-f', composeFile ] ).flat(), + 'up', + '--quiet-pull', + '-d', + ...containers, + ], + { stdio: 'inherit' } +); // If Docker Toolbox is being used, we need to manually forward LOCAL_PORT to the Docker VM. if ( process.env.DOCKER_TOOLBOX_INSTALL_PATH ) { // VBoxManage is added to the PATH on every platform except Windows. - const vboxmanage = process.env.VBOX_MSI_INSTALL_PATH ? `${ process.env.VBOX_MSI_INSTALL_PATH }/VBoxManage` : 'VBoxManage' + const vboxmanage = process.env.VBOX_MSI_INSTALL_PATH ? `${ process.env.VBOX_MSI_INSTALL_PATH }/VBoxManage` : 'VBoxManage'; // Check if the port forwarding is already configured for this port. - const vminfoBuffer = execSync( `"${ vboxmanage }" showvminfo "${ process.env.DOCKER_MACHINE_NAME }" --machinereadable` ); + const vminfoBuffer = spawnSync( + vboxmanage, + [ + 'showvminfo', + process.env.DOCKER_MACHINE_NAME, + '--machinereadable' + ] + ).stdout; const vminfo = vminfoBuffer.toString().split( /[\r\n]+/ ); vminfo.forEach( ( info ) => { @@ -53,10 +75,29 @@ if ( process.env.DOCKER_TOOLBOX_INSTALL_PATH ) { // Delete rules that are using the port we need. if ( rule[ 3 ] === process.env.LOCAL_PORT || rule[ 5 ] === process.env.LOCAL_PORT ) { - execSync( `"${ vboxmanage }" controlvm "${ process.env.DOCKER_MACHINE_NAME }" natpf1 delete ${ rule[ 0 ] }`, { stdio: 'inherit' } ); + spawnSync( + vboxmanage, + [ + 'controlvm', + process.env.DOCKER_MACHINE_NAME, + 'natpf1', + 'delete', + rule[ 0 ] + ], + { stdio: 'inherit' } + ); } } ); // Add our port forwarding rule. - execSync( `"${ vboxmanage }" controlvm "${ process.env.DOCKER_MACHINE_NAME }" natpf1 "tcp-port${ process.env.LOCAL_PORT },tcp,127.0.0.1,${ process.env.LOCAL_PORT },,${ process.env.LOCAL_PORT }"`, { stdio: 'inherit' } ); + spawnSync( + vboxmanage, + [ + 'controlvm', + process.env.DOCKER_MACHINE_NAME, + 'natpf1', + `tcp-port${ process.env.LOCAL_PORT },tcp,127.0.0.1,${ process.env.LOCAL_PORT },,${ process.env.LOCAL_PORT }` + ], + { stdio: 'inherit' } + ); } diff --git a/tools/local-env/scripts/utils.js b/tools/local-env/scripts/utils.js index d76f3068a5..3f3e601db2 100644 --- a/tools/local-env/scripts/utils.js +++ b/tools/local-env/scripts/utils.js @@ -1,3 +1,5 @@ +/* jshint node:true */ + const { existsSync } = require( 'node:fs' ); const local_env_utils = { @@ -10,12 +12,14 @@ const local_env_utils = { * * When PHP 7.2 or 7.3 is used in combination with MySQL 8.4, an override file will also be returned to ensure * that the mysql_native_password plugin authentication plugin is on and available for use. + * + * @return {string[]} Compose files. */ get_compose_files: function() { - var composeFiles = '-f docker-compose.yml'; + const composeFiles = [ 'docker-compose.yml' ]; if ( existsSync( 'docker-compose.override.yml' ) ) { - composeFiles = composeFiles + ' -f docker-compose.override.yml'; + composeFiles.push( 'docker-compose.override.yml' ); } if ( process.env.LOCAL_DB_TYPE !== 'mysql' ) { @@ -28,7 +32,7 @@ const local_env_utils = { // PHP 7.2/7.3 in combination with MySQL 8.4 requires additional configuration to function properly. if ( process.env.LOCAL_DB_VERSION === '8.4' ) { - composeFiles = composeFiles + ' -f tools/local-env/old-php-mysql-84.override.yml'; + composeFiles.push( 'tools/local-env/old-php-mysql-84.override.yml' ); } return composeFiles; |