@automattic/vip 2.5.0 → 2.7.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
@@ -27,6 +27,23 @@ By default, we record information about the usage of this tool using an in-house
27
27
 
28
28
  ## Changelog
29
29
 
30
+ ### 2.7.0 (07 December 2021)
31
+ - #941 [dev-env] Bump lando CLI dependency
32
+ - #938 Hide roll back message after SQL Import failure for launched sites
33
+ - #936 Sets jest maxWorkers to 4
34
+
35
+ https://github.com/Automattic/vip/releases/tag/v2.7.0
36
+
37
+ ### 2.6.0 (23 November 2021)
38
+ - #921 [dev-env] Introuces update to change existing environment
39
+ - #928 [dev-env] Switch lando to use our fork
40
+ - #927 [dev-env] Handles user already exists during sql import
41
+ - #925 [dev-env] Fix the issue with dev-env update
42
+ - #924 FORNO-985 Increase SQL Import limit for unlaunched sites to 100GB
43
+ - #923 FORNO-943 Fixes a bug which prevents displaying SQL Import error messages
44
+ - #922 Update eslint-config-wpvip commit hash to c6605d1
45
+ - #873 Pin dependencies
46
+
30
47
  ### 2.5.0 (9 November 2021)
31
48
  - #919 [dev-env] Expose lando core logs
32
49
  - #916 [dev-env] Save instance data state
@@ -50,23 +50,14 @@ const examples = [{
50
50
  usage: `${_devEnvironment.DEV_ENVIRONMENT_FULL_COMMAND} create --multisite --wordpress "5.8" --client-code "~/git/my_code"`,
51
51
  description: 'Creates a local multisite dev environment using WP 5.8 and client code is expected to be in "~/git/my_code"'
52
52
  }];
