@automattic/vip 2.4.0 → 2.7.0-dev2
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 +16 -0
- package/automattic-vip-2.7.0-dev2.tgz +0 -0
- package/config/config.json +2 -2
- package/dist/bin/vip-config-envvar-delete.js +4 -0
- package/dist/bin/vip-config-envvar-set.js +4 -0
- package/dist/bin/vip-dev-env-create.js +11 -24
- package/dist/bin/vip-dev-env-import-sql.js +13 -2
- package/dist/bin/vip-dev-env-update.js +80 -0
- package/dist/bin/vip-dev-env.js +1 -1
- package/dist/bin/vip-import-media-abort.js +0 -0
- package/dist/bin/vip-import-media-status.js +0 -0
- package/dist/bin/vip-import-sql.js +2 -1
- package/dist/bin/vip-import.js +0 -0
- package/dist/bin/vip-logs.js +151 -0
- package/dist/bin/vip.js +1 -1
- package/dist/lib/app-logs/app-logs.js +62 -0
- package/dist/lib/constants/dev-environment.js +3 -1
- package/dist/lib/dev-environment/dev-environment-cli.js +107 -47
- package/dist/lib/dev-environment/dev-environment-core.js +54 -8
- package/dist/lib/dev-environment/dev-environment-lando.js +4 -2
- package/dist/lib/dev-environment/types.js +1 -0
- package/dist/lib/site-import/db-file-import.js +1 -1
- package/dist/lib/site-import/status.js +1 -1
- package/package.json +7 -5
package/README.md
CHANGED
|
@@ -27,6 +27,22 @@ By default, we record information about the usage of this tool using an in-house
|
|
|
27
27
|
|
|
28
28
|
## Changelog
|
|
29
29
|
|
|
30
|
+
### 2.6.0 (23 November 2021)
|
|
31
|
+
- #921 [dev-env] Introuces update to change existing environment
|
|
32
|
+
- #928 [dev-env] Switch lando to use our fork
|
|
33
|
+
- #927 [dev-env] Handles user already exists during sql import
|
|
34
|
+
- #925 [dev-env] Fix the issue with dev-env update
|
|
35
|
+
- #924 FORNO-985 Increase SQL Import limit for unlaunched sites to 100GB
|
|
36
|
+
- #923 FORNO-943 Fixes a bug which prevents displaying SQL Import error messages
|
|
37
|
+
- #922 Update eslint-config-wpvip commit hash to c6605d1
|
|
38
|
+
- #873 Pin dependencies
|
|
39
|
+
|
|
40
|
+
### 2.5.0 (9 November 2021)
|
|
41
|
+
- #919 [dev-env] Expose lando core logs
|
|
42
|
+
- #916 [dev-env] Save instance data state
|
|
43
|
+
- #914 [dev-env] update help wording for dev env
|
|
44
|
+
- #915 Add warning message when an envvar is set/deleted
|
|
45
|
+
|
|
30
46
|
### 2.4.0 (5 November 2021)
|
|
31
47
|
- #913 [dev-env] No login required for dev-env
|
|
32
48
|
- #911 Adds more release instructions
|
|
Binary file
|
package/config/config.json
CHANGED
|
@@ -82,6 +82,10 @@ async function deleteEnvVarCommand(arg, opt) {
|
|
|
82
82
|
});
|
|
83
83
|
await (0, _tracker.trackEvent)('envvar_delete_command_success', trackingParams);
|
|
84
84
|
console.log(_chalk.default.green(`Successfully deleted environment variable ${JSON.stringify(name)}`));
|
|
85
|
+
|
|
86
|
+
if (!opt.skipConfirmation) {
|
|
87
|
+
console.log(_chalk.default.bgYellow(_chalk.default.bold('Important:')), 'Updates to environment variables will not be available until the application’s next deploy.');
|
|
88
|
+
}
|
|
85
89
|
}
|
|
86
90
|
|
|
87
91
|
(0, _command.default)({
|
|
@@ -101,6 +101,10 @@ async function setEnvVarCommand(arg, opt) {
|
|
|
101
101
|
});
|
|
102
102
|
await (0, _tracker.trackEvent)('envvar_set_command_success', trackingParams);
|
|
103
103
|
console.log(_chalk.default.green(`Successfully set environment variable ${JSON.stringify(name)}`));
|
|
104
|
+
|
|
105
|
+
if (!opt.skipConfirmation) {
|
|
106
|
+
console.log(_chalk.default.bgYellow(_chalk.default.bold('Important:')), 'Updates to environment variables will not be available until the application’s next deploy.');
|
|
107
|
+
}
|
|
104
108
|
}
|
|
105
109
|
|
|
106
110
|
(0, _command.default)({
|
|
@@ -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
|
|
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
|
-
})
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
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
|
|
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,
|
|
95
|
-
|
|
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)(
|
|
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
|
-
|
|
66
|
-
|
|
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
|
}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
*
|
|
5
|
+
* @format
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* External dependencies
|
|
10
|
+
*/
|
|
11
|
+
"use strict";
|
|
12
|
+
|
|
13
|
+
var _debug = _interopRequireDefault(require("debug"));
|
|
14
|
+
|
|
15
|
+
var _chalk = _interopRequireDefault(require("chalk"));
|
|
16
|
+
|
|
17
|
+
var _command = _interopRequireDefault(require("../lib/cli/command"));
|
|
18
|
+
|
|
19
|
+
var _devEnvironmentCli = require("../lib/dev-environment/dev-environment-cli");
|
|
20
|
+
|
|
21
|
+
var _devEnvironment = require("../lib/constants/dev-environment");
|
|
22
|
+
|
|
23
|
+
var _devEnvironmentCore = require("../lib/dev-environment/dev-environment-core");
|
|
24
|
+
|
|
25
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Internal dependencies
|
|
29
|
+
*/
|
|
30
|
+
const debug = (0, _debug.default)('@automattic/vip:bin:dev-environment');
|
|
31
|
+
const examples = [{
|
|
32
|
+
usage: `${_devEnvironment.DEV_ENVIRONMENT_FULL_COMMAND} update`,
|
|
33
|
+
description: 'Retriggers setup wizard in order to change environment configuration'
|
|
34
|
+
}];
|
|
35
|
+
const cmd = (0, _command.default)().option('slug', 'Custom name of the dev environment');
|
|
36
|
+
(0, _devEnvironmentCli.addDevEnvConfigurationOptions)(cmd);
|
|
37
|
+
cmd.examples(examples);
|
|
38
|
+
cmd.argv(process.argv, async (arg, opt) => {
|
|
39
|
+
const slug = (0, _devEnvironmentCli.getEnvironmentName)(opt);
|
|
40
|
+
|
|
41
|
+
try {
|
|
42
|
+
const environmentAlreadyExists = (0, _devEnvironmentCore.doesEnvironmentExist)(slug);
|
|
43
|
+
|
|
44
|
+
if (!environmentAlreadyExists) {
|
|
45
|
+
throw new Error(_devEnvironment.DEV_ENVIRONMENT_NOT_FOUND);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
const currentInstanceData = (0, _devEnvironmentCore.readEnvironmentData)(slug);
|
|
49
|
+
debug('Read instance data', currentInstanceData);
|
|
50
|
+
const preselectedOptions = {
|
|
51
|
+
// Title and multisite can't be changed during update
|
|
52
|
+
title: currentInstanceData.wpTitle,
|
|
53
|
+
multisite: currentInstanceData.multisite,
|
|
54
|
+
...opt
|
|
55
|
+
};
|
|
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);
|
|
72
|
+
} catch (error) {
|
|
73
|
+
if ('ENOENT' === error.code) {
|
|
74
|
+
const message = 'Environment was created before update was supported.\n\nTo update environment please destroy it and create a new one.';
|
|
75
|
+
(0, _devEnvironmentCli.handleCLIException)(new Error(message));
|
|
76
|
+
} else {
|
|
77
|
+
(0, _devEnvironmentCli.handleCLIException)(error);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
});
|
package/dist/bin/vip-dev-env.js
CHANGED
|
@@ -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);
|
|
File without changes
|
|
File without changes
|
package/dist/bin/vip-import.js
CHANGED
|
File without changes
|
|
@@ -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 (
|
|
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
|
-
|
|
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
|
-
|
|
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 (
|
|
134
|
-
|
|
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:
|
|
143
|
-
multisite: 'multisite' in
|
|
144
|
-
elasticsearch:
|
|
145
|
-
mariadb:
|
|
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 (
|
|
154
|
-
const mediaRedirectPromptText = `Would you like to redirect to ${
|
|
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 =
|
|
179
|
+
instanceData.mediaRedirectDomain = defaultOptions.mediaRedirectDomain;
|
|
159
180
|
}
|
|
160
181
|
}
|
|
161
182
|
|
|
162
183
|
for (const component of _devEnvironment.DEV_ENVIRONMENT_COMPONENTS) {
|
|
163
|
-
const option =
|
|
164
|
-
|
|
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,
|
|
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 (
|
|
175
|
-
result = processComponentOptionInput(
|
|
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
|
|
278
|
+
const modChoices = [];
|
|
246
279
|
|
|
247
280
|
if (allowLocal) {
|
|
248
|
-
|
|
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
|
-
|
|
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 =
|
|
302
|
+
const selectMode = modChoices.length > 1;
|
|
266
303
|
|
|
267
304
|
if (selectMode) {
|
|
268
|
-
const initialModeIndex =
|
|
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:
|
|
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
|
/**
|
|
@@ -64,6 +68,7 @@ const nginxFileTemplatePath = _path.default.join(__dirname, '..', '..', '..', 'a
|
|
|
64
68
|
|
|
65
69
|
const landoFileName = '.lando.yml';
|
|
66
70
|
const nginxFileName = 'extra.conf';
|
|
71
|
+
const instanceDataFileName = 'instance_data.json';
|
|
67
72
|
const homeDirPathInsideContainers = '/user';
|
|
68
73
|
const uploadPathString = 'uploads';
|
|
69
74
|
const nginxPathString = 'nginx';
|
|
@@ -76,7 +81,7 @@ async function startEnvironment(slug, options) {
|
|
|
76
81
|
const environmentExists = _fs.default.existsSync(instancePath);
|
|
77
82
|
|
|
78
83
|
if (!environmentExists) {
|
|
79
|
-
throw new Error(
|
|
84
|
+
throw new Error(_devEnvironment.DEV_ENVIRONMENT_NOT_FOUND);
|
|
80
85
|
}
|
|
81
86
|
|
|
82
87
|
if (options.skipRebuild) {
|
|
@@ -96,7 +101,7 @@ async function stopEnvironment(slug) {
|
|
|
96
101
|
const environmentExists = _fs.default.existsSync(instancePath);
|
|
97
102
|
|
|
98
103
|
if (!environmentExists) {
|
|
99
|
-
throw new Error(
|
|
104
|
+
throw new Error(_devEnvironment.DEV_ENVIRONMENT_NOT_FOUND);
|
|
100
105
|
}
|
|
101
106
|
|
|
102
107
|
await (0, _devEnvironmentLando.landoStop)(instancePath);
|
|
@@ -104,7 +109,7 @@ async function stopEnvironment(slug) {
|
|
|
104
109
|
|
|
105
110
|
async function createEnvironment(instanceData) {
|
|
106
111
|
const slug = instanceData.siteSlug;
|
|
107
|
-
debug('Will
|
|
112
|
+
debug('Will create an environment', slug, 'with instanceData: ', instanceData);
|
|
108
113
|
const instancePath = getEnvironmentPath(slug);
|
|
109
114
|
debug('Instance path for', slug, 'is:', instancePath);
|
|
110
115
|
|
|
@@ -114,12 +119,36 @@ async function createEnvironment(instanceData) {
|
|
|
114
119
|
throw new Error('Environment already exists.');
|
|
115
120
|
}
|
|
116
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
|
+
|
|
117
146
|
if (instanceData.mediaRedirectDomain && !instanceData.mediaRedirectDomain.match(/^http/)) {
|
|
118
147
|
// We need to make sure the redirect is an absolute path
|
|
119
|
-
|
|
148
|
+
newInstanceData.mediaRedirectDomain = `https://${instanceData.mediaRedirectDomain}`;
|
|
120
149
|
}
|
|
121
150
|
|
|
122
|
-
|
|
151
|
+
return newInstanceData;
|
|
123
152
|
}
|
|
124
153
|
|
|
125
154
|
async function destroyEnvironment(slug, removeFiles) {
|
|
@@ -130,7 +159,7 @@ async function destroyEnvironment(slug, removeFiles) {
|
|
|
130
159
|
const environmentExists = _fs.default.existsSync(instancePath);
|
|
131
160
|
|
|
132
161
|
if (!environmentExists) {
|
|
133
|
-
throw new Error(
|
|
162
|
+
throw new Error(_devEnvironment.DEV_ENVIRONMENT_NOT_FOUND);
|
|
134
163
|
}
|
|
135
164
|
|
|
136
165
|
const landoFilePath = _path.default.join(instancePath, landoFileName);
|
|
@@ -169,7 +198,7 @@ async function printEnvironmentInfo(slug) {
|
|
|
169
198
|
const environmentExists = _fs.default.existsSync(instancePath);
|
|
170
199
|
|
|
171
200
|
if (!environmentExists) {
|
|
172
|
-
throw new Error(
|
|
201
|
+
throw new Error(_devEnvironment.DEV_ENVIRONMENT_NOT_FOUND);
|
|
173
202
|
}
|
|
174
203
|
|
|
175
204
|
const appInfo = await (0, _devEnvironmentLando.landoInfo)(instancePath);
|
|
@@ -184,7 +213,7 @@ async function exec(slug, args) {
|
|
|
184
213
|
const environmentExists = _fs.default.existsSync(instancePath);
|
|
185
214
|
|
|
186
215
|
if (!environmentExists) {
|
|
187
|
-
throw new Error(
|
|
216
|
+
throw new Error(_devEnvironment.DEV_ENVIRONMENT_NOT_FOUND);
|
|
188
217
|
}
|
|
189
218
|
|
|
190
219
|
const command = args.shift();
|
|
@@ -204,9 +233,21 @@ function doesEnvironmentExist(slug) {
|
|
|
204
233
|
return _fs.default.existsSync(instancePath);
|
|
205
234
|
}
|
|
206
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
|
+
|
|
207
247
|
async function prepareLandoEnv(instanceData, instancePath) {
|
|
208
248
|
const landoFile = await _ejs.default.renderFile(landoFileTemplatePath, instanceData);
|
|
209
249
|
const nginxFile = await _ejs.default.renderFile(nginxFileTemplatePath, instanceData);
|
|
250
|
+
const instanceDataFile = JSON.stringify(instanceData);
|
|
210
251
|
|
|
211
252
|
const landoFileTargetPath = _path.default.join(instancePath, landoFileName);
|
|
212
253
|
|
|
@@ -214,6 +255,8 @@ async function prepareLandoEnv(instanceData, instancePath) {
|
|
|
214
255
|
|
|
215
256
|
const nginxFileTargetPath = _path.default.join(nginxFolderPath, nginxFileName);
|
|
216
257
|
|
|
258
|
+
const instanceDataTargetPath = _path.default.join(instancePath, instanceDataFileName);
|
|
259
|
+
|
|
217
260
|
_fs.default.mkdirSync(instancePath, {
|
|
218
261
|
recursive: true
|
|
219
262
|
});
|
|
@@ -226,8 +269,11 @@ async function prepareLandoEnv(instanceData, instancePath) {
|
|
|
226
269
|
|
|
227
270
|
_fs.default.writeFileSync(nginxFileTargetPath, nginxFile);
|
|
228
271
|
|
|
272
|
+
_fs.default.writeFileSync(instanceDataTargetPath, instanceDataFile);
|
|
273
|
+
|
|
229
274
|
debug(`Lando file created in ${landoFileTargetPath}`);
|
|
230
275
|
debug(`Nginx file created in ${nginxFileTargetPath}`);
|
|
276
|
+
debug(`Instance data file created in ${instanceDataTargetPath}`);
|
|
231
277
|
}
|
|
232
278
|
|
|
233
279
|
function getAllEnvironmentNames() {
|
|
@@ -42,14 +42,16 @@ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { de
|
|
|
42
42
|
/**
|
|
43
43
|
* This file will hold all the interactions with lando library
|
|
44
44
|
*/
|
|
45
|
-
const
|
|
45
|
+
const DEBUG_KEY = '@automattic/vip:bin:dev-environment-lando';
|
|
46
|
+
const debug = (0, _debug.default)(DEBUG_KEY);
|
|
46
47
|
|
|
47
48
|
function getLandoConfig() {
|
|
48
49
|
const landoPath = _path.default.join(__dirname, '..', '..', '..', 'node_modules', 'lando');
|
|
49
50
|
|
|
50
51
|
debug(`Getting lando config, using path '${landoPath}' for plugins`);
|
|
52
|
+
const logLevelConsole = (process.env.DEBUG || '').includes(DEBUG_KEY) ? 'debug' : 'warn';
|
|
51
53
|
return {
|
|
52
|
-
logLevelConsole
|
|
54
|
+
logLevelConsole,
|
|
53
55
|
landoFile: '.lando.yml',
|
|
54
56
|
preLandoFiles: ['.lando.base.yml', '.lando.dist.yml', '.lando.upstream.yml'],
|
|
55
57
|
postLandoFiles: ['.lando.local.yml'],
|
|
@@ -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 =
|
|
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;
|
|
@@ -345,7 +345,7 @@ ${maybeExitPrompt}
|
|
|
345
345
|
|
|
346
346
|
let failedImportStep;
|
|
347
347
|
|
|
348
|
-
if (jobCreationTime && (importStepProgress === null || importStepProgress === void 0 ? void 0 : importStepProgress.started_at) * 1000
|
|
348
|
+
if (jobCreationTime && (importStepProgress === null || importStepProgress === void 0 ? void 0 : importStepProgress.started_at) * 1000 >= jobCreationTime) {
|
|
349
349
|
// The contents of the `import_progress` meta are pertinent to the most recent import job
|
|
350
350
|
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
351
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@automattic/vip",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.7.0-dev2",
|
|
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": "
|
|
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#
|
|
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": "
|
|
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
|
|
120
|
+
"lando": "git+https://github.com/Automattic/lando-cli.git#v3.5.1-patch2021_11_22",
|
|
119
121
|
"node-fetch": "^2.6.1",
|
|
120
122
|
"opn": "5.5.0",
|
|
121
123
|
"rollbar": "2.22.0",
|