@automattic/vip 3.22.1 → 3.22.3
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/commands/export-sql.js +22 -14
- package/dist/lib/cli/progress.js +17 -11
- package/npm-shrinkwrap.json +2 -2
- package/package.json +1 -1
|
@@ -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');
|
|
@@ -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,13 @@ class ExportSQLCommand {
|
|
|
348
350
|
}
|
|
349
351
|
size = Number(bytesWrittenMeta.value);
|
|
350
352
|
}
|
|
353
|
+
if (this.skipDownload) {
|
|
354
|
+
this.progressTracker.stepSkipped(this.steps.CONFIRM_ENOUGH_STORAGE);
|
|
355
|
+
this.progressTracker.stepSkipped(this.steps.DOWNLOAD);
|
|
356
|
+
this.progressTracker.print();
|
|
357
|
+
this.progressTracker.stopPrinting();
|
|
358
|
+
return;
|
|
359
|
+
}
|
|
351
360
|
const storageConfirmed = await this.progressTracker.handleContinuePrompt(async setPromptShown => {
|
|
352
361
|
const status = await this.confirmEnoughStorage(Number(size));
|
|
353
362
|
if (status.isPromptShown) {
|
|
@@ -386,6 +395,9 @@ class ExportSQLCommand {
|
|
|
386
395
|
exit.withError(`Error downloading exported file: ${error.message}`);
|
|
387
396
|
}
|
|
388
397
|
}
|
|
398
|
+
generateDownloadURLOutputString(url) {
|
|
399
|
+
return `${_chalk.default.green('Download URL')}: ${url}`;
|
|
400
|
+
}
|
|
389
401
|
async runBackup() {
|
|
390
402
|
if (this.generateBackup) {
|
|
391
403
|
await this.runBackupJob();
|
|
@@ -401,19 +413,15 @@ class ExportSQLCommand {
|
|
|
401
413
|
});
|
|
402
414
|
exit.withError(`No backup found for site ${this.app.name}`);
|
|
403
415
|
}
|
|
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
|
-
}
|
|
416
|
+
const prepareAdditionalInfo = [];
|
|
409
417
|
const showMyDumperWarning = this.showMyDumperWarning && (latestBackup.sqlDumpTool ?? envSqlDumpTool) === 'mydumper';
|
|
410
418
|
if (showMyDumperWarning) {
|
|
411
|
-
|
|
419
|
+
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
420
|
}
|
|
413
421
|
if (await this.getExportJob()) {
|
|
414
|
-
|
|
422
|
+
prepareAdditionalInfo.push(`Attaching to an existing export for the backup with timestamp ${latestBackup.createdAt}`);
|
|
415
423
|
} else {
|
|
416
|
-
|
|
424
|
+
prepareAdditionalInfo.push(`Exporting database backup with timestamp ${latestBackup.createdAt}`);
|
|
417
425
|
try {
|
|
418
426
|
await createExportJob(this.app.id, this.env.id, latestBackup.id);
|
|
419
427
|
} catch (err) {
|
|
@@ -437,11 +445,11 @@ class ExportSQLCommand {
|
|
|
437
445
|
}
|
|
438
446
|
}
|
|
439
447
|
await (0, _utils.pollUntil)(this.getExportJob.bind(this), EXPORT_SQL_PROGRESS_POLL_INTERVAL, this.isPrepared.bind(this));
|
|
440
|
-
this.progressTracker.stepSuccess(this.steps.PREPARE);
|
|
448
|
+
this.progressTracker.stepSuccess(this.steps.PREPARE, prepareAdditionalInfo);
|
|
441
449
|
await (0, _utils.pollUntil)(this.getExportJob.bind(this), EXPORT_SQL_PROGRESS_POLL_INTERVAL, this.isCreated.bind(this));
|
|
442
450
|
this.progressTracker.stepSuccess(this.steps.CREATE);
|
|
443
451
|
const url = await generateDownloadLink(this.app.id, this.env.id, latestBackup.id);
|
|
444
|
-
this.progressTracker.stepSuccess(this.steps.DOWNLOAD_LINK);
|
|
452
|
+
this.progressTracker.stepSuccess(this.steps.DOWNLOAD_LINK, [this.generateDownloadURLOutputString(url)]);
|
|
445
453
|
return url;
|
|
446
454
|
}
|
|
447
455
|
async generateLiveBackupCopy() {
|
|
@@ -466,7 +474,7 @@ class ExportSQLCommand {
|
|
|
466
474
|
copyId
|
|
467
475
|
});
|
|
468
476
|
this.progressTracker.stepSuccess(this.steps.CREATE);
|
|
469
|
-
this.progressTracker.stepSuccess(this.steps.DOWNLOAD_LINK);
|
|
477
|
+
this.progressTracker.stepSuccess(this.steps.DOWNLOAD_LINK, [this.generateDownloadURLOutputString(result.url)]);
|
|
470
478
|
return result;
|
|
471
479
|
} catch (err) {
|
|
472
480
|
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.3",
|
|
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.3",
|
|
10
10
|
"hasInstallScript": true,
|
|
11
11
|
"license": "MIT",
|
|
12
12
|
"dependencies": {
|