Skip to content

Commit 69e435c

Browse files
committed
Update ab.
1 parent 2a876f6 commit 69e435c

File tree

2 files changed

+74
-10
lines changed

2 files changed

+74
-10
lines changed

build/ab.py

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -388,6 +388,10 @@ def _filetarget(value, cwd):
388388
return t
389389

390390

391+
def getcwd():
392+
return cwdStack[-1]
393+
394+
391395
def targetof(value, cwd=None):
392396
if not cwd:
393397
cwd = cwdStack[-1]
@@ -544,12 +548,14 @@ def shell(*args):
544548

545549
def add_commanddb_entry(commands, file):
546550
global commandsDb
547-
commandsDb += [{
548-
"directory": os.getcwd(),
549-
"command": (" && ".join(commands)),
550-
"file": file
551-
}
552-
]
551+
commandsDb += [
552+
{
553+
"directory": os.getcwd(),
554+
"command": (" && ".join(commands)),
555+
"file": file,
556+
}
557+
]
558+
553559

554560
def emit_rule(self, ins, outs, cmds=[], label=None):
555561
name = self.name

build/utils.py

Lines changed: 62 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,19 @@
44
Targets,
55
filenameof,
66
filenamesof,
7-
cwdStack,
7+
getcwd,
88
error,
99
simplerule,
10-
G
10+
G,
1111
)
12-
from os.path import relpath, splitext, join, basename, isfile
12+
from os.path import relpath, splitext, join, basename, isfile, normpath
13+
from os import walk
1314
from glob import iglob
1415
import fnmatch
1516
import subprocess
1617
import shutil
18+
import re
19+
import functools
1720

1821

1922
def filenamesmatchingof(xs, pattern):
@@ -35,9 +38,64 @@ def collectattrs(*, targets, name, initial=[]):
3538
return sorted(s)
3639

3740

41+
@functools.cache
42+
def _glob_to_re(glob_str):
43+
opts = re.compile("([.]|[*][*]/|[*]|[?])|(.)")
44+
out = ""
45+
for pattern_match, literal_text in opts.findall(glob_str):
46+
if pattern_match == ".":
47+
out += "[.]"
48+
elif pattern_match == "**/":
49+
out += "(?:.*/)?"
50+
elif pattern_match == "*":
51+
out += "[^/]*"
52+
elif pattern_match == "?":
53+
out += "."
54+
elif literal_text:
55+
out += literal_text
56+
return re.compile(out)
57+
58+
59+
def _glob_filter(paths, pattern):
60+
r = _glob_to_re(pattern)
61+
for f in paths:
62+
if r.match(f):
63+
yield f
64+
65+
66+
def _glob_matches(path, pattern):
67+
r = _glob_to_re(pattern)
68+
return r.match(path)
69+
70+
71+
def glob(include=["*"], exclude=[], dir=None, relative_to="."):
72+
if not dir:
73+
dir = getcwd()
74+
if dir.startswith("./"):
75+
dir = normpath(join(getcwd(), dir))
76+
if relative_to.startswith("./"):
77+
relative_to = normpath(join(getcwd(), relative_to))
78+
79+
def iterate():
80+
for dirpath, dirnames, filenames in walk(
81+
dir, topdown=True, followlinks=True
82+
):
83+
dirpath = relpath(dirpath, dir)
84+
filenames = [normpath(join(dirpath, f)) for f in filenames]
85+
matching = set()
86+
for p in include:
87+
matching.update(_glob_filter(filenames, p))
88+
for p in exclude:
89+
matching = [n for n in matching if not _glob_matches(n, p)]
90+
for f in matching:
91+
yield normpath(relpath(join(dir, f), relative_to))
92+
93+
return list(iterate())
94+
95+
3896
def itemsof(pattern, root=None, cwd=None):
3997
if not cwd:
40-
cwd = cwdStack[-1]
98+
cwd = getcwd()
4199
if not root:
42100
root = "."
43101

0 commit comments

Comments
 (0)