@wordpress/env 10.38.0 → 10.39.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/lib/wordpress.js CHANGED
@@ -2,17 +2,10 @@
2
2
  /**
3
3
  * External dependencies
4
4
  */
5
- const { v2: dockerCompose } = require( 'docker-compose' );
6
- const util = require( 'util' );
5
+ const dns = require( 'dns' ).promises;
7
6
  const fs = require( 'fs' ).promises;
8
7
  const path = require( 'path' );
9
8
  const got = require( 'got' );
10
- const dns = require( 'dns' ).promises;
11
-
12
- /**
13
- * Promisified dependencies
14
- */
15
- const copyDir = util.promisify( require( 'copy-dir' ) );
16
9
 
17
10
  /**
18
11
  * Internal dependencies
@@ -20,292 +13,8 @@ const copyDir = util.promisify( require( 'copy-dir' ) );
20
13
  const { getCache, setCache } = require( './cache' );
21
14
 
22
15
  /**
23
- * @typedef {import('./config').WPConfig} WPConfig
24
- * @typedef {import('./config').WPEnvironmentConfig} WPEnvironmentConfig
25
16
  * @typedef {import('./config').WPSource} WPSource
26
- * @typedef {'development'|'tests'} WPEnvironment
27
- * @typedef {'development'|'tests'|'all'} WPEnvironmentSelection
28
- */
29
-
30
- /**
31
- * Utility function to check if a WordPress version is lower than another version.
32
- *
33
- * This is a non-comprehensive check only intended for this usage, to avoid pulling in a full semver library.
34
- * It only considers the major and minor portions of the version and ignores the rest. Additionally, it assumes that
35
- * the minor version is always a single digit (i.e. 0-9).
36
- *
37
- * Do not use this function for general version comparison, as it will not work for all cases.
38
- *
39
- * @param {string} version The version to check.
40
- * @param {string} compareVersion The compare version to check whether the version is lower than.
41
- * @return {boolean} True if the version is lower than the compare version, false otherwise.
42
- */
43
- function isWPMajorMinorVersionLower( version, compareVersion ) {
44
- const versionNumber = Number.parseFloat(
45
- version.match( /^[0-9]+(\.[0-9]+)?/ )[ 0 ]
46
- );
47
- const compareVersionNumber = Number.parseFloat(
48
- compareVersion.match( /^[0-9]+(\.[0-9]+)?/ )[ 0 ]
49
- );
50
-
51
- return versionNumber < compareVersionNumber;
52
- }
53
-
54
- /**
55
- * Checks a WordPress database connection. An error is thrown if the test is
56
- * unsuccessful.
57
- *
58
- * @param {WPConfig} config The wp-env config object.
59
- */
60
- async function checkDatabaseConnection( { dockerComposeConfigPath, debug } ) {
61
- await dockerCompose.run( 'cli', 'wp db check', {
62
- config: dockerComposeConfigPath,
63
- commandOptions: [ '--rm' ],
64
- log: debug,
65
- } );
66
- }
67
-
68
- /**
69
- * Configures WordPress for the given environment by installing WordPress,
70
- * activating all plugins, and activating the first theme. These steps are
71
- * performed sequentially so as to not overload the WordPress instance.
72
- *
73
- * @param {WPEnvironment} environment The environment to configure. Either 'development' or 'tests'.
74
- * @param {WPConfig} config The wp-env config object.
75
- * @param {Object} spinner A CLI spinner which indicates progress.
76
- */
77
- async function configureWordPress( environment, config, spinner ) {
78
- let wpVersion = '';
79
- try {
80
- wpVersion = await readWordPressVersion(
81
- config.env[ environment ].coreSource,
82
- spinner,
83
- config.debug
84
- );
85
- } catch ( err ) {
86
- // Ignore error.
87
- }
88
-
89
- // Create a project-specific wp-cli configuration, important for the `rewrite` command.
90
- // Don't overwrite existing configuration.
91
- const cliConfigCommand = `[ -f /var/www/html/wp-cli.yml ] || (
92
- exec > /var/www/html/wp-cli.yml
93
- echo "apache_modules:"
94
- echo " - mod_rewrite"
95
- )`;
96
-
97
- const isMultisite = config.env[ environment ].multisite;
98
-
99
- const installMethod = isMultisite ? 'multisite-install' : 'install';
100
- const installCommand = `wp core ${ installMethod } --url="${ config.env[ environment ].config.WP_SITEURL }" --title="${ config.name }" --admin_user=admin --admin_password=password --admin_email=wordpress@example.com --skip-email`;
101
-
102
- // -eo pipefail exits the command as soon as anything fails in bash.
103
- const setupCommands = [
104
- 'set -eo pipefail',
105
- cliConfigCommand,
106
- installCommand,
107
- ];
108
-
109
- // Bootstrap .htaccess for multisite
110
- if ( isMultisite ) {
111
- // Using a subshell with `exec` was the best tradeoff I could come up
112
- // with between readability of this source and compatibility with the
113
- // way that all strings in `setupCommands` are later joined with '&&'.
114
- setupCommands.push(
115
- `(
116
- exec > /var/www/html/.htaccess
117
- echo 'RewriteEngine On'
118
- echo 'RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]'
119
- echo 'RewriteBase /'
120
- echo 'RewriteRule ^index\.php$ - [L]'
121
- echo ''
122
- echo '# add a trailing slash to /wp-admin'
123
- echo 'RewriteRule ^([_0-9a-zA-Z-]+/)?wp-admin$ $1wp-admin/ [R=301,L]'
124
- echo ''
125
- echo 'RewriteCond %{REQUEST_FILENAME} -f [OR]'
126
- echo 'RewriteCond %{REQUEST_FILENAME} -d'
127
- echo 'RewriteRule ^ - [L]'
128
- echo 'RewriteRule ^([_0-9a-zA-Z-]+/)?(wp-(content|admin|includes).*) $2 [L]'
129
- echo 'RewriteRule ^([_0-9a-zA-Z-]+/)?(.*\.php)$ $2 [L]'
130
- echo 'RewriteRule . index.php [L]'
131
- )`
132
- );
133
- }
134
-
135
- // WordPress versions below 5.1 didn't use proper spacing in wp-config.
136
- const configAnchor =
137
- wpVersion && isWPMajorMinorVersionLower( wpVersion, '5.1' )
138
- ? `"define('WP_DEBUG',"`
139
- : `"define( 'WP_DEBUG',"`;
140
-
141
- // Set wp-config.php values.
142
- for ( let [ key, value ] of Object.entries(
143
- config.env[ environment ].config
144
- ) ) {
145
- // Allow the configuration to skip a default constant by specifying it as null.
146
- if ( null === value ) {
147
- continue;
148
- }
149
-
150
- // Add quotes around string values to work with multi-word strings better.
151
- value = typeof value === 'string' ? `"${ value }"` : value;
152
- setupCommands.push(
153
- `wp config set ${ key } ${ value } --anchor=${ configAnchor }${
154
- typeof value !== 'string' ? ' --raw' : ''
155
- }`
156
- );
157
- }
158
-
159
- // Activate all plugins.
160
- for ( const pluginSource of config.env[ environment ].pluginSources ) {
161
- setupCommands.push( `wp plugin activate ${ pluginSource.basename }` );
162
- }
163
-
164
- if ( config.debug ) {
165
- spinner.info(
166
- `Running the following setup commands on the ${ environment } instance:\n - ${ setupCommands.join(
167
- '\n - '
168
- ) }\n`
169
- );
170
- }
171
-
172
- // Execute all setup commands in a batch.
173
- await dockerCompose.run(
174
- environment === 'development' ? 'cli' : 'tests-cli',
175
- [ 'bash', '-c', setupCommands.join( ' && ' ) ],
176
- {
177
- config: config.dockerComposeConfigPath,
178
- commandOptions: [ '--rm' ],
179
- log: config.debug,
180
- }
181
- );
182
-
183
- // WordPress versions below 5.1 didn't use proper spacing in wp-config.
184
- // Additionally, WordPress versions below 5.4 used `dirname( __FILE__ )` instead of `__DIR__`.
185
- let abspathDef = `define( 'ABSPATH', __DIR__ . '\\/' );`;
186
- if ( wpVersion && isWPMajorMinorVersionLower( wpVersion, '5.1' ) ) {
187
- abspathDef = `define('ABSPATH', dirname(__FILE__) . '\\/');`;
188
- } else if ( wpVersion && isWPMajorMinorVersionLower( wpVersion, '5.4' ) ) {
189
- abspathDef = `define( 'ABSPATH', dirname( __FILE__ ) . '\\/' );`;
190
- }
191
-
192
- // WordPress' PHPUnit suite expects a `wp-tests-config.php` in
193
- // the directory that the test suite is contained within.
194
- // Make sure ABSPATH points to the WordPress install.
195
- await dockerCompose.exec(
196
- environment === 'development' ? 'wordpress' : 'tests-wordpress',
197
- [
198
- 'sh',
199
- '-c',
200
- `sed -e "/^require.*wp-settings.php/d" -e "s/${ abspathDef }/define( 'ABSPATH', '\\/var\\/www\\/html\\/' );\\n\\tdefine( 'WP_DEFAULT_THEME', 'default' );/" /var/www/html/wp-config.php > /wordpress-phpunit/wp-tests-config.php`,
201
- ],
202
- {
203
- config: config.dockerComposeConfigPath,
204
- log: config.debug,
205
- }
206
- );
207
- }
208
-
209
- /**
210
- * Resets the development server's database, the tests server's database, or both.
211
- *
212
- * @param {WPEnvironmentSelection} environment The environment to clean. Either 'development', 'tests', or 'all'.
213
- * @param {WPConfig} config The wp-env config object.
214
- */
215
- async function resetDatabase(
216
- environment,
217
- { dockerComposeConfigPath, debug }
218
- ) {
219
- const options = {
220
- config: dockerComposeConfigPath,
221
- commandOptions: [ '--rm' ],
222
- log: debug,
223
- };
224
-
225
- const tasks = [];
226
-
227
- if ( environment === 'all' || environment === 'development' ) {
228
- tasks.push( dockerCompose.run( 'cli', 'wp db reset --yes', options ) );
229
- }
230
-
231
- if ( environment === 'all' || environment === 'tests' ) {
232
- tasks.push(
233
- dockerCompose.run( 'tests-cli', 'wp db reset --yes', options )
234
- );
235
- }
236
-
237
- await Promise.all( tasks );
238
- }
239
-
240
- async function setupWordPressDirectories( config ) {
241
- if (
242
- config.env.development.coreSource &&
243
- hasSameCoreSource( [ config.env.development, config.env.tests ] )
244
- ) {
245
- await copyCoreFiles(
246
- config.env.development.coreSource.path,
247
- config.env.development.coreSource.testsPath
248
- );
249
- }
250
- }
251
-
252
- /**
253
- * Returns true if all given environment configs have the same core source.
254
- *
255
- * @param {WPEnvironmentConfig[]} envs An array of environments to check.
256
- *
257
- * @return {boolean} True if all the environments have the same core source.
258
17
  */
