@automattic/vip 2.27.0-dev7 → 2.28.0-dev

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.
@@ -18,4 +18,4 @@ var _command = _interopRequireDefault(require("../lib/cli/command"));
18
18
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
19
19
  (0, _command.default)({
20
20
  requiredArgs: 0
21
- }).command('create', 'Create a new local dev environment').command('update', 'Update an already created local dev environment').command('start', 'Start a local dev environment').command('stop', 'Stop a local dev environment').command('destroy', 'Remove containers, networks, volumes and configuration files of a local dev environment').command('info', 'Provides basic info about one or multiple local dev environments').command('list', 'Provides basic info about all local dev environments').command('exec', 'Execute a WP-CLI command in local dev environment').command('import', 'Import data into a local WordPress environment').command('shell', 'Spawns a shell in a dev environment').command('logs', 'View logs from a local WordPress environment').command('sync', 'Pull data from production to local development environment').argv(process.argv);
21
+ }).command('create', 'Create a new local dev environment').command('update', 'Update an already created local dev environment').command('start', 'Start a local dev environment').command('stop', 'Stop a local dev environment').command('destroy', 'Remove containers, networks, volumes and configuration files of a local dev environment').command('info', 'Provides basic info about one or multiple local dev environments').command('list', 'Provides basic info about all local dev environments').command('exec', 'Execute a WP-CLI command in local dev environment').command('import', 'Import data into a local WordPress environment').command('shell', 'Spawns a shell in a dev environment').command('logs', 'View logs from a local WordPress environment').argv(process.argv);
@@ -16,7 +16,6 @@ Object.defineProperty(exports, "__esModule", {
16
16
  exports.DevEnvSyncSQLCommand = void 0;
17
17
  var _fs = _interopRequireDefault(require("fs"));
18
18
  var _chalk = _interopRequireDefault(require("chalk"));
19
- var _url = _interopRequireDefault(require("url"));
20
19
  var _vipSearchReplace = require("@automattic/vip-search-replace");
21
20
  var _clientFileUploader = require("../lib/client-file-uploader");
22
21
  var _exportSql = require("./export-sql");
@@ -40,8 +39,8 @@ function findSiteHomeUrl(sql) {
40
39
  const regex = "'(siteurl|home)',\\s?'(.*?)'";
41
40
  const results = sql.match(regex);
42
41
  if (results) {
43
- const url = results[2];
44
- return _url.default.parse(url).hostname;
42
+ const domain = results[2].replace(/https?:\/\//, '');
43
+ return domain;
45
44
  }
46
45
  return null;
47
46
  }
@@ -56,15 +55,15 @@ function findSiteHomeUrl(sql) {
56
55
  async function extractSiteUrls(sqlFile) {
57
56
  const readInterface = await (0, _lineByLine.getReadInterface)(sqlFile);
58
57
  return new Promise((resolve, reject) => {
59
- const domains = new Set();
58
+ const domains = [];
60
59
  readInterface.on('line', line => {
61
60
  const domain = findSiteHomeUrl(line);
62
61
  if (domain) {
63
- domains.add('//' + domain);
62
+ domains.push(domain);
64
63
  }
65
64
  });
66
65
  readInterface.on('close', () => {
67
- resolve(Array.from(domains));
66
+ resolve(domains);
68
67
  });
69
68
  readInterface.on('error', reject);
70
69
  });
@@ -73,20 +72,18 @@ class DevEnvSyncSQLCommand {
73
72
  /**
74
73
  * Creates a new instance of the command
75
74
  *
76
- * @param {string} app The app object
77
- * @param {string} env The environment object
78
- * @param {string} slug The site slug
79
- * @param {Function} trackerFn Function to call for tracking
75
+ * @param {string} app The app object
76
+ * @param {string} env The environment object
77
+ * @param {string} slug The site slug
80
78
  */
81
- constructor(app, env, slug, trackerFn = () => {}) {
79
+ constructor(app, env, slug) {
82
80
  this.app = app;
83
81
  this.env = env;
84
82
  this.slug = slug;
85
- this.track = trackerFn;
86
83
  this.tmpDir = (0, _utils.makeTempDir)();
87
84
  }
88
85
  get landoDomain() {
89
- return `//${this.slug}.vipdev.lndo.site`;
86
+ return `${this.slug}.vipdev.lndo.site`;
90
87
  }
91
88
  get sqlFile() {
92
89
  return `${this.tmpDir}/sql-export.sql`;
@@ -102,7 +99,7 @@ class DevEnvSyncSQLCommand {
102
99
  * @return {Promise<void>} Promise that resolves when the export is complete
103
100
  */
104
101
  async generateExport() {
105
- const exportCommand = new _exportSql.ExportSQLCommand(this.app, this.env, this.gzFile, this.track);
102
+ const exportCommand = new _exportSql.ExportSQLCommand(this.app, this.env, this.gzFile);
106
103
  await exportCommand.run();
107
104
  }
108
105
 
@@ -117,13 +114,9 @@ class DevEnvSyncSQLCommand {
117
114
  const replacements = this.siteUrls.reduce((acc, url) => [...acc, url, this.landoDomain], []);
118
115
  const readStream = _fs.default.createReadStream(this.sqlFile);
119
116
  const replacedStream = await (0, _vipSearchReplace.replace)(readStream, replacements);
120
- const outputFile = `${this.tmpDir}/sql-export-sr.sql`;
121
- replacedStream.pipe(_fs.default.createWriteStream(outputFile));
117
+ replacedStream.pipe(_fs.default.createWriteStream(this.sqlFile));
122
118
  return new Promise((resolve, reject) => {
123
- replacedStream.on('finish', () => {
124
- _fs.default.renameSync(outputFile, this.sqlFile);
125
- resolve();
126
- });
119
+ replacedStream.on('finish', resolve);
127
120
  replacedStream.on('error', reject);
128
121
  });
129
122
  }
@@ -136,10 +129,11 @@ class DevEnvSyncSQLCommand {
136
129
  */
137
130
  async runImport() {
138
131
  const importOptions = {
132
+ slug: this.slug,
139
133
  inPlace: true,
140
134
  skipValidate: true
141
135
  };
142
- const importCommand = new _devEnvImportSql.DevEnvImportSQLCommand(this.sqlFile, importOptions, this.slug);
136
+ const importCommand = new _devEnvImportSql.DevEnvImportSQLCommand(this.sqlFile, importOptions);
143
137
  await importCommand.run(true);
144
138
  }
145
139
 
@@ -160,9 +154,6 @@ class DevEnvSyncSQLCommand {
160
154
  await (0, _clientFileUploader.unzipFile)(this.gzFile, this.sqlFile);
161
155
  console.log(`${_chalk.default.green('✓')} Extracted to ${this.sqlFile}`);
162
156
  } catch (err) {
163
- await this.track('archive_extraction_error', {
164
- errorMessage: err === null || err === void 0 ? void 0 : err.message
165
- });
166
157
  exit.withError(`Error extracting the SQL export: ${err === null || err === void 0 ? void 0 : err.message}`);
167
158
  }
168
159
  try {
@@ -179,9 +170,6 @@ class DevEnvSyncSQLCommand {
179
170
  await this.runSearchReplace();
180
171
  console.log(`${_chalk.default.green('✓')} Search-replace operation is complete`);
181
172
  } catch (err) {
182
- await this.track('search_replace_error', {
183
- errorMessage: err === null || err === void 0 ? void 0 : err.message
184
- });
185
173
  exit.withError(`Error replacing domains: ${err === null || err === void 0 ? void 0 : err.message}`);
186
174
  }
187
175
  try {
@@ -189,9 +177,6 @@ class DevEnvSyncSQLCommand {
189
177
  await this.runImport();
190
178
  console.log(`${_chalk.default.green('✓')} SQL file imported`);
191
179
  } catch (err) {
192
- await this.track('import_error', {
193
- errorMessage: err === null || err === void 0 ? void 0 : err.message
194
- });
195
180
  exit.withError(`Error importing SQL file: ${err === null || err === void 0 ? void 0 : err.message}`);
196
181
  }
197
182
  }
@@ -8,7 +8,7 @@ var _graphqlTag = _interopRequireDefault(require("graphql-tag"));
8
8
  var _fs = _interopRequireDefault(require("fs"));
9
9
  var _https = _interopRequireDefault(require("https"));
10
10
  var _path = _interopRequireDefault(require("path"));
11
- var _api = _interopRequireWildcard(require("../lib/api"));
11
+ var _api = _interopRequireDefault(require("../lib/api"));
12
12
  var _format = require("../lib/cli/format");
13
13
  var _progress = require("../lib/cli/progress");
14
14
  var exit = _interopRequireWildcard(require("../lib/cli/exit"));
@@ -162,10 +162,8 @@ async function generateDownloadLink(appId, envId, backupId) {
162
162
  * @throws {Error} Throws an error if the job creation fails
163
163
  */
164
164
  async function createExportJob(appId, envId, backupId) {
165
- // Disable global error handling so that we can handle errors ourselves
166
- (0, _api.disableGlobalGraphQLErrorHandling)();
167
165
  const api = await (0, _api.default)();
168
- await api.mutate({
166
+ const response = await api.mutate({
169
167
  mutation: CREATE_EXPORT_JOB_MUTATION,
170
168
  variables: {
171
169
  input: {
@@ -175,9 +173,16 @@ async function createExportJob(appId, envId, backupId) {
175
173
  }
176
174
  }
177
175
  });
178
-
179
- // Re-enable global error handling
180
- (0, _api.enableGlobalGraphQLErrorHandling)();
176
+ const {
177
+ data: {
178
+ startDBBackupCopy: {
179
+ success
180
+ }
181
+ }
182
+ } = response;
183
+ if (!success) {
184
+ throw new Error();
185
+ }
181
186
  }
182
187
 
183
188
  /**
@@ -190,15 +195,15 @@ class ExportSQLCommand {
190
195
  DOWNLOAD_LINK: 'downloadLink',
191
196
  DOWNLOAD: 'download'
192
197
  };
198
+
193
199
  /**
194
200
  * Creates an instance of SQLExportCommand
195
201
  *
196
- * @param {any} app The application object
197
- * @param {any} env The environment object
198
- * @param {string} outputFile The output file path
199
- * @param {Function} trackerFn The progress tracker function
202
+ * @param {any} app The application object
203
+ * @param {any} env The environment object
204
+ * @param {string} outputFile The output file path
200
205
  */
201
- constructor(app, env, outputFile, trackerFn = () => {}) {
206
+ constructor(app, env, outputFile) {
202
207
  this.app = app;
203
208
  this.env = env;
204
209
  this.outputFile = outputFile;
@@ -215,7 +220,6 @@ class ExportSQLCommand {
215
220
  id: this.steps.DOWNLOAD,
216
221
  name: 'Downloading file'
217
222
  }]);
218
- this.track = trackerFn;
219
223
  }
220
224
 
221
225
  /**
@@ -315,29 +319,21 @@ class ExportSQLCommand {
315
319
  latestBackup
316
320
  } = await fetchLatestBackupAndJobStatus(this.app.id, this.env.id);
317
321
  if (!latestBackup) {
318
- await this.track('no_backup_found_error', {
319
- errorMessage: 'No backup found for the site'
320
- });
321
322
  exit.withError(`No backup found for site ${this.app.name}`);
322
323
  } else {
323
324
  console.log(`${(0, _format.getGlyphForStatus)('success')} Latest backup found with timestamp ${latestBackup.createdAt}`);
324
325
  }
325
- if (await this.getExportJob()) {
326
- console.log(`Attaching to an existing export for the backup with timestamp ${latestBackup.createdAt}`);
327
- } else {
326
+
327
+ // See if there is an existing export job for the latest backup
328
+ if (!(await this.getExportJob())) {
328
329
  console.log(`Creating a new export for the backup with timestamp ${latestBackup.createdAt}`);
329
330
  try {
330
331
  await createExportJob(this.app.id, this.env.id, latestBackup.id);
331
332
  } catch (err) {
332
- // Todo: match error code instead of message substring
333
- if (err !== null && err !== void 0 && err.message.includes('Backup Copy already in progress')) {
334
- await this.track('export_job_already_running_error', {
335
- errorMessage: err === null || err === void 0 ? void 0 : err.message
336
- });
337
- exit.withError('There is an export job already running for this site: ' + `https://dashboard.wpvip.com/apps/${this.app.id}/${this.env.uniqueLabel}/data/database/backups\n` + 'Currently, we allow only one export job per site. Please try again later.');
338
- }
339
333
  exit.withError(`Error creating export job: ${err === null || err === void 0 ? void 0 : err.message}`);
340
334
  }
335
+ } else {
336
+ console.log(`Attaching to an existing export for the backup with timestamp ${latestBackup.createdAt}`);
341
337
  }
342
338
  this.progressTracker.stepRunning(this.steps.PREPARE);
343
339
  this.progressTracker.startPrinting();
@@ -357,9 +353,6 @@ class ExportSQLCommand {
357
353
  } catch (err) {
358
354
  this.progressTracker.stepFailed(this.steps.DOWNLOAD);
359
355
  this.stopProgressTracker();
360
- await this.track('download_failed_error', {
361
- errorMessage: err === null || err === void 0 ? void 0 : err.message
362
- });
363
356
  exit.withError(`Error downloading exported file: ${err === null || err === void 0 ? void 0 : err.message}`);
364
357
  }
365
358
  }
@@ -83,13 +83,7 @@ async function getLandoConfig() {
83
83
  subdir: '.',
84
84
  namespace: '@lando'
85
85
  }],
86
- disablePlugins: [
87
- // Plugins we need:
88
- // '@lando/compose',
89
- // '@lando/mailhog',
90
- // '@lando/phpmyadmin',
91
- // The rest we don't need
92
- '@lando/acquia', '@lando/apache', '@lando/argv', '@lando/backdrop', '@lando/dotnet', '@lando/drupal', '@lando/elasticsearch', '@lando/go', '@lando/joomla', '@lando/lagoon', '@lando/lamp', '@lando/laravel', '@lando/lemp', '@lando/mariadb', '@lando/mean', '@lando/memcached', '@lando/mongo', '@lando/mssql', '@lando/mysql', '@lando/nginx', '@lando/node', '@lando/pantheon', '@lando/php', '@lando/platformsh', '@lando/postgres', '@lando/python', '@lando/redis', '@lando/ruby', '@lando/solr', '@lando/symfony', '@lando/tomcat', '@lando/varnish', '@lando/wordpress'],
86
+ disablePlugins: ['@lando/argv'],
93
87
  proxyName: 'vip-dev-env-proxy',
94
88
  userConfRoot: landoDir,
95
89
  home: fakeHomeDir,
@@ -4,7 +4,6 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.aliasUser = aliasUser;
7
- exports.makeCommandTracker = makeCommandTracker;
8
7
  exports.trackEvent = trackEvent;
9
8
  exports.trackEventWithEnv = trackEventWithEnv;
10
9
  var _index = _interopRequireDefault(require("./analytics/index"));
@@ -78,13 +77,4 @@ async function trackEventWithEnv(appId, envId, eventName, eventProps = {}) {
78
77
  app_id: appId,
79
78
  env_id: envId
80
79
  });
81
- }
82
- function makeCommandTracker(command, trackingInfo = {}) {
83
- const trackerFn = async (type, data = {}) => {
84
- await trackEvent(`${command}_command_${type}`, {
85
- ...trackingInfo,
86
- ...data
87
- });
88
- };
89
- return trackerFn;
90
80
  }