@elementor/wp-lite-env 0.0.16 → 0.0.18
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/CHANGELOG.md +18 -0
- package/__tests__/__snapshots__/template.test.ts.snap +9 -12
- package/__tests__/config.test.ts +2 -2
- package/__tests__/e2e.ts +2 -2
- package/__tests__/template.test.ts +6 -6
- package/dist/bin.cjs +127 -129
- package/dist/bin.js +15 -14
- package/dist/{chunk-UBXF6D42.js → chunk-FNPCY3S6.js} +114 -125
- package/dist/index.cjs +24 -13
- package/dist/index.d.cts +3 -3
- package/dist/index.d.ts +3 -3
- package/dist/index.js +1 -1
- package/package.json +6 -2
- package/src/bin.ts +14 -11
- package/src/config.ts +1 -8
- package/src/run.ts +31 -38
- package/src/templates.ts +87 -66
- /package/{tests → __tests__}/.wp-lite-env.json +0 -0
@@ -17,100 +17,108 @@ var getConfig = (configFilePath) => {
|
|
17
17
|
mappings: {},
|
18
18
|
config: {}
|
19
19
|
};
|
20
|
-
return {
|
21
|
-
core: configFile.core || defaultConfig.core,
|
22
|
-
phpVersion: configFile.phpVersion || defaultConfig.phpVersion,
|
23
|
-
plugins: configFile.plugins || defaultConfig.plugins,
|
24
|
-
themes: configFile.themes || defaultConfig.themes,
|
25
|
-
mappings: configFile.mappings || defaultConfig.mappings,
|
26
|
-
config: configFile.config || defaultConfig.config
|
27
|
-
};
|
20
|
+
return Object.assign({}, defaultConfig, configFile);
|
28
21
|
};
|
29
22
|
|
30
23
|
// src/run.ts
|
31
|
-
import fs2 from "fs";
|
24
|
+
import fs2 from "fs/promises";
|
32
25
|
|
33
26
|
// src/templates.ts
|
34
27
|
import path from "path";
|
35
|
-
|
28
|
+
import { dump } from "js-yaml";
|
29
|
+
var generateVolumeMapping = (basePath, configPath, config) => {
|
36
30
|
const mappingsStringArray = Object.keys(config.mappings).map((key) => {
|
37
31
|
const value = config.mappings[key];
|
38
|
-
return
|
39
|
-
${path.resolve(basePath, value)}:/var/www/html/${key}
|
40
|
-
`;
|
32
|
+
return `${path.resolve(basePath, value)}:/var/www/html/${key}`;
|
41
33
|
});
|
42
34
|
const pluginsStringArray = Object.keys(config.plugins).map((key) => {
|
43
35
|
const value = config.plugins[key];
|
44
|
-
return
|
45
|
-
${path.resolve(basePath, value)}:/var/www/html/wp-content/plugins/${key}
|
46
|
-
`;
|
36
|
+
return `${path.resolve(basePath, value)}:/var/www/html/wp-content/plugins/${key}`;
|
47
37
|
});
|
48
38
|
const themesStringArray = Object.keys(config.themes).map((key) => {
|
49
39
|
const value = config.themes[key];
|
50
|
-
return
|
51
|
-
${path.resolve(basePath, value)}:/var/www/html/wp-content/themes/${key}
|
52
|
-
`;
|
40
|
+
return `${path.resolve(basePath, value)}:/var/www/html/wp-content/themes/${key}`;
|
53
41
|
});
|
54
|
-
const wpContent = `
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
const
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
42
|
+
const wpContent = `wpcontent:/var/www/html`;
|
43
|
+
const wpConfig = `${configPath}:/var/www/html/wp-config`;
|
44
|
+
return mappingsStringArray.concat(pluginsStringArray).concat(themesStringArray).concat([wpContent, wpConfig]);
|
45
|
+
};
|
46
|
+
var generateDockerComposeYmlTemplate = (config, basePath, port, configPath) => {
|
47
|
+
const hostUid = "502";
|
48
|
+
const hostGid = "20";
|
49
|
+
const wordpressDbUser = "root";
|
50
|
+
const wordpressDbPassword = "password";
|
51
|
+
const wordpressDbName = "wordpress";
|
52
|
+
const args = {
|
53
|
+
HOST_USERNAME: "someuser",
|
54
|
+
HOST_UID: hostUid,
|
55
|
+
HOST_GID: hostGid
|
56
|
+
};
|
57
|
+
const volumes = generateVolumeMapping(basePath, configPath, config);
|
58
|
+
const compose = {
|
59
|
+
services: {
|
60
|
+
mysql: {
|
61
|
+
image: "mariadb:lts",
|
62
|
+
ports: [
|
63
|
+
"${WP_ENV_MYSQL_PORT:-}:3306"
|
64
|
+
],
|
65
|
+
environment: {
|
66
|
+
MYSQL_ROOT_HOST: "%",
|
67
|
+
MYSQL_ROOT_PASSWORD: "password",
|
68
|
+
MYSQL_DATABASE: "wordpress"
|
69
|
+
},
|
70
|
+
volumes: [
|
71
|
+
"mysql:/var/lib/mysql"
|
72
|
+
]
|
73
|
+
},
|
74
|
+
wordpress: {
|
75
|
+
depends_on: ["mysql"],
|
76
|
+
build: {
|
77
|
+
context: ".",
|
78
|
+
dockerfile: "WordPress.Dockerfile",
|
79
|
+
no_cache: true,
|
80
|
+
args
|
81
|
+
},
|
82
|
+
ports: [
|
83
|
+
`\${WP_ENV_PORT:-${port}}:80`
|
84
|
+
],
|
85
|
+
environment: {
|
86
|
+
APACHE_RUN_USER: `#${hostUid}`,
|
87
|
+
APACHE_RUN_GROUP: `#${hostGid}`,
|
88
|
+
WORDPRESS_DB_USER: wordpressDbUser,
|
89
|
+
WORDPRESS_DB_PASSWORD: wordpressDbPassword,
|
90
|
+
WORDPRESS_DB_NAME: wordpressDbName
|
91
|
+
},
|
92
|
+
volumes,
|
93
|
+
extra_hosts: [
|
94
|
+
"host.docker.internal:host-gateway"
|
95
|
+
]
|
96
|
+
},
|
97
|
+
cli: {
|
98
|
+
depends_on: ["wordpress"],
|
99
|
+
build: {
|
100
|
+
context: ".",
|
101
|
+
dockerfile: "CLI.Dockerfile",
|
102
|
+
args
|
103
|
+
},
|
104
|
+
volumes,
|
105
|
+
user: `${hostUid}:${hostGid}`,
|
106
|
+
environment: {
|
107
|
+
WORDPRESS_DB_USER: wordpressDbUser,
|
108
|
+
WORDPRESS_DB_PASSWORD: wordpressDbPassword,
|
109
|
+
WORDPRESS_DB_NAME: wordpressDbName
|
110
|
+
},
|
111
|
+
extra_hosts: [
|
112
|
+
"host.docker.internal:host-gateway"
|
113
|
+
]
|
114
|
+
}
|
115
|
+
},
|
116
|
+
volumes: {
|
117
|
+
mysql: {},
|
118
|
+
wpcontent: {}
|
119
|
+
}
|
120
|
+
};
|
121
|
+
return dump(compose);
|
114
122
|
};
|
115
123
|
var generateWordPressDockerfileTemplate = (config) => {
|
116
124
|
return `FROM wordpress:${config.core}-php${config.phpVersion}
|
@@ -152,22 +160,28 @@ set -eox pipefail
|
|
152
160
|
import { createHash } from "crypto";
|
153
161
|
import os from "node:os";
|
154
162
|
var waitForServer = async (url, timeoutMs) => {
|
155
|
-
const startTime = Date.now();
|
156
163
|
const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
|
157
|
-
|
164
|
+
const pollEveryMs = 100;
|
165
|
+
let retries = timeoutMs / pollEveryMs;
|
166
|
+
while (retries > 0) {
|
158
167
|
try {
|
159
168
|
const response = await fetch(url);
|
160
|
-
if (
|
169
|
+
if (200 === response.status || 302 === response.status) {
|
161
170
|
return true;
|
162
171
|
}
|
163
172
|
} catch (e) {
|
164
|
-
|
165
|
-
|
173
|
+
if ("ECONNREFUSED" !== e.cause?.code) {
|
174
|
+
console.warn(`Encountered an error while waiting for server to start: ${e.message}
|
175
|
+
Trying to reach server again.`);
|
176
|
+
}
|
166
177
|
}
|
178
|
+
await sleep(pollEveryMs);
|
179
|
+
retries--;
|
167
180
|
}
|
181
|
+
console.error(`Server did not start within ${timeoutMs}ms`);
|
168
182
|
return false;
|
169
183
|
};
|
170
|
-
var getRunPath = (port) => path2.resolve(os.tmpdir(), port);
|
184
|
+
var getRunPath = (port) => path2.resolve(os.tmpdir(), `${port}`);
|
171
185
|
var start = async (port) => {
|
172
186
|
const runPath = getRunPath(port);
|
173
187
|
await upAll({
|
@@ -176,7 +190,7 @@ var start = async (port) => {
|
|
176
190
|
cwd: runPath,
|
177
191
|
log: true
|
178
192
|
});
|
179
|
-
await waitForServer(`http://
|
193
|
+
await waitForServer(`http://0.0.0.0:${port}`, 1e4);
|
180
194
|
await cli(port, "bash wp-config/configure-wp.sh");
|
181
195
|
};
|
182
196
|
var stop = async (port) => {
|
@@ -187,7 +201,7 @@ var stop = async (port) => {
|
|
187
201
|
composeOptions: ["-p", `port${port}`],
|
188
202
|
log: true
|
189
203
|
});
|
190
|
-
cleanup(port);
|
204
|
+
await cleanup(port);
|
191
205
|
};
|
192
206
|
var cli = async (port, command) => {
|
193
207
|
const runPath = getRunPath(port);
|
@@ -203,52 +217,30 @@ var commandMap = {
|
|
203
217
|
stop,
|
204
218
|
cli
|
205
219
|
};
|
206
|
-
var getWpConfigPath = (port) => path2.resolve(process.cwd(), port);
|
207
|
-
var generateFiles = (port, configFilePath) => {
|
220
|
+
var getWpConfigPath = (port) => path2.resolve(process.cwd(), `${port}`);
|
221
|
+
var generateFiles = async (port, configFilePath) => {
|
208
222
|
const config = getConfig(configFilePath);
|
209
223
|
const wpConfigPath = getWpConfigPath(port);
|
210
|
-
|
211
|
-
fs2.mkdirSync(wpConfigPath, { recursive: true });
|
212
|
-
}
|
224
|
+
await fs2.mkdir(wpConfigPath, { recursive: true });
|
213
225
|
const wpConfig = generateConfiguration(config, port);
|
214
|
-
fs2.
|
226
|
+
await fs2.writeFile(path2.resolve(wpConfigPath, "configure-wp.sh"), wpConfig);
|
215
227
|
const dockerComposeYmlTemplate = generateDockerComposeYmlTemplate(config, process.cwd(), port, wpConfigPath);
|
216
228
|
const wordPressDockerfileTemplate = generateWordPressDockerfileTemplate(config);
|
217
229
|
const cliDockerfileTemplate = generateCliDockerfileTemplate(config);
|
218
230
|
const hash = createHash("sha256");
|
219
231
|
hash.update(dockerComposeYmlTemplate + wordPressDockerfileTemplate + cliDockerfileTemplate + port);
|
220
232
|
const runPath = getRunPath(port);
|
221
|
-
|
222
|
-
fs2.mkdirSync(runPath);
|
223
|
-
}
|
233
|
+
await fs2.mkdir(runPath, { recursive: true });
|
224
234
|
console.log(`writing files to run path: ${runPath}`);
|
225
|
-
fs2.
|
226
|
-
fs2.
|
227
|
-
fs2.
|
235
|
+
await fs2.writeFile(path2.resolve(runPath, "docker-compose.yml"), dockerComposeYmlTemplate);
|
236
|
+
await fs2.writeFile(path2.resolve(runPath, "WordPress.Dockerfile"), wordPressDockerfileTemplate);
|
237
|
+
await fs2.writeFile(path2.resolve(runPath, "CLI.Dockerfile"), cliDockerfileTemplate);
|
228
238
|
return runPath;
|
229
239
|
};
|
230
|
-
var
|
231
|
-
for (let i = 3; i < processArgs.length; i++) {
|
232
|
-
const argument = processArgs[i];
|
233
|
-
if (argument.startsWith(`${argumentKey}=`)) {
|
234
|
-
return argument.substring(argumentKey.length + 1);
|
235
|
-
}
|
236
|
-
}
|
237
|
-
return void 0;
|
238
|
-
};
|
239
|
-
var getConfigFilePath = (processArgs) => {
|
240
|
-
return path2.resolve(getArgument("config", processArgs));
|
241
|
-
};
|
242
|
-
var getCliCommand = (processArgs) => {
|
243
|
-
return getArgument("command", processArgs);
|
244
|
-
};
|
245
|
-
var getPort = (processArgs) => {
|
246
|
-
return getArgument("port", processArgs) || "8888";
|
247
|
-
};
|
248
|
-
var cleanup = (port) => {
|
240
|
+
var cleanup = async (port) => {
|
249
241
|
const runPath = getRunPath(port);
|
250
|
-
fs2.
|
251
|
-
fs2.
|
242
|
+
await fs2.rm(getWpConfigPath(port), { recursive: true, force: true });
|
243
|
+
await fs2.rm(runPath, { recursive: true, force: true });
|
252
244
|
};
|
253
245
|
|
254
246
|
export {
|
@@ -256,9 +248,6 @@ export {
|
|
256
248
|
stop,
|
257
249
|
cli,
|
258
250
|
commandMap,
|
259
|
-
generateFiles
|
260
|
-
getConfigFilePath,
|
261
|
-
getCliCommand,
|
262
|
-
getPort
|
251
|
+
generateFiles
|
263
252
|
};
|
264
|
-
//# sourceMappingURL=chunk-
|
253
|
+
//# sourceMappingURL=chunk-FNPCY3S6.js.map
|
package/dist/index.cjs
CHANGED
@@ -38,25 +38,36 @@ module.exports = __toCommonJS(src_exports);
|
|
38
38
|
// src/run.ts
|
39
39
|
var import_docker_compose = require("docker-compose");
|
40
40
|
var import_path = __toESM(require("path"), 1);
|
41
|
-
var
|
41
|
+
var import_promises = __toESM(require("fs/promises"), 1);
|
42
|
+
|
43
|
+
// src/templates.ts
|
44
|
+
var import_js_yaml = require("js-yaml");
|
45
|
+
|
46
|
+
// src/run.ts
|
42
47
|
var import_node_os = __toESM(require("os"), 1);
|
43
48
|
var waitForServer = async (url, timeoutMs) => {
|
44
|
-
const startTime = Date.now();
|
45
49
|
const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
|
46
|
-
|
50
|
+
const pollEveryMs = 100;
|
51
|
+
let retries = timeoutMs / pollEveryMs;
|
52
|
+
while (retries > 0) {
|
47
53
|
try {
|
48
54
|
const response = await fetch(url);
|
49
|
-
if (
|
55
|
+
if (200 === response.status || 302 === response.status) {
|
50
56
|
return true;
|
51
57
|
}
|
52
58
|
} catch (e) {
|
53
|
-
|
54
|
-
|
59
|
+
if ("ECONNREFUSED" !== e.cause?.code) {
|
60
|
+
console.warn(`Encountered an error while waiting for server to start: ${e.message}
|
61
|
+
Trying to reach server again.`);
|
62
|
+
}
|
55
63
|
}
|
64
|
+
await sleep(pollEveryMs);
|
65
|
+
retries--;
|
56
66
|
}
|
67
|
+
console.error(`Server did not start within ${timeoutMs}ms`);
|
57
68
|
return false;
|
58
69
|
};
|
59
|
-
var getRunPath = (port) => import_path.default.resolve(import_node_os.default.tmpdir(), port);
|
70
|
+
var getRunPath = (port) => import_path.default.resolve(import_node_os.default.tmpdir(), `${port}`);
|
60
71
|
var start = async (port) => {
|
61
72
|
const runPath = getRunPath(port);
|
62
73
|
await (0, import_docker_compose.upAll)({
|
@@ -65,7 +76,7 @@ var start = async (port) => {
|
|
65
76
|
cwd: runPath,
|
66
77
|
log: true
|
67
78
|
});
|
68
|
-
await waitForServer(`http://
|
79
|
+
await waitForServer(`http://0.0.0.0:${port}`, 1e4);
|
69
80
|
await cli(port, "bash wp-config/configure-wp.sh");
|
70
81
|
};
|
71
82
|
var stop = async (port) => {
|
@@ -76,7 +87,7 @@ var stop = async (port) => {
|
|
76
87
|
composeOptions: ["-p", `port${port}`],
|
77
88
|
log: true
|
78
89
|
});
|
79
|
-
cleanup(port);
|
90
|
+
await cleanup(port);
|
80
91
|
};
|
81
92
|
var cli = async (port, command) => {
|
82
93
|
const runPath = getRunPath(port);
|
@@ -87,11 +98,11 @@ var cli = async (port, command) => {
|
|
87
98
|
log: true
|
88
99
|
});
|
89
100
|
};
|
90
|
-
var getWpConfigPath = (port) => import_path.default.resolve(process.cwd(), port);
|
91
|
-
var cleanup = (port) => {
|
101
|
+
var getWpConfigPath = (port) => import_path.default.resolve(process.cwd(), `${port}`);
|
102
|
+
var cleanup = async (port) => {
|
92
103
|
const runPath = getRunPath(port);
|
93
|
-
|
94
|
-
|
104
|
+
await import_promises.default.rm(getWpConfigPath(port), { recursive: true, force: true });
|
105
|
+
await import_promises.default.rm(runPath, { recursive: true, force: true });
|
95
106
|
};
|
96
107
|
// Annotate the CommonJS export names for ESM import in node:
|
97
108
|
0 && (module.exports = {
|
package/dist/index.d.cts
CHANGED
@@ -1,5 +1,5 @@
|
|
1
|
-
declare const start: (port:
|
2
|
-
declare const stop: (port:
|
3
|
-
declare const cli: (port:
|
1
|
+
declare const start: (port: number) => Promise<void>;
|
2
|
+
declare const stop: (port: number) => Promise<void>;
|
3
|
+
declare const cli: (port: number, command: string) => Promise<void>;
|
4
4
|
|
5
5
|
export { cli, start, stop };
|
package/dist/index.d.ts
CHANGED
@@ -1,5 +1,5 @@
|
|
1
|
-
declare const start: (port:
|
2
|
-
declare const stop: (port:
|
3
|
-
declare const cli: (port:
|
1
|
+
declare const start: (port: number) => Promise<void>;
|
2
|
+
declare const stop: (port: number) => Promise<void>;
|
3
|
+
declare const cli: (port: number, command: string) => Promise<void>;
|
4
4
|
|
5
5
|
export { cli, start, stop };
|
package/dist/index.js
CHANGED
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@elementor/wp-lite-env",
|
3
|
-
"version": "0.0.
|
3
|
+
"version": "0.0.18",
|
4
4
|
"private": false,
|
5
5
|
"description": "A simple, lightweight, docker-based WordPress environment",
|
6
6
|
"main": "dist/index.cjs",
|
@@ -31,13 +31,17 @@
|
|
31
31
|
},
|
32
32
|
"homepage": "https://github.com/elementor/wp-lite-env#readme",
|
33
33
|
"dependencies": {
|
34
|
-
"
|
34
|
+
"command-line-args": "^6.0.1",
|
35
|
+
"docker-compose": "^1.1.0",
|
36
|
+
"js-yaml": "^4.1.0"
|
35
37
|
},
|
36
38
|
"devDependencies": {
|
37
39
|
"@changesets/cli": "^2.27.9",
|
38
40
|
"@eslint/js": "^9.15.0",
|
39
41
|
"@jest/globals": "^29.7.0",
|
42
|
+
"@types/command-line-args": "^5.2.3",
|
40
43
|
"@types/eslint__js": "^8.42.3",
|
44
|
+
"@types/js-yaml": "^4.0.9",
|
41
45
|
"@types/node": "^22.10.0",
|
42
46
|
"eslint": "~9.14.0",
|
43
47
|
"jest": "^29.7.0",
|
package/src/bin.ts
CHANGED
@@ -1,15 +1,18 @@
|
|
1
1
|
#!/usr/bin/env node
|
2
2
|
|
3
|
-
import
|
3
|
+
import commandLineArgs from 'command-line-args';
|
4
|
+
import {commandMap, generateFiles} from './run';
|
4
5
|
|
5
|
-
const
|
6
|
-
|
7
|
-
|
8
|
-
}
|
6
|
+
const cliOptionDefinitions = [
|
7
|
+
{ name: 'cmd', type: String, defaultOption: true, description: 'The command to run. Can be one of "start", "stop" or "cli"' },
|
8
|
+
{ name: 'config', type: String, description: "Path to the configuration file defining the WordPress environment." },
|
9
|
+
{ name: 'port', type: Number, description: "Port to run the WordPress environment on" },
|
10
|
+
{ name: 'command', type: String, defaultValue: '', description: "The command to run by the WP CLI" },
|
11
|
+
];
|
12
|
+
const cliOptions = commandLineArgs(cliOptionDefinitions);
|
9
13
|
|
10
|
-
const
|
11
|
-
const
|
12
|
-
const
|
13
|
-
|
14
|
-
|
15
|
-
commandMap[command](port, cliCommand);
|
14
|
+
const command = cliOptions.cmd;
|
15
|
+
const port = cliOptions.port;
|
16
|
+
const configFilePath = cliOptions.config;
|
17
|
+
const cliCommand = cliOptions.command;
|
18
|
+
generateFiles( port, configFilePath ).then( () => commandMap[command](port, cliCommand) );
|
package/src/config.ts
CHANGED
@@ -24,12 +24,5 @@ export const getConfig = ( configFilePath?: string ): Config => {
|
|
24
24
|
config: {},
|
25
25
|
};
|
26
26
|
|
27
|
-
return {
|
28
|
-
core: configFile.core || defaultConfig.core,
|
29
|
-
phpVersion: configFile.phpVersion || defaultConfig.phpVersion,
|
30
|
-
plugins: configFile.plugins || defaultConfig.plugins,
|
31
|
-
themes: configFile.themes || defaultConfig.themes,
|
32
|
-
mappings: configFile.mappings || defaultConfig.mappings,
|
33
|
-
config: configFile.config || defaultConfig.config,
|
34
|
-
};
|
27
|
+
return Object.assign({}, defaultConfig, configFile);
|
35
28
|
};
|
package/src/run.ts
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
import {downAll, run, upAll} from "docker-compose";
|
2
2
|
import path from "path";
|
3
3
|
import {getConfig} from "./config";
|
4
|
-
import fs from "fs";
|
4
|
+
import fs from "fs/promises";
|
5
5
|
import {
|
6
6
|
generateCliDockerfileTemplate,
|
7
7
|
generateConfiguration,
|
@@ -12,27 +12,32 @@ import {createHash} from "crypto";
|
|
12
12
|
import os from "node:os";
|
13
13
|
|
14
14
|
const waitForServer = async ( url: string, timeoutMs: number ) => {
|
15
|
-
const startTime = Date.now();
|
16
15
|
const sleep = ( ms: number ) => new Promise( ( r ) => setTimeout( r, ms ) );
|
17
16
|
|
18
|
-
|
17
|
+
const pollEveryMs = 100;
|
18
|
+
let retries = timeoutMs / pollEveryMs;
|
19
|
+
|
20
|
+
while (retries > 0) {
|
19
21
|
try {
|
20
22
|
const response = await fetch( url );
|
21
|
-
if (
|
23
|
+
if ( 200 === response.status || 302 === response.status ) {
|
22
24
|
return true;
|
23
25
|
}
|
24
|
-
} catch ( e ) {
|
25
|
-
|
26
|
-
|
27
|
-
|
26
|
+
} catch ( e ) {
|
27
|
+
if ( 'ECONNREFUSED' !== e.cause?.code ) {
|
28
|
+
console.warn( `Encountered an error while waiting for server to start: ${ e.message }\nTrying to reach server again.` );
|
29
|
+
}
|
28
30
|
}
|
31
|
+
await sleep (pollEveryMs);
|
32
|
+
retries--;
|
29
33
|
}
|
34
|
+
console.error( `Server did not start within ${ timeoutMs }ms` );
|
30
35
|
return false;
|
31
36
|
};
|
32
37
|
|
33
|
-
const getRunPath = ( port:
|
38
|
+
const getRunPath = ( port: number ) => path.resolve( os.tmpdir(), `${port}` );
|
34
39
|
|
35
|
-
export const start = async ( port:
|
40
|
+
export const start = async ( port: number ) => {
|
36
41
|
const runPath = getRunPath( port );
|
37
42
|
await upAll( {
|
38
43
|
commandOptions: [ '--build' ],
|
@@ -40,11 +45,11 @@ export const start = async ( port: string ) => {
|
|
40
45
|
cwd: runPath,
|
41
46
|
log: true,
|
42
47
|
} );
|
43
|
-
await waitForServer( `http://
|
48
|
+
await waitForServer( `http://0.0.0.0:${ port }`, 10000 );
|
44
49
|
await cli( port, 'bash wp-config/configure-wp.sh' );
|
45
50
|
};
|
46
51
|
|
47
|
-
export const stop = async ( port:
|
52
|
+
export const stop = async ( port: number ) => {
|
48
53
|
const runPath = getRunPath( port );
|
49
54
|
await downAll( {
|
50
55
|
cwd: runPath,
|
@@ -52,10 +57,10 @@ export const stop = async ( port: string ) => {
|
|
52
57
|
composeOptions: [ '-p', `port${ port }` ],
|
53
58
|
log: true,
|
54
59
|
} );
|
55
|
-
cleanup( port );
|
60
|
+
await cleanup( port );
|
56
61
|
};
|
57
62
|
|
58
|
-
export const cli = async ( port:
|
63
|
+
export const cli = async ( port: number, command: string ) => {
|
59
64
|
const runPath = getRunPath( port );
|
60
65
|
await run( 'cli', command, {
|
61
66
|
cwd: runPath,
|
@@ -65,25 +70,23 @@ export const cli = async ( port: string, command: string ) => {
|
|
65
70
|
} );
|
66
71
|
};
|
67
72
|
|
68
|
-
export const commandMap: { [key: string]: ( ( port:
|
73
|
+
export const commandMap: { [key: string]: ( ( port: number ) => Promise<void> ) | ( ( port: number, command: string ) => Promise<void> ) } = {
|
69
74
|
start,
|
70
75
|
stop,
|
71
76
|
cli,
|
72
77
|
};
|
73
78
|
|
74
|
-
const getWpConfigPath = ( port:
|
79
|
+
const getWpConfigPath = ( port: number ) => path.resolve( process.cwd(), `${port}` );
|
75
80
|
|
76
|
-
export const generateFiles = ( port:
|
81
|
+
export const generateFiles = async ( port: number, configFilePath: string ) => {
|
77
82
|
const config = getConfig( configFilePath );
|
78
83
|
|
79
84
|
// Using a local path since Docker Compose cannot access /tmp
|
80
85
|
// See: https://github.com/docker/compose/issues/1153
|
81
86
|
const wpConfigPath = getWpConfigPath( port );
|
82
|
-
|
83
|
-
fs.mkdirSync( wpConfigPath, { recursive: true } );
|
84
|
-
}
|
87
|
+
await fs.mkdir( wpConfigPath, { recursive: true } );
|
85
88
|
const wpConfig = generateConfiguration( config, port );
|
86
|
-
fs.
|
89
|
+
await fs.writeFile( path.resolve( wpConfigPath, 'configure-wp.sh' ), wpConfig );
|
87
90
|
|
88
91
|
const dockerComposeYmlTemplate = generateDockerComposeYmlTemplate( config, process.cwd(), port, wpConfigPath );
|
89
92
|
const wordPressDockerfileTemplate = generateWordPressDockerfileTemplate( config );
|
@@ -91,14 +94,12 @@ export const generateFiles = ( port: string, configFilePath: string ) => {
|
|
91
94
|
const hash = createHash( 'sha256' );
|
92
95
|
hash.update( dockerComposeYmlTemplate + wordPressDockerfileTemplate + cliDockerfileTemplate + port );
|
93
96
|
const runPath = getRunPath( port );
|
94
|
-
|
95
|
-
fs.mkdirSync( runPath );
|
96
|
-
}
|
97
|
+
await fs.mkdir( runPath, { recursive: true } );
|
97
98
|
|
98
99
|
console.log( `writing files to run path: ${ runPath }` );
|
99
|
-
fs.
|
100
|
-
fs.
|
101
|
-
fs.
|
100
|
+
await fs.writeFile( path.resolve( runPath, 'docker-compose.yml' ), dockerComposeYmlTemplate );
|
101
|
+
await fs.writeFile( path.resolve( runPath, 'WordPress.Dockerfile' ), wordPressDockerfileTemplate );
|
102
|
+
await fs.writeFile( path.resolve( runPath, 'CLI.Dockerfile' ), cliDockerfileTemplate );
|
102
103
|
|
103
104
|
return runPath;
|
104
105
|
};
|
@@ -117,16 +118,8 @@ export const getConfigFilePath = ( processArgs: string[] ) => {
|
|
117
118
|
return path.resolve(getArgument( 'config', processArgs ));
|
118
119
|
};
|
119
120
|
|
120
|
-
|
121
|
-
return getArgument( 'command', processArgs );
|
122
|
-
};
|
123
|
-
|
124
|
-
export const getPort = ( processArgs: string[] ) => {
|
125
|
-
return getArgument( 'port', processArgs ) || '8888';
|
126
|
-
};
|
127
|
-
|
128
|
-
const cleanup = ( port: string ) => {
|
121
|
+
const cleanup = async ( port: number ) => {
|
129
122
|
const runPath = getRunPath( port );
|
130
|
-
fs.
|
131
|
-
fs.
|
123
|
+
await fs.rm( getWpConfigPath( port ), { recursive: true, force: true } );
|
124
|
+
await fs.rm( runPath, { recursive: true, force: true } );
|
132
125
|
}
|