@wordpress/env 6.0.0 → 8.0.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.
Files changed (55) hide show
  1. package/README.md +130 -66
  2. package/lib/build-docker-compose-config.js +67 -96
  3. package/lib/cache.js +1 -0
  4. package/lib/cli.js +39 -10
  5. package/lib/commands/clean.js +13 -1
  6. package/lib/commands/destroy.js +21 -42
  7. package/lib/commands/index.js +1 -0
  8. package/lib/commands/install-path.js +1 -0
  9. package/lib/commands/logs.js +1 -0
  10. package/lib/commands/run.js +45 -21
  11. package/lib/commands/start.js +29 -8
  12. package/lib/commands/stop.js +1 -0
  13. package/lib/config/add-or-replace-port.js +12 -3
  14. package/lib/config/db-env.js +1 -0
  15. package/lib/config/detect-directory-type.js +1 -1
  16. package/lib/config/get-cache-directory.js +39 -0
  17. package/lib/config/get-config-from-environment-vars.js +106 -0
  18. package/lib/config/index.js +7 -5
  19. package/lib/config/load-config.js +92 -0
  20. package/lib/config/merge-configs.js +105 -0
  21. package/lib/config/parse-config.js +501 -157
  22. package/lib/config/parse-source-string.js +164 -0
  23. package/lib/config/post-process-config.js +202 -0
  24. package/lib/config/read-raw-config-file.js +7 -33
  25. package/lib/config/test/__snapshots__/config-integration.js.snap +295 -0
  26. package/lib/config/test/add-or-replace-port.js +29 -1
  27. package/lib/config/test/config-integration.js +164 -0
  28. package/lib/config/test/get-cache-directory.js +57 -0
  29. package/lib/config/test/merge-configs.js +121 -0
  30. package/lib/config/test/parse-config.js +393 -0
  31. package/lib/config/test/parse-source-string.js +154 -0
  32. package/lib/config/test/post-process-config.js +299 -0
  33. package/lib/config/test/read-raw-config-file.js +19 -63
  34. package/lib/config/test/validate-config.js +363 -0
  35. package/lib/config/validate-config.js +119 -54
  36. package/lib/env.js +2 -0
  37. package/lib/execute-lifecycle-script.js +86 -0
  38. package/lib/get-host-user.js +27 -0
  39. package/lib/init-config.js +186 -63
  40. package/lib/md5.js +1 -0
  41. package/lib/parse-xdebug-mode.js +1 -0
  42. package/lib/retry.js +1 -0
  43. package/lib/test/__snapshots__/md5.js.snap +9 -0
  44. package/lib/test/build-docker-compose-config.js +134 -0
  45. package/lib/test/cache.js +154 -0
  46. package/lib/test/cli.js +149 -0
  47. package/lib/test/execute-lifecycle-script.js +59 -0
  48. package/lib/test/md5.js +35 -0
  49. package/lib/test/parse-xdebug-mode.js +41 -0
  50. package/lib/validate-run-container.js +41 -0
  51. package/lib/wordpress.js +4 -19
  52. package/package.json +2 -2
  53. package/lib/config/config.js +0 -353
  54. package/lib/config/test/__snapshots__/config.js.snap +0 -83
  55. package/lib/config/test/config.js +0 -1241
package/README.md CHANGED
@@ -175,32 +175,33 @@ $ wp-env destroy
175
175
  $ wp-env start
