@automattic/vip 2.10.0 → 2.11.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/README.md CHANGED
@@ -26,6 +26,14 @@ By default, we record information about the usage of this tool using an in-house
26
26
 
27
27
  ## Changelog
28
28
 
29
+ ### 2.11.0 (11 May 2022)
30
+
31
+ - #1022 [dev-env] Validate docker installed
32
+ - #1026 [dev-env] adds tracking to stop subcommand
33
+ - #1028 Re-calculate the fileMeta if file gets changed by the searchAndReplace
34
+ - #1029 Adds Pendo analytics client
35
+ - #1030 [dev-env] Fix failure tracking
36
+
29
37
  ### 2.10.0 (4 May 2022)
30
38
 
31
39
  - #1021 [dev-env] Add login info and documentation link to `dev-env info`
Binary file
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "tracksUserType": "vip:user_id",
3
3
  "tracksAnonUserType": "anon",
4
- "tracksEventPrefix": "vip_cli_",
5
- "environment": "production"
4
+ "tracksEventPrefix": "vip_cli_dev_",
5
+ "environment": "development"
6
6
  }
@@ -60,6 +60,7 @@ const cmd = (0, _command.default)().option('slug', 'Custom name of the dev envir
60
60
  (0, _devEnvironmentCli.addDevEnvConfigurationOptions)(cmd);
61
61
  cmd.examples(examples);
62
62
  cmd.argv(process.argv, async (arg, opt) => {
63
+ await (0, _devEnvironmentCli.validateDependencies)();
63
64
  const slug = (0, _devEnvironmentCli.getEnvironmentName)(opt);
64
65
  debug('Args: ', arg, 'Options: ', opt);
65
66
  const trackingInfo = {
@@ -38,6 +38,7 @@ const examples = [{
38
38
  description: 'Destroys a local dev environment named foo'
39
39
  }];
40
40
  (0, _command.default)().option('slug', 'Custom name of the dev environment').option('soft', 'Keep config files needed to start an environment intact').examples(examples).argv(process.argv, async (arg, opt) => {
41
+ await (0, _devEnvironmentCli.validateDependencies)();
41
42
  const slug = (0, _devEnvironmentCli.getEnvironmentName)(opt);
42
43
  const trackingInfo = (0, _devEnvironmentCli.getEnvTrackingInfo)(slug);
43
44
  await (0, _tracker.trackEvent)('dev_env_destroy_command_execute', trackingInfo);
@@ -39,6 +39,7 @@ const examples = [{
39
39
  (0, _command.default)({
40
40
  wildcardCommand: true
41
41
  }).option('slug', 'Custom name of the dev environment').examples(examples).argv(process.argv, async (unmatchedArgs, opt) => {
42
+ await (0, _devEnvironmentCli.validateDependencies)();
42
43
  const slug = (0, _devEnvironmentCli.getEnvironmentName)(opt);
43
44
  const trackingInfo = (0, _devEnvironmentCli.getEnvTrackingInfo)(slug);
44
45
  await (0, _tracker.trackEvent)('dev_env_exec_command_execute', trackingInfo);
@@ -36,6 +36,7 @@ const examples = [{
36
36
  (0, _command.default)({
37
37
  requiredArgs: 1
38
38
  }).examples(examples).option('slug', 'Custom name of the dev environment').argv(process.argv, async (unmatchedArgs, opt) => {
39
+ await (0, _devEnvironmentCli.validateDependencies)();
39
40
  const [filePath] = unmatchedArgs;
40
41
  const slug = (0, _devEnvironmentCli.getEnvironmentName)(opt);
41
42
  const trackingInfo = (0, _devEnvironmentCli.getEnvTrackingInfo)(slug);
@@ -45,6 +45,7 @@ const examples = [{
45
45
  (0, _command.default)({
46
46
  requiredArgs: 1
47
47
  }).option('slug', 'Custom name of the dev environment').option('search-replace', 'Perform Search and Replace on the specified SQL file').option('in-place', 'Search and Replace explicitly on the given input file').option('skip-validate', 'Do not perform file validation.').examples(examples).argv(process.argv, async (unmatchedArgs, opt) => {
48
+ await (0, _devEnvironmentCli.validateDependencies)();
48
49
  const [fileName] = unmatchedArgs;
49
50
  const {
50
51
  searchReplace,
@@ -39,6 +39,7 @@ const examples = [{
39
39
  description: 'Return information about a local dev environment named "my_site"'
40
40
  }];
41
41
  (0, _command.default)().option('slug', 'Custom name of the dev environment').option('all', 'Show Info for all local dev environments').examples(examples).argv(process.argv, async (arg, opt) => {
42
+ await (0, _devEnvironmentCli.validateDependencies)();
42
43
  const slug = (0, _devEnvironmentCli.getEnvironmentName)(opt);
43
44
  const trackingInfo = opt.all ? {
44
45
  all: true
@@ -31,6 +31,7 @@ const examples = [{
31
31
  description: 'Return information about all local dev environments'
32
32
  }];
33
33
  (0, _command.default)().examples(examples).argv(process.argv, async () => {
34
+ await (0, _devEnvironmentCli.validateDependencies)();
34
35
  const trackingInfo = {
35
36
  all: true
36
37
  };
@@ -22,10 +22,10 @@ var _command = _interopRequireDefault(require("../lib/cli/command"));
22
22
 
23
23
  var _devEnvironmentCore = require("../lib/dev-environment/dev-environment-core");
24
24
 
25
- var _devEnvironmentCli = require("../lib/dev-environment/dev-environment-cli");
26
-
27
25
  var _devEnvironment = require("../lib/constants/dev-environment");
28
26
 
27
+ var _devEnvironmentCli = require("../lib/dev-environment/dev-environment-cli");
28
+
29
29
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
30
30
 
31
31
  /**
@@ -39,6 +39,7 @@ const examples = [{
39
39
  description: 'Starts a local dev environment'
40
40
  }];
41
41
  (0, _command.default)().option('slug', 'Custom name of the dev environment').option('skip-rebuild', 'Only start stopped services').examples(examples).argv(process.argv, async (arg, opt) => {
42
+ await (0, _devEnvironmentCli.validateDependencies)();
42
43
  const startProcessing = new Date();
43
44
  const slug = (0, _devEnvironmentCli.getEnvironmentName)(opt);
44
45
  const trackingInfo = (0, _devEnvironmentCli.getEnvTrackingInfo)(slug);
@@ -67,7 +68,7 @@ const examples = [{
67
68
  await (0, _devEnvironmentCore.startEnvironment)(slug, options);
68
69
  const processingTime = new Date() - startProcessing;
69
70
  const successTrackingInfo = { ...trackingInfo,
70
- processingTime
71
+ processing_time: processingTime
71
72
  };
72
73
  await (0, _tracker.trackEvent)('dev_env_start_command_success', successTrackingInfo);
73
74
  } catch (error) {
@@ -14,6 +14,8 @@ var _debug = _interopRequireDefault(require("debug"));
14
14
 
15
15
  var _chalk = _interopRequireDefault(require("chalk"));
16
16
 
17
+ var _tracker = require("../lib/tracker");
18
+
17
19
  var _command = _interopRequireDefault(require("../lib/cli/command"));
18
20
 
19
21
  var _devEnvironmentCore = require("../lib/dev-environment/dev-environment-core");
@@ -33,14 +35,18 @@ const examples = [{
33
35
  description: 'Stops a local dev environment'
34
36
  }];
35
37
  (0, _command.default)().option('slug', 'Custom name of the dev environment').examples(examples).argv(process.argv, async (arg, opt) => {
38
+ await (0, _devEnvironmentCli.validateDependencies)();
36
39
  const slug = (0, _devEnvironmentCli.getEnvironmentName)(opt);
37
40
  debug('Args: ', arg, 'Options: ', opt);
41
+ const trackingInfo = (0, _devEnvironmentCli.getEnvTrackingInfo)(slug);
42
+ await (0, _tracker.trackEvent)('dev_env_stop_command_execute', trackingInfo);
38
43
 
39
44
  try {
40
45
  await (0, _devEnvironmentCore.stopEnvironment)(slug);
41
46
  const message = _chalk.default.green('✓') + ' environment stopped.\n';
42
47
  console.log(message);
48
+ await (0, _tracker.trackEvent)('dev_env_stop_command_success', trackingInfo);
43
49
  } catch (error) {
44
- (0, _devEnvironmentCli.handleCLIException)(error);
50
+ (0, _devEnvironmentCli.handleCLIException)(error, 'dev_env_stop_command_error', trackingInfo);
45
51
  }
46
52
  });
@@ -38,6 +38,7 @@ const cmd = (0, _command.default)().option('slug', 'Custom name of the dev envir
38
38
  (0, _devEnvironmentCli.addDevEnvConfigurationOptions)(cmd);
39
39
  cmd.examples(examples);
40
40
  cmd.argv(process.argv, async (arg, opt) => {
41
+ await (0, _devEnvironmentCli.validateDependencies)();
41
42
  const slug = (0, _devEnvironmentCli.getEnvironmentName)(opt);
42
43
  const trackingInfo = (0, _devEnvironmentCli.getEnvTrackingInfo)(slug);
43
44
  await (0, _tracker.trackEvent)('dev_env_update_command_execute', trackingInfo);
@@ -54,6 +54,8 @@ var _progress = require("../lib/cli/progress");
54
54
 
55
55
  var _isMultiSite = require("../lib/validations/is-multi-site");
56
56
 
57
+ var _rollbar = require("../lib/rollbar");
58
+
57
59
  function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
58
60
 
59
61
  function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
@@ -379,7 +381,7 @@ const displayPlaybook = ({
379
381
  } = env;
380
382
  const [fileName] = arg;
381
383
  const isMultiSite = await (0, _isMultiSite.isMultiSiteInSiteMeta)(appId, envId);
382
- const fileMeta = await (0, _clientFileUploader.getFileMeta)(fileName);
384
+ let fileMeta = await (0, _clientFileUploader.getFileMeta)(fileName);
383
385
 
384
386
  if (fileMeta.isCompressed) {
385
387
  console.log(_chalk.default.yellowBright('You are importing a compressed file. Validation and search-replace operation will be skipped.'));
@@ -453,6 +455,9 @@ Processing the SQL import for your environment...
453
455
  progressTracker.print({
454
456
  clearAfter: true
455
457
  });
458
+
459
+ _rollbar.rollbar.error(failureError);
460
+
456
461
  exit.withError(failureError);
457
462
  };
458
463
 
@@ -474,6 +479,7 @@ Processing the SQL import for your environment...
474
479
  }
475
480
 
476
481
  fileNameToUpload = outputFileName;
482
+ fileMeta = await (0, _clientFileUploader.getFileMeta)(fileNameToUpload);
477
483
  progressTracker.stepSuccess('replace');
478
484
  } else {
479
485
  progressTracker.stepSkipped('replace');
@@ -0,0 +1,92 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = void 0;
7
+
8
+ var _api = _interopRequireDefault(require("../../api"));
9
+
10
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
11
+
12
+ function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
13
+
14
+ /**
15
+ * External dependencies
16
+ */
17
+ const debug = require('debug')('@automattic/vip:analytics:clients:pendo');
18
+ /**
19
+ * Internal dependencies
20
+ */
21
+
22
+
23
+ /**
24
+ * Pendo analytics client.
25
+ */
26
+ class Pendo {
27
+ static get ENDPOINT() {
28
+ return '/pendo';
29
+ }
30
+
31
+ constructor({
32
+ userId,
33
+ eventPrefix,
34
+ env
35
+ }) {
36
+ _defineProperty(this, "context", {});
37
+
38
+ this.eventPrefix = eventPrefix;
39
+ this.userAgent = env.userAgent;
40
+ this.userId = userId;
41
+ this.context = { ...env
42
+ };
43
+ }
44
+
45
+ async trackEvent(eventName, eventProps = {}) {
46
+ if (!eventName.startsWith(this.eventPrefix)) {
47
+ eventName = this.eventPrefix + eventName;
48
+ }
49
+
50
+ debug('trackEvent()', eventProps);
51
+ this.context = { ...this.context,
52
+ org_id: eventProps.org_slug,
53
+ org_slug: eventProps.org_slug,
54
+ userAgent: this.userAgent,
55
+ userId: this.userId
56
+ };
57
+
58
+ try {
59
+ return await this.send(eventName, eventProps);
60
+ } catch (error) {
61
+ debug(error);
62
+ } // Resolve to false instead of rejecting
63
+
64
+
65
+ return Promise.resolve(false);
66
+ }
67
+
68
+ async send(eventName, eventProps) {
69
+ const body = {
70
+ context: this.context,
71
+ event: eventName,
72
+ properties: eventProps,
73
+ timestamp: Date.now(),
74
+ type: 'track',
75
+ visitorId: `${this.context.userId}`
76
+ };
77
+ debug('send()', body);
78
+ const {
79
+ apiFetch
80
+ } = await (0, _api.default)();
81
+ const response = await apiFetch(Pendo.ENDPOINT, {
82
+ method: 'POST',
83
+ body
84
+ });
85
+ const responseText = await response.text();
86
+ debug('response', responseText);
87
+ return responseText;
88
+ }
89
+
90
+ }
91
+
92
+ exports.default = Pendo;
@@ -26,13 +26,18 @@ const client_info = {
26
26
 
27
27
  class Analytics {
28
28
  constructor({
29
- tracks = new _stub.default()
29
+ clients = new _stub.default()
30
30
  }) {
31
- this.tracks = tracks;
31
+ this.clients = clients;
32
32
  }
33
33
 
34
34
  async trackEvent(name, props = {}) {
35
- return Promise.all([this.tracks.trackEvent(name, Object.assign({}, client_info, props))]);
35
+ return Promise.all(this.clients.map(client => {
36
+ return client.trackEvent(name, { // eslint-disable-next-line camelcase
37
+ ...client_info,
38
+ ...props
39
+ });
40
+ }));
36
41
  }
37
42
 
38
43
  }
@@ -18,6 +18,7 @@ exports.promptForComponent = promptForComponent;
18
18
  exports.addDevEnvConfigurationOptions = addDevEnvConfigurationOptions;
19
19
  exports.getTagChoices = getTagChoices;
20
20
  exports.getEnvTrackingInfo = getEnvTrackingInfo;
21
+ exports.validateDependencies = void 0;
21
22
 
22
23
  var _chalk = _interopRequireDefault(require("chalk"));
23
24
 
@@ -33,12 +34,20 @@ var _path = _interopRequireDefault(require("path"));
33
34
 
34
35
  var _os = _interopRequireDefault(require("os"));
35
36
 
37
+ var exit = _interopRequireWildcard(require("../cli/exit"));
38
+
36
39
  var _tracker = require("../tracker");
37
40
 
38
41
  var _devEnvironment = require("../constants/dev-environment");
39
42
 
40
43
  var _devEnvironmentCore = require("./dev-environment-core");
41
44
 
45
+ var _devEnvironmentLando = require("./dev-environment-lando");
46
+
47
+ function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
48
+
49
+ function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
50
+
42
51
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
43
52
 
44
53
  /**
@@ -73,7 +82,7 @@ async function handleCLIException(exception, trackKey, trackBaseInfo = {}) {
73
82
  if (trackKey) {
74
83
  try {
75
84
  const errorTrackingInfo = { ...trackBaseInfo,
76
- error: message
85
+ failure: message
77
86
  };
78
87
  await (0, _tracker.trackEvent)(trackKey, errorTrackingInfo);
79
88
  } catch (trackException) {
@@ -91,6 +100,16 @@ async function handleCLIException(exception, trackKey, trackBaseInfo = {}) {
91
100
  }
92
101
  }
93
102
 
103
+ const validateDependencies = async () => {
104
+ try {
105
+ await (0, _devEnvironmentLando.validateDockerInstalled)();
106
+ } catch (exception) {
107
+ exit.withError(exception.message);
108
+ }
109
+ };
110
+
111
+ exports.validateDependencies = validateDependencies;
112
+
94
113
  function getEnvironmentName(options) {
95
114
  if (options.slug) {
96
115
  return options.slug;
@@ -476,7 +495,8 @@ function getEnvTrackingInfo(slug) {
476
495
  for (const key of Object.keys(envData)) {
477
496
  // track doesnt like camelCase
478
497
  const snakeCasedKey = key.replace(/[A-Z]/g, letter => `_${letter.toLowerCase()}`);
479
- result[snakeCasedKey] = envData[key];
498
+ const value = _devEnvironment.DEV_ENVIRONMENT_COMPONENTS.includes(key) ? JSON.stringify(envData[key]) : envData[key];
499
+ result[snakeCasedKey] = value;
480
500
  }
481
501
 
482
502
  return result;
@@ -9,6 +9,7 @@ exports.landoStop = landoStop;
9
9
  exports.landoDestroy = landoDestroy;
10
10
  exports.landoInfo = landoInfo;
11
11
  exports.landoExec = landoExec;
12
+ exports.validateDockerInstalled = validateDockerInstalled;
12
13
 
13
14
  var _debug = _interopRequireDefault(require("debug"));
14
15
 
@@ -310,4 +311,20 @@ async function ensureNoOrphantProxyContainer(lando) {
310
311
  }
311
312
 
312
313
  await proxyContainer.remove();
314
+ }
315
+
316
+ async function validateDockerInstalled() {
317
+ const lando = new _lando.default(getLandoConfig());
318
+ await lando.bootstrap();
319
+ lando.log.verbose('docker-engine exists: %s', lando.engine.dockerInstalled);
320
+
321
+ if (lando.engine.dockerInstalled === false) {
322
+ throw Error('docker could not be located! Please follow the following instructions to install it - https://docs.docker.com/engine/install/');
323
+ }
324
+
325
+ lando.log.verbose('docker-compose exists: %s', lando.engine.composeInstalled);
326
+
327
+ if (lando.engine.composeInstalled === false) {
328
+ throw Error('docker-compose could not be located! Please follow the following instructions to install it - https://docs.docker.com/compose/install/');
329
+ }
313
330
  }
@@ -11,6 +11,8 @@ var _index = _interopRequireDefault(require("./analytics/index"));
11
11
 
12
12
  var _tracks = _interopRequireDefault(require("./analytics/clients/tracks"));
13
13
 
14
+ var _pendo = _interopRequireDefault(require("./analytics/clients/pendo"));
15
+
14
16
  var _token = _interopRequireDefault(require("./token"));
15
17
 
16
18
  var _config = _interopRequireDefault(require("../../config/config.json"));
@@ -32,15 +34,22 @@ let analytics = null;
32
34
 
33
35
  async function init() {
34
36
  const uuid = await _token.default.uuid();
35
- const clients = {};
37
+ const clients = [];
36
38
  const tracksUserType = _config.default.tracksUserType;
37
39
  const tracksEventPrefix = _config.default.tracksEventPrefix;
38
40
 
39
41
  if (tracksUserType && tracksEventPrefix) {
40
- clients.tracks = new _tracks.default(uuid, tracksUserType, tracksEventPrefix, _env.default);
42
+ clients.push(new _tracks.default(uuid, tracksUserType, tracksEventPrefix, _env.default));
43
+ clients.push(new _pendo.default({
44
+ env: _env.default,
45
+ eventPrefix: tracksEventPrefix,
46
+ userId: uuid
47
+ }));
41
48
  }
42
49
 
43
- analytics = new _index.default(clients);
50
+ analytics = new _index.default({
51
+ clients
52
+ });
44
53
  return analytics;
45
54
  }
46
55
 
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@automattic/vip",
3
- "version": "2.10.0",
3
+ "version": "2.11.0",
4
4
  "lockfileVersion": 1,
5
5
  "requires": true,
6
6
  "dependencies": {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@automattic/vip",
3
- "version": "2.10.0",
3
+ "version": "2.11.0",
4
4
  "description": "The VIP Javascript library & CLI",
5
5
  "main": "index.js",
6
6
  "bin": {