@automattic/vip 3.9.4 → 3.9.6

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.
@@ -19,18 +19,14 @@ services:
19
19
  type: compose
20
20
  services:
21
21
  image: ghcr.io/automattic/vip-container-images/dev-tools:0.9
22
- command: /bin/true
23
22
  volumes:
24
23
  - devtools:/dev-tools
25
24
  - scripts:/scripts
26
- environment:
27
- LANDO_NO_USER_PERMS: 1
28
- LANDO_NO_SCRIPTS: 1
29
- LANDO_NEEDS_EXEC: 1
30
25
  volumes:
31
26
  devtools: {}
32
27
  scripts:
33
28
  initOnly: true
29
+ entrypoint: sh -c 'test -d /dev-tools-orig && /usr/bin/rsync -a --delete /dev-tools-orig/ /dev-tools/ || true'
34
30
 
35
31
  nginx:
36
32
  type: compose
@@ -38,14 +34,13 @@ services:
38
34
  sslExpose: false
39
35
  services:
40
36
  image: ghcr.io/automattic/vip-container-images/nginx:latest
41
- command: nginx -g "daemon off;"
42
- environment:
43
- LANDO_NEEDS_EXEC: 1
44
- LANDO_WEBROOT_USER: nginx
45
- LANDO_WEBROOT_GROUP: nginx
46
37
  volumes:
47
38
  - ./nginx/extra.conf:/etc/nginx/conf.extra/extra.conf
48
39
  <% wpVolumes() %>
40
+ depends_on:
41
+ php:
42
+ condition: service_started
43
+ entrypoint: /usr/sbin/nginx -g "daemon off;"
49
44
 
50
45
  php:
51
46
  type: compose
@@ -66,6 +61,27 @@ services:
66
61
  <% } %>
67
62
  LANDO_NO_USER_PERMS: 'enable'
68
63
  LANDO_NEEDS_EXEC: 1
64
+ depends_on:
65
+ database:
66
+ condition: service_started
67
+ memcached:
68
+ condition: service_started
69
+ <% if ( elasticsearch ) { %>
70
+ elasticsearch:
71
+ condition: service_started
72
+ <% } %>
73
+ devtools:
74
+ condition: service_completed_successfully
75
+ wordpress:
76
+ condition: service_completed_successfully
77
+ <% if ( muPlugins.mode == 'image' ) { %>
78
+ vip-mu-plugins:
79
+ condition: service_started
80
+ <% } %>
81
+ <% if ( appCode.mode == 'image' ) { %>
82
+ demo-app-code:
83
+ condition: service_completed_successfully
84
+ <% } %>
69
85
  volumes:
70
86
  - type: volume
71
87
  source: devtools
@@ -175,8 +191,6 @@ services:
175
191
  type: compose
176
192
  services:
177
193
  image: ghcr.io/automattic/vip-container-images/wordpress:<%= wordpress.tag %>
178
- # command: /usr/local/bin/entrypoint.sh
179
- command: sh -c "rsync -a --chown=www-data:www-data /wp/ /shared/; sleep infinity"
180
194
  volumes:
181
195
  - ./wordpress:/shared
182
196
  - type: volume
@@ -184,10 +198,8 @@ services:
184
198
  target: /scripts
185
199
  volume:
186
200
  nocopy: true
187
- # environment:
188
- # LANDO_NO_SCRIPTS: 1
189
- # LANDO_NEEDS_EXEC: 1
190
- # initOnly: true
201
+ initOnly: true
202
+ entrypoint: /usr/bin/rsync -a --chown=${LANDO_HOST_USER_ID}:${LANDO_HOST_GROUP_ID} /wp/ /shared/
191
203
 
192
204
  <% if ( muPlugins.mode == 'image' ) { %>
193
205
  vip-mu-plugins:
@@ -5,6 +5,7 @@ var _chalk = _interopRequireDefault(require("chalk"));
5
5
  var _app = _interopRequireDefault(require("../lib/api/app"));
6
6
  var _command = _interopRequireWildcard(require("../lib/cli/command"));
7
7
  var _tracker = require("../lib/tracker");
8
+ var _utils = require("../lib/utils");
8
9
  function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
9
10
  function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
10
11
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
@@ -20,14 +21,24 @@ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e
20
21
  await (0, _tracker.trackEvent)('app_command_fetch_error', {
21
22
  error: `App ${arg[0]} does not exist`
22
23
  });
23
- console.log(`App ${_chalk.default.blueBright(arg[0])} does not exist`);
24
+
25
+ // Get error message, if available.
26
+ const apiErrorMsg = (0, _utils.parseApiError)(err);
27
+ let errorMsg = `Unable to locate app ${_chalk.default.blueBright(arg[0])}: `;
28
+ if (apiErrorMsg) {
29
+ errorMsg += apiErrorMsg;
30
+ } else {
31
+ // No error message, so let's include stack trace for debugging.
32
+ errorMsg += 'Unknown error. Please contact VIP support if this persists.\n' + err.stack;
33
+ }
34
+ console.log(errorMsg);
24
35
  return;
25
36
  }
