forked from nodejs/node
-
Notifications
You must be signed in to change notification settings - Fork 0
/
print_help.js
151 lines (129 loc) · 4.89 KB
/
print_help.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
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
'use strict';
const { internalBinding } = require('internal/bootstrap/loaders');
const { getOptions, types } = internalBinding('options');
const typeLookup = [];
for (const key of Object.keys(types))
typeLookup[types[key]] = key;
// Environment variables are parsed ad-hoc throughout the code base,
// so we gather the documentation here.
const { hasIntl, hasSmallICU, hasNodeOptions } = process.binding('config');
const envVars = new Map([
['NODE_DEBUG', { helpText: "','-separated list of core modules that " +
'should print debug information' }],
['NODE_DEBUG_NATIVE', { helpText: "','-separated list of C++ core debug " +
'categories that should print debug output' }],
['NODE_DISABLE_COLORS', { helpText: 'set to 1 to disable colors in ' +
'the REPL' }],
['NODE_EXTRA_CA_CERTS', { helpText: 'path to additional CA certificates ' +
'file' }],
['NODE_NO_WARNINGS', { helpText: 'set to 1 to silence process warnings' }],
['NODE_PATH', { helpText: `'${require('path').delimiter}'-separated list ` +
'of directories prefixed to the module search path' }],
['NODE_PENDING_DEPRECATION', { helpText: 'set to 1 to emit pending ' +
'deprecation warnings' }],
['NODE_PRESERVE_SYMLINKS', { helpText: 'set to 1 to preserve symbolic ' +
'links when resolving and caching modules' }],
['NODE_REDIRECT_WARNINGS', { helpText: 'write warnings to path instead ' +
'of stderr' }],
['NODE_REPL_HISTORY', { helpText: 'path to the persistent REPL ' +
'history file' }],
['OPENSSL_CONF', { helpText: 'load OpenSSL configuration from file' }]
].concat(hasIntl ? [
['NODE_ICU_DATA', { helpText: 'data path for ICU (Intl object) data' +
hasSmallICU ? '' : ' (will extend linked-in data)' }]
] : []).concat(hasNodeOptions ? [
['NODE_OPTIONS', { helpText: 'set CLI options in the environment via a ' +
'space-separated list' }]
] : []));
function indent(text, depth) {
return text.replace(/^/gm, ' '.repeat(depth));
}
function fold(text, width) {
return text.replace(new RegExp(`([^\n]{0,${width}})( |$)`, 'g'),
(_, newLine, end) => newLine + (end === ' ' ? '\n' : ''));
}
function getArgDescription(type) {
switch (typeLookup[type]) {
case 'kNoOp':
case 'kV8Option':
case 'kBoolean':
break;
case 'kHostPort':
return '[host:]port';
case 'kInteger':
case 'kString':
case 'kStringList':
return '...';
case undefined:
break;
default:
require('assert').fail(`unknown option type ${type}`);
}
}
function format({ options, aliases = new Map(), firstColumn, secondColumn }) {
let text = '';
for (const [
name, { helpText, type, value }
] of [...options.entries()].sort()) {
if (!helpText) continue;
let displayName = name;
const argDescription = getArgDescription(type);
if (argDescription)
displayName += `=${argDescription}`;
for (const [ from, to ] of aliases) {
// For cases like e.g. `-e, --eval`.
if (to[0] === name && to.length === 1) {
displayName = `${from}, ${displayName}`;
}
// For cases like `--inspect-brk[=[host:]port]`.
const targetInfo = options.get(to[0]);
const targetArgDescription =
targetInfo ? getArgDescription(targetInfo.type) : '...';
if (from === `${name}=`) {
displayName += `[=${targetArgDescription}]`;
} else if (from === `${name} <arg>`) {
displayName += ` [${targetArgDescription}]`;
}
}
let displayHelpText = helpText;
if (value === true) {
// Mark boolean options we currently have enabled.
// In particular, it indicates whether --use-openssl-ca
// or --use-bundled-ca is the (current) default.
displayHelpText += ' (currently set)';
}
text += displayName;
if (displayName.length >= firstColumn)
text += '\n' + ' '.repeat(firstColumn);
else
text += ' '.repeat(firstColumn - displayName.length);
text += indent(fold(displayHelpText, secondColumn),
firstColumn).trimLeft() + '\n';
}
return text;
}
function print(stream) {
const { options, aliases } = getOptions();
// TODO(addaleax): Allow a bit of expansion depending on `stream.columns`
// if it is set.
const firstColumn = 28;
const secondColumn = 40;
options.set('-', { helpText: 'script read from stdin (default; ' +
'interactive mode if a tty)' });
options.set('--', { helpText: 'indicate the end of node options' });
stream.write(
'Usage: node [options] [ -e script | script.js | - ] [arguments]\n' +
' node inspect script.js [arguments]\n\n' +
'Options:\n');
stream.write(indent(format({
options, aliases, firstColumn, secondColumn
}), 2));
stream.write('\nEnvironment variables:\n');
stream.write(format({
options: envVars, firstColumn, secondColumn
}));
stream.write('\nDocumentation can be found at https://nodejs.org/\n');
}
module.exports = {
print
};