Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add .wp-env.json support to wp-env #20002

Merged
merged 4 commits into from
Feb 7, 2020
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .wp-env.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"core": "WordPress/WordPress",
"plugins": [ "." ]
}
1 change: 1 addition & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 9 additions & 0 deletions packages/env/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,14 @@
## Master

### Breaking Changes

- `wp-env start` no longer accepts a WordPress branch or tag reference as its argument. Instead, create a `.wp-env.json` file and specify a `"core"` field.
noahtallen marked this conversation as resolved.
Show resolved Hide resolved
- `wp-env start` will now download WordPress into a hidden directory located in `~/.wp-env`. You may delete your `{projectName}-wordpress` and `{projectName}-tests-wordpress` directories.

### New Feature

- A `.wp-env.json` configuration file can now be used to specify the WordPress installation, plugins, and themes to use in the local development environment.

## 0.4.0 (2020-02-04)

### Bug Fixes
Expand Down
86 changes: 71 additions & 15 deletions packages/env/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -138,13 +138,13 @@ $ wp-env start
### `wp-env start [ref]`

```sh
wp-env start [ref]
wp-env start

Starts WordPress for development on port 8888 (​http://localhost:8888​)
(override with WP_ENV_PORT) and tests on port 8889 (​http://localhost:8889​)
(override with WP_ENV_TESTS_PORT). If the current working directory is a plugin
and/or has e2e-tests with plugins and/or mu-plugins, they will be mounted
appropriately.
(override with WP_ENV_TESTS_PORT). The current working directory must be a
WordPress installation, a plugin, a theme, or contain a .wp-env.json file.


Positionals:
ref A `https://github.com/WordPress/WordPress` git repo branch or commit for
Expand All @@ -171,28 +171,84 @@ Positionals:
[string] [choices: "all", "development", "tests"] [default: "tests"]
```

## Running with multiple plugins and/or themes
## .wp-env.json

You can customize the WordPress installation, plugins and themes that the development environment will use by specifying a `.wp-env.json` file in the directory that you run `wp-env` from.

`.wp-env.json` supports three fields:

| Field | Type | Default | Description |
| -- | -- | -- | -- |
| `"core"` | `string|null` | `null` | The WordPress installation to use. If `null` is specified, `wp-env` will use the latest production release of WordPress. |
| `"plugins"` | `string[]` | `[]` | A list of plugins to install and activate in the environment. |
| `"themes"` | `string[]` | `[]` | A list of themes to install in the environment. The first theme in the list will be activated. |

Several types of strings can be passed into these fields:

`wp-env` also supports a configuration file. At the moment, this is only used for loading extra themes and plugins that you may be developing together with your main one. The script will attach the specified theme and plugin directories as volumes on the docker containers so that changes you make to them exist in the WordPress instance.
| Type | Format | Example(s) |
| -- | -- | -- |
| Relative path | `.<path>|~<path>` | `"./a/directory"`, `"../a/directory"`, `"~/a/directory"` |
| Absolute path | `/<path>|<letter>:\<path>` | `"/a/directory"`, `"C:\\a\\directory"` |
| GitHub repository | `<owner>/<repo>[#<ref>]` | `"WordPress/WordPress"`, `"WordPress/gutenberg#master"` |

### Example:
Remote sources will be downloaded into a temporary directory located in `~/.wp-env`.

### Examples

#### Latest production WordPress + current directory as a plugin

This is useful for plugin development.

`wp-env.json`
```json
{
"themes": [
"../path/to/theme/dir"
],
"core": null,
"plugins": [
"."
]
}
```

#### Latest development WordPress + current directory as a plugin

This is useful for plugin development when upstream Core changes need to be tested.

```json
{
"core": "WordPress/WordPress#master",
"plugins": [
"."
]
}
```

#### Local `wordpress-develop` + current directory as a plugin

This is useful for working on plugins and WordPress Core at the same time.

```json
{
"core": "../wordpress-develop/build",
"plugins": [
"../path/to/plugin/dir"
"."
]
}
```

### Caveats:
#### A complete testing environment

The file should be located in the same directory from which you run `wp-env` commands for a project. So if you are running `wp-env` in the root directory of a plugin, `wp-env.json` should also be located there.
This is useful for integration testing: that is, testing how old versions of WordPress and different combinations of plugins and themes impact each other.

Each item in the `themes` or `plugins` array should be an absolute or relative path to the root of a different theme or plugin directory. Relative paths will be resolved from the current working directory, which means they will be resolved from the location of the `wp-env.json` file.
```json
{
"core": "WordPress/WordPress#5.2.0",
"plugins": [
"WordPress/wp-lazy-loading",
"WordPress/classic-editor",
],
"themes": [
"WordPress/theme-experiments"
]
}
```

<br/><br/><p align="center"><img src="https://s.w.org/style/images/codeispoetry.png?1" alt="Code is Poetry." /></p>
101 changes: 101 additions & 0 deletions packages/env/lib/build-docker-compose-config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
'use strict';
/**
* External dependencies
*/
const fs = require( 'fs' );
const path = require( 'path' );

/**
* @typedef {import('./config').Config} Config
*/

/**
* Creates a docker-compose config object which, when serialized into a
* docker-compose.yml file, tells docker-compose how to run the environment.
*
* @param {Config} config A wp-env config object.
noisysocks marked this conversation as resolved.
Show resolved Hide resolved
* @return {Object} A docker-compose config object, ready to serialize into YAML.
*/
module.exports = function buildDockerComposeConfig( config ) {
noisysocks marked this conversation as resolved.
Show resolved Hide resolved
const pluginMounts = config.pluginSources.flatMap( ( source ) => [
`${ source.path }:/var/www/html/wp-content/plugins/${ source.basename }`,

// If this is is the Gutenberg plugin, then mount its E2E test plugins.
// TODO: Implement an API that lets Gutenberg mount test plugins without this workaround.
...( fs.existsSync( path.resolve( source.path, 'gutenberg.php' ) ) && [
`${ source.path }/packages/e2e-tests/plugins:/var/www/html/wp-content/plugins/gutenberg-test-plugins`,
`${ source.path }/packages/e2e-tests/mu-plugins:/var/www/html/wp-content/mu-plugins`,
noahtallen marked this conversation as resolved.
Show resolved Hide resolved
] ),
] );

const themeMounts = config.themeSources.map(
( source ) =>
`${ source.path }:/var/www/html/wp-content/themes/${ source.basename }`
);

const developmentMounts = [
`${
config.coreSource ? config.coreSource.path : 'wordpress'
}:/var/www/html`,
...pluginMounts,
...themeMounts,
];

const testsMounts = [
`${
config.coreSource ? config.coreSource.testsPath : 'tests-wordpress'
}:/var/www/html`,
...pluginMounts,
...themeMounts,
];

return {
version: '3.7',
services: {
mysql: {
image: 'mariadb',
environment: {
MYSQL_ALLOW_EMPTY_PASSWORD: 'yes',
},
},
wordpress: {
depends_on: [ 'mysql' ],
image: 'wordpress',
ports: [ '${WP_ENV_PORT:-8888}:80' ],
environment: {
WORDPRESS_DEBUG: '1',
WORDPRESS_DB_NAME: 'wordpress',
},
volumes: developmentMounts,
},
'tests-wordpress': {
depends_on: [ 'mysql' ],
image: 'wordpress',
ports: [ '${WP_ENV_TESTS_PORT:-8889}:80' ],
environment: {
WORDPRESS_DEBUG: '1',
WORDPRESS_DB_NAME: 'tests-wordpress',
},
volumes: testsMounts,
},
cli: {
depends_on: [ 'wordpress' ],
image: 'wordpress:cli',
volumes: developmentMounts,
},
'tests-cli': {
depends_on: [ 'wordpress' ],
image: 'wordpress:cli',
volumes: testsMounts,
},
composer: {
image: 'composer',
volumes: [ `${ config.configDirectoryPath }:/app` ],
},
},
volumes: {
...( ! config.coreSource && { wordpress: {} } ),
...( ! config.coreSource && { 'tests-wordpress': {} } ),
},
};
};
25 changes: 10 additions & 15 deletions packages/env/lib/cli.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,13 @@ const withSpinner = ( command ) => ( ...args ) => {
).toFixed( 0 ) }ms)`
);
},
( err ) => {
spinner.fail( err.message || err.err );
// eslint-disable-next-line no-console
console.error( `\n\n${ err.out || err.err }\n\n` );
process.exit( err.exitCode || 1 );
( error ) => {
spinner.fail( error.message || error.err );
if ( ! ( error instanceof env.ValidationError ) ) {
// eslint-disable-next-line no-console
console.error( '\n\n', error, '\n\n' );
}
process.exit( error.exitCode || 1 );
}
);
};
Expand All @@ -46,24 +48,17 @@ module.exports = function cli() {
yargs.usage( wpPrimary( '$0 <command>' ) );

yargs.command(
'start [ref]',
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This needs a dev note, right?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I noted that this breaks backwards compatibility in packages/env/CHANGELOG.md but a agree dev note would be good, too. If nothing else it will help publicise that this tool can be used for core development.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

'start',
wpGreen(
chalk`Starts WordPress for development on port {bold.underline ${ terminalLink(
'8888',
'http://localhost:8888'
) }} (override with WP_ENV_PORT) and tests on port {bold.underline ${ terminalLink(
'8889',
'http://localhost:8889'
) }} (override with WP_ENV_TESTS_PORT). If the current working directory is a plugin and/or has e2e-tests with plugins and/or mu-plugins, they will be mounted appropriately.`
) }} (override with WP_ENV_TESTS_PORT). The current working directory must be a WordPress installation, a plugin, a theme, or contain a .wp-env.json file.`
),
( args ) => {
args.positional( 'ref', {
type: 'string',
describe:
'A `https://github.com/WordPress/WordPress` git repo branch or commit for choosing a specific version.',
default: 'master',
} );
},
() => {},
withSpinner( env.start )
);
yargs.command(
Expand Down
Loading