@wordpress/env 5.0.0 → 5.1.0

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 CHANGED
@@ -2,6 +2,14 @@
2
2
 
3
3
  ## Unreleased
4
4
 
5
+ ## 5.1.0 (2022-08-10)
6
+
7
+ ### Enhancement
8
+ - 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.
9
+
10
+ ### Bug Fix
11
+ - 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.
12
+
5
13
  ## 5.0.0 (2022-07-27)
6
14
 
7
15
  ### Breaking Changes
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 10 Pro](https://docs.docker.com/docker-for-windows/install/), [all other versions of Windows](https://docs.docker.com/toolbox/toolbox_install_windows/), [macOS](https://docs.docker.com/docker-for-mac/install/), and [Linux](https://docs.docker.com/v17.12/install/linux/docker-ce/ubuntu/#install-using-the-convenience-script).
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
- Then modify your package.json and add an extra command to npm `scripts` (https://docs.npmjs.com/misc/scripts):
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 the "update" flag to wp-env
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 stop
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. Nuke everything and start again 🔥
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 volumes. This will allow you to start from scratch.
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 nuke everything:
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
 
@@ -211,10 +213,12 @@ wp-env start
211
213
  wp-env start --xdebug=profile,trace,debug
212
214
  ```
213
215
 
214
- When you're running `wp-env` using `npm run`, like when working in the Gutenberg repo or when having `wp-env` as a local project dependency, don't forget to add an extra double dash before the `--xdebug` command:
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:
215
217
 
216
218
  ```sh
217
219
  npm run wp-env start -- --xdebug
220
+ # Alternatively, use npx:
221
+ npx wp-env start --xdebug
218
222
  ```
219
223
 
220
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.
@@ -532,7 +536,7 @@ Additionally, the values referencing a URL include the specified port for the gi
532
536
 
533
537
  ### Examples
534
538
 
535
- #### Latest production WordPress + current directory as a plugin
539
+ #### Latest stable WordPress + current directory as a plugin
536
540
 
537
541
  This is useful for plugin development.
538
542
 
@@ -15,6 +15,7 @@ const readRawConfigFile = require( './read-raw-config-file' );
15
15
  const parseConfig = require( './parse-config' );
16
16
  const { includeTestsPath, parseSourceString } = parseConfig;
17
17
  const md5 = require( '../md5' );
18
+ const { getLatestWordPressVersion } = require( '../wordpress' );
18
19
 
19
20
  /**
20
21
  * wp-env configuration.
@@ -33,7 +34,7 @@ const md5 = require( '../md5' );
33
34
  * Base-level config for any particular environment. (development/tests/etc)
34
35
  *
35
36
  * @typedef WPServiceConfig
36
- * @property {?WPSource} coreSource The WordPress installation to load in the environment.
37
+ * @property {WPSource} coreSource The WordPress installation to load in the environment.
37
38
  * @property {WPSource[]} pluginSources Plugins to load in the environment.
38
39
  * @property {WPSource[]} themeSources Themes to load in the environment.
39
40
  * @property {number} port The port to use.
@@ -68,9 +69,37 @@ module.exports = async function readConfig( configPath ) {
68
69
  md5( configPath )
69
70
  );
70
71
 
72
+ // The specified base configuration from .wp-env.json or from the local
73
+ // source type which was automatically detected.
74
+ const baseConfig =
75
+ ( await readRawConfigFile( '.wp-env.json', configPath ) ) ||
76
+ ( await getDefaultBaseConfig( configPath ) );
77
+
78
+ // Overriden .wp-env.json on a per-user case.
79
+ const overrideConfig =
80
+ ( await readRawConfigFile(
81
+ '.wp-env.override.json',
82
+ configPath.replace( /\.wp-env\.json$/, '.wp-env.override.json' )
83
+ ) ) || {};
84
+
85
+ const detectedLocalConfig =
86
+ Object.keys( { ...baseConfig, ...overrideConfig } ).length > 0;
87
+
88
+ // If there is no local WordPress version, use the latest stable version from GitHub.
89
+ let coreRef;
90
+ if ( ! overrideConfig.core && ! baseConfig.core ) {
91
+ const wpVersion = await getLatestWordPressVersion();
92
+ if ( ! wpVersion ) {
93
+ throw new ValidationError(
94
+ 'Could not find the latest WordPress version. There may be a network issue.'
95
+ );
96
+ }
97
+ coreRef = `WordPress/WordPress#${ wpVersion }`;
98
+ }
99
+
71
100
  // Default configuration which is overridden by .wp-env.json files.
72
101
  const defaultConfiguration = {
73
- core: null,
102
+ core: coreRef,
74
103
  phpVersion: null,
75
104
  plugins: [],
76
105
  themes: [],
@@ -96,22 +125,6 @@ module.exports = async function readConfig( configPath ) {
96
125
  },
97
126
  };
98
127
 
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
128
  // A quick validation before merging on a service by service level allows us
116
129
  // to check the root configuration options and provide more helpful errors.
117
130
  validateConfig(
@@ -21,7 +21,6 @@ Object {
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 [],
@@ -44,7 +43,6 @@ Object {
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 [],
@@ -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 ).not.toBeNull();
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 ).toBeNull();
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 ).toBeNull();
87
- expect( config.env.tests.coreSource ).toBeNull();
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
  } );
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
@@ -246,11 +247,6 @@ async function copyCoreFiles( fromPath, toPath ) {
246
247
  * @return {string} The version of WordPress the source is for.
247
248
  */
248
249
  async function readWordPressVersion( coreSource, spinner, debug ) {
249
- // No source means they're using the bleeding edge.
250
- if ( coreSource === null ) {
251
- return null;
252
- }
253
-
254
250
  const versionFilePath = path.join(
255
251
  coreSource.path,
256
252
  'wp-includes',
@@ -275,6 +271,24 @@ async function readWordPressVersion( coreSource, spinner, debug ) {
275
271
  return versionMatch[ 1 ];
276
272
  }
277
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
+ async function getLatestWordPressVersion() {
281
+ const versions = await got(
282
+ 'https://api.wordpress.org/core/stable-check/1.0/'
283
+ ).json();
284
+
285
+ for ( const [ version, status ] of Object.entries( versions ) ) {
286
+ if ( status === 'latest' ) {
287
+ return version;
288
+ }
289
+ }
290
+ }
291
+
278
292
  module.exports = {
279
293
  hasSameCoreSource,
280
294
  checkDatabaseConnection,
@@ -282,4 +296,5 @@ module.exports = {
282
296
  resetDatabase,
283
297
  setupWordPressDirectories,
284
298
  readWordPressVersion,
299
+ getLatestWordPressVersion,
285
300
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wordpress/env",
3
- "version": "5.0.0",
3
+ "version": "5.1.0",
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",
@@ -51,5 +51,5 @@
51
51
  "scripts": {
52
52
  "test": "echo \"Error: run tests from root\" && exit 1"
53
53
  },
54
- "gitHead": "0315dbc240cb2aa146d7c1bafd251f004b88300e"
54
+ "gitHead": "08358f53b627a15148c3a3e433cdf58cf8714aa4"
55
55
  }