forked from webpack/webpack-cli
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathbootstrap.js
124 lines (113 loc) · 4.5 KB
/
bootstrap.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
const WebpackCLI = require('./webpack-cli');
const { core, commands } = require('./utils/cli-flags');
const cmdArgs = require('command-line-args');
const logger = require('./utils/logger');
const leven = require('leven');
require('./utils/process-log');
process.title = 'webpack-cli';
const isFlagPresent = (args, flag) => args.find(arg => [flag, `--${flag}`].includes(arg));
const isArgCommandName = (arg, cmd) => arg === cmd.name || arg === cmd.alias;
const removeCmdFromArgs = (args, cmd) => args.filter(arg => !isArgCommandName(arg, cmd));
const normalizeFlags = (args, cmd) => {
const slicedArgs = args.slice(2);
return removeCmdFromArgs(slicedArgs, cmd);
};
const isCommandUsed = commands =>
commands.find(cmd => {
return process.argv.includes(cmd.name) || process.argv.includes(cmd.alias);
});
const resolveNegatedArgs = args => {
args._unknown.forEach((arg, idx) => {
if (arg.includes('--') || arg.includes('--no')) {
const argPair = arg.split('=');
const optName = arg.includes('--no') ? argPair[0].slice(5) : argPair[0].slice(2);
let argValue = arg.includes('--no') ? 'false' : argPair[1];
if (argValue === 'false') {
argValue = false;
} else if (argValue === 'true') {
argValue = true;
}
const cliFlag = core.find(opt => opt.name === optName);
if (cliFlag) {
args[cliFlag.group][optName] = argValue;
args._all[optName] = argValue;
args._unknown[idx] = null;
}
}
});
};
async function runCLI(cli, commandIsUsed) {
let args;
const helpFlagExists = isFlagPresent(process.argv, 'help');
const versionFlagExists = isFlagPresent(process.argv, 'version');
if (helpFlagExists) {
cli.runHelp(process.argv);
return;
} else if (versionFlagExists) {
cli.runVersion();
return;
}
if (commandIsUsed) {
commandIsUsed.defaultOption = true;
args = normalizeFlags(process.argv, commandIsUsed);
return await cli.runCommand(commandIsUsed, ...args);
} else {
try {
args = cmdArgs(core, { stopAtFirstUnknown: false, partial: true });
if (args._unknown) {
resolveNegatedArgs(args);
args._unknown
.filter(e => e)
.forEach(unknown => {
logger.warn('Unknown argument:', unknown);
});
const unknownOption = args._unknown[0].replace(/-/g, '');
const suggestion = core.find(option => {
return leven(option.name, unknownOption) < 3;
});
if (suggestion) {
logger.info(`Did you mean --${suggestion.name}?`);
return;
}
}
const result = await cli.run(args, core);
if (!result) {
return;
}
} catch (err) {
if (err.name === 'UNKNOWN_VALUE') {
logger.error(`Parse Error (unknown argument): ${err.value}`);
return;
} else if (err.name === 'ALREADY_SET') {
const argsMap = {};
const keysToDelete = [];
process.argv.forEach((arg, idx) => {
const oldMapValue = argsMap[arg];
argsMap[arg] = {
value: process.argv[idx],
pos: idx,
};
// Swap idx of overriden value
if (oldMapValue) {
argsMap[arg].pos = oldMapValue.pos;
keysToDelete.push(idx + 1);
}
});
// Filter out the value for the overriden key
const newArgKeys = Object.keys(argsMap).filter(arg => !keysToDelete.includes(argsMap[arg].pos));
// eslint-disable-next-line require-atomic-updates
process.argv = newArgKeys;
args = cmdArgs(core, { stopAtFirstUnknown: false, partial: true });
await cli.run(args, core);
process.stdout.write('\n');
logger.warn('Duplicate flags found, defaulting to last set value');
} else {
logger.error(err);
return;
}
}
}
}
const commandIsUsed = isCommandUsed(commands);
const cli = new WebpackCLI();
runCLI(cli, commandIsUsed);