Skip to content

Commit fab13ca

Browse files
committed
update
1 parent b050153 commit fab13ca

File tree

4 files changed

+729
-62
lines changed

4 files changed

+729
-62
lines changed

bin/handlers/npm-handler.ts

Lines changed: 3 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -59,41 +59,12 @@ const npmOptionHandlers: OptionHandlers = {
5959

6060
'install-strategy': listHandler(
6161
['hoisted', 'nested', 'shallow', 'linked'],
62-
(v) =>
63-
(
64-
({
65-
hoisted: 'Hoist all dependencies to top level',
66-
nested: 'Nested node_modules structure',
67-
shallow: 'Shallow dependency installation',
68-
linked: 'Use linked dependencies',
69-
}) as Record<string, string>
70-
)[v] ?? ' '
62+
() => ' '
7163
),
7264

73-
omit: listHandler(
74-
['dev', 'optional', 'peer'],
75-
(v) =>
76-
(
77-
({
78-
dev: 'Omit devDependencies',
79-
optional: 'Omit optionalDependencies',
80-
peer: 'Omit peerDependencies',
81-
}) as Record<string, string>
82-
)[v] ?? ' '
83-
),
65+
omit: listHandler(['dev', 'optional', 'peer'], () => ' '),
8466

85-
include: listHandler(
86-
['prod', 'dev', 'optional', 'peer'],
87-
(v) =>
88-
(
89-
({
90-
prod: 'Include production deps',
91-
dev: 'Include dev deps',
92-
optional: 'Include optional deps',
93-
peer: 'Include peer deps',
94-
}) as Record<string, string>
95-
)[v] ?? ' '
96-
),
67+
include: listHandler(['prod', 'dev', 'optional', 'peer'], () => ' '),
9768
};
9869

