From a35af8295d29e8e31fcbc5117572f2071d9bd121 Mon Sep 17 00:00:00 2001 From: David Given Date: Wed, 17 Dec 2025 20:43:57 +0100 Subject: [PATCH 1/2] Fix ab bug where glob's exclude=[] wasn't working as expected. --- build/utils.py | 36 ++++++++++++++++++++++-------------- 1 file changed, 22 insertions(+), 14 deletions(-) diff --git a/build/utils.py b/build/utils.py index da1742c5..0488b0ef 100644 --- a/build/utils.py +++ b/build/utils.py @@ -40,31 +40,34 @@ def collectattrs(*, targets, name, initial=[]): @functools.cache def _glob_to_re(glob_str): - opts = re.compile('([.]|[*][*]/|[*]|[?])|(.)') - out = '' - for (pattern_match, literal_text) in opts.findall(glob_str): - if pattern_match == '.': - out += '[.]' - elif pattern_match == '**/': - out += '(?:.*/)?' - elif pattern_match == '*': - out += '[^/]*' - elif pattern_match == '?': - out += '.' + opts = re.compile("([.]|[*][*]/|[*]|[?])|(.)") + out = "" + for pattern_match, literal_text in opts.findall(glob_str): + if pattern_match == ".": + out += "[.]" + elif pattern_match == "**/": + out += "(?:.*/)?" + elif pattern_match == "*": + out += "[^/]*" + elif pattern_match == "?": + out += "." elif literal_text: out += literal_text return re.compile(out) + def _glob_filter(paths, pattern): r = _glob_to_re(pattern) for f in paths: if r.match(f): yield f + def _glob_matches(path, pattern): r = _glob_to_re(pattern) return r.match(path) + def glob(include=["*"], exclude=[], dir=None, relative_to="."): if not dir: dir = getcwd() @@ -81,11 +84,16 @@ def iterate(): filenames = [normpath(join(dirpath, f)) for f in filenames] matching = set() for p in include: - matching.update(_glob_filter(filenames, p)) + matching.update( + [ + normpath(relpath(join(dir, f), relative_to)) + for f in _glob_filter(filenames, p) + ] + ) for p in exclude: - matching = [n for n in matching if not _glob_matches(n, p)] + matching = [n for n in matching if not _glob_matches(n, p)] for f in matching: - yield normpath(relpath(join(dir, f), relative_to)) + yield f return list(iterate()) From eefbaafdcc266ba5c2e1952e4361a785598ee435 Mon Sep 17 00:00:00 2001 From: David Given Date: Wed, 17 Dec 2025 21:01:29 +0100 Subject: [PATCH 2/2] Update ab. --- build/protobuf.py | 1 + build/utils.py | 12 +++++------- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/build/protobuf.py b/build/protobuf.py index edfc826c..d83d7ee8 100644 --- a/build/protobuf.py +++ b/build/protobuf.py @@ -11,6 +11,7 @@ PROTO_SEPARATOR = ";" if (platform.system() == "Windows") else ":" + def _getprotodeps(deps): r = set() for d in deps: diff --git a/build/utils.py b/build/utils.py index 0488b0ef..224cae40 100644 --- a/build/utils.py +++ b/build/utils.py @@ -40,6 +40,9 @@ def collectattrs(*, targets, name, initial=[]): @functools.cache def _glob_to_re(glob_str): + if glob_str.startswith("./"): + glob_str = normpath(join(getcwd(), glob_str)) + opts = re.compile("([.]|[*][*]/|[*]|[?])|(.)") out = "" for pattern_match, literal_text in opts.findall(glob_str): @@ -80,16 +83,11 @@ def iterate(): for dirpath, dirnames, filenames in walk( dir, topdown=True, followlinks=True ): - dirpath = relpath(dirpath, dir) + dirpath = relpath(dirpath, relative_to) filenames = [normpath(join(dirpath, f)) for f in filenames] matching = set() for p in include: - matching.update( - [ - normpath(relpath(join(dir, f), relative_to)) - for f in _glob_filter(filenames, p) - ] - ) + matching.update([f for f in _glob_filter(filenames, p)]) for p in exclude: matching = [n for n in matching if not _glob_matches(n, p)] for f in matching: