← Files taskplaneARCHIVED FILE
taskplane/glob_match.py
1.45 KB · Oct 2, 2026 · 00:29 UTC
"""Dependency-neutral repository path glob matching.
Both the high-level lens router and the lower graph-signal router depend on
this module. It deliberately imports neither routing layer, which prevents
the old duplication from becoming an import cycle.
"""
from __future__ import annotations
import fnmatch
import os
def path_matches(path: str, pattern: str) -> bool:
"""Match one repository path with Taskplane's historical ``**/`` rules."""
if fnmatch.fnmatch(path, pattern):
return True
if pattern.startswith("**/"):
tail = pattern[3:]
if (fnmatch.fnmatch(path, tail)
or fnmatch.fnmatch(os.path.basename(path), tail)):
return True
parts = path.split("/")
return any(fnmatch.fnmatch("/".join(parts[index:]), tail)
for index in range(len(parts)))
return False
def first_match(files, patterns):
"""Return the first deterministic ``(file, pattern)`` match, if any."""
for pattern in patterns or ():
for path in files or ():
if path_matches(path, pattern):
return path, pattern
return None
def matches_by_pattern(files, patterns) -> list:
"""Return the first file matched by each pattern, preserving order."""
hits = []
for pattern in patterns or ():
for path in files or ():
if path_matches(path, pattern):
hits.append((path, pattern))
break
return hits
SHA-256: 51f98184313a5c2e93d1f6308152c986fa7a71a344da47692759ae5ebed79dc0