From 44d7f339f5c6ffe493476fc45dfb2c664c5f4f40 Mon Sep 17 00:00:00 2001 From: Kjell Tore Guttormsen Date: Mon, 4 May 2026 20:32:06 +0200 Subject: [PATCH] feat(tally): wire regex counting path in main with invalid-regex exit-2 Step 2 of plan.md (Spor B B3 pipeline run). Wires the --regex/-r flag into main(): when set, compileRegex(pattern) is used and the count is text.match(re).length. Invalid regex exits 2 via the existing fail() helper. JSON output now includes flags.regex so consumers can tell the mode apart. Baseline tests remain green; -i/--ignore-case has no effect when --regex is set (out of brief scope). Verify covered: SC #1 (any position), SC #2 (-r short form), SC #3 (regex semantics differ), SC #4 (invalid exits 2), SC #5 (JSON regex), SC #6 (byte-identical baseline). [skip-docs] --- .../ultraplan-local/examples/02-real-cli/tally.mjs | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/plugins/ultraplan-local/examples/02-real-cli/tally.mjs b/plugins/ultraplan-local/examples/02-real-cli/tally.mjs index f63719a..8192829 100755 --- a/plugins/ultraplan-local/examples/02-real-cli/tally.mjs +++ b/plugins/ultraplan-local/examples/02-real-cli/tally.mjs @@ -70,13 +70,19 @@ function main() { process.stderr.write(`tally: ${what}: ${file}\n`); process.exit(1); } - const count = flags.lines - ? countLines(text, pattern, flags.ignoreCase) - : countOccurrences(text, pattern, flags.ignoreCase); + let count; + if (flags.regex) { + const re = compileRegex(pattern); + count = (text.match(re) || []).length; + } else if (flags.lines) { + count = countLines(text, pattern, flags.ignoreCase); + } else { + count = countOccurrences(text, pattern, flags.ignoreCase); + } if (flags.json) { process.stdout.write(JSON.stringify({ pattern, file, count, - flags: { json: flags.json, ignoreCase: flags.ignoreCase, lines: flags.lines }, + flags: { json: flags.json, ignoreCase: flags.ignoreCase, lines: flags.lines, regex: flags.regex }, }) + '\n'); } else { process.stdout.write(count + '\n');