@automattic/vip 3.17.1 → 3.19.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 +1 -1
- package/dist/bin/vip-config-envvar-delete.js +1 -0
- package/dist/bin/vip-config-envvar-get-all.js +2 -1
- package/dist/bin/vip-config-envvar-get.js +1 -0
- package/dist/bin/vip-config-envvar-list.js +2 -1
- package/dist/bin/vip-config-envvar-set.js +1 -0
- package/dist/bin/vip-dev-env-envvar-delete.js +55 -0
- package/dist/bin/vip-dev-env-envvar-get-all.js +51 -0
- package/dist/bin/vip-dev-env-envvar-get.js +43 -0
- package/dist/bin/vip-dev-env-envvar-list.js +46 -0
- package/dist/bin/vip-dev-env-envvar-set.js +78 -0
- package/dist/bin/vip-dev-env-envvar.js +27 -0
- package/dist/bin/vip-dev-env.js +1 -1
- package/dist/bin/vip-import-media.js +1 -1
- package/dist/bin/vip-import-sql.js +5 -20
- package/dist/bin/vip-logs.js +1 -0
- package/dist/bin/vip-slowlogs.js +1 -0
- package/dist/bin/vip.js +1 -1
- package/dist/commands/backup-db.js +2 -5
- package/dist/commands/dev-env-sync-sql.js +13 -4
- package/dist/commands/phpmyadmin.js +2 -5
- package/dist/commands/wp-ssh.js +3 -5
- package/dist/lib/analytics/clients/pendo.js +3 -1
- package/dist/lib/analytics/clients/tracks.js +0 -1
- package/dist/lib/analytics/index.js +0 -1
- package/dist/lib/api/http.js +2 -0
- package/dist/lib/api/user.js +1 -0
- package/dist/lib/backup-storage-availability/backup-storage-availability.js +0 -1
- package/dist/lib/cli/format.js +1 -22
- package/dist/lib/custom-deploy/custom-deploy.js +2 -2
- package/dist/lib/database.js +6 -6
- package/dist/lib/dev-environment/dev-environment-cli.js +7 -5
- package/dist/lib/dev-environment/dev-environment-core.js +9 -4
- package/dist/lib/dev-environment/dev-environment-database.js +4 -0
- package/dist/lib/dev-environment/dev-environment-lando.js +37 -17
- package/dist/lib/dev-environment/env-vars.js +75 -0
- package/dist/lib/keychain/insecure.js +0 -1
- package/dist/lib/media-import/config.js +1 -1
- package/dist/lib/site-import/status.js +2 -7
- package/dist/lib/validations/is-multisite-domain-mapped.js +3 -2
- package/dist/lib/validations/line-by-line.js +1 -1
- package/docs/CHANGELOG.md +55 -0
- package/npm-shrinkwrap.json +3623 -3854
- package/package.json +18 -15
- package/dist/bin/vip-validate-preflight.js +0 -481
- package/dist/bin/vip-validate.js +0 -11
package/dist/lib/api/http.js
CHANGED
|
@@ -29,6 +29,8 @@ var _default = async (path, options = {}) => {
|
|
|
29
29
|
url = `${_api.API_HOST}${path}`;
|
|
30
30
|
}
|
|
31
31
|
const authToken = await _token.default.get();
|
|
32
|
+
|
|
33
|
+
// TODO: remove this cast once the typings are fixed
|
|
32
34
|
const proxyAgent = (0, _proxyAgent.createProxyAgent)(url);
|
|
33
35
|
debug('running fetch', url);
|
|
34
36
|
return (0, _nodeFetch.default)(url, {
|
package/dist/lib/api/user.js
CHANGED
|
@@ -13,7 +13,6 @@ var _format = require("../cli/format");
|
|
|
13
13
|
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
14
14
|
const oneGiBInBytes = 1024 * 1024 * 1024;
|
|
15
15
|
class BackupStorageAvailability {
|
|
16
|
-
archiveSize;
|
|
17
16
|
constructor(archiveSize) {
|
|
18
17
|
this.archiveSize = archiveSize;
|
|
19
18
|
}
|
package/dist/lib/cli/format.js
CHANGED
|
@@ -10,8 +10,6 @@ exports.formatEnvironment = formatEnvironment;
|
|
|
10
10
|
exports.formatMetricBytes = void 0;
|
|
11
11
|
exports.formatSearchReplaceValues = formatSearchReplaceValues;
|
|
12
12
|
exports.getGlyphForStatus = getGlyphForStatus;
|
|
13
|
-
exports.isJson = isJson;
|
|
14
|
-
exports.isJsonObject = isJsonObject;
|
|
15
13
|
exports.keyValue = keyValue;
|
|
16
14
|
exports.requoteArgs = requoteArgs;
|
|
17
15
|
exports.table = table;
|
|
@@ -108,26 +106,7 @@ function keyValue(values) {
|
|
|
108
106
|
return lines.join('\n');
|
|
109
107
|
}
|
|
110
108
|
function requoteArgs(args) {
|
|
111
|
-
return args.map(arg => {
|
|
112
|
-
if (arg.includes('--') && arg.includes('=') && arg.includes(' ')) {
|
|
113
|
-
return arg.replace(/"/g, '\\"').replace(/^--([^=]*)=(.*)$/, '--$1="$2"');
|
|
114
|
-
}
|
|
115
|
-
if (arg.includes(' ') && !isJsonObject(arg)) {
|
|
116
|
-
return `"${arg.replace(/"/g, '\\"')}"`;
|
|
117
|
-
}
|
|
118
|
-
return arg;
|
|
119
|
-
});
|
|
120
|
-
}
|
|
121
|
-
function isJsonObject(str) {
|
|
122
|
-
return typeof str === 'string' && str.trim().startsWith('{') && isJson(str);
|
|
123
|
-
}
|
|
124
|
-
function isJson(str) {
|
|
125
|
-
try {
|
|
126
|
-
JSON.parse(str);
|
|
127
|
-
return true;
|
|
128
|
-
} catch (error) {
|
|
129
|
-
return false;
|
|
130
|
-
}
|
|
109
|
+
return args.map(arg => `"${arg.replace(/"/g, '\\"')}"`);
|
|
131
110
|
}
|
|
132
111
|
function capitalize(str) {
|
|
133
112
|
if (typeof str !== 'string' || !str.length) {
|
|
@@ -48,7 +48,7 @@ async function validateCustomDeployKey(app, env) {
|
|
|
48
48
|
throw new Error('Not found');
|
|
49
49
|
}
|
|
50
50
|
return result.data?.validateCustomDeployAccess;
|
|
51
|
-
} catch
|
|
51
|
+
} catch {
|
|
52
52
|
exit.withError(`Unauthorized: Invalid or non-existent custom deploy key for environment.`);
|
|
53
53
|
}
|
|
54
54
|
}
|
|
@@ -93,7 +93,7 @@ async function validateFile(appId, envId, fileMeta) {
|
|
|
93
93
|
}
|
|
94
94
|
try {
|
|
95
95
|
await (0, _clientFileUploader.checkFileAccess)(fileName);
|
|
96
|
-
} catch
|
|
96
|
+
} catch {
|
|
97
97
|
await track('deploy_app_command_error', {
|
|
98
98
|
error_type: 'appfile-unreadable'
|
|
99
99
|
});
|
package/dist/lib/database.js
CHANGED
|
@@ -28,15 +28,15 @@ const getSqlDumpDetails = async filePath => {
|
|
|
28
28
|
crlfDelay: Infinity
|
|
29
29
|
});
|
|
30
30
|
let isMyDumper = false;
|
|
31
|
-
let sourceDB
|
|
31
|
+
let sourceDB;
|
|
32
32
|
let currentLineNumber = 0;
|
|
33
33
|
for await (const line of readLine) {
|
|
34
34
|
if (line === '') {
|
|
35
35
|
continue;
|
|
36
36
|
}
|
|
37
|
-
const metadataMatch =
|
|
38
|
-
const sourceDBMatch =
|
|
39
|
-
const sourceDBName = sourceDBMatch[1];
|
|
37
|
+
const metadataMatch = /^-- metadata.header /.exec(line);
|
|
38
|
+
const sourceDBMatch = /^-- (.*)-schema-create.sql/.exec(line);
|
|
39
|
+
const sourceDBName = sourceDBMatch?.[1];
|
|
40
40
|
if (metadataMatch && !isMyDumper) {
|
|
41
41
|
isMyDumper = true;
|
|
42
42
|
}
|
|
@@ -87,13 +87,13 @@ const getSqlFileStreamFromCompressedFile = async filePath => {
|
|
|
87
87
|
throw new Error('Not a supported compressed file');
|
|
88
88
|
};
|
|
89
89
|
const fixMyDumperTransform = () => {
|
|
90
|
+
const regex = /^-- ([^ ]+) \d+$/;
|
|
90
91
|
return new _nodeStream.Transform({
|
|
91
92
|
transform(chunk, _encoding, callback) {
|
|
92
93
|
const chunkString = chunk.toString();
|
|
93
94
|
const lineEnding = chunkString.includes('\r\n') ? '\r\n' : '\n';
|
|
94
|
-
const regex = /^-- ([^ ]+) [0-9]+$/;
|
|
95
95
|
const lines = chunk.toString().split(lineEnding).map(line => {
|
|
96
|
-
const match =
|
|
96
|
+
const match = regex.exec(line);
|
|
97
97
|
if (!match) {
|
|
98
98
|
return line;
|
|
99
99
|
}
|
|
@@ -252,7 +252,7 @@ async function promptForArguments(preselectedOptions, defaultOptions, suppressPr
|
|
|
252
252
|
if (setMediaRedirectDomain) {
|
|
253
253
|
instanceData.mediaRedirectDomain = defaultOptions.mediaRedirectDomain;
|
|
254
254
|
}
|
|
255
|
-
} else if (!create && defaultOptions.mediaRedirectDomain) {
|
|
255
|
+
} else if (!create && defaultOptions.mediaRedirectDomain && !preselectedOptions.mediaRedirectDomain) {
|
|
256
256
|
const mediaRedirectPromptText = 'URL to redirect for missing media files ("n" to disable)?';
|
|
257
257
|
const mediaRedirectDomain = await promptForURL(mediaRedirectPromptText, defaultOptions.mediaRedirectDomain);
|
|
258
258
|
instanceData.mediaRedirectDomain = mediaRedirectDomain;
|
|
@@ -300,11 +300,13 @@ async function processWordPress(preselectedValue, defaultValue) {
|
|
|
300
300
|
if (versions.length) {
|
|
301
301
|
versions.sort((before, after) => before.tag < after.tag ? 1 : -1);
|
|
302
302
|
const match = versions.find(({
|
|
303
|
+
prerelease,
|
|
303
304
|
tag
|
|
304
|
-
}) => tag === result.tag);
|
|
305
|
-
if (
|
|
305
|
+
}) => result.tag === 'latest' ? !prerelease : tag === result.tag);
|
|
306
|
+
if (match === undefined) {
|
|
306
307
|
throw new _userError.default(`Unknown or unsupported WordPress version: ${result.tag}.`);
|
|
307
308
|
}
|
|
309
|
+
result.tag = match.tag;
|
|
308
310
|
}
|
|
309
311
|
debug(result);
|
|
310
312
|
return result;
|
|
@@ -677,7 +679,7 @@ function processVersionOption(value) {
|
|
|
677
679
|
const phpVersionsSupported = Object.keys(_devEnvironment.DEV_ENVIRONMENT_PHP_VERSIONS).join(', ');
|
|
678
680
|
function addDevEnvConfigurationOptions(command) {
|
|
679
681
|
// We leave the third parameter to undefined on some because the defaults are handled in preProcessInstanceData()
|
|
680
|
-
return command.option('wordpress', 'Manage the version of WordPress. Accepts a string value for major versions (6.x). Defaults to the
|
|
682
|
+
return command.option('wordpress', 'Manage the version of WordPress. Accepts a string value for major versions (6.x) or "latest". Defaults to the recommended version of WordPress for development.', undefined, processVersionOption).option(['u', 'mu-plugins'], 'Manage the source for VIP MU plugins. Accepts "demo" (default) for a read-only image of the staging branch, or a path to a built copy of VIP MU plugins on the local machine.').option('app-code', 'Manage the source for application code. Accepts "demo" (default) for a read-only image of WordPress VIP skeleton application code, or a path to a VIP formatted application repo on the local machine.').option('phpmyadmin', 'Enable or disable phpMyAdmin, disabled by default. Accepts "y" (default value) to enable or "n" to disable. When enabled, refer to the value of "PHPMYADMIN URLS" in the information output for a local environment for the URL to access phpMyAdmin.', undefined, processBooleanOption).option('xdebug', 'Enable or disable XDebug, disabled by default. Accepts "y" (default value) to enable or "n" to disable.', undefined, processBooleanOption).option('xdebug_config', 'Override some default configuration settings for Xdebug. Accepts a string value that is assigned to the XDEBUG_CONFIG environment variable.').option('elasticsearch', 'Enable or disable Elasticsearch (required by Enterprise Search), disabled by default. Accepts "y" (default value) to enable or "n" to disable.', undefined, processBooleanOption).option(['r', 'media-redirect-domain'], 'Configure media files to be proxied from a VIP Platform environment. Accepts a string value for the primary domain of the VIP Platform environment or "n" to disable the media proxy.', undefined, processMediaRedirectDomainOption).option('php', `Manage the version of PHP. Accepts a string value for minor versions: ${phpVersionsSupported}`, undefined, processVersionOption).option('cron', 'Enable or disable cron, disabled by default. Accepts "y" (default value) to enable or "n" to disable.', undefined, processBooleanOption).option(['A', 'mailpit'], 'Enable or disable Mailpit, disabled by default. Accepts "y" (default value) to enable or "n" to disable.', undefined, processBooleanOption).option(['H', 'photon'], 'Enable or disable Photon, disabled by default. Accepts "y" (default value) to enable or "n" to disable.', undefined, processBooleanOption);
|
|
681
683
|
}
|
|
682
684
|
|
|
683
685
|
/**
|
|
@@ -736,7 +738,7 @@ function getEnvTrackingInfo(slug) {
|
|
|
736
738
|
}
|
|
737
739
|
result.php = result.php.replace(/^[^:]+:/, '');
|
|
738
740
|
return result;
|
|
739
|
-
} catch
|
|
741
|
+
} catch {
|
|
740
742
|
return {
|
|
741
743
|
slug
|
|
742
744
|
};
|
|
@@ -82,6 +82,10 @@ async function startEnvironment(lando, slug, options) {
|
|
|
82
82
|
updated = await maybeUpdateWordPressImage(lando, slug);
|
|
83
83
|
}
|
|
84
84
|
updated = updated || (await maybeUpdateVersion(lando, slug));
|
|
85
|
+
const proxyContainer = await (0, _devEnvironmentLando.getProxyContainer)(lando);
|
|
86
|
+
if (!proxyContainer?.State.Running) {
|
|
87
|
+
await (0, _devEnvironmentLando.removeProxyCache)(lando);
|
|
88
|
+
}
|
|
85
89
|
if (options.skipRebuild && !updated) {
|
|
86
90
|
await (0, _devEnvironmentLando.landoStart)(lando, instancePath);
|
|
87
91
|
} else {
|
|
@@ -265,12 +269,12 @@ function exec(lando, slug, args, options = {}) {
|
|
|
265
269
|
return (0, _devEnvironmentLando.landoExec)(lando, instancePath, command, commandArgs, options);
|
|
266
270
|
}
|
|
267
271
|
async function doesEnvironmentExist(instancePath) {
|
|
268
|
-
debug('Will check for environment at', instancePath);
|
|
272
|
+
debug('Will check for environment at %s', instancePath);
|
|
269
273
|
const file = _nodePath.default.join(instancePath, instanceDataFileName);
|
|
270
274
|
try {
|
|
271
275
|
const stats = await _nodeFs.default.promises.stat(file);
|
|
272
276
|
return stats.isFile();
|
|
273
|
-
} catch
|
|
277
|
+
} catch {
|
|
274
278
|
return false;
|
|
275
279
|
}
|
|
276
280
|
}
|
|
@@ -688,6 +692,7 @@ async function maybeUpdateVersion(lando, slug) {
|
|
|
688
692
|
*/
|
|
689
693
|
function fetchVersionList() {
|
|
690
694
|
const url = `https://${_devEnvironment.DEV_ENVIRONMENT_RAW_GITHUB_HOST}${_devEnvironment.DEV_ENVIRONMENT_WORDPRESS_VERSIONS_URI}`;
|
|
695
|
+
// TODO: remove this cast once the typings are fixed
|
|
691
696
|
const proxyAgent = (0, _proxyAgent.createProxyAgent)(url);
|
|
692
697
|
return (0, _nodeFetch.default)(url, {
|
|
693
698
|
agent: proxyAgent ?? undefined
|
|
@@ -708,7 +713,8 @@ async function isVersionListExpired(cacheFile, ttl) {
|
|
|
708
713
|
} = await _nodeFs.default.promises.stat(cacheFile);
|
|
709
714
|
expire.setSeconds(expire.getSeconds() + ttl);
|
|
710
715
|
return Number(new Date()) > Number(expire);
|
|
711
|
-
} catch (
|
|
716
|
+
} catch (error) {
|
|
717
|
+
debug(`Error checking version list expiration for cache file ${cacheFile}:`, error);
|
|
712
718
|
return true;
|
|
713
719
|
}
|
|
714
720
|
}
|
|
@@ -840,7 +846,6 @@ function getVSCodeWorkspacePath(slug) {
|
|
|
840
846
|
function generatePHPStormWorkspace(slug) {
|
|
841
847
|
debug('Generating PHPStorm Workspace');
|
|
842
848
|
const location = getEnvironmentPath(slug);
|
|
843
|
-
// const location = location;
|
|
844
849
|
const instanceData = readEnvironmentData(slug);
|
|
845
850
|
const pathMappings = generatePathMappings(location, instanceData);
|
|
846
851
|
|
|
@@ -2,8 +2,11 @@
|
|
|
2
2
|
|
|
3
3
|
exports.__esModule = true;
|
|
4
4
|
exports.reIndexSearch = exports.generatePassword = exports.flushCache = exports.executeQuery = exports.dataCleanup = exports.addAdminUser = void 0;
|
|
5
|
+
var _debug = _interopRequireDefault(require("debug"));
|
|
5
6
|
var _nodeCrypto = require("node:crypto");
|
|
6
7
|
var _devEnvironmentCore = require("./dev-environment-core");
|
|
8
|
+
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
9
|
+
const debug = (0, _debug.default)('@automattic/vip:bin:dev-environment');
|
|
7
10
|
const generatePassword = () => {
|
|
8
11
|
const chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_';
|
|
9
12
|
const passwordLength = 12;
|
|
@@ -36,6 +39,7 @@ const dataCleanup = async (lando, slug, quiet) => {
|
|
|
36
39
|
} catch (error) {
|
|
37
40
|
// This must not be a fatal error
|
|
38
41
|
console.log('WARNING: data cleanup failed.');
|
|
42
|
+
debug('Error during data cleanup:', error);
|
|
39
43
|
}
|
|
40
44
|
};
|
|
41
45
|
exports.dataCleanup = dataCleanup;
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
exports.__esModule = true;
|
|
4
4
|
exports.bootstrapLando = bootstrapLando;
|
|
5
5
|
exports.checkEnvHealth = checkEnvHealth;
|
|
6
|
+
exports.getProxyContainer = getProxyContainer;
|
|
6
7
|
exports.isEnvUp = isEnvUp;
|
|
7
8
|
exports.landoDestroy = landoDestroy;
|
|
8
9
|
exports.landoExec = landoExec;
|
|
@@ -12,6 +13,7 @@ exports.landoRebuild = landoRebuild;
|
|
|
12
13
|
exports.landoShell = landoShell;
|
|
13
14
|
exports.landoStart = landoStart;
|
|
14
15
|
exports.landoStop = landoStop;
|
|
16
|
+
exports.removeProxyCache = removeProxyCache;
|
|
15
17
|
exports.validateDockerInstalled = validateDockerInstalled;
|
|
16
18
|
var _chalk = _interopRequireDefault(require("chalk"));
|
|
17
19
|
var _debug = _interopRequireDefault(require("debug"));
|
|
@@ -63,7 +65,7 @@ async function getLandoConfig() {
|
|
|
63
65
|
await (0, _promises2.mkdir)(fakeHomeDir, {
|
|
64
66
|
recursive: true
|
|
65
67
|
});
|
|
66
|
-
} catch
|
|
68
|
+
} catch {
|
|
67
69
|
// Ignore
|
|
68
70
|
}
|
|
69
71
|
const config = {
|
|
@@ -110,7 +112,8 @@ async function regenerateLandofile(lando, instancePath) {
|
|
|
110
112
|
const backup = `${landoFile}.${now}`;
|
|
111
113
|
await (0, _promises2.rename)(landoFile, backup);
|
|
112
114
|
console.warn(_chalk.default.yellow('Backed up %s to %s'), landoFile, backup);
|
|
113
|
-
} catch (
|
|
115
|
+
} catch (error) {
|
|
116
|
+
debug(`Failed to backup lando file ${landoFile}:`, error);
|
|
114
117
|
// Rename failed - possibly the file does not exist. Silently ignoring.
|
|
115
118
|
}
|
|
116
119
|
const slug = _nodePath.default.basename(instancePath);
|
|
@@ -246,6 +249,17 @@ async function getBridgeNetwork(lando) {
|
|
|
246
249
|
return null;
|
|
247
250
|
}
|
|
248
251
|
}
|
|
252
|
+
async function removeProxyCache(lando) {
|
|
253
|
+
const {
|
|
254
|
+
userConfRoot,
|
|
255
|
+
proxyCache
|
|
256
|
+
} = lando.config;
|
|
257
|
+
try {
|
|
258
|
+
await (0, _promises2.unlink)(_nodePath.default.join(userConfRoot, 'cache', proxyCache ?? 'proxyCache'));
|
|
259
|
+
} catch {
|
|
260
|
+
// Swallow
|
|
261
|
+
}
|
|
262
|
+
}
|
|
249
263
|
async function cleanUpLandoProxy(lando) {
|
|
250
264
|
const network = await getBridgeNetwork(lando);
|
|
251
265
|
if (network?.Containers && Object.keys(network.Containers).length === 1) {
|
|
@@ -257,6 +271,7 @@ async function cleanUpLandoProxy(lando) {
|
|
|
257
271
|
} catch (err) {
|
|
258
272
|
debug('Error removing proxy container: %s', err.message);
|
|
259
273
|
}
|
|
274
|
+
await removeProxyCache(lando);
|
|
260
275
|
}
|
|
261
276
|
}
|
|
262
277
|
async function landoStop(lando, instancePath) {
|
|
@@ -395,7 +410,7 @@ async function tryResolveDomains(urls) {
|
|
|
395
410
|
const domains = [...new Set(urls.filter(url => url.toLowerCase().startsWith('http')).map(url => {
|
|
396
411
|
try {
|
|
397
412
|
return new URL(url).hostname;
|
|
398
|
-
} catch
|
|
413
|
+
} catch {
|
|
399
414
|
return undefined;
|
|
400
415
|
}
|
|
401
416
|
}).filter(domain => domain !== undefined))];
|
|
@@ -525,6 +540,20 @@ async function landoShell(lando, instancePath, service, user, command) {
|
|
|
525
540
|
_app: app
|
|
526
541
|
});
|
|
527
542
|
}
|
|
543
|
+
async function getProxyContainer(lando) {
|
|
544
|
+
const proxyContainerName = lando.config.proxyContainer;
|
|
545
|
+
const {
|
|
546
|
+
docker
|
|
547
|
+
} = lando.engine;
|
|
548
|
+
const containers = await docker.listContainers({
|
|
549
|
+
all: true
|
|
550
|
+
});
|
|
551
|
+
if (containers.some(container => container.Names.includes(`/${proxyContainerName}`))) {
|
|
552
|
+
const container = docker.getContainer(proxyContainerName);
|
|
553
|
+
return container.inspect();
|
|
554
|
+
}
|
|
555
|
+
return null;
|
|
556
|
+
}
|
|
528
557
|
|
|
529
558
|
/**
|
|
530
559
|
* Sometimes the proxy network seems to disapper leaving only orphant stopped proxy container.
|
|
@@ -535,21 +564,12 @@ async function landoShell(lando, instancePath, service, user, command) {
|
|
|
535
564
|
* can safely add a network and a new proxy container.
|
|
536
565
|
*/
|
|
537
566
|
async function ensureNoOrphantProxyContainer(lando) {
|
|
538
|
-
const
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
const proxyContainerExists = containers.some(container => container.Names.includes(`/${proxyContainerName}`));
|
|
544
|
-
if (!proxyContainerExists) {
|
|
545
|
-
return;
|
|
546
|
-
}
|
|
547
|
-
const proxyContainer = docker.getContainer(proxyContainerName);
|
|
548
|
-
const status = await proxyContainer.inspect();
|
|
549
|
-
if (status.State.Running) {
|
|
550
|
-
return;
|
|
567
|
+
const proxyContainer = await getProxyContainer(lando);
|
|
568
|
+
if (proxyContainer && !proxyContainer.State.Running) {
|
|
569
|
+
const containerName = proxyContainer.Name.startsWith('/') ? proxyContainer.Name.slice(1) : proxyContainer.Name;
|
|
570
|
+
const container = lando.engine.docker.getContainer(containerName);
|
|
571
|
+
await container.remove();
|
|
551
572
|
}
|
|
552
|
-
await proxyContainer.remove();
|
|
553
573
|
}
|
|
554
574
|
function validateDockerInstalled(lando) {
|
|
555
575
|
const {
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
exports.__esModule = true;
|
|
4
|
+
exports.getEnvFilePath = getEnvFilePath;
|
|
5
|
+
exports.parseEnvValue = parseEnvValue;
|
|
6
|
+
exports.preparseEnvData = preparseEnvData;
|
|
7
|
+
exports.quoteEnvValue = quoteEnvValue;
|
|
8
|
+
exports.readEnvFile = readEnvFile;
|
|
9
|
+
exports.updateEnvFile = updateEnvFile;
|
|
10
|
+
var _promises = require("node:fs/promises");
|
|
11
|
+
var _nodePath = require("node:path");
|
|
12
|
+
var _devEnvironmentCore = require("./dev-environment-core");
|
|
13
|
+
var _devEnvironment = require("../constants/dev-environment");
|
|
14
|
+
function preparseEnvData(data) {
|
|
15
|
+
return data.split(/\r?\n/).map(line => line.trim()).filter(line => line && !line.startsWith('#'));
|
|
16
|
+
}
|
|
17
|
+
function parseEnvValue(value) {
|
|
18
|
+
if (value.startsWith('"') && value.endsWith('"')) {
|
|
19
|
+
return value.slice(1, -1).replace(/\\(["$\\nrt])/g, (match, char) => {
|
|
20
|
+
switch (char) {
|
|
21
|
+
case '"':
|
|
22
|
+
case '$':
|
|
23
|
+
case '\\':
|
|
24
|
+
return char;
|
|
25
|
+
case 'n':
|
|
26
|
+
return '\n';
|
|
27
|
+
case 'r':
|
|
28
|
+
return '\r';
|
|
29
|
+
case 't':
|
|
30
|
+
return '\t';
|
|
31
|
+
default:
|
|
32
|
+
return match;
|
|
33
|
+
}
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
if (value.startsWith("'") && value.endsWith("'")) {
|
|
37
|
+
return value.slice(1, -1).replace(/\\'/g, "'");
|
|
38
|
+
}
|
|
39
|
+
return value;
|
|
40
|
+
}
|
|
41
|
+
function quoteEnvValue(value) {
|
|
42
|
+
return `"${value.replace(/[\\"$\n\r\t]/g, match => {
|
|
43
|
+
switch (match) {
|
|
44
|
+
case '\\':
|
|
45
|
+
case '"':
|
|
46
|
+
case '$':
|
|
47
|
+
return '\\' + match;
|
|
48
|
+
case '\n':
|
|
49
|
+
return '\\n';
|
|
50
|
+
case '\r':
|
|
51
|
+
return '\\r';
|
|
52
|
+
case '\t':
|
|
53
|
+
return '\\t';
|
|
54
|
+
default:
|
|
55
|
+
return match;
|
|
56
|
+
}
|
|
57
|
+
})}"`;
|
|
58
|
+
}
|
|
59
|
+
async function getEnvFilePath(slug, checkEnvExists = true) {
|
|
60
|
+
const environmentPath = (0, _devEnvironmentCore.getEnvironmentPath)(slug);
|
|
61
|
+
if (checkEnvExists && !(await (0, _devEnvironmentCore.doesEnvironmentExist)(environmentPath))) {
|
|
62
|
+
throw new Error(_devEnvironment.DEV_ENVIRONMENT_NOT_FOUND);
|
|
63
|
+
}
|
|
64
|
+
return (0, _nodePath.join)(environmentPath, '.env');
|
|
65
|
+
}
|
|
66
|
+
async function readEnvFile(slug) {
|
|
67
|
+
const name = await getEnvFilePath(slug);
|
|
68
|
+
const content = await (0, _promises.readFile)(name, 'utf-8');
|
|
69
|
+
return preparseEnvData(content);
|
|
70
|
+
}
|
|
71
|
+
async function updateEnvFile(slug, content) {
|
|
72
|
+
const name = await getEnvFilePath(slug, false);
|
|
73
|
+
await (0, _promises.writeFile)(`${name}.tmp`, content, 'utf-8');
|
|
74
|
+
await (0, _promises.rename)(`${name}.tmp`, name);
|
|
75
|
+
}
|
|
@@ -289,14 +289,9 @@ ${maybeExitPrompt}
|
|
|
289
289
|
importInProgress,
|
|
290
290
|
importStepProgress
|
|
291
291
|
});
|
|
292
|
-
|
|
293
|
-
try {
|
|
294
|
-
jobCreationTime = new Date(createdAt ?? '').getTime();
|
|
295
|
-
} catch (err) {
|
|
296
|
-
debug('Unable to parse createdAt to a Date');
|
|
297
|
-
}
|
|
292
|
+
const jobCreationTime = new Date(createdAt ?? '').getTime();
|
|
298
293
|
let failedImportStep;
|
|
299
|
-
if (jobCreationTime && (importStepProgress?.started_at ?? 0) * 1000 >= jobCreationTime) {
|
|
294
|
+
if (!isNaN(jobCreationTime) && (importStepProgress?.started_at ?? 0) * 1000 >= jobCreationTime) {
|
|
300
295
|
// The contents of the `import_progress` meta are pertinent to the most recent import job
|
|
301
296
|
failedImportStep = importStepProgress?.steps?.find(step => step?.result === 'failed' && 1000 * (step.started_at ?? 0) > new Date(createdAt ?? '').getTime());
|
|
302
297
|
}
|
|
@@ -20,8 +20,9 @@ const getPrimaryDomainFromSQL = statements => {
|
|
|
20
20
|
if (!statements.length) {
|
|
21
21
|
return '';
|
|
22
22
|
}
|
|
23
|
-
const SQL_WP_SITE_DOMAINS_REGEX = /\(1,'(
|
|
24
|
-
const
|
|
23
|
+
const SQL_WP_SITE_DOMAINS_REGEX = /\(1,'([^']+)'/s;
|
|
24
|
+
const normalizedSql = statements[0]?.join('').replace(/\s/g, '') ?? '';
|
|
25
|
+
const matches = SQL_WP_SITE_DOMAINS_REGEX.exec(normalizedSql);
|
|
25
26
|
return matches ? matches[1] : '';
|
|
26
27
|
};
|
|
27
28
|
|
|
@@ -15,7 +15,7 @@ async function getReadInterface(filename) {
|
|
|
15
15
|
let fd;
|
|
16
16
|
try {
|
|
17
17
|
fd = await (0, _promises.open)(filename);
|
|
18
|
-
} catch
|
|
18
|
+
} catch {
|
|
19
19
|
exit.withError('The file at the provided path is either missing or not readable. Please check the input and try again.');
|
|
20
20
|
}
|
|
21
21
|
return (0, _nodeReadline.createInterface)({
|
package/docs/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,60 @@
|
|
|
1
1
|
## Changelog
|
|
2
2
|
|
|
3
|
+
### 3.19.0
|
|
4
|
+
|
|
5
|
+
* build(deps-dev): bump the testing group across 1 directory with 4 updates
|
|
6
|
+
* New develop release: 3.18.1-dev.0 by @gi
|
|
7
|
+
* build(deps-dev): bump the testing group with 3 updates
|
|
8
|
+
* Remove preflight as part of the harmonia deprecation
|
|
9
|
+
* Add changelog workflow
|
|
10
|
+
* Changelogs: Update `vip-actions`
|
|
11
|
+
* build(deps-dev): bump @types/dockerode from 3.3.41 to 3.3.42
|
|
12
|
+
* build(deps-dev): bump the testing group with 2 updates
|
|
13
|
+
* build(deps): bump step-security/harden-runner from 2.12.1 to 2.12.2
|
|
14
|
+
* build(deps-dev): bump @babel/core from 7.27.4 to 7.27.7 in the babel group
|
|
15
|
+
* build(deps-dev): bump the babel group with 3 updates
|
|
16
|
+
* build(deps-dev): bump @types/shelljs from 0.8.16 to 0.8.17
|
|
17
|
+
* build(deps-dev): bump the testing group with 3 updates
|
|
18
|
+
* chore(deps): update Lando to fix PLTFRM-1195
|
|
19
|
+
* build(deps): bump socks-proxy-agent from 5.0.1 to 8.0.5
|
|
20
|
+
* build(deps): bump https-proxy-agent from 5.0.1 to 7.0.6
|
|
21
|
+
* build(deps-dev): bump @types/node from 24.0.3 to 24.0.10
|
|
22
|
+
* feat(dev-env): allow `latest` as WP version
|
|
23
|
+
* feat(dev-env): add some logging to `DevEnvSyncSQLCommand`
|
|
24
|
+
* Update to the description of the `--wordpress` option for `dev-env`
|
|
25
|
+
* build(deps-dev): bump @types/node from 24.0.10 to 24.0.12
|
|
26
|
+
* fix: drop superfluous `as unknown` casts
|
|
27
|
+
* fix: exception handling-related code smells
|
|
28
|
+
* fix: Promise rejection is not caught by `try`
|
|
29
|
+
* fix: RegExp-related issues
|
|
30
|
+
* fix: fields that are only assigned in the constructor should be "readonly"
|
|
31
|
+
* fix(dev-env): make URL extraction less error-prone
|
|
32
|
+
|
|
33
|
+
**Full Changelog**: https://github.com/Automattic/vip-cli/compare/3.18.0...3.19.0
|
|
34
|
+
|
|
35
|
+
### 3.18.0
|
|
36
|
+
|
|
37
|
+
* fix: properly quote parameters for `vip wp`
|
|
38
|
+
* build(deps-dev): bump dockerode from 4.0.6 to 4.0.7
|
|
39
|
+
* build(deps-dev): bump @types/node from 22.15.29 to 22.15.30
|
|
40
|
+
* build(deps-dev): bump @types/dockerode from 3.3.39 to 3.3.40
|
|
41
|
+
* build(deps-dev): bump @types/node from 22.15.30 to 24.0.0
|
|
42
|
+
* build(deps): bump step-security/harden-runner from 2.12.0 to 2.12.1
|
|
43
|
+
* build(deps-dev): bump @types/node from 24.0.0 to 24.0.1
|
|
44
|
+
* fix(dev-env): clear proxy cache before startup and after shutdown
|
|
45
|
+
* feat(dev-env): add `vip dev-env envvar` commands
|
|
46
|
+
* chore(deps): update `lando` to the latest version
|
|
47
|
+
* Remove MD5 requirement restrictions for URL imports in vip-import-sql
|
|
48
|
+
* build(deps-dev): bump @types/node from 24.0.1 to 24.0.3
|
|
49
|
+
* build(deps-dev): bump @types/dockerode from 3.3.40 to 3.3.41
|
|
50
|
+
* chore(deps): update `brace-expansion` to fix CVE-2025-5889
|
|
51
|
+
* Bump ES to 8.18.2
|
|
52
|
+
* fix: suppress prompt for media redirect with config files
|
|
53
|
+
* Add changelog section to PR template
|
|
54
|
+
* Update/Org salesforceId
|
|
55
|
+
|
|
56
|
+
**Full Changelog**: https://github.com/Automattic/vip-cli/compare/3.17.1...3.18.0
|
|
57
|
+
|
|
3
58
|
### 3.17.1
|
|
4
59
|
|
|
5
60
|
* chore: Update Git Hash Checker Github Action
|