26
37
  if (!res || !res.environments) {
27
38
  await (0, _tracker.trackEvent)('app_command_fetch_error', {
28
39
  error: `App ${arg[0]} does not exist`
29
40
  });
30
- console.log(`App ${_chalk.default.blueBright(arg[0])} does not exist`);
41
+ console.log(`App ${_chalk.default.blueBright(arg[0])} was not found`);
31
42
  return;
32
43
  }
33
44
  await (0, _tracker.trackEvent)('app_command_success');
@@ -17,6 +17,7 @@ var _package = _interopRequireDefault(require("../../../package.json"));
17
17
  var _api = _interopRequireDefault(require("../../lib/api"));
18
18
  var _app = _interopRequireDefault(require("../../lib/api/app"));
19
19
  var _tracker = require("../../lib/tracker");
20
+ var _utils = require("../../lib/utils");
20
21
  var _userError = _interopRequireDefault(require("../user-error"));
21
22
  function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
22
23
  function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
@@ -214,7 +215,7 @@ _args.default.argv = async function (argv, cb) {
214
215
  await (0, _tracker.trackEvent)('command_appcontext_list_select_error', {
215
216
  error: 'Invalid app selected'
216
217
  });
217
- exit.withError(`App ${_chalk.default.blueBright(appSelection.app.name)} does not exist`);
218
+ exit.withError(`App ${_chalk.default.blueBright(appSelection.app.name)} could not be located`);
218
219
  }
219
220
  await (0, _tracker.trackEvent)('command_appcontext_list_select_success');