176
176
  ```
177
177
 
178
- ### 7. Debug mode and inspecting the generated dockerfile.
178
+ ## Using included WordPress PHPUnit test files
179
179
 
180
- `wp-env` uses docker behind the scenes. Inspecting the generated docker-compose file can help to understand what's going on.
180
+ 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.
181
181
 
182
- Start `wp-env` in debug mode
182
+ ### Customizing the `wp-tests-config.php` file
183
183
 
184
- ```sh
185
- wp-env start --debug
186
- ```
184
+ 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.
187
185
 
188
- `wp-env` will output its config which includes `dockerComposeConfigPath`.
186
+ ## Using `composer`, `phpunit`, and `wp-cli` tools.
189
187
 
190
- ```sh
191
- ℹ Config:
192
- ...
193
- "dockerComposeConfigPath": "/Users/$USERNAME/.wp-env/5a619d332a92377cd89feb339c67b833/docker-compose.yml",
194
- ...
195
- ```
188
+ For ease of use, Composer, PHPUnit, and wp-cli are available for in the environment. To run these executables, use `wp-env run <env> <tool> <command>`. For example, `wp-env run cli composer install`, or `wp-env run tests-cli phpunit`. You can also access various shells like `wp-env run cli bash` or `wp-env run cli wp shell`.
196
189
 
197
- ## Using included WordPress PHPUnit test files
190
+ For the `env` part, `cli` and `wordpress` share a database and mapped volumes, but more tools are available in the cli environment. You should use the `tests-cli` / `tests-wordpress` environments for a separate testing database.
198
191
 
199
- 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.
192
+ By default, the cwd of the run command is the root of the WordPress install. If you're working on a plugin, you likely need to pass `--env-cwd` to make sure composer/phpunit commands are executed relative to the plugin you're working on. For example, `wp-env run cli --env-cwd=wp-content/plugins/gutenberg composer install`.
200
193
 
201
- ### Customizing the `wp-tests-config.php` file
194
+ To make this easier, it's often helpful to add scripts in your `package.json` file:
202
195
 
203
- 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.
196
+ ```json
197
+ {
198
+ "scripts": {
199
+ "composer": "wp-env run cli --env-cwd=wp-content/plugins/gutenberg composer"
200
+ }
201
+ }
202
+ ```
203
+
204
+ Then, `npm run composer install` would run composer install in the environment. You could also do this for phpunit, wp-cli, etc.
204
205
 
205
206
  ## Using Xdebug
206
207
 
@@ -272,15 +273,14 @@ The start command installs and initializes the WordPress environment, which incl
272
273
  ```sh
273
274
  wp-env start
274
275
 
