1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
|
"""
Filename globbing like the python glob module with minor differences:
* glob relative to an arbitrary directory
* include . and ..
* check that link targets exist, not just links
"""
import os, re, fnmatch
import util
_globcheck = re.compile('[[*?]')
def hasglob(p):
return _globcheck.search(p) is not None
def glob(fsdir, path):
"""
Yield paths matching the path glob. Sorts as a bonus. Excludes '.' and '..'
"""
dir, leaf = os.path.split(path)
if dir == '':
return globpattern(fsdir, leaf)
if hasglob(dir):
dirsfound = glob(fsdir, dir)
else:
dirsfound = [dir]
r = []
for dir in dirsfound:
fspath = util.normaljoin(fsdir, dir)
if not os.path.isdir(fspath):
continue
r.extend((util.normaljoin(dir, found) for found in globpattern(fspath, leaf)))
return r
def globpattern(dir, pattern):
"""
Return leaf names in the specified directory which match the pattern.
"""
if not hasglob(pattern):
if pattern == '':
if os.path.isdir(dir):
return ['']
return []
if os.path.exists(util.normaljoin(dir, pattern)):
return [pattern]
return []
leaves = os.listdir(dir) + ['.', '..']
# "hidden" filenames are a bit special
if not pattern.startswith('.'):
leaves = [leaf for leaf in leaves
if not leaf.startswith('.')]
leaves = fnmatch.filter(leaves, pattern)
leaves = filter(lambda l: os.path.exists(util.normaljoin(dir, l)), leaves)
leaves.sort()
return leaves
|