@automattic/vip 3.23.2 → 3.23.4-dev.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/dist/bin/vip-dev-env-create.js +3 -1
- package/dist/bin/vip-dev-env-destroy.js +3 -1
- package/dist/bin/vip-dev-env-exec.js +3 -1
- package/dist/bin/vip-dev-env-info.js +4 -2
- package/dist/bin/vip-dev-env-list.js +3 -1
- package/dist/bin/vip-dev-env-logs.js +3 -1
- package/dist/bin/vip-dev-env-purge.js +3 -1
- package/dist/bin/vip-dev-env-shell.js +3 -1
- package/dist/bin/vip-dev-env-start.js +3 -1
- package/dist/bin/vip-dev-env-stop.js +8 -2
- package/dist/bin/vip-dev-env-sync-sql.js +3 -1
- package/dist/bin/vip-dev-env-update.js +3 -1
- package/dist/bin/vip-import-media.js +9 -1
- package/dist/commands/dev-env-import-sql.js +3 -1
- package/dist/lib/cli/command.js +33 -24
- package/dist/lib/dev-environment/dev-environment-cli.js +13 -0
- package/dist/lib/dev-environment/dev-environment-lando.js +124 -3
- package/npm-shrinkwrap.json +525 -377
- package/package.json +9 -9
|
@@ -49,7 +49,9 @@ cmd.argv(process.argv, async (arg, opt) => {
|
|
|
49
49
|
if (hasConfiguration) {
|
|
50
50
|
slug = await (0, _devEnvironmentCli.getEnvironmentName)(environmentNameOptions);
|
|
51
51
|
}
|
|
52
|
-
const lando = await (0, _devEnvironmentLando.bootstrapLando)(
|
|
52
|
+
const lando = await (0, _devEnvironmentLando.bootstrapLando)({
|
|
53
|
+
logFile: (0, _devEnvironmentCli.getDevEnvLogFile)(slug)
|
|
54
|
+
});
|
|
53
55
|
(0, _devEnvironmentCli.validateDependencies)(lando);
|
|
54
56
|
debug('Args: ', arg, 'Options: ', opt);
|
|
55
57
|
const trackingInfo = {
|
|
@@ -23,7 +23,9 @@ const examples = [{
|
|
|
23
23
|
usage
|
|
24
24
|
}).option('slug', 'A unique name for a local environment. Default is "vip-local".', undefined, _devEnvironmentCli.processSlug).option('soft', 'Preserve an environment’s configuration files; allows an environment to be regenerated with the start command.').examples(examples).argv(process.argv, async (arg, opt) => {
|
|
25
25
|
const slug = await (0, _devEnvironmentCli.getEnvironmentName)(opt);
|
|
26
|
-
const lando = await (0, _devEnvironmentLando.bootstrapLando)(
|
|
26
|
+
const lando = await (0, _devEnvironmentLando.bootstrapLando)({
|
|
27
|
+
logFile: (0, _devEnvironmentCli.getDevEnvLogFile)(slug)
|
|
28
|
+
});
|
|
27
29
|
(0, _devEnvironmentCli.validateDependencies)(lando);
|
|
28
30
|
const trackingInfo = (0, _devEnvironmentCli.getEnvTrackingInfo)(slug);
|
|
29
31
|
await (0, _tracker.trackEvent)('dev_env_destroy_command_execute', trackingInfo);
|
|
@@ -25,7 +25,9 @@ const examples = [{
|
|
|
25
25
|
usage
|
|
26
26
|
}).option('slug', 'A unique name for a local environment. Default is "vip-local".', undefined, _devEnvironmentCli.processSlug).option('force', 'Skip validation for a local environment to be in a running state.', undefined, _devEnvironmentCli.processBooleanOption).option('quiet', 'Suppress informational messages.', undefined, _devEnvironmentCli.processBooleanOption).examples(examples).argv(process.argv, async (unmatchedArgs, opt) => {
|
|
27
27
|
const slug = await (0, _devEnvironmentCli.getEnvironmentName)(opt);
|
|
28
|
-
const lando = await (0, _devEnvironmentLando.bootstrapLando)(
|
|
28
|
+
const lando = await (0, _devEnvironmentLando.bootstrapLando)({
|
|
29
|
+
logFile: (0, _devEnvironmentCli.getDevEnvLogFile)(slug)
|
|
30
|
+
});
|
|
29
31
|
(0, _devEnvironmentCli.validateDependencies)(lando);
|
|
30
32
|
const trackingInfo = (0, _devEnvironmentCli.getEnvTrackingInfo)(slug);
|
|
31
33
|
await (0, _tracker.trackEvent)('dev_env_exec_command_execute', trackingInfo);
|
|
@@ -23,16 +23,18 @@ const examples = [{
|
|
|
23
23
|
}).option('slug', 'A unique name for a local environment. Default is "vip-local".', undefined, _devEnvironmentCli.processSlug).option('all', 'Retrieve information about all local environments.').option('extended', 'Deprecated, not used.').examples(examples).argv(process.argv, async (arg, opt) => {
|
|
24
24
|
let trackingInfo;
|
|
25
25
|
let slug;
|
|
26
|
-
const lando = await (0, _devEnvironmentLando.bootstrapLando)();
|
|
27
26
|
if (opt.all) {
|
|
28
27
|
trackingInfo = {
|
|
29
28
|
all: true
|
|
30
29
|
};
|
|
31
|
-
slug =
|
|
30
|
+
slug = undefined;
|
|
32
31
|
} else {
|
|
33
32
|
slug = await (0, _devEnvironmentCli.getEnvironmentName)(opt);
|
|
34
33
|
trackingInfo = (0, _devEnvironmentCli.getEnvTrackingInfo)(slug);
|
|
35
34
|
}
|
|
35
|
+
const lando = await (0, _devEnvironmentLando.bootstrapLando)({
|
|
36
|
+
logFile: (0, _devEnvironmentCli.getDevEnvLogFile)(slug)
|
|
37
|
+
});
|
|
36
38
|
(0, _devEnvironmentCli.validateDependencies)(lando);
|
|
37
39
|
await (0, _tracker.trackEvent)('dev_env_info_command_execute', trackingInfo);
|
|
38
40
|
debug('Args: ', arg, 'Options: ', opt);
|
|
@@ -16,7 +16,9 @@ const examples = [{
|
|
|
16
16
|
(0, _command.default)({
|
|
17
17
|
usage
|
|
18
18
|
}).examples(examples).argv(process.argv, async () => {
|
|
19
|
-
const lando = await (0, _devEnvironmentLando.bootstrapLando)(
|
|
19
|
+
const lando = await (0, _devEnvironmentLando.bootstrapLando)({
|
|
20
|
+
logFile: (0, _devEnvironmentCli.getDevEnvLogFile)()
|
|
21
|
+
});
|
|
20
22
|
lando.events.constructor.prototype.setMaxListeners(1024);
|
|
21
23
|
(0, _devEnvironmentCli.validateDependencies)(lando);
|
|
22
24
|
const trackingInfo = {
|
|
@@ -25,7 +25,9 @@ const examples = [{
|
|
|
25
25
|
usage
|
|
26
26
|
}).option('slug', 'A unique name for a local environment. Default is "vip-local".', undefined, _devEnvironmentCli.processSlug).option(['f', 'follow'], 'Continually output logs as they are generated.').option('service', 'Restrict to a single service.').examples(examples).argv(process.argv, async (arg, opt) => {
|
|
27
27
|
const slug = await (0, _devEnvironmentCli.getEnvironmentName)(opt);
|
|
28
|
-
const lando = await (0, _devEnvironmentLando.bootstrapLando)(
|
|
28
|
+
const lando = await (0, _devEnvironmentLando.bootstrapLando)({
|
|
29
|
+
logFile: (0, _devEnvironmentCli.getDevEnvLogFile)(slug)
|
|
30
|
+
});
|
|
29
31
|
(0, _devEnvironmentCli.validateDependencies)(lando);
|
|
30
32
|
const trackingInfo = (0, _devEnvironmentCli.getEnvTrackingInfo)(slug);
|
|
31
33
|
await (0, _tracker.trackEvent)('dev_env_logs_command_execute', trackingInfo);
|
|
@@ -34,7 +34,9 @@ const examples = [{
|
|
|
34
34
|
}).option('soft', 'Preserve an environment’s configuration files; allows an environment to be regenerated with the start command.').option('force', 'Skip confirmation.').examples(examples).argv(process.argv, async (arg, opt) => {
|
|
35
35
|
debug('Args: ', arg, 'Options: ', opt);
|
|
36
36
|
const allEnvNames = (0, _devEnvironmentCore.getAllEnvironmentNames)();
|
|
37
|
-
const lando = await (0, _devEnvironmentLando.bootstrapLando)(
|
|
37
|
+
const lando = await (0, _devEnvironmentLando.bootstrapLando)({
|
|
38
|
+
logFile: (0, _devEnvironmentCli.getDevEnvLogFile)()
|
|
39
|
+
});
|
|
38
40
|
if (allEnvNames.length === 0) {
|
|
39
41
|
console.log('No environments to purge!');
|
|
40
42
|
return;
|
|
@@ -57,7 +57,9 @@ function getCommand(args) {
|
|
|
57
57
|
usage
|
|
58
58
|
}).option('slug', 'A unique name for a local environment. Default is "vip-local".', undefined, _devEnvironmentCli.processSlug).option('root', 'Create with root privileges.').option('service', 'Restrict to a single service.').examples(examples).argv(process.argv, async (args, opt) => {
|
|
59
59
|
const slug = await (0, _devEnvironmentCli.getEnvironmentName)(opt);
|
|
60
|
-
const lando = await (0, _devEnvironmentLando.bootstrapLando)(
|
|
60
|
+
const lando = await (0, _devEnvironmentLando.bootstrapLando)({
|
|
61
|
+
logFile: (0, _devEnvironmentCli.getDevEnvLogFile)(slug)
|
|
62
|
+
});
|
|
61
63
|
(0, _devEnvironmentCli.validateDependencies)(lando);
|
|
62
64
|
const trackingInfo = (0, _devEnvironmentCli.getEnvTrackingInfo)(slug);
|
|
63
65
|
await (0, _tracker.trackEvent)('dev_env_shell_command_execute', trackingInfo);
|
|
@@ -34,7 +34,9 @@ const examples = [{
|
|
|
34
34
|
usage
|
|
35
35
|
}).option('slug', 'A unique name for a local environment. Default is "vip-local".', undefined, _devEnvironmentCli.processSlug).option('skip-rebuild', 'Only start services that are not in a running state.').option(['w', 'skip-wp-versions-check'], 'Skip the prompt to update WordPress; occurs if the last major release version is not configured.').option('vscode', 'Generate a Visual Studio Code Workspace file (deprecated, use --editor=vscode instead).').option('editor', 'Generate a workspace file for the specified editor (supports: vscode, cursor, windsurf, phpstorm).').examples(examples).argv(process.argv, async (arg, opt) => {
|
|
36
36
|
const slug = await (0, _devEnvironmentCli.getEnvironmentName)(opt);
|
|
37
|
-
const lando = await (0, _devEnvironmentLando.bootstrapLando)(
|
|
37
|
+
const lando = await (0, _devEnvironmentLando.bootstrapLando)({
|
|
38
|
+
logFile: (0, _devEnvironmentCli.getDevEnvLogFile)(slug)
|
|
39
|
+
});
|
|
38
40
|
(0, _devEnvironmentCli.validateDependencies)(lando);
|
|
39
41
|
const startProcessing = new Date();
|
|
40
42
|
const trackingInfo = (0, _devEnvironmentCli.getEnvTrackingInfo)(slug);
|
|
@@ -22,24 +22,30 @@ const examples = [{
|
|
|
22
22
|
(0, _command.default)({
|
|
23
23
|
usage
|
|
24
24
|
}).option('slug', 'A unique name for a local environment. Default is "vip-local".', undefined, _devEnvironmentCli.processSlug).option('all', 'Stop all local environments.').examples(examples).argv(process.argv, async (arg, opt) => {
|
|
25
|
-
const lando = await (0, _devEnvironmentLando.bootstrapLando)();
|
|
26
|
-
(0, _devEnvironmentCli.validateDependencies)(lando);
|
|
27
25
|
debug('Args: ', arg, 'Options: ', opt);
|
|
28
26
|
|
|
29
27
|
/** @type {Record< string, unknown >} */
|
|
30
28
|
let trackingInfo;
|
|
31
29
|
/** @type {string[]} */
|
|
32
30
|
let environments;
|
|
31
|
+
/** @type {string|undefined} */
|
|
32
|
+
let logSlug;
|
|
33
33
|
if (opt.all) {
|
|
34
34
|
trackingInfo = {
|
|
35
35
|
all: true
|
|
36
36
|
};
|
|
37
37
|
environments = (0, _devEnvironmentCore.getAllEnvironmentNames)();
|
|
38
|
+
logSlug = undefined;
|
|
38
39
|
} else {
|
|
39
40
|
const slug = await (0, _devEnvironmentCli.getEnvironmentName)(opt);
|
|
40
41
|
trackingInfo = (0, _devEnvironmentCli.getEnvTrackingInfo)(slug);
|
|
41
42
|
environments = [slug];
|
|
43
|
+
logSlug = slug;
|
|
42
44
|
}
|
|
45
|
+
const lando = await (0, _devEnvironmentLando.bootstrapLando)({
|
|
46
|
+
logFile: (0, _devEnvironmentCli.getDevEnvLogFile)(logSlug)
|
|
47
|
+
});
|
|
48
|
+
(0, _devEnvironmentCli.validateDependencies)(lando);
|
|
43
49
|
await (0, _tracker.trackEvent)('dev_env_stop_command_execute', trackingInfo);
|
|
44
50
|
for (const slug of environments) {
|
|
45
51
|
try {
|
|
@@ -70,7 +70,9 @@ const appQuery = `
|
|
|
70
70
|
multisite: env.isMultisite
|
|
71
71
|
});
|
|
72
72
|
await trackerFn('execute');
|
|
73
|
-
const lando = await (0, _devEnvironmentLando.bootstrapLando)(
|
|
73
|
+
const lando = await (0, _devEnvironmentLando.bootstrapLando)({
|
|
74
|
+
logFile: (0, _devEnvironmentCli.getDevEnvLogFile)(slug)
|
|
75
|
+
});
|
|
74
76
|
const isUp = (await Promise.all([(0, _devEnvironmentLando.isContainerRunning)(lando, slug, 'php'), (0, _devEnvironmentLando.isContainerRunning)(lando, slug, 'database')])).every(Boolean);
|
|
75
77
|
if (!isUp && !opt.force) {
|
|
76
78
|
await trackerFn('env_not_running_error', {
|
|
@@ -31,7 +31,9 @@ const cmd = (0, _command.default)({
|
|
|
31
31
|
cmd.examples(examples);
|
|
32
32
|
cmd.argv(process.argv, async (arg, opt) => {
|
|
33
33
|
const slug = await (0, _devEnvironmentCli.getEnvironmentName)(opt);
|
|
34
|
-
const lando = await (0, _devEnvironmentLando.bootstrapLando)(
|
|
34
|
+
const lando = await (0, _devEnvironmentLando.bootstrapLando)({
|
|
35
|
+
logFile: (0, _devEnvironmentCli.getDevEnvLogFile)(slug)
|
|
36
|
+
});
|
|
35
37
|
(0, _devEnvironmentCli.validateDependencies)(lando);
|
|
36
38
|
const trackingInfo = (0, _devEnvironmentCli.getEnvTrackingInfo)(slug);
|
|
37
39
|
await (0, _tracker.trackEvent)('dev_env_update_command_execute', trackingInfo);
|
|
@@ -131,6 +131,7 @@ Are you sure you want to import the contents of the URL?
|
|
|
131
131
|
sourceIsLocal = true;
|
|
132
132
|
const fileMeta = await (0, _clientFileUploader.getFileMeta)(fileNameOrURL);
|
|
133
133
|
fileMeta.fileName = fileNameOrURL;
|
|
134
|
+
let lastProgress = '';
|
|
134
135
|
const {
|
|
135
136
|
fileMeta: {
|
|
136
137
|
basename
|
|
@@ -141,8 +142,15 @@ Are you sure you want to import the contents of the URL?
|
|
|
141
142
|
app,
|
|
142
143
|
env,
|
|
143
144
|
fileMeta,
|
|
144
|
-
progressCallback: percentage =>
|
|
145
|
+
progressCallback: percentage => {
|
|
146
|
+
if (percentage === lastProgress) {
|
|
147
|
+
return;
|
|
148
|
+
}
|
|
149
|
+
lastProgress = percentage;
|
|
150
|
+
process.stdout.write(`\rUpload progress: ${percentage} `);
|
|
151
|
+
}
|
|
145
152
|
});
|
|
153
|
+
process.stdout.write('\n');
|
|
146
154
|
|
|
147
155
|
// small debug info to keep variables used
|
|
148
156
|
debug('Uploaded file basename:', basename);
|
|
@@ -24,7 +24,9 @@ class DevEnvImportSQLCommand {
|
|
|
24
24
|
this.slug = slug;
|
|
25
25
|
}
|
|
26
26
|
async run() {
|
|
27
|
-
const lando = await (0, _devEnvironmentLando.bootstrapLando)(
|
|
27
|
+
const lando = await (0, _devEnvironmentLando.bootstrapLando)({
|
|
28
|
+
logFile: (0, _devEnvironmentCli.getDevEnvLogFile)(this.slug)
|
|
29
|
+
});
|
|
28
30
|
(0, _devEnvironmentCli.validateDependencies)(lando);
|
|
29
31
|
(0, _sql.validateImportFileExtension)(this.fileName);
|
|
30
32
|
const dumpDetails = await (0, _database.getSqlDumpDetails)(this.fileName);
|
package/dist/lib/cli/command.js
CHANGED
|
@@ -440,30 +440,39 @@ _args.default.argv = async function (argv, cb) {
|
|
|
440
440
|
break;
|
|
441
441
|
}
|
|
442
442
|
case 'import-media':
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
443
|
+
{
|
|
444
|
+
const isUrl = this.sub && (String(this.sub).startsWith('http://') || String(this.sub).startsWith('https://'));
|
|
445
|
+
const archiveLabel = isUrl ? 'Archive URL' : 'Archive Path';
|
|
446
|
+
info.push({
|
|
447
|
+
key: archiveLabel,
|
|
448
|
+
value: _chalk.default.blue.underline(this.sub)
|
|
449
|
+
});
|
|
450
|
+
|
|
451
|
+
// Update confirmation message if it's a local path
|
|
452
|
+
if (!isUrl && 'string' === typeof _opts.requireConfirm) {
|
|
453
|
+
message = message.replaceAll('the URL', 'the path');
|
|
454
|
+
}
|
|
455
|
+
options.overwriteExistingFiles = Object.hasOwn(options, 'overwriteExistingFiles') && Boolean(options.overwriteExistingFiles) && !['false', 'no'].includes(options.overwriteExistingFiles);
|
|
456
|
+
info.push({
|
|
457
|
+
key: 'Overwrite any existing files',
|
|
458
|
+
value: options.overwriteExistingFiles ? '✅ Yes' : `${_chalk.default.red('x')} No`
|
|
459
|
+
});
|
|
460
|
+
options.importIntermediateImages = Object.hasOwn(options, 'importIntermediateImages') && Boolean(options.importIntermediateImages) && !['false', 'no'].includes(options.importIntermediateImages);
|
|
461
|
+
info.push({
|
|
462
|
+
key: 'Import intermediate image files',
|
|
463
|
+
value: options.importIntermediateImages ? '✅ Yes' : `${_chalk.default.red('x')} No`
|
|
464
|
+
});
|
|
465
|
+
options.exportFileErrorsToJson = Object.hasOwn(options, 'exportFileErrorsToJson') && Boolean(options.exportFileErrorsToJson) && !['false', 'no'].includes(options.exportFileErrorsToJson);
|
|
466
|
+
info.push({
|
|
467
|
+
key: 'Export any file errors encountered to a JSON file instead of a plain text file.',
|
|
468
|
+
value: options.exportFileErrorsToJson ? '✅ Yes' : `${_chalk.default.red('x')} No`
|
|
469
|
+
});
|
|
470
|
+
info.push({
|
|
471
|
+
key: 'Download file-error logs?',
|
|
472
|
+
value: options.saveErrorLog
|
|
473
|
+
});
|
|
474
|
+
break;
|
|
475
|
+
}
|
|
467
476
|
default:
|
|
468
477
|
}
|
|
469
478
|
const skipPrompt = _opts.skipConfirmPrompt || false;
|
|
@@ -4,6 +4,9 @@ exports.__esModule = true;
|
|
|
4
4
|
exports.DEFAULT_SLUG = exports.CONFIGURATION_FOLDER = void 0;
|
|
5
5
|
exports.addDevEnvConfigurationOptions = addDevEnvConfigurationOptions;
|
|
6
6
|
exports.ensureValidPathsInOptions = ensureValidPathsInOptions;
|
|
7
|
+
exports.formatDevEnvLogSlug = formatDevEnvLogSlug;
|
|
8
|
+
exports.formatDevEnvLogTimestamp = formatDevEnvLogTimestamp;
|
|
9
|
+
exports.getDevEnvLogFile = getDevEnvLogFile;
|
|
7
10
|
exports.getEnvTrackingInfo = getEnvTrackingInfo;
|
|
8
11
|
exports.getEnvironmentName = getEnvironmentName;
|
|
9
12
|
exports.getEnvironmentStartCommand = getEnvironmentStartCommand;
|
|
@@ -666,6 +669,16 @@ function processSlug(value) {
|
|
|
666
669
|
// eslint-disable-next-line @typescript-eslint/no-base-to-string
|
|
667
670
|
return (value ?? '').toString().toLowerCase();
|
|
668
671
|
}
|
|
672
|
+
function formatDevEnvLogTimestamp(date) {
|
|
673
|
+
return date.toISOString().replace(/\..*$/, '').replace(/[-:]/g, '').replace('T', '-');
|
|
674
|
+
}
|
|
675
|
+
function formatDevEnvLogSlug(slug) {
|
|
676
|
+
return slug.replace(/[^a-z0-9_-]+/gi, '-').toLowerCase();
|
|
677
|
+
}
|
|
678
|
+
function getDevEnvLogFile(slug) {
|
|
679
|
+
const slugPart = slug ? formatDevEnvLogSlug(slug) : 'all';
|
|
680
|
+
return `vip-dev-env-${slugPart}-${formatDevEnvLogTimestamp(new Date())}.log`;
|
|
681
|
+
}
|
|
669
682
|
function processVersionOption(value) {
|
|
670
683
|
if (typeof value === 'string' || typeof value === 'number') {
|
|
671
684
|
if (!isNaN(value) && Number(value) % 1 === 0) {
|
|
@@ -22,14 +22,17 @@ var _bootstrap = require("lando/lib/bootstrap");
|
|
|
22
22
|
var _lando = _interopRequireDefault(require("lando/lib/lando"));
|
|
23
23
|
var _utils = _interopRequireDefault(require("lando/plugins/lando-core/lib/utils"));
|
|
24
24
|
var _build = _interopRequireDefault(require("lando/plugins/lando-tooling/lib/build"));
|
|
25
|
+
var _nodeChild_process = require("node:child_process");
|
|
25
26
|
var _promises = require("node:dns/promises");
|
|
26
27
|
var _promises2 = require("node:fs/promises");
|
|
27
28
|
var _nodeOs = require("node:os");
|
|
28
29
|
var _nodePath = _interopRequireWildcard(require("node:path"));
|
|
30
|
+
var _nodeUtil = require("node:util");
|
|
29
31
|
var _semver = require("semver");
|
|
30
32
|
var _devEnvironmentCore = require("./dev-environment-core");
|
|
31
33
|
var _dockerUtils = require("./docker-utils");
|
|
32
34
|
var _devEnvironment = require("../constants/dev-environment");
|
|
35
|
+
var _env = _interopRequireDefault(require("../env"));
|
|
33
36
|
var _userError = _interopRequireDefault(require("../user-error"));
|
|
34
37
|
var _xdgData = require("../xdg-data");
|
|
35
38
|
function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
|
|
@@ -39,11 +42,117 @@ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e
|
|
|
39
42
|
*/
|
|
40
43
|
const DEBUG_KEY = '@automattic/vip:bin:dev-environment';
|
|
41
44
|
const debug = (0, _debug.default)(DEBUG_KEY);
|
|
45
|
+
const execFileAsync = (0, _nodeUtil.promisify)(_nodeChild_process.execFile);
|
|
46
|
+
const bannerLabelWidth = 18;
|
|
47
|
+
let logPathRegistered = false;
|
|
48
|
+
let resolvedLogPath = null;
|
|
49
|
+
const getLogFilePath = config => {
|
|
50
|
+
if (config.logFile) {
|
|
51
|
+
return _nodePath.default.isAbsolute(config.logFile) ? config.logFile : _nodePath.default.join(config.logDir ?? '', config.logFile);
|
|
52
|
+
}
|
|
53
|
+
if (config.logDir && config.logName) {
|
|
54
|
+
return _nodePath.default.join(config.logDir, `${config.logName}.log`);
|
|
55
|
+
}
|
|
56
|
+
return null;
|
|
57
|
+
};
|
|
58
|
+
const registerLogPathOutput = config => {
|
|
59
|
+
if (logPathRegistered) {
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
resolvedLogPath = getLogFilePath(config);
|
|
63
|
+
if (!resolvedLogPath) {
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
logPathRegistered = true;
|
|
67
|
+
process.once('exit', () => {
|
|
68
|
+
if (resolvedLogPath && process.stdout.isTTY) {
|
|
69
|
+
console.log(`\n ${formatBannerLine(_chalk.default.cyan('COMMAND LOG FILE'.padEnd(bannerLabelWidth)), resolvedLogPath)}`);
|
|
70
|
+
}
|
|
71
|
+
});
|
|
72
|
+
};
|
|
73
|
+
const formatBytes = bytes => {
|
|
74
|
+
const gb = bytes / 1024 ** 3;
|
|
75
|
+
return `${gb.toFixed(1)} GB`;
|
|
76
|
+
};
|
|
77
|
+
const isRecord = value => typeof value === 'object' && value !== null;
|
|
78
|
+
const isDockerPluginInfo = value => isRecord(value);
|
|
79
|
+
const getDockerVersions = async config => {
|
|
80
|
+
const dockerBin = config.dockerBin ?? '';
|
|
81
|
+
const composeBin = config.composeBin ?? '';
|
|
82
|
+
let engine = 'unknown';
|
|
83
|
+
let compose = 'unknown';
|
|
84
|
+
let composePlugin = 'unknown';
|
|
85
|
+
try {
|
|
86
|
+
if (dockerBin) {
|
|
87
|
+
const {
|
|
88
|
+
stdout
|
|
89
|
+
} = await execFileAsync(dockerBin, ['info', '--format', 'json']);
|
|
90
|
+
const dockerData = JSON.parse(stdout);
|
|
91
|
+
if (isRecord(dockerData)) {
|
|
92
|
+
const serverVersion = dockerData.ServerVersion;
|
|
93
|
+
if (typeof serverVersion === 'string') {
|
|
94
|
+
engine = serverVersion;
|
|
95
|
+
}
|
|
96
|
+
const clientInfo = dockerData.ClientInfo;
|
|
97
|
+
if (isRecord(clientInfo)) {
|
|
98
|
+
const plugins = clientInfo.Plugins;
|
|
99
|
+
if (Array.isArray(plugins)) {
|
|
100
|
+
const composePluginEntry = plugins.find(plugin => isDockerPluginInfo(plugin) && plugin.Name === 'compose');
|
|
101
|
+
if (composePluginEntry && typeof composePluginEntry.Version === 'string') {
|
|
102
|
+
composePlugin = composePluginEntry.Version;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
} catch (error) {
|
|
109
|
+
debug('Failed to read docker version info: %O', error);
|
|
110
|
+
}
|
|
111
|
+
try {
|
|
112
|
+
if (composeBin) {
|
|
113
|
+
const {
|
|
114
|
+
stdout
|
|
115
|
+
} = await execFileAsync(composeBin, ['version', '--short']);
|
|
116
|
+
compose = stdout.trim() || compose;
|
|
117
|
+
}
|
|
118
|
+
} catch (error) {
|
|
119
|
+
debug('Failed to read docker-compose version info: %O', error);
|
|
120
|
+
}
|
|
121
|
+
return {
|
|
122
|
+
engine,
|
|
123
|
+
compose,
|
|
124
|
+
composePlugin
|
|
125
|
+
};
|
|
126
|
+
};
|
|
127
|
+
const formatBannerLine = (label, value) => `${label.padEnd(bannerLabelWidth)} ${value}`;
|
|
128
|
+
const writeLogBanner = async config => {
|
|
129
|
+
const logFilePath = getLogFilePath(config);
|
|
130
|
+
if (!logFilePath) {
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
133
|
+
try {
|
|
134
|
+
const existing = await (0, _promises2.stat)(logFilePath);
|
|
135
|
+
if (existing.size > 0) {
|
|
136
|
+
return;
|
|
137
|
+
}
|
|
138
|
+
} catch {
|
|
139
|
+
// File does not exist yet.
|
|
140
|
+
}
|
|
141
|
+
await (0, _promises2.mkdir)(_nodePath.default.dirname(logFilePath), {
|
|
142
|
+
recursive: true
|
|
143
|
+
});
|
|
144
|
+
const dockerVersions = await getDockerVersions(config);
|
|
145
|
+
const command = process.argv.slice(1).join(' ');
|
|
146
|
+
const bannerLines = ['=== VIP Dev Env Log ===', formatBannerLine('COMMAND', command), formatBannerLine('OS', `${_env.default.os.name} ${_env.default.os.version} ${_env.default.os.arch}`), formatBannerLine('NODE', _env.default.node.version), formatBannerLine('VIP-CLI', _env.default.app.version), formatBannerLine('DOCKER ENGINE', dockerVersions.engine), formatBannerLine('DOCKER COMPOSE', dockerVersions.compose), formatBannerLine('COMPOSE PLUGIN', dockerVersions.composePlugin), formatBannerLine('DOCKER BIN', config.dockerBin ?? 'unknown'), formatBannerLine('COMPOSE BIN', config.composeBin ?? 'unknown'), formatBannerLine('RAM', formatBytes((0, _nodeOs.totalmem)())), formatBannerLine('CPU', String((0, _nodeOs.cpus)().length)), '===', '', ''];
|
|
147
|
+
await (0, _promises2.writeFile)(logFilePath, bannerLines.join('\n'), {
|
|
148
|
+
flag: 'a'
|
|
149
|
+
});
|
|
150
|
+
};
|
|
42
151
|
|
|
43
152
|
/**
|
|
44
153
|
* @return {Promise<LandoConfig>} Lando configuration
|
|
45
154
|
*/
|
|
46
|
-
async function getLandoConfig() {
|
|
155
|
+
async function getLandoConfig(options = {}) {
|
|
47
156
|
// The path will be smth like `yarn/global/node_modules/lando/lib/lando.js`; we need the path up to `lando` (inclusive)
|
|
48
157
|
const landoPath = (0, _nodePath.dirname)((0, _nodePath.dirname)(require.resolve('lando')));
|
|
49
158
|
debug(`Getting Lando config, using paths '${landoPath}' for plugins`);
|
|
@@ -60,6 +169,7 @@ async function getLandoConfig() {
|
|
|
60
169
|
const vipDir = _nodePath.default.join((0, _xdgData.xdgData)(), 'vip');
|
|
61
170
|
const landoDir = _nodePath.default.join(vipDir, 'lando');
|
|
62
171
|
const fakeHomeDir = _nodePath.default.join(landoDir, 'home');
|
|
172
|
+
const logDir = _nodePath.default.join(landoDir, 'logs');
|
|
63
173
|
try {
|
|
64
174
|
await (0, _promises2.mkdir)(fakeHomeDir, {
|
|
65
175
|
recursive: true
|
|
@@ -69,6 +179,9 @@ async function getLandoConfig() {
|
|
|
69
179
|
}
|
|
70
180
|
const config = {
|
|
71
181
|
logLevelConsole,
|
|
182
|
+
logDir,
|
|
183
|
+
logFile: options.logFile ?? 'vip-dev-env.log',
|
|
184
|
+
logName: options.logName ?? 'vip-dev-env',
|
|
72
185
|
configSources: [_nodePath.default.join(landoDir, 'config.yml')],
|
|
73
186
|
landoFile: '.lando.yml',
|
|
74
187
|
preLandoFiles: ['.lando.base.yml', '.lando.dist.yml', '.lando.upstream.yml'],
|
|
@@ -159,17 +272,25 @@ async function getLandoApplication(lando, instancePath) {
|
|
|
159
272
|
debug('getLandoApplication() took %d ms', duration);
|
|
160
273
|
}
|
|
161
274
|
}
|
|
162
|
-
async function bootstrapLando() {
|
|
275
|
+
async function bootstrapLando(options = {}) {
|
|
163
276
|
const started = new Date();
|
|
164
277
|
try {
|
|
278
|
+
if (process.env.DEBUG && !process.env.DEBUG.includes('-winston:*')) {
|
|
279
|
+
process.env.DEBUG = `${process.env.DEBUG},-winston:*`;
|
|
280
|
+
}
|
|
165
281
|
const socket = await (0, _dockerUtils.getDockerSocket)();
|
|
166
|
-
const config = await getLandoConfig();
|
|
282
|
+
const config = await getLandoConfig(options);
|
|
167
283
|
debug('Docker socket: %j', socket);
|
|
168
284
|
if (socket) {
|
|
169
285
|
config.engineConfig = await (0, _dockerUtils.getEngineConfig)(socket);
|
|
170
286
|
debug('Engine config: %j', config.engineConfig);
|
|
171
287
|
}
|
|
288
|
+
registerLogPathOutput(config);
|
|
289
|
+
await writeLogBanner(config);
|
|
172
290
|
const lando = new _lando.default(config);
|
|
291
|
+
_debug.default.log = (message, ...args) => {
|
|
292
|
+
lando.log.debug(message, ...args);
|
|
293
|
+
};
|
|
173
294
|
lando.events.once('pre-engine-build', async data => {
|
|
174
295
|
const instanceData = (0, _devEnvironmentCore.readEnvironmentData)(data.name);
|
|
175
296
|
let registryResolvable = false;
|