@wordpress/env 10.38.1-next.v.0 → 11.0.1-next.v.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 +57 -5
- package/lib/cli.js +31 -21
- package/lib/commands/clean.js +6 -37
- package/lib/commands/destroy.js +5 -25
- package/lib/commands/index.js +2 -2
- package/lib/commands/logs.js +6 -57
- package/lib/commands/run.js +5 -110
- package/lib/commands/start.js +35 -240
- package/lib/commands/status.js +154 -0
- package/lib/commands/stop.js +6 -15
- package/lib/download-sources.js +9 -53
- package/lib/{build-docker-compose-config.js → runtime/docker/build-docker-compose-config.js} +3 -3
- package/lib/runtime/docker/download-sources.js +59 -0
- package/lib/runtime/docker/index.js +741 -0
- package/lib/{init-config.js → runtime/docker/init-config.js} +2 -2
- package/lib/runtime/docker/wordpress.js +324 -0
- package/lib/runtime/errors.js +17 -0
- package/lib/runtime/index.js +69 -0
- package/lib/runtime/playground/blueprint-builder.js +166 -0
- package/lib/runtime/playground/index.js +502 -0
- package/lib/test/build-docker-compose-config.js +3 -3
- package/lib/wordpress.js +1 -297
- package/package.json +6 -3
- package/lib/commands/install-path.js +0 -21
- package/lib/{download-wp-phpunit.js → runtime/docker/download-wp-phpunit.js} +1 -1
- /package/lib/{get-host-user.js → runtime/docker/get-host-user.js} +0 -0
- /package/lib/{validate-run-container.js → runtime/docker/validate-run-container.js} +0 -0
|
@@ -0,0 +1,502 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* External dependencies
|
|
5
|
+
*/
|
|
6
|
+
const fs = require( 'fs' ).promises;
|
|
7
|
+
const http = require( 'http' );
|
|
8
|
+
const path = require( 'path' );
|
|
9
|
+
const spawn = require( 'cross-spawn' );
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Promisified dependencies
|
|
13
|
+
*/
|
|
14
|
+
const { rimraf } = require( 'rimraf' );
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Internal dependencies
|
|
18
|
+
*/
|
|
19
|
+
const { buildBlueprint, getMountArgs } = require( './blueprint-builder' );
|
|
20
|
+
const { UnsupportedCommandError } = require( '../errors' );
|
|
21
|
+
const { downloadSource } = require( '../../download-sources' );
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Playground runtime implementation for wp-env.
|
|
25
|
+
*/
|
|
26
|
+
class PlaygroundRuntime {
|
|
27
|
+
constructor() {
|
|
28
|
+
this.serverProcess = null;
|
|
29
|
+
this.serverPort = null;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Get the name of this runtime.
|
|
34
|
+
*
|
|
35
|
+
* @return {string} Runtime name.
|
|
36
|
+
*/
|
|
37
|
+
getName() {
|
|
38
|
+
return 'playground';
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Get supported features for this runtime.
|
|
43
|
+
*
|
|
44
|
+
* @return {Object} Feature flags.
|
|
45
|
+
*/
|
|
46
|
+
getFeatures() {
|
|
47
|
+
return {
|
|
48
|
+
testsEnvironment: false, // Single environment only
|
|
49
|
+
xdebug: true, // Supported via --xdebug flag
|
|
50
|
+
spx: false, // Not supported in WebAssembly
|
|
51
|
+
phpMyAdmin: false, // Supported on playground.wordpress.net but not in CLI yet
|
|
52
|
+
multisite: true, // Supported via Blueprint
|
|
53
|
+
customPhpVersion: true, // Supported via --php flag
|
|
54
|
+
persistentDatabase: false, // Could be supported via mounts (not yet implemented)
|
|
55
|
+
wpCli: true, // Limited support (not extensively tested)
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Check if Playground CLI is available.
|
|
61
|
+
*
|
|
62
|
+
* @return {Promise<boolean>} True if Playground CLI is available.
|
|
63
|
+
*/
|
|
64
|
+
async isAvailable() {
|
|
65
|
+
// npx will fetch it if not installed locally
|
|
66
|
+
return true;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Get the warning message for destroy confirmation.
|
|
71
|
+
*
|
|
72
|
+
* @return {string} Warning message.
|
|
73
|
+
*/
|
|
74
|
+
getDestroyWarningMessage() {
|
|
75
|
+
return 'WARNING! This will remove the WordPress Playground environment and all local files.';
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Start the WordPress Playground environment.
|
|
80
|
+
*
|
|
81
|
+
* @param {Object} config The wp-env config object.
|
|
82
|
+
* @param {Object} options Start options.
|
|
83
|
+
* @param {Object} options.spinner A CLI spinner which indicates progress.
|
|
84
|
+
* @param {boolean} options.debug True if debug mode is enabled.
|
|
85
|
+
* @param {string} options.xdebug The Xdebug mode to set.
|
|
86
|
+
*/
|
|
87
|
+
async start( config, { spinner, debug, xdebug } ) {
|
|
88
|
+
const envConfig = config.env.development;
|
|
89
|
+
|
|
90
|
+
spinner.text = 'Starting WordPress Playground.';
|
|
91
|
+
|
|
92
|
+
// Download remote sources (git/zip) if needed
|
|
93
|
+
const sources = [];
|
|
94
|
+
const addedSources = {};
|
|
95
|
+
const addSource = ( source ) => {
|
|
96
|
+
if (
|
|
97
|
+
source &&
|
|
98
|
+
( source.type === 'git' || source.type === 'zip' ) &&
|
|
99
|
+
! addedSources[ source.url ]
|
|
100
|
+
) {
|
|
101
|
+
sources.push( source );
|
|
102
|
+
addedSources[ source.url ] = true;
|
|
103
|
+
}
|
|
104
|
+
};
|
|
105
|
+
|
|
106
|
+
// Collect all sources that need downloading
|
|
107
|
+
envConfig.pluginSources.forEach( addSource );
|
|
108
|
+
envConfig.themeSources.forEach( addSource );
|
|
109
|
+
Object.values( envConfig.mappings ).forEach( addSource );
|
|
110
|
+
addSource( envConfig.coreSource );
|
|
111
|
+
|
|
112
|
+
// Download sources if any exist
|
|
113
|
+
if ( sources.length > 0 ) {
|
|
114
|
+
spinner.text = 'Downloading sources.';
|
|
115
|
+
|
|
116
|
+
await Promise.all(
|
|
117
|
+
sources.map( ( source ) =>
|
|
118
|
+
downloadSource( source, {
|
|
119
|
+
onProgress: () => {}, // Progress tracking could be added
|
|
120
|
+
spinner,
|
|
121
|
+
debug,
|
|
122
|
+
} )
|
|
123
|
+
)
|
|
124
|
+
);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
// Build and save blueprint
|
|
128
|
+
const blueprint = buildBlueprint( config );
|
|
129
|
+
const blueprintPath = path.join(
|
|
130
|
+
config.workDirectoryPath,
|
|
131
|
+
'playground-blueprint.json'
|
|
132
|
+
);
|
|
133
|
+
await fs.mkdir( config.workDirectoryPath, { recursive: true } );
|
|
134
|
+
await fs.writeFile(
|
|
135
|
+
blueprintPath,
|
|
136
|
+
JSON.stringify( blueprint, null, 2 )
|
|
137
|
+
);
|
|
138
|
+
|
|
139
|
+
// Get mount arguments
|
|
140
|
+
const mountArgs = getMountArgs( config );
|
|
141
|
+
|
|
142
|
+
// Determine port
|
|
143
|
+
const port = envConfig.port || 8888;
|
|
144
|
+
const phpVersion = envConfig.phpVersion || '8.2';
|
|
145
|
+
|
|
146
|
+
// Build command arguments for direct execution
|
|
147
|
+
const cliArgs = [
|
|
148
|
+
'server',
|
|
149
|
+
'--port',
|
|
150
|
+
String( port ),
|
|
151
|
+
'--php',
|
|
152
|
+
phpVersion,
|
|
153
|
+
'--blueprint',
|
|
154
|
+
blueprintPath,
|
|
155
|
+
'--login',
|
|
156
|
+
'--experimental-multi-worker',
|
|
157
|
+
...mountArgs,
|
|
158
|
+
];
|
|
159
|
+
|
|
160
|
+
if ( debug ) {
|
|
161
|
+
cliArgs.push( '--verbosity', 'debug' );
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
if ( xdebug ) {
|
|
165
|
+
cliArgs.push( '--xdebug' );
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
spinner.text = `Starting Playground on port ${ port }...`;
|
|
169
|
+
|
|
170
|
+
const siteUrl = `http://localhost:${ port }`;
|
|
171
|
+
const logFile = path.join( config.workDirectoryPath, 'playground.log' );
|
|
172
|
+
const pidFile = path.join( config.workDirectoryPath, 'playground.pid' );
|
|
173
|
+
|
|
174
|
+
// Use cross-spawn with detached mode for cross-platform support
|
|
175
|
+
// Create write stream for log file
|
|
176
|
+
const logFileStream = await fs.open( logFile, 'w' );
|
|
177
|
+
|
|
178
|
+
return new Promise( ( resolve, reject ) => {
|
|
179
|
+
const child = spawn( 'npx', [ '@wp-playground/cli', ...cliArgs ], {
|
|
180
|
+
detached: true,
|
|
181
|
+
stdio: [ 'ignore', logFileStream.fd, logFileStream.fd ],
|
|
182
|
+
env: { ...process.env, FORCE_COLOR: '0' },
|
|
183
|
+
} );
|
|
184
|
+
|
|
185
|
+
// Store child process reference
|
|
186
|
+
this.serverProcess = child;
|
|
187
|
+
this.serverPort = port;
|
|
188
|
+
|
|
189
|
+
// Save PID to file immediately so stop command can find the
|
|
190
|
+
// process even if startup fails before the server is ready.
|
|
191
|
+
fs.writeFile( pidFile, String( child.pid ) ).catch( () => {} );
|
|
192
|
+
|
|
193
|
+
// Allow parent to exit independently
|
|
194
|
+
child.unref();
|
|
195
|
+
|
|
196
|
+
// Track whether the process has exited so cleanup knows
|
|
197
|
+
// whether it still needs to kill it.
|
|
198
|
+
let processExited = false;
|
|
199
|
+
|
|
200
|
+
// If the process exits before the server is ready (e.g. blueprint
|
|
201
|
+
// validation error), reject immediately instead of waiting for
|
|
202
|
+
// the full 120-second timeout.
|
|
203
|
+
const earlyExitPromise = new Promise( ( _, rejectEarly ) => {
|
|
204
|
+
child.on( 'exit', ( code, signal ) => {
|
|
205
|
+
processExited = true;
|
|
206
|
+
const reason =
|
|
207
|
+
code !== null
|
|
208
|
+
? `with code ${ code }`
|
|
209
|
+
: `from signal ${ signal }`;
|
|
210
|
+
rejectEarly(
|
|
211
|
+
new Error(
|
|
212
|
+
`Playground process exited unexpectedly ${ reason }.`
|
|
213
|
+
)
|
|
214
|
+
);
|
|
215
|
+
} );
|
|
216
|
+
} );
|
|
217
|
+
|
|
218
|
+
child.on( 'error', ( error ) => {
|
|
219
|
+
logFileStream.close();
|
|
220
|
+
reject(
|
|
221
|
+
new Error(
|
|
222
|
+
`Failed to start Playground: ${ error.message }`
|
|
223
|
+
)
|
|
224
|
+
);
|
|
225
|
+
} );
|
|
226
|
+
|
|
227
|
+
// Race: wait for server to respond vs process early exit.
|
|
228
|
+
Promise.race( [
|
|
229
|
+
this._waitForServer( port, 120000 ),
|
|
230
|
+
earlyExitPromise,
|
|
231
|
+
] )
|
|
232
|
+
.then( async () => {
|
|
233
|
+
spinner.text = `WordPress Playground started at ${ siteUrl }`;
|
|
234
|
+
|
|
235
|
+
const message =
|
|
236
|
+
'WordPress development site started at ' + siteUrl;
|
|
237
|
+
|
|
238
|
+
resolve( {
|
|
239
|
+
message,
|
|
240
|
+
siteUrl,
|
|
241
|
+
} );
|
|
242
|
+
} )
|
|
243
|
+
.catch( async ( error ) => {
|
|
244
|
+
// Kill the process if it is still running.
|
|
245
|
+
if ( ! processExited && this.serverProcess ) {
|
|
246
|
+
this.serverProcess.kill( 'SIGKILL' );
|
|
247
|
+
this.serverProcess = null;
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
// Clean up PID file
|
|
251
|
+
try {
|
|
252
|
+
await fs.unlink( pidFile );
|
|
253
|
+
} catch {
|
|
254
|
+
// Ignore if file doesn't exist
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
// Read log file for error details
|
|
258
|
+
let logContent = '';
|
|
259
|
+
try {
|
|
260
|
+
logContent = await fs.readFile( logFile, 'utf8' );
|
|
261
|
+
} catch {
|
|
262
|
+
// Ignore
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
await logFileStream.close();
|
|
266
|
+
|
|
267
|
+
reject(
|
|
268
|
+
new Error(
|
|
269
|
+
`${ error.message }\n\nPlayground log:\n${
|
|
270
|
+
logContent || '(no log output)'
|
|
271
|
+
}`
|
|
272
|
+
)
|
|
273
|
+
);
|
|
274
|
+
} );
|
|
275
|
+
} );
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
/**
|
|
279
|
+
* Stop the WordPress Playground environment.
|
|
280
|
+
*
|
|
281
|
+
* @param {Object} config The wp-env config object.
|
|
282
|
+
* @param {Object} options Stop options.
|
|
283
|
+
* @param {Object} options.spinner A CLI spinner which indicates progress.
|
|
284
|
+
*/
|
|
285
|
+
async stop( config, { spinner } ) {
|
|
286
|
+
spinner.text = 'Stopping WordPress Playground.';
|
|
287
|
+
|
|
288
|
+
const pidFile = path.join( config.workDirectoryPath, 'playground.pid' );
|
|
289
|
+
|
|
290
|
+
// Try to read PID from file if process reference not available
|
|
291
|
+
let pid = this.serverProcess?.pid;
|
|
292
|
+
if ( ! pid ) {
|
|
293
|
+
try {
|
|
294
|
+
const pidContent = await fs.readFile( pidFile, 'utf8' );
|
|
295
|
+
pid = parseInt( pidContent.trim(), 10 );
|
|
296
|
+
} catch ( error ) {
|
|
297
|
+
// PID file doesn't exist or can't be read
|
|
298
|
+
spinner.text = 'Stopped WordPress Playground.';
|
|
299
|
+
return;
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
if ( pid ) {
|
|
304
|
+
try {
|
|
305
|
+
// Kill the entire process group (negative PID)
|
|
306
|
+
// This ensures both the npm process and child node process are killed
|
|
307
|
+
process.kill( -pid, 'SIGTERM' );
|
|
308
|
+
|
|
309
|
+
// Give it a moment for graceful shutdown
|
|
310
|
+
await new Promise( ( r ) => setTimeout( r, 1000 ) );
|
|
311
|
+
|
|
312
|
+
// Check if still running and force kill if needed
|
|
313
|
+
try {
|
|
314
|
+
process.kill( -pid, 0 ); // Check if process group exists
|
|
315
|
+
process.kill( -pid, 'SIGKILL' ); // Force kill entire group
|
|
316
|
+
} catch {
|
|
317
|
+
// Process group already terminated
|
|
318
|
+
}
|
|
319
|
+
} catch ( error ) {
|
|
320
|
+
// Process group doesn't exist or already terminated
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
// Clean up PID file
|
|
324
|
+
try {
|
|
325
|
+
await fs.unlink( pidFile );
|
|
326
|
+
} catch {
|
|
327
|
+
// Ignore if file doesn't exist
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
this.serverProcess = null;
|
|
331
|
+
this.serverPort = null;
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
spinner.text = 'Stopped WordPress Playground.';
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
/**
|
|
338
|
+
* Destroy the WordPress Playground environment.
|
|
339
|
+
*
|
|
340
|
+
* @param {Object} config The wp-env config object.
|
|
341
|
+
* @param {Object} options Destroy options.
|
|
342
|
+
* @param {Object} options.spinner A CLI spinner which indicates progress.
|
|
343
|
+
*/
|
|
344
|
+
async destroy( config, { spinner } ) {
|
|
345
|
+
await this.stop( config, { spinner } );
|
|
346
|
+
|
|
347
|
+
spinner.text = 'Removing local files.';
|
|
348
|
+
await rimraf( config.workDirectoryPath );
|
|
349
|
+
|
|
350
|
+
spinner.text = 'Removed WordPress Playground environment.';
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
/**
|
|
354
|
+
* Run a command in the Playground environment.
|
|
355
|
+
*
|
|
356
|
+
* @param {Object} config The wp-env config object.
|
|
357
|
+
* @param {Object} options Run options.
|
|
358
|
+
* @param {string} options.container The container to run the command in.
|
|
359
|
+
* @param {string[]} options.command The command to run.
|
|
360
|
+
* @param {string} options.envCwd The working directory.
|
|
361
|
+
* @param {Object} options.spinner A CLI spinner which indicates progress.
|
|
362
|
+
* @param {boolean} options.debug True if debug mode is enabled.
|
|
363
|
+
*/
|
|
364
|
+
// eslint-disable-next-line no-unused-vars
|
|
365
|
+
async run( config, { container, command, envCwd, spinner, debug } ) {
|
|
366
|
+
throw new UnsupportedCommandError( 'run' );
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
/**
|
|
370
|
+
* Clean/reset the WordPress database.
|
|
371
|
+
*
|
|
372
|
+
* @param {Object} config The wp-env config object.
|
|
373
|
+
* @param {Object} options Clean options.
|
|
374
|
+
* @param {Object} options.spinner A CLI spinner which indicates progress.
|
|
375
|
+
* @param {boolean} options.debug True if debug mode is enabled.
|
|
376
|
+
*/
|
|
377
|
+
async clean( config, { spinner, debug } ) {
|
|
378
|
+
spinner.text = 'Cleaning WordPress Playground environment.';
|
|
379
|
+
|
|
380
|
+
// For Playground, we restart the server to reset the database
|
|
381
|
+
await this.stop( config, { spinner } );
|
|
382
|
+
await this.start( config, { spinner, debug } );
|
|
383
|
+
|
|
384
|
+
spinner.text = 'Cleaned WordPress Playground environment.';
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
/**
|
|
388
|
+
* Get the status of the Playground environment.
|
|
389
|
+
*
|
|
390
|
+
* @param {Object} config The wp-env config object.
|
|
391
|
+
* @param {Object} options Status options.
|
|
392
|
+
* @param {Object} options.spinner A CLI spinner which indicates progress.
|
|
393
|
+
* @return {Promise<Object>} Status object with environment information.
|
|
394
|
+
*/
|
|
395
|
+
async getStatus( config, { spinner } ) {
|
|
396
|
+
spinner.text = 'Getting environment status.';
|
|
397
|
+
|
|
398
|
+
const envConfig = config.env.development;
|
|
399
|
+
const port = envConfig.port || 8888;
|
|
400
|
+
const pidFile = path.join( config.workDirectoryPath, 'playground.pid' );
|
|
401
|
+
|
|
402
|
+
// Check if server is running.
|
|
403
|
+
let isRunning = false;
|
|
404
|
+
|
|
405
|
+
try {
|
|
406
|
+
const pidContent = await fs.readFile( pidFile, 'utf8' );
|
|
407
|
+
const pid = parseInt( pidContent.trim(), 10 );
|
|
408
|
+
|
|
409
|
+
// Check if process is still alive.
|
|
410
|
+
process.kill( pid, 0 );
|
|
411
|
+
|
|
412
|
+
// Check if server is responding.
|
|
413
|
+
await this._checkServer( port );
|
|
414
|
+
isRunning = true;
|
|
415
|
+
} catch {
|
|
416
|
+
// Process not running or server not responding.
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
return {
|
|
420
|
+
status: isRunning ? 'running' : 'stopped',
|
|
421
|
+
runtime: 'playground',
|
|
422
|
+
urls: {
|
|
423
|
+
development: isRunning ? `http://localhost:${ port }` : null,
|
|
424
|
+
},
|
|
425
|
+
ports: {
|
|
426
|
+
development: port,
|
|
427
|
+
},
|
|
428
|
+
config: {
|
|
429
|
+
multisite: envConfig.multisite,
|
|
430
|
+
xdebug: 'off',
|
|
431
|
+
},
|
|
432
|
+
configPath: config.configDirectoryPath,
|
|
433
|
+
installPath: config.workDirectoryPath,
|
|
434
|
+
};
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
/**
|
|
438
|
+
* Show logs from the Playground environment.
|
|
439
|
+
*
|
|
440
|
+
* @param {Object} config The wp-env config object.
|
|
441
|
+
* @param {Object} options Logs options.
|
|
442
|
+
* @param {string} options.environment The environment to show logs for.
|
|
443
|
+
* @param {boolean} options.watch If true, follow along with log output.
|
|
444
|
+
* @param {Object} options.spinner A CLI spinner which indicates progress.
|
|
445
|
+
* @param {boolean} options.debug True if debug mode is enabled.
|
|
446
|
+
*/
|
|
447
|
+
// eslint-disable-next-line no-unused-vars
|
|
448
|
+
async logs( config, { environment, watch, spinner, debug } ) {
|
|
449
|
+
throw new UnsupportedCommandError( 'logs' );
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
/**
|
|
453
|
+
* Wait for the server to be ready.
|
|
454
|
+
*
|
|
455
|
+
* @param {number} port Port to check.
|
|
456
|
+
* @param {number} timeout Timeout in milliseconds.
|
|
457
|
+
* @return {Promise<void>}
|
|
458
|
+
*/
|
|
459
|
+
async _waitForServer( port, timeout = 30000 ) {
|
|
460
|
+
const start = Date.now();
|
|
461
|
+
|
|
462
|
+
while ( Date.now() - start < timeout ) {
|
|
463
|
+
try {
|
|
464
|
+
await this._checkServer( port );
|
|
465
|
+
return;
|
|
466
|
+
} catch {
|
|
467
|
+
await new Promise( ( r ) => setTimeout( r, 500 ) );
|
|
468
|
+
}
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
throw new Error(
|
|
472
|
+
`Playground server did not start within ${
|
|
473
|
+
timeout / 1000
|
|
474
|
+
} seconds.`
|
|
475
|
+
);
|
|
476
|
+
}
|
|
477
|
+
|
|
478
|
+
/**
|
|
479
|
+
* Check if server is responding.
|
|
480
|
+
*
|
|
481
|
+
* @param {number} port Port to check.
|
|
482
|
+
* @return {Promise<void>}
|
|
483
|
+
*/
|
|
484
|
+
_checkServer( port ) {
|
|
485
|
+
return new Promise( ( resolve, reject ) => {
|
|
486
|
+
const req = http.get( `http://localhost:${ port }`, ( res ) => {
|
|
487
|
+
if ( res.statusCode >= 200 && res.statusCode < 400 ) {
|
|
488
|
+
resolve();
|
|
489
|
+
} else {
|
|
490
|
+
reject( new Error( `Status: ${ res.statusCode }` ) );
|
|
491
|
+
}
|
|
492
|
+
} );
|
|
493
|
+
req.on( 'error', reject );
|
|
494
|
+
req.setTimeout( 1000, () => {
|
|
495
|
+
req.destroy();
|
|
496
|
+
reject( new Error( 'Timeout' ) );
|
|
497
|
+
} );
|
|
498
|
+
} );
|
|
499
|
+
}
|
|
500
|
+
}
|
|
501
|
+
|
|
502
|
+
module.exports = PlaygroundRuntime;
|
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
/**
|
|
3
3
|
* Internal dependencies
|
|
4
4
|
*/
|
|
5
|
-
const buildDockerComposeConfig = require( '../build-docker-compose-config' );
|
|
6
|
-
const getHostUser = require( '../get-host-user' );
|
|
5
|
+
const buildDockerComposeConfig = require( '../runtime/docker/build-docker-compose-config' );
|
|
6
|
+
const getHostUser = require( '../runtime/docker/get-host-user' );
|
|
7
7
|
|
|
8
8
|
// The basic config keys which build docker compose config requires.
|
|
9
9
|
const CONFIG = {
|
|
@@ -14,7 +14,7 @@ const CONFIG = {
|
|
|
14
14
|
configDirectoryPath: '/path/to/config',
|
|
15
15
|
};
|
|
16
16
|
|
|
17
|
-
jest.mock( '../get-host-user', () => jest.fn() );
|
|
17
|
+
jest.mock( '../runtime/docker/get-host-user', () => jest.fn() );
|
|
18
18
|
getHostUser.mockImplementation( () => {
|
|
19
19
|
return {
|
|
20
20
|
name: 'test',
|