275
- Starts WordPress for development on port 8888 (override with WP_ENV_PORT) and
276
- tests on port 8889 (override with WP_ENV_TESTS_PORT). The current working
277
- directory must be a WordPress installation, a plugin, a theme, or contain a
278
- .wp-env.json file. After first install, use the '--update' flag to download
279
- updates to mapped sources and to re-apply WordPress configuration options.
276
+ Starts WordPress for development on port 8888 (​http://localhost:8888​)
277
+ (override with WP_ENV_PORT) and tests on port 8889 (​http://localhost:8889​)
278
+ (override with WP_ENV_TESTS_PORT). The current working directory must be a
279
+ WordPress installation, a plugin, a theme, or contain a .wp-env.json file. After
280
+ first install, use the '--update' flag to download updates to mapped sources and
281
+ to re-apply WordPress configuration options.
280
282
 
281
283
  Options:
282
- --help Show help [boolean]
283
- --version Show version number [boolean]
284
284
  --debug Enable debug output. [boolean] [default: false]
285
285
  --update Download source updates and apply WordPress configuration.
286
286
  [boolean] [default: false]
@@ -289,6 +289,7 @@ Options:
289
289
  them in a comma-separated list: `--xdebug=develop,coverage`. See
290
290
  https://xdebug.org/docs/all_settings#mode for information about
291
291
  Xdebug modes. [string]
292
+ --scripts Execute any configured lifecycle scripts. [boolean] [default: true]
292
293
  ```
293
294
 
294
295
  ### `wp-env stop`
@@ -297,6 +298,9 @@ Options:
297
298
  wp-env stop
298
299
 
299
300
  Stops running WordPress for development and tests and frees the ports.
301
+
302
+ Options:
303
+ --debug Enable debug output. [boolean] [default: false]
300
304
  ```
301
305
 
302
306
  ### `wp-env clean [environment]`
@@ -309,45 +313,46 @@ Cleans the WordPress databases.
309
313
  Positionals:
310
314
  environment Which environments' databases to clean.
311
315
  [string] [choices: "all", "development", "tests"] [default: "tests"]
312
- ```
313
316
 
314
- ### `wp-env run [container] [command]`
317
+ Options:
318
+ --debug Enable debug output. [boolean] [default: false]
319
+ --scripts Execute any configured lifecycle scripts. [boolean] [default: true]
320
+ ```
315
321
 
316
- The run command can be used to open shell sessions or invoke WP-CLI commands.
322
+ ### `wp-env run <container> [command...]`
317
323
 
318
- <div class="callout callout-alert">In some cases, <code>wp-env</code> may consume options that you are attempting to pass to
319
- the container. This happens with options that <code>wp-env</code> has already declared,
320
- such as <code>--env-cwd</code>, <code>--debug</code>, <code>--help</code>, and <code>--version</code>. When this happens, you should fall
321
- back to using quotation marks; <code>wp-env</code> considers everything inside the
322
- quotation marks to be command argument.
324
+ The run command can be used to open shell sessions, invoke WP-CLI commands, or run any arbitrary commands inside of a container.
323
325
 
324
- For example, to ask <code>WP-CLI</code> for its help text:
325
- <pre>sh
326
- <code class="language-sh">wp-env run cli "wp --help"</code></pre>
327
-
328
- Without the quotation marks, <code>wp-env</code> will print its own help text instead of
329
- passing it to the container. If you experience any problems where the command
330
- is not being passed correctly, fall back to using quotation marks.
326
+ <div class="callout callout-alert">
327
+ <p>
328
+ In some cases <code class="language-sh">wp-env run</code> may conflict with options that you are passing to the container.
329
+ When this happens, <code class="language-sh">wp-env</code> will treat the option as its own and take action accordingly.
330
+ For example, if you try <code class="language-sh">wp-env run cli php --help</code>, you will receive the <code class="language-sh">wp-env</code> help text.
331
+ </p>
331
332
 
333
+ <p>
334
+ You can get around this by passing any conflicting options after a double dash. <code class="language-sh">wp-env</code> will not process anything after
335
+ the double dash and will simply pass it on to the container. To get the PHP help text you would use <code class="language-sh">wp-env run cli php -- --help</code>.
336
+ </p>
332
337
  </div>
333
338
 
334
339
  ```sh
335
- wp-env run <container> [command..]
340
+ wp-env run <container> [command...]
336
341
 
337
- Runs an arbitrary command in one of the underlying Docker containers. The
338
- "container" param should reference one of the underlying Docker services like
339
- "development", "tests", or "cli". To run a wp-cli command, use the "cli" or
340
- "tests-cli" service. You can also use this command to open shell sessions like
341
- bash and the WordPress shell in the WordPress instance. For example, `wp-env run
342
- cli bash` will open bash in the development WordPress instance.
342
+ Runs an arbitrary command in one of the underlying Docker containers. A double
343
+ dash can be used to pass arguments to the container without parsing them. This
344
+ is necessary if you are using an option that is defined below. You can use
345
+ `bash` to open a shell session and both `composer` and `phpunit` are available
346
+ in all WordPress and CLI containers. WP-CLI is also available in the CLI
347
+ containers.
343
348
 
344
349
  Positionals:
345
- container The container to run the command on. [string] [required]
346
- command The command to run. [array] [default: []]
350
+ container The Docker service to run the command on.
351
+ [string] [required] [choices: "mysql", "tests-mysql", "wordpress",
352
+ "tests-wordpress", "cli", "tests-cli", "composer", "phpunit"]
353
+ command The command to run. [required]
347
354
 
348
355
  Options:
349
- --help Show help [boolean]
350
- --version Show version number [boolean]
351
356
  --debug Enable debug output. [boolean] [default: false]
352
357
  --env-cwd The command's working directory inside of the container. Paths
353
358
  without a leading slash are relative to the WordPress root.
@@ -409,11 +414,22 @@ Success: Installed 1 of 1 plugins.
409
414
  ✔ Ran `plugin install custom-post-type-ui` in 'cli'. (in 6s 483ms)
410
415
  ```
411
416
 
412
- **NOTE**: Depending on your host OS, you may experience errors when trying to install plugins or themes (e.g. `Warning: Could not create directory.`). This is typically because the user ID used within the container does not have write access to the mounted directories created by `wp-env`. To resolve this, run the `docker-compose` command directly from the directory created by `wp-env` and add `-u $(id -u)` and `-e HOME=/tmp` the `run` command as options:
417
+ #### Changing the permalink structure
418
+
419
+ You might want to do this to enable access to the REST API (`wp-env/wp/v2/`) endpoint in your wp-env environment. The endpoint is not available with plain permalinks.
420
+
421
+ **Examples**
422
+
423
+ To set the permalink to just the post name:
413
424
 
414
- ```sh
415
- $ cd ~/wp-env/500cd328b649d63e882d5c4695871d04
416
- $ docker-compose run --rm -u $(id -u) -e HOME=/tmp cli [plugin|theme] install <plugin|theme>
425
+ ```
426
+ wp-env run cli "wp rewrite structure /%postname%/"
427
+ ```
428
+
429
+ To set the permalink to the year, month, and post name:
430
+
431
+ ```
432
+ wp-env run cli "wp rewrite structure /%year%/%monthnum%/%postname%/"
417
433
  ```
418
434
 
419
435
  ### `wp-env destroy`
@@ -423,6 +439,10 @@ wp-env destroy
423
439
 
424
440
  Destroy the WordPress environment. Deletes docker containers, volumes, and
425
441
  networks associated with the WordPress environment and removes local files.
442
+
443
+ Options:
444
+ --debug Enable debug output. [boolean] [default: false]
445
+ --scripts Execute any configured lifecycle scripts. [boolean] [default: true]
426
446
  ```
427
447
 
428
448
  ### `wp-env logs [environment]`
@@ -437,15 +457,13 @@ Positionals:
437
457
  [string] [choices: "development", "tests", "all"] [default: "development"]
438
458
 
439
459
  Options:
440
- --help Show help [boolean]
441
- --version Show version number [boolean]
442
460
  --debug Enable debug output. [boolean] [default: false]
443
461
  --watch Watch for logs as they happen. [boolean] [default: true]
444
462
  ```
445
463
 
446
464
  ### `wp-env install-path`
447
465
 
448
- Outputs the absolute path to the WordPress environment files.
466
+ Get the path where all of the environment files are stored. This includes the Docker files, WordPress, PHPUnit files, and any sources that were downloaded.
449
467
 
450
468
  Example:
451
469
 
@@ -540,9 +558,20 @@ These can be overridden by setting a value within the `config` configuration. Se
540
558
 
541
559
  Additionally, the values referencing a URL include the specified port for the given environment. So if you set `testsPort: 3000, port: 2000`, `WP_HOME` (for example) will be `http://localhost:3000` on the tests instance and `http://localhost:2000` on the development instance.
542
560
 
543
- ### Examples
561
+ ## Lifecycle Scripts
562
+
563
+ Using the `lifecycleScripts` option in `.wp-env.json` will allow you to set arbitrary commands to be executed at certain points in the lifecycle. This configuration
564
+ can also be overridden using `WP_ENV_LIFECYCLE_SCRIPT_{LIFECYCLE_EVENT}` environment variables, with the remainder being the all-caps snake_case name of the option, for
565
+ example, `WP_ENV_LIFECYCLE_SCRIPT_AFTER_START`. Keep in mind that these will be executed on both fresh and existing environments, so, ensure any commands you
566
+ build won't break on subsequent executions.
567
+
568
+ * `afterStart`: Runs after `wp-env start` has finished setting up the environment.
569
+ * `afterClean`: Runs after `wp-env clean` has finished cleaning the environment.
570
+ * `afterDestroy`: Runs after `wp-env destroy` has destroyed the environment.
571
+
572
+ ## Examples
544
573
 
545
- #### Latest stable WordPress + current directory as a plugin
574
+ ### Latest stable WordPress + current directory as a plugin
546
575
 
547
576
  This is useful for plugin development.
548
577
 
@@ -564,7 +593,7 @@ This is useful for plugin development when upstream Core changes need to be test
564
593
  }
565
594
  ```
566
595
 
567
- #### Local `wordpress-develop` + current directory as a plugin
596
+ ### Local `wordpress-develop` + current directory as a plugin
568
597
 
569
598
  This is useful for working on plugins and WordPress Core at the same time.
570
599
 
@@ -586,7 +615,7 @@ If you are running `wordpress-develop` in a dev mode (e.g. the watch command `de
586
615
  }
