@wordpress/env 4.9.0 → 5.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +27 -0
- package/README.md +25 -13
- package/lib/build-docker-compose-config.js +33 -8
- package/lib/commands/run.js +6 -6
- package/lib/commands/start.js +22 -2
- package/lib/config/config.js +32 -36
- package/lib/config/parse-config.js +18 -2
- package/lib/config/test/__snapshots__/config.js.snap +4 -6
- package/lib/config/test/config.js +80 -39
- package/lib/download-sources.js +3 -3
- package/lib/download-wp-phpunit.js +140 -0
- package/lib/wordpress.js +66 -14
- package/package.json +3 -3
package/CHANGELOG.md
CHANGED
|
@@ -2,7 +2,34 @@
|
|
|
2
2
|
|
|
3
3
|
## Unreleased
|
|
4
4
|
|
|
5
|
+
## 5.1.1 (2022-08-16)
|
|
6
|
+
|
|
7
|
+
### Bug Fix
|
|
8
|
+
- Fix a crash when "core" was set to `null` in a `.wp-env.json` file. We now use the latest stable WordPress version in that case. This also restores the previous behavior of `"core": null` in `.wp-env.override.json`, which was to use the latest stable WordPress version.
|
|
9
|
+
|
|
10
|
+
## 5.1.0 (2022-08-10)
|
|
11
|
+
|
|
12
|
+
### Enhancement
|
|
13
|
+
- Previously, wp-env used the WordPress version provided by Docker in the WordPress image for installations which don't specify a WordPress version. Now, wp-env will find the latest stable version on WordPress.org and check out the https://github.com/WordPress/WordPress repository at the tag matching that version. In most cases, this will match what Docker provides. The benefit is that wp-env (and WordPress.org) now controls the default WordPress version rather than Docker.
|
|
14
|
+
|
|
15
|
+
### Bug Fix
|
|
16
|
+
- Downloading a default WordPress version also resolves a bug where the wrong WordPress test files were used if no core source was specified in wp-env.json. The current trunk test files were downloaded rather than the stable version. Now, the test files will match the default stable version.
|
|
17
|
+
|
|
18
|
+
## 5.0.0 (2022-07-27)
|
|
19
|
+
|
|
20
|
+
### Breaking Changes
|
|
21
|
+
- Removed the `WP_PHPUNIT__TESTS_CONFIG` environment variable from the `phpunit` container. **This removes automatic support for the `wp-phpunit/wp-phpunit` Composer package. To continue using the package, set the following two environment variables in your `phpunit.xml` file or similar: `WP_TESTS_DIR=""` and `WP_PHPUNIT__TESTS_CONFIG="/wordpress-phpunit/wp-tests-config.php"`.**
|
|
22
|
+
- Removed the generated `/var/www/html/phpunit-wp-config.php` file from the environment.
|
|
23
|
+
|
|
24
|
+
### Enhancement
|
|
25
|
+
- Read WordPress' version and include the corresponding PHPUnit test files in the environment.
|
|
26
|
+
- Set the `WP_TESTS_DIR` environment variable in all containers to point at the PHPUnit test files.
|
|
27
|
+
|
|
28
|
+
### Bug Fix
|
|
29
|
+
- Restrict `WP_TESTS_DOMAIN` constant to just hostname rather than an entire URL (e.g. it now excludes scheme, port, etc.) ([#41039](https://github.com/WordPress/gutenberg/pull/41039)).
|
|
30
|
+
|
|
5
31
|
## 4.8.0 (2022-06-01)
|
|
32
|
+
|
|
6
33
|
### Enhancement
|
|
7
34
|
- Removed the need for quotation marks when passing options to `wp-env run`.
|
|
8
35
|
- Setting a `config` key to `null` will prevent adding the constant to `wp-config.php` even if a default value is defined by `wp-env`.
|
package/README.md
CHANGED
|
@@ -16,7 +16,7 @@ The local environment will be available at http://localhost:8888 (Username: `adm
|
|
|
16
16
|
|
|
17
17
|
## Prerequisites
|
|
18
18
|
|
|
19
|
-
`wp-env` requires Docker to be installed. There are instructions available for installing Docker on [Windows
|
|
19
|
+
`wp-env` requires Docker to be installed. There are instructions available for installing Docker on [Windows](https://docs.docker.com/desktop/install/windows-install/), [macOS](https://docs.docker.com/docker-for-mac/install/), and [Linux](https://docs.docker.com/desktop/install/linux-install/).
|
|
20
20
|
|
|
21
21
|
Node.js and NPM are required. The latest LTS version of Node.js is used to develop `wp-env` and is recommended.
|
|
22
22
|
|
|
@@ -40,7 +40,9 @@ If your project already has a package.json, it's also possible to use `wp-env` a
|
|
|
40
40
|
$ npm i @wordpress/env --save-dev
|
|
41
41
|
```
|
|
42
42
|
|
|
43
|
-
|
|
43
|
+
At this point, you can use the local, project-level version of wp-env via [`npx`](https://www.npmjs.com/package/npx), a utility automatically installed with `npm`.`npx` finds binaries like wp-env installed through node modules. As an example: `npx wp-env start --update`.
|
|
44
|
+
|
|
45
|
+
If you don't wish to use `npx`, modify your package.json and add an extra command to npm `scripts` (https://docs.npmjs.com/misc/scripts):
|
|
44
46
|
|
|
45
47
|
```json
|
|
46
48
|
"scripts": {
|
|
@@ -51,7 +53,7 @@ Then modify your package.json and add an extra command to npm `scripts` (https:/
|
|
|
51
53
|
When installing `wp-env` in this way, all `wp-env` commands detailed in these docs must be prefixed with `npm run`, for example:
|
|
52
54
|
|
|
53
55
|
```sh
|
|
54
|
-
# You must add another double dash to pass
|
|
56
|
+
# You must add another double dash to pass flags to the script (wp-env) rather than to npm itself
|
|
55
57
|
$ npm run wp-env start -- --update
|
|
56
58
|
```
|
|
57
59
|
|
|
@@ -117,15 +119,14 @@ Running `docker ps` and inspecting the `PORTS` column allows you to determine wh
|
|
|
117
119
|
|
|
118
120
|
You may also specify the port numbers in your `.wp-env.json` file, but the environment variables take precedent.
|
|
119
121
|
|
|
120
|
-
### 3. Restart `wp-env`
|
|
122
|
+
### 3. Restart `wp-env` with updates
|
|
121
123
|
|
|
122
124
|
Restarting `wp-env` will restart the underlying Docker containers which can fix many issues.
|
|
123
125
|
|
|
124
|
-
To restart `wp-env
|
|
126
|
+
To restart `wp-env`, just run `wp-env start` again. It will automatically stop and start the container. If you also pass the `--update` argument, it will download updates and configure WordPress agian.
|
|
125
127
|
|
|
126
128
|
```sh
|
|
127
|
-
$ wp-env
|
|
128
|
-
$ wp-env start
|
|
129
|
+
$ wp-env start --update
|
|
129
130
|
```
|
|
130
131
|
|
|
131
132
|
### 4. Restart Docker
|
|
@@ -156,16 +157,17 @@ $ wp-env clean all
|
|
|
156
157
|
$ wp-env start
|
|
157
158
|
```
|
|
158
159
|
|
|
159
|
-
### 6.
|
|
160
|
+
### 6. Destroy everything and start again 🔥
|
|
160
161
|
|
|
161
|
-
When all else fails, you can use `wp-env destroy` to forcibly remove all of the underlying Docker containers and
|
|
162
|
+
When all else fails, you can use `wp-env destroy` to forcibly remove all of the underlying Docker containers, volumes, and files. This will allow you to start from scratch.
|
|
162
163
|
|
|
163
|
-
To
|
|
164
|
+
To do so:
|
|
164
165
|
|
|
165
166
|
**⚠️ WARNING: This will permanently delete any posts, pages, media, etc. in the local WordPress installation.**
|
|
166
167
|
|
|
167
168
|
```sh
|
|
168
169
|
$ wp-env destroy
|
|
170
|
+
# This new instance is a fresh start with no existing data:
|
|
169
171
|
$ wp-env start
|
|
170
172
|
```
|
|
171
173
|
|
|
@@ -188,6 +190,14 @@ wp-env start --debug
|
|
|
188
190
|
...
|
|
189
191
|
```
|
|
190
192
|
|
|
193
|
+
## Using included WordPress PHPUnit test files
|
|
194
|
+
|
|
195
|
+
Out of the box `wp-env` includes the [WordPress' PHPUnit test files](https://develop.svn.wordpress.org/trunk/tests/phpunit/) corresponding to the version of WordPress installed. There is an environment variable, `WP_TESTS_DIR`, which points to the location of these files within each container. By including these files in the environment, we remove the need for you to use a package or install and mount them yourself. If you do not want to use these files, you should ignore the `WP_TESTS_DIR` environment variable and load them from the location of your choosing.
|
|
196
|
+
|
|
197
|
+
### Customizing the `wp-tests-config.php` file
|
|
198
|
+
|
|
199
|
+
While we do provide a default `wp-tests-config.php` file within the environment, there may be cases where you want to use your own. WordPress provides a `WP_TESTS_CONFIG_FILE_PATH` constant that you can use to change the `wp-config.php` file used for testing. Set this to a desired path in your `bootstrap.php` file and the file you've chosen will be used instead of the one included in the environment.
|
|
200
|
+
|
|
191
201
|
## Using Xdebug
|
|
192
202
|
|
|
193
203
|
Xdebug is installed in the wp-env environment, but it is turned off by default. To enable Xdebug, you can use the `--xdebug` flag with the `wp-env start` command. Here is a reference to how the flag works:
|
|
@@ -203,10 +213,12 @@ wp-env start
|
|
|
203
213
|
wp-env start --xdebug=profile,trace,debug
|
|
204
214
|
```
|
|
205
215
|
|
|
206
|
-
When you're running `wp-env` using `npm run`, like when working in the Gutenberg repo or when
|
|
216
|
+
When you're running `wp-env` using `npm run`, like when working in the Gutenberg repo or when `wp-env` is a local project dependency, don't forget to add an extra double dash before the `--xdebug` command:
|
|
207
217
|
|
|
208
218
|
```sh
|
|
209
219
|
npm run wp-env start -- --xdebug
|
|
220
|
+
# Alternatively, use npx:
|
|
221
|
+
npx wp-env start --xdebug
|
|
210
222
|
```
|
|
211
223
|
|
|
212
224
|
If you forget about that, the `--xdebug` parameter will be passed to NPM instead of the `wp-env start` command and it will be ignored.
|
|
@@ -511,7 +523,7 @@ SCRIPT_DEBUG: true,
|
|
|
511
523
|
WP_PHP_BINARY: 'php',
|
|
512
524
|
WP_TESTS_EMAIL: 'admin@example.org',
|
|
513
525
|
WP_TESTS_TITLE: 'Test Blog',
|
|
514
|
-
WP_TESTS_DOMAIN: '
|
|
526
|
+
WP_TESTS_DOMAIN: 'localhost',
|
|
515
527
|
WP_SITEURL: 'http://localhost',
|
|
516
528
|
WP_HOME: 'http://localhost',
|
|
517
529
|
```
|
|
@@ -524,7 +536,7 @@ Additionally, the values referencing a URL include the specified port for the gi
|
|
|
524
536
|
|
|
525
537
|
### Examples
|
|
526
538
|
|
|
527
|
-
#### Latest
|
|
539
|
+
#### Latest stable WordPress + current directory as a plugin
|
|
528
540
|
|
|
529
541
|
This is useful for plugin development.
|
|
530
542
|
|
|
@@ -19,13 +19,18 @@ const { dbEnv } = require( './config' );
|
|
|
19
19
|
/**
|
|
20
20
|
* Gets the volume mounts for an individual service.
|
|
21
21
|
*
|
|
22
|
-
* @param {
|
|
23
|
-
* @param {
|
|
24
|
-
*
|
|
22
|
+
* @param {string} workDirectoryPath The working directory for wp-env.
|
|
23
|
+
* @param {WPServiceConfig} config The service config to get the mounts from.
|
|
24
|
+
* @param {string} wordpressDefault The default internal path for the WordPress
|
|
25
|
+
* source code (such as tests-wordpress).
|
|
25
26
|
*
|
|
26
27
|
* @return {string[]} An array of volumes to mount in string format.
|
|
27
28
|
*/
|
|
28
|
-
function getMounts(
|
|
29
|
+
function getMounts(
|
|
30
|
+
workDirectoryPath,
|
|
31
|
+
config,
|
|
32
|
+
wordpressDefault = 'wordpress'
|
|
33
|
+
) {
|
|
29
34
|
// Top-level WordPress directory mounts (like wp-content/themes)
|
|
30
35
|
const directoryMounts = Object.entries( config.mappings ).map(
|
|
31
36
|
( [ wpDir, source ] ) => `${ source.path }:/var/www/html/${ wpDir }`
|
|
@@ -45,9 +50,19 @@ function getMounts( config, wordpressDefault = 'wordpress' ) {
|
|
|
45
50
|
config.coreSource ? config.coreSource.path : wordpressDefault
|
|
46
51
|
}:/var/www/html`;
|
|
47
52
|
|
|
53
|
+
const corePHPUnitMount = `${ path.join(
|
|
54
|
+
workDirectoryPath,
|
|
55
|
+
wordpressDefault === 'wordpress'
|
|
56
|
+
? 'WordPress-PHPUnit'
|
|
57
|
+
: 'tests-WordPress-PHPUnit',
|
|
58
|
+
'tests',
|
|
59
|
+
'phpunit'
|
|
60
|
+
) }:/wordpress-phpunit`;
|
|
61
|
+
|
|
48
62
|
return [
|
|
49
63
|
...new Set( [
|
|
50
64
|
coreMount,
|
|
65
|
+
corePHPUnitMount,
|
|
51
66
|
...directoryMounts,
|
|
52
67
|
...pluginMounts,
|
|
53
68
|
...themeMounts,
|
|
@@ -64,8 +79,15 @@ function getMounts( config, wordpressDefault = 'wordpress' ) {
|
|
|
64
79
|
* @return {Object} A docker-compose config object, ready to serialize into YAML.
|
|
65
80
|
*/
|
|
66
81
|
module.exports = function buildDockerComposeConfig( config ) {
|
|
67
|
-
const developmentMounts = getMounts(
|
|
68
|
-
|
|
82
|
+
const developmentMounts = getMounts(
|
|
83
|
+
config.workDirectoryPath,
|
|
84
|
+
config.env.development
|
|
85
|
+
);
|
|
86
|
+
const testsMounts = getMounts(
|
|
87
|
+
config.workDirectoryPath,
|
|
88
|
+
config.env.tests,
|
|
89
|
+
'tests-wordpress'
|
|
90
|
+
);
|
|
69
91
|
|
|
70
92
|
// When both tests and development reference the same WP source, we need to
|
|
71
93
|
// ensure that tests pulls from a copy of the files so that it maintains
|
|
@@ -208,6 +230,7 @@ module.exports = function buildDockerComposeConfig( config ) {
|
|
|
208
230
|
environment: {
|
|
209
231
|
...dbEnv.credentials,
|
|
210
232
|
...dbEnv.development,
|
|
233
|
+
WP_TESTS_DIR: '/wordpress-phpunit',
|
|
211
234
|
},
|
|
212
235
|
volumes: developmentMounts,
|
|
213
236
|
},
|
|
@@ -218,6 +241,7 @@ module.exports = function buildDockerComposeConfig( config ) {
|
|
|
218
241
|
environment: {
|
|
219
242
|
...dbEnv.credentials,
|
|
220
243
|
...dbEnv.tests,
|
|
244
|
+
WP_TESTS_DIR: '/wordpress-phpunit',
|
|
221
245
|
},
|
|
222
246
|
volumes: testsMounts,
|
|
223
247
|
},
|
|
@@ -229,6 +253,7 @@ module.exports = function buildDockerComposeConfig( config ) {
|
|
|
229
253
|
environment: {
|
|
230
254
|
...dbEnv.credentials,
|
|
231
255
|
...dbEnv.development,
|
|
256
|
+
WP_TESTS_DIR: '/wordpress-phpunit',
|
|
232
257
|
},
|
|
233
258
|
},
|
|
234
259
|
'tests-cli': {
|
|
@@ -239,6 +264,7 @@ module.exports = function buildDockerComposeConfig( config ) {
|
|
|
239
264
|
environment: {
|
|
240
265
|
...dbEnv.credentials,
|
|
241
266
|
...dbEnv.tests,
|
|
267
|
+
WP_TESTS_DIR: '/wordpress-phpunit',
|
|
242
268
|
},
|
|
243
269
|
},
|
|
244
270
|
composer: {
|
|
@@ -256,8 +282,7 @@ module.exports = function buildDockerComposeConfig( config ) {
|
|
|
256
282
|
],
|
|
257
283
|
environment: {
|
|
258
284
|
LOCAL_DIR: 'html',
|
|
259
|
-
|
|
260
|
-
'/var/www/html/phpunit-wp-config.php',
|
|
285
|
+
WP_TESTS_DIR: '/wordpress-phpunit',
|
|
261
286
|
...dbEnv.credentials,
|
|
262
287
|
...dbEnv.tests,
|
|
263
288
|
},
|
package/lib/commands/run.js
CHANGED
|
@@ -9,7 +9,7 @@ const { spawn } = require( 'child_process' );
|
|
|
9
9
|
const initConfig = require( '../init-config' );
|
|
10
10
|
|
|
11
11
|
/**
|
|
12
|
-
* @typedef {import('../config').
|
|
12
|
+
* @typedef {import('../config').WPConfig} WPConfig
|
|
13
13
|
*/
|
|
14
14
|
|
|
15
15
|
/**
|
|
@@ -42,11 +42,11 @@ module.exports = async function run( { container, command, spinner, debug } ) {
|
|
|
42
42
|
/**
|
|
43
43
|
* Runs an arbitrary command on the given Docker container.
|
|
44
44
|
*
|
|
45
|
-
* @param {Object}
|
|
46
|
-
* @param {string}
|
|
47
|
-
* @param {string}
|
|
48
|
-
* @param {
|
|
49
|
-
* @param {Object}
|
|
45
|
+
* @param {Object} options
|
|
46
|
+
* @param {string} options.container The Docker container to run the command on.
|
|
47
|
+
* @param {string} options.command The command to run.
|
|
48
|
+
* @param {WPConfig} options.config The wp-env configuration.
|
|
49
|
+
* @param {Object} options.spinner A CLI spinner which indicates progress.
|
|
50
50
|
*/
|
|
51
51
|
function spawnCommandDirectly( { container, command, config, spinner } ) {
|
|
52
52
|
const composeCommand = [
|
package/lib/commands/start.js
CHANGED
|
@@ -21,16 +21,18 @@ const retry = require( '../retry' );
|
|
|
21
21
|
const stop = require( './stop' );
|
|
22
22
|
const initConfig = require( '../init-config' );
|
|
23
23
|
const downloadSources = require( '../download-sources' );
|
|
24
|
+
const downloadWPPHPUnit = require( '../download-wp-phpunit' );
|
|
24
25
|
const {
|
|
25
26
|
checkDatabaseConnection,
|
|
26
27
|
configureWordPress,
|
|
27
28
|
setupWordPressDirectories,
|
|
29
|
+
readWordPressVersion,
|
|
28
30
|
} = require( '../wordpress' );
|
|
29
31
|
const { didCacheChange, setCache } = require( '../cache' );
|
|
30
32
|
const md5 = require( '../md5' );
|
|
31
33
|
|
|
32
34
|
/**
|
|
33
|
-
* @typedef {import('../config').
|
|
35
|
+
* @typedef {import('../config').WPConfig} WPConfig
|
|
34
36
|
*/
|
|
35
37
|
const CONFIG_CACHE_KEY = 'config_checksum';
|
|
36
38
|
|
|
@@ -127,7 +129,25 @@ module.exports = async function start( { spinner, debug, update, xdebug } ) {
|
|
|
127
129
|
] );
|
|
128
130
|
|
|
129
131
|
if ( shouldConfigureWp ) {
|
|
132
|
+
spinner.text = 'Setting up WordPress directories';
|
|
133
|
+
|
|
130
134
|
await setupWordPressDirectories( config );
|
|
135
|
+
|
|
136
|
+
// Use the WordPress versions to download the PHPUnit suite.
|
|
137
|
+
const wpVersions = await Promise.all( [
|
|
138
|
+
readWordPressVersion(
|
|
139
|
+
config.env.development.coreSource,
|
|
140
|
+
spinner,
|
|
141
|
+
debug
|
|
142
|
+
),
|
|
143
|
+
readWordPressVersion( config.env.tests.coreSource, spinner, debug ),
|
|
144
|
+
] );
|
|
145
|
+
await downloadWPPHPUnit(
|
|
146
|
+
config,
|
|
147
|
+
{ development: wpVersions[ 0 ], tests: wpVersions[ 1 ] },
|
|
148
|
+
spinner,
|
|
149
|
+
debug
|
|
150
|
+
);
|
|
131
151
|
}
|
|
132
152
|
|
|
133
153
|
spinner.text = 'Starting WordPress.';
|
|
@@ -173,7 +193,7 @@ module.exports = async function start( { spinner, debug, update, xdebug } ) {
|
|
|
173
193
|
}
|
|
174
194
|
|
|
175
195
|
const siteUrl = config.env.development.config.WP_SITEURL;
|
|
176
|
-
const e2eSiteUrl = config.env.tests.config.WP_TESTS_DOMAIN
|
|
196
|
+
const e2eSiteUrl = `http://${ config.env.tests.config.WP_TESTS_DOMAIN }:${ config.env.tests.port }/`;
|
|
177
197
|
|
|
178
198
|
const { out: mySQLAddress } = await dockerCompose.port(
|
|
179
199
|
'mysql',
|
package/lib/config/config.js
CHANGED
|
@@ -33,7 +33,7 @@ const md5 = require( '../md5' );
|
|
|
33
33
|
* Base-level config for any particular environment. (development/tests/etc)
|
|
34
34
|
*
|
|
35
35
|
* @typedef WPServiceConfig
|
|
36
|
-
* @property {
|
|
36
|
+
* @property {WPSource} coreSource The WordPress installation to load in the environment.
|
|
37
37
|
* @property {WPSource[]} pluginSources Plugins to load in the environment.
|
|
38
38
|
* @property {WPSource[]} themeSources Themes to load in the environment.
|
|
39
39
|
* @property {number} port The port to use.
|
|
@@ -68,9 +68,25 @@ module.exports = async function readConfig( configPath ) {
|
|
|
68
68
|
md5( configPath )
|
|
69
69
|
);
|
|
70
70
|
|
|
71
|
+
// The specified base configuration from .wp-env.json or from the local
|
|
72
|
+
// source type which was automatically detected.
|
|
73
|
+
const baseConfig =
|
|
74
|
+
( await readRawConfigFile( '.wp-env.json', configPath ) ) ||
|
|
75
|
+
( await getDefaultBaseConfig( configPath ) );
|
|
76
|
+
|
|
77
|
+
// Overriden .wp-env.json on a per-user case.
|
|
78
|
+
const overrideConfig =
|
|
79
|
+
( await readRawConfigFile(
|
|
80
|
+
'.wp-env.override.json',
|
|
81
|
+
configPath.replace( /\.wp-env\.json$/, '.wp-env.override.json' )
|
|
82
|
+
) ) || {};
|
|
83
|
+
|
|
84
|
+
const detectedLocalConfig =
|
|
85
|
+
Object.keys( { ...baseConfig, ...overrideConfig } ).length > 0;
|
|
86
|
+
|
|
71
87
|
// Default configuration which is overridden by .wp-env.json files.
|
|
72
88
|
const defaultConfiguration = {
|
|
73
|
-
core: null,
|
|
89
|
+
core: null, // Indicates that the latest stable version should ultimately be used.
|
|
74
90
|
phpVersion: null,
|
|
75
91
|
plugins: [],
|
|
76
92
|
themes: [],
|
|
@@ -83,7 +99,7 @@ module.exports = async function readConfig( configPath ) {
|
|
|
83
99
|
WP_PHP_BINARY: 'php',
|
|
84
100
|
WP_TESTS_EMAIL: 'admin@example.org',
|
|
85
101
|
WP_TESTS_TITLE: 'Test Blog',
|
|
86
|
-
WP_TESTS_DOMAIN: '
|
|
102
|
+
WP_TESTS_DOMAIN: 'localhost',
|
|
87
103
|
WP_SITEURL: 'http://localhost',
|
|
88
104
|
WP_HOME: 'http://localhost',
|
|
89
105
|
},
|
|
@@ -96,22 +112,6 @@ module.exports = async function readConfig( configPath ) {
|
|
|
96
112
|
},
|
|
97
113
|
};
|
|
98
114
|
|
|
99
|
-
// The specified base configuration from .wp-env.json or from the local
|
|
100
|
-
// source type which was automatically detected.
|
|
101
|
-
const baseConfig =
|
|
102
|
-
( await readRawConfigFile( '.wp-env.json', configPath ) ) ||
|
|
103
|
-
( await getDefaultBaseConfig( configPath ) );
|
|
104
|
-
|
|
105
|
-
// Overriden .wp-env.json on a per-user case.
|
|
106
|
-
const overrideConfig =
|
|
107
|
-
( await readRawConfigFile(
|
|
108
|
-
'.wp-env.override.json',
|
|
109
|
-
configPath.replace( /\.wp-env\.json$/, '.wp-env.override.json' )
|
|
110
|
-
) ) || {};
|
|
111
|
-
|
|
112
|
-
const detectedLocalConfig =
|
|
113
|
-
Object.keys( { ...baseConfig, ...overrideConfig } ).length > 0;
|
|
114
|
-
|
|
115
115
|
// A quick validation before merging on a service by service level allows us
|
|
116
116
|
// to check the root configuration options and provide more helpful errors.
|
|
117
117
|
validateConfig(
|
|
@@ -142,23 +142,21 @@ module.exports = async function readConfig( configPath ) {
|
|
|
142
142
|
|
|
143
143
|
// Merge each of the specified environment-level overrides.
|
|
144
144
|
const allPorts = new Set(); // Keep track of unique ports for validation.
|
|
145
|
-
const env =
|
|
146
|
-
|
|
145
|
+
const env = {};
|
|
146
|
+
for ( const envName of allEnvs ) {
|
|
147
|
+
env[ envName ] = await parseConfig(
|
|
147
148
|
validateConfig(
|
|
148
149
|
mergeWpServiceConfigs( [
|
|
149
|
-
...getEnvConfig( defaultConfiguration,
|
|
150
|
-
...getEnvConfig( baseConfig,
|
|
151
|
-
...getEnvConfig( overrideConfig,
|
|
150
|
+
...getEnvConfig( defaultConfiguration, envName ),
|
|
151
|
+
...getEnvConfig( baseConfig, envName ),
|
|
152
|
+
...getEnvConfig( overrideConfig, envName ),
|
|
152
153
|
] ),
|
|
153
|
-
|
|
154
|
+
envName
|
|
154
155
|
),
|
|
155
|
-
{
|
|
156
|
-
workDirectoryPath,
|
|
157
|
-
}
|
|
156
|
+
{ workDirectoryPath }
|
|
158
157
|
);
|
|
159
|
-
allPorts.add(
|
|
160
|
-
|
|
161
|
-
}, {} );
|
|
158
|
+
allPorts.add( env[ envName ].port );
|
|
159
|
+
}
|
|
162
160
|
|
|
163
161
|
if ( allPorts.size !== allEnvs.length ) {
|
|
164
162
|
throw new ValidationError(
|
|
@@ -249,6 +247,7 @@ async function getDefaultBaseConfig( configPath ) {
|
|
|
249
247
|
* @return {WPConfig} configuration object with overrides applied.
|
|
250
248
|
*/
|
|
251
249
|
function withOverrides( config ) {
|
|
250
|
+
const workDirectoryPath = config.workDirectoryPath;
|
|
252
251
|
// Override port numbers with environment variables.
|
|
253
252
|
config.env.development.port =
|
|
254
253
|
getNumberFromEnvVariable( 'WP_ENV_PORT' ) ||
|
|
@@ -260,10 +259,8 @@ function withOverrides( config ) {
|
|
|
260
259
|
// Override WordPress core with environment variable.
|
|
261
260
|
if ( process.env.WP_ENV_CORE ) {
|
|
262
261
|
const coreSource = includeTestsPath(
|
|
263
|
-
parseSourceString( process.env.WP_ENV_CORE, {
|
|
264
|
-
|
|
265
|
-
} ),
|
|
266
|
-
{ workDirectoryPath: config.workDirectoryPath }
|
|
262
|
+
parseSourceString( process.env.WP_ENV_CORE, { workDirectoryPath } ),
|
|
263
|
+
{ workDirectoryPath }
|
|
267
264
|
);
|
|
268
265
|
config.env.development.coreSource = coreSource;
|
|
269
266
|
config.env.tests.coreSource = coreSource;
|
|
@@ -297,7 +294,6 @@ function withOverrides( config ) {
|
|
|
297
294
|
};
|
|
298
295
|
|
|
299
296
|
// Update wp config options to include the correct port number in the URL.
|
|
300
|
-
updateEnvUrl( 'WP_TESTS_DOMAIN' );
|
|
301
297
|
updateEnvUrl( 'WP_SITEURL' );
|
|
302
298
|
updateEnvUrl( 'WP_HOME' );
|
|
303
299
|
|
|
@@ -9,6 +9,7 @@ const os = require( 'os' );
|
|
|
9
9
|
* Internal dependencies
|
|
10
10
|
*/
|
|
11
11
|
const { ValidationError } = require( './validate-config' );
|
|
12
|
+
const { getLatestWordPressVersion } = require( '../wordpress' );
|
|
12
13
|
|
|
13
14
|
/**
|
|
14
15
|
* @typedef {import('./config').WPServiceConfig} WPServiceConfig
|
|
@@ -32,12 +33,12 @@ const HOME_PATH_PREFIX = `~${ path.sep }`;
|
|
|
32
33
|
* @param {string} options.workDirectoryPath Path to the work directory located in ~/.wp-env.
|
|
33
34
|
* @return {WPServiceConfig} Parsed environment-level configuration.
|
|
34
35
|
*/
|
|
35
|
-
module.exports = function parseConfig( config, options ) {
|
|
36
|
+
module.exports = async function parseConfig( config, options ) {
|
|
36
37
|
return {
|
|
37
38
|
port: config.port,
|
|
38
39
|
phpVersion: config.phpVersion,
|
|
39
40
|
coreSource: includeTestsPath(
|
|
40
|
-
|
|
41
|
+
await parseCoreSource( config.core, options ),
|
|
41
42
|
options
|
|
42
43
|
),
|
|
43
44
|
pluginSources: config.plugins.map( ( sourceString ) =>
|
|
@@ -58,6 +59,21 @@ module.exports = function parseConfig( config, options ) {
|
|
|
58
59
|
};
|
|
59
60
|
};
|
|
60
61
|
|
|
62
|
+
async function parseCoreSource( coreSource, options ) {
|
|
63
|
+
// An empty source means we should use the latest version of WordPress.
|
|
64
|
+
if ( ! coreSource ) {
|
|
65
|
+
const wpVersion = await getLatestWordPressVersion();
|
|
66
|
+
if ( ! wpVersion ) {
|
|
67
|
+
throw new ValidationError(
|
|
68
|
+
'Could not find the latest WordPress version. There may be a network issue.'
|
|
69
|
+
);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
coreSource = `WordPress/WordPress#${ wpVersion }`;
|
|
73
|
+
}
|
|
74
|
+
return parseSourceString( coreSource, options );
|
|
75
|
+
}
|
|
76
|
+
|
|
61
77
|
/**
|
|
62
78
|
* Parses a source string into a source object.
|
|
63
79
|
*
|
|
@@ -17,11 +17,10 @@ Object {
|
|
|
17
17
|
"WP_HOME": "http://localhost:2000/",
|
|
18
18
|
"WP_PHP_BINARY": "php",
|
|
19
19
|
"WP_SITEURL": "http://localhost:2000/",
|
|
20
|
-
"WP_TESTS_DOMAIN": "
|
|
20
|
+
"WP_TESTS_DOMAIN": "localhost",
|
|
21
21
|
"WP_TESTS_EMAIL": "admin@example.org",
|
|
22
22
|
"WP_TESTS_TITLE": "Test Blog",
|
|
23
23
|
},
|
|
24
|
-
"coreSource": null,
|
|
25
24
|
"mappings": Object {},
|
|
26
25
|
"phpVersion": null,
|
|
27
26
|
"pluginSources": Array [],
|
|
@@ -40,11 +39,10 @@ Object {
|
|
|
40
39
|
"WP_HOME": "http://localhost:1000/",
|
|
41
40
|
"WP_PHP_BINARY": "php",
|
|
42
41
|
"WP_SITEURL": "http://localhost:1000/",
|
|
43
|
-
"WP_TESTS_DOMAIN": "
|
|
42
|
+
"WP_TESTS_DOMAIN": "localhost",
|
|
44
43
|
"WP_TESTS_EMAIL": "admin@example.org",
|
|
45
44
|
"WP_TESTS_TITLE": "Test Blog",
|
|
46
45
|
},
|
|
47
|
-
"coreSource": null,
|
|
48
46
|
"mappings": Object {},
|
|
49
47
|
"phpVersion": null,
|
|
50
48
|
"pluginSources": Array [],
|
|
@@ -64,7 +62,7 @@ Object {
|
|
|
64
62
|
"WP_HOME": "http://localhost:8889/",
|
|
65
63
|
"WP_PHP_BINARY": "php",
|
|
66
64
|
"WP_SITEURL": "http://localhost:8889/",
|
|
67
|
-
"WP_TESTS_DOMAIN": "
|
|
65
|
+
"WP_TESTS_DOMAIN": "localhost",
|
|
68
66
|
"WP_TESTS_EMAIL": "admin@example.org",
|
|
69
67
|
"WP_TESTS_TITLE": "Test Blog",
|
|
70
68
|
}
|
|
@@ -78,7 +76,7 @@ Object {
|
|
|
78
76
|
"WP_HOME": "http://localhost:8888/",
|
|
79
77
|
"WP_PHP_BINARY": "php",
|
|
80
78
|
"WP_SITEURL": "http://localhost:8888/",
|
|
81
|
-
"WP_TESTS_DOMAIN": "
|
|
79
|
+
"WP_TESTS_DOMAIN": "localhost",
|
|
82
80
|
"WP_TESTS_EMAIL": "admin@example.org",
|
|
83
81
|
"WP_TESTS_TITLE": "Test Blog",
|
|
84
82
|
}
|
|
@@ -19,6 +19,23 @@ jest.mock( 'fs', () => ( {
|
|
|
19
19
|
},
|
|
20
20
|
} ) );
|
|
21
21
|
|
|
22
|
+
// This mocks a small response with a format matching the stable-check API.
|
|
23
|
+
// It makes getLatestWordPressVersion resolve to "100.0.0".
|
|
24
|
+
jest.mock( 'got', () =>
|
|
25
|
+
jest.fn( ( url ) => ( {
|
|
26
|
+
json: () => {
|
|
27
|
+
if ( url === 'https://api.wordpress.org/core/stable-check/1.0/' ) {
|
|
28
|
+
return Promise.resolve( {
|
|
29
|
+
'1.0': 'insecure',
|
|
30
|
+
'99.1.1': 'outdated',
|
|
31
|
+
'100.0.0': 'latest',
|
|
32
|
+
'100.0.1': 'fancy',
|
|
33
|
+
} );
|
|
34
|
+
}
|
|
35
|
+
},
|
|
36
|
+
} ) )
|
|
37
|
+
);
|
|
38
|
+
|
|
22
39
|
jest.mock( '../detect-directory-type', () => jest.fn() );
|
|
23
40
|
|
|
24
41
|
describe( 'readConfig', () => {
|
|
@@ -59,19 +76,38 @@ describe( 'readConfig', () => {
|
|
|
59
76
|
);
|
|
60
77
|
detectDirectoryType.mockImplementation( () => 'core' );
|
|
61
78
|
const config = await readConfig( '.wp-env.json' );
|
|
62
|
-
expect( config.env.development.coreSource ).
|
|
79
|
+
expect( config.env.development.coreSource.type ).toBe( 'local' );
|
|
63
80
|
expect( config.env.tests.coreSource ).not.toBeNull();
|
|
64
81
|
expect( config.env.development.pluginSources ).toHaveLength( 0 );
|
|
65
82
|
expect( config.env.development.themeSources ).toHaveLength( 0 );
|
|
66
83
|
} );
|
|
67
84
|
|
|
85
|
+
it( 'should use the most recent stable WordPress version for the default core source', async () => {
|
|
86
|
+
readFile.mockImplementation( () =>
|
|
87
|
+
Promise.resolve( JSON.stringify( {} ) )
|
|
88
|
+
);
|
|
89
|
+
const config = await readConfig( '.wp-env.json' );
|
|
90
|
+
|
|
91
|
+
const expected = {
|
|
92
|
+
url: 'https://github.com/WordPress/WordPress.git',
|
|
93
|
+
type: 'git',
|
|
94
|
+
basename: 'WordPress',
|
|
95
|
+
ref: '100.0.0', // From the mock of https at the top of the file.
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
expect( config.env.development.coreSource ).toMatchObject(
|
|
99
|
+
expected
|
|
100
|
+
);
|
|
101
|
+
expect( config.env.tests.coreSource ).toMatchObject( expected );
|
|
102
|
+
} );
|
|
103
|
+
|
|
68
104
|
it( 'should infer a plugin config when ran from a plugin directory', async () => {
|
|
69
105
|
readFile.mockImplementation( () =>
|
|
70
106
|
Promise.reject( { code: 'ENOENT' } )
|
|
71
107
|
);
|
|
72
108
|
detectDirectoryType.mockImplementation( () => 'plugin' );
|
|
73
109
|
const config = await readConfig( '.wp-env.json' );
|
|
74
|
-
expect( config.env.development.coreSource ).
|
|
110
|
+
expect( config.env.development.coreSource.type ).toBe( 'git' );
|
|
75
111
|
expect( config.env.development.pluginSources ).toHaveLength( 1 );
|
|
76
112
|
expect( config.env.tests.pluginSources ).toHaveLength( 1 );
|
|
77
113
|
expect( config.env.development.themeSources ).toHaveLength( 0 );
|
|
@@ -83,8 +119,8 @@ describe( 'readConfig', () => {
|
|
|
83
119
|
);
|
|
84
120
|
detectDirectoryType.mockImplementation( () => 'theme' );
|
|
85
121
|
const config = await readConfig( '.wp-env.json' );
|
|
86
|
-
expect( config.env.development.coreSource ).
|
|
87
|
-
expect( config.env.tests.coreSource ).
|
|
122
|
+
expect( config.env.development.coreSource.type ).toBe( 'git' );
|
|
123
|
+
expect( config.env.tests.coreSource.type ).toBe( 'git' );
|
|
88
124
|
expect( config.env.development.themeSources ).toHaveLength( 1 );
|
|
89
125
|
expect( config.env.tests.themeSources ).toHaveLength( 1 );
|
|
90
126
|
expect( config.env.development.pluginSources ).toHaveLength( 0 );
|
|
@@ -197,6 +233,11 @@ describe( 'readConfig', () => {
|
|
|
197
233
|
// Remove generated values which are different on other machines.
|
|
198
234
|
delete config.dockerComposeConfigPath;
|
|
199
235
|
delete config.workDirectoryPath;
|
|
236
|
+
|
|
237
|
+
// This encodes both the version of WordPress (which can change frequently)
|
|
238
|
+
// as well as the wp-env directory which is unique on every machine.
|
|
239
|
+
delete config.env.development.coreSource;
|
|
240
|
+
delete config.env.tests.coreSource;
|
|
200
241
|
expect( config ).toMatchSnapshot();
|
|
201
242
|
} );
|
|
202
243
|
} );
|
|
@@ -265,17 +306,17 @@ describe( 'readConfig', () => {
|
|
|
265
306
|
pluginSources: [
|
|
266
307
|
{
|
|
267
308
|
type: 'local',
|
|
268
|
-
path: expect.stringMatching( /^(
|
|
309
|
+
path: expect.stringMatching( /^(\/|\\).*relative$/ ),
|
|
269
310
|
basename: 'relative',
|
|
270
311
|
},
|
|
271
312
|
{
|
|
272
313
|
type: 'local',
|
|
273
|
-
path: expect.stringMatching( /^(
|
|
314
|
+
path: expect.stringMatching( /^(\/|\\).*parent$/ ),
|
|
274
315
|
basename: 'parent',
|
|
275
316
|
},
|
|
276
317
|
{
|
|
277
318
|
type: 'local',
|
|
278
|
-
path: expect.stringMatching( /^(
|
|
319
|
+
path: expect.stringMatching( /^(\/|\\).*home$/ ),
|
|
279
320
|
basename: 'home',
|
|
280
321
|
},
|
|
281
322
|
],
|
|
@@ -284,17 +325,17 @@ describe( 'readConfig', () => {
|
|
|
284
325
|
pluginSources: [
|
|
285
326
|
{
|
|
286
327
|
type: 'local',
|
|
287
|
-
path: expect.stringMatching( /^(
|
|
328
|
+
path: expect.stringMatching( /^(\/|\\).*relative$/ ),
|
|
288
329
|
basename: 'relative',
|
|
289
330
|
},
|
|
290
331
|
{
|
|
291
332
|
type: 'local',
|
|
292
|
-
path: expect.stringMatching( /^(
|
|
333
|
+
path: expect.stringMatching( /^(\/|\\).*parent$/ ),
|
|
293
334
|
basename: 'parent',
|
|
294
335
|
},
|
|
295
336
|
{
|
|
296
337
|
type: 'local',
|
|
297
|
-
path: expect.stringMatching( /^(
|
|
338
|
+
path: expect.stringMatching( /^(\/|\\).*home$/ ),
|
|
298
339
|
basename: 'home',
|
|
299
340
|
},
|
|
300
341
|
],
|
|
@@ -324,28 +365,28 @@ describe( 'readConfig', () => {
|
|
|
324
365
|
expect( config.env.development.pluginSources ).toEqual( [
|
|
325
366
|
{
|
|
326
367
|
type: 'local',
|
|
327
|
-
path: expect.stringMatching( /^(
|
|
368
|
+
path: expect.stringMatching( /^(\/|\\).*test1a$/ ),
|
|
328
369
|
basename: 'test1a',
|
|
329
370
|
},
|
|
330
371
|
] );
|
|
331
372
|
expect( config.env.development.themeSources ).toEqual( [
|
|
332
373
|
{
|
|
333
374
|
type: 'local',
|
|
334
|
-
path: expect.stringMatching( /^(
|
|
375
|
+
path: expect.stringMatching( /^(\/|\\).*test2a$/ ),
|
|
335
376
|
basename: 'test2a',
|
|
336
377
|
},
|
|
337
378
|
] );
|
|
338
379
|
expect( config.env.tests.pluginSources ).toEqual( [
|
|
339
380
|
{
|
|
340
381
|
type: 'local',
|
|
341
|
-
path: expect.stringMatching( /^(
|
|
382
|
+
path: expect.stringMatching( /^(\/|\\).*test1b$/ ),
|
|
342
383
|
basename: 'test1b',
|
|
343
384
|
},
|
|
344
385
|
] );
|
|
345
386
|
expect( config.env.tests.themeSources ).toEqual( [
|
|
346
387
|
{
|
|
347
388
|
type: 'local',
|
|
348
|
-
path: expect.stringMatching( /^(
|
|
389
|
+
path: expect.stringMatching( /^(\/|\\).*test2b$/ ),
|
|
349
390
|
basename: 'test2b',
|
|
350
391
|
},
|
|
351
392
|
] );
|
|
@@ -359,18 +400,18 @@ describe( 'readConfig', () => {
|
|
|
359
400
|
expect( config.env.development ).toMatchObject( {
|
|
360
401
|
coreSource: {
|
|
361
402
|
type: 'local',
|
|
362
|
-
path: expect.stringMatching( /^(
|
|
403
|
+
path: expect.stringMatching( /^(\/|\\).*relative$/ ),
|
|
363
404
|
testsPath: expect.stringMatching(
|
|
364
|
-
/^(
|
|
405
|
+
/^(\/|\\).*tests-relative$/
|
|
365
406
|
),
|
|
366
407
|
},
|
|
367
408
|
} );
|
|
368
409
|
expect( config.env.tests ).toMatchObject( {
|
|
369
410
|
coreSource: {
|
|
370
411
|
type: 'local',
|
|
371
|
-
path: expect.stringMatching( /^(
|
|
412
|
+
path: expect.stringMatching( /^(\/|\\).*relative$/ ),
|
|
372
413
|
testsPath: expect.stringMatching(
|
|
373
|
-
/^(
|
|
414
|
+
/^(\/|\\).*tests-relative$/
|
|
374
415
|
),
|
|
375
416
|
},
|
|
376
417
|
} );
|
|
@@ -396,21 +437,21 @@ describe( 'readConfig', () => {
|
|
|
396
437
|
type: 'git',
|
|
397
438
|
url: 'https://github.com/WordPress/gutenberg.git',
|
|
398
439
|
ref: undefined,
|
|
399
|
-
path: expect.stringMatching( /^(
|
|
440
|
+
path: expect.stringMatching( /^(\/|\\).*gutenberg$/ ),
|
|
400
441
|
basename: 'gutenberg',
|
|
401
442
|
},
|
|
402
443
|
{
|
|
403
444
|
type: 'git',
|
|
404
445
|
url: 'https://github.com/WordPress/gutenberg.git',
|
|
405
446
|
ref: 'trunk',
|
|
406
|
-
path: expect.stringMatching( /^(
|
|
447
|
+
path: expect.stringMatching( /^(\/|\\).*gutenberg$/ ),
|
|
407
448
|
basename: 'gutenberg',
|
|
408
449
|
},
|
|
409
450
|
{
|
|
410
451
|
type: 'git',
|
|
411
452
|
url: 'https://github.com/WordPress/gutenberg.git',
|
|
412
453
|
ref: '5.0',
|
|
413
|
-
path: expect.stringMatching( /^(
|
|
454
|
+
path: expect.stringMatching( /^(\/|\\).*gutenberg$/ ),
|
|
414
455
|
basename: 'gutenberg',
|
|
415
456
|
},
|
|
416
457
|
{
|
|
@@ -418,7 +459,7 @@ describe( 'readConfig', () => {
|
|
|
418
459
|
url: 'https://github.com/WordPress/theme-experiments.git',
|
|
419
460
|
ref: 'tt1-blocks@0.4.3',
|
|
420
461
|
path: expect.stringMatching(
|
|
421
|
-
/^(
|
|
462
|
+
/^(\/|\\).*theme-experiments(\/|\\)tt1-blocks$/
|
|
422
463
|
),
|
|
423
464
|
basename: 'tt1-blocks',
|
|
424
465
|
},
|
|
@@ -447,20 +488,20 @@ describe( 'readConfig', () => {
|
|
|
447
488
|
{
|
|
448
489
|
type: 'zip',
|
|
449
490
|
url: 'https://downloads.wordpress.org/plugin/gutenberg.zip',
|
|
450
|
-
path: expect.stringMatching( /^(
|
|
491
|
+
path: expect.stringMatching( /^(\/|\\).*gutenberg$/ ),
|
|
451
492
|
basename: 'gutenberg',
|
|
452
493
|
},
|
|
453
494
|
{
|
|
454
495
|
type: 'zip',
|
|
455
496
|
url: 'https://downloads.wordpress.org/plugin/gutenberg.8.1.0.zip',
|
|
456
|
-
path: expect.stringMatching( /^(
|
|
497
|
+
path: expect.stringMatching( /^(\/|\\).*gutenberg$/ ),
|
|
457
498
|
basename: 'gutenberg',
|
|
458
499
|
},
|
|
459
500
|
{
|
|
460
501
|
type: 'zip',
|
|
461
502
|
url: 'https://downloads.wordpress.org/theme/twentytwenty.zip',
|
|
462
503
|
path: expect.stringMatching(
|
|
463
|
-
/^(
|
|
504
|
+
/^(\/|\\).*twentytwenty$/
|
|
464
505
|
),
|
|
465
506
|
basename: 'twentytwenty',
|
|
466
507
|
},
|
|
@@ -468,7 +509,7 @@ describe( 'readConfig', () => {
|
|
|
468
509
|
type: 'zip',
|
|
469
510
|
url: 'https://downloads.wordpress.org/theme/twentytwenty.1.3.zip',
|
|
470
511
|
path: expect.stringMatching(
|
|
471
|
-
/^(
|
|
512
|
+
/^(\/|\\).*twentytwenty$/
|
|
472
513
|
),
|
|
473
514
|
basename: 'twentytwenty',
|
|
474
515
|
},
|
|
@@ -498,14 +539,14 @@ describe( 'readConfig', () => {
|
|
|
498
539
|
{
|
|
499
540
|
type: 'zip',
|
|
500
541
|
url: 'https://www.example.com/test/path/to/gutenberg.zip',
|
|
501
|
-
path: expect.stringMatching( /^(
|
|
542
|
+
path: expect.stringMatching( /^(\/|\\).*gutenberg$/ ),
|
|
502
543
|
basename: 'gutenberg',
|
|
503
544
|
},
|
|
504
545
|
{
|
|
505
546
|
type: 'zip',
|
|
506
547
|
url: 'https://www.example.com/test/path/to/gutenberg.8.1.0.zip',
|
|
507
548
|
path: expect.stringMatching(
|
|
508
|
-
/^(
|
|
549
|
+
/^(\/|\\).*gutenberg.8.1.0$/
|
|
509
550
|
),
|
|
510
551
|
basename: 'gutenberg.8.1.0',
|
|
511
552
|
},
|
|
@@ -513,7 +554,7 @@ describe( 'readConfig', () => {
|
|
|
513
554
|
type: 'zip',
|
|
514
555
|
url: 'https://www.example.com/test/path/to/twentytwenty.zip',
|
|
515
556
|
path: expect.stringMatching(
|
|
516
|
-
/^(
|
|
557
|
+
/^(\/|\\).*twentytwenty$/
|
|
517
558
|
),
|
|
518
559
|
basename: 'twentytwenty',
|
|
519
560
|
},
|
|
@@ -521,7 +562,7 @@ describe( 'readConfig', () => {
|
|
|
521
562
|
type: 'zip',
|
|
522
563
|
url: 'https://www.example.com/test/path/to/twentytwenty.1.3.zip',
|
|
523
564
|
path: expect.stringMatching(
|
|
524
|
-
/^(
|
|
565
|
+
/^(\/|\\).*twentytwenty.1.3$/
|
|
525
566
|
),
|
|
526
567
|
basename: 'twentytwenty.1.3',
|
|
527
568
|
},
|
|
@@ -529,7 +570,7 @@ describe( 'readConfig', () => {
|
|
|
529
570
|
type: 'zip',
|
|
530
571
|
url: 'https://example.com/twentytwenty.1.3.zip',
|
|
531
572
|
path: expect.stringMatching(
|
|
532
|
-
/^(
|
|
573
|
+
/^(\/|\\).*twentytwenty.1.3$/
|
|
533
574
|
),
|
|
534
575
|
basename: 'twentytwenty.1.3',
|
|
535
576
|
},
|
|
@@ -571,12 +612,12 @@ describe( 'readConfig', () => {
|
|
|
571
612
|
const matchObj = {
|
|
572
613
|
test: {
|
|
573
614
|
type: 'local',
|
|
574
|
-
path: expect.stringMatching( /^(
|
|
615
|
+
path: expect.stringMatching( /^(\/|\\).*relative$/ ),
|
|
575
616
|
basename: 'relative',
|
|
576
617
|
},
|
|
577
618
|
test2: {
|
|
578
619
|
type: 'git',
|
|
579
|
-
path: expect.stringMatching( /^(
|
|
620
|
+
path: expect.stringMatching( /^(\/|\\).*gutenberg$/ ),
|
|
580
621
|
basename: 'gutenberg',
|
|
581
622
|
},
|
|
582
623
|
};
|
|
@@ -804,7 +845,7 @@ describe( 'readConfig', () => {
|
|
|
804
845
|
development: {
|
|
805
846
|
port: 1000,
|
|
806
847
|
config: {
|
|
807
|
-
WP_TESTS_DOMAIN: '
|
|
848
|
+
WP_TESTS_DOMAIN: 'localhost',
|
|
808
849
|
WP_SITEURL: 'http://localhost:1000/',
|
|
809
850
|
WP_HOME: 'http://localhost:1000/',
|
|
810
851
|
},
|
|
@@ -812,7 +853,7 @@ describe( 'readConfig', () => {
|
|
|
812
853
|
tests: {
|
|
813
854
|
port: 2000,
|
|
814
855
|
config: {
|
|
815
|
-
WP_TESTS_DOMAIN: '
|
|
856
|
+
WP_TESTS_DOMAIN: 'localhost',
|
|
816
857
|
WP_SITEURL: 'http://localhost:2000/',
|
|
817
858
|
WP_HOME: 'http://localhost:2000/',
|
|
818
859
|
},
|
|
@@ -840,7 +881,7 @@ describe( 'readConfig', () => {
|
|
|
840
881
|
development: {
|
|
841
882
|
port: 1000,
|
|
842
883
|
config: {
|
|
843
|
-
WP_TESTS_DOMAIN: '
|
|
884
|
+
WP_TESTS_DOMAIN: 'localhost',
|
|
844
885
|
WP_SITEURL: 'http://localhost:1000/',
|
|
845
886
|
WP_HOME: 'http://localhost:3000/',
|
|
846
887
|
},
|
|
@@ -848,7 +889,7 @@ describe( 'readConfig', () => {
|
|
|
848
889
|
tests: {
|
|
849
890
|
port: 2000,
|
|
850
891
|
config: {
|
|
851
|
-
WP_TESTS_DOMAIN: '
|
|
892
|
+
WP_TESTS_DOMAIN: 'localhost',
|
|
852
893
|
WP_SITEURL: 'http://localhost:2000/',
|
|
853
894
|
WP_HOME: 'http://localhost:3000/',
|
|
854
895
|
},
|
|
@@ -1103,7 +1144,7 @@ describe( 'readConfig', () => {
|
|
|
1103
1144
|
WP_PHP_BINARY: 'php',
|
|
1104
1145
|
WP_TESTS_EMAIL: 'admin@example.org',
|
|
1105
1146
|
WP_TESTS_TITLE: 'Test Blog',
|
|
1106
|
-
WP_TESTS_DOMAIN: '
|
|
1147
|
+
WP_TESTS_DOMAIN: 'localhost',
|
|
1107
1148
|
WP_SITEURL: 'http://localhost:8889/',
|
|
1108
1149
|
WP_HOME: 'http://localhost:8889/',
|
|
1109
1150
|
} );
|
|
@@ -1117,7 +1158,7 @@ describe( 'readConfig', () => {
|
|
|
1117
1158
|
WP_PHP_BINARY: 'php',
|
|
1118
1159
|
WP_TESTS_EMAIL: 'admin@example.org',
|
|
1119
1160
|
WP_TESTS_TITLE: 'Test Blog',
|
|
1120
|
-
WP_TESTS_DOMAIN: '
|
|
1161
|
+
WP_TESTS_DOMAIN: 'localhost',
|
|
1121
1162
|
WP_SITEURL: 'http://localhost:8888/',
|
|
1122
1163
|
WP_HOME: 'http://localhost:8888/',
|
|
1123
1164
|
} );
|
package/lib/download-sources.js
CHANGED
|
@@ -16,7 +16,7 @@ const extractZip = util.promisify( require( 'extract-zip' ) );
|
|
|
16
16
|
const rimraf = util.promisify( require( 'rimraf' ) );
|
|
17
17
|
|
|
18
18
|
/**
|
|
19
|
-
* @typedef {import('./config').
|
|
19
|
+
* @typedef {import('./config').WPConfig} WPConfig
|
|
20
20
|
* @typedef {import('./config').WPSource} WPSource
|
|
21
21
|
*/
|
|
22
22
|
|
|
@@ -24,8 +24,8 @@ const rimraf = util.promisify( require( 'rimraf' ) );
|
|
|
24
24
|
* Download each source for each environment. If the same source is used in
|
|
25
25
|
* multiple environments, it will only be downloaded once.
|
|
26
26
|
*
|
|
27
|
-
* @param {
|
|
28
|
-
* @param {Object}
|
|
27
|
+
* @param {WPConfig} config The wp-env configuration object.
|
|
28
|
+
* @param {Object} spinner The spinner object to show progress.
|
|
29
29
|
* @return {Promise} Returns a promise which resolves when the downloads finish.
|
|
30
30
|
*/
|
|
31
31
|
module.exports = function downloadSources( config, spinner ) {
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
/**
|
|
3
|
+
* External dependencies
|
|
4
|
+
*/
|
|
5
|
+
const SimpleGit = require( 'simple-git' );
|
|
6
|
+
const fs = require( 'fs' );
|
|
7
|
+
const path = require( 'path' );
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* @typedef {import('./config').WPConfig} WPConfig
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Downloads the WordPress PHPUnit files for each environment into the appropriate directories.
|
|
15
|
+
*
|
|
16
|
+
* @param {WPConfig} config The wp-env config object.
|
|
17
|
+
* @param {Object} wpVersions The WordPress versions for each environment.
|
|
18
|
+
* @param {Object} spinner The spinner object to show progress.
|
|
19
|
+
* @param {boolean} debug Indicates whether or not debug mode is active.
|
|
20
|
+
* @return {Promise} Returns a promise which resolves when the downloads finish.
|
|
21
|
+
*/
|
|
22
|
+
module.exports = function downloadWPPHPUnit(
|
|
23
|
+
config,
|
|
24
|
+
wpVersions,
|
|
25
|
+
spinner,
|
|
26
|
+
debug
|
|
27
|
+
) {
|
|
28
|
+
const progresses = {};
|
|
29
|
+
const getProgressSetter = ( id ) => ( progress ) => {
|
|
30
|
+
progresses[ id ] = progress;
|
|
31
|
+
spinner.text =
|
|
32
|
+
'Downloading WordPress PHPUnit Suite.\n' +
|
|
33
|
+
Object.entries( progresses )
|
|
34
|
+
.map(
|
|
35
|
+
( [ key, value ] ) =>
|
|
36
|
+
` - ${ key }: ${ ( value * 100 ).toFixed( 0 ) }/100%`
|
|
37
|
+
)
|
|
38
|
+
.join( '\n' );
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
const promises = [];
|
|
42
|
+
for ( const env in config.env ) {
|
|
43
|
+
const wpVersion = wpVersions[ env ] ? wpVersions[ env ] : null;
|
|
44
|
+
const directory = path.join(
|
|
45
|
+
config.workDirectoryPath,
|
|
46
|
+
env === 'development'
|
|
47
|
+
? 'WordPress-PHPUnit'
|
|
48
|
+
: 'tests-WordPress-PHPUnit'
|
|
49
|
+
);
|
|
50
|
+
promises.push(
|
|
51
|
+
downloadTestSuite( directory, wpVersion, {
|
|
52
|
+
onProgress: getProgressSetter,
|
|
53
|
+
spinner,
|
|
54
|
+
debug,
|
|
55
|
+
} )
|
|
56
|
+
);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
return Promise.all( promises );
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Downloads the PHPUnit tests for a given WordPress version into the appropriate directory.
|
|
64
|
+
*
|
|
65
|
+
* @param {string} directory The directory to place the PHPUnit tests in.
|
|
66
|
+
* @param {string} wpVersion The version of WordPress to install PHPUnit tests for. Trunk when empty.
|
|
67
|
+
* @param {Object} options
|
|
68
|
+
* @param {Function} options.onProgress A function called with download progress. Will be invoked with one argument: a number that ranges from 0 to 1 which indicates current download progress for this source.
|
|
69
|
+
* @param {Object} options.spinner A CLI spinner which indicates progress.
|
|
70
|
+
* @param {boolean} options.debug True if debug mode is enabled.
|
|
71
|
+
*/
|
|
72
|
+
async function downloadTestSuite(
|
|
73
|
+
directory,
|
|
74
|
+
wpVersion,
|
|
75
|
+
{ onProgress, spinner, debug }
|
|
76
|
+
) {
|
|
77
|
+
const log = debug
|
|
78
|
+
? ( message ) => {
|
|
79
|
+
spinner.info( `SimpleGit: ${ message }` );
|
|
80
|
+
spinner.start();
|
|
81
|
+
}
|
|
82
|
+
: () => {};
|
|
83
|
+
onProgress( 0 );
|
|
84
|
+
|
|
85
|
+
const progressHandler = ( { progress } ) => {
|
|
86
|
+
onProgress( progress / 100 );
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
// Make sure that the version is in X.X.X format. This is required
|
|
90
|
+
// because WordPress/wordpress-develop uses X.X.X tags but
|
|
91
|
+
// WordPress uses X.X for non-patch releases.
|
|
92
|
+
if ( wpVersion && wpVersion.match( /^[0-9]+.[0-9]+$/ ) ) {
|
|
93
|
+
wpVersion += '.0';
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
log( 'Cloning or getting the PHPUnit suite from GitHub.' );
|
|
97
|
+
const git = SimpleGit( { progress: progressHandler } );
|
|
98
|
+
|
|
99
|
+
const isRepo =
|
|
100
|
+
fs.existsSync( directory ) &&
|
|
101
|
+
( await git.cwd( directory ).checkIsRepo( 'root' ) );
|
|
102
|
+
|
|
103
|
+
if ( isRepo ) {
|
|
104
|
+
log( 'Repo already exists, using it.' );
|
|
105
|
+
} else {
|
|
106
|
+
await git.clone(
|
|
107
|
+
'https://github.com/WordPress/wordpress-develop.git',
|
|
108
|
+
directory,
|
|
109
|
+
{
|
|
110
|
+
'--depth': '1',
|
|
111
|
+
'--no-checkout': null,
|
|
112
|
+
}
|
|
113
|
+
);
|
|
114
|
+
await git.cwd( directory );
|
|
115
|
+
|
|
116
|
+
// We use a sparse checkout to minimize the amount of data we need to download.
|
|
117
|
+
log( 'Enabling sparse checkout.' );
|
|
118
|
+
await git.raw( 'sparse-checkout', 'set', '--cone', 'tests/phpunit' );
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
// Figure out the ref that we need to checkout to get the correct version of the PHPUnit library.
|
|
122
|
+
// Alpha, Beta, and RC versions are bleeding edge and should pull from trunk.
|
|
123
|
+
let ref;
|
|
124
|
+
const fetchRaw = [];
|
|
125
|
+
if ( ! wpVersion || wpVersion.match( /-(?:alpha|beta|rc)/ ) ) {
|
|
126
|
+
ref = 'trunk';
|
|
127
|
+
fetchRaw.push( 'fetch', 'origin', ref, '--depth', '1' );
|
|
128
|
+
} else {
|
|
129
|
+
ref = `tags/${ wpVersion }`;
|
|
130
|
+
fetchRaw.push( 'fetch', 'origin', 'tag', wpVersion, '--depth', '1' );
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
log( `Fetching ${ ref }.` );
|
|
134
|
+
await git.raw( fetchRaw );
|
|
135
|
+
|
|
136
|
+
log( `Checking out ${ ref }.` );
|
|
137
|
+
await git.checkout( ref );
|
|
138
|
+
|
|
139
|
+
onProgress( 1 );
|
|
140
|
+
}
|
package/lib/wordpress.js
CHANGED
|
@@ -5,6 +5,7 @@ const dockerCompose = require( 'docker-compose' );
|
|
|
5
5
|
const util = require( 'util' );
|
|
6
6
|
const fs = require( 'fs' ).promises;
|
|
7
7
|
const path = require( 'path' );
|
|
8
|
+
const got = require( 'got' );
|
|
8
9
|
|
|
9
10
|
/**
|
|
10
11
|
* Promisified dependencies
|
|
@@ -14,6 +15,7 @@ const copyDir = util.promisify( require( 'copy-dir' ) );
|
|
|
14
15
|
/**
|
|
15
16
|
* @typedef {import('./config').WPConfig} WPConfig
|
|
16
17
|
* @typedef {import('./config').WPServiceConfig} WPServiceConfig
|
|
18
|
+
* @typedef {import('./config').WPSource} WPSource
|
|
17
19
|
* @typedef {'development'|'tests'} WPEnvironment
|
|
18
20
|
* @typedef {'development'|'tests'|'all'} WPEnvironmentSelection
|
|
19
21
|
*/
|
|
@@ -101,25 +103,15 @@ async function configureWordPress( environment, config, spinner ) {
|
|
|
101
103
|
}
|
|
102
104
|
);
|
|
103
105
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
* we load it too early, then some things (like MULTISITE) will be defined
|
|
108
|
-
* before wp-phpunit has a chance to configure them. To avoid this, create a
|
|
109
|
-
* copy of wp-config.php for phpunit which doesn't require wp-settings.php.
|
|
110
|
-
*
|
|
111
|
-
* Note that This needs to be executed using `exec` on the wordpress service
|
|
112
|
-
* so that file permissions work properly.
|
|
113
|
-
*
|
|
114
|
-
* This will be removed in the future. @see https://github.com/WordPress/gutenberg/issues/23171
|
|
115
|
-
*
|
|
116
|
-
*/
|
|
106
|
+
// WordPress' PHPUnit suite expects a `wp-tests-config.php` in
|
|
107
|
+
// the directory that the test suite is contained within.
|
|
108
|
+
// Make sure ABSPATH points to the WordPress install.
|
|
117
109
|
await dockerCompose.exec(
|
|
118
110
|
environment === 'development' ? 'wordpress' : 'tests-wordpress',
|
|
119
111
|
[
|
|
120
112
|
'sh',
|
|
121
113
|
'-c',
|
|
122
|
-
|
|
114
|
+
`sed -e "/^require.*wp-settings.php/d" -e "s/define( 'ABSPATH', __DIR__ . '\\/' );/define( 'ABSPATH', '\\/var\\/www\\/html\\/' );\\n\\tdefine( 'WP_DEFAULT_THEME', 'default' );/" /var/www/html/wp-config.php > /wordpress-phpunit/wp-tests-config.php`,
|
|
123
115
|
],
|
|
124
116
|
{
|
|
125
117
|
config: config.dockerComposeConfigPath,
|
|
@@ -246,10 +238,70 @@ async function copyCoreFiles( fromPath, toPath ) {
|
|
|
246
238
|
} );
|
|
247
239
|
}
|
|
248
240
|
|
|
241
|
+
/**
|
|
242
|
+
* Scans through a WordPress source to find the version of WordPress it contains.
|
|
243
|
+
*
|
|
244
|
+
* @param {WPSource} coreSource The WordPress source.
|
|
245
|
+
* @param {Object} spinner A CLI spinner which indicates progress.
|
|
246
|
+
* @param {boolean} debug Indicates whether or not the CLI is in debug mode.
|
|
247
|
+
* @return {string} The version of WordPress the source is for.
|
|
248
|
+
*/
|
|
249
|
+
async function readWordPressVersion( coreSource, spinner, debug ) {
|
|
250
|
+
const versionFilePath = path.join(
|
|
251
|
+
coreSource.path,
|
|
252
|
+
'wp-includes',
|
|
253
|
+
'version.php'
|
|
254
|
+
);
|
|
255
|
+
const versionFile = await fs.readFile( versionFilePath, {
|
|
256
|
+
encoding: 'utf-8',
|
|
257
|
+
} );
|
|
258
|
+
const versionMatch = versionFile.match(
|
|
259
|
+
/\$wp_version = '([A-Za-z\-0-9.]+)'/
|
|
260
|
+
);
|
|
261
|
+
if ( ! versionMatch ) {
|
|
262
|
+
throw new Error( `Failed to find version in ${ versionFilePath }` );
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
if ( debug ) {
|
|
266
|
+
spinner.info(
|
|
267
|
+
`Found WordPress ${ versionMatch[ 1 ] } in ${ versionFilePath }.`
|
|
268
|
+
);
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
return versionMatch[ 1 ];
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
/**
|
|
275
|
+
* Returns the latest stable version of WordPress by requesting the stable-check
|
|
276
|
+
* endpoint on WordPress.org.
|
|
277
|
+
*
|
|
278
|
+
* @return {string} The latest stable version of WordPress, like "6.0.1"
|
|
279
|
+
*/
|
|
280
|
+
let CACHED_WP_VERSION;
|
|
281
|
+
async function getLatestWordPressVersion() {
|
|
282
|
+
// Avoid extra network requests.
|
|
283
|
+
if ( CACHED_WP_VERSION ) {
|
|
284
|
+
return CACHED_WP_VERSION;
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
const versions = await got(
|
|
288
|
+
'https://api.wordpress.org/core/stable-check/1.0/'
|
|
289
|
+
).json();
|
|
290
|
+
|
|
291
|
+
for ( const [ version, status ] of Object.entries( versions ) ) {
|
|
292
|
+
if ( status === 'latest' ) {
|
|
293
|
+
CACHED_WP_VERSION = version;
|
|
294
|
+
return version;
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
|
|
249
299
|
module.exports = {
|
|
250
300
|
hasSameCoreSource,
|
|
251
301
|
checkDatabaseConnection,
|
|
252
302
|
configureWordPress,
|
|
253
303
|
resetDatabase,
|
|
254
304
|
setupWordPressDirectories,
|
|
305
|
+
readWordPressVersion,
|
|
306
|
+
getLatestWordPressVersion,
|
|
255
307
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wordpress/env",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "5.1.1",
|
|
4
4
|
"description": "A zero-config, self contained local WordPress environment for development and testing.",
|
|
5
5
|
"author": "The WordPress Contributors",
|
|
6
6
|
"license": "GPL-2.0-or-later",
|
|
@@ -36,7 +36,7 @@
|
|
|
36
36
|
"copy-dir": "^1.3.0",
|
|
37
37
|
"docker-compose": "^0.22.2",
|
|
38
38
|
"extract-zip": "^1.6.7",
|
|
39
|
-
"got": "^
|
|
39
|
+
"got": "^11.8.5",
|
|
40
40
|
"inquirer": "^7.1.0",
|
|
41
41
|
"js-yaml": "^3.13.1",
|
|
42
42
|
"ora": "^4.0.2",
|
|
@@ -51,5 +51,5 @@
|
|
|
51
51
|
"scripts": {
|
|
52
52
|
"test": "echo \"Error: run tests from root\" && exit 1"
|
|
53
53
|
},
|
|
54
|
-
"gitHead": "
|
|
54
|
+
"gitHead": "002058dceb89577290da6139aea3e99459fb2298"
|
|
55
55
|
}
|