@automattic/vip 2.20.0 → 2.22.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/CHANGELOG.md CHANGED
@@ -1,30 +1,59 @@
1
1
  ## Changelog
2
2
 
3
- ### 2.20.0 (23 Sep 2022)
4
-
5
- - #1121 Add support for custom PHP images
6
- - #1136 SQL Import: Add validation for unique_checks being disabled
7
- - #1131 SQL Import - Add ALTER TABLE statement validation
8
- - #1134 [dev-env] add app and env to tracks when creating env
9
- - #1135 [dev-env] Make xdebug config not break during wp update
10
- - #1098 Include options into reading software config
11
- - #1114 [dev-env] Verify current user is a docker user
12
- - #1130 Update/exec help
13
- - #1125 add validation output
14
- - #1127 Run wp-cli as www-data
15
- - #1120 Update php-fpm image names
16
- - #1126 Update memcached to 1.6-alpine3.16
17
- - #1124 [dev-env] Supress Setup wizard during update
18
- - #1111 [dev-env] prompt for es index after db import
19
- - #1119 Use --yes instead of --force
3
+ ## 2.22.0 (2 Nov 2022)
4
+
5
+ #1165 Add caching type policy for `WPSite` data
6
+ #1164 Fix regExp to categorize multisite tables during SQL Imports
7
+ #1163 Pull correct environment's details from API when displaying Multisite SQL Import preflight details
8
+ #1159 chore(deps): Bump debug from 4.3.3 to 4.3.4
9
+ #1162 chore(deps): Bump update-notifier from 4.1.3 to 5.1.0
10
+ #1160 chore(deps): Bump json2csv from 5.0.6 to 5.0.7
11
+ #1158 chore(deps): Bump args from 5.0.1 to 5.0.3
12
+ #1157 chore(deps): Bump semver from 7.3.5 to 7.3.8
13
+ #1155 chore(deps): Bump uuid from 8.3.2 to 9.0.0
14
+ #1154 chore(deps): Update Babel-related packages
15
+ #1153 chore(deps): Fix security vulnerabilities in dependencies
16
+ #1152 ci: Update workflows
17
+ #1151 refactor(dev-env): Modify `verifyDNSResolution()` to use Promises API
18
+
19
+ ### 2.21.0 (24 Oct 2022)
20
+
21
+ - #1143 [dev-env] adds default for wordpress version prompt
22
+ - #1146 fix(dev-env): Resolve the "xdebugConfig is not defined" issue
23
+ - #1142 Update Slack channel on which to (optionally) ping before release
24
+ - #1144 fix: Suppress ES security-related warnings
25
+ - #1132 [PIE-3105] Update VIP-CLI command line output
26
+ - #1118 Remove unused confirmation prompt during sql import
27
+ - #1137 [dev-env] simplify and rename elasticsearch service config
28
+ - #1138 [dev-env] Update/rename app code and mu-plugins
29
+
30
+ ### 2.20.0 (19 Oct 2022)
31
+
32
+ - #1121 Add support for custom PHP images
33
+ - #1136 SQL Import: Add validation for unique_checks being disabled
34
+ - #1131 SQL Import - Add ALTER TABLE statement validation
35
+ - #1134 [dev-env] add app and env to tracks when creating env
36
+ - #1135 [dev-env] Make xdebug config not break during wp update
37
+ - #1098 Include options into reading software config
38
+ - #1114 [dev-env] Verify current user is a docker user
39
+ - #1130 Update/exec help
40
+ - #1125 add validation output
41
+ - #1127 Run wp-cli as www-data
42
+ - #1120 Update php-fpm image names
43
+ - #1126 Update memcached to 1.6-alpine3.16
44
+ - #1124 [dev-env] Supress Setup wizard during update
45
+ - #1111 [dev-env] prompt for es index after db import
46
+ - #1119 Use --yes instead of --force
20
47
  - #1115 [dev-env] reclasify most common error
21
- - #1122 [dev-env] support xdebug_config environment variable
48
+ - #1122 [dev-env] support xdebug_config environment variable
22
49
  - #1129 Fix ESLint/Flow/SonarScan issues
