@automattic/vip 3.1.1-dev.1 → 3.3.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/assets/dev-env.lando.template.yml.ejs +6 -8
- package/dist/bin/vip-dev-env-create.js +2 -2
- package/dist/bin/vip-dev-env-stop.js +47 -11
- package/dist/bin/vip-dev-env-update.js +4 -4
- package/dist/bin/vip-slowlogs.js +13 -10
- package/dist/bin/vip.js +1 -1
- package/dist/lib/constants/dev-environment.js +5 -5
- package/dist/lib/dev-environment/dev-environment-cli.js +30 -13
- package/dist/lib/dev-environment/dev-environment-configuration-file.js +1 -1
- package/dist/lib/dev-environment/dev-environment-core.js +24 -18
- package/dist/lib/dev-environment/dev-environment-lando.js +3 -3
- package/docs/CHANGELOG.md +21 -0
- package/npm-shrinkwrap.json +1551 -1343
- package/package.json +6 -6
|
@@ -3,14 +3,14 @@ env_file:
|
|
|
3
3
|
- .env
|
|
4
4
|
proxy:
|
|
5
5
|
nginx:
|
|
6
|
-
- <%= siteSlug
|
|
6
|
+
- <%= siteSlug %>.<%= domain %>
|
|
7
7
|
<% if ( multisite ) { %>
|
|
8
|
-
- '*.<%= siteSlug
|
|
8
|
+
- '*.<%= siteSlug %>.<%= domain %>'
|
|
9
9
|
<% } %>
|
|
10
10
|
phpmyadmin:
|
|
11
|
-
- <%= siteSlug %>-pma
|
|
11
|
+
- <%= siteSlug %>-pma.<%= domain %>
|
|
12
12
|
mailpit:
|
|
13
|
-
- <%= siteSlug %>-mailpit
|
|
13
|
+
- <%= siteSlug %>-mailpit.<%= domain %>:8025
|
|
14
14
|
|
|
15
15
|
services:
|
|
16
16
|
devtools:
|
|
@@ -38,7 +38,6 @@ services:
|
|
|
38
38
|
image: ghcr.io/automattic/vip-container-images/nginx:latest
|
|
39
39
|
command: nginx -g "daemon off;"
|
|
40
40
|
environment:
|
|
41
|
-
LANDO_NO_SCRIPTS: 1
|
|
42
41
|
LANDO_NEEDS_EXEC: 1
|
|
43
42
|
volumes:
|
|
44
43
|
- ./nginx/extra.conf:/etc/nginx/conf.extra/extra.conf
|
|
@@ -79,9 +78,9 @@ services:
|
|
|
79
78
|
sh /dev-tools/setup.sh
|
|
80
79
|
--host database
|
|
81
80
|
--user root
|
|
82
|
-
--domain "http://<%= siteSlug
|
|
81
|
+
--domain "http://<%= siteSlug %>.<%= domain %>/"
|
|
83
82
|
--title "<%= wpTitle %>"
|
|
84
|
-
<% if ( multisite ) { %>--ms-domain "<%= siteSlug
|
|
83
|
+
<% if ( multisite ) { %>--ms-domain "<%= siteSlug %>.<%= domain %>" <% if ( multisite === true || multisite === 'subdomain' ) { %>--subdomain <% } %> <% } %>
|
|
85
84
|
database:
|
|
86
85
|
type: compose
|
|
87
86
|
services:
|
|
@@ -226,7 +225,6 @@ services:
|
|
|
226
225
|
- ":8025"
|
|
227
226
|
environment:
|
|
228
227
|
LANDO_NO_USER_PERMS: 1
|
|
229
|
-
LANDO_NO_SCRIPTS: 1
|
|
230
228
|
LANDO_NEEDS_EXEC: 1
|
|
231
229
|
<% } %>
|
|
232
230
|
|
|
@@ -84,10 +84,10 @@ cmd.argv(process.argv, async (arg, opt) => {
|
|
|
84
84
|
preselectedOptions = (0, _devEnvironmentConfigurationFile.mergeConfigurationFileOptions)(opt, configurationFileOptions);
|
|
85
85
|
suppressPrompts = true;
|
|
86
86
|
}
|
|
87
|
-
const instanceData = await (0, _devEnvironmentCli.promptForArguments)(preselectedOptions, defaultOptions, suppressPrompts);
|
|
87
|
+
const instanceData = await (0, _devEnvironmentCli.promptForArguments)(preselectedOptions, defaultOptions, suppressPrompts, true);
|
|
88
88
|
instanceData.siteSlug = slug;
|
|
89
89
|
try {
|
|
90
|
-
await (0, _devEnvironmentCore.createEnvironment)(instanceData);
|
|
90
|
+
await (0, _devEnvironmentCore.createEnvironment)(lando, instanceData);
|
|
91
91
|
await (0, _devEnvironmentCore.printEnvironmentInfo)(lando, slug, {
|
|
92
92
|
extended: false,
|
|
93
93
|
suppressWarnings: true
|
|
@@ -15,23 +15,59 @@ const usage = 'vip dev-env stop';
|
|
|
15
15
|
const examples = [{
|
|
16
16
|
usage: `${exampleUsage} --slug=example-site`,
|
|
17
17
|
description: 'Stop a local environment named "example-site".'
|
|
18
|
+
}, {
|
|
19
|
+
usage: `${exampleUsage} --all`,
|
|
20
|
+
description: 'Stops all local environments.'
|
|
18
21
|
}];
|
|
19
22
|
(0, _command.default)({
|
|
20
23
|
usage
|
|
21
|
-
}).option('slug', 'A unique name for a local environment. Default is "vip-local".', undefined, _devEnvironmentCli.processSlug).examples(examples).argv(process.argv, async (arg, opt) => {
|
|
22
|
-
const slug = await (0, _devEnvironmentCli.getEnvironmentName)(opt);
|
|
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) => {
|
|
23
25
|
const lando = await (0, _devEnvironmentLando.bootstrapLando)();
|
|
24
|
-
await (0, _devEnvironmentCli.validateDependencies)(lando,
|
|
26
|
+
await (0, _devEnvironmentCli.validateDependencies)(lando, '');
|
|
25
27
|
debug('Args: ', arg, 'Options: ', opt);
|
|
26
|
-
|
|
28
|
+
|
|
29
|
+
/** @type {Record< string, unknown >} */
|
|
30
|
+
let trackingInfo;
|
|
31
|
+
/** @type {string[]} */
|
|
32
|
+
let environments;
|
|
33
|
+
if (opt.all) {
|
|
34
|
+
trackingInfo = {
|
|
35
|
+
all: true
|
|
36
|
+
};
|
|
37
|
+
environments = (0, _devEnvironmentCore.getAllEnvironmentNames)();
|
|
38
|
+
} else {
|
|
39
|
+
const slug = await (0, _devEnvironmentCli.getEnvironmentName)(opt);
|
|
40
|
+
trackingInfo = (0, _devEnvironmentCli.getEnvTrackingInfo)(slug);
|
|
41
|
+
environments = [slug];
|
|
42
|
+
}
|
|
27
43
|
await (0, _tracker.trackEvent)('dev_env_stop_command_execute', trackingInfo);
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
44
|
+
for (const slug of environments) {
|
|
45
|
+
try {
|
|
46
|
+
// eslint-disable-next-line no-await-in-loop
|
|
47
|
+
await (0, _devEnvironmentCore.stopEnvironment)(lando, slug);
|
|
48
|
+
const message = _chalk.default.green('✓') + ` environment "${slug}" stopped.\n`;
|
|
49
|
+
console.log(message);
|
|
50
|
+
} catch (error) {
|
|
51
|
+
let err;
|
|
52
|
+
if (!(error instanceof Error)) {
|
|
53
|
+
err = new Error(error?.toString());
|
|
54
|
+
} else {
|
|
55
|
+
err = error;
|
|
56
|
+
}
|
|
57
|
+
process.exitCode = 1;
|
|
58
|
+
const errorTrackingInfo = {
|
|
59
|
+
...trackingInfo,
|
|
60
|
+
failure: err.message,
|
|
61
|
+
stack: err.stack
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
// trackEvent does not throw
|
|
65
|
+
// eslint-disable-next-line no-await-in-loop
|
|
66
|
+
await (0, _tracker.trackEvent)('dev_env_stop_command_error', errorTrackingInfo);
|
|
67
|
+
console.error(_chalk.default.red('Error:'), err.message.replace('ERROR: ', ''));
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
if (process.exitCode === 0) {
|
|
32
71
|
await (0, _tracker.trackEvent)('dev_env_stop_command_success', trackingInfo);
|
|
33
|
-
} catch (error) {
|
|
34
|
-
await (0, _devEnvironmentCli.handleCLIException)(error, 'dev_env_stop_command_error', trackingInfo);
|
|
35
|
-
process.exitCode = 1;
|
|
36
72
|
}
|
|
37
73
|
});
|
|
@@ -55,8 +55,8 @@ cmd.argv(process.argv, async (arg, opt) => {
|
|
|
55
55
|
|
|
56
56
|
/** @type {InstanceOptions} */
|
|
57
57
|
const defaultOptions = {
|
|
58
|
-
appCode: currentInstanceData.appCode.dir || currentInstanceData.appCode.tag || '
|
|
59
|
-
muPlugins: currentInstanceData.muPlugins.dir || currentInstanceData.muPlugins.tag || '
|
|
58
|
+
appCode: currentInstanceData.appCode.dir || currentInstanceData.appCode.tag || 'demo',
|
|
59
|
+
muPlugins: currentInstanceData.muPlugins.dir || currentInstanceData.muPlugins.tag || 'demo',
|
|
60
60
|
wordpress: currentInstanceData.wordpress.tag || 'trunk',
|
|
61
61
|
elasticsearch: currentInstanceData.elasticsearch,
|
|
62
62
|
php: currentInstanceData.php || _devEnvironment.DEV_ENVIRONMENT_PHP_VERSIONS[Object.keys(_devEnvironment.DEV_ENVIRONMENT_PHP_VERSIONS)[0]].image,
|
|
@@ -73,9 +73,9 @@ cmd.argv(process.argv, async (arg, opt) => {
|
|
|
73
73
|
.filter(option => !['debug', 'help', 'slug'].includes(option)); // Filter out options that are not related to instance configuration
|
|
74
74
|
|
|
75
75
|
const suppressPrompts = providedOptions.length > 0 || thereAreOptionsFromConfigFile;
|
|
76
|
-
const instanceData = await (0, _devEnvironmentCli.promptForArguments)(finalPreselectedOptions, defaultOptions, suppressPrompts);
|
|
76
|
+
const instanceData = await (0, _devEnvironmentCli.promptForArguments)(finalPreselectedOptions, defaultOptions, suppressPrompts, false);
|
|
77
77
|
instanceData.siteSlug = slug;
|
|
78
|
-
await (0, _devEnvironmentCore.updateEnvironment)(instanceData);
|
|
78
|
+
await (0, _devEnvironmentCore.updateEnvironment)(lando, instanceData);
|
|
79
79
|
const message = '\n' + _chalk.default.green('✓') + ' environment updated. Please start environment again for changes to take effect: ' + _chalk.default.bold(`vip dev-env --slug ${slug} start`);
|
|
80
80
|
console.log(message);
|
|
81
81
|
await (0, _tracker.trackEvent)('dev_env_update_command_success', trackingInfo);
|
package/dist/bin/vip-slowlogs.js
CHANGED
|
@@ -22,6 +22,8 @@ const ALLOWED_FORMATS = ['csv', 'json', 'table'];
|
|
|
22
22
|
const DEFAULT_POLLING_DELAY_IN_SECONDS = 30;
|
|
23
23
|
const MIN_POLLING_DELAY_IN_SECONDS = 5;
|
|
24
24
|
const MAX_POLLING_DELAY_IN_SECONDS = 300;
|
|
25
|
+
const exampleUsage = 'vip @example-app.develop slowlogs';
|
|
26
|
+
const baseUsage = 'vip slowlogs';
|
|
25
27
|
async function getSlowlogs(arg, opt) {
|
|
26
28
|
validateInputs(opt.limit, opt.format);
|
|
27
29
|
const trackingParams = getBaseTrackingParams(opt);
|
|
@@ -167,17 +169,18 @@ void (0, _command.default)({
|
|
|
167
169
|
appQuery,
|
|
168
170
|
envContext: true,
|
|
169
171
|
format: false,
|
|
170
|
-
module: 'slowlogs'
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
172
|
+
module: 'slowlogs',
|
|
173
|
+
usage: baseUsage
|
|
174
|
+
}).option('limit', 'The maximum number of log entries', 500).option('format', 'Output the log entries in CSV or JSON format', 'table').examples([{
|
|
175
|
+
description: 'Retrieve up to 500 of the most recent entries from the MySQL slow query logs in the default format.',
|
|
176
|
+
usage: exampleUsage
|
|
174
177
|
}, {
|
|
175
|
-
|
|
176
|
-
|
|
178
|
+
description: 'Retrieve up to 50 of the most recent entries from the MySQL slow query logs in the default format.',
|
|
179
|
+
usage: `${exampleUsage} --limit=50`
|
|
177
180
|
}, {
|
|
178
|
-
|
|
179
|
-
|
|
181
|
+
description: 'Retrieve up to 100 of the most recent entries from the MySQL slow query logs in CSV format.',
|
|
182
|
+
usage: `${exampleUsage} --limit=100 --format=csv`
|
|
180
183
|
}, {
|
|
181
|
-
|
|
182
|
-
|
|
184
|
+
description: 'Retrieve up to 100 of the most recent entries from the MySQL slow query logs in JSON format.',
|
|
185
|
+
usage: `${exampleUsage} --limit=100 --format=json`
|
|
183
186
|
}]).argv(process.argv, getSlowlogs);
|
package/dist/bin/vip.js
CHANGED
|
@@ -22,7 +22,7 @@ const tokenURL = 'https://dashboard.wpvip.com/me/cli/token';
|
|
|
22
22
|
const customDeployToken = process.env.WPVIP_DEPLOY_TOKEN;
|
|
23
23
|
const runCmd = async function () {
|
|
24
24
|
const cmd = (0, _command.default)();
|
|
25
|
-
cmd.command('logout', 'Log out the current authenticated VIP-CLI user.').command('app', 'List and modify your VIP applications').command('backup', 'Generate a backup of an environment.').command('cache', 'Manage page cache for your VIP applications').command('config', 'Manage environment configurations.').command('dev-env', 'Create and manage VIP Local Development Environments.').command('export', 'Export a copy of data associated with an environment.').command('import', 'Import media or SQL files into your VIP applications').command('logs', 'Get logs from your VIP applications').command('search-replace', 'Perform search and replace tasks on files').command('slowlogs', '
|
|
25
|
+
cmd.command('logout', 'Log out the current authenticated VIP-CLI user.').command('app', 'List and modify your VIP applications').command('backup', 'Generate a backup of an environment.').command('cache', 'Manage page cache for your VIP applications').command('config', 'Manage environment configurations.').command('dev-env', 'Create and manage VIP Local Development Environments.').command('export', 'Export a copy of data associated with an environment.').command('import', 'Import media or SQL files into your VIP applications').command('logs', 'Get logs from your VIP applications').command('search-replace', 'Perform search and replace tasks on files').command('slowlogs', 'Retrieve MySQL slow query logs from an environment.').command('db', "Access an environment's database.").command('sync', 'Sync production to a development environment').command('whoami', 'Retrieve details about the current authenticated VIP-CLI user.').command('validate', 'Validate your VIP application and environment').command('wp', 'Run WP CLI commands against an environment');
|
|
26
26
|
cmd.argv(process.argv);
|
|
27
27
|
};
|
|
28
28
|
|
|
@@ -4,11 +4,6 @@ exports.__esModule = true;
|
|
|
4
4
|
exports.DEV_ENVIRONMENT_WORDPRESS_VERSION_TTL = exports.DEV_ENVIRONMENT_WORDPRESS_VERSIONS_URI = exports.DEV_ENVIRONMENT_WORDPRESS_CACHE_KEY = exports.DEV_ENVIRONMENT_VERSION = exports.DEV_ENVIRONMENT_SUBCOMMAND = exports.DEV_ENVIRONMENT_RAW_GITHUB_HOST = exports.DEV_ENVIRONMENT_PROMPT_INTRO = exports.DEV_ENVIRONMENT_PHP_VERSIONS = exports.DEV_ENVIRONMENT_NOT_FOUND = exports.DEV_ENVIRONMENT_FULL_COMMAND = exports.DEV_ENVIRONMENT_DEFAULTS = exports.DEV_ENVIRONMENT_COMPONENTS_WITH_WP = exports.DEV_ENVIRONMENT_COMPONENTS = void 0;
|
|
5
5
|
const DEV_ENVIRONMENT_SUBCOMMAND = exports.DEV_ENVIRONMENT_SUBCOMMAND = 'dev-env';
|
|
6
6
|
const DEV_ENVIRONMENT_FULL_COMMAND = exports.DEV_ENVIRONMENT_FULL_COMMAND = `vip ${DEV_ENVIRONMENT_SUBCOMMAND}`;
|
|
7
|
-
const DEV_ENVIRONMENT_DEFAULTS = exports.DEV_ENVIRONMENT_DEFAULTS = {
|
|
8
|
-
title: 'VIP Dev',
|
|
9
|
-
multisite: false,
|
|
10
|
-
phpVersion: '8.0'
|
|
11
|
-
};
|
|
12
7
|
const DEV_ENVIRONMENT_PROMPT_INTRO = exports.DEV_ENVIRONMENT_PROMPT_INTRO = 'This is a wizard to help you set up your local dev environment.\n\n' + 'Sensible default values were pre-selected for convenience. ' + 'You may also choose to create multiple environments with different settings using the --slug option.\n\n';
|
|
13
8
|
const DEV_ENVIRONMENT_NOT_FOUND = exports.DEV_ENVIRONMENT_NOT_FOUND = 'Environment not found.';
|
|
14
9
|
const DEV_ENVIRONMENT_COMPONENTS = exports.DEV_ENVIRONMENT_COMPONENTS = ['muPlugins', 'appCode'];
|
|
@@ -32,4 +27,9 @@ const DEV_ENVIRONMENT_PHP_VERSIONS = exports.DEV_ENVIRONMENT_PHP_VERSIONS = {
|
|
|
32
27
|
label: '8.3'
|
|
33
28
|
}
|
|
34
29
|
};
|
|
30
|
+
const DEV_ENVIRONMENT_DEFAULTS = exports.DEV_ENVIRONMENT_DEFAULTS = {
|
|
31
|
+
title: 'VIP Dev',
|
|
32
|
+
multisite: false,
|
|
33
|
+
phpVersion: Object.keys(DEV_ENVIRONMENT_PHP_VERSIONS)[0]
|
|
34
|
+
};
|
|
35
35
|
const DEV_ENVIRONMENT_VERSION = exports.DEV_ENVIRONMENT_VERSION = '2.0.3';
|
|
@@ -13,6 +13,7 @@ exports.postStart = postStart;
|
|
|
13
13
|
exports.printTable = printTable;
|
|
14
14
|
exports.processBooleanOption = processBooleanOption;
|
|
15
15
|
exports.processComponentOptionInput = processComponentOptionInput;
|
|
16
|
+
exports.processMediaRedirectDomainOption = processMediaRedirectDomainOption;
|
|
16
17
|
exports.processSlug = processSlug;
|
|
17
18
|
exports.processStringOrBooleanOption = processStringOrBooleanOption;
|
|
18
19
|
exports.processVersionOption = processVersionOption;
|
|
@@ -213,7 +214,7 @@ function getOptionsFromAppInfo(appInfo) {
|
|
|
213
214
|
* @return {any} instance data
|
|
214
215
|
*/
|
|
215
216
|
// eslint-disable-next-line complexity
|
|
216
|
-
async function promptForArguments(preselectedOptions, defaultOptions, suppressPrompts
|
|
217
|
+
async function promptForArguments(preselectedOptions, defaultOptions, suppressPrompts, create) {
|
|
217
218
|
debug('Provided preselected', preselectedOptions, 'and default', defaultOptions);
|
|
218
219
|
if (suppressPrompts) {
|
|
219
220
|
preselectedOptions = {
|
|
@@ -257,7 +258,7 @@ async function promptForArguments(preselectedOptions, defaultOptions, suppressPr
|
|
|
257
258
|
mailpit: 'Mailpit',
|
|
258
259
|
photon: 'Photon'
|
|
259
260
|
};
|
|
260
|
-
if (!instanceData.mediaRedirectDomain && defaultOptions.mediaRedirectDomain) {
|
|
261
|
+
if (create && !instanceData.mediaRedirectDomain && defaultOptions.mediaRedirectDomain) {
|
|
261
262
|
const mediaRedirectPromptText = `Would you like to redirect to ${defaultOptions.mediaRedirectDomain} for missing media files?`;
|
|
262
263
|
const setMediaRedirectDomain = await promptForBoolean(mediaRedirectPromptText, true);
|
|
263
264
|
if (setMediaRedirectDomain) {
|
|
@@ -304,6 +305,16 @@ async function processWordPress(preselectedValue, defaultValue) {
|
|
|
304
305
|
} else {
|
|
305
306
|
result = await promptForWordPress(defaultObject);
|
|
306
307
|
}
|
|
308
|
+
const versions = await (0, _devEnvironmentCore.getVersionList)();
|
|
309
|
+
if (versions.length) {
|
|
310
|
+
versions.sort((before, after) => before.tag < after.tag ? 1 : -1);
|
|
311
|
+
const match = versions.find(({
|
|
312
|
+
tag
|
|
313
|
+
}) => tag === result.tag);
|
|
314
|
+
if (typeof match === 'undefined') {
|
|
315
|
+
throw new _userError.default(`Unknown or unsupported WordPress version: ${result.tag}.`);
|
|
316
|
+
}
|
|
317
|
+
}
|
|
307
318
|
debug(result);
|
|
308
319
|
return result;
|
|
309
320
|
}
|
|
@@ -444,24 +455,19 @@ function resolveMultisite(value) {
|
|
|
444
455
|
return isMultisiteOption(value) ? value : _devEnvironment.DEV_ENVIRONMENT_DEFAULTS.multisite;
|
|
445
456
|
}
|
|
446
457
|
function resolvePhpVersion(version) {
|
|
447
|
-
|
|
448
|
-
if (version
|
|
449
|
-
return
|
|
458
|
+
// It is painful to rewrite tests :-(
|
|
459
|
+
if (version === '') {
|
|
460
|
+
return '';
|
|
450
461
|
}
|
|
462
|
+
debug(`Resolving PHP version %j`, version);
|
|
451
463
|
let result;
|
|
452
464
|
if (!(version in _devEnvironment.DEV_ENVIRONMENT_PHP_VERSIONS)) {
|
|
453
465
|
const images = Object.values(_devEnvironment.DEV_ENVIRONMENT_PHP_VERSIONS);
|
|
454
466
|
const image = images.find(value => value.image === version);
|
|
455
467
|
if (image) {
|
|
456
468
|
result = image.image;
|
|
457
|
-
} else if (version.includes('/')) {
|
|
458
|
-
// Assuming this is a Docker image
|
|
459
|
-
// This can happen when we first called `vip dev-env update -P image:ghcr.io/...`
|
|
460
|
-
// and then called `vip dev-env update` again. The custom image won't match our images
|
|
461
|
-
// but we still want to use it.
|
|
462
|
-
result = version;
|
|
463
469
|
} else {
|
|
464
|
-
|
|
470
|
+
throw new _userError.default(`Unknown or unsupported PHP version: ${version}.`);
|
|
465
471
|
}
|
|
466
472
|
} else {
|
|
467
473
|
result = _devEnvironment.DEV_ENVIRONMENT_PHP_VERSIONS[version].image;
|
|
@@ -579,6 +585,17 @@ function processBooleanOption(value) {
|
|
|
579
585
|
// eslint-disable-next-line @typescript-eslint/no-base-to-string
|
|
580
586
|
return !FALSE_OPTIONS.includes(value.toString().toLowerCase()); // NOSONAR
|
|
581
587
|
}
|
|
588
|
+
function processMediaRedirectDomainOption(value) {
|
|
589
|
+
// eslint-disable-next-line @typescript-eslint/no-base-to-string
|
|
590
|
+
const val = (value ?? '').toString();
|
|
591
|
+
if (FALSE_OPTIONS.includes(val.toLowerCase())) {
|
|
592
|
+
return '';
|
|
593
|
+
}
|
|
594
|
+
if (TRUE_OPTIONS.includes(val.toLowerCase())) {
|
|
595
|
+
throw new _userError.default('Media redirect domain must be a domain name or an URL');
|
|
596
|
+
}
|
|
597
|
+
return val;
|
|
598
|
+
}
|
|
582
599
|
function processStringOrBooleanOption(value) {
|
|
583
600
|
if (typeof value === 'boolean') {
|
|
584
601
|
return value;
|
|
@@ -605,7 +622,7 @@ function processVersionOption(value) {
|
|
|
605
622
|
}
|
|
606
623
|
function addDevEnvConfigurationOptions(command) {
|
|
607
624
|
// We leave the third parameter to undefined on some because the defaults are handled in preProcessInstanceData()
|
|
608
|
-
return command.option('wordpress', 'Use a specific WordPress version', undefined, processVersionOption).option(['u', 'mu-plugins'], 'Use a specific mu-plugins changeset or local directory').option('app-code', 'Use the application code from a local directory or use "demo" for VIP skeleton code').option('phpmyadmin', 'Enable PHPMyAdmin component. By default it is disabled', undefined, processBooleanOption).option('xdebug', 'Enable XDebug. By default it is disabled', undefined, processBooleanOption).option('xdebug_config', 'Extra configuration to pass to xdebug via XDEBUG_CONFIG environment variable').option('elasticsearch', 'Enable Elasticsearch (needed by Enterprise Search)', undefined, processBooleanOption).option(['r', 'media-redirect-domain'], 'Domain to redirect for missing media files. This can be used to still have images without the need to import them locally.').option('php', 'Explicitly choose PHP version to use', undefined, processVersionOption).option(['A', 'mailpit'], 'Enable Mailpit. By default it is disabled', undefined, processBooleanOption).option(['H', 'photon'], 'Enable Photon. By default it is disabled', undefined, processBooleanOption);
|
|
625
|
+
return command.option('wordpress', 'Use a specific WordPress version', undefined, processVersionOption).option(['u', 'mu-plugins'], 'Use a specific mu-plugins changeset or local directory').option('app-code', 'Use the application code from a local directory or use "demo" for VIP skeleton code').option('phpmyadmin', 'Enable PHPMyAdmin component. By default it is disabled', undefined, processBooleanOption).option('xdebug', 'Enable XDebug. By default it is disabled', undefined, processBooleanOption).option('xdebug_config', 'Extra configuration to pass to xdebug via XDEBUG_CONFIG environment variable').option('elasticsearch', 'Enable Elasticsearch (needed by Enterprise Search)', undefined, processBooleanOption).option(['r', 'media-redirect-domain'], 'Domain to redirect for missing media files. This can be used to still have images without the need to import them locally.', undefined, processMediaRedirectDomainOption).option('php', 'Explicitly choose PHP version to use', undefined, processVersionOption).option(['A', 'mailpit'], 'Enable Mailpit. By default it is disabled', undefined, processBooleanOption).option(['H', 'photon'], 'Enable Photon. By default it is disabled', undefined, processBooleanOption);
|
|
609
626
|
}
|
|
610
627
|
|
|
611
628
|
/**
|
|
@@ -70,9 +70,9 @@ async function startEnvironment(lando, slug, options) {
|
|
|
70
70
|
}
|
|
71
71
|
let updated = false;
|
|
72
72
|
if (!options.skipWpVersionsCheck) {
|
|
73
|
-
updated = await maybeUpdateWordPressImage(slug);
|
|
73
|
+
updated = await maybeUpdateWordPressImage(lando, slug);
|
|
74
74
|
}
|
|
75
|
-
updated = updated || (await maybeUpdateVersion(slug));
|
|
75
|
+
updated = updated || (await maybeUpdateVersion(lando, slug));
|
|
76
76
|
if (options.skipRebuild && !updated) {
|
|
77
77
|
await (0, _devEnvironmentLando.landoStart)(lando, instancePath);
|
|
78
78
|
} else {
|
|
@@ -92,7 +92,7 @@ async function stopEnvironment(lando, slug) {
|
|
|
92
92
|
}
|
|
93
93
|
await (0, _devEnvironmentLando.landoStop)(lando, instancePath);
|
|
94
94
|
}
|
|
95
|
-
async function createEnvironment(instanceData) {
|
|
95
|
+
async function createEnvironment(lando, instanceData) {
|
|
96
96
|
const slug = instanceData.siteSlug;
|
|
97
97
|
debug('Will process an environment', slug, 'with instanceData for creation: ', instanceData);
|
|
98
98
|
const instancePath = getEnvironmentPath(slug);
|
|
@@ -103,9 +103,9 @@ async function createEnvironment(instanceData) {
|
|
|
103
103
|
}
|
|
104
104
|
const preProcessedInstanceData = preProcessInstanceData(instanceData);
|
|
105
105
|
debug('Will create an environment', slug, 'with instanceData: ', preProcessedInstanceData);
|
|
106
|
-
await prepareLandoEnv(preProcessedInstanceData, instancePath);
|
|
106
|
+
await prepareLandoEnv(lando, preProcessedInstanceData, instancePath);
|
|
107
107
|
}
|
|
108
|
-
async function updateEnvironment(instanceData) {
|
|
108
|
+
async function updateEnvironment(lando, instanceData) {
|
|
109
109
|
const slug = instanceData.siteSlug;
|
|
110
110
|
debug('Will process an environment', slug, 'with instanceData for updating: ', instanceData);
|
|
111
111
|
const instancePath = getEnvironmentPath(slug);
|
|
@@ -116,7 +116,7 @@ async function updateEnvironment(instanceData) {
|
|
|
116
116
|
}
|
|
117
117
|
const preProcessedInstanceData = preProcessInstanceData(instanceData);
|
|
118
118
|
debug('Will create an environment', slug, 'with instanceData: ', preProcessedInstanceData);
|
|
119
|
-
await prepareLandoEnv(preProcessedInstanceData, instancePath);
|
|
119
|
+
await prepareLandoEnv(lando, preProcessedInstanceData, instancePath);
|
|
120
120
|
}
|
|
121
121
|
function preProcessInstanceData(instanceData) {
|
|
122
122
|
const newInstanceData = {
|
|
@@ -131,9 +131,6 @@ function preProcessInstanceData(instanceData) {
|
|
|
131
131
|
newInstanceData.elasticsearch = instanceData.elasticsearch || false; // NOSONAR
|
|
132
132
|
|
|
133
133
|
newInstanceData.php = instanceData.php || _devEnvironment.DEV_ENVIRONMENT_PHP_VERSIONS[Object.keys(_devEnvironment.DEV_ENVIRONMENT_PHP_VERSIONS)[0]].image;
|
|
134
|
-
if (newInstanceData.php.startsWith('image:')) {
|
|
135
|
-
newInstanceData.php = newInstanceData.php.slice('image:'.length);
|
|
136
|
-
}
|
|
137
134
|
|
|
138
135
|
// FIXME: isNaN supports only number in TypeScript, actually, because isNaN('123') returns false despite being a string
|
|
139
136
|
if (isNaN(instanceData.wordpress.tag)) {
|
|
@@ -211,7 +208,7 @@ function parseComponentForInfo(component) {
|
|
|
211
208
|
}
|
|
212
209
|
|
|
213
210
|
// Environments created by the old code will have `component.tag` set to `demo` instead of `undefined`.
|
|
214
|
-
if (component.tag === 'demo') {
|
|
211
|
+
if (component.tag === 'demo' || component.tag === 'latest') {
|
|
215
212
|
component.tag = undefined;
|
|
216
213
|
}
|
|
217
214
|
return component.tag ?? '[demo-image]';
|
|
@@ -245,6 +242,11 @@ async function printEnvironmentInfo(lando, slug, options) {
|
|
|
245
242
|
appInfo.title = environmentData.wpTitle;
|
|
246
243
|
appInfo.multisite = Boolean(environmentData.multisite);
|
|
247
244
|
appInfo.php = environmentData.php.split(':')[1];
|
|
245
|
+
let xdebug = environmentData.xdebug ? 'enabled' : 'disabled';
|
|
246
|
+
if (environmentData.xdebug && environmentData.xdebugConfig) {
|
|
247
|
+
xdebug += ' (with additional configuration)';
|
|
248
|
+
}
|
|
249
|
+
appInfo.xdebug = xdebug;
|
|
248
250
|
appInfo.wordpress = parseComponentForInfo(environmentData.wordpress);
|
|
249
251
|
appInfo['Mu plugins'] = parseComponentForInfo(environmentData.muPlugins);
|
|
250
252
|
appInfo['App Code'] = parseComponentForInfo(environmentData.appCode);
|
|
@@ -327,9 +329,13 @@ function writeEnvironmentData(slug, data) {
|
|
|
327
329
|
const instanceDataTargetPath = _nodePath.default.join(instancePath, instanceDataFileName);
|
|
328
330
|
return _nodeFs.default.promises.writeFile(instanceDataTargetPath, JSON.stringify(data, null, 2));
|
|
329
331
|
}
|
|
330
|
-
async function prepareLandoEnv(instanceData, instancePath) {
|
|
331
|
-
const
|
|
332
|
-
|
|
332
|
+
async function prepareLandoEnv(lando, instanceData, instancePath) {
|
|
333
|
+
const templateData = {
|
|
334
|
+
...instanceData,
|
|
335
|
+
domain: lando.config.domain
|
|
336
|
+
};
|
|
337
|
+
const landoFile = await _ejs.default.renderFile(landoFileTemplatePath, templateData);
|
|
338
|
+
const nginxFile = await _ejs.default.renderFile(nginxFileTemplatePath, templateData);
|
|
333
339
|
const instanceDataFile = JSON.stringify(instanceData);
|
|
334
340
|
const landoFileTargetPath = _nodePath.default.join(instancePath, landoFileName);
|
|
335
341
|
const landoBackupFileTargetPath = _nodePath.default.join(instancePath, landoBackupFileName);
|
|
@@ -507,7 +513,7 @@ async function importMediaPath(slug, filePath) {
|
|
|
507
513
|
* @param {string} slug slug
|
|
508
514
|
* @return {boolean} boolean
|
|
509
515
|
*/
|
|
510
|
-
async function maybeUpdateWordPressImage(slug) {
|
|
516
|
+
async function maybeUpdateWordPressImage(lando, slug) {
|
|
511
517
|
const versions = await getVersionList();
|
|
512
518
|
if (!versions.length) {
|
|
513
519
|
return false;
|
|
@@ -588,7 +594,7 @@ async function maybeUpdateWordPressImage(slug) {
|
|
|
588
594
|
// FIXME: version?.tag is possibly null. Should we throw if we can't find a version somehow?
|
|
589
595
|
envData.wordpress.tag = version?.tag ?? '';
|
|
590
596
|
envData.wordpress.ref = version?.ref;
|
|
591
|
-
await updateEnvironment(envData);
|
|
597
|
+
await updateEnvironment(lando, envData);
|
|
592
598
|
return true;
|
|
593
599
|
}
|
|
594
600
|
if (confirm.upgrade === "no (don't ask anymore)") {
|
|
@@ -596,16 +602,16 @@ async function maybeUpdateWordPressImage(slug) {
|
|
|
596
602
|
envData.wordpress.doNotUpgrade = true;
|
|
597
603
|
console.log("We won't ask about upgrading this environment anymore.");
|
|
598
604
|
console.log(`To manually upgrade please run: ${_chalk.default.yellow(updateCommand)}`);
|
|
599
|
-
await updateEnvironment(envData);
|
|
605
|
+
await updateEnvironment(lando, envData);
|
|
600
606
|
}
|
|
601
607
|
return false;
|
|
602
608
|
}
|
|
603
|
-
async function maybeUpdateVersion(slug) {
|
|
609
|
+
async function maybeUpdateVersion(lando, slug) {
|
|
604
610
|
const envData = readEnvironmentData(slug);
|
|
605
611
|
const currentVersion = envData.version;
|
|
606
612
|
console.log('Current local environment version is: ' + _chalk.default.yellow(currentVersion));
|
|
607
613
|
if (!currentVersion || _semver.default.lt(currentVersion, _devEnvironment.DEV_ENVIRONMENT_VERSION)) {
|
|
608
|
-
await updateEnvironment(envData);
|
|
614
|
+
await updateEnvironment(lando, envData);
|
|
609
615
|
console.log('Local environment version updated to: ' + _chalk.default.green(_devEnvironment.DEV_ENVIRONMENT_VERSION));
|
|
610
616
|
return true;
|
|
611
617
|
}
|
|
@@ -106,7 +106,7 @@ async function initLandoApplication(lando, instancePath) {
|
|
|
106
106
|
await app.init();
|
|
107
107
|
return app;
|
|
108
108
|
}
|
|
109
|
-
async function regenerateLandofile(instancePath) {
|
|
109
|
+
async function regenerateLandofile(lando, instancePath) {
|
|
110
110
|
const landoFile = _nodePath.default.join(instancePath, '.lando.yml');
|
|
111
111
|
try {
|
|
112
112
|
const now = new Date().toISOString().replace(/[^\d]/g, '').slice(0, -3);
|
|
@@ -119,13 +119,13 @@ async function regenerateLandofile(instancePath) {
|
|
|
119
119
|
const slug = _nodePath.default.basename(instancePath);
|
|
120
120
|
const currentInstanceData = (0, _devEnvironmentCore.readEnvironmentData)(slug);
|
|
121
121
|
currentInstanceData.pullAfter = 0;
|
|
122
|
-
await (0, _devEnvironmentCore.updateEnvironment)(currentInstanceData);
|
|
122
|
+
await (0, _devEnvironmentCore.updateEnvironment)(lando, currentInstanceData);
|
|
123
123
|
}
|
|
124
124
|
async function landoRecovery(lando, instancePath, error) {
|
|
125
125
|
debug('Error initializing Lando app', error);
|
|
126
126
|
console.warn(_chalk.default.yellow('There was an error initializing Lando, trying to recover...'));
|
|
127
127
|
try {
|
|
128
|
-
await regenerateLandofile(instancePath);
|
|
128
|
+
await regenerateLandofile(lando, instancePath);
|
|
129
129
|
} catch (err) {
|
|
130
130
|
console.error(`${_chalk.default.bold.red('Recovery failed, aborting.')} Please recreate the environment or contact support.`);
|
|
131
131
|
throw err;
|
package/docs/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,26 @@
|
|
|
1
1
|
## Changelog
|
|
2
2
|
|
|
3
|
+
### 3.3.0
|
|
4
|
+
|
|
5
|
+
* fix(dev-env): make sure wildcard subdomains work with SSL/TLS
|
|
6
|
+
* feat(dev-env): add XDebug information to `vip dev-env info --extended`
|
|
7
|
+
|
|
8
|
+
**Full Changelog**: https://github.com/Automattic/vip-cli/compare/3.2.0...3.3.0
|
|
9
|
+
|
|
10
|
+
### 3.2.0
|
|
11
|
+
|
|
12
|
+
* feat(dev-env): make `domain` configurable
|
|
13
|
+
* build(deps): bump actions/dependency-review-action from 4.3.2 to 4.3.3
|
|
14
|
+
* build(deps-dev): bump the babel group with 4 updates
|
|
15
|
+
* Update the slowlogs command to follow the VIP-CLI styleguide
|
|
16
|
+
* feat(dev-env): add `--all` to `vip dev-env stop`
|
|
17
|
+
* chore: update lando to 77dad3a
|
|
18
|
+
* fix: CVE-2024-29415 in `socks`
|
|
19
|
+
* fix(dev-env): allow for unsetting media redirect domain
|
|
20
|
+
* fix(dev-env): validate version values
|
|
21
|
+
|
|
22
|
+
**Full Changelog**: https://github.com/Automattic/vip-cli/compare/3.1.0...3.2.0
|
|
23
|
+
|
|
3
24
|
### 3.1.0
|
|
4
25
|
|
|
5
26
|
* Integrate Media Import v2 flow and expand on media import error report messaging
|