53
- (0, _command.default)().option('slug', 'Custom name of the dev environment').option('title', 'Title for the WordPress site').option('multisite', 'Enable multisite install', undefined, value => {
53
+ const cmd = (0, _command.default)().option('slug', 'Custom name of the dev environment').option('title', 'Title for the WordPress site').option('multisite', 'Enable multisite install', undefined, value => {
54
54
  var _value$toLowerCase;
55
55
 
56
56
  return 'false' !== (value === null || value === void 0 ? void 0 : (_value$toLowerCase = value.toLowerCase) === null || _value$toLowerCase === void 0 ? void 0 : _value$toLowerCase.call(value));
57
- }).option('wordpress', 'Use a specific WordPress version').option(['u', 'mu-plugins'], 'Use a specific mu-plugins changeset or local directory').option('client-code', 'Use the client code from a local directory or VIP skeleton').option('statsd', 'Enable statsd component. By default it is disabled', undefined, value => {
58
- var _value$toLowerCase2;
59
-
60
- return 'false' !== (value === null || value === void 0 ? void 0 : (_value$toLowerCase2 = value.toLowerCase) === null || _value$toLowerCase2 === void 0 ? void 0 : _value$toLowerCase2.call(value));
61
- }).option('phpmyadmin', 'Enable PHPMyAdmin component. By default it is disabled', undefined, value => {
62
- var _value$toLowerCase3;
63
-
64
- return 'false' !== (value === null || value === void 0 ? void 0 : (_value$toLowerCase3 = value.toLowerCase) === null || _value$toLowerCase3 === void 0 ? void 0 : _value$toLowerCase3.call(value));
65
- }).option('xdebug', 'Enable XDebug. By default it is disabled', undefined, value => {
66
- var _value$toLowerCase4;
67
-
68
- return 'false' !== (value === null || value === void 0 ? void 0 : (_value$toLowerCase4 = value.toLowerCase) === null || _value$toLowerCase4 === void 0 ? void 0 : _value$toLowerCase4.call(value));
69
- }).option('elasticsearch', 'Explicitly choose Elasticsearch version to use').option('mariadb', 'Explicitly choose MariaDB version to use').option('media-redirect-domain', 'Domain to redirect for missing media files. This can be used to still have images without the need to import them locally.').examples(examples).argv(process.argv, async (arg, opt) => {
57
+ });
58
+ (0, _devEnvironmentCli.addDevEnvConfigurationOptions)(cmd);
59
+ cmd.examples(examples);
60
+ cmd.argv(process.argv, async (arg, opt) => {
70
61
  const slug = (0, _devEnvironmentCli.getEnvironmentName)(opt);
71
62
  debug('Args: ', arg, 'Options: ', opt);
72
63
 
@@ -79,11 +70,12 @@ const examples = [{
79
70
  exit.withError(messageToShow);
80
71
  }
81
72
 
82
- let appInfo = {};
73
+ let defaultOptions = {};
83
74
 
84
75
  try {
85
76
  if (opt.app) {
86
- appInfo = await (0, _devEnvironmentCore.getApplicationInformation)(opt.app, opt.env);
77
+ const appInfo = await (0, _devEnvironmentCore.getApplicationInformation)(opt.app, opt.env);
78
+ defaultOptions = (0, _devEnvironmentCli.getOptionsFromAppInfo)(appInfo);
87
79
  }
88
80
  } catch (error) {
89
81
  const message = `failed to fetch application "${opt.app}" information`;
@@ -91,16 +83,11 @@ const examples = [{
91
83
  console.log(_chalk.default.yellow('Warning:'), message);
92
84
  }
93
85
 
94
- const instanceData = await (0, _devEnvironmentCli.promptForArguments)(opt, appInfo);
95
- const instanceDataWithSlug = { ...instanceData,
96
- siteSlug: slug,
97
- statsd: opt.statsd || false,
98
- phpmyadmin: opt.phpmyadmin || false,
99
- xdebug: opt.xdebug || false
100
- };
86
+ const instanceData = await (0, _devEnvironmentCli.promptForArguments)(opt, defaultOptions);
87
+ instanceData.siteSlug = slug;
101
88
 
102
89
  try {
103
- await (0, _devEnvironmentCore.createEnvironment)(instanceDataWithSlug);
90
+ await (0, _devEnvironmentCore.createEnvironment)(instanceData);
104
91
  await (0, _devEnvironmentCore.printEnvironmentInfo)(slug);
105
92
  const message = '\n' + _chalk.default.green('✓') + ` environment created.\n\nTo start it please run:\n\n${startCommand}\n`;
106
93
  console.log(message);
@@ -12,6 +12,8 @@
12
12
 
13
13
  var _fs = _interopRequireDefault(require("fs"));
14
14
 
15
+ var _chalk = _interopRequireDefault(require("chalk"));
16
+
15
17
  var _command = _interopRequireDefault(require("../lib/cli/command"));
16
18
 
17
19
  var _devEnvironmentCli = require("../lib/dev-environment/dev-environment-cli");
@@ -62,8 +64,17 @@ const examples = [{
62
64
 
63
65
  const cacheArg = ['wp', 'cache', 'flush'];
64
66
  await (0, _devEnvironmentCore.exec)(slug, cacheArg);
65
- const addUserArg = ['wp', 'user', 'create', 'vipgo', 'vipgo@go-vip.net', '--user_pass=password', '--role=administrator'];
66
- await (0, _devEnvironmentCore.exec)(slug, addUserArg);
67
+
68
+ try {
69
+ const addUserArg = ['wp', 'user', 'create', 'vipgo', 'vipgo@go-vip.net', '--user_pass=password', '--role=administrator'];
70
+ await (0, _devEnvironmentCore.exec)(slug, addUserArg);
71
+ } catch (exception) {
72
+ if ((exception.message || '').includes('is already registered')) {
73
+ console.log(_chalk.default.bold(_chalk.default.green('Success: ')) + 'Skipping user vipgo provisioning');
74
+ } else {
75
+ throw exception;
76
+ }
77
+ }
67
78
  } catch (error) {
68
79
  (0, _devEnvironmentCli.handleCLIException)(error);
69
80
  }
@@ -53,14 +53,22 @@ cmd.argv(process.argv, async (arg, opt) => {
53
53
  multisite: currentInstanceData.multisite,
54
54
  ...opt
55
55
  };
56
- debug('Combined preselected data are', preselectedOptions);
57
- const instanceData = await (0, _devEnvironmentCli.promptForArguments)(preselectedOptions, {}); // const instanceDataWithSlug = {
58
- // ...currentInstanceData,
59
- // siteSlug: slug,
60
- // statsd: opt.statsd || false,
61
- // phpmyadmin: opt.phpmyadmin || false,
62
- // xdebug: opt.xdebug || false,
63
- // };
56
+ const defaultOptions = {
57
+ clientCode: currentInstanceData.clientCode.dir || currentInstanceData.clientCode.tag || 'latest',
58
+ muPlugins: currentInstanceData.muPlugins.dir || currentInstanceData.muPlugins.tag || 'latest',
59
+ wordpress: currentInstanceData.wordpress.tag,
60
+ elasticsearch: currentInstanceData.elasticsearch,
61
+ mariadb: currentInstanceData.mariadb,
62
+ statsd: currentInstanceData.statsd,
63
+ phpmyadmin: currentInstanceData.phpmyadmin,
64
+ xdebug: currentInstanceData.xdebug,
65
+ mediaRedirectDomain: currentInstanceData.mediaRedirectDomain
66
+ };
67
+ const instanceData = await (0, _devEnvironmentCli.promptForArguments)(preselectedOptions, defaultOptions);
68
+ instanceData.siteSlug = slug;
69
+ await (0, _devEnvironmentCore.updateEnvironment)(instanceData);
70
+ const message = '\n' + _chalk.default.green('✓') + ' environment updated. Restart environment for changes to take an affect.';
71
+ console.log(message);
64
72
  } catch (error) {
65
73
  if ('ENOENT' === error.code) {
66
74
  const message = 'Environment was created before update was supported.\n\nTo update environment please destroy it and create a new one.';
@@ -20,4 +20,4 @@ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { de
20
20
 
21
21
  (0, _command.default)({
22
22
  requiredArgs: 1
23
- }).command('create', 'Create a new 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('exec', 'Execute an operation on a dev environment').command('import', 'Import data into a local WordPress environment').argv(process.argv);
23
+ }).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('exec', 'Execute an operation on a dev environment').command('import', 'Import data into a local WordPress environment').argv(process.argv);
@@ -495,7 +495,8 @@ Processing the SQL import for your environment...
495
495
  id: app.id,
496
496
  environmentId: env.id,
497
497
  basename: basename,
498
- md5: md5
498
+ md5: md5,
499
+ searchReplace: []
499
500
  };
500
501
 
501
502
  if (searchReplace) {
@@ -0,0 +1,151 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * Internal dependencies
5
+ */
6
+ "use strict";
7
+
8
+ Object.defineProperty(exports, "__esModule", {
9
+ value: true
10
+ });
11
+ exports.getLogs = getLogs;
12
+ exports.validateInputs = validateInputs;
13
+ exports.appQuery = void 0;
14
+
15
+ var _command = _interopRequireDefault(require("../lib/cli/command"));
16
+
17
+ var _rollbar = require("../lib/rollbar");
18
+
19
+ var _tracker = require("../lib/tracker");
20
+
21
+ var logsLib = _interopRequireWildcard(require("../lib/app-logs/app-logs"));
22
+
23
+ var exit = _interopRequireWildcard(require("../lib/cli/exit"));
24
+
25
+ var _format = require("../lib/cli/format");
26
+
27
+ 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); }
28
+
29
+ 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; }
30
+
31
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
32
+
33
+ const LIMIT_MAX = 5000;
34
+ const LIMIT_MIN = 1;
35
+ const ALLOWED_TYPES = ['app', 'batch'];
36
+ const ALLOWED_FORMATS = ['csv', 'json', 'text'];
37
+
38
+ async function getLogs(arg, opt) {
39
+ validateInputs(opt.type, opt.limit, opt.format);
40
+ const trackingParams = {
41
+ command: 'vip logs',
42
+ org_id: opt.app.organization.id,
43
+ app_id: opt.app.id,
44
+ env_id: opt.env.id,
45
+ type: opt.type,
46
+ limit: opt.limit,
47
+ format: opt.format
48
+ };
49
+ await (0, _tracker.trackEvent)('logs_command_execute', trackingParams);
50
+ let logs = [];
51
+
52
+ try {
53
+ logs = await logsLib.getRecentLogs(opt.app.id, opt.env.id, opt.type, opt.limit);
54
+ } catch (error) {
55
+ _rollbar.rollbar.error(error);
56
+
57
+ await (0, _tracker.trackEvent)('logs_command_error', { ...trackingParams,
58
+ error: error.message
59
+ });
60
+ return exit.withError(error.message);
61
+ }
62
+
63
+ await (0, _tracker.trackEvent)('logs_command_success', { ...trackingParams,
64
+ logs_output: logs.length
65
+ });
66
+
67
+ if (!logs.length) {
68
+ console.error('No logs found');
69
+ return;
70
+ } // Strip out __typename
71
+
72
+
73
+ logs = logs.map(log => {
74
+ const {
75
+ timestamp,
76
+ message
77
+ } = log;
78
+ return {
79
+ timestamp,
80
+ message
81
+ };
82
+ });
83
+ let output = '';
84
+
85
+ if (opt.format && 'text' === opt.format) {
86
+ const rows = [];
87
+
88
+ for (const {
89
+ timestamp,
90
+ message
91
+ } of logs) {
92
+ rows.push(`${timestamp} ${message}`);
93
+ output = rows.join('\n');
94
+ }
95
+ } else {
96
+ output = (0, _format.formatData)(logs, opt.format);
97
+ }
98
+
99
+ console.log(output);
100
+ }
101
+
102
+ function validateInputs(type, limit, format) {
103
+ if (!ALLOWED_TYPES.includes(type)) {
104
+ exit.withError(`Invalid type: ${type}. The supported types are: ${ALLOWED_TYPES.join(', ')}.`);
105
+ }
106
+
107
+ if (!ALLOWED_FORMATS.includes(format)) {
108
+ exit.withError(`Invalid format: ${format}. The supported formats are: ${ALLOWED_FORMATS.join(', ')}.`);
109
+ }
110
+
111
+ if (!Number.isInteger(limit) || limit < LIMIT_MIN || limit > LIMIT_MAX) {
112
+ exit.withError(`Invalid limit: ${limit}. It should be a number between ${LIMIT_MIN} and ${LIMIT_MAX}.`);
113
+ }
114
+ }
115
+
116
+ const appQuery = `
117
+ id
118
+ name
119
+ environments {
120
+ id
121
+ appId
122
+ name
123
+ type
124
+ }
125
+ organization {
126
+ id
127
+ name
128
+ }
129
+ `;
130
+ exports.appQuery = appQuery;
131
+ (0, _command.default)({
132
+ appContext: true,
133
+ appQuery,
134
+ envContext: true,
135
+ module: 'logs'
136
+ }).option('type', 'The type of logs to be returned: "app" or "batch"', 'app').option('limit', 'The maximum number of log lines', 500).option('format', 'Output the log lines in CSV or JSON format', 'text').examples([{
137
+ usage: 'vip @mysite.production logs',
138
+ description: 'Get the most recent app logs'
139
+ }, {
140
+ usage: 'vip @mysite.production logs --type batch',
141
+ description: 'Get the most recent batch logs'
142
+ }, {
143
+ usage: 'vip @mysite.production logs --limit 100',
144
+ description: 'Get the most recent 100 log entries'
145
+ }, {
146
+ usage: 'vip @mysite.production logs --limit 100 --format csv',
147
+ description: 'Get the most recent 100 log entries formatted as comma-separated values (CSV)'
148
+ }, {
149
+ usage: 'vip @mysite.production logs --limit 100 --format json',
150
+ description: 'Get the most recent 100 log entries formatted as JSON'
151
+ }]).argv(process.argv, getLogs);
package/dist/bin/vip.js CHANGED
@@ -48,7 +48,7 @@ const runCmd = async function () {
48
48
  await _token.default.purge();
49
49
  await (0, _tracker.trackEvent)('logout_command_execute');
50
50
  console.log('You are successfully logged out.');
51
- }).command('app', 'List and modify your VIP applications').command('config', 'Set configuration for your VIP applications').command('dev-env', 'Use local dev-environment').command('import', 'Import media or SQL files into your VIP applications').command('search-replace', 'Perform search and replace tasks on files').command('sync', 'Sync production to a development environment').command('wp', 'Run WP CLI commands against an environment');
51
+ }).command('app', 'List and modify your VIP applications').command('config', 'Set configuration for your VIP applications').command('dev-env', 'Use local dev-environment').command('import', 'Import media or SQL files into your VIP applications').command('logs', 'Get logs from your VIP applications').command('search-replace', 'Perform search and replace tasks on files').command('sync', 'Sync production to a development environment').command('wp', 'Run WP CLI commands against an environment');
52
52
  cmd.argv(process.argv);
53
53
  };
54
54
 
@@ -0,0 +1,62 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.getRecentLogs = getRecentLogs;
7
+
8
+ var _graphqlTag = _interopRequireDefault(require("graphql-tag"));
9
+
10
+ var _api = _interopRequireDefault(require("../api"));
11
+
12
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
13
+
14
+ /**
15
+ *
16
+ * @format
17
+ */
18
+
19
+ /**
20
+ * External dependencies
21
+ */
22
+
23
+ /**
24
+ * Internal dependencies
25
+ */
26
+ const QUERY_ENVIRONMENT_LOGS = (0, _graphqlTag.default)`
27
+ query GetAppLogs( $appId: Int, $envId: Int, $type: AppEnvironmentLogType, $limit: Int ) {
28
+ app( id: $appId ) {
29
+ environments( id: $envId ) {
30
+ id
31
+ logs( type: $type, limit: $limit ) {
32
+ nodes {
33
+ timestamp
34
+ message
35
+ }
36
+ }
37
+ }
38
+ }
39
+ }
40
+ `;
41
+
42
+ async function getRecentLogs(appId, envId, type, limit) {
43
+ var _response$data, _response$data$app, _response$data$app$en, _response$data$app$en2;
44
+
45
+ const api = await (0, _api.default)();
46
+ const response = await api.query({
47
+ query: QUERY_ENVIRONMENT_LOGS,
48
+ variables: {
49
+ appId,
50
+ envId,
51
+ type,
52
+ limit
53
+ }
54
+ });
55
+ const logs = response === null || response === void 0 ? void 0 : (_response$data = response.data) === null || _response$data === void 0 ? void 0 : (_response$data$app = _response$data.app) === null || _response$data$app === void 0 ? void 0 : (_response$data$app$en = _response$data$app.environments[0]) === null || _response$data$app$en === void 0 ? void 0 : (_response$data$app$en2 = _response$data$app$en.logs) === null || _response$data$app$en2 === void 0 ? void 0 : _response$data$app$en2.nodes;
56
+
57
+ if (!logs) {
58
+ throw new Error('Unable to query logs');
59
+ }
60
+
61
+ return logs;
62
+ }
@@ -3,7 +3,7 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.DEV_ENVIRONMENT_COMPONENTS = exports.DEV_ENVIRONMENT_PROMPT_INTRO = exports.DEV_ENVIRONMENT_DEFAULTS = exports.DEV_ENVIRONMENT_FULL_COMMAND = exports.DEV_ENVIRONMENT_SUBCOMMAND = void 0;
6
+ exports.DEV_ENVIRONMENT_COMPONENTS = exports.DEV_ENVIRONMENT_NOT_FOUND = exports.DEV_ENVIRONMENT_PROMPT_INTRO = exports.DEV_ENVIRONMENT_DEFAULTS = exports.DEV_ENVIRONMENT_FULL_COMMAND = exports.DEV_ENVIRONMENT_SUBCOMMAND = void 0;
7
7
  const DEV_ENVIRONMENT_SUBCOMMAND = 'dev-env';
8
8
  exports.DEV_ENVIRONMENT_SUBCOMMAND = DEV_ENVIRONMENT_SUBCOMMAND;
9
9
  const DEV_ENVIRONMENT_FULL_COMMAND = `vip ${DEV_ENVIRONMENT_SUBCOMMAND}`;
@@ -17,5 +17,7 @@ const DEV_ENVIRONMENT_DEFAULTS = {
17
17
  exports.DEV_ENVIRONMENT_DEFAULTS = DEV_ENVIRONMENT_DEFAULTS;
18
18
  const DEV_ENVIRONMENT_PROMPT_INTRO = 'This is a wizard to help you set up your local dev environment.\n\n' + 'Sensible default values were pre-selected for convenience. ' + 'You may also choose to create multiple environments with different settings using the --slug option.\n\n';
19
19
  exports.DEV_ENVIRONMENT_PROMPT_INTRO = DEV_ENVIRONMENT_PROMPT_INTRO;
20
+ const DEV_ENVIRONMENT_NOT_FOUND = 'Environment not found.';
21
+ exports.DEV_ENVIRONMENT_NOT_FOUND = DEV_ENVIRONMENT_NOT_FOUND;
20
22
  const DEV_ENVIRONMENT_COMPONENTS = ['wordpress', 'muPlugins', 'clientCode'];
21
23
  exports.DEV_ENVIRONMENT_COMPONENTS = DEV_ENVIRONMENT_COMPONENTS;
@@ -8,11 +8,13 @@ exports.getEnvironmentName = getEnvironmentName;
8
8
  exports.getEnvironmentStartCommand = getEnvironmentStartCommand;
9
9
  exports.printTable = printTable;
10
10
  exports.processComponentOptionInput = processComponentOptionInput;
11
+ exports.getOptionsFromAppInfo = getOptionsFromAppInfo;
11
12
  exports.promptForArguments = promptForArguments;
12
13
  exports.resolvePath = resolvePath;
13
14
  exports.promptForText = promptForText;
14
15
  exports.promptForBoolean = promptForBoolean;
15
16
  exports.promptForComponent = promptForComponent;
17
+ exports.addDevEnvConfigurationOptions = addDevEnvConfigurationOptions;
16
18
 
17
19
  var _chalk = _interopRequireDefault(require("chalk"));
18
20
 
@@ -30,6 +32,8 @@ var _os = _interopRequireDefault(require("os"));
30
32
 
31
33
  var _devEnvironment = require("../constants/dev-environment");
32
34
 
35
+ var _types = require("./types");
36
+
33
37
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
34
38
 
35
39
  /**
@@ -50,7 +54,7 @@ const DEFAULT_SLUG = 'vip-local';
50
54
  function handleCLIException(exception) {
51
55
  const errorPrefix = _chalk.default.red('Error:');
52
56
 
53
- if ('Environment not found.' === exception.message) {
57
+ if (_devEnvironment.DEV_ENVIRONMENT_NOT_FOUND === exception.message) {
54
58
  const createCommand = _chalk.default.bold(_devEnvironment.DEV_ENVIRONMENT_FULL_COMMAND + ' create');
55
59
 
56
60
  const message = `Environment doesn't exist.\n\n\nTo create a new environment run:\n\n${createCommand}\n`;
@@ -121,60 +125,89 @@ function processComponentOptionInput(passedParam, allowLocal) {
121
125
  };
122
126
  }
123
127
 
124
- async function promptForArguments(providedOptions, appInfo) {
125
- var _appInfo$environment, _appInfo$environment3;
128
+ function getOptionsFromAppInfo(appInfo) {
129
+ var _appInfo$environment, _appInfo$environment2, _appInfo$environment3;
130
+
131
+ if (!appInfo) {
132
+ return {};
133
+ }
134
+
135
+ return {
136
+ title: ((_appInfo$environment = appInfo.environment) === null || _appInfo$environment === void 0 ? void 0 : _appInfo$environment.name) || appInfo.name,
137
+ multisite: !!(appInfo !== null && appInfo !== void 0 && (_appInfo$environment2 = appInfo.environment) !== null && _appInfo$environment2 !== void 0 && _appInfo$environment2.isMultisite),
138
+ mediaRedirectDomain: (_appInfo$environment3 = appInfo.environment) === null || _appInfo$environment3 === void 0 ? void 0 : _appInfo$environment3.primaryDomain
139
+ };
140
+ }
141
+ /**
142
+ * Prompt for arguments
143
+ * @param {InstanceOptions} preselectedOptions - options to be used without prompt
144
+ * @param {InstanceOptions} defaultOptions - options to be used as default values for prompt
145
+ * @returns {any} instance data
146
+ */
126
147
 
127
- debug('Provided options', providedOptions);
148
+
149
+ async function promptForArguments(preselectedOptions, defaultOptions) {
150
+ debug('Provided preselected', preselectedOptions, 'and default', defaultOptions);
128
151
  console.log(_devEnvironment.DEV_ENVIRONMENT_PROMPT_INTRO);
129
- const name = (appInfo === null || appInfo === void 0 ? void 0 : (_appInfo$environment = appInfo.environment) === null || _appInfo$environment === void 0 ? void 0 : _appInfo$environment.name) || (appInfo === null || appInfo === void 0 ? void 0 : appInfo.name);
130
152
  let multisiteText = 'Multisite';
131
153
  let multisiteDefault = _devEnvironment.DEV_ENVIRONMENT_DEFAULTS.multisite;
132
154
 
133
- if (appInfo !== null && appInfo !== void 0 && appInfo.environment) {
134
- var _appInfo$environment2;
135
-
136
- const isEnvMultisite = !!(appInfo !== null && appInfo !== void 0 && (_appInfo$environment2 = appInfo.environment) !== null && _appInfo$environment2 !== void 0 && _appInfo$environment2.isMultisite);
137
- multisiteText += ` (${name} ${isEnvMultisite ? 'IS' : 'is NOT'} multisite)`;
138
- multisiteDefault = isEnvMultisite;
155
+ if (defaultOptions.title) {
156
+ multisiteText += ` (${defaultOptions.title} ${defaultOptions.multisite ? 'IS' : 'is NOT'} multisite)`;
157
+ multisiteDefault = defaultOptions.multisite;
139
158
  }
140
159
 
141
160
  const instanceData = {
142
- wpTitle: providedOptions.title || (await promptForText('WordPress site title', name || _devEnvironment.DEV_ENVIRONMENT_DEFAULTS.title)),
143
- multisite: 'multisite' in providedOptions ? providedOptions.multisite : await promptForBoolean(multisiteText, multisiteDefault),
144
- elasticsearch: providedOptions.elasticsearch || _devEnvironment.DEV_ENVIRONMENT_DEFAULTS.elasticsearchVersion,
145
- mariadb: providedOptions.mariadb || _devEnvironment.DEV_ENVIRONMENT_DEFAULTS.mariadbVersion,
146
- mediaRedirectDomain: '',
161
+ wpTitle: preselectedOptions.title || (await promptForText('WordPress site title', defaultOptions.title || _devEnvironment.DEV_ENVIRONMENT_DEFAULTS.title)),
162
+ multisite: 'multisite' in preselectedOptions ? preselectedOptions.multisite : await promptForBoolean(multisiteText, !!multisiteDefault),
163
+ elasticsearch: preselectedOptions.elasticsearch || defaultOptions.elasticsearch || _devEnvironment.DEV_ENVIRONMENT_DEFAULTS.elasticsearchVersion,
164
+ mariadb: preselectedOptions.mariadb || defaultOptions.mariadb || _devEnvironment.DEV_ENVIRONMENT_DEFAULTS.mariadbVersion,
165
+ mediaRedirectDomain: preselectedOptions.mediaRedirectDomain || '',
147
166
  wordpress: {},
148
167
  muPlugins: {},
149
- clientCode: {}
168
+ clientCode: {},
169
+ statsd: false,
170
+ phpmyadmin: false,
171
+ xdebug: false
150
172
  };
151
- const primaryDomain = appInfo === null || appInfo === void 0 ? void 0 : (_appInfo$environment3 = appInfo.environment) === null || _appInfo$environment3 === void 0 ? void 0 : _appInfo$environment3.primaryDomain;
152
173
 
153
- if (primaryDomain) {
154
- const mediaRedirectPromptText = `Would you like to redirect to ${primaryDomain} for missing media files?`;
174
+ if (!instanceData.mediaRedirectDomain && defaultOptions.mediaRedirectDomain) {
175
+ const mediaRedirectPromptText = `Would you like to redirect to ${defaultOptions.mediaRedirectDomain} for missing media files?`;
155
176
  const setMediaRedirectDomain = await promptForBoolean(mediaRedirectPromptText, true);
156
177
 
157
178
  if (setMediaRedirectDomain) {
158
- instanceData.mediaRedirectDomain = primaryDomain;
179
+ instanceData.mediaRedirectDomain = defaultOptions.mediaRedirectDomain;
159
180
  }
160
181
  }
161
182
 
162
183
  for (const component of _devEnvironment.DEV_ENVIRONMENT_COMPONENTS) {
163
- const option = providedOptions[component];
164
- instanceData[component] = await processComponent(component, option);
184
+ const option = preselectedOptions[component];
185
+ const defaultValue = defaultOptions[component];
186
+ instanceData[component] = await processComponent(component, option, defaultValue);
187
+ }
188
+
189
+ for (const service of ['statsd', 'phpmyadmin', 'xdebug']) {
190
+ if (service in preselectedOptions) {
191
+ instanceData[service] = preselectedOptions[service];
192
+ } else if (service in defaultOptions) {
193
+ instanceData[service] = defaultOptions[service];
194
+ }
165
195
  }
166
196
 
197
+ debug('Instance data after prompts', instanceData);
167
198
  return instanceData;
168
199
  }
169
200
 
170
- async function processComponent(component, option) {
201
+ async function processComponent(component, preselectedValue, defaultValue) {
202
+ debug(`processing a component '${component}', with preselected/deafault - ${preselectedValue}/${defaultValue}`);
171
203
  let result = null;
172
204
  const allowLocal = component !== 'wordpress';
205
+ const defaultObject = defaultValue ? processComponentOptionInput(defaultValue, allowLocal) : null;
173
206
 
174
- if (option) {
175
- result = processComponentOptionInput(option, allowLocal);
207
+ if (preselectedValue) {
208
+ result = processComponentOptionInput(preselectedValue, allowLocal);
176
209
  } else {
177
- result = await promptForComponent(component, allowLocal);
210
+ result = await promptForComponent(component, allowLocal, defaultObject);
178
211
  }
179
212
 
180
213
  while ('local' === ((_result = result) === null || _result === void 0 ? void 0 : _result.mode)) {
@@ -192,7 +225,7 @@ async function processComponent(component, option) {
192
225
  } else {
193
226
  const message = `Provided path "${resolvedPath}" does not point to a valid or existing directory.`;
194
227
  console.log(_chalk.default.yellow('Warning:'), message);
195
- result = await promptForComponent(component, allowLocal);
228
+ result = await promptForComponent(component, allowLocal, defaultObject);
196
229
  }
197
230
  }
198
231
 
@@ -222,7 +255,7 @@ async function promptForText(message, initial) {
222
255
  initial,
223
256
  validate: nonEmptyValidator
224
257
  });
225
- return result.input.trim();
258
+ return ((result === null || result === void 0 ? void 0 : result.input) || '').trim();
226
259
  }
227
260
 
228
261
  async function promptForBoolean(message, initial) {
@@ -239,19 +272,19 @@ const componentDisplayNames = {
239
272
  clientCode: 'site-code'
240
273
  };
241
274
 
242
- async function promptForComponent(component, allowLocal) {
243
- debug(`Prompting for ${component}`);
275
+ async function promptForComponent(component, allowLocal, defaultObject) {
276
+ debug(`Prompting for ${component} with default:`, defaultObject);
244
277
  const componentDisplayName = componentDisplayNames[component] || component;
245
- const choices = [];
278
+ const modChoices = [];
246
279
 
247
280
  if (allowLocal) {
248
- choices.push({
281
+ modChoices.push({
249
282
  message: `local folder - where you already have ${componentDisplayName} code`,
250
283
  value: 'local'
251
284
  });
252
285
  }
253
286
 
254
- choices.push({
287
+ modChoices.push({
255
288
  message: 'image - that gets automatically fetched',
256
289
  value: 'image'
257
290
  });
@@ -261,14 +294,18 @@ async function promptForComponent(component, allowLocal) {
261
294
  initialMode = 'local';
262
295
  }
263
296
 
297
+ if (defaultObject !== null && defaultObject !== void 0 && defaultObject.mode) {
298
+ initialMode = defaultObject.mode;
299
+ }
300
+
264
301
  let modeResult = initialMode;
265
- const selectMode = choices.length > 1;
302
+ const selectMode = modChoices.length > 1;
266
303
 
267
304
  if (selectMode) {
268
- const initialModeIndex = choices.findIndex(choice => choice.value === initialMode);
305
+ const initialModeIndex = modChoices.findIndex(choice => choice.value === initialMode);
269
306
  const select = new _enquirer.Select({
270
307
  message: `How would you like to source ${componentDisplayName}`,
271
- choices,
308
+ choices: modChoices,
272
309
  initial: initialModeIndex
273
310
  });
274
311
  modeResult = await select.run();
@@ -277,38 +314,61 @@ async function promptForComponent(component, allowLocal) {
277
314
  const messagePrefix = selectMode ? '\t' : `${componentDisplayName} - `;
278
315
 
279
316
  if ('local' === modeResult) {
280
- const directoryPath = await promptForText(`${messagePrefix}What is a path to your local ${componentDisplayName}`, '');
317
+ const directoryPath = await promptForText(`${messagePrefix}What is a path to your local ${componentDisplayName}`, (defaultObject === null || defaultObject === void 0 ? void 0 : defaultObject.dir) || '');
281
318
  return {
282
319
  mode: modeResult,
283
320
  dir: directoryPath
284
321
  };
285
- }
286
-
287
- if ('inherit' === modeResult) {
288
- return {
289
- mode: modeResult
290
- };
291
- } // image
322
+ } // image with selection
292
323
 
293
324
 
294
325
  if (component === 'wordpress') {
295
326
  const message = `${messagePrefix}Which version would you like`;
327
+ const tagChoices = getWordpressImageTags();
328
+ let initialTagIndex = 0;
329
+
330
+ if (defaultObject !== null && defaultObject !== void 0 && defaultObject.tag) {
331
+ const defaultTagIndex = tagChoices.indexOf(defaultObject.tag);
332
+
333
+ if (defaultTagIndex !== -1) {
334
+ initialTagIndex = defaultTagIndex;
335
+ }
336
+ }
337
+
296
338
  const selectTag = new _enquirer.Select({
297
339
  message,
298
- choices: getWordpressImageTags()
340
+ choices: tagChoices,
341
+ initial: initialTagIndex
299
342
  });
300
343
  const tag = await selectTag.run();
301
344
  return {
302
345
  mode: modeResult,
303
346
  tag
304
347
  };
305
- }
348
+ } // image
349
+
306
350
 
307
351
  return {
308
352
  mode: modeResult
309
353
  };
310
354
  }
311
355
 
356
+ function addDevEnvConfigurationOptions(command) {
357
+ return command.option('wordpress', 'Use a specific WordPress version').option(['u', 'mu-plugins'], 'Use a specific mu-plugins changeset or local directory').option('client-code', 'Use the client code from a local directory or VIP skeleton').option('statsd', 'Enable statsd component. By default it is disabled', undefined, value => {
358
+ var _value$toLowerCase;
359
+
360
+ return 'false' !== (value === null || value === void 0 ? void 0 : (_value$toLowerCase = value.toLowerCase) === null || _value$toLowerCase === void 0 ? void 0 : _value$toLowerCase.call(value));
361
+ }).option('phpmyadmin', 'Enable PHPMyAdmin component. By default it is disabled', undefined, value => {
362
+ var _value$toLowerCase2;
363
+
364
+ return 'false' !== (value === null || value === void 0 ? void 0 : (_value$toLowerCase2 = value.toLowerCase) === null || _value$toLowerCase2 === void 0 ? void 0 : _value$toLowerCase2.call(value));
365
+ }).option('xdebug', 'Enable XDebug. By default it is disabled', undefined, value => {
366
+ var _value$toLowerCase3;
367
+
368
+ return 'false' !== (value === null || value === void 0 ? void 0 : (_value$toLowerCase3 = value.toLowerCase) === null || _value$toLowerCase3 === void 0 ? void 0 : _value$toLowerCase3.call(value));
369
+ }).option('elasticsearch', 'Explicitly choose Elasticsearch version to use').option('mariadb', 'Explicitly choose MariaDB version to use').option('media-redirect-domain', 'Domain to redirect for missing media files. This can be used to still have images without the need to import them locally.');
370
+ }
371
+
312
372
  function getWordpressImageTags() {
313
373
  return ['5.8.1', '5.8', '5.7.3', '5.7.2'];
314
374
  }
@@ -6,11 +6,13 @@ Object.defineProperty(exports, "__esModule", {
6
6
  exports.startEnvironment = startEnvironment;
7
7
  exports.stopEnvironment = stopEnvironment;
8
8
  exports.createEnvironment = createEnvironment;
9
+ exports.updateEnvironment = updateEnvironment;
9
10
  exports.destroyEnvironment = destroyEnvironment;
10
11
  exports.printAllEnvironmentsInfo = printAllEnvironmentsInfo;
11
12
  exports.printEnvironmentInfo = printEnvironmentInfo;
12
13
  exports.exec = exec;
13
14
  exports.doesEnvironmentExist = doesEnvironmentExist;
15
+ exports.readEnvironmentData = readEnvironmentData;
14
16
  exports.getEnvironmentPath = getEnvironmentPath;
15
17
  exports.getApplicationInformation = getApplicationInformation;
16
18
  exports.resolveImportPath = resolveImportPath;
@@ -42,6 +44,8 @@ var _devEnvironmentCli = require("./dev-environment-cli");
42
44
 
43
45
  var _app = _interopRequireDefault(require("../api/app"));
44
46
 
47
+ var _devEnvironment = require("../constants/dev-environment");
48
+
45
49
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
46
50
 
47
51
  /**
@@ -77,7 +81,7 @@ async function startEnvironment(slug, options) {
77
81
  const environmentExists = _fs.default.existsSync(instancePath);
78
82
 
79
83
  if (!environmentExists) {
80
- throw new Error('Environment not found.');
84
+ throw new Error(_devEnvironment.DEV_ENVIRONMENT_NOT_FOUND);
81
85
  }
82
86
 
83
87
  if (options.skipRebuild) {
@@ -97,7 +101,7 @@ async function stopEnvironment(slug) {
97
101
  const environmentExists = _fs.default.existsSync(instancePath);
98
102
 
99
103
  if (!environmentExists) {
100
- throw new Error('Environment not found.');
104
+ throw new Error(_devEnvironment.DEV_ENVIRONMENT_NOT_FOUND);
101
105
  }
102
106
 
103
107
  await (0, _devEnvironmentLando.landoStop)(instancePath);
@@ -105,7 +109,7 @@ async function stopEnvironment(slug) {
105
109
 
106
110
  async function createEnvironment(instanceData) {
107
111
  const slug = instanceData.siteSlug;
108
- debug('Will start an environment', slug, 'with instanceData: ', instanceData);
112
+ debug('Will create an environment', slug, 'with instanceData: ', instanceData);
109
113
  const instancePath = getEnvironmentPath(slug);
110
114
  debug('Instance path for', slug, 'is:', instancePath);
111
115
 
@@ -115,12 +119,36 @@ async function createEnvironment(instanceData) {
115
119
  throw new Error('Environment already exists.');
116
120
  }
117
121
 
122
+ const preProcessedInstanceData = preProcessInstanceData(instanceData);
123
+ await prepareLandoEnv(preProcessedInstanceData, instancePath);
124
+ }
125
+
126
+ async function updateEnvironment(instanceData) {
127
+ const slug = instanceData.siteSlug;
128
+ debug('Will update an environment', slug, 'with instanceData: ', instanceData);
129
+ const instancePath = getEnvironmentPath(slug);
130
+ debug('Instance path for', slug, 'is:', instancePath);
131
+
132
+ const alreadyExists = _fs.default.existsSync(instancePath);
133
+
134
+ if (!alreadyExists) {
135
+ throw new Error('Environment doesn\'t exist.');
136
+ }
137
+
138
+ const preProcessedInstanceData = preProcessInstanceData(instanceData);
139
+ await prepareLandoEnv(preProcessedInstanceData, instancePath);
140
+ }
141
+
142
+ function preProcessInstanceData(instanceData) {
143
+ const newInstanceData = { ...instanceData
144
+ };
145
+
118
146
  if (instanceData.mediaRedirectDomain && !instanceData.mediaRedirectDomain.match(/^http/)) {
119
147
  // We need to make sure the redirect is an absolute path
120
- instanceData.mediaRedirectDomain = `https://${instanceData.mediaRedirectDomain}`;
148
+ newInstanceData.mediaRedirectDomain = `https://${instanceData.mediaRedirectDomain}`;
121
149
  }
122
150
 
123
- await prepareLandoEnv(instanceData, instancePath);
151
+ return newInstanceData;
124
152
  }
125
153
 
126
154
  async function destroyEnvironment(slug, removeFiles) {
@@ -131,7 +159,7 @@ async function destroyEnvironment(slug, removeFiles) {
131
159
  const environmentExists = _fs.default.existsSync(instancePath);
132
160
 
133
161
  if (!environmentExists) {
134
- throw new Error('Environment not found.');
162
+ throw new Error(_devEnvironment.DEV_ENVIRONMENT_NOT_FOUND);
135
163
  }
136
164
 
137
165
  const landoFilePath = _path.default.join(instancePath, landoFileName);
@@ -170,7 +198,7 @@ async function printEnvironmentInfo(slug) {
170
198
  const environmentExists = _fs.default.existsSync(instancePath);
171
199
 
172
200
  if (!environmentExists) {
173
- throw new Error('Environment not found.');
201
+ throw new Error(_devEnvironment.DEV_ENVIRONMENT_NOT_FOUND);
174
202
  }
175
203
 
176
204
  const appInfo = await (0, _devEnvironmentLando.landoInfo)(instancePath);
@@ -185,7 +213,7 @@ async function exec(slug, args) {
185
213
  const environmentExists = _fs.default.existsSync(instancePath);
186
214
 
187
215
  if (!environmentExists) {
188
- throw new Error('Environment not found.');
216
+ throw new Error(_devEnvironment.DEV_ENVIRONMENT_NOT_FOUND);
189
217
  }
190
218
 
191
219
  const command = args.shift();
@@ -205,6 +233,17 @@ function doesEnvironmentExist(slug) {
205
233
  return _fs.default.existsSync(instancePath);
206
234
  }
207
235
 
236
+ function readEnvironmentData(slug) {
237
+ debug('Will try to get instance data for environment', slug);
238
+ const instancePath = getEnvironmentPath(slug);
239
+
240
+ const instanceDataTargetPath = _path.default.join(instancePath, instanceDataFileName);
241
+
242
+ const instanceDataString = _fs.default.readFileSync(instanceDataTargetPath, 'utf8');
243
+
244
+ return JSON.parse(instanceDataString);
245
+ }
246
+
208
247
  async function prepareLandoEnv(instanceData, instancePath) {
209
248
  const landoFile = await _ejs.default.renderFile(landoFileTemplatePath, instanceData);
210
249
  const nginxFile = await _ejs.default.renderFile(nginxFileTemplatePath, instanceData);
@@ -0,0 +1 @@
1
+ "use strict";
@@ -16,7 +16,7 @@ var _fileSize = require("../constants/file-size");
16
16
  /**
17
17
  * Internal dependencies
18
18
  */
19
- const SQL_IMPORT_FILE_SIZE_LIMIT = 10 * _fileSize.GB_IN_BYTES;
19
+ const SQL_IMPORT_FILE_SIZE_LIMIT = 100 * _fileSize.GB_IN_BYTES;
20
20
  exports.SQL_IMPORT_FILE_SIZE_LIMIT = SQL_IMPORT_FILE_SIZE_LIMIT;
21
21
  const SQL_IMPORT_FILE_SIZE_LIMIT_LAUNCHED = 350 * _fileSize.MB_IN_BYTES;
22
22
  exports.SQL_IMPORT_FILE_SIZE_LIMIT_LAUNCHED = SQL_IMPORT_FILE_SIZE_LIMIT_LAUNCHED;
@@ -48,6 +48,7 @@ const IMPORT_SQL_PROGRESS_QUERY = (0, _graphqlTag.default)`
48
48
  environments(id: $envId) {
49
49
  id
50
50
  isK8sResident
51
+ launched
51
52
  jobs(types: "sql_import") {
52
53
  id
53
54
  type
@@ -106,7 +107,8 @@ async function getStatus(api, appId, envId) {
106
107
  const [environment] = environments;
107
108
  const {
108
109
  importStatus,
109
- jobs
110
+ jobs,
111
+ launched
110
112
  } = environment;
111
113
 
112
114
  if (!environment.isK8sResident && !(jobs !== null && jobs !== void 0 && jobs.length)) {
@@ -116,15 +118,16 @@ async function getStatus(api, appId, envId) {
116
118
  const [importJob] = jobs;
117
119
  return {
118
120
  importStatus,
119
- importJob
121
+ importJob,
122
+ launched
120
123
  };
121
124
  }
122
125
 
123
- function getErrorMessage(importFailed) {
126
+ function getErrorMessage(importFailed, launched = false) {
124
127
  debug({
125
128
  importFailed
126
129
  });
127
- const rollbackMessage = `Your site is ${_chalk.default.blue('automatically being rolled back')} to the last backup prior to your import job.
130
+ const rollbackMessage = launched ? '' : `Your site is ${_chalk.default.blue('automatically being rolled back')} to the last backup prior to your import job.
128
131
  `;
129
132
  let message = importFailed.error;
130
133
 
@@ -262,7 +265,8 @@ ${maybeExitPrompt}
262
265
  }
263
266
 
264
267
  const {
265
- importStatus
268
+ importStatus,
269
+ launched
266
270
  } = status;
267
271
  let {
268
272
  importJob
@@ -345,14 +349,15 @@ ${maybeExitPrompt}
345
349
 
346
350
  let failedImportStep;
347
351
 
348
- if (jobCreationTime && (importStepProgress === null || importStepProgress === void 0 ? void 0 : importStepProgress.started_at) * 1000 > jobCreationTime) {
352
+ if (jobCreationTime && (importStepProgress === null || importStepProgress === void 0 ? void 0 : importStepProgress.started_at) * 1000 >= jobCreationTime) {
349
353
  // The contents of the `import_progress` meta are pertinent to the most recent import job
350
354
  failedImportStep = importStepProgress.steps.find(step => (step === null || step === void 0 ? void 0 : step.result) === 'failed' && 1000 * (step === null || step === void 0 ? void 0 : step.started_at) > new Date(createdAt).getTime());
351
355
  }
352
356
 
353
357
  if (!jobSteps.length) {
354
358
  return reject({
355
- error: 'Could not enumerate the import job steps'
359
+ error: 'Could not enumerate the import job steps',
360
+ launched
356
361
  });
357
362
  }
358
363
 
@@ -375,7 +380,8 @@ ${maybeExitPrompt}
375
380
  commandOutput: failedImportStep.output,
376
381
  error: 'Import step failed',
377
382
  stepName: failedImportStep.name,
378
- errorText: failedImportStep.error
383
+ errorText: failedImportStep.error,
384
+ launched
379
385
  });
380
386
  }
381
387
 
@@ -385,7 +391,8 @@ ${maybeExitPrompt}
385
391
  if (jobStatus === 'error') {
386
392
  return reject({
387
393
  error: 'Import job failed',
388
- steps: jobSteps
394
+ steps: jobSteps,
395
+ launched
389
396
  });
390
397
  }
391
398
 
@@ -425,7 +432,7 @@ ${maybeExitPrompt}
425
432
  progressTracker.print({
426
433
  clearAfter: true
427
434
  });
428
- exit.withError(getErrorMessage(importFailed));
435
+ exit.withError(getErrorMessage(importFailed, importFailed.launched));
429
436
  }
430
437
  }
431
438
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@automattic/vip",
3
- "version": "2.5.0",
3
+ "version": "2.7.0",
4
4
  "description": "The VIP Javascript library & CLI",
5
5
  "main": "index.js",
6
6
  "bin": {
@@ -16,6 +16,7 @@
16
16
  "vip-config-envvar-set": "dist/bin/vip-config-envvar-set.js",
17
17
  "vip-dev-env": "dist/bin/vip-dev-env.js",
18
18
  "vip-dev-env-create": "dist/bin/vip-dev-env-create.js",
19
+ "vip-dev-env-update": "dist/bin/vip-dev-env-update.js",
19
20
  "vip-dev-env-destroy": "dist/bin/vip-dev-env-destroy.js",
20
21
  "vip-dev-env-exec": "dist/bin/vip-dev-env-exec.js",
21
22
  "vip-dev-env-import": "dist/bin/vip-dev-env-import.js",
@@ -32,6 +33,7 @@
32
33
  "vip-import-sql-status": "dist/bin/vip-import-sql-status.js",
33
34
  "vip-import-validate-files": "dist/bin/vip-import-validate-files.js",
34
35
  "vip-import-validate-sql": "dist/bin/vip-import-validate-sql.js",
36
+ "vip-logs": "dist/bin/vip-logs.js",
35
37
  "vip-search-replace": "dist/bin/vip-search-replace.js",
36
38
  "vip-sync": "dist/bin/vip-sync.js",
37
39
  "vip-wp": "dist/bin/vip-wp.js"
@@ -75,7 +77,7 @@
75
77
  "devDependencies": {
76
78
  "@babel/cli": "7.15.7",
77
79
  "@babel/core": "7.14.0",
78
- "@babel/eslint-parser": "^7.13.14",
80
+ "@babel/eslint-parser": "7.13.14",
79
81
  "@babel/plugin-transform-modules-commonjs": "7.14.0",
80
82
  "@babel/preset-env": "7.14.1",
81
83
  "@babel/preset-flow": "7.13.13",
@@ -84,14 +86,14 @@
84
86
  "babel-plugin-module-resolver": "4.1.0",
85
87
  "core-js": "3.12.0",
86
88
  "eslint": "7.32.0",
87
- "eslint-config-wpvip": "github:automattic/eslint-config-wpvip#d0aa883",
89
+ "eslint-config-wpvip": "github:automattic/eslint-config-wpvip#c6605d1",
88
90
  "eslint-plugin-flowtype": "5.7.2",
89
91
  "eslint-plugin-import": "2.22.1",
90
92
  "eslint-plugin-jest": "24.3.6",
91
93
  "eslint-plugin-json": "3.0.0",
92
94
  "eslint-plugin-jsx-a11y": "6.4.1",
93
95
  "eslint-plugin-no-async-foreach": "0.1.1",
94
- "eslint-plugin-react": "^7.26.0",
96
+ "eslint-plugin-react": "7.26.0",
95
97
  "eslint-plugin-wpcalypso": "5.0.0",
96
98
  "flow-bin": "0.150.0",
97
99
  "jest": "27.2.1",
@@ -115,7 +117,7 @@
115
117
  "ini": "2.0.0",
116
118
  "json2csv": "5.0.6",
117
119
  "jwt-decode": "2.2.0",
118
- "lando": "git+https://github.com/lando/cli.git#v3.4.3",
120
+ "lando": "git+https://github.com/Automattic/lando-cli.git#v3.5.1-patch2021_12_06",
119
121
  "node-fetch": "^2.6.1",
120
122
  "opn": "5.5.0",
121
123
  "rollbar": "2.22.0",