23
50
  - #1133 Add PHP 8.2 image
24
51
  - #1141 SQL validation: Change formatting to make it more readable
25
52
 
53
+ https://github.com/Automattic/vip-cli/releases/tag/v2.20.0
54
+
26
55
  ### 2.19.2 (23 Sep 2022)
27
- - #1116 Reverted #1049 changes
56
+ - #1116 Reverted #1049 changes
28
57
 
29
58
  ### 2.19.0 (23 Sep 2022)
30
59
  - #1108 [dev-env] Validate import file and add debug lines
package/CONTRIBUTING.md CHANGED
@@ -50,7 +50,7 @@ Our release flow for VIP CLI follows this pattern:
50
50
  - This is a public repository. Please do not include any internal links in PRs, changelogs, testing instructions, etc.
51
51
  - Merge changes from your feature branch to the `develop` branch
52
52
  - If you are ready to release your changes publicly, merge your changes from the `develop` branch to the `master` branch. All changes that are not ready to be public should be feature flagged or stay in the `develop` branch to avoid conflicts when releasing urgent fixes (not recommended).
53
- - Finally, release your changes as a new minor or major NPM version. Ping in the #vip-platform-patisserie channel to notify folks of a new release, but please feel free to release your changes without any blockers from the team. Any team member that is part of the Automattic NPM organization can release a new version; if you aren't a member, generic credentials are available in the Secret Store.
53
+ - Finally, release your changes as a new minor or major NPM version. Ping in the #vip-platform channel to notify folks of a new release, but please feel free to release your changes without any blockers from the team. Any team member that is part of the Automattic NPM organization can release a new version; if you aren't a member, generic credentials are available in the Secret Store.
54
54
 
55
55
  ### Changelogs
56
56
  Changelogs allow customers to keep up with all the changes happening across our VIP Platform. Changelogs for VIP CLI are posted to the [VIP Cloud Changelog P2](https://wpvipchangelog.wordpress.com/), along with the repository’s `README.md`.
@@ -14,7 +14,7 @@ services:
14
14
  devtools:
15
15
  type: compose
16
16
  services:
17
- image: ghcr.io/automattic/vip-container-images/dev-tools:0.8
17
+ image: ghcr.io/automattic/vip-container-images/dev-tools:0.9
18
18
  command: sleep infinity
19
19
  volumes:
20
20
  - devtools:/dev-tools
@@ -27,7 +27,7 @@ services:
27
27
  ssl: true
28
28
  sslExpose: false
29
29
  services:
30
- image: ghcr.io/automattic/vip-container-images/nginx:1.21.6
30
+ image: ghcr.io/automattic/vip-container-images/nginx:1.23.2
31
31
  command: nginx -g "daemon off;"
32
32
  volumes:
33
33
  - ./nginx/extra.conf:/etc/nginx/conf.extra/extra.conf
@@ -92,11 +92,11 @@ services:
92
92
  environment:
93
93
  UPLOAD_LIMIT: 4G
94
94
  <% } %>
