@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.
@@ -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
- if (!this.generateBackup) {
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
- console.warn(_chalk.default.yellow.bold('WARNING:'), _chalk.default.yellow('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'));
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
- console.log(`Attaching to an existing export for the backup with timestamp ${latestBackup.createdAt}`);
422
+ prepareAdditionalInfo.push(`Attaching to an existing export for the backup with timestamp ${latestBackup.createdAt}`);
415
423
  } else {
416
- console.log(`Exporting database backup with timestamp ${latestBackup.createdAt}`);
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';
@@ -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
 
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "@automattic/vip",
3
- "version": "3.22.1",
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.1",
9
+ "version": "3.22.3",
10
10
  "hasInstallScript": true,
11
11
  "license": "MIT",
12
12
  "dependencies": {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@automattic/vip",
3
- "version": "3.22.1",
3
+ "version": "3.22.3",
4
4
  "description": "The VIP Javascript library & CLI",
5
5
  "main": "index.js",
6
6
  "bin": {