587
616
  ```
588
617
 
589
- #### A complete testing environment
618
+ ### A complete testing environment
590
619
 
591
620
  This is useful for integration testing: that is, testing how old versions of WordPress and different combinations of plugins and themes impact each other.
592
621
 
@@ -598,7 +627,7 @@ This is useful for integration testing: that is, testing how old versions of Wor
598
627
  }
599
628
  ```
600
629
 
601
- #### Add mu-plugins and other mapped directories
630
+ ### Add mu-plugins and other mapped directories
602
631
 
603
632
  You can add mu-plugins via the mapping config. The mapping config also allows you to mount a directory to any location in the wordpress install, so you could even mount a subdirectory. Note here that theme-1, will not be activated.
604
633
 
@@ -613,7 +642,7 @@ You can add mu-plugins via the mapping config. The mapping config also allows yo
613
642
  }
614
643
  ```
615
644
 
616
- #### Avoid activating plugins or themes on the instance
645
+ ### Avoid activating plugins or themes on the instance
617
646
 
618
647
  Since all plugins in the `plugins` key are activated by default, you should use the `mappings` key to avoid this behavior. This might be helpful if you have a test plugin that should not be activated all the time.
619
648
 
@@ -626,7 +655,7 @@ Since all plugins in the `plugins` key are activated by default, you should use
626
655
  }
627
656
  ```