95
- <% if ( elasticsearchEnabled ) { %>
96
- vip-search:
95
+ <% if ( elasticsearch ) { %>
96
+ elasticsearch:
97
97
  type: compose
98
98
  services:
99
- image: elasticsearch:<%= elasticsearch %>
99
+ image: elasticsearch:7.17.2
100
100
  command: /usr/local/bin/docker-entrypoint.sh
101
101
  environment:
102
102
  ELASTICSEARCH_IS_DEDICATED_NODE: 'no'
@@ -104,6 +104,7 @@ services:
104
104
  ELASTICSEARCH_NODE_NAME: 'lando'
105
105
  ELASTICSEARCH_PORT_NUMBER: 9200
106
106
  discovery.type: 'single-node'
107
+ xpack.security.enabled: 'false'
107
108
  ports:
108
109
  - ":9200"
109
110
  volumes:
@@ -133,7 +134,7 @@ services:
133
134
  nocopy: true
134
135
 
135
136
  <% if ( muPlugins.mode == 'image' ) { %>
136
- mu-plugins:
137
+ vip-mu-plugins:
137
138
  type: compose
138
139
  services:
139
140
  image: ghcr.io/automattic/vip-container-images/mu-plugins:0.1
@@ -150,7 +151,7 @@ services:
150
151
  <% } %>
151
152
 
152
153
  <% if ( appCode.mode == 'image' ) { %>
153
- client-code:
154
+ demo-app-code:
154
155
  type: compose
155
156
  services:
156
157
  image: ghcr.io/automattic/vip-container-images/skeleton:latest
@@ -62,7 +62,6 @@ cmd.argv(process.argv, async (arg, opt) => {
62
62
  appCode: currentInstanceData.appCode.dir || currentInstanceData.appCode.tag || 'latest',
63
63
  muPlugins: currentInstanceData.muPlugins.dir || currentInstanceData.muPlugins.tag || 'latest',
64
64
  wordpress: currentInstanceData.wordpress.tag,
65
- elasticsearchEnabled: currentInstanceData.elasticsearchEnabled,
66
65
  elasticsearch: currentInstanceData.elasticsearch,
67
66
  php: currentInstanceData.php || _devEnvironment.DEV_ENVIRONMENT_PHP_VERSIONS.default,
68
67
  mariadb: currentInstanceData.mariadb,
@@ -279,6 +279,7 @@ const displayPlaybook = ({
279
279
  fileName,
280
280
  domain,
281
281
  formattedEnvironment,
282
+ unformattedEnvironment,
282
283
  isMultiSite,
283
284
  app
284
285
  }) => {
@@ -299,11 +300,12 @@ const displayPlaybook = ({
299
300
  let siteArray = [];
300
301
 
301
302
  if (isMultiSite) {
302
- var _app$environments$, _app$environments$$wp;
303
+ var _app$environments, _selectedEnvironmentO;
303
304
 
304
305
  // eslint-disable-next-line no-multi-spaces
305
306
  console.log(` multisite: ${isMultiSite.toString()}`);
306
- siteArray = app === null || app === void 0 ? void 0 : (_app$environments$ = app.environments[0]) === null || _app$environments$ === void 0 ? void 0 : (_app$environments$$wp = _app$environments$.wpSites) === null || _app$environments$$wp === void 0 ? void 0 : _app$environments$$wp.nodes;
307
+ const selectedEnvironmentObj = app === null || app === void 0 ? void 0 : (_app$environments = app.environments) === null || _app$environments === void 0 ? void 0 : _app$environments.find(env => unformattedEnvironment === env.type);
308
+ siteArray = selectedEnvironmentObj === null || selectedEnvironmentObj === void 0 ? void 0 : (_selectedEnvironmentO = selectedEnvironmentObj.wpSites) === null || _selectedEnvironmentO === void 0 ? void 0 : _selectedEnvironmentO.nodes;
307
309
  }
308
310
 
309
311
  if (!tableNames.length) {
@@ -330,9 +332,9 @@ const displayPlaybook = ({
330
332
  let siteRegex;
331
333
 
332
334
  if (wpSite.id === 1) {
333
- siteRegex = /wp_[a-z]+/i;
335
+ siteRegex = /^wp_[a-z]+/i;
334
336
  } else {
335
- siteRegex = new RegExp(`wp_${wpSite.id}_[a-z]+`, 'i');
337
+ siteRegex = new RegExp(`^wp_${wpSite.id}_[a-z]+`, 'i');
336
338
  }
337
339
 
338
340
  const tableNamesInGroup = tableNames.filter(name => siteRegex.test(name));
@@ -362,9 +364,7 @@ const displayPlaybook = ({
362
364
  appQuery,
363
365
  envContext: true,
364
366
  requiredArgs: 1,
365
- module: 'import-sql',
366
- requireConfirm: 'Are you sure you want to import the contents of the provided SQL file?',
367
- skipConfirmPrompt: true
367
+ module: 'import-sql'
368
368
  }).command('status', 'Check the status of the current running import').option('skip-validate', 'Do not perform pre-upload file validation. If unsupported entries are present, the import is likely to fail').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('output', 'Specify the replacement output file for Search and Replace', 'process.stdout').examples(examples).argv(process.argv, async (arg, opts) => {
369
369
  var _env$primaryDomain;
370
370
 
@@ -419,6 +419,7 @@ const displayPlaybook = ({
419
419
  fileName,
420
420
  domain,
421
421
  formattedEnvironment,
422
+ unformattedEnvironment: opts.env.type,
422
423
  isMultiSite,
423
424
  app
424
425
  }); // PROMPT TO PROCEED WITH THE IMPORT
package/dist/bin/vip.js CHANGED
@@ -65,22 +65,21 @@ const rootCmd = async function () {
65
65
  runCmd();
66
66
  } else {
67
67
  console.log();
68
- console.log(' Welcome to');
69
68
  console.log(' _ __ ________ ________ ____');
70
- console.log(' | | / // _/ __ \ / ____/ / / _/');
69
+ console.log(' | | / // _/ __ / ____/ / / _/');
71
70
  console.log(' | | / / / // /_/ /______/ / / / / / ');
72
71
  console.log(' | |/ /_/ // ____//_____/ /___/ /____/ / ');
73
- console.log(' |___//___/_/ \____/_____/___/ ');
72
+ console.log(' |___//___/_/ ____/_____/___/ ');
74
73
  console.log();
75
- console.log(' VIP CLI is your tool for interacting with and managing your VIP applications.');
74
+ console.log(' VIP-CLI is your tool for interacting with and managing your VIP applications.');
76
75
  console.log();
77
- console.log(` To get started, we need an access token for your VIP account. We'll open ${tokenURL} in your web browser; follow the instructions there to continue.`);
76
+ console.log(' Authenticate your installation of VIP-CLI with your Personal Access Token. This URL will be opened in your web browser automatically so that you can retrieve your token: ' + tokenURL);
78
77
  console.log();
79
78
  await (0, _tracker.trackEvent)('login_command_execute');
80
79
  const answer = await (0, _enquirer.prompt)({
81
80
  type: 'confirm',
82
81
  name: 'continue',
83
- message: 'Ready?'
82
+ message: 'Ready to authenticate?'
84
83
  });
85
84
 
86
85
  if (!answer.continue) {
package/dist/lib/api.js CHANGED
@@ -108,6 +108,15 @@ async function API({
108
108
  });
109
109
  return new _core.ApolloClient({
110
110
  link: _core2.ApolloLink.from([withToken, errorLink, authLink, httpLink]),
111
- cache: new _core.InMemoryCache()
111
+ cache: new _core.InMemoryCache({
112
+ typePolicies: {
113
+ WPSite: {
114
+ // By default the cache key is assumed to be `id` which is not globally unique.
115
+ // So we are using `id` + `homeUrl` to prevent clashing keys.
116
+ // Change this to `blogId` + `homeUrl` when we switch to using wpSitesSDS
117
+ keyFields: ['id', 'homeUrl']
118
+ }
119
+ }
120
+ })
112
121
  });
113
122
  }
@@ -11,7 +11,6 @@ exports.DEV_ENVIRONMENT_FULL_COMMAND = DEV_ENVIRONMENT_FULL_COMMAND;
11
11
  const DEV_ENVIRONMENT_DEFAULTS = {
12
12
  title: 'VIP Dev',
13
13
  multisite: false,
14
- elasticsearchVersion: '7.17.2',
15
14
  mariadbVersion: '10.3',
16
15
  phpVersion: '8.0'
17
16
  };
@@ -35,6 +35,8 @@ var _path = _interopRequireDefault(require("path"));
35
35
 
36
36
  var _os = _interopRequireDefault(require("os"));
37
37
 
38
+ var _dns = _interopRequireDefault(require("dns"));
39
+
38
40
  var _progress = require("../cli/progress");
39
41
 
40
42
  var _tracker = require("../tracker");
@@ -62,7 +64,7 @@ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { de
62
64
  * Internal dependencies
63
65
  */
64
66
  const debug = (0, _debug.default)('@automattic/vip:bin:dev-environment');
65
- const DEFAULT_SLUG = 'vip-local';
67
+ const DEFAULT_SLUG = 'vip-local'; // Forward declaratrion to avoid no-use-before-define
66
68
 
67
69
  async function handleCLIException(exception, trackKey, trackBaseInfo = {}) {
68
70
  const errorPrefix = _chalk.default.red('Error:');
@@ -103,28 +105,23 @@ async function handleCLIException(exception, trackKey, trackBaseInfo = {}) {
103
105
  }
104
106
  }
105
107
 
106
- const verifyDNSResolution = slug => {
107
- const dns = require('dns');
108
-
108
+ const verifyDNSResolution = async slug => {
109
109
  const expectedIP = '127.0.0.1';
110
110
  const testDomain = `${slug}.vipdev.lndo.site`;
111
111
  const advice = `Please add following line to hosts file on your system:\n${expectedIP} ${testDomain}`;
112
112
  debug(`Verifying DNS resolution for ${testDomain}`);
113
- return new Promise((resolve, reject) => {
114
- dns.lookup(testDomain, (error, address) => {
115
- debug(`Got DNS response ${address}`);
116
-
117
- if (error) {
118
- reject(new _userError.default(`DNS resolution for ${testDomain} failed. ${advice}`));
119
- }
113
+ let address;
120
114
 
121
- if (address !== expectedIP) {
122
- reject(new _userError.default(`DNS resolution for ${testDomain} returned unexpected IP ${address}. Expected value is ${expectedIP}. ${advice}`));
123
- }
115
+ try {
116
+ address = await _dns.default.promises.lookup(testDomain, 4);
117
+ debug(`Got DNS response ${address.address}`);
118
+ } catch (error) {
119
+ throw new _userError.default(`DNS resolution for ${testDomain} failed. ${advice}`);
120
+ }
124
121
 
125
- resolve();
126
- });
127
- });
122
+ if (address.address !== expectedIP) {
123
+ throw new _userError.default(`DNS resolution for ${testDomain} returned unexpected IP ${address.address}. Expected value is ${expectedIP}. ${advice}`);
124
+ }
128
125
  };
129
126
 
130
127
  const VALIDATION_STEPS = [{
@@ -243,15 +240,15 @@ function getOptionsFromAppInfo(appInfo) {
243
240
  * Prompt for arguments
244
241
  * @param {InstanceOptions} preselectedOptions - options to be used without prompt
245
242
  * @param {InstanceOptions} defaultOptions - options to be used as default values for prompt
246
- * @param {boolean} supressPrompts - supress prompts and use default values where needed
243
+ * @param {boolean} suppressPrompts - supress prompts and use default values where needed
247
244
  * @returns {any} instance data
248
245
  */
249
246
 
250
247
 
251
- async function promptForArguments(preselectedOptions, defaultOptions, supressPrompts = false) {
248
+ async function promptForArguments(preselectedOptions, defaultOptions, suppressPrompts = false) {
252
249
  debug('Provided preselected', preselectedOptions, 'and default', defaultOptions);
253
250
 
254
- if (supressPrompts) {
251
+ if (suppressPrompts) {
255
252
  preselectedOptions = { ...defaultOptions,
256
253
  ...preselectedOptions
257
254
  };
@@ -270,13 +267,13 @@ async function promptForArguments(preselectedOptions, defaultOptions, supressPro
270
267
  const instanceData = {
271
268
  wpTitle: preselectedOptions.title || (await promptForText('WordPress site title', defaultOptions.title || _devEnvironment.DEV_ENVIRONMENT_DEFAULTS.title)),
272
269
  multisite: 'multisite' in preselectedOptions ? preselectedOptions.multisite : await promptForBoolean(multisiteText, !!multisiteDefault),
273
- elasticsearchEnabled: false,
274
- elasticsearch: preselectedOptions.elasticsearch || defaultOptions.elasticsearch || _devEnvironment.DEV_ENVIRONMENT_DEFAULTS.elasticsearchVersion,
270
+ elasticsearch: false,
275
271
  php: preselectedOptions.php ? resolvePhpVersion(preselectedOptions.php) : await promptForPhpVersion(resolvePhpVersion(defaultOptions.php || _devEnvironment.DEV_ENVIRONMENT_DEFAULTS.phpVersion)),
276
272
  mariadb: preselectedOptions.mariadb || defaultOptions.mariadb || _devEnvironment.DEV_ENVIRONMENT_DEFAULTS.mariadbVersion,
277
273
  mediaRedirectDomain: preselectedOptions.mediaRedirectDomain || '',
278
274
  wordpress: {
279
- mode: 'image'
275
+ mode: 'image',
276
+ tag: ''
280
277
  },
281
278
  muPlugins: {
282
279
  mode: 'image'
@@ -323,12 +320,12 @@ async function promptForArguments(preselectedOptions, defaultOptions, supressPro
323
320
  debug(`Processing elasticsearch with preselected "${preselectedOptions.elasticsearch}"`);
324
321
 
325
322
  if ('elasticsearch' in preselectedOptions) {
326
- instanceData.elasticsearchEnabled = !!preselectedOptions.elasticsearch;
323
+ instanceData.elasticsearch = !!preselectedOptions.elasticsearch;
327
324
  } else {
328
- instanceData.elasticsearchEnabled = await promptForBoolean('Enable Elasticsearch (needed by Enterprise Search)?', defaultOptions.elasticsearchEnabled);
325
+ instanceData.elasticsearch = await promptForBoolean('Enable Elasticsearch (needed by Enterprise Search)?', !!defaultOptions.elasticsearch);
329
326
  }
330
327
 
331
- if (instanceData.elasticsearchEnabled) {
328
+ if (instanceData.elasticsearch) {
332
329
  instanceData.statsd = preselectedOptions.statsd || defaultOptions.statsd || false;
333
330
  } else {
334
331
  instanceData.statsd = false;
@@ -501,7 +498,7 @@ const componentDisplayNames = {
501
498
  const componentDemoyNames = {
502
499
  muPlugins: 'vip-go-mu-plugins',
503
500
  appCode: 'vip-go-skeleton'
504
- };
501
+ }; // eslint-disable-next-line no-redeclare
505
502
 
506
503
  async function promptForComponent(component, allowLocal, defaultObject) {
507
504
  debug(`Prompting for ${component} with default:`, defaultObject);
@@ -559,11 +556,12 @@ async function promptForComponent(component, allowLocal, defaultObject) {
559
556
  const tagChoices = await getTagChoices();
560
557
  const selectTag = new _enquirer.Select({
561
558
  message,
562
- choices: tagChoices
559
+ choices: tagChoices,
560
+ initial: (defaultObject === null || defaultObject === void 0 ? void 0 : defaultObject.tag) || ''
563
561
  });
564
562
  const option = await selectTag.run();
565
563
  return {
566
- mode: modeResult,
564
+ mode: 'image',
567
565
  tag: option
568
566
  };
569
567
  } // image
@@ -587,11 +585,7 @@ function processBooleanOption(value) {
587
585
  }
588
586
 
589
587
  function addDevEnvConfigurationOptions(command) {
590
- return command.option('wordpress', 'Use a specific WordPress version').option(['u', 'mu-plugins'], 'Use a specific mu-plugins changeset or local directory').option('app-code', 'Use the application code from a local directory or use "demo" for VIP skeleton code').option('statsd', 'Enable statsd component. By default it is disabled', undefined, processBooleanOption).option('phpmyadmin', 'Enable PHPMyAdmin component. By default it is disabled', undefined, processBooleanOption).option('xdebug', 'Enable XDebug. By default it is disabled', undefined, processBooleanOption).option('xdebug_config', 'Extra configuration to pass to xdebug via XDEBUG_CONFIG environment variable').option('elasticsearch', 'Explicitly choose Elasticsearch version to use or false to disable it', undefined, value => {
591
- var _value$toLowerCase2;
592
-
593
- return FALSE_OPTIONS.includes(value === null || value === void 0 ? void 0 : (_value$toLowerCase2 = value.toLowerCase) === null || _value$toLowerCase2 === void 0 ? void 0 : _value$toLowerCase2.call(value)) ? false : value;
594
- }).option('mariadb', 'Explicitly choose MariaDB version to use').option(['r', '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.').option('php', 'Explicitly choose PHP version to use');
588
+ return command.option('wordpress', 'Use a specific WordPress version').option(['u', 'mu-plugins'], 'Use a specific mu-plugins changeset or local directory').option('app-code', 'Use the application code from a local directory or use "demo" for VIP skeleton code').option('statsd', 'Enable statsd component. By default it is disabled', undefined, processBooleanOption).option('phpmyadmin', 'Enable PHPMyAdmin component. By default it is disabled', undefined, processBooleanOption).option('xdebug', 'Enable XDebug. By default it is disabled', undefined, processBooleanOption).option('xdebug_config', 'Extra configuration to pass to xdebug via XDEBUG_CONFIG environment variable').option('elasticsearch', 'Enable Elasticsearch (needed by Enterprise Search)', undefined, processBooleanOption).option('mariadb', 'Explicitly choose MariaDB version to use').option(['r', '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.').option('php', 'Explicitly choose PHP version to use');
595
589
  }
596
590
  /**
597
591
  * Provides the list of tag choices for selection
@@ -599,10 +593,28 @@ function addDevEnvConfigurationOptions(command) {
599
593
 
600
594
 
601
595
  async function getTagChoices() {
602
- const versions = await (0, _devEnvironmentCore.getVersionList)();
596
+ let versions = await (0, _devEnvironmentCore.getVersionList)();
603
597
 
604
598
  if (versions.length < 1) {
605
- return ['5.9', '5.8', '5.7', '5.6', '5.5'];
599
+ versions = [{
600
+ ref: '5.9.5',
601
+ tag: '5.9',
602
+ cacheable: true,
603
+ locked: true,
604
+ prerelease: false
605
+ }, {
606
+ ref: '5.8.6',
607
+ tag: '5.8',
608
+ cacheable: true,
609
+ locked: true,
610
+ prerelease: false
611
+ }, {
612
+ ref: '5.7.8',
613
+ tag: '5.7',
614
+ cacheable: true,
615
+ locked: true,
616
+ prerelease: false
617
+ }];
606
618
  }
607
619
 
608
620
  return versions.map(version => {
@@ -164,13 +164,17 @@ function preProcessInstanceData(instanceData) {
164
164
  newInstanceData.mediaRedirectDomain = `https://${instanceData.mediaRedirectDomain}`;
165
165
  }
166
166
 
167
- newInstanceData.elasticsearchEnabled = instanceData.elasticsearchEnabled || false;
167
+ newInstanceData.elasticsearch = instanceData.elasticsearch || false;
168
168
  newInstanceData.php = instanceData.php || _devEnvironment.DEV_ENVIRONMENT_PHP_VERSIONS.default;
169
169
 
170
170
  if (newInstanceData.php.startsWith('image:')) {
171
171
  newInstanceData.php = newInstanceData.php.slice('image:'.length);
172
172
  }
173
173
 
174
+ if (!newInstanceData.xdebugConfig) {
175
+ newInstanceData.xdebugConfig = '';
176
+ }
177
+
174
178
  return newInstanceData;
175
179
  }
176
180
 
@@ -289,9 +293,9 @@ function readEnvironmentData(slug) {
289
293
  ***********************************/
290
294
  // REMOVEME after the wheel of time spins around few times
291
295
 
292
- if (instanceData.enterpriseSearchEnabled) {
293
- // enterpriseSearchEnabled was renamed to elasticsearchEnabled
294
- instanceData.elasticsearchEnabled = instanceData.enterpriseSearchEnabled;
296
+ if (instanceData.enterpriseSearchEnabled || instanceData.elasticsearchEnabled) {
297
+ // enterpriseSearchEnabled and elasticsearchEnabled was renamed to elasticsearch
298
+ instanceData.elasticsearch = instanceData.enterpriseSearchEnabled || instanceData.elasticsearchEnabled;
295
299
  } // REMOVEME after the wheel of time spins around few times
296
300
 
297
301
 
@@ -316,20 +320,13 @@ async function prepareLandoEnv(instanceData, instancePath) {
316
320
 
317
321
  const instanceDataTargetPath = _path.default.join(instancePath, instanceDataFileName);
318
322
 
319
- _fs.default.mkdirSync(instancePath, {
323
+ await _fs.default.promises.mkdir(instancePath, {
320
324
  recursive: true
321
325
  });
322
-
323
- _fs.default.mkdirSync(nginxFolderPath, {
326
+ await _fs.default.promises.mkdir(nginxFolderPath, {
324
327
  recursive: true
325
328
  });
326
-
327
- _fs.default.writeFileSync(landoFileTargetPath, landoFile);
328
-
329
- _fs.default.writeFileSync(nginxFileTargetPath, nginxFile);
330
-
331
- _fs.default.writeFileSync(instanceDataTargetPath, instanceDataFile);
332
-
329
+ await Promise.all([_fs.default.promises.writeFile(landoFileTargetPath, landoFile), _fs.default.promises.writeFile(nginxFileTargetPath, nginxFile), _fs.default.promises.writeFile(instanceDataTargetPath, instanceDataFile)]);
333
330
  debug(`Lando file created in ${landoFileTargetPath}`);
334
331
  debug(`Nginx file created in ${nginxFileTargetPath}`);
335
332
  debug(`Instance data file created in ${instanceDataTargetPath}`);
@@ -584,7 +581,7 @@ async function updateWordPressImage(slug) {
584
581
  } else {
585
582
  console.log('Environment WordPress version is: ' + _chalk.default.yellow(`${match.tag} (${match.ref})`));
586
583
 
587
- if (envData.wordpress.doNotUpgrade || false) {
584
+ if (envData.wordpress.doNotUpgrade) {
588
585
  return false;
589
586
  }
590
587
  } // Prompt the user to select a new WordPress Version
@@ -600,18 +597,13 @@ async function updateWordPressImage(slug) {
600
597
  if (confirm.upgrade === 'yes') {
601
598
  console.log('Upgrading from: ' + _chalk.default.yellow(currentWordPressTag) + ' to:'); // Select a new image
602
599
 
603
- const choice = await (0, _devEnvironmentCli.promptForComponent)('wordpress');
600
+ const choice = await (0, _devEnvironmentCli.promptForComponent)('wordpress', false, null);
604
601
  const version = versions.find(({
605
602
  tag
606
603
  }) => tag.trim() === choice.tag.trim()); // Write new data and stage for rebuild
607
604
 
608
605
  envData.wordpress.tag = version.tag;
609
- envData.wordpress.ref = version.ref; // Ensure xdebugConfig is not undefined (needed by .lando.yml template)
610
-
611
- if (!envData.xdebugConfig) {
612
- envData.xdebugConfig = '';
613
- }
614
-
606
+ envData.wordpress.ref = version.ref;
615
607
  await updateEnvironment(envData);
616
608
  return true;
617
609
  }
@@ -664,17 +656,10 @@ async function getVersionList() {
664
656
 
665
657
  try {
666
658
  // If the cache doesn't exist, create it
667
- if (!_fs.default.existsSync(cacheFile)) {
659
+ // If the cache is expired, refresh it
660
+ if (!_fs.default.existsSync(cacheFile) || isVersionListExpired(cacheFile, _devEnvironment.DEV_ENVIRONMENT_WORDPRESS_VERSION_TTL)) {
668
661
  res = await fetchVersionList();
669
-
670
- _fs.default.writeFileSync(cacheFile, res);
671
- } // If the cache is expired, refresh it
672
-
673
-
674
- if (isVersionListExpired(cacheFile, _devEnvironment.DEV_ENVIRONMENT_WORDPRESS_VERSION_TTL)) {
675
- res = await fetchVersionList();
676
-
677
- _fs.default.writeFileSync(cacheFile, res);
662
+ await _fs.default.promises.writeFile(cacheFile, res);
678
663
  }
679
664
  } catch (err) {
680
665
  // Soft error handling here, since it's still possible to use a previously cached file.
@@ -684,7 +669,8 @@ async function getVersionList() {
684
669
 
685
670
 
686
671
  try {
687
- return JSON.parse(_fs.default.readFileSync(cacheFile));
672
+ const data = await _fs.default.promises.readFile(cacheFile, 'utf8');
673
+ return JSON.parse(data);
688
674
  } catch (err) {
689
675
  debug(err);
690
676
  return [];