@automattic/vip 3.22.0 → 3.22.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/dist/bin/vip-export-sql.js +8 -3
- package/dist/bin/vip-import-media.js +4 -4
- package/dist/commands/export-sql.js +21 -14
- package/dist/lib/cli/progress.js +17 -11
- package/npm-shrinkwrap.json +10 -10
- package/package.json +2 -2
|
@@ -15,6 +15,9 @@ const examples = [{
|
|
|
15
15
|
}, {
|
|
16
16
|
usage: 'vip @example-app.develop export sql --generate-backup',
|
|
17
17
|
description: 'Generate a fresh database backup for an environment and download an archived copy of that backup.'
|
|
18
|
+
}, {
|
|
19
|
+
usage: 'vip @example-app.develop export sql --skip-download',
|
|
20
|
+
description: 'Skip downloading the database backup file.'
|
|
18
21
|
}, {
|
|
19
22
|
usage: 'vip @example-app.develop export sql --table=wp_posts --table=wp_comments',
|
|
20
23
|
description: 'Generate and download an archived partial database export file that includes only the wp_posts and wp_comments tables.'
|
|
@@ -52,7 +55,7 @@ const appQuery = `
|
|
|
52
55
|
module: 'export-sql',
|
|
53
56
|
requiredArgs: 0,
|
|
54
57
|
usage: 'vip export sql'
|
|
55
|
-
}).option('output', 'Download the file to a specific local directory path with a custom file name.').option('table', 'The name of a table to include in the partial database export. Accepts a string value and can be passed more than once with a different value, or add multiple values in a comma-separated list.').option('site-id', 'The ID of a network site to include in the partial database export. Accepts an integer value and can be passed more than once with a different value, or add multiple values in a comma-separated list.').option('wpcli-command', 'Run a custom WP-CLI command that has logic to retrieve specific data for the partial database export.').option('config-file', 'A local configuration file that specifies the data to include in the partial database export. Accepts a relative or absolute path to the file.', undefined).option('generate-backup', 'Generate a fresh database backup and export an archived copy of that backup.').examples(examples).argv(process.argv, async (arg, {
|
|
58
|
+
}).option('output', 'Download the file to a specific local directory path with a custom file name.').option('table', 'The name of a table to include in the partial database export. Accepts a string value and can be passed more than once with a different value, or add multiple values in a comma-separated list.').option('site-id', 'The ID of a network site to include in the partial database export. Accepts an integer value and can be passed more than once with a different value, or add multiple values in a comma-separated list.').option('wpcli-command', 'Run a custom WP-CLI command that has logic to retrieve specific data for the partial database export.').option('config-file', 'A local configuration file that specifies the data to include in the partial database export. Accepts a relative or absolute path to the file.', undefined).option('generate-backup', 'Generate a fresh database backup and export an archived copy of that backup.').option('skip-download', 'Skip downloading the file.').examples(examples).argv(process.argv, async (arg, {
|
|
56
59
|
app,
|
|
57
60
|
env,
|
|
58
61
|
output,
|
|
@@ -60,7 +63,8 @@ const appQuery = `
|
|
|
60
63
|
table,
|
|
61
64
|
siteId,
|
|
62
65
|
wpcliCommand,
|
|
63
|
-
generateBackup
|
|
66
|
+
generateBackup,
|
|
67
|
+
skipDownload
|
|
64
68
|
}) => {
|
|
65
69
|
const liveBackupCopyCLIOptions = (0, _liveBackupCopy.parseLiveBackupCopyCLIOptions)(configFile, table, siteId, wpcliCommand);
|
|
66
70
|
const trackerFn = (0, _tracker.makeCommandTracker)('export_sql', {
|
|
@@ -73,7 +77,8 @@ const appQuery = `
|
|
|
73
77
|
const exportCommand = new _exportSql.ExportSQLCommand(app, env, {
|
|
74
78
|
outputFile: output,
|
|
75
79
|
generateBackup,
|
|
76
|
-
liveBackupCopyCLIOptions
|
|
80
|
+
liveBackupCopyCLIOptions,
|
|
81
|
+
skipDownload
|
|
77
82
|
}, trackerFn);
|
|
78
83
|
await exportCommand.run();
|
|
79
84
|
await trackerFn('success');
|
|
@@ -52,15 +52,15 @@ const debug = (0, _debug.default)('vip:vip-import-media');
|
|
|
52
52
|
|
|
53
53
|
// Command examples for the `vip import media` help prompt
|
|
54
54
|
const examples = [{
|
|
55
|
+
usage: 'vip @example-app.production import media /path/to/uploads.zip',
|
|
56
|
+
description: 'Import the archived file "uploads.zip" from the user\'s local machine to a production environment.'
|
|
57
|
+
}, {
|
|
55
58
|
usage: 'vip @example-app.production import media https://example.com/uploads.tar.gz',
|
|
56
59
|
description: 'Import the archived file "uploads.tar.gz" from a publicly accessible URL to a production environment.'
|
|
57
|
-
}, {
|
|
58
|
-
usage: 'vip @example-app.production import media /path/to/uploads.tar.gz',
|
|
59
|
-
description: 'Import a local archive file (e.g. .tar.gz, .tgz, .zip) from your machine into a production environment. The file will be uploaded temporarily and then imported.'
|
|
60
60
|
},
|
|
61
61
|
// Format error logs
|
|
62
62
|
{
|
|
63
|
-
usage: 'vip @example-app.production import media https://example.com/uploads.
|
|
63
|
+
usage: 'vip @example-app.production import media https://example.com/uploads.tgz --overwriteExistingFiles --exportFileErrorsToJson',
|
|
64
64
|
description: 'Overwrite existing files with the imported files if they have the same file path and name, and format the error log for the import in JSON.'
|
|
65
65
|
},
|
|
66
66
|
// `media status` subcommand
|
|
@@ -193,6 +193,7 @@ class ExportSQLCommand {
|
|
|
193
193
|
track;
|
|
194
194
|
liveBackupCopyCLIOptions;
|
|
195
195
|
showMyDumperWarning;
|
|
196
|
+
skipDownload;
|
|
196
197
|
|
|
197
198
|
/**
|
|
198
199
|
* Creates an instance of SQLExportCommand
|
|
@@ -214,12 +215,12 @@ class ExportSQLCommand {
|
|
|
214
215
|
}, {
|
|
215
216
|
id: this.steps.CREATE,
|
|
216
217
|
name: 'Creating backup copy'
|
|
217
|
-
}, {
|
|
218
|
-
id: this.steps.CONFIRM_ENOUGH_STORAGE,
|
|
219
|
-
name: "Checking if there's enough storage"
|
|
220
218
|
}, {
|
|
221
219
|
id: this.steps.DOWNLOAD_LINK,
|
|
222
220
|
name: 'Requesting download link'
|
|
221
|
+
}, {
|
|
222
|
+
id: this.steps.CONFIRM_ENOUGH_STORAGE,
|
|
223
|
+
name: "Checking if there's enough storage"
|
|
223
224
|
}, {
|
|
224
225
|
id: this.steps.DOWNLOAD,
|
|
225
226
|
name: 'Downloading file'
|
|
@@ -227,6 +228,7 @@ class ExportSQLCommand {
|
|
|
227
228
|
this.track = trackerFn;
|
|
228
229
|
this.liveBackupCopyCLIOptions = options.liveBackupCopyCLIOptions;
|
|
229
230
|
this.showMyDumperWarning = options.showMyDumperWarning === undefined ? true : options.showMyDumperWarning;
|
|
231
|
+
this.skipDownload = options.skipDownload || false;
|
|
230
232
|
}
|
|
231
233
|
|
|
232
234
|
/**
|
|
@@ -348,6 +350,15 @@ class ExportSQLCommand {
|
|
|
348
350
|
}
|
|
349
351
|
size = Number(bytesWrittenMeta.value);
|
|
350
352
|
}
|
|
353
|
+
const downloadURLString = `\n${_chalk.default.green('Download URL')}:\n${url}\n\n`;
|
|
354
|
+
if (this.skipDownload) {
|
|
355
|
+
this.progressTracker.stepSkipped(this.steps.CONFIRM_ENOUGH_STORAGE);
|
|
356
|
+
this.progressTracker.stepSkipped(this.steps.DOWNLOAD);
|
|
357
|
+
this.progressTracker.print();
|
|
358
|
+
this.progressTracker.stopPrinting();
|
|
359
|
+
console.log(downloadURLString);
|
|
360
|
+
return;
|
|
361
|
+
}
|
|
351
362
|
const storageConfirmed = await this.progressTracker.handleContinuePrompt(async setPromptShown => {
|
|
352
363
|
const status = await this.confirmEnoughStorage(Number(size));
|
|
353
364
|
if (status.isPromptShown) {
|
|
@@ -401,19 +412,15 @@ class ExportSQLCommand {
|
|
|
401
412
|
});
|
|
402
413
|
exit.withError(`No backup found for site ${this.app.name}`);
|
|
403
414
|
}
|
|
404
|
-
|
|
405
|
-
console.log(`${(0, _format.getGlyphForStatus)('success')} Latest backup found with timestamp ${latestBackup.createdAt}`);
|
|
406
|
-
} else {
|
|
407
|
-
console.log(`${(0, _format.getGlyphForStatus)('success')} Backup created with timestamp ${latestBackup.createdAt}`);
|
|
408
|
-
}
|
|
415
|
+
const prepareAdditionalInfo = [];
|
|
409
416
|
const showMyDumperWarning = this.showMyDumperWarning && (latestBackup.sqlDumpTool ?? envSqlDumpTool) === 'mydumper';
|
|
410
417
|
if (showMyDumperWarning) {
|
|
411
|
-
|
|
418
|
+
prepareAdditionalInfo.push(`${_chalk.default.yellow.bold('WARNING:')} This is a large or complex database. The backup file for this database is generated with MyDumper. The file can only be loaded with MyLoader. For more information: https://github.com/mydumper/mydumper`);
|
|
412
419
|
}
|
|
413
420
|
if (await this.getExportJob()) {
|
|
414
|
-
|
|
421
|
+
prepareAdditionalInfo.push(`Attaching to an existing export for the backup with timestamp ${latestBackup.createdAt}`);
|
|
415
422
|
} else {
|
|
416
|
-
|
|
423
|
+
prepareAdditionalInfo.push(`Exporting database backup with timestamp ${latestBackup.createdAt}`);
|
|
417
424
|
try {
|
|
418
425
|
await createExportJob(this.app.id, this.env.id, latestBackup.id);
|
|
419
426
|
} catch (err) {
|
|
@@ -437,11 +444,11 @@ class ExportSQLCommand {
|
|
|
437
444
|
}
|
|
438
445
|
}
|
|
439
446
|
await (0, _utils.pollUntil)(this.getExportJob.bind(this), EXPORT_SQL_PROGRESS_POLL_INTERVAL, this.isPrepared.bind(this));
|
|
440
|
-
this.progressTracker.stepSuccess(this.steps.PREPARE);
|
|
447
|
+
this.progressTracker.stepSuccess(this.steps.PREPARE, prepareAdditionalInfo);
|
|
441
448
|
await (0, _utils.pollUntil)(this.getExportJob.bind(this), EXPORT_SQL_PROGRESS_POLL_INTERVAL, this.isCreated.bind(this));
|
|
442
449
|
this.progressTracker.stepSuccess(this.steps.CREATE);
|
|
443
450
|
const url = await generateDownloadLink(this.app.id, this.env.id, latestBackup.id);
|
|
444
|
-
this.progressTracker.stepSuccess(this.steps.DOWNLOAD_LINK);
|
|
451
|
+
this.progressTracker.stepSuccess(this.steps.DOWNLOAD_LINK, [url]);
|
|
445
452
|
return url;
|
|
446
453
|
}
|
|
447
454
|
async generateLiveBackupCopy() {
|
|
@@ -466,7 +473,7 @@ class ExportSQLCommand {
|
|
|
466
473
|
copyId
|
|
467
474
|
});
|
|
468
475
|
this.progressTracker.stepSuccess(this.steps.CREATE);
|
|
469
|
-
this.progressTracker.stepSuccess(this.steps.DOWNLOAD_LINK);
|
|
476
|
+
this.progressTracker.stepSuccess(this.steps.DOWNLOAD_LINK, [result.url]);
|
|
470
477
|
return result;
|
|
471
478
|
} catch (err) {
|
|
472
479
|
const message = err instanceof Error ? err.message : 'Unknown error';
|
package/dist/lib/cli/progress.js
CHANGED
|
@@ -128,17 +128,17 @@ class ProgressTracker {
|
|
|
128
128
|
status
|
|
129
129
|
}) => status === StepStatus.RUNNING);
|
|
130
130
|
}
|
|
131
|
-
stepRunning(stepId) {
|
|
132
|
-
this.setStatusForStepId(stepId, StepStatus.RUNNING);
|
|
131
|
+
stepRunning(stepId, additionalInfo = []) {
|
|
132
|
+
this.setStatusForStepId(stepId, StepStatus.RUNNING, additionalInfo);
|
|
133
133
|
}
|
|
134
|
-
stepFailed(stepId) {
|
|
135
|
-
this.setStatusForStepId(stepId, StepStatus.FAILED);
|
|
134
|
+
stepFailed(stepId, additionalInfo = []) {
|
|
135
|
+
this.setStatusForStepId(stepId, StepStatus.FAILED, additionalInfo);
|
|
136
136
|
}
|
|
137
|
-
stepSkipped(stepId) {
|
|
138
|
-
this.setStatusForStepId(stepId, StepStatus.SKIPPED);
|
|
137
|
+
stepSkipped(stepId, additionalInfo = []) {
|
|
138
|
+
this.setStatusForStepId(stepId, StepStatus.SKIPPED, additionalInfo);
|
|
139
139
|
}
|
|
140
|
-
stepSuccess(stepId) {
|
|
141
|
-
this.setStatusForStepId(stepId, StepStatus.SUCCESS);
|
|
140
|
+
stepSuccess(stepId, additionalInfo = []) {
|
|
141
|
+
this.setStatusForStepId(stepId, StepStatus.SUCCESS, additionalInfo);
|
|
142
142
|
// The stepSuccess helper automatically sets the next step to "running"
|
|
143
143
|
const nextStep = this.getNextStep();
|
|
144
144
|
if (nextStep) {
|
|
@@ -150,7 +150,7 @@ class ProgressTracker {
|
|
|
150
150
|
status
|
|
151
151
|
}) => status === StepStatus.SUCCESS);
|
|
152
152
|
}
|
|
153
|
-
setStatusForStepId(stepId, status) {
|
|
153
|
+
setStatusForStepId(stepId, status, additionalInfo = []) {
|
|
154
154
|
const step = this.stepsFromCaller.get(stepId);
|
|
155
155
|
if (!step) {
|
|
156
156
|
// Only allowed to update existing steps with this method
|
|
@@ -164,7 +164,8 @@ class ProgressTracker {
|
|
|
164
164
|
}
|
|
165
165
|
this.stepsFromCaller.set(stepId, {
|
|
166
166
|
...step,
|
|
167
|
-
status
|
|
167
|
+
status,
|
|
168
|
+
additionalInfo: Array.isArray(additionalInfo) ? additionalInfo : [additionalInfo]
|
|
168
169
|
});
|
|
169
170
|
}
|
|
170
171
|
startPrinting(prePrintCallback = () => {}) {
|
|
@@ -225,7 +226,8 @@ class ProgressTracker {
|
|
|
225
226
|
id,
|
|
226
227
|
percentage,
|
|
227
228
|
status,
|
|
228
|
-
progress
|
|
229
|
+
progress,
|
|
230
|
+
additionalInfo
|
|
229
231
|
}, stepNumber) => {
|
|
230
232
|
if (stepNumber < this.displayFromStep) {
|
|
231
233
|
return accumulator;
|
|
@@ -239,6 +241,10 @@ class ProgressTracker {
|
|
|
239
241
|
} else if (progress) {
|
|
240
242
|
suffix = progress;
|
|
241
243
|
}
|
|
244
|
+
if (additionalInfo && additionalInfo.length > 0) {
|
|
245
|
+
suffix += _nodeOs.EOL;
|
|
246
|
+
suffix += additionalInfo.map(stepInfo => ` - ${stepInfo}`).join(_nodeOs.EOL);
|
|
247
|
+
}
|
|
242
248
|
return `${accumulator}${statusIcon} ${name} ${suffix}\n`;
|
|
243
249
|
}, '');
|
|
244
250
|
|
package/npm-shrinkwrap.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@automattic/vip",
|
|
3
|
-
"version": "3.22.
|
|
3
|
+
"version": "3.22.2",
|
|
4
4
|
"lockfileVersion": 2,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "@automattic/vip",
|
|
9
|
-
"version": "3.22.
|
|
9
|
+
"version": "3.22.2",
|
|
10
10
|
"hasInstallScript": true,
|
|
11
11
|
"license": "MIT",
|
|
12
12
|
"dependencies": {
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
"https-proxy-agent": "^7.0.6",
|
|
30
30
|
"js-yaml": "^4.1.0",
|
|
31
31
|
"jwt-decode": "4.0.0",
|
|
32
|
-
"lando": "github:automattic/lando-cli#
|
|
32
|
+
"lando": "github:automattic/lando-cli#603e9dc490d402a07816560f07b6bfecfc902c5a",
|
|
33
33
|
"node-fetch": "^3.3.2",
|
|
34
34
|
"node-stream-zip": "1.15.0",
|
|
35
35
|
"open": "^11.0.0",
|
|
@@ -11061,8 +11061,8 @@
|
|
|
11061
11061
|
"node_modules/lando": {
|
|
11062
11062
|
"name": "@lando/cli",
|
|
11063
11063
|
"version": "3.6.5",
|
|
11064
|
-
"resolved": "git+ssh://git@github.com/automattic/lando-cli.git#
|
|
11065
|
-
"integrity": "sha512-
|
|
11064
|
+
"resolved": "git+ssh://git@github.com/automattic/lando-cli.git#603e9dc490d402a07816560f07b6bfecfc902c5a",
|
|
11065
|
+
"integrity": "sha512-ql/EFlUe8y8tfgMmeYL2rECgbfDFQ3FiU1JpKmTklhJyast/h0MVYW3oq5tn/pLJjs+r1MQDiDD1I0iCC+3lwA==",
|
|
11066
11066
|
"license": "GPL-3.0",
|
|
11067
11067
|
"dependencies": {
|
|
11068
11068
|
"axios": "^1.12.1",
|
|
@@ -11072,7 +11072,7 @@
|
|
|
11072
11072
|
"copy-dir": "^1.3.0",
|
|
11073
11073
|
"dockerode": "^4.0.0",
|
|
11074
11074
|
"figlet": "^1.8.0",
|
|
11075
|
-
"glob": "^10.
|
|
11075
|
+
"glob": "^10.5.0",
|
|
11076
11076
|
"js-yaml": "^4.1.0",
|
|
11077
11077
|
"jsonfile": "^6.1.0",
|
|
11078
11078
|
"lodash": "^4.17.21",
|
|
@@ -21977,9 +21977,9 @@
|
|
|
21977
21977
|
"integrity": "sha512-tPhhoGUiEiU/WXR4rt8klIoLdnTtyu+9jVKHd/wauEjYud32jyn63mzKWQweaQrHWxBQtYoVtdcEnYX1LosnFQ=="
|
|
21978
21978
|
},
|
|
21979
21979
|
"lando": {
|
|
21980
|
-
"version": "git+ssh://git@github.com/automattic/lando-cli.git#
|
|
21981
|
-
"integrity": "sha512-
|
|
21982
|
-
"from": "lando@github:automattic/lando-cli#
|
|
21980
|
+
"version": "git+ssh://git@github.com/automattic/lando-cli.git#603e9dc490d402a07816560f07b6bfecfc902c5a",
|
|
21981
|
+
"integrity": "sha512-ql/EFlUe8y8tfgMmeYL2rECgbfDFQ3FiU1JpKmTklhJyast/h0MVYW3oq5tn/pLJjs+r1MQDiDD1I0iCC+3lwA==",
|
|
21982
|
+
"from": "lando@github:automattic/lando-cli#603e9dc490d402a07816560f07b6bfecfc902c5a",
|
|
21983
21983
|
"requires": {
|
|
21984
21984
|
"axios": "^1.12.1",
|
|
21985
21985
|
"bluebird": "^3.4.1",
|
|
@@ -21988,7 +21988,7 @@
|
|
|
21988
21988
|
"copy-dir": "^1.3.0",
|
|
21989
21989
|
"dockerode": "^4.0.0",
|
|
21990
21990
|
"figlet": "^1.8.0",
|
|
21991
|
-
"glob": "^10.
|
|
21991
|
+
"glob": "^10.5.0",
|
|
21992
21992
|
"js-yaml": "^4.1.0",
|
|
21993
21993
|
"jsonfile": "^6.1.0",
|
|
21994
21994
|
"lodash": "^4.17.21",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@automattic/vip",
|
|
3
|
-
"version": "3.22.
|
|
3
|
+
"version": "3.22.2",
|
|
4
4
|
"description": "The VIP Javascript library & CLI",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"bin": {
|
|
@@ -158,7 +158,7 @@
|
|
|
158
158
|
"https-proxy-agent": "^7.0.6",
|
|
159
159
|
"js-yaml": "^4.1.0",
|
|
160
160
|
"jwt-decode": "4.0.0",
|
|
161
|
-
"lando": "github:automattic/lando-cli#
|
|
161
|
+
"lando": "github:automattic/lando-cli#603e9dc490d402a07816560f07b6bfecfc902c5a",
|
|
162
162
|
"node-fetch": "^3.3.2",
|
|
163
163
|
"node-stream-zip": "1.15.0",
|
|
164
164
|
"open": "^11.0.0",
|