628
657
 
629
- #### Map a plugin only in the tests environment
658
+ ### Map a plugin only in the tests environment
630
659
 
631
660
  If you need a plugin active in one environment but not the other, you can use `env.<envName>` to set options specific to one environment. Here, we activate cwd and a test plugin on the tests instance. This plugin is not activated on any other instances.
632
661
 
@@ -641,7 +670,7 @@ If you need a plugin active in one environment but not the other, you can use `e
641
670
  }
642
671
  ```
643
672
 
644
- #### Custom Port Numbers
673
+ ### Custom Port Numbers
645
674
 
646
675
  You can tell `wp-env` to use a custom port number so that your instance does not conflict with other `wp-env` instances.
647
676
 
@@ -657,7 +686,7 @@ You can tell `wp-env` to use a custom port number so that your instance does not
657
686
  }
658
687
  ```
659
688
 
660
- #### Specific PHP Version
689
+ ### Specific PHP Version
661
690
 
662
691
  You can tell `wp-env` to use a specific PHP version for compatibility and testing. This can also be set via the environment variable `WP_ENV_PHP_VERSION`.
663
692
 
@@ -668,6 +697,41 @@ You can tell `wp-env` to use a specific PHP version for compatibility and testin
668
697
  }
669
698
  ```
670
699
 
700
+ ### Node Lifecycle Script
701
+
702
+ This is useful for performing some actions after setting up the environment, such as bootstrapping an E2E test environment.
703
+
704
+ ```json
705
+ {
706
+ "lifecycleScripts": {
707
+ "afterStart": "node tests/e2e/bin/setup-env.js"
708
+ }
709
+ }
710
+ ```
711
+
712
+ ### Advanced PHP settings
713
+
714
+ You can set PHP settings by mapping an `.htaccess` file. This maps an `.htaccess` file to the WordPress root (`/var/www/html`) from the directory in which you run `wp-env`.
715
+
716
+ ```json
717
+ {
718
+ "mappings": {
719
+ ".htaccess": ".htaccess"
720
+ }
721
+ }
722
+ ```
723
+
724
+ Then, your .htaccess file can contain various settings like this:
725
+
726
+ ```
727
+ # Note: the default upload value is 1G.
728
+ php_value post_max_size 2G
729
+ php_value upload_max_filesize 2G
730
+ php_value memory_limit 2G
731
+ ```
732
+
733
+ This is useful if there are options you'd like to add to `php.ini`, which is difficult to access in this environment.
734
+
671
735
  ## Contributing to this package
672
736
 