9970
export function parseNpmHelp(helpText: string): Record<string, string> {

bin/handlers/pnpm-handler.ts

Lines changed: 74 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,13 @@ import {
2323
const OPTIONS_SECTION_RE = /^\s*Options:/i;
2424
const LEVEL_MATCH_RE = /(?:levels?|options?|values?)[^:]*:\s*([^.]+)/i;
2525
const LINE_SPLIT_RE = /\r?\n/;
26-
const REPORTER_LINE_RE = /^\s*--reporter\s+\w/;
27-
const REPORTER_MATCH_RE = /^\s*--reporter\s+(\w+(?:-\w+)*)\s+(.+)$/;
28-
const SILENT_REPORTER_RE = /-s,\s*--silent,\s*--reporter\s+silent\s+(.+)/;
2926
const COMMA_SPACE_SPLIT_RE = /[,\s]+/;
27+
const OPTION_WITH_VALUE_RE =
28+
/^\s*(?:-\w,?\s*)?--(\w+(?:-\w+)*)\s+(\w+(?:-\w+)*)\s+(.+)$/;
29+
const OPTION_ALIAS_RE =
30+
/^\s*-\w,?\s*--\w+(?:,\s*--(\w+(?:-\w+)*)\s+(\w+(?:-\w+)*))?\s+(.+)$/;
31+
const CONTINUATION_LINE_RE = /^\s{20,}/;
32+
const SECTION_HEADER_RE = /^\s*[A-Z][^:]*:\s*$/;
3033

3134
function toLines(text: string): string[] {
3235
return stripAnsiEscapes(text).split(LINE_SPLIT_RE);
@@ -60,29 +63,74 @@ function extractValidValuesFromHelp(
6063
optionName: string
6164
): Array<{ value: string; desc: string }> {
6265
const lines = toLines(helpText);
66+
const results: Array<{ value: string; desc: string }> = [];
6367

64-
// edge case: reporter often appears as multiple lines
65-
if (optionName === 'reporter') {
66-
const out: Array<{ value: string; desc: string }> = [];
67-
68-
for (const line of lines) {
69-
if (line.includes('--reporter') && REPORTER_LINE_RE.test(line)) {
70-
const match = line.match(REPORTER_MATCH_RE);
71-
if (match) {
72-
const [, value, desc] = match;
73-
out.push({ value, desc: desc.trim() });
68+
for (let i = 0; i < lines.length; i++) {
69+
const line = lines[i];
70+
71+
// Look for options with values in any section
72+
const optionMatch = line.match(OPTION_WITH_VALUE_RE);
73+
if (optionMatch) {
74+
const [, option, value, initialDesc] = optionMatch;
75+
if (option === optionName) {
76+
// capture continuation lines for complete description
77+
let fullDesc = initialDesc.trim();
78+
let j = i + 1;
79+
80+
// Look ahead for continuation lines (indented lines that don't start new options)
81+
while (j < lines.length) {
82+
const nextLine = lines[j];
83+
const isIndented = CONTINUATION_LINE_RE.test(nextLine);
84+
const isNewOption =
85+
OPTION_WITH_VALUE_RE.test(nextLine) ||
86+
OPTION_ALIAS_RE.test(nextLine);
87+
const isEmptyOrSection =
88+
!nextLine.trim() || SECTION_HEADER_RE.test(nextLine);
89+
90+
if (isIndented && !isNewOption && !isEmptyOrSection) {
91+
fullDesc += ' ' + nextLine.trim();
92+
j++;
93+
} else {
94+
break;
95+
}
7496
}
75-
}
7697

77-
const silent = line.match(SILENT_REPORTER_RE);
78-
if (silent && !out.some((r) => r.value === 'silent')) {
79-
out.push({ value: 'silent', desc: silent[1].trim() });
98+
results.push({ value, desc: fullDesc });
8099
}
81100
}
82101

83-
if (out.length) return out;
102+
const aliasMatch = line.match(OPTION_ALIAS_RE);
103+
if (aliasMatch) {
104+
const [, option, value, initialDesc] = aliasMatch;
105+
if (option === optionName && value) {
106+
// capture continuation lines for alias descriptions too
107+
let fullDesc = initialDesc.trim();
108+
let j = i + 1;
109+
110+
while (j < lines.length) {
111+
const nextLine = lines[j];
112+
const isIndented = CONTINUATION_LINE_RE.test(nextLine);
113+
const isNewOption =
114+
OPTION_WITH_VALUE_RE.test(nextLine) ||
115+
OPTION_ALIAS_RE.test(nextLine);
116+
const isEmptyOrSection =
117+
!nextLine.trim() || SECTION_HEADER_RE.test(nextLine);
118+
119+
if (isIndented && !isNewOption && !isEmptyOrSection) {
120+
fullDesc += ' ' + nextLine.trim();
121+
j++;
122+
} else {
123+
break;
124+
}
125+
}
126+
127+
results.push({ value, desc: fullDesc });
128+
}
129+
}
84130
}
85131

132+
if (results.length) return results;
133+
86134
for (let i = 0; i < lines.length; i++) {
87135
const ln = lines[i];
88136
if (ln.includes(`--${optionName}`) || ln.includes(`${optionName}:`)) {
@@ -259,11 +307,14 @@ function loadPnpmOptionsSync(cmd: LazyCommand, command: string): void {
259307
else cmd.option(long, desc, short);
260308
}
261309

262-
// edge case: reporter sometimes doesn’t match standard row pattern
263-
if (output.includes('--reporter') && !cmd.optionsRaw?.get?.('reporter')) {
264-
const handler = pnpmOptionHandlers['reporter'];
265-
if (handler)
266-
cmd.option('reporter', 'Output reporter for pnpm commands', handler);
310+
// Register options found by general algorithm but not in standard parsing
311+
for (const [optionName, handler] of Object.entries(pnpmOptionHandlers)) {
312+
if (!cmd.optionsRaw?.get?.(optionName)) {
313+
const values = extractValidValuesFromHelp(output, optionName);
314+
if (values.length > 0) {
315+
cmd.option(optionName, ' ', handler);
316+
}
317+
}
267318
}
268319
}
269320

bin/utils/shared.ts

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -26,13 +26,6 @@ export const commonOptionHandlers: OptionHandlers = {
2626
workspace(complete) {
2727
const patterns = getWorkspacePatterns();
2828
patterns.forEach((p) => complete(p, `Workspace pattern: ${p}`));
29-
complete('packages/*', 'All packages in packages directory');
30-
complete('apps/*', 'All apps in apps directory');
31-
},
32-
33-
registry(complete) {
34-
complete('https://registry.npmjs.org/', 'Official npm registry');
35-
complete('https://registry.npmmirror.com/', 'npm China mirror');
3629
},
3730
};
3831

0 commit comments

Comments
 (0)