@automattic/vip 2.11.0 → 2.11.2
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 +8 -0
- package/config/config.json +2 -2
- package/npm-shrinkwrap.json +1 -1
- package/package/dist/bin/vip-app-list.js +73 -0
- package/package/dist/bin/vip-app.js +76 -0
- package/package/dist/bin/vip-config-envvar-delete.js +97 -0
- package/package/dist/bin/vip-config-envvar-get-all.js +94 -0
- package/package/dist/bin/vip-config-envvar-get.js +79 -0
- package/package/dist/bin/vip-config-envvar-list.js +91 -0
- package/package/dist/bin/vip-config-envvar-set.js +123 -0
- package/package/dist/bin/vip-config-envvar.js +23 -0
- package/package/dist/bin/vip-config.js +20 -0
- package/package/dist/bin/vip-dev-env-create.js +105 -0
- package/package/dist/bin/vip-dev-env-destroy.js +56 -0
- package/package/dist/bin/vip-dev-env-exec.js +67 -0
- package/package/dist/bin/vip-dev-env-import-media.js +51 -0
- package/package/dist/bin/vip-dev-env-import-sql.js +83 -0
- package/package/dist/bin/vip-dev-env-import.js +32 -0
- package/package/dist/bin/vip-dev-env-info.js +61 -0
- package/package/dist/bin/vip-dev-env-list.js +46 -0
- package/package/dist/bin/vip-dev-env-start.js +77 -0
- package/package/dist/bin/vip-dev-env-stop.js +52 -0
- package/package/dist/bin/vip-dev-env-update.js +89 -0
- package/package/dist/bin/vip-dev-env.js +23 -0
- package/package/dist/bin/vip-import-media-abort.js +132 -0
- package/package/dist/bin/vip-import-media-status.js +84 -0
- package/package/dist/bin/vip-import-media.js +168 -0
- package/package/dist/bin/vip-import-sql-status.js +83 -0
- package/package/dist/bin/vip-import-sql.js +580 -0
- package/package/dist/bin/vip-import-validate-files.js +191 -0
- package/package/dist/bin/vip-import-validate-sql.js +34 -0
- package/package/dist/bin/vip-import.js +20 -0
- package/package/dist/bin/vip-logs.js +232 -0
- package/package/dist/bin/vip-search-replace.js +71 -0
- package/package/dist/bin/vip-sync.js +191 -0
- package/package/dist/bin/vip-whoami.js +67 -0
- package/package/dist/bin/vip-wp.js +555 -0
- package/package/dist/bin/vip.js +149 -0
- package/package/dist/lib/analytics/clients/client.js +1 -0
- package/package/dist/lib/analytics/clients/pendo.js +92 -0
- package/package/dist/lib/analytics/clients/stub.js +19 -0
- package/package/dist/lib/analytics/clients/tracks.js +128 -0
- package/package/dist/lib/analytics/index.js +45 -0
- package/package/dist/lib/api/app.js +70 -0
- package/package/dist/lib/api/feature-flags.js +39 -0
- package/package/dist/lib/api/user.js +58 -0
- package/package/dist/lib/api.js +136 -0
- package/package/dist/lib/app-logs/app-logs.js +70 -0
- package/package/dist/lib/cli/apiConfig.js +90 -0
- package/package/dist/lib/cli/command.js +606 -0
- package/package/dist/lib/cli/envAlias.js +60 -0
- package/package/dist/lib/cli/exit.js +33 -0
- package/package/dist/lib/cli/format.js +213 -0
- package/package/dist/lib/cli/pager.js +52 -0
- package/package/dist/lib/cli/progress.js +208 -0
- package/package/dist/lib/cli/prompt.js +37 -0
- package/package/dist/lib/cli/repo.js +77 -0
- package/package/dist/lib/client-file-uploader.js +602 -0
- package/package/dist/lib/constants/dev-environment.js +42 -0
- package/package/dist/lib/constants/file-size.js +14 -0
- package/package/dist/lib/dev-environment/dev-environment-cli.js +508 -0
- package/package/dist/lib/dev-environment/dev-environment-core.js +620 -0
- package/package/dist/lib/dev-environment/dev-environment-lando.js +330 -0
- package/package/dist/lib/dev-environment/types.js +1 -0
- package/package/dist/lib/env.js +36 -0
- package/package/dist/lib/envvar/api-delete.js +56 -0
- package/package/dist/lib/envvar/api-get-all.js +59 -0
- package/package/dist/lib/envvar/api-get.js +24 -0
- package/package/dist/lib/envvar/api-list.js +60 -0
- package/package/dist/lib/envvar/api-set.js +58 -0
- package/package/dist/lib/envvar/api.js +104 -0
- package/package/dist/lib/envvar/input.js +55 -0
- package/package/dist/lib/envvar/logging.js +33 -0
- package/package/dist/lib/envvar/read-file.js +43 -0
- package/package/dist/lib/http/socks-proxy-agent.js +25 -0
- package/package/dist/lib/keychain/browser.js +35 -0
- package/package/dist/lib/keychain/insecure.js +63 -0
- package/package/dist/lib/keychain/keychain.js +1 -0
- package/package/dist/lib/keychain/secure.js +36 -0
- package/package/dist/lib/keychain.js +36 -0
- package/package/dist/lib/media-import/media-file-import.js +34 -0
- package/package/dist/lib/media-import/progress.js +86 -0
- package/package/dist/lib/media-import/status.js +335 -0
- package/package/dist/lib/rollbar.js +35 -0
- package/package/dist/lib/search-and-replace.js +203 -0
- package/package/dist/lib/site-import/db-file-import.js +46 -0
- package/package/dist/lib/site-import/status.js +444 -0
- package/package/dist/lib/token.js +132 -0
- package/package/dist/lib/tracker.js +96 -0
- package/package/dist/lib/validations/is-multi-site-sql-dump.js +59 -0
- package/package/dist/lib/validations/is-multi-site.js +99 -0
- package/package/dist/lib/validations/line-by-line.js +92 -0
- package/package/dist/lib/validations/site-type.js +66 -0
- package/package/dist/lib/validations/sql.js +371 -0
- package/package/dist/lib/vip-import-validate-files.js +548 -0
- package/package/vip.iml +11 -0
- package/package.json +1 -1
- package/vip.iml +11 -0
- package/automattic-vip-2.11.0.tgz +0 -0
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* External dependencies
|
|
5
|
+
*/
|
|
6
|
+
exports.isAlias = function (alias) {
|
|
7
|
+
return /^@[A-Za-z0-9\.\-]+$/.test(alias);
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
exports.parseEnvAlias = function (alias) {
|
|
11
|
+
if (!exports.isAlias(alias)) {
|
|
12
|
+
throw new Error('Invalid environment alias. Aliases are in the format of @app-name or @app-name.environment-name');
|
|
13
|
+
} // Remove the '@'
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
const stripped = alias.substr(1).toLowerCase(); // in JS, .split() with a limit discards the extra ones, so can't use it
|
|
17
|
+
// Also convert to lowercase because mixed case environment names would cause problems
|
|
18
|
+
|
|
19
|
+
const [app, ...rest] = stripped.split('.');
|
|
20
|
+
let env = undefined; // Rejoin the env on '.' (if present), to handle instance names (env.instance-01)
|
|
21
|
+
|
|
22
|
+
if (rest && rest.length) {
|
|
23
|
+
env = rest.join('.');
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
return {
|
|
27
|
+
app,
|
|
28
|
+
env
|
|
29
|
+
};
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
exports.parseEnvAliasFromArgv = function (processArgv) {
|
|
33
|
+
// Clone to not affect original arvg
|
|
34
|
+
const argv = processArgv.slice(0); // If command included a `--` to indicate end of named args, lets only consider aliases
|
|
35
|
+
// _before_ it, so that it can be passed to other commands directly
|
|
36
|
+
|
|
37
|
+
const dashDashIndex = argv.indexOf('--');
|
|
38
|
+
let argsBeforeDashDash = argv;
|
|
39
|
+
|
|
40
|
+
if (dashDashIndex > -1) {
|
|
41
|
+
argsBeforeDashDash = argv.slice(0, dashDashIndex);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const alias = argsBeforeDashDash.find(arg => exports.isAlias(arg));
|
|
45
|
+
|
|
46
|
+
if (!alias) {
|
|
47
|
+
return {
|
|
48
|
+
argv
|
|
49
|
+
};
|
|
50
|
+
} // If we did have an alias, split it up into app/env
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
const parsedAlias = exports.parseEnvAlias(alias); // Splice out the alias
|
|
54
|
+
|
|
55
|
+
argv.splice(argv.indexOf(alias), 1);
|
|
56
|
+
return {
|
|
57
|
+
argv,
|
|
58
|
+
...parsedAlias
|
|
59
|
+
};
|
|
60
|
+
};
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.withError = withError;
|
|
7
|
+
|
|
8
|
+
var _chalk = _interopRequireDefault(require("chalk"));
|
|
9
|
+
|
|
10
|
+
var _env = _interopRequireDefault(require("../env"));
|
|
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
|
+
function withError(message) {
|
|
27
|
+
console.log(`${_chalk.default.red('Error: ')} ${message.toString().replace(/^Error:\s*/, '')}`); // Debug ouput is printed below error output both for information
|
|
28
|
+
// hierarchy and to make it more likely that the user copies it to their
|
|
29
|
+
// clipboard when dragging across output.
|
|
30
|
+
|
|
31
|
+
console.log(`${_chalk.default.yellow('Debug: ')} VIP-CLI v${_env.default.app.version}, Node ${_env.default.node.version}, ${_env.default.os.name} ${_env.default.os.version}`);
|
|
32
|
+
process.exit(1);
|
|
33
|
+
}
|
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.formatData = formatData;
|
|
7
|
+
exports.formatEnvironment = formatEnvironment;
|
|
8
|
+
exports.table = table;
|
|
9
|
+
exports.keyValue = keyValue;
|
|
10
|
+
exports.requoteArgs = requoteArgs;
|
|
11
|
+
exports.capitalize = capitalize;
|
|
12
|
+
exports.getGlyphForStatus = getGlyphForStatus;
|
|
13
|
+
exports.formatSearchReplaceValues = exports.RunningSprite = exports.RUNNING_SPRITE_GLYPHS = void 0;
|
|
14
|
+
|
|
15
|
+
var _chalk = _interopRequireDefault(require("chalk"));
|
|
16
|
+
|
|
17
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
18
|
+
|
|
19
|
+
/** @format */
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* External dependencies
|
|
23
|
+
*/
|
|
24
|
+
function formatData(data, format, opts) {
|
|
25
|
+
if (!data || !data.length) {
|
|
26
|
+
return '';
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
switch (format) {
|
|
30
|
+
case 'ids':
|
|
31
|
+
return ids(data, opts);
|
|
32
|
+
|
|
33
|
+
case 'json':
|
|
34
|
+
return JSON.stringify(data, null, '\t');
|
|
35
|
+
|
|
36
|
+
case 'csv':
|
|
37
|
+
return csv(data, opts);
|
|
38
|
+
|
|
39
|
+
case 'keyValue':
|
|
40
|
+
return keyValue(data, opts);
|
|
41
|
+
|
|
42
|
+
case 'table':
|
|
43
|
+
default:
|
|
44
|
+
return table(data, opts);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function formatEnvironment(environment) {
|
|
49
|
+
if ('production' === environment.toLowerCase()) {
|
|
50
|
+
return _chalk.default.red(environment.toUpperCase());
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
return _chalk.default.blueBright(environment.toLowerCase());
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
function ids(data) {
|
|
57
|
+
const fields = Object.keys(data[0]).map(key => key.toLowerCase());
|
|
58
|
+
|
|
59
|
+
if (0 > fields.indexOf('id')) {
|
|
60
|
+
return 'No ID field found';
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
const id = [];
|
|
64
|
+
data.forEach(datum => id.push(datum.id));
|
|
65
|
+
return id.join(' ');
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
function csv(data) {
|
|
69
|
+
const {
|
|
70
|
+
Parser
|
|
71
|
+
} = require('json2csv');
|
|
72
|
+
|
|
73
|
+
const fields = Object.keys(data[0]);
|
|
74
|
+
const parser = new Parser({
|
|
75
|
+
fields: formatFields(fields)
|
|
76
|
+
});
|
|
77
|
+
return parser.parse(data);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
function table(data) {
|
|
81
|
+
const Table = require('cli-table');
|
|
82
|
+
|
|
83
|
+
const fields = Object.keys(data[0]);
|
|
84
|
+
const dataTable = new Table({
|
|
85
|
+
head: formatFields(fields),
|
|
86
|
+
style: {
|
|
87
|
+
head: ['blueBright']
|
|
88
|
+
}
|
|
89
|
+
});
|
|
90
|
+
data.forEach(datum => {
|
|
91
|
+
const row = [];
|
|
92
|
+
fields.forEach(field => row.push(datum[field]));
|
|
93
|
+
dataTable.push(row);
|
|
94
|
+
});
|
|
95
|
+
return dataTable.toString();
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
function formatFields(fields) {
|
|
99
|
+
return fields.map(field => {
|
|
100
|
+
return field.split(/(?=[A-Z])/).join(' ').toLowerCase();
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
function keyValue(values) {
|
|
105
|
+
const lines = [];
|
|
106
|
+
const pairs = values.length > 0;
|
|
107
|
+
pairs ? lines.push('===================================') : '';
|
|
108
|
+
|
|
109
|
+
for (const {
|
|
110
|
+
key,
|
|
111
|
+
value
|
|
112
|
+
} of values) {
|
|
113
|
+
let formattedValue = value;
|
|
114
|
+
|
|
115
|
+
switch (key.toLowerCase()) {
|
|
116
|
+
case 'environment':
|
|
117
|
+
formattedValue = formatEnvironment(value);
|
|
118
|
+
break;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
lines.push(`+ ${key}: ${formattedValue}`);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
lines.push('===================================');
|
|
125
|
+
return lines.join('\n');
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
function requoteArgs(args) {
|
|
129
|
+
return args.map(arg => {
|
|
130
|
+
if (arg.includes('--') && arg.includes('=') && arg.includes(' ')) {
|
|
131
|
+
return arg.replace(/^--(.*)=(.*)$/, '--$1="$2"');
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
if (arg.includes(' ')) {
|
|
135
|
+
return `"${arg}"`;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
return arg;
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
function capitalize(str) {
|
|
143
|
+
if (typeof str !== 'string' || !str.length) {
|
|
144
|
+
return '';
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
return str[0].toUpperCase() + str.slice(1);
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
const RUNNING_SPRITE_GLYPHS = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'];
|
|
151
|
+
exports.RUNNING_SPRITE_GLYPHS = RUNNING_SPRITE_GLYPHS;
|
|
152
|
+
|
|
153
|
+
class RunningSprite {
|
|
154
|
+
constructor() {
|
|
155
|
+
this.count = 0;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
next() {
|
|
159
|
+
if (++this.count >= RUNNING_SPRITE_GLYPHS.length) {
|
|
160
|
+
this.count = 0;
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
toString() {
|
|
165
|
+
const glyph = RUNNING_SPRITE_GLYPHS[this.count];
|
|
166
|
+
this.next(); // TODO: throttle
|
|
167
|
+
|
|
168
|
+
return glyph;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
exports.RunningSprite = RunningSprite;
|
|
174
|
+
|
|
175
|
+
function getGlyphForStatus(status, runningSprite) {
|
|
176
|
+
switch (status) {
|
|
177
|
+
default:
|
|
178
|
+
return '';
|
|
179
|
+
|
|
180
|
+
case 'pending':
|
|
181
|
+
return '○';
|
|
182
|
+
|
|
183
|
+
case 'running':
|
|
184
|
+
return _chalk.default.blueBright(runningSprite);
|
|
185
|
+
|
|
186
|
+
case 'success':
|
|
187
|
+
return _chalk.default.green('✓');
|
|
188
|
+
|
|
189
|
+
case 'failed':
|
|
190
|
+
return _chalk.default.red('✕');
|
|
191
|
+
|
|
192
|
+
case 'unknown':
|
|
193
|
+
return _chalk.default.yellow('✕');
|
|
194
|
+
|
|
195
|
+
case 'skipped':
|
|
196
|
+
return _chalk.default.green('-');
|
|
197
|
+
}
|
|
198
|
+
} // Format Search and Replace values to output
|
|
199
|
+
|
|
200
|
+
|
|
201
|
+
const formatSearchReplaceValues = (values, message) => {
|
|
202
|
+
// Convert single pair S-R values to arrays
|
|
203
|
+
const searchReplaceValues = typeof values === 'string' ? [values] : values;
|
|
204
|
+
const formattedOutput = searchReplaceValues.map(pairs => {
|
|
205
|
+
// Turn each S-R pair into its own array, then trim away whitespace
|
|
206
|
+
const [from, to] = pairs.split(',').map(pair => pair.trim());
|
|
207
|
+
const output = message(from, to);
|
|
208
|
+
return output;
|
|
209
|
+
});
|
|
210
|
+
return formattedOutput;
|
|
211
|
+
};
|
|
212
|
+
|
|
213
|
+
exports.formatSearchReplaceValues = formatSearchReplaceValues;
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.default = pager;
|
|
7
|
+
exports.end = end;
|
|
8
|
+
|
|
9
|
+
var _child_process = require("child_process");
|
|
10
|
+
|
|
11
|
+
var _stream = require("stream");
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* External dependencies
|
|
15
|
+
*/
|
|
16
|
+
let proc;
|
|
17
|
+
|
|
18
|
+
function pager() {
|
|
19
|
+
let less;
|
|
20
|
+
|
|
21
|
+
switch (process.platform) {
|
|
22
|
+
case 'win32':
|
|
23
|
+
// PROGRA~1 is the short name for Program Files
|
|
24
|
+
// we're using it here to avoid the space which is broken by .split( ' ' )
|
|
25
|
+
less = 'C:\\PROGRA~1\\Git\\usr\\bin\\less.exe -FRX';
|
|
26
|
+
break;
|
|
27
|
+
|
|
28
|
+
default:
|
|
29
|
+
less = 'less -FRX';
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
const args = (process.env.PAGER || less).split(' ');
|
|
33
|
+
const bin = args.shift(); // passthrough pipe so we can change the output pipe if necessary
|
|
34
|
+
|
|
35
|
+
const pipe = new _stream.PassThrough();
|
|
36
|
+
proc = (0, _child_process.spawn)(bin, args, {
|
|
37
|
+
stdio: ['pipe', process.stdout, process.stderr]
|
|
38
|
+
});
|
|
39
|
+
proc.on('exit', () => {
|
|
40
|
+
proc.stdin.emit('done');
|
|
41
|
+
}); // If we can't spawn less, pipe directly to stdout
|
|
42
|
+
|
|
43
|
+
pipe.pipe(proc.stdin);
|
|
44
|
+
proc.on('error', () => {
|
|
45
|
+
pipe.pipe(process.stdout);
|
|
46
|
+
});
|
|
47
|
+
return pipe;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
function end() {
|
|
51
|
+
proc.end();
|
|
52
|
+
}
|
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.ProgressTracker = void 0;
|
|
7
|
+
|
|
8
|
+
var _singleLineLog = require("single-line-log");
|
|
9
|
+
|
|
10
|
+
var _format = require("./format");
|
|
11
|
+
|
|
12
|
+
/** @format */
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* External dependencies
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Internal dependencies
|
|
20
|
+
*/
|
|
21
|
+
const PRINT_INTERVAL = process.env.DEBUG ? 5000 : 200; // How often the report is printed. Mainly affects the "spinner" animation.
|
|
22
|
+
|
|
23
|
+
const COMPLETED_STEP_SLUGS = ['success', 'skipped'];
|
|
24
|
+
|
|
25
|
+
class ProgressTracker {
|
|
26
|
+
// Track the state of each step
|
|
27
|
+
// Spinnerz go brrrr
|
|
28
|
+
// This gets printed before the step status
|
|
29
|
+
// This gets printed after the step status
|
|
30
|
+
constructor(steps) {
|
|
31
|
+
this.runningSprite = new _format.RunningSprite();
|
|
32
|
+
this.hasFailure = false;
|
|
33
|
+
this.stepsFromCaller = this.mapSteps(steps);
|
|
34
|
+
this.stepsFromServer = new Map();
|
|
35
|
+
this.prefix = '';
|
|
36
|
+
this.suffix = '';
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
getSteps() {
|
|
40
|
+
return new Map([...this.stepsFromCaller, ...this.stepsFromServer]);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
mapSteps(steps) {
|
|
44
|
+
return steps.reduce((map, {
|
|
45
|
+
id,
|
|
46
|
+
name,
|
|
47
|
+
status
|
|
48
|
+
}) => {
|
|
49
|
+
map.set(id, {
|
|
50
|
+
id,
|
|
51
|
+
name,
|
|
52
|
+
status: status || 'pending'
|
|
53
|
+
});
|
|
54
|
+
return map;
|
|
55
|
+
}, new Map());
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
setUploadPercentage(percentage) {
|
|
59
|
+
const uploadStep = this.stepsFromCaller.get('upload');
|
|
60
|
+
|
|
61
|
+
if (!uploadStep) {
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
this.stepsFromCaller.set('upload', { ...uploadStep,
|
|
66
|
+
percentage
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
setStepsFromServer(steps) {
|
|
71
|
+
const formattedSteps = steps.map(({
|
|
72
|
+
name,
|
|
73
|
+
status
|
|
74
|
+
}, index) => ({
|
|
75
|
+
id: `server-${index}-${name}`,
|
|
76
|
+
name,
|
|
77
|
+
status
|
|
78
|
+
}));
|
|
79
|
+
|
|
80
|
+
if (!steps.some(({
|
|
81
|
+
status
|
|
82
|
+
}) => status === 'running')) {
|
|
83
|
+
const firstPendingStepIndex = steps.findIndex(({
|
|
84
|
+
status
|
|
85
|
+
}) => status === 'pending');
|
|
86
|
+
|
|
87
|
+
if (firstPendingStepIndex !== -1) {
|
|
88
|
+
// "Promote" the first "pending" to "running"
|
|
89
|
+
formattedSteps[firstPendingStepIndex].status = 'running';
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
this.stepsFromServer = this.mapSteps(formattedSteps);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
getNextStep() {
|
|
97
|
+
if (this.allStepsSucceeded()) {
|
|
98
|
+
return undefined;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
const steps = [...this.getSteps().values()];
|
|
102
|
+
return steps.find(({
|
|
103
|
+
status
|
|
104
|
+
}) => status === 'pending');
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
stepRunning(stepId) {
|
|
108
|
+
this.setStatusForStepId(stepId, 'running');
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
stepFailed(stepId) {
|
|
112
|
+
this.setStatusForStepId(stepId, 'failed');
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
stepSkipped(stepId) {
|
|
116
|
+
this.setStatusForStepId(stepId, 'skipped');
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
stepSuccess(stepId) {
|
|
120
|
+
this.setStatusForStepId(stepId, 'success'); // The stepSuccess helper automatically sets the next step to "running"
|
|
121
|
+
|
|
122
|
+
const nextStep = this.getNextStep();
|
|
123
|
+
|
|
124
|
+
if (nextStep) {
|
|
125
|
+
this.stepRunning(nextStep.id);
|
|
126
|
+
return;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
allStepsSucceeded() {
|
|
131
|
+
return ![...this.getSteps().values()].some(({
|
|
132
|
+
status
|
|
133
|
+
}) => status !== 'success');
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
setStatusForStepId(stepId, status) {
|
|
137
|
+
const step = this.stepsFromCaller.get(stepId);
|
|
138
|
+
|
|
139
|
+
if (!step) {
|
|
140
|
+
// Only allowed to update existing steps with this method
|
|
141
|
+
throw new Error(`Step name ${stepId} is not valid.`);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
if (COMPLETED_STEP_SLUGS.includes(step.status)) {
|
|
145
|
+
throw new Error(`Step name ${stepId} is already completed.`);
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
if (status === 'failed') {
|
|
149
|
+
this.hasFailure = true;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
this.stepsFromCaller.set(stepId, { ...step,
|
|
153
|
+
status
|
|
154
|
+
});
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
startPrinting(prePrintCallback = () => {}) {
|
|
158
|
+
this.printInterval = setInterval(() => {
|
|
159
|
+
prePrintCallback();
|
|
160
|
+
this.print();
|
|
161
|
+
}, PRINT_INTERVAL);
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
stopPrinting() {
|
|
165
|
+
if (this.printInterval) {
|
|
166
|
+
clearInterval(this.printInterval);
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
print({
|
|
171
|
+
clearAfter = false
|
|
172
|
+
} = {}) {
|
|
173
|
+
if (!this.hasPrinted) {
|
|
174
|
+
this.hasPrinted = true;
|
|
175
|
+
|
|
176
|
+
_singleLineLog.stdout.clear();
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
const stepValues = [...this.getSteps().values()];
|
|
180
|
+
const logs = stepValues.reduce((accumulator, {
|
|
181
|
+
name,
|
|
182
|
+
id,
|
|
183
|
+
percentage,
|
|
184
|
+
status
|
|
185
|
+
}) => {
|
|
186
|
+
const statusIcon = (0, _format.getGlyphForStatus)(status, this.runningSprite);
|
|
187
|
+
let suffix = '';
|
|
188
|
+
|
|
189
|
+
if (id === 'upload') {
|
|
190
|
+
if (status === 'running' && percentage) {
|
|
191
|
+
suffix = percentage;
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
return `${accumulator}${statusIcon} ${name} ${suffix}\n`;
|
|
196
|
+
}, ''); // Output the logs
|
|
197
|
+
|
|
198
|
+
(0, _singleLineLog.stdout)(`${this.prefix || ''}${logs}${this.suffix || ''}`);
|
|
199
|
+
|
|
200
|
+
if (clearAfter) {
|
|
201
|
+
// Break out of the "Single log line" buffer
|
|
202
|
+
_singleLineLog.stdout.clear();
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
exports.ProgressTracker = ProgressTracker;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.confirm = confirm;
|
|
7
|
+
|
|
8
|
+
var _enquirer = require("enquirer");
|
|
9
|
+
|
|
10
|
+
var _format = require("./format");
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* External dependencies
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Internal dependencies
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
/* eslint-disable no-duplicate-imports */
|
|
21
|
+
|
|
22
|
+
/* eslint-enable no-duplicate-imports */
|
|
23
|
+
async function confirm(values, message, skipPrompt = false) {
|
|
24
|
+
console.log((0, _format.keyValue)(values));
|
|
25
|
+
|
|
26
|
+
if (!skipPrompt) {
|
|
27
|
+
const answer = await (0, _enquirer.prompt)({
|
|
28
|
+
type: 'confirm',
|
|
29
|
+
name: 'confirm',
|
|
30
|
+
message: message,
|
|
31
|
+
default: false
|
|
32
|
+
});
|
|
33
|
+
return answer.confirm;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
return true;
|
|
37
|
+
}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.default = getRepoFromGitConfig;
|
|
7
|
+
|
|
8
|
+
var _fs = _interopRequireDefault(require("fs"));
|
|
9
|
+
|
|
10
|
+
var _path = _interopRequireDefault(require("path"));
|
|
11
|
+
|
|
12
|
+
var _ini = _interopRequireDefault(require("ini"));
|
|
13
|
+
|
|
14
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* External dependencies
|
|
18
|
+
*/
|
|
19
|
+
async function getRepoFromGitConfig() {
|
|
20
|
+
const file = await find();
|
|
21
|
+
|
|
22
|
+
if (!file.length) {
|
|
23
|
+
return '';
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const config = _ini.default.parse(_fs.default.readFileSync(file, 'utf-8')); // Find the first 'wpcomvip' remote
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
for (const key in config) {
|
|
30
|
+
if ('remote' !== key.substring(0, 6)) {
|
|
31
|
+
continue;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
if (!config[key].url) {
|
|
35
|
+
continue;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
if (0 > config[key].url.indexOf('wpcomvip/')) {
|
|
39
|
+
continue;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
let repo = config[key].url;
|
|
43
|
+
repo = repo.replace(/.git$/, '');
|
|
44
|
+
repo = repo.replace('https://github.com/', '');
|
|
45
|
+
repo = repo.replace('git@github.com:', '');
|
|
46
|
+
return repo;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
async function find(dir) {
|
|
53
|
+
dir = dir || process.cwd();
|
|
54
|
+
const test = dir + '/.git/config';
|
|
55
|
+
|
|
56
|
+
if (await exists(test)) {
|
|
57
|
+
return test;
|
|
58
|
+
} // Bail if we went all the way and didn't find it
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
const directory = _path.default.parse(dir);
|
|
62
|
+
|
|
63
|
+
if (directory.dir === directory.root) {
|
|
64
|
+
return '';
|
|
65
|
+
} // cd ..
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
const up = dir.split(_path.default.sep);
|
|
69
|
+
up.pop();
|
|
70
|
+
return find(up.join(_path.default.sep));
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
async function exists(file) {
|
|
74
|
+
return new Promise(resolve => {
|
|
75
|
+
_fs.default.access(file, _fs.default.constants.F_OK, err => resolve(!err));
|
|
76
|
+
});
|
|
77
|
+
}
|