673
737
  This is an individual package that's part of the Gutenberg project. The project is organized as a monorepo. It's made up of multiple self-contained software packages, each with a specific purpose. The packages in this monorepo are published to [npm](https://www.npmjs.com/) and used by [WordPress](https://make.wordpress.org/core/) as well as other software projects.
@@ -10,25 +10,28 @@ const path = require( 'path' );
10
10
  */
11
11
  const { hasSameCoreSource } = require( './wordpress' );
12
12
  const { dbEnv } = require( './config' );
13
+ const getHostUser = require( './get-host-user' );
13
14
 
14
15
  /**
15
16
  * @typedef {import('./config').WPConfig} WPConfig
16
- * @typedef {import('./config').WPServiceConfig} WPServiceConfig
17
+ * @typedef {import('./config').WPEnvironmentConfig} WPEnvironmentConfig
17
18
  */
18
19
 
19
20
  /**
20
21
  * Gets the volume mounts for an individual service.
21
22
  *
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).
23
+ * @param {string} workDirectoryPath The working directory for wp-env.
24
+ * @param {WPEnvironmentConfig} config The service config to get the mounts from.
25
+ * @param {string} hostUsername The username of the host running wp-env.
26
+ * @param {string} wordpressDefault The default internal path for the WordPress
27
+ * source code (such as tests-wordpress).
26
28
  *
27
29
  * @return {string[]} An array of volumes to mount in string format.
28
30
  */
29
31
  function getMounts(
30
32
  workDirectoryPath,
31
33
  config,
34
+ hostUsername,
32
35
  wordpressDefault = 'wordpress'
33
36
  ) {
34
37
  // Top-level WordPress directory mounts (like wp-content/themes)
@@ -46,9 +49,10 @@ function getMounts(
46
49
  `${ source.path }:/var/www/html/wp-content/themes/${ source.basename }`
47
50
  );
48
51
 
49
- const coreMount = `${
50
- config.coreSource ? config.coreSource.path : wordpressDefault
51
- }:/var/www/html`;
52
+ const userHomeMount =
53
+ wordpressDefault === 'wordpress'
54
+ ? `user-home:/home/${ hostUsername }`
55
+ : `tests-user-home:/home/${ hostUsername }`;
52
56
 
53
57
  const corePHPUnitMount = `${ path.join(
54
58
  workDirectoryPath,
@@ -59,10 +63,15 @@ function getMounts(
59
63
  'phpunit'
60
64
  ) }:/wordpress-phpunit`;
61
65
 
66
+ const coreMount = `${
67
+ config.coreSource ? config.coreSource.path : wordpressDefault
68
+ }:/var/www/html`;
69
+
62
70
  return [
63
71
  ...new Set( [
64
- coreMount,
72
+ coreMount, // Must be first because of some operations later that expect it to be!
65
73
  corePHPUnitMount,
74
+ userHomeMount,
66
75
  ...directoryMounts,
67
76
  ...pluginMounts,
68
77
  ...themeMounts,
@@ -79,16 +88,32 @@ function getMounts(
79
88
  * @return {Object} A docker-compose config object, ready to serialize into YAML.
80
89
  */
81
90
  module.exports = function buildDockerComposeConfig( config ) {
91
+ // Since we are mounting files from the host operating system
92
+ // we want to create the host user in some of our containers.
93
+ // This ensures ownership parity and lets us access files
94
+ // and folders between the containers and the host.
95
+ const hostUser = getHostUser();
96
+
82
97
  const developmentMounts = getMounts(
83
98
  config.workDirectoryPath,
84
- config.env.development
99
+ config.env.development,
100
+ hostUser.name
85
101
  );
86
102
  const testsMounts = getMounts(
87
103
  config.workDirectoryPath,
88
104
  config.env.tests,
105
+ hostUser.name,
89
106
  'tests-wordpress'
90
107
  );
91
108
 
109
+ // We use a custom Dockerfile in order to make sure that
110
+ // the current host user exists inside the container.
111
+ const imageBuildArgs = {
112
+ HOST_USERNAME: hostUser.name,
113
+ HOST_UID: hostUser.uid,
114
+ HOST_GID: hostUser.gid,
115
+ };
116
+
92
117
  // When both tests and development reference the same WP source, we need to
93
118
  // ensure that tests pulls from a copy of the files so that it maintains
94
119
  // a separate DB and config. Additionally, if the source type is local we
@@ -143,64 +168,6 @@ module.exports = function buildDockerComposeConfig( config ) {
143
168
  const developmentPorts = `\${WP_ENV_PORT:-${ config.env.development.port }}:80`;
144
169
  const testsPorts = `\${WP_ENV_TESTS_PORT:-${ config.env.tests.port }}:80`;
145
170
 
146
- // Set the WordPress, WP-CLI, PHPUnit PHP version if defined.
147
- const developmentPhpVersion = config.env.development.phpVersion
148
- ? config.env.development.phpVersion
149
- : '';
150
- const testsPhpVersion = config.env.tests.phpVersion
151
- ? config.env.tests.phpVersion
152
- : '';
153
-
154
- // Set the WordPress images with the PHP version tag.
155
- const developmentWpImage = `wordpress${
156
- developmentPhpVersion ? ':php' + developmentPhpVersion : ''
157
- }`;
158
- const testsWpImage = `wordpress${
159
- testsPhpVersion ? ':php' + testsPhpVersion : ''
160
- }`;
161
- // Set the WordPress CLI images with the PHP version tag.
162
- const developmentWpCliImage = `wordpress:cli${
163
- ! developmentPhpVersion || developmentPhpVersion.length === 0
164
- ? ''
165
- : '-php' + developmentPhpVersion
166
- }`;
167
- const testsWpCliImage = `wordpress:cli${
168
- ! testsPhpVersion || testsPhpVersion.length === 0
169
- ? ''
170
- : '-php' + testsPhpVersion
171
- }`;
172
-
173
- // Defaults are to use the most recent version of PHPUnit that provides
174
- // support for the specified version of PHP.
175
- // PHP Unit is assumed to be for Tests so use the testsPhpVersion.
176
- let phpunitTag = 'latest';
177
- const phpunitPhpVersion = '-php-' + testsPhpVersion + '-fpm';
178
- if ( testsPhpVersion === '5.6' ) {
179
- phpunitTag = '5' + phpunitPhpVersion;
180
- } else if ( testsPhpVersion === '7.0' ) {
181
- phpunitTag = '6' + phpunitPhpVersion;
182
- } else if ( testsPhpVersion === '7.1' ) {
183
- phpunitTag = '7' + phpunitPhpVersion;
184
- } else if ( testsPhpVersion === '7.2' ) {
185
- phpunitTag = '8' + phpunitPhpVersion;
186
- } else if (
187
- [ '7.3', '7.4', '8.0', '8.1', '8.2' ].indexOf( testsPhpVersion ) >= 0
188
- ) {
189
- phpunitTag = '9' + phpunitPhpVersion;
190
- }
191
- const phpunitImage = `wordpressdevelop/phpunit:${ phpunitTag }`;
192
-
193
- // The www-data user in wordpress:cli has a different UID (82) to the
194
- // www-data user in wordpress (33). Ensure we use the wordpress www-data
195
- // user for CLI commands.
196
- // https://github.com/docker-library/wordpress/issues/256
197
- const cliUser = '33:33';
198
-
199
- // If the user mounted their own uploads folder, we should not override it in the phpunit service.
200
- const isMappingTestUploads = testsMounts.some( ( mount ) =>
201
- mount.endsWith( ':/var/www/html/wp-content/uploads' )
202
- );
203
-
204
171
  return {
205
172
  version: '3.7',
206
173
  services: {
@@ -227,69 +194,72 @@ module.exports = function buildDockerComposeConfig( config ) {
227
194
  volumes: [ 'mysql-test:/var/lib/mysql' ],
228
195
  },
229
196
  wordpress: {
230
- build: '.',
231
197
  depends_on: [ 'mysql' ],
232
- image: developmentWpImage,
198
+ build: {
199
+ context: '.',
200
+ dockerfile: 'WordPress.Dockerfile',
201
+ args: imageBuildArgs,
202
+ },
233
203
  ports: [ developmentPorts ],
234
204
  environment: {
205
+ APACHE_RUN_USER: '#' + hostUser.uid,
206
+ APACHE_RUN_GROUP: '#' + hostUser.gid,
235
207
  ...dbEnv.credentials,
236
208
  ...dbEnv.development,
237
209
  WP_TESTS_DIR: '/wordpress-phpunit',
238
210
  },
239
211
  volumes: developmentMounts,
212
+ extra_hosts: [ 'host.docker.internal:host-gateway' ],
240
213
  },
241
214
  'tests-wordpress': {
242
215
  depends_on: [ 'tests-mysql' ],
243
- image: testsWpImage,
216
+ build: {
217
+ context: '.',
218
+ dockerfile: 'Tests-WordPress.Dockerfile',
219
+ args: imageBuildArgs,
220
+ },
244
221
  ports: [ testsPorts ],
245
222
  environment: {
223
+ APACHE_RUN_USER: '#' + hostUser.uid,
224
+ APACHE_RUN_GROUP: '#' + hostUser.gid,
246
225
  ...dbEnv.credentials,
247
226
  ...dbEnv.tests,
248
227
  WP_TESTS_DIR: '/wordpress-phpunit',
249
228
  },
250
229
  volumes: testsMounts,
230
+ extra_hosts: [ 'host.docker.internal:host-gateway' ],
251
231
  },
252
232
  cli: {
253
233
  depends_on: [ 'wordpress' ],
254
- image: developmentWpCliImage,
234
+ build: {
235
+ context: '.',
236
+ dockerfile: 'CLI.Dockerfile',
237
+ args: imageBuildArgs,
238
+ },
255
239
  volumes: developmentMounts,
256
- user: cliUser,
240
+ user: hostUser.fullUser,
257
241
  environment: {
258
242
  ...dbEnv.credentials,
259
243
  ...dbEnv.development,
260
244
  WP_TESTS_DIR: '/wordpress-phpunit',
261
245
  },
246
+ extra_hosts: [ 'host.docker.internal:host-gateway' ],
262
247
  },
263
248
  'tests-cli': {
264
249
  depends_on: [ 'tests-wordpress' ],
265
- image: testsWpCliImage,
250
+ build: {
251
+ context: '.',
252
+ dockerfile: 'Tests-CLI.Dockerfile',
253
+ args: imageBuildArgs,
254
+ },
266
255
  volumes: testsMounts,
267
- user: cliUser,
256
+ user: hostUser.fullUser,
268
257
  environment: {
269
258
  ...dbEnv.credentials,
270
259
  ...dbEnv.tests,
271
260
  WP_TESTS_DIR: '/wordpress-phpunit',
272
261
  },
273
- },
274
- composer: {
275
- image: 'composer',
276
- volumes: [ `${ config.configDirectoryPath }:/app` ],
277
- },
278
- phpunit: {
279
- image: phpunitImage,
280
- depends_on: [ 'tests-wordpress' ],
281
- volumes: [
282
- ...testsMounts,
283
- ...( ! isMappingTestUploads
284
- ? [ 'phpunit-uploads:/var/www/html/wp-content/uploads' ]
285
- : [] ),
286
- ],
287
- environment: {
288
- LOCAL_DIR: 'html',
289
- WP_TESTS_DIR: '/wordpress-phpunit',
290
- ...dbEnv.credentials,
291
- ...dbEnv.tests,
292
- },
262
+ extra_hosts: [ 'host.docker.internal:host-gateway' ],
293
263
  },
294
264
  },
295
265
  volumes: {
@@ -297,7 +267,8 @@ module.exports = function buildDockerComposeConfig( config ) {
297
267
  ...( ! config.env.tests.coreSource && { 'tests-wordpress': {} } ),
298
268
  mysql: {},
299
269
  'mysql-test': {},
300
- 'phpunit-uploads': {},
270
+ 'user-home': {},
271
+ 'tests-user-home': {},
301
272
  },
302
273
  };
303
274
  };
package/lib/cache.js CHANGED
@@ -1,3 +1,4 @@
1
+ 'use strict';
1
2
  /**
2
3
  * External dependencies
3
4
  */