feat(tally): parse --regex/-r flag and add compileRegex helper

Step 1 of plan.md (Spor B B3 pipeline run). Adds the new --regex / -r
flag to parseArgs and a compileRegex(pattern) helper. The flag is
parsed but main() does not yet branch on it (wired in step 2). All
10 baseline tests remain green.

[skip-docs]
This commit is contained in:
Kjell Tore Guttormsen 2026-05-04 20:31:23 +02:00
commit c4cf49f1d2

View file

@ -21,11 +21,12 @@ function fail(msg, code = 2) {
function parseArgs(argv) { function parseArgs(argv) {
const positional = []; const positional = [];
const flags = { json: false, ignoreCase: false, lines: false }; const flags = { json: false, ignoreCase: false, lines: false, regex: false };
for (const a of argv) { for (const a of argv) {
if (a === '--json') flags.json = true; if (a === '--json') flags.json = true;
else if (a === '-i' || a === '--ignore-case') flags.ignoreCase = true; else if (a === '-i' || a === '--ignore-case') flags.ignoreCase = true;
else if (a === '--lines') flags.lines = true; else if (a === '--lines') flags.lines = true;
else if (a === '--regex' || a === '-r') flags.regex = true;
else if (a === '-h' || a === '--help') { process.stdout.write(HELP); process.exit(0); } else if (a === '-h' || a === '--help') { process.stdout.write(HELP); process.exit(0); }
else if (a.startsWith('-')) fail(`unknown flag: ${a}`); else if (a.startsWith('-')) fail(`unknown flag: ${a}`);
else positional.push(a); else positional.push(a);
@ -34,6 +35,11 @@ function parseArgs(argv) {
return { pattern: positional[0], file: positional[1], flags }; return { pattern: positional[0], file: positional[1], flags };
} }
function compileRegex(pattern) {
try { return new RegExp(pattern, 'g'); }
catch (e) { fail(`invalid regex: ${e.message}`); }
}
function countOccurrences(text, pattern, ignoreCase) { function countOccurrences(text, pattern, ignoreCase) {
if (pattern.length === 0) return 0; if (pattern.length === 0) return 0;
const haystack = ignoreCase ? text.toLowerCase() : text; const haystack = ignoreCase ? text.toLowerCase() : text;