220
221
  options.app = {
@@ -228,7 +229,17 @@ _args.default.argv = async function (argv, cb) {
228
229
  await (0, _tracker.trackEvent)('command_appcontext_param_error', {
229
230
  error: 'App lookup failed'
230
231
  });
231
- exit.withError(`App ${_chalk.default.blueBright(options.app)} does not exist`);
232
+
233
+ // Get error message, if available.
234
+ const apiErrorMsg = (0, _utils.parseApiError)(err);
235
+ let errorMsg = `Unable to find app ${_chalk.default.blueBright(options.app)}: `;
236
+ if (apiErrorMsg) {
237
+ errorMsg += apiErrorMsg;
238
+ } else {
239
+ // Should happen rarely, if ever. Let's include stack trace for debugging.
240
+ errorMsg += 'Unknown error. If this persists, please contact VIP support.\n' + err.stack;
241
+ }
242
+ exit.withError(errorMsg);
232
243
  }
233
244
  if (!appLookup?.id) {
234
245
  await (0, _tracker.trackEvent)('command_appcontext_param_error', {
@@ -36,4 +36,4 @@ const DEV_ENVIRONMENT_DEFAULTS = exports.DEV_ENVIRONMENT_DEFAULTS = {
36
36
  multisite: false,
37
37
  phpVersion: Object.keys(DEV_ENVIRONMENT_PHP_VERSIONS)[0]
38
38
  };
39
- const DEV_ENVIRONMENT_VERSION = exports.DEV_ENVIRONMENT_VERSION = '2.1.2';
39
+ const DEV_ENVIRONMENT_VERSION = exports.DEV_ENVIRONMENT_VERSION = '2.1.3';
@@ -85,7 +85,11 @@ async function getLandoConfig() {
85
85
  userConfRoot: landoDir,
86
86
  home: fakeHomeDir,
87
87
  domain: 'vipdev.lndo.site',
88
- version: 'unknown'
88
+ version: 'unknown',
89
+ env: {
90
+ LANDO_HOST_USER_ID: process.platform === 'win32' ? '1000' : `${(0, _nodeOs.userInfo)().uid}`,
91
+ LANDO_HOST_GROUP_ID: process.platform === 'win32' ? '1000' : `${(0, _nodeOs.userInfo)().gid}`
92
+ }
89
93
  };
90
94
  return (0, _bootstrap.buildConfig)(config);
91
95
  }
@@ -231,7 +235,6 @@ async function landoRebuild(lando, instancePath) {
231
235
  try {
232
236
  debug('Will rebuild lando app on path:', instancePath);
233
237
  const app = await getLandoApplication(lando, instancePath);
234
- app.events.on('post-uninstall', async () => removeDevToolsVolumes(lando, app));
235
238
  await ensureNoOrphantProxyContainer(lando);
236
239
  await app.rebuild();
237
240
  } finally {
@@ -526,39 +529,6 @@ async function landoShell(lando, instancePath, service, user, command) {
526
529
  });
527
530
  }
528
531
 
529
- /**
530
- * Dev-tools volumes can get stale and is not updated when the new version of dev-tools
531
- * image is installed. Removing it during rebuild ensures the content is freshly populated
532
- * on startup.
533
- *
534
- * @param {Lando} lando
535
- * @param {App} app
536
- */
537
- async function removeDevToolsVolumes(lando, app) {
538
- debug('Attempting to removing dev-tools volumes');
539
- const scanResult = await lando.engine.docker.listVolumes();
540
- const devToolsVolumeNames = scanResult.Volumes.map(volume => volume.Name)
541
- // eslint-disable-next-line security/detect-non-literal-regexp
542
- .filter(volumeName => new RegExp(`${app.project}.*devtools`).test(volumeName));
543
- debug('Will remove', devToolsVolumeNames);
544
- const removalPromises = devToolsVolumeNames.map(volumeName => removeVolume(lando, volumeName));
545
- await Promise.all(removalPromises);
546
- }
547
-
548
- /**
549
- * Remove volume
550
- */
551
- async function removeVolume(lando, volumeName) {
552
- debug(`Removing devtools volume ${volumeName}`);
553
- const devToolsVolume = lando.engine.docker.getVolume(volumeName);
554
- try {
555
- await devToolsVolume.remove();
556
- debug(`${volumeName} volume removed`);
557
- } catch (err) {
558
- debug(`Failed to remove volume ${volumeName}`, err);
559
- }
560
- }
561
-
562
532
  /**
563
533
  * Sometimes the proxy network seems to disapper leaving only orphant stopped proxy container.
564
534
  * It seems to happen while restarting/powering off computer. This container would then failed
package/dist/lib/utils.js CHANGED
@@ -3,6 +3,7 @@
3
3
  exports.__esModule = true;
4
4
  exports.getAbsolutePath = getAbsolutePath;
5
5
  exports.makeTempDir = makeTempDir;
6
+ exports.parseApiError = parseApiError;
6
7
  exports.pollUntil = pollUntil;
7
8
  var _debug = _interopRequireDefault(require("debug"));
8
9
  var _fs = _interopRequireDefault(require("fs"));
@@ -74,4 +75,24 @@ function getAbsolutePath(filePath) {
74
75
  return _path.default.resolve(process.cwd(), filePath);
75
76
  }
76
77
  return filePath;
78
+ }
79
+
80
+ /**
81
+ * Parse error object and return probable error.
82
+ *
83
+ * @param {Error} Error object
84
+ *
85
+ * @return {string|null} Error string when error was found, otherwise null.
86
+ */
87
+ function parseApiError(err) {
88
+ if (err?.networkError?.message) {
89
+ return err?.networkError?.message;
90
+ }
91
+ if (err?.graphQLErrors?.[0]?.message) {
92
+ return err.graphQLErrors[0].message;
93
+ }
94
+ if (err?.message) {
95
+ return err?.message;
96
+ }
97
+ return null;
77
98
  }
@@ -312,6 +312,17 @@ const checks = {
312
312
  message: 'ENGINE != InnoDB',
313
313
  excerpt: "'ENGINE=InnoDB' should be present (case-insensitive) for all tables",
314
314
  recommendation: "Ensure your application works with InnoDB and update your SQL dump to include only 'ENGINE=InnoDB' engine definitions in 'CREATE TABLE' statements. " + "We suggest you search for all 'ENGINE=X' entries and replace them with 'ENGINE=InnoDB'!"
315
+ },
316
+ autoIncrement: {
317
+ matcher: /\s(NOT NULL AUTO_INCREMENT,)/i,
318
+ matchHandler: (_lineNumber, results) => ({
319
+ text: results[1]
320
+ }),
321
+ outputFormatter: requiredCheckFormatter,
322
+ results: [],
323
+ message: 'AUTO_INCREMENT attribute',
324
+ excerpt: "'AUTO_INCREMENT attribute' should be present (case-insensitive) for all CREATE TABLE statements",
325
+ recommendation: 'Check import settings to include AUTO_INCREMENT attribute in all the CREATE TABLE statements'
315
326
  }
316
327
  };
317
328
  const DEV_ENV_SPECIFIC_CHECKS = ['useStatement', 'siteHomeUrlLando'];
package/docs/CHANGELOG.md CHANGED
@@ -1,5 +1,13 @@
1
1
  ## Changelog
2
2
 
3
+ ### 3.9.5
4
+
5
+ * fix: improve error handling and output
6
+ * refactor(dev-env): make wordpress init-only container
7
+ * refactor(dev-env): let dev-tools handle their volumes
8
+
9
+ **Full Changelog**: https://github.com/Automattic/vip-cli/compare/3.9.4...3.9.5
10
+
3
11
  ### 3.9.4
4
12
 
5
13
  * fix(phpmyadmin): populate application name in App Query
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "@automattic/vip",
3
- "version": "3.9.4",
3
+ "version": "3.9.6",
4
4
  "lockfileVersion": 2,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "@automattic/vip",
9
- "version": "3.9.4",
9
+ "version": "3.9.6",
10
10
  "hasInstallScript": true,
11
11
  "license": "MIT",
12
12
  "dependencies": {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@automattic/vip",
3
- "version": "3.9.4",
3
+ "version": "3.9.6",
4
4
  "description": "The VIP Javascript library & CLI",
5
5
  "main": "index.js",
6
6
  "bin": {