@automattic/vip 4.0.1 → 4.0.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/dist/bin/vip-dev-env-sync-sql.js +1 -1
- package/dist/bin/vip-export-sql.js +1 -1
- package/dist/bin/vip-logs.js +1 -1
- package/dist/bin/vip-slowlogs.js +2 -1
- package/dist/lib/cli/command.js +125 -8
- package/npm-shrinkwrap.json +372 -360
- package/package.json +3 -3
|
@@ -51,7 +51,7 @@ const appQuery = `
|
|
|
51
51
|
requiredArgs: 0,
|
|
52
52
|
module: 'dev-env-sync-sql',
|
|
53
53
|
usage
|
|
54
|
-
}).option('slug', 'A unique name for a local environment. Default is "vip-local".', undefined, _devEnvironmentCli.processSlug).option('table', 'The name of a table to include in the partial database sync. Accepts a string value and can be passed more than once with a different value, or add multiple values in a comma-separated list.').option('site-id', 'The ID of a network site to include in the partial database sync. Accepts an integer value (can be passed more than once with different values), or multiple integer values in a comma-separated list.').option('wpcli-command', 'Run a custom WP-CLI command that has logic to retrieve specific data for the partial database export.').option('config-file', 'A local configuration file that specifies the data to include in the partial database sync. Accepts a relative or absolute path to the file.', undefined).option('force', 'Skip validations.', undefined, _devEnvironmentCli.processBooleanOption).examples(examples).argv(process.argv, async (arg, opt) => {
|
|
54
|
+
}).option('slug', 'A unique name for a local environment. Default is "vip-local".', undefined, _devEnvironmentCli.processSlug).option('table', 'The name of a table to include in the partial database sync. Accepts a string value and can be passed more than once with a different value, or add multiple values in a comma-separated list.').option('site-id', 'The ID of a network site to include in the partial database sync. Accepts an integer value (can be passed more than once with different values), or multiple integer values in a comma-separated list.', undefined, Number.parseInt).option('wpcli-command', 'Run a custom WP-CLI command that has logic to retrieve specific data for the partial database export.').option('config-file', 'A local configuration file that specifies the data to include in the partial database sync. Accepts a relative or absolute path to the file.', undefined).option('force', 'Skip validations.', undefined, _devEnvironmentCli.processBooleanOption).examples(examples).argv(process.argv, async (arg, opt) => {
|
|
55
55
|
const {
|
|
56
56
|
app,
|
|
57
57
|
env,
|
|
@@ -55,7 +55,7 @@ const appQuery = `
|
|
|
55
55
|
module: 'export-sql',
|
|
56
56
|
requiredArgs: 0,
|
|
57
57
|
usage: 'vip export sql'
|
|
58
|
-
}).option('output', 'Download the file to a specific local directory path with a custom file name.').option('table', 'The name of a table to include in the partial database export. Accepts a string value and can be passed more than once with a different value, or add multiple values in a comma-separated list.').option('site-id', 'The ID of a network site to include in the partial database export. Accepts an integer value and can be passed more than once with a different value, or add multiple values in a comma-separated list.').option('wpcli-command', 'Run a custom WP-CLI command that has logic to retrieve specific data for the partial database export.').option('config-file', 'A local configuration file that specifies the data to include in the partial database export. Accepts a relative or absolute path to the file.', undefined).option('generate-backup', 'Generate a fresh database backup and export an archived copy of that backup.').option('skip-download', 'Skip downloading the file.').examples(examples).argv(process.argv, async (arg, {
|
|
58
|
+
}).option('output', 'Download the file to a specific local directory path with a custom file name.').option('table', 'The name of a table to include in the partial database export. Accepts a string value and can be passed more than once with a different value, or add multiple values in a comma-separated list.').option('site-id', 'The ID of a network site to include in the partial database export. Accepts an integer value and can be passed more than once with a different value, or add multiple values in a comma-separated list.', undefined, Number.parseInt).option('wpcli-command', 'Run a custom WP-CLI command that has logic to retrieve specific data for the partial database export.').option('config-file', 'A local configuration file that specifies the data to include in the partial database export. Accepts a relative or absolute path to the file.', undefined).option('generate-backup', 'Generate a fresh database backup and export an archived copy of that backup.').option('skip-download', 'Skip downloading the file.').examples(examples).argv(process.argv, async (arg, {
|
|
59
59
|
app,
|
|
60
60
|
env,
|
|
61
61
|
output,
|
package/dist/bin/vip-logs.js
CHANGED
|
@@ -218,7 +218,7 @@ const appQuery = exports.appQuery = `
|
|
|
218
218
|
module: 'logs'
|
|
219
219
|
}).option('type', 'Specify the type of Runtime Logs to retrieve. Accepts "batch" (only valid for WordPress environments).', 'app')
|
|
220
220
|
// The default limit is set manually in the validateInputs function to address validation issues, avoiding incorrect replacement of the default value.
|
|
221
|
-
.option('limit', `The maximum number of entries to return. Accepts an integer value between 1 and 5000 (defaults to ${LIMIT_DEFAULT})
|
|
221
|
+
.option('limit', `The maximum number of entries to return. Accepts an integer value between 1 and 5000 (defaults to ${LIMIT_DEFAULT}).`, undefined, Number.parseInt).option('follow', 'Output new entries as they are generated.').option('format', 'Render output in a particular format. Accepts “table“ (default), “csv“, “json“, and “text”.').examples([{
|
|
222
222
|
usage: 'vip @example-app.production logs',
|
|
223
223
|
description: 'Retrieve up to 500 of the most recent entries of application Runtime Logs from web containers.'
|
|
224
224
|
}, {
|
package/dist/bin/vip-slowlogs.js
CHANGED
|
@@ -163,6 +163,7 @@ const appQuery = exports.appQuery = `
|
|
|
163
163
|
name
|
|
164
164
|
}
|
|
165
165
|
`;
|
|
166
|
+
const parseLimit = value => Number.parseInt(String(value), 10);
|
|
166
167
|
void (0, _command.default)({
|
|
167
168
|
appContext: true,
|
|
168
169
|
appQuery,
|
|
@@ -170,7 +171,7 @@ void (0, _command.default)({
|
|
|
170
171
|
format: true,
|
|
171
172
|
module: 'slowlogs',
|
|
172
173
|
usage: baseUsage
|
|
173
|
-
}).option('limit', 'Set the maximum number of log entries. Accepts an integer value between 1 and 500.', 500).examples([{
|
|
174
|
+
}).option('limit', 'Set the maximum number of log entries. Accepts an integer value between 1 and 500.', 500, parseLimit).examples([{
|
|
174
175
|
description: 'Retrieve up to 500 of the most recent entries from the MySQL slow query logs in the default format.',
|
|
175
176
|
usage: exampleUsage
|
|
176
177
|
}, {
|
package/dist/lib/cli/command.js
CHANGED
|
@@ -104,7 +104,8 @@ function createOptionDefinition(name, description, defaultValue, parseFn, usedSh
|
|
|
104
104
|
flags,
|
|
105
105
|
description,
|
|
106
106
|
defaultValue,
|
|
107
|
-
parser
|
|
107
|
+
parser,
|
|
108
|
+
normalizedShortName
|
|
108
109
|
};
|
|
109
110
|
}
|
|
110
111
|
function isOptionToken(arg) {
|
|
@@ -118,21 +119,43 @@ class CommanderArgsCompat {
|
|
|
118
119
|
this.sub = [];
|
|
119
120
|
this.examplesList = [];
|
|
120
121
|
this.usedShortNames = new Set();
|
|
122
|
+
this.shortOptionsExpectingValue = new Set();
|
|
123
|
+
this.longOptionsExpectingValue = new Set();
|
|
124
|
+
this.knownShortOptions = new Set();
|
|
125
|
+
this.knownLongOptions = new Set();
|
|
121
126
|
this._opts = opts;
|
|
122
127
|
this.program = new _commander.Command();
|
|
123
128
|
this.program.allowUnknownOption(true);
|
|
124
129
|
this.program.allowExcessArguments(true);
|
|
125
130
|
this.program.helpOption(false);
|
|
126
131
|
normalizeUsage(this.program, this._opts.usage);
|
|
132
|
+
this.optionDefaults = new Map();
|
|
127
133
|
}
|
|
128
134
|
option(name, description, defaultValue, parseFn) {
|
|
129
135
|
const definition = createOptionDefinition(name, description, defaultValue, parseFn, this.usedShortNames);
|
|
130
136
|
const {
|
|
131
137
|
flags,
|
|
132
|
-
parser
|
|
138
|
+
parser,
|
|
139
|
+
normalizedShortName
|
|
133
140
|
} = definition;
|
|
141
|
+
const normalizedLongName = String(Array.isArray(name) ? name[1] : name).trim().replace(/^--?/, '');
|
|
142
|
+
const isValueOption = typeof defaultValue !== 'boolean';
|
|
143
|
+
this.knownLongOptions.add(normalizedLongName);
|
|
144
|
+
if (normalizedShortName) {
|
|
145
|
+
this.knownShortOptions.add(normalizedShortName);
|
|
146
|
+
}
|
|
147
|
+
if (isValueOption && normalizedShortName) {
|
|
148
|
+
this.shortOptionsExpectingValue.add(normalizedShortName);
|
|
149
|
+
}
|
|
150
|
+
if (isValueOption) {
|
|
151
|
+
this.longOptionsExpectingValue.add(normalizedLongName);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
// When there's a parser, track the default separately and don't pass it to Commander.
|
|
155
|
+
// This prevents the parser from incorrectly accumulating the default value with the first explicit value.
|
|
134
156
|
if (parser && defaultValue !== undefined) {
|
|
135
|
-
this.
|
|
157
|
+
this.optionDefaults.set(normalizedLongName, defaultValue);
|
|
158
|
+
this.program.option(flags, description, parser);
|
|
136
159
|
} else if (parser) {
|
|
137
160
|
this.program.option(flags, description, parser);
|
|
138
161
|
} else if (defaultValue !== undefined) {
|
|
@@ -194,16 +217,43 @@ class CommanderArgsCompat {
|
|
|
194
217
|
return this.details.commands.some(entry => entry.usage === value);
|
|
195
218
|
}
|
|
196
219
|
parse(argv) {
|
|
197
|
-
this.program.parse(argv, {
|
|
220
|
+
this.program.parse(this.normalizeShortOptionEqualsSyntax(argv), {
|
|
198
221
|
from: 'node'
|
|
199
222
|
});
|
|
200
223
|
this.sub = this.program.args.slice();
|
|
201
|
-
|
|
224
|
+
const opts = this.program.opts();
|
|
225
|
+
|
|
226
|
+
// Apply tracked defaults for options with parsers
|
|
227
|
+
for (const [optionName, defaultValue] of this.optionDefaults) {
|
|
228
|
+
if (opts[optionName] === undefined) {
|
|
229
|
+
opts[optionName] = defaultValue;
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
return opts;
|
|
233
|
+
}
|
|
234
|
+
normalizeShortOptionEqualsSyntax(argv) {
|
|
235
|
+
const normalizedArgv = argv.slice(0, 2);
|
|
236
|
+
for (const arg of argv.slice(2)) {
|
|
237
|
+
const shortOptionEqualsMatch = /^-([A-Za-z0-9])=(.*)$/.exec(arg);
|
|
238
|
+
if (!shortOptionEqualsMatch) {
|
|
239
|
+
normalizedArgv.push(arg);
|
|
240
|
+
continue;
|
|
241
|
+
}
|
|
242
|
+
const shortOptionName = shortOptionEqualsMatch[1];
|
|
243
|
+
const optionValue = shortOptionEqualsMatch[2];
|
|
244
|
+
if (!this.shortOptionsExpectingValue.has(shortOptionName)) {
|
|
245
|
+
normalizedArgv.push(arg);
|
|
246
|
+
continue;
|
|
247
|
+
}
|
|
248
|
+
normalizedArgv.push(`-${shortOptionName}`, optionValue);
|
|
249
|
+
}
|
|
250
|
+
return normalizedArgv;
|
|
202
251
|
}
|
|
203
252
|
findSubcommand(argv) {
|
|
204
|
-
const
|
|
253
|
+
const searchStart = argv[2] === '--' ? 3 : 2;
|
|
254
|
+
const dashDashIndex = argv.indexOf('--', searchStart);
|
|
205
255
|
const searchEnd = dashDashIndex === -1 ? argv.length : dashDashIndex;
|
|
206
|
-
for (let index =
|
|
256
|
+
for (let index = searchStart; index < searchEnd; index++) {
|
|
207
257
|
const arg = argv[index];
|
|
208
258
|
if (this.isDefined(arg, 'commands')) {
|
|
209
259
|
return {
|
|
@@ -221,6 +271,56 @@ class CommanderArgsCompat {
|
|
|
221
271
|
index++;
|
|
222
272
|
}
|
|
223
273
|
}
|
|
274
|
+
if (dashDashIndex > -1 && this.isDefined(argv[dashDashIndex + 1], 'commands')) {
|
|
275
|
+
return {
|
|
276
|
+
index: dashDashIndex + 1,
|
|
277
|
+
name: argv[dashDashIndex + 1]
|
|
278
|
+
};
|
|
279
|
+
}
|
|
280
|
+
return null;
|
|
281
|
+
}
|
|
282
|
+
findUnknownOption(argv) {
|
|
283
|
+
const dashDashIndex = argv.indexOf('--', 2);
|
|
284
|
+
const searchEnd = dashDashIndex === -1 ? argv.length : dashDashIndex;
|
|
285
|
+
for (let index = 2; index < searchEnd; index++) {
|
|
286
|
+
const arg = argv[index];
|
|
287
|
+
if (!isOptionToken(arg)) {
|
|
288
|
+
continue;
|
|
289
|
+
}
|
|
290
|
+
if (arg.startsWith('--')) {
|
|
291
|
+
const [tokenName] = arg.slice(2).split('=');
|
|
292
|
+
if (!this.knownLongOptions.has(tokenName)) {
|
|
293
|
+
return tokenName;
|
|
294
|
+
}
|
|
295
|
+
const hasInlineValue = arg.includes('=');
|
|
296
|
+
const nextArg = argv[index + 1];
|
|
297
|
+
if (this.longOptionsExpectingValue.has(tokenName) && !hasInlineValue && nextArg && !isOptionToken(nextArg)) {
|
|
298
|
+
index++;
|
|
299
|
+
}
|
|
300
|
+
continue;
|
|
301
|
+
}
|
|
302
|
+
const shortEqualsMatch = /^-([A-Za-z0-9])=(.*)$/.exec(arg);
|
|
303
|
+
if (shortEqualsMatch) {
|
|
304
|
+
const shortName = shortEqualsMatch[1];
|
|
305
|
+
if (!this.knownShortOptions.has(shortName)) {
|
|
306
|
+
return shortName;
|
|
307
|
+
}
|
|
308
|
+
continue;
|
|
309
|
+
}
|
|
310
|
+
const shortMatch = /^-([A-Za-z0-9])$/.exec(arg);
|
|
311
|
+
if (shortMatch) {
|
|
312
|
+
const shortName = shortMatch[1];
|
|
313
|
+
if (!this.knownShortOptions.has(shortName)) {
|
|
314
|
+
return shortName;
|
|
315
|
+
}
|
|
316
|
+
const nextArg = argv[index + 1];
|
|
317
|
+
if (this.shortOptionsExpectingValue.has(shortName) && nextArg && !isOptionToken(nextArg)) {
|
|
318
|
+
index++;
|
|
319
|
+
}
|
|
320
|
+
continue;
|
|
321
|
+
}
|
|
322
|
+
return arg.replace(/^-+/, '');
|
|
323
|
+
}
|
|
224
324
|
return null;
|
|
225
325
|
}
|
|
226
326
|
async executeSubcommand(argv, parsedAlias, subcommand) {
|
|
@@ -230,7 +330,15 @@ class CommanderArgsCompat {
|
|
|
230
330
|
const baseScriptPath = extension ? currentScript.slice(0, -extension.length) : currentScript;
|
|
231
331
|
const childScriptPath = extension ? `${baseScriptPath}-${subcommandName}${extension}` : `${baseScriptPath}-${subcommandName}`;
|
|
232
332
|
const aliasFromRawArgv = argv.slice(2).find(arg => (0, _envAlias.isAlias)(arg));
|
|
233
|
-
|
|
333
|
+
const rawArgsBeforeSubcommand = parsedAlias.argv.slice(2, subcommand.index);
|
|
334
|
+
const hasSeparatorBeforeSubcommand = rawArgsBeforeSubcommand.includes('--');
|
|
335
|
+
const argsBeforeSubcommand = rawArgsBeforeSubcommand.filter(arg => arg !== '--');
|
|
336
|
+
const subcommandArgs = parsedAlias.argv.slice(subcommand.index + 1);
|
|
337
|
+
const hasSeparator = argv.includes('--');
|
|
338
|
+
if (subcommandName === 'wp' && subcommandArgs.length && !hasSeparator) {
|
|
339
|
+
exit.withError('A double dash ("--") must separate the arguments of "vip" from those of "wp". Run "vip wp --help" for examples.');
|
|
340
|
+
}
|
|
341
|
+
let childArgs = [...argsBeforeSubcommand, ...(hasSeparatorBeforeSubcommand ? ['--'] : []), ...subcommandArgs];
|
|
234
342
|
if (aliasFromRawArgv) {
|
|
235
343
|
childArgs = [aliasFromRawArgv, ...childArgs];
|
|
236
344
|
}
|
|
@@ -285,6 +393,15 @@ CommanderArgsCompat.prototype.argv = async function (argv, cb) {
|
|
|
285
393
|
await this.executeSubcommand(argv, parsedAlias, dispatchSubcommand);
|
|
286
394
|
return {};
|
|
287
395
|
}
|
|
396
|
+
if (!_opts.wildcardCommand) {
|
|
397
|
+
const unknownOption = this.findUnknownOption(parsedAlias.argv);
|
|
398
|
+
if (unknownOption) {
|
|
399
|
+
await (0, _tracker.trackEvent)('command_validation_error', {
|
|
400
|
+
error: `Unknown option: ${unknownOption}`
|
|
401
|
+
});
|
|
402
|
+
exit.withError(`The option "${unknownOption}" is unknown. Did you mean the following one?\n-h, --help Retrieve a description, examples, and available options for a (sub)command.`);
|
|
403
|
+
}
|
|
404
|
+
}
|
|
288
405
|
if (_opts.format && !options.format) {
|
|
289
406
|
options.format = 'table';
|
|
290
407
|
}
|