@automattic/vip 2.26.0 → 2.26.2
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 +15 -0
- package/assets/dev-env.lando.template.yml.ejs +11 -1
- package/automattic-vip-2.26.2.tgz +0 -0
- package/dist/bin/vip-dev-env-create.js +2 -1
- package/dist/bin/vip-dev-env-import-sql.js +8 -67
- package/dist/bin/vip-dev-env-info.js +2 -1
- package/dist/bin/vip-dev-env-update.js +3 -3
- package/dist/bin/vip-import-sql.js +3 -3
- package/dist/commands/dev-env-import-sql.js +94 -0
- package/dist/commands/dev-env-sync-sql.js +184 -0
- package/dist/{lib/sql-export.js → commands/export-sql.js} +4 -4
- package/dist/lib/client-file-uploader.js +16 -0
- package/dist/lib/constants/dev-environment.js +0 -1
- package/dist/lib/dev-environment/dev-environment-cli.js +21 -12
- package/dist/lib/dev-environment/dev-environment-core.js +13 -3
- package/dist/lib/dev-environment/dev-environment-lando.js +55 -11
- package/dist/lib/search-and-replace.js +3 -8
- package/dist/lib/utils.js +41 -0
- package/npm-shrinkwrap.json +172 -174
- package/package.json +2 -2
- package/automattic-vip-2.26.0.tgz +0 -0
|
@@ -93,7 +93,7 @@ async function stopEnvironment(lando, slug) {
|
|
|
93
93
|
}
|
|
94
94
|
async function createEnvironment(instanceData) {
|
|
95
95
|
const slug = instanceData.siteSlug;
|
|
96
|
-
debug('Will
|
|
96
|
+
debug('Will process an environment', slug, 'with instanceData for creation: ', instanceData);
|
|
97
97
|
const instancePath = getEnvironmentPath(slug);
|
|
98
98
|
debug('Instance path for', slug, 'is:', instancePath);
|
|
99
99
|
const alreadyExists = _fs.default.existsSync(instancePath);
|
|
@@ -101,11 +101,12 @@ async function createEnvironment(instanceData) {
|
|
|
101
101
|
throw new Error('Environment already exists.');
|
|
102
102
|
}
|
|
103
103
|
const preProcessedInstanceData = preProcessInstanceData(instanceData);
|
|
104
|
+
debug('Will create an environment', slug, 'with instanceData: ', preProcessedInstanceData);
|
|
104
105
|
await prepareLandoEnv(preProcessedInstanceData, instancePath);
|
|
105
106
|
}
|
|
106
107
|
async function updateEnvironment(instanceData) {
|
|
107
108
|
const slug = instanceData.siteSlug;
|
|
108
|
-
debug('Will
|
|
109
|
+
debug('Will process an environment', slug, 'with instanceData for updating: ', instanceData);
|
|
109
110
|
const instancePath = getEnvironmentPath(slug);
|
|
110
111
|
debug('Instance path for', slug, 'is:', instancePath);
|
|
111
112
|
const alreadyExists = _fs.default.existsSync(instancePath);
|
|
@@ -113,6 +114,7 @@ async function updateEnvironment(instanceData) {
|
|
|
113
114
|
throw new Error('Environment doesn\'t exist.');
|
|
114
115
|
}
|
|
115
116
|
const preProcessedInstanceData = preProcessInstanceData(instanceData);
|
|
117
|
+
debug('Will create an environment', slug, 'with instanceData: ', preProcessedInstanceData);
|
|
116
118
|
await prepareLandoEnv(preProcessedInstanceData, instancePath);
|
|
117
119
|
}
|
|
118
120
|
function preProcessInstanceData(instanceData) {
|
|
@@ -128,6 +130,9 @@ function preProcessInstanceData(instanceData) {
|
|
|
128
130
|
if (newInstanceData.php.startsWith('image:')) {
|
|
129
131
|
newInstanceData.php = newInstanceData.php.slice('image:'.length);
|
|
130
132
|
}
|
|
133
|
+
if (isNaN(instanceData.wordpress.tag)) {
|
|
134
|
+
newInstanceData.wordpress.tag = 'trunk';
|
|
135
|
+
}
|
|
131
136
|
if (!newInstanceData.xdebugConfig) {
|
|
132
137
|
newInstanceData.xdebugConfig = '';
|
|
133
138
|
}
|
|
@@ -142,6 +147,11 @@ function preProcessInstanceData(instanceData) {
|
|
|
142
147
|
if (!newInstanceData.mailhog) {
|
|
143
148
|
newInstanceData.mailhog = false;
|
|
144
149
|
}
|
|
150
|
+
|
|
151
|
+
// MariaDB migration
|
|
152
|
+
if (!newInstanceData.mariadb) {
|
|
153
|
+
newInstanceData.mariadb = undefined;
|
|
154
|
+
}
|
|
145
155
|
return newInstanceData;
|
|
146
156
|
}
|
|
147
157
|
async function destroyEnvironment(lando, slug, removeFiles) {
|
|
@@ -198,7 +208,7 @@ async function printEnvironmentInfo(lando, slug, options) {
|
|
|
198
208
|
if (!environmentExists) {
|
|
199
209
|
throw new _userError.default(_devEnvironment.DEV_ENVIRONMENT_NOT_FOUND);
|
|
200
210
|
}
|
|
201
|
-
const appInfo = await (0, _devEnvironmentLando.landoInfo)(lando, instancePath);
|
|
211
|
+
const appInfo = await (0, _devEnvironmentLando.landoInfo)(lando, instancePath, !!options.suppressWarnings);
|
|
202
212
|
if (options.extended) {
|
|
203
213
|
const environmentData = readEnvironmentData(slug);
|
|
204
214
|
appInfo.title = environmentData.wpTitle;
|
|
@@ -4,6 +4,7 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.bootstrapLando = bootstrapLando;
|
|
7
|
+
exports.checkEnvHealth = checkEnvHealth;
|
|
7
8
|
exports.isEnvUp = isEnvUp;
|
|
8
9
|
exports.landoDestroy = landoDestroy;
|
|
9
10
|
exports.landoExec = landoExec;
|
|
@@ -18,6 +19,7 @@ var _os = _interopRequireDefault(require("os"));
|
|
|
18
19
|
var _fs = _interopRequireDefault(require("fs"));
|
|
19
20
|
var _path = _interopRequireDefault(require("path"));
|
|
20
21
|
var _lando = _interopRequireDefault(require("lando/lib/lando"));
|
|
22
|
+
var _bootstrap = require("lando/lib/bootstrap");
|
|
21
23
|
var _utils = _interopRequireDefault(require("lando/plugins/lando-core/lib/utils"));
|
|
22
24
|
var _build = _interopRequireDefault(require("lando/plugins/lando-tooling/lib/build"));
|
|
23
25
|
var _chalk = _interopRequireDefault(require("chalk"));
|
|
@@ -48,7 +50,7 @@ async function getLandoConfig() {
|
|
|
48
50
|
const nodeModulesPath = _path.default.join(__dirname, '..', '..', '..', 'node_modules');
|
|
49
51
|
const landoPath = _path.default.join(nodeModulesPath, 'lando');
|
|
50
52
|
const atLandoPath = _path.default.join(nodeModulesPath, '@lando');
|
|
51
|
-
debug(`Getting
|
|
53
|
+
debug(`Getting Lando config, using paths '${landoPath}' and '${atLandoPath}' for plugins`);
|
|
52
54
|
const isLandoDebugSelected = _debug.default.enabled(DEBUG_KEY);
|
|
53
55
|
const isAllDebugSelected = _debug.default.enabled('"*"');
|
|
54
56
|
let logLevelConsole;
|
|
@@ -69,8 +71,9 @@ async function getLandoConfig() {
|
|
|
69
71
|
} catch (err) {
|
|
70
72
|
// Ignore
|
|
71
73
|
}
|
|
72
|
-
|
|
74
|
+
const config = {
|
|
73
75
|
logLevelConsole,
|
|
76
|
+
configSources: [_path.default.join(landoDir, 'config.yml')],
|
|
74
77
|
landoFile: '.lando.yml',
|
|
75
78
|
preLandoFiles: ['.lando.base.yml', '.lando.dist.yml', '.lando.upstream.yml'],
|
|
76
79
|
postLandoFiles: ['.lando.local.yml'],
|
|
@@ -92,6 +95,7 @@ async function getLandoConfig() {
|
|
|
92
95
|
domain: 'lndo.site',
|
|
93
96
|
version: 'unknown'
|
|
94
97
|
};
|
|
98
|
+
return (0, _bootstrap.buildConfig)(config);
|
|
95
99
|
}
|
|
96
100
|
const appMap = new Map();
|
|
97
101
|
async function regenerateLandofile(instancePath) {
|
|
@@ -102,7 +106,7 @@ async function regenerateLandofile(instancePath) {
|
|
|
102
106
|
await _fs.default.promises.rename(landoFile, backup);
|
|
103
107
|
console.warn(_chalk.default.yellow('Backed up %s to %s'), landoFile, backup);
|
|
104
108
|
} catch (err) {
|
|
105
|
-
// Rename failed -
|
|
109
|
+
// Rename failed - possibly the file does not exist. Silently ignoring.
|
|
106
110
|
}
|
|
107
111
|
const slug = _path.default.basename(instancePath);
|
|
108
112
|
const currentInstanceData = (0, _devEnvironmentCore.readEnvironmentData)(slug);
|
|
@@ -138,7 +142,7 @@ async function getLandoApplication(lando, instancePath) {
|
|
|
138
142
|
let app;
|
|
139
143
|
try {
|
|
140
144
|
app = lando.getApp(instancePath);
|
|
141
|
-
addHooks(app, lando);
|
|
145
|
+
await addHooks(app, lando);
|
|
142
146
|
await app.init();
|
|
143
147
|
} catch (error) {
|
|
144
148
|
app = await landoRecovery(lando, instancePath, error);
|
|
@@ -162,7 +166,7 @@ async function landoRebuild(lando, instancePath) {
|
|
|
162
166
|
await ensureNoOrphantProxyContainer(lando);
|
|
163
167
|
await app.rebuild();
|
|
164
168
|
}
|
|
165
|
-
function addHooks(app, lando) {
|
|
169
|
+
async function addHooks(app, lando) {
|
|
166
170
|
app.events.on('post-start', 1, () => healthcheckHook(app, lando));
|
|
167
171
|
lando.events.once('pre-engine-build', async data => {
|
|
168
172
|
const instanceData = (0, _devEnvironmentCore.readEnvironmentData)(app._name);
|
|
@@ -249,13 +253,13 @@ async function landoDestroy(lando, instancePath) {
|
|
|
249
253
|
const app = await getLandoApplication(lando, instancePath);
|
|
250
254
|
await app.destroy();
|
|
251
255
|
}
|
|
252
|
-
async function landoInfo(lando, instancePath) {
|
|
256
|
+
async function landoInfo(lando, instancePath, suppressWarnings) {
|
|
253
257
|
var _app$info$find;
|
|
254
258
|
const app = await getLandoApplication(lando, instancePath);
|
|
255
259
|
let appInfo = _utils.default.startTable(app);
|
|
256
260
|
const reachableServices = app.info.filter(service => service.urls.length);
|
|
257
261
|
reachableServices.forEach(service => appInfo[`${service.service} urls`] = service.urls);
|
|
258
|
-
const
|
|
262
|
+
const health = await checkEnvHealth(lando, instancePath);
|
|
259
263
|
const frontEndUrl = (_app$info$find = app.info.find(service => 'nginx' === service.service)) === null || _app$info$find === void 0 ? void 0 : _app$info$find.urls[0];
|
|
260
264
|
const extraService = await getExtraServicesConnections(lando, app);
|
|
261
265
|
appInfo = {
|
|
@@ -264,7 +268,15 @@ async function landoInfo(lando, instancePath) {
|
|
|
264
268
|
...extraService
|
|
265
269
|
};
|
|
266
270
|
delete appInfo.name;
|
|
267
|
-
|
|
271
|
+
const hasResults = Object.values(health).length > 0;
|
|
272
|
+
const hasWarnings = Object.values(health).some(status => !status);
|
|
273
|
+
if (hasResults && !hasWarnings) {
|
|
274
|
+
appInfo.status = _chalk.default.green('UP');
|
|
275
|
+
} else if (health.nginx) {
|
|
276
|
+
appInfo.status = _chalk.default.yellow('PARTIALLY UP');
|
|
277
|
+
} else {
|
|
278
|
+
appInfo.status = _chalk.default.red('DOWN');
|
|
279
|
+
}
|
|
268
280
|
|
|
269
281
|
// Add login information
|
|
270
282
|
if (frontEndUrl) {
|
|
@@ -273,6 +285,15 @@ async function landoInfo(lando, instancePath) {
|
|
|
273
285
|
appInfo['Default username'] = 'vipgo';
|
|
274
286
|
appInfo['Default password'] = 'password';
|
|
275
287
|
}
|
|
288
|
+
if (!suppressWarnings && hasWarnings) {
|
|
289
|
+
let message = _chalk.default.bold.yellow('The following services have failed health checks:\n');
|
|
290
|
+
Object.keys(health).forEach(service => {
|
|
291
|
+
if (!health[service]) {
|
|
292
|
+
message += `${_chalk.default.red(service)}\n`;
|
|
293
|
+
}
|
|
294
|
+
});
|
|
295
|
+
appInfo['Health warnings'] = message;
|
|
296
|
+
}
|
|
276
297
|
|
|
277
298
|
// Add documentation link
|
|
278
299
|
appInfo.Documentation = 'https://docs.wpvip.com/technical-references/vip-local-development-environment/';
|
|
@@ -286,6 +307,9 @@ const extraServiceDisplayConfiguration = [{
|
|
|
286
307
|
name: 'phpmyadmin',
|
|
287
308
|
// Skipping, as the phpmyadmin was already printed by the regular services
|
|
288
309
|
skip: true
|
|
310
|
+
}, {
|
|
311
|
+
name: 'mailhog',
|
|
312
|
+
skip: true
|
|
289
313
|
}];
|
|
290
314
|
async function getExtraServicesConnections(lando, app) {
|
|
291
315
|
const extraServices = {};
|
|
@@ -316,19 +340,39 @@ async function getExtraServicesConnections(lando, app) {
|
|
|
316
340
|
}
|
|
317
341
|
return extraServices;
|
|
318
342
|
}
|
|
343
|
+
async function checkEnvHealth(lando, instancePath) {
|
|
344
|
+
const urls = {};
|
|
345
|
+
const now = new Date();
|
|
346
|
+
const app = await getLandoApplication(lando, instancePath);
|
|
347
|
+
app.info.filter(service => service.urls.length).forEach(service => {
|
|
348
|
+
service.urls.forEach(url => {
|
|
349
|
+
urls[url] = service.service;
|
|
350
|
+
});
|
|
351
|
+
});
|
|
352
|
+
const scanResults = await app.scanUrls(Object.keys(urls), {
|
|
353
|
+
max: 1
|
|
354
|
+
});
|
|
355
|
+
const result = {};
|
|
356
|
+
scanResults.forEach(scanResult => {
|
|
357
|
+
result[urls[scanResult.url]] = scanResult.status;
|
|
358
|
+
});
|
|
359
|
+
const duration = new Date().getTime() - now.getTime();
|
|
360
|
+
debug('checkEnvHealth took %d ms', duration);
|
|
361
|
+
return result;
|
|
362
|
+
}
|
|
319
363
|
async function isEnvUp(lando, instancePath) {
|
|
320
364
|
const now = new Date();
|
|
321
365
|
const app = await getLandoApplication(lando, instancePath);
|
|
322
366
|
const reachableServices = app.info.filter(service => service.urls.length);
|
|
323
|
-
const
|
|
324
|
-
const scanResult = await app.scanUrls(
|
|
367
|
+
const webUrls = reachableServices.map(service => service.urls).flat().filter(url => !url.match(/^https?:\/\/(localhost|127\.0\.0\.1):/));
|
|
368
|
+
const scanResult = await app.scanUrls(webUrls, {
|
|
325
369
|
max: 1
|
|
326
370
|
});
|
|
327
371
|
const duration = new Date().getTime() - now.getTime();
|
|
328
372
|
debug('isEnvUp took %d ms', duration);
|
|
329
373
|
|
|
330
374
|
// If all the URLs are reachable then the app is considered 'up'
|
|
331
|
-
return
|
|
375
|
+
return scanResult.length && scanResult.filter(result => result.status).length === scanResult.length;
|
|
332
376
|
}
|
|
333
377
|
async function landoExec(lando, instancePath, toolName, args, options) {
|
|
334
378
|
const app = await getLandoApplication(lando, instancePath);
|
|
@@ -6,7 +6,6 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
6
6
|
exports.getReadAndWriteStreams = getReadAndWriteStreams;
|
|
7
7
|
exports.searchAndReplace = void 0;
|
|
8
8
|
var _fs = _interopRequireDefault(require("fs"));
|
|
9
|
-
var _os = _interopRequireDefault(require("os"));
|
|
10
9
|
var _path = _interopRequireDefault(require("path"));
|
|
11
10
|
var _chalk = _interopRequireDefault(require("chalk"));
|
|
12
11
|
var _debug = _interopRequireDefault(require("debug"));
|
|
@@ -15,6 +14,7 @@ var _tracker = require("../lib/tracker");
|
|
|
15
14
|
var _prompt = require("../lib/cli/prompt");
|
|
16
15
|
var _clientFileUploader = require("../lib/client-file-uploader");
|
|
17
16
|
var exit = _interopRequireWildcard(require("../lib/cli/exit"));
|
|
17
|
+
var _utils = require("./utils");
|
|
18
18
|
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
|
|
19
19
|
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
|
|
20
20
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
@@ -37,11 +37,6 @@ const flatten = arr => {
|
|
|
37
37
|
return flat.concat(Array.isArray(toFlatten) ? flatten(toFlatten) : toFlatten);
|
|
38
38
|
}, []);
|
|
39
39
|
};
|
|
40
|
-
function makeTempDir() {
|
|
41
|
-
const tmpDir = _fs.default.mkdtempSync(_path.default.join(_os.default.tmpdir(), 'vip-search-replace-'));
|
|
42
|
-
debug(`Created a directory to hold temporary files: ${tmpDir}`);
|
|
43
|
-
return tmpDir;
|
|
44
|
-
}
|
|
45
40
|
function getReadAndWriteStreams({
|
|
46
41
|
fileName,
|
|
47
42
|
inPlace,
|
|
@@ -51,7 +46,7 @@ function getReadAndWriteStreams({
|
|
|
51
46
|
let usingStdOut = false;
|
|
52
47
|
let outputFileName;
|
|
53
48
|
if (inPlace) {
|
|
54
|
-
const midputFileName = _path.default.join(makeTempDir(), _path.default.basename(fileName));
|
|
49
|
+
const midputFileName = _path.default.join((0, _utils.makeTempDir)('vip-search-replace'), _path.default.basename(fileName));
|
|
55
50
|
_fs.default.copyFileSync(fileName, midputFileName);
|
|
56
51
|
debug(`Copied input file to ${midputFileName}`);
|
|
57
52
|
debug(`Set output to the original file path ${fileName}`);
|
|
@@ -81,7 +76,7 @@ function getReadAndWriteStreams({
|
|
|
81
76
|
break;
|
|
82
77
|
default:
|
|
83
78
|
{
|
|
84
|
-
const tmpOutFile = _path.default.join(makeTempDir(), _path.default.basename(fileName));
|
|
79
|
+
const tmpOutFile = _path.default.join((0, _utils.makeTempDir)('vip-search-replace'), _path.default.basename(fileName));
|
|
85
80
|
writeStream = _fs.default.createWriteStream(tmpOutFile);
|
|
86
81
|
outputFileName = tmpOutFile;
|
|
87
82
|
debug(`Outputting to file: ${outputFileName}`);
|
package/dist/lib/utils.js
CHANGED
|
@@ -3,7 +3,28 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
+
exports.makeTempDir = makeTempDir;
|
|
6
7
|
exports.pollUntil = pollUntil;
|
|
8
|
+
var _fs = _interopRequireDefault(require("fs"));
|
|
9
|
+
var _path = _interopRequireDefault(require("path"));
|
|
10
|
+
var _os = _interopRequireDefault(require("os"));
|
|
11
|
+
var _debug = _interopRequireDefault(require("debug"));
|
|
12
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
13
|
+
/**
|
|
14
|
+
*
|
|
15
|
+
* @format
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* External dependencies
|
|
20
|
+
*/
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Internal dependencies
|
|
24
|
+
*/
|
|
25
|
+
|
|
26
|
+
const debug = (0, _debug.default)('@automattic/vip:lib:utils');
|
|
27
|
+
|
|
7
28
|
/**
|
|
8
29
|
* Polls a function until its return value satisfies a condition
|
|
9
30
|
*
|
|
@@ -25,4 +46,24 @@ async function pollUntil(fn, interval, isDone) {
|
|
|
25
46
|
// eslint-disable-next-line no-await-in-loop
|
|
26
47
|
await new Promise(res => setTimeout(res, interval));
|
|
27
48
|
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Create a temporary directory in the system's temp directory
|
|
53
|
+
*
|
|
54
|
+
* @param {string} prefix Prefix for the directory name
|
|
55
|
+
* @return {string} Path to the temporary directory
|
|
56
|
+
* @throws {Error} If the directory cannot be created
|
|
57
|
+
*/
|
|
58
|
+
function makeTempDir(prefix = 'vip-cli') {
|
|
59
|
+
const tempDir = _fs.default.mkdtempSync(_path.default.join(_os.default.tmpdir(), `${prefix}-`));
|
|
60
|
+
debug(`Created a directory to hold temporary files: ${tempDir}`);
|
|
61
|
+
process.on('exit', () => {
|
|
62
|
+
_fs.default.rmSync(tempDir, {
|
|
63
|
+
recursive: true,
|
|
64
|
+
force: true
|
|
65
|
+
});
|
|
66
|
+
debug(`Removed temporary directory: ${tempDir}`);
|
|
67
|
+
});
|
|
68
|
+
return tempDir;
|
|
28
69
|
}
|