#testsupport/discovery.tcl - test-file discovery for runtests.tcl #added 2026-07-19, reworked to directory-oriented pass-through 2026-07-20 (agent, G-093) # #Discovery contract: -include-paths/-exclude-paths patterns are handed to #punk::path::treefilenames unchanged and carry ITS directory-oriented semantics - #patterns match the DIRECTORY containing test files (tailbase-relative, forward #slashes), with the deliberately separable forms: # X files directly in X only # X/* files in folders exactly one below X # X/** files in the subtrees strictly below X (not files directly in X) # X/*** files in X and everything below it <- the common subtree form #File-tail globs (the runtests trailing arguments, default *.test) select FILENAMES #within the contributing directories - the directory and filename axes are independent. #-exclude-paths uses the same syntax; **|***-tail patterns prune the matched subtree, #other matches exclude just that folder's files; exclusion wins over inclusion. # #History (G-093): the 2026-07-19 increment instead filtered tailbase-relative FILE #paths at the runtests layer, which fixed the X/** boundary miss but gave #-include-paths a different meaning here than in treefilenames. Reworked at user #direction 2026-07-20: punk::path 0.4.0 gained *** (zero or more segments) plus #include/exclude separability fixes, so the runner passes patterns through and the #pathglob semantics are identical everywhere. # #Sourced by runtests.tcl (parent side - discovery happens once, before any child #processes) and by the runner-targeting regression suite #(runner/testsuites/discovery/pathdiscovery.test). Callers need module paths #established before sourcing: bootsupport for the runner - which therefore needs the #punk::path 0.4.0 snapshot for *** support - and the generated payload for suite #child processes. package require punk::path 0.4.0- namespace eval ::runtests_discovery {} proc ::runtests_discovery::discover_testfiles {base include_patterns exclude_patterns tailglobs exclude_files} { return [punk::path::treefilenames -directory $base -tailbase $base -include-paths $include_patterns -exclude-paths $exclude_patterns -exclude-files $exclude_files {*}$tailglobs] } proc ::runtests_discovery::dir_matches_any {patterns filepath} { #directory-of-file matching for post-discovery classification (-serial-paths and the #per-pattern zero-match advisory): true when the directory containing filepath matches #any pattern - the same directory-oriented reading the discovery patterns use. set dir [file dirname $filepath] if {$dir eq "."} { #a file directly at the discovery base - its tailbase-relative directory is the #empty string (matched by e.g bare *, ** and ***) set dir "" } foreach pat $patterns { if {[punk::path::globmatchpath $pat $dir]} { return 1 } } return 0 }