259
- function hasSameCoreSource( envs ) {
260
- if ( envs.length < 2 ) {
261
- return true;
262
- }
263
- return ! envs.some( ( env ) =>
264
- areCoreSourcesDifferent( envs[ 0 ].coreSource, env.coreSource )
265
- );
266
- }
267
-
268
- function areCoreSourcesDifferent( coreSource1, coreSource2 ) {
269
- if (
270
- ( ! coreSource1 && coreSource2 ) ||
271
- ( coreSource1 && ! coreSource2 )
272
- ) {
273
- return true;
274
- }
275
-
276
- if ( coreSource1 && coreSource2 && coreSource1.path !== coreSource2.path ) {
277
- return true;
278
- }
279
-
280
- return false;
281
- }
282
-
283
- /**
284
- * Copies a WordPress installation, taking care to ignore large directories
285
- * (.git, node_modules) and configuration files (wp-config.php).
286
- *
287
- * @param {string} fromPath Path to the WordPress directory to copy.
288
- * @param {string} toPath Destination path.
289
- */
290
- async function copyCoreFiles( fromPath, toPath ) {
291
- await copyDir( fromPath, toPath, {
292
- filter( stat, filepath, filename ) {
293
- if ( stat === 'symbolicLink' ) {
294
- return false;
295
- }
296
- if ( stat === 'directory' && filename === '.git' ) {
297
- return false;
298
- }
299
- if ( stat === 'directory' && filename === 'node_modules' ) {
300
- return false;
301
- }
302
- if ( stat === 'file' && filename === 'wp-config.php' ) {
303
- return false;
304
- }
305
- return true;
306
- },
307
- } );
308
- }
309
18
 
310
19
  /**
311
20
  * Scans through a WordPress source to find the version of WordPress it contains.
@@ -402,11 +111,6 @@ async function getLatestWordPressVersion( options ) {
402
111
  }
403
112
 
404
113
  module.exports = {
405
- hasSameCoreSource,
406
- checkDatabaseConnection,
407
- configureWordPress,
408
- resetDatabase,
409
- setupWordPressDirectories,
410
114
  readWordPressVersion,
411
115
  canAccessWPORG,
412
116
  getLatestWordPressVersion,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wordpress/env",
3
- "version": "10.38.0",
3
+ "version": "10.39.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",
@@ -8,7 +8,8 @@
8
8
  "wordpress",
9
9
  "gutenberg",
10
10
  "environment",
11
- "docker"
11
+ "docker",
12
+ "playground"
12
13
  ],
13
14
  "homepage": "https://github.com/WordPress/gutenberg/tree/HEAD/packages/env#readme",
14
15
  "repository": {
@@ -43,8 +44,10 @@
43
44
  },
44
45
  "dependencies": {
45
46
  "@inquirer/prompts": "^7.2.0",
47
+ "@wp-playground/cli": "^3.0.0",
46
48
  "chalk": "^4.0.0",
47
49
  "copy-dir": "^1.3.0",
50
+ "cross-spawn": "^7.0.6",
48
51
  "docker-compose": "^0.24.3",
49
52
  "extract-zip": "^1.6.7",
50
53
  "got": "^11.8.5",
@@ -61,5 +64,5 @@
61
64
  "scripts": {
62
65
  "test": "echo \"Error: run tests from root\" && exit 1"
63
66
  },
64
- "gitHead": "50c4c0f51e4797c217946ce42adfaa5eb026f33f"
67
+ "gitHead": "eee1cfb1472f11183e40fb77465a5f13145df7ad"
65
68
  }
@@ -2,9 +2,9 @@
2
2
  /**
3
3
  * External dependencies
4
4
  */
5
- const SimpleGit = require( 'simple-git' );
6
5
  const fs = require( 'fs' );
7
6
  const path = require( 'path' );
7
+ const SimpleGit = require( 'simple-git' );
8
8
 
9
9
  /**
10
10
  * @typedef {import('./config').WPConfig} WPConfig