Skip to content

engine: wire -regex captures into gated -exec {0}..{N} - #54

Merged
helly25 merged 1 commit into
mainfrom
feat/exec-captures-wire
Jun 21, 2026
Merged

engine: wire -regex captures into gated -exec {0}..{N}#54
helly25 merged 1 commit into
mainfrom
feat/exec-captures-wire

Conversation

@helly25

@helly25 helly25 commented Jun 21, 2026

Copy link
Copy Markdown
Owner

Summary

Completes capture-aware -exec (#50). A -regex/-iregex match now records its capture groups, and a gated -exec substitutes them as {0}..{N}:

xff --exec-fields . -regex '.*/(.*)\.(.*)' -exec mv {} {1}.bak.{2} \;
  • EvalContext gains a per-entry captures store.
  • MatchesRegex fills it on a match (via FullMatchCaptures): {0} whole match, {1}..{N} the groups.
  • The gated -exec passes ctx.captures on the RenderContext, so fields' {0}..{N} placeholders resolve.
  • The store is active only under --exec-fields (null otherwise), so the default -regex path stays a plain boolean match with no capture allocation — and default -exec is unchanged.

This closes the #51#50 arc: the named-field vocabulary and regex captures are both available in -exec, opt-in.

Test plan

  • evaluate_test.ExecFieldsSubstitutesRegexCaptures: a per-Match capture store; {1} resolves to group 1 only under the gate (exit-code check), literal without it.
  • run_test.ExecFieldsSubstitutesRegexCaptures: end-to-end --exec-fields . -regex '.*/(a)\.(txt)' -exec … "{1}.{2}" > "{path}.cap" \; → marker contains a.txt.
  • Green on both toolchains: bazel test //... (default) and --config=clang --config=asan.

Complete capture-aware -exec (#50): EvalContext gains a per-entry
captures store; a -regex/-iregex match records its groups into it (via
FullMatchCaptures), and the gated -exec passes them on RenderContext so
{0}..{N} resolve to the matched groups. The store is active only under
--exec-fields (null otherwise), so the default -regex path stays a plain
boolean match with no capture overhead.

Tests: evaluate_test threads a per-Match capture store and checks {1}
resolves to a group only under the gate; run_test drives
--exec-fields . -regex ... -exec ... {1}.{2} end-to-end and verifies the
captured groups land in the marker file.
@helly25
helly25 merged commit 70e265a into main Jun 21, 2026
4 checks passed
@helly25
helly25 deleted the feat/exec-captures-wire branch June 21, 2026 12:03
helly25 added a commit that referenced this pull request Jun 22, 2026
…, space default, zulu) (#87)

Refines the FormatTime presets per review into a consistent scheme where only genuinely-conformant forms carry a standard's name:
- iso8601 (+ iso alias) - ISO-8601 extended, T: 2026-06-22T14:30:00+0100
- iso8601-basic - ISO-8601 basic/compact: 20260622T143000+0100
- rfc3339 - RFC 3339, colon offset: 2026-06-22T14:30:00+01:00
- space (no-flag default) - readable, claims no standard, space before the offset: 2026-06-22 14:30:00 +0100
- asctime - asctime(3); the find default %t
- zulu / zulu-dense - UTC with a Z designator, extended / compact (force UTC)
- epoch - Unix seconds

Drops the redundant find alias (it is just asctime) and renames iso -> iso8601 with iso kept as a shorthand alias. The modern default is space (human-readable); find/strict mode defaults to asctime via the mode system (#54). Tests cover every preset, the iso alias, the space offset spacing, and zulu forcing UTC (UTC for determinism).
helly25 added a commit that referenced this pull request Jun 22, 2026
…efault decision (#88)

Follow-up to #87. Adds iso8601-full (ISO-8601 with sub-second precision: 2026-06-22T14:30:00.000000000+0100) and human as an alias of the space readable default (both via shared consts, the alias fashion).

Drops the considered sql alias: the SQL TIMESTAMP WITH TIME ZONE form uses a colon offset with no leading space (2026-06-22 14:30:00+01:00), so our space form (+0100, space before the offset) is not exactly SQL - same honesty rule as not over-claiming ISO.

Adds TODO.md to track open cross-cutting decisions; first entry is whether the modern (non-find) default should stay space or become rfc3339 (revisit before v1 / with the mode system #54).
helly25 added a commit that referenced this pull request Jun 27, 2026
* engine: parallel directory traversal + --sort modes + -j (#43)

Add a bounded worker pool (ReadPool) that runs readdir+lstat off the
coordinator thread; the visitor still runs single-threaded in --sort order,
so evaluate/emit/exec/capture/summary stay unchanged and race-free. Workers
are pure (path -> stat'd listing), touching only the thread-safe VFS and a
mutex-guarded queue.

--sort grows to none|dir|subtree|tree (name aliases dir): none = readdir
order; dir = each directory's sorted listing block then its subtrees; subtree
= sorted non-dir entries then contiguous subtrees; tree = total path order.
The ordered modes are deterministic (siblings consumed in sorted order while
the pool prefetches their reads). -j N / --jobs=N sets the worker count
(default 1 = sequential); the parent batches subdirectory reads so the pool
overlaps their IO.

Adds --config=tsan and a ubuntu-only, repo-cache-only clang-tsan CI cell
(kept off the disk cache so the 10 GB Actions budget stays healthy next to
asan). walk_test covers parallel set-equality and deterministic ordering for
all modes at workers=1 and 4; full suite is green under asan+ubsan and tsan.

Deferred (follow-ups): mode-scoped auto-defaults (modern -> parallel+dir) with
the mode mechanism (#54); completion-order subtree streaming; per-worker eval.

* docs: note v1 scope in parallel-traversal design

Record the three deliberate v1 simplifications: IO-only parallelism with a
single-threaded visitor, deterministic (sorted) ordered modes, and opt-in
-j/--sort with mode-scoped auto-defaults deferred to the mode mechanism (#54).
helly25 added a commit that referenced this pull request Jun 27, 2026
…unordered) (#144)

* engine: mode-scoped traversal defaults (modern parallel+sorted, find unordered)

Completes the deferred piece of the parallel walk (#43/#54). RunFind gains an
optional registry::Style: when the user gives no --sort / -j, the default is
mode-scoped - kXff (modern) sorts each directory (--sort=dir) and runs a capped
parallel walk (max(1, min(cores-1, 15))); kFind matches find (unordered) but
saturates cores. std::nullopt keeps the conservative unordered + sequential
default, so the ~32 in-process RunFind callers and conformance are untouched;
the CLI passes the active style (config::ActiveStyle / argv[0] dispatch).

run_test::ModeScopedSortDefault locks the behavior (kXff deterministic dir-
sorted; kFind same set, unordered). Full suite green under default and
asan+ubsan; tsan unaffected (test callers stay sequential; walk_test already
covers the parallel path).

* test+style: use unqualified ElementsAre; document the no-::testing-prefix rule

run_test's ModeScopedSortDefault wrote ::testing::ElementsAre inline even
though the file already has `using ::testing::ElementsAre;` - use the bare
name. STYLE_CPP.md now states the rule explicitly: bring matchers in with a
using and never write the ::testing:: prefix inside an EXPECT_THAT/ASSERT_THAT
expression (fixture utilities like ::testing::Test are exempt). Audited the
suite: this was the only inline-qualified matcher.
helly25 added a commit that referenced this pull request Jun 28, 2026
…oadmap decisions (#193)

Per the directive to put enforcement rules in the repo, not just memory:

AGENTS.md gains two sections:
- Self-documenting features: the registry + globals are the doc SOT; every
  feature add/change updates its Descriptor.summary / GlobalFlag entry +
  kHelpText in the same change, so --help/--man/--markdown stay complete.
- CLI conventions: flag scope by dash count (--global vs -primary; -h/-q/-help/
  -version are special-cased compat globals); flag-only, no subcommands; and a
  user-toggleable boolean capability is a --feature, not a one-off flag.

TODO.md roadmap decisions (design phase, accounting for existing code):
- #43 parallel traversal + --sort: already BUILT (ReadPool, sort modes, tests,
  tsan cell); remaining is a CLI bashtest.
- #45 --exact/--path-encoding: default = filesystem-native (natural per-platform
  case behavior); --exact forces verbatim byte matching; --path-encoding=raw|escape.
- #73 --feature: PARKED (no customer yet) with the full ready-to-build design +
  a trigger (first boolean capability builds it); trigger mirrored in AGENTS.md.
- #54 mode mechanism: subsumed by --config (no --mode flag; --modern deferred).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant