@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.
- package/README.md +130 -66
- package/lib/build-docker-compose-config.js +67 -96
- package/lib/cache.js +1 -0
- package/lib/cli.js +39 -10
- package/lib/commands/clean.js +13 -1
- package/lib/commands/destroy.js +21 -42
- package/lib/commands/index.js +1 -0
- package/lib/commands/install-path.js +1 -0
- package/lib/commands/logs.js +1 -0
- package/lib/commands/run.js +45 -21
- package/lib/commands/start.js +29 -8
- package/lib/commands/stop.js +1 -0
- package/lib/config/add-or-replace-port.js +12 -3
- package/lib/config/db-env.js +1 -0
- package/lib/config/detect-directory-type.js +1 -1
- package/lib/config/get-cache-directory.js +39 -0
- package/lib/config/get-config-from-environment-vars.js +106 -0
- package/lib/config/index.js +7 -5
- package/lib/config/load-config.js +92 -0
- package/lib/config/merge-configs.js +105 -0
- package/lib/config/parse-config.js +501 -157
- package/lib/config/parse-source-string.js +164 -0
- package/lib/config/post-process-config.js +202 -0
- package/lib/config/read-raw-config-file.js +7 -33
- package/lib/config/test/__snapshots__/config-integration.js.snap +295 -0
- package/lib/config/test/add-or-replace-port.js +29 -1
- package/lib/config/test/config-integration.js +164 -0
- package/lib/config/test/get-cache-directory.js +57 -0
- package/lib/config/test/merge-configs.js +121 -0
- package/lib/config/test/parse-config.js +393 -0
- package/lib/config/test/parse-source-string.js +154 -0
- package/lib/config/test/post-process-config.js +299 -0
- package/lib/config/test/read-raw-config-file.js +19 -63
- package/lib/config/test/validate-config.js +363 -0
- package/lib/config/validate-config.js +119 -54
- package/lib/env.js +2 -0
- package/lib/execute-lifecycle-script.js +86 -0
- package/lib/get-host-user.js +27 -0
- package/lib/init-config.js +186 -63
- package/lib/md5.js +1 -0
- package/lib/parse-xdebug-mode.js +1 -0
- package/lib/retry.js +1 -0
- package/lib/test/__snapshots__/md5.js.snap +9 -0
- package/lib/test/build-docker-compose-config.js +134 -0
- package/lib/test/cache.js +154 -0
- package/lib/test/cli.js +149 -0
- package/lib/test/execute-lifecycle-script.js +59 -0
- package/lib/test/md5.js +35 -0
- package/lib/test/parse-xdebug-mode.js +41 -0
- package/lib/validate-run-container.js +41 -0
- package/lib/wordpress.js +4 -19
- package/package.json +2 -2
- package/lib/config/config.js +0 -353
- package/lib/config/test/__snapshots__/config.js.snap +0 -83
- package/lib/config/test/config.js +0 -1241
package/lib/cli.js
CHANGED
|
@@ -13,6 +13,10 @@ const { execSync } = require( 'child_process' );
|
|
|
13
13
|
*/
|
|
14
14
|
const env = require( './env' );
|
|
15
15
|
const parseXdebugMode = require( './parse-xdebug-mode' );
|
|
16
|
+
const {
|
|
17
|
+
RUN_CONTAINERS,
|
|
18
|
+
validateRunContainer,
|
|
19
|
+
} = require( './validate-run-container' );
|
|
16
20
|
|
|
17
21
|
// Colors.
|
|
18
22
|
const boldWhite = chalk.bold.white;
|
|
@@ -39,8 +43,11 @@ const withSpinner =
|
|
|
39
43
|
process.exit( 0 );
|
|
40
44
|
},
|
|
41
45
|
( error ) => {
|
|
42
|
-
if (
|
|
43
|
-
|
|
46
|
+
if (
|
|
47
|
+
error instanceof env.ValidationError ||
|
|
48
|
+
error instanceof env.LifecycleScriptError
|
|
49
|
+
) {
|
|
50
|
+
// Error is a configuration error. That means the user did something wrong.
|
|
44
51
|
spinner.fail( error.message );
|
|
45
52
|
process.exit( 1 );
|
|
46
53
|
} else if (
|
|
@@ -96,9 +103,12 @@ module.exports = function cli() {
|
|
|
96
103
|
default: false,
|
|
97
104
|
} );
|
|
98
105
|
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
106
|
+
yargs.parserConfiguration( {
|
|
107
|
+
// Treats unknown options as arguments for commands to deal with instead of discarding them.
|
|
108
|
+
'unknown-options-as-args': true,
|
|
109
|
+
// Populates '--' in the command options with arguments after the double dash.
|
|
110
|
+
'populate--': true,
|
|
111
|
+
} );
|
|
102
112
|
|
|
103
113
|
yargs.command(
|
|
104
114
|
'start',
|
|
@@ -124,6 +134,11 @@ module.exports = function cli() {
|
|
|
124
134
|
coerce: parseXdebugMode,
|
|
125
135
|
type: 'string',
|
|
126
136
|
} );
|
|
137
|
+
args.option( 'scripts', {
|
|
138
|
+
type: 'boolean',
|
|
139
|
+
describe: 'Execute any configured lifecycle scripts.',
|
|
140
|
+
default: true,
|
|
141
|
+
} );
|
|
127
142
|
},
|
|
128
143
|
withSpinner( env.start )
|
|
129
144
|
);
|
|
@@ -145,6 +160,11 @@ module.exports = function cli() {
|
|
|
145
160
|
choices: [ 'all', 'development', 'tests' ],
|
|
146
161
|
default: 'tests',
|
|
147
162
|
} );
|
|
163
|
+
args.option( 'scripts', {
|
|
164
|
+
type: 'boolean',
|
|
165
|
+
describe: 'Execute any configured lifecycle scripts.',
|
|
166
|
+
default: true,
|
|
167
|
+
} );
|
|
148
168
|
},
|
|
149
169
|
withSpinner( env.clean )
|
|
150
170
|
);
|
|
@@ -171,8 +191,8 @@ module.exports = function cli() {
|
|
|
171
191
|
'Displays the latest logs for the e2e test environment without watching.'
|
|
172
192
|
);
|
|
173
193
|
yargs.command(
|
|
174
|
-
'run <container> [command
|
|
175
|
-
'Runs an arbitrary command in one of the underlying Docker containers.
|
|
194
|
+
'run <container> [command...]',
|
|
195
|
+
'Runs an arbitrary command in one of the underlying Docker containers. A double dash can be used to pass arguments to the container without parsing them. This is necessary if you are using an option that is defined below. You can use `bash` to open a shell session and both `composer` and `phpunit` are available in all WordPress and CLI containers. WP-CLI is also available in the CLI containers.',
|
|
176
196
|
( args ) => {
|
|
177
197
|
args.option( 'env-cwd', {
|
|
178
198
|
type: 'string',
|
|
@@ -183,7 +203,10 @@ module.exports = function cli() {
|
|
|
183
203
|
} );
|
|
184
204
|
args.positional( 'container', {
|
|
185
205
|
type: 'string',
|
|
186
|
-
describe:
|
|
206
|
+
describe:
|
|
207
|
+
'The underlying Docker service to run the command on.',
|
|
208
|
+
choices: RUN_CONTAINERS,
|
|
209
|
+
coerce: validateRunContainer,
|
|
187
210
|
} );
|
|
188
211
|
args.positional( 'command', {
|
|
189
212
|
type: 'array',
|
|
@@ -210,12 +233,18 @@ module.exports = function cli() {
|
|
|
210
233
|
wpRed(
|
|
211
234
|
'Destroy the WordPress environment. Deletes docker containers, volumes, and networks associated with the WordPress environment and removes local files.'
|
|
212
235
|
),
|
|
213
|
-
() => {
|
|
236
|
+
( args ) => {
|
|
237
|
+
args.option( 'scripts', {
|
|
238
|
+
type: 'boolean',
|
|
239
|
+
describe: 'Execute any configured lifecycle scripts.',
|
|
240
|
+
default: true,
|
|
241
|
+
} );
|
|
242
|
+
},
|
|
214
243
|
withSpinner( env.destroy )
|
|
215
244
|
);
|
|
216
245
|
yargs.command(
|
|
217
246
|
'install-path',
|
|
218
|
-
'Get the path where environment files are
|
|
247
|
+
'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.',
|
|
219
248
|
() => {},
|
|
220
249
|
withSpinner( env.installPath )
|
|
221
250
|
);
|
package/lib/commands/clean.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
'use strict';
|
|
1
2
|
/**
|
|
2
3
|
* External dependencies
|
|
3
4
|
*/
|
|
@@ -8,6 +9,7 @@ const dockerCompose = require( 'docker-compose' );
|
|
|
8
9
|
*/
|
|
9
10
|
const initConfig = require( '../init-config' );
|
|
10
11
|
const { configureWordPress, resetDatabase } = require( '../wordpress' );
|
|
12
|
+
const { executeLifecycleScript } = require( '../execute-lifecycle-script' );
|
|
11
13
|
|
|
12
14
|
/**
|
|
13
15
|
* @typedef {import('../wordpress').WPEnvironment} WPEnvironment
|
|
@@ -20,9 +22,15 @@ const { configureWordPress, resetDatabase } = require( '../wordpress' );
|
|
|
20
22
|
* @param {Object} options
|
|
21
23
|
* @param {WPEnvironmentSelection} options.environment The environment to clean. Either 'development', 'tests', or 'all'.
|
|
22
24
|
* @param {Object} options.spinner A CLI spinner which indicates progress.
|
|
25
|
+
* @param {boolean} options.scripts Indicates whether or not lifecycle scripts should be executed.
|
|
23
26
|
* @param {boolean} options.debug True if debug mode is enabled.
|
|
24
27
|
*/
|
|
25
|
-
module.exports = async function clean( {
|
|
28
|
+
module.exports = async function clean( {
|
|
29
|
+
environment,
|
|
30
|
+
spinner,
|
|
31
|
+
scripts,
|
|
32
|
+
debug,
|
|
33
|
+
} ) {
|
|
26
34
|
const config = await initConfig( { spinner, debug } );
|
|
27
35
|
|
|
28
36
|
const description = `${ environment } environment${
|
|
@@ -57,5 +65,9 @@ module.exports = async function clean( { environment, spinner, debug } ) {
|
|
|
57
65
|
|
|
58
66
|
await Promise.all( tasks );
|
|
59
67
|
|
|
68
|
+
if ( scripts ) {
|
|
69
|
+
await executeLifecycleScript( 'afterClean', config, spinner );
|
|
70
|
+
}
|
|
71
|
+
|
|
60
72
|
spinner.text = `Cleaned ${ description }.`;
|
|
61
73
|
};
|
package/lib/commands/destroy.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
'use strict';
|
|
1
2
|
/**
|
|
2
3
|
* External dependencies
|
|
3
4
|
*/
|
|
@@ -11,35 +12,33 @@ const inquirer = require( 'inquirer' );
|
|
|
11
12
|
* Promisified dependencies
|
|
12
13
|
*/
|
|
13
14
|
const rimraf = util.promisify( require( 'rimraf' ) );
|
|
14
|
-
const exec = util.promisify( require( 'child_process' ).exec );
|
|
15
15
|
|
|
16
16
|
/**
|
|
17
17
|
* Internal dependencies
|
|
18
18
|
*/
|
|
19
|
-
const {
|
|
19
|
+
const { loadConfig } = require( '../config' );
|
|
20
|
+
const { executeLifecycleScript } = require( '../execute-lifecycle-script' );
|
|
20
21
|
|
|
21
22
|
/**
|
|
22
23
|
* Destroy the development server.
|
|
23
24
|
*
|
|
24
25
|
* @param {Object} options
|
|
25
26
|
* @param {Object} options.spinner A CLI spinner which indicates progress.
|
|
27
|
+
* @param {boolean} options.scripts Indicates whether or not lifecycle scripts should be executed.
|
|
26
28
|
* @param {boolean} options.debug True if debug mode is enabled.
|
|
27
29
|
*/
|
|
28
|
-
module.exports = async function destroy( { spinner, debug } ) {
|
|
29
|
-
const
|
|
30
|
-
const { dockerComposeConfigPath, workDirectoryPath } = await readConfig(
|
|
31
|
-
configPath
|
|
32
|
-
);
|
|
30
|
+
module.exports = async function destroy( { spinner, scripts, debug } ) {
|
|
31
|
+
const config = await loadConfig( path.resolve( '.' ) );
|
|
33
32
|
|
|
34
33
|
try {
|
|
35
|
-
await fs.readdir( workDirectoryPath );
|
|
34
|
+
await fs.readdir( config.workDirectoryPath );
|
|
36
35
|
} catch {
|
|
37
36
|
spinner.text = 'Could not find any files to remove.';
|
|
38
37
|
return;
|
|
39
38
|
}
|
|
40
39
|
|
|
41
40
|
spinner.info(
|
|
42
|
-
'WARNING! This will remove Docker containers, volumes, and
|
|
41
|
+
'WARNING! This will remove Docker containers, volumes, networks, and images associated with the WordPress instance.'
|
|
43
42
|
);
|
|
44
43
|
|
|
45
44
|
const { yesDelete } = await inquirer.prompt( [
|
|
@@ -58,44 +57,24 @@ module.exports = async function destroy( { spinner, debug } ) {
|
|
|
58
57
|
return;
|
|
59
58
|
}
|
|
60
59
|
|
|
61
|
-
spinner.text = 'Removing
|
|
60
|
+
spinner.text = 'Removing docker images, volumes, and networks.';
|
|
62
61
|
|
|
63
|
-
await dockerCompose.
|
|
64
|
-
config: dockerComposeConfigPath,
|
|
65
|
-
commandOptions: [ '--
|
|
62
|
+
await dockerCompose.down( {
|
|
63
|
+
config: config.dockerComposeConfigPath,
|
|
64
|
+
commandOptions: [ '--volumes', '--remove-orphans', '--rmi', 'all' ],
|
|
66
65
|
log: debug,
|
|
67
66
|
} );
|
|
68
67
|
|
|
69
|
-
const directoryHash = path.basename( workDirectoryPath );
|
|
70
|
-
|
|
71
|
-
spinner.text = 'Removing docker volumes.';
|
|
72
|
-
await removeDockerItems( 'volume', directoryHash );
|
|
73
|
-
|
|
74
|
-
spinner.text = 'Removing docker networks.';
|
|
75
|
-
await removeDockerItems( 'network', directoryHash );
|
|
76
|
-
|
|
77
68
|
spinner.text = 'Removing local files.';
|
|
78
|
-
|
|
79
|
-
|
|
69
|
+
// Note: there is a race condition where docker compose actually hasn't finished
|
|
70
|
+
// by this point, which causes rimraf to fail. We need to wait at least 2.5-5s,
|
|
71
|
+
// but using 10s in case it's dependant on the machine.
|
|
72
|
+
await new Promise( ( resolve ) => setTimeout( resolve, 10000 ) );
|
|
73
|
+
await rimraf( config.workDirectoryPath );
|
|
74
|
+
|
|
75
|
+
if ( scripts ) {
|
|
76
|
+
await executeLifecycleScript( 'afterDestroy', config, spinner );
|
|
77
|
+
}
|
|
80
78
|
|
|
81
79
|
spinner.text = 'Removed WordPress environment.';
|
|
82
80
|
};
|
|
83
|
-
|
|
84
|
-
/**
|
|
85
|
-
* Removes docker items, like networks or volumes, matching the given name.
|
|
86
|
-
*
|
|
87
|
-
* @param {string} itemType The item type, like "network" or "volume"
|
|
88
|
-
* @param {string} name Remove items whose name match this string.
|
|
89
|
-
*/
|
|
90
|
-
async function removeDockerItems( itemType, name ) {
|
|
91
|
-
const { stdout: items } = await exec(
|
|
92
|
-
`docker ${ itemType } ls -q --filter name=${ name }`
|
|
93
|
-
);
|
|
94
|
-
if ( items ) {
|
|
95
|
-
await exec(
|
|
96
|
-
`docker ${ itemType } rm ${ items
|
|
97
|
-
.split( '\n' ) // TODO: use os.EOL?
|
|
98
|
-
.join( ' ' ) }`
|
|
99
|
-
);
|
|
100
|
-
}
|
|
101
|
-
}
|
package/lib/commands/index.js
CHANGED
package/lib/commands/logs.js
CHANGED
package/lib/commands/run.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
'use strict';
|
|
1
2
|
/**
|
|
2
3
|
* External dependencies
|
|
3
4
|
*/
|
|
@@ -8,6 +9,7 @@ const path = require( 'path' );
|
|
|
8
9
|
* Internal dependencies
|
|
9
10
|
*/
|
|
10
11
|
const initConfig = require( '../init-config' );
|
|
12
|
+
const getHostUser = require( '../get-host-user' );
|
|
11
13
|
|
|
12
14
|
/**
|
|
13
15
|
* @typedef {import('../config').WPConfig} WPConfig
|
|
@@ -19,6 +21,7 @@ const initConfig = require( '../init-config' );
|
|
|
19
21
|
* @param {Object} options
|
|
20
22
|
* @param {string} options.container The Docker container to run the command on.
|
|
21
23
|
* @param {string[]} options.command The command to run.
|
|
24
|
+
* @param {string[]} options.'--' Any arguments that were passed after a double dash.
|
|
22
25
|
* @param {string} options.envCwd The working directory for the command to be executed from.
|
|
23
26
|
* @param {Object} options.spinner A CLI spinner which indicates progress.
|
|
24
27
|
* @param {boolean} options.debug True if debug mode is enabled.
|
|
@@ -26,20 +29,26 @@ const initConfig = require( '../init-config' );
|
|
|
26
29
|
module.exports = async function run( {
|
|
27
30
|
container,
|
|
28
31
|
command,
|
|
32
|
+
'--': doubleDashedArgs,
|
|
29
33
|
envCwd,
|
|
30
34
|
spinner,
|
|
31
35
|
debug,
|
|
32
36
|
} ) {
|
|
33
37
|
const config = await initConfig( { spinner, debug } );
|
|
34
38
|
|
|
35
|
-
|
|
39
|
+
// Include any double dashed arguments in the command so that we can pass them to Docker.
|
|
40
|
+
// This lets users pass options that the command defines without them being parsed.
|
|
41
|
+
if ( Array.isArray( doubleDashedArgs ) ) {
|
|
42
|
+
command.push( ...doubleDashedArgs );
|
|
43
|
+
}
|
|
36
44
|
|
|
37
45
|
// Shows a contextual tip for the given command.
|
|
38
|
-
|
|
46
|
+
const joinedCommand = command.join( ' ' );
|
|
47
|
+
showCommandTips( joinedCommand, container, spinner );
|
|
39
48
|
|
|
40
49
|
await spawnCommandDirectly( config, container, command, envCwd, spinner );
|
|
41
50
|
|
|
42
|
-
spinner.text = `Ran \`${
|
|
51
|
+
spinner.text = `Ran \`${ joinedCommand }\` in '${ container }'.`;
|
|
43
52
|
};
|
|
44
53
|
|
|
45
54
|
/**
|
|
@@ -47,25 +56,43 @@ module.exports = async function run( {
|
|
|
47
56
|
*
|
|
48
57
|
* @param {WPConfig} config The wp-env configuration.
|
|
49
58
|
* @param {string} container The Docker container to run the command on.
|
|
50
|
-
* @param {string}
|
|
59
|
+
* @param {string[]} command The command to run.
|
|
51
60
|
* @param {string} envCwd The working directory for the command to be executed from.
|
|
52
61
|
* @param {Object} spinner A CLI spinner which indicates progress.
|
|
53
62
|
*/
|
|
54
63
|
function spawnCommandDirectly( config, container, command, envCwd, spinner ) {
|
|
55
|
-
//
|
|
56
|
-
|
|
64
|
+
// Both the `wordpress` and `tests-wordpress` containers have the host's
|
|
65
|
+
// user so that they can maintain ownership parity with the host OS.
|
|
66
|
+
// We should run any commands as that user so that they are able
|
|
67
|
+
// to interact with the files mounted from the host.
|
|
68
|
+
const hostUser = getHostUser();
|
|
69
|
+
|
|
70
|
+
// Since Docker requires absolute paths, we should resolve the input to a POSIX path.
|
|
71
|
+
// This is needed because Windows resolves relative paths from the C: drive.
|
|
72
|
+
envCwd = path.posix.resolve(
|
|
73
|
+
// Not all containers have the same starting working directory.
|
|
74
|
+
container === 'mysql' || container === 'tests-mysql'
|
|
75
|
+
? '/'
|
|
76
|
+
: '/var/www/html',
|
|
77
|
+
envCwd
|
|
78
|
+
);
|
|
57
79
|
|
|
58
80
|
const composeCommand = [
|
|
59
81
|
'-f',
|
|
60
82
|
config.dockerComposeConfigPath,
|
|
61
|
-
'
|
|
83
|
+
'exec',
|
|
62
84
|
'-w',
|
|
63
85
|
envCwd,
|
|
64
|
-
'--
|
|
65
|
-
|
|
66
|
-
...command.split( ' ' ), // The command will fail if passed as a complete string.
|
|
86
|
+
'--user',
|
|
87
|
+
hostUser.fullUser,
|
|
67
88
|
];
|
|
68
89
|
|
|
90
|
+
if ( ! process.stdout.isTTY ) {
|
|
91
|
+
composeCommand.push( '-T' );
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
composeCommand.push( container, ...command );
|
|
95
|
+
|
|
69
96
|
return new Promise( ( resolve, reject ) => {
|
|
70
97
|
// Note: since the npm docker-compose package uses the -T option, we
|
|
71
98
|
// cannot use it to spawn an interactive command. Thus, we run docker-
|
|
@@ -73,10 +100,7 @@ function spawnCommandDirectly( config, container, command, envCwd, spinner ) {
|
|
|
73
100
|
const childProc = spawn(
|
|
74
101
|
'docker-compose',
|
|
75
102
|
composeCommand,
|
|
76
|
-
{
|
|
77
|
-
stdio: 'inherit',
|
|
78
|
-
shell: true,
|
|
79
|
-
},
|
|
103
|
+
{ stdio: 'inherit' },
|
|
80
104
|
spinner
|
|
81
105
|
);
|
|
82
106
|
childProc.on( 'error', reject );
|
|
@@ -97,17 +121,17 @@ function spawnCommandDirectly( config, container, command, envCwd, spinner ) {
|
|
|
97
121
|
* bash) may have weird behavior (exit with ctrl-d instead of ctrl-c or ctrl-z),
|
|
98
122
|
* so we want the user to have that information without having to ask someone.
|
|
99
123
|
*
|
|
100
|
-
* @param {string}
|
|
101
|
-
* @param {string} container
|
|
102
|
-
* @param {Object} spinner
|
|
124
|
+
* @param {string} joinedCommand The command for which to show a tip joined by spaces.
|
|
125
|
+
* @param {string} container The container the command will be run on.
|
|
126
|
+
* @param {Object} spinner A spinner object to show progress.
|
|
103
127
|
*/
|
|
104
|
-
function showCommandTips(
|
|
105
|
-
if ( !
|
|
128
|
+
function showCommandTips( joinedCommand, container, spinner ) {
|
|
129
|
+
if ( ! joinedCommand.length ) {
|
|
106
130
|
return;
|
|
107
131
|
}
|
|
108
132
|
|
|
109
|
-
const tip = `Starting '${
|
|
110
|
-
switch (
|
|
133
|
+
const tip = `Starting '${ joinedCommand }' on the ${ container } container. ${ ( () => {
|
|
134
|
+
switch ( joinedCommand ) {
|
|
111
135
|
case 'bash':
|
|
112
136
|
return 'Exit bash with ctrl-d.';
|
|
113
137
|
case 'wp shell':
|
package/lib/commands/start.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
'use strict';
|
|
1
2
|
/**
|
|
2
3
|
* External dependencies
|
|
3
4
|
*/
|
|
@@ -30,6 +31,7 @@ const {
|
|
|
30
31
|
} = require( '../wordpress' );
|
|
31
32
|
const { didCacheChange, setCache } = require( '../cache' );
|
|
32
33
|
const md5 = require( '../md5' );
|
|
34
|
+
const { executeLifecycleScript } = require( '../execute-lifecycle-script' );
|
|
33
35
|
|
|
34
36
|
/**
|
|
35
37
|
* @typedef {import('../config').WPConfig} WPConfig
|
|
@@ -41,11 +43,18 @@ const CONFIG_CACHE_KEY = 'config_checksum';
|
|
|
41
43
|
*
|
|
42
44
|
* @param {Object} options
|
|
43
45
|
* @param {Object} options.spinner A CLI spinner which indicates progress.
|
|
44
|
-
* @param {boolean} options.debug True if debug mode is enabled.
|
|
45
46
|
* @param {boolean} options.update If true, update sources.
|
|
46
47
|
* @param {string} options.xdebug The Xdebug mode to set.
|
|
48
|
+
* @param {boolean} options.scripts Indicates whether or not lifecycle scripts should be executed.
|
|
49
|
+
* @param {boolean} options.debug True if debug mode is enabled.
|
|
47
50
|
*/
|
|
48
|
-
module.exports = async function start( {
|
|
51
|
+
module.exports = async function start( {
|
|
52
|
+
spinner,
|
|
53
|
+
update,
|
|
54
|
+
xdebug,
|
|
55
|
+
scripts,
|
|
56
|
+
debug,
|
|
57
|
+
} ) {
|
|
49
58
|
spinner.text = 'Reading configuration.';
|
|
50
59
|
await checkForLegacyInstall( spinner );
|
|
51
60
|
|
|
@@ -152,12 +161,20 @@ module.exports = async function start( { spinner, debug, update, xdebug } ) {
|
|
|
152
161
|
|
|
153
162
|
spinner.text = 'Starting WordPress.';
|
|
154
163
|
|
|
155
|
-
await dockerCompose.upMany(
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
:
|
|
160
|
-
|
|
164
|
+
await dockerCompose.upMany(
|
|
165
|
+
[ 'wordpress', 'tests-wordpress', 'cli', 'tests-cli' ],
|
|
166
|
+
{
|
|
167
|
+
...dockerComposeConfig,
|
|
168
|
+
commandOptions: shouldConfigureWp
|
|
169
|
+
? [ '--build', '--force-recreate' ]
|
|
170
|
+
: [],
|
|
171
|
+
}
|
|
172
|
+
);
|
|
173
|
+
|
|
174
|
+
// Make sure we've consumed the custom CLI dockerfile.
|
|
175
|
+
if ( shouldConfigureWp ) {
|
|
176
|
+
await dockerCompose.buildOne( [ 'cli' ], { ...dockerComposeConfig } );
|
|
177
|
+
}
|
|
161
178
|
|
|
162
179
|
// Only run WordPress install/configuration when config has changed.
|
|
163
180
|
if ( shouldConfigureWp ) {
|
|
@@ -192,6 +209,10 @@ module.exports = async function start( { spinner, debug, update, xdebug } ) {
|
|
|
192
209
|
} );
|
|
193
210
|
}
|
|
194
211
|
|
|
212
|
+
if ( scripts ) {
|
|
213
|
+
await executeLifecycleScript( 'afterStart', config, spinner );
|
|
214
|
+
}
|
|
215
|
+
|
|
195
216
|
const siteUrl = config.env.development.config.WP_SITEURL;
|
|
196
217
|
const testsSiteUrl = config.env.tests.config.WP_SITEURL;
|
|
197
218
|
|
package/lib/commands/stop.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
'use strict';
|
|
1
2
|
/**
|
|
2
3
|
* Internal dependencies
|
|
3
4
|
*/
|
|
@@ -6,9 +7,10 @@ const { ValidationError } = require( './validate-config' );
|
|
|
6
7
|
/**
|
|
7
8
|
* Adds or replaces the port to the given domain or URI.
|
|
8
9
|
*
|
|
9
|
-
* @param {string}
|
|
10
|
-
* @param {string}
|
|
11
|
-
* @param {boolean}
|
|
10
|
+
* @param {string} input The domain or URI to operate on.
|
|
11
|
+
* @param {number|string} port The port to append.
|
|
12
|
+
* @param {boolean} [replace] Indicates whether or not the port should be replaced if one is already present. Defaults to true.
|
|
13
|
+
*
|
|
12
14
|
* @return {string} The string with the port added or replaced.
|
|
13
15
|
*/
|
|
14
16
|
module.exports = function addOrReplacePort( input, port, replace = true ) {
|
|
@@ -27,6 +29,13 @@ module.exports = function addOrReplacePort( input, port, replace = true ) {
|
|
|
27
29
|
return input;
|
|
28
30
|
}
|
|
29
31
|
|
|
32
|
+
// There's never a reason to add the default ports.
|
|
33
|
+
// We use == to catch both string and number ports.
|
|
34
|
+
// eslint-disable-next-line eqeqeq
|
|
35
|
+
if ( port == 80 || port == 443 ) {
|
|
36
|
+
return input;
|
|
37
|
+
}
|
|
38
|
+
|
|
30
39
|
// Place the port in the correct location in the input.
|
|
31
40
|
return matches[ 1 ] + ':' + port + matches[ 3 ];
|
|
32
41
|
};
|
package/lib/config/db-env.js
CHANGED
|
@@ -18,7 +18,7 @@ const finished = util.promisify( stream.finished );
|
|
|
18
18
|
* Detects whether the given directory is a WordPress installation, a plugin or a theme.
|
|
19
19
|
*
|
|
20
20
|
* @param {string} directoryPath The directory to detect.
|
|
21
|
-
* @return {string|null} 'core' if the directory is a WordPress installation, 'plugin' if it is a plugin, 'theme' if it is a theme, or null if we can't tell.
|
|
21
|
+
* @return {Promise<string|null>} 'core' if the directory is a WordPress installation, 'plugin' if it is a plugin, 'theme' if it is a theme, or null if we can't tell.
|
|
22
22
|
*/
|
|
23
23
|
module.exports = async function detectDirectoryType( directoryPath ) {
|
|
24
24
|
// If we have a `wp-includes/version.php` file, then this is a Core install.
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
/**
|
|
3
|
+
* External dependencies
|
|
4
|
+
*/
|
|
5
|
+
const path = require( 'path' );
|
|
6
|
+
const fs = require( 'fs' ).promises;
|
|
7
|
+
const os = require( 'os' );
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Gets the directory in which generated files are created.
|
|
11
|
+
*
|
|
12
|
+
* By default: '~/.wp-env/'. On Linux with snap packages: '~/wp-env/'. Can be
|
|
13
|
+
* overridden with the WP_ENV_HOME environment variable.
|
|
14
|
+
*
|
|
15
|
+
* @return {Promise<string>} The absolute path to the `wp-env` home directory.
|
|
16
|
+
*/
|
|
17
|
+
module.exports = async function getCacheDirectory() {
|
|
18
|
+
// Allow user to override download location.
|
|
19
|
+
if ( process.env.WP_ENV_HOME ) {
|
|
20
|
+
return path.resolve( process.env.WP_ENV_HOME );
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Installing docker with Snap Packages on Linux is common, but does not
|
|
25
|
+
* support hidden directories. Therefore we use a public directory when
|
|
26
|
+
* snap packages exist.
|
|
27
|
+
*
|
|
28
|
+
* @see https://github.com/WordPress/gutenberg/issues/20180#issuecomment-587046325
|
|
29
|
+
*/
|
|
30
|
+
let usesSnap;
|
|
31
|
+
try {
|
|
32
|
+
await fs.stat( '/snap' );
|
|
33
|
+
usesSnap = true;
|
|
34
|
+
} catch {
|
|
35
|
+
usesSnap = false;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
return path.resolve( os.homedir(), usesSnap ? 'wp-env' : '.wp-env' );
|
|
39
|
+
};
|