Mercurial > hg > mercurial-crew-with-dirclash
comparison mercurial/util.py @ 896:01215ad04283
Merge with BOS
author | mpm@selenic.com |
---|---|
date | Sat, 13 Aug 2005 19:43:42 -0800 |
parents | 9c918287d10b 77b52b864249 |
children | fe30f5434b51 |
comparison
equal
deleted
inserted
replaced
867:0cd2ee61b10a | 896:01215ad04283 |
---|---|
14 for f in g: | 14 for f in g: |
15 if f not in seen: | 15 if f not in seen: |
16 seen[f] = 1 | 16 seen[f] = 1 |
17 yield f | 17 yield f |
18 | 18 |
19 class CommandError(Exception): pass | 19 class Abort(Exception): |
20 """Raised if a command needs to print an error and exit.""" | |
20 | 21 |
21 def always(fn): return True | 22 def always(fn): return True |
22 def never(fn): return False | 23 def never(fn): return False |
23 | 24 |
24 def globre(pat, head = '^', tail = '$'): | 25 def globre(pat, head = '^', tail = '$'): |
66 res += re.escape(c) | 67 res += re.escape(c) |
67 return head + res + tail | 68 return head + res + tail |
68 | 69 |
69 _globchars = {'[': 1, '{': 1, '*': 1, '?': 1} | 70 _globchars = {'[': 1, '{': 1, '*': 1, '?': 1} |
70 | 71 |
71 def matcher(cwd, names, inc, exc, head = ''): | 72 def pathto(n1, n2): |
73 '''return the relative path from one place to another. | |
74 this returns a path in the form used by the local filesystem, not hg.''' | |
75 if not n1: return localpath(n2) | |
76 a, b = n1.split('/'), n2.split('/') | |
77 a.reverse(), b.reverse() | |
78 while a and b and a[-1] == b[-1]: | |
79 a.pop(), b.pop() | |
80 b.reverse() | |
81 return os.sep.join((['..'] * len(a)) + b) | |
82 | |
83 def canonpath(repo, cwd, myname): | |
84 rootsep = repo.root + os.sep | |
85 name = myname | |
86 if not name.startswith(os.sep): | |
87 name = os.path.join(repo.root, cwd, name) | |
88 name = os.path.normpath(name) | |
89 if name.startswith(rootsep): | |
90 return pconvert(name[len(rootsep):]) | |
91 elif name == repo.root: | |
92 return '' | |
93 else: | |
94 raise Abort('%s not under repository root' % myname) | |
95 | |
96 def matcher(repo, cwd, names, inc, exc, head = ''): | |
72 def patkind(name): | 97 def patkind(name): |
73 for prefix in 're:', 'glob:', 'path:': | 98 for prefix in 're:', 'glob:', 'path:', 'relpath:': |
74 if name.startswith(prefix): return name.split(':', 1) | 99 if name.startswith(prefix): return name.split(':', 1) |
75 for c in name: | 100 for c in name: |
76 if c in _globchars: return 'glob', name | 101 if c in _globchars: return 'glob', name |
77 return 'relpath', name | 102 return 'relpath', name |
78 | 103 |
79 cwdsep = cwd + os.sep | 104 def regex(kind, name, tail): |
80 | |
81 def regex(name, tail): | |
82 '''convert a pattern into a regular expression''' | 105 '''convert a pattern into a regular expression''' |
83 kind, name = patkind(name) | |
84 if kind == 're': | 106 if kind == 're': |
85 return name | 107 return name |
86 elif kind == 'path': | 108 elif kind == 'path': |
87 return '^' + re.escape(name) + '$' | 109 return '^' + re.escape(name) + '(?:/|$)' |
88 if cwd: name = os.path.join(cwdsep, name) | 110 elif kind == 'relpath': |
89 name = os.path.normpath(name) | 111 return head + re.escape(name) + tail |
90 if name == '.': name = '**' | |
91 return head + globre(name, '', tail) | 112 return head + globre(name, '', tail) |
92 | |
93 def under(fn): | |
94 """check if fn is under our cwd""" | |
95 return not cwd or fn.startswith(cwdsep) | |
96 | 113 |
97 def matchfn(pats, tail): | 114 def matchfn(pats, tail): |
98 """build a matching function from a set of patterns""" | 115 """build a matching function from a set of patterns""" |
99 if pats: | 116 if pats: |
100 pat = '(?:%s)' % '|'.join([regex(p, tail) for p in pats]) | 117 pat = '(?:%s)' % '|'.join([regex(k, p, tail) for (k, p) in pats]) |
101 return re.compile(pat).match | 118 return re.compile(pat).match |
102 | 119 |
103 def globprefix(pat): | 120 def globprefix(pat): |
104 '''return the non-glob prefix of a path, e.g. foo/* -> foo''' | 121 '''return the non-glob prefix of a path, e.g. foo/* -> foo''' |
105 root = [] | 122 root = [] |
106 for p in pat.split(os.sep): | 123 for p in pat.split(os.sep): |
107 if patkind(p)[0] == 'glob': break | 124 if patkind(p)[0] == 'glob': break |
108 root.append(p) | 125 root.append(p) |
109 return os.sep.join(root) | 126 return '/'.join(root) |
110 | 127 |
111 patkinds = map(patkind, names) | 128 pats = [] |
112 pats = [name for (kind, name) in patkinds if kind != 'relpath'] | 129 files = [] |
113 files = [name for (kind, name) in patkinds if kind == 'relpath'] | 130 roots = [] |
114 roots = filter(None, map(globprefix, pats)) + files | 131 for kind, name in map(patkind, names): |
115 if cwd: roots = [cwdsep + r for r in roots] | 132 if kind in ('glob', 'relpath'): |
133 name = canonpath(repo, cwd, name) | |
134 if name == '': | |
135 kind, name = 'glob', '**' | |
136 if kind in ('glob', 'path', 're'): | |
137 pats.append((kind, name)) | |
138 if kind == 'glob': | |
139 root = globprefix(name) | |
140 if root: roots.append(root) | |
141 elif kind == 'relpath': | |
142 files.append((kind, name)) | |
143 roots.append(name) | |
116 | 144 |
117 patmatch = matchfn(pats, '$') or always | 145 patmatch = matchfn(pats, '$') or always |
118 filematch = matchfn(files, '(?:/|$)') or always | 146 filematch = matchfn(files, '(?:/|$)') or always |
119 incmatch = matchfn(inc, '(?:/|$)') or always | 147 incmatch = matchfn(map(patkind, inc), '(?:/|$)') or always |
120 excmatch = matchfn(exc, '(?:/|$)') or (lambda fn: False) | 148 excmatch = matchfn(map(patkind, exc), '(?:/|$)') or (lambda fn: False) |
121 | 149 |
122 return roots, lambda fn: (incmatch(fn) and not excmatch(fn) and | 150 return roots, lambda fn: (incmatch(fn) and not excmatch(fn) and |
123 (fn.endswith('/') or | 151 (fn.endswith('/') or |
124 (not pats and not files) or | 152 (not pats and not files) or |
125 (pats and patmatch(fn)) or | 153 (pats and patmatch(fn)) or |
131 if rc: | 159 if rc: |
132 errmsg = "%s %s" % (os.path.basename(cmd.split(None, 1)[0]), | 160 errmsg = "%s %s" % (os.path.basename(cmd.split(None, 1)[0]), |
133 explain_exit(rc)[0]) | 161 explain_exit(rc)[0]) |
134 if errprefix: | 162 if errprefix: |
135 errmsg = "%s: %s" % (errprefix, errmsg) | 163 errmsg = "%s: %s" % (errprefix, errmsg) |
136 raise CommandError(errmsg) | 164 raise Abort(errmsg) |
137 | 165 |
138 def rename(src, dst): | 166 def rename(src, dst): |
139 try: | 167 try: |
140 os.rename(src, dst) | 168 os.rename(src, dst) |
141 except: | 169 except: |
175 def set_exec(f, mode): | 203 def set_exec(f, mode): |
176 pass | 204 pass |
177 | 205 |
178 def pconvert(path): | 206 def pconvert(path): |
179 return path.replace("\\", "/") | 207 return path.replace("\\", "/") |
208 | |
209 def localpath(path): | |
210 return path.replace('/', '\\') | |
211 | |
212 def normpath(path): | |
213 return pconvert(os.path.normpath(path)) | |
180 | 214 |
181 makelock = _makelock_file | 215 makelock = _makelock_file |
182 readlock = _readlock_file | 216 readlock = _readlock_file |
183 | 217 |
184 def explain_exit(code): | 218 def explain_exit(code): |
204 os.chmod(f, s & 0666) | 238 os.chmod(f, s & 0666) |
205 | 239 |
206 def pconvert(path): | 240 def pconvert(path): |
207 return path | 241 return path |
208 | 242 |
243 def localpath(path): | |
244 return path | |
245 | |
246 normpath = os.path.normpath | |
247 | |
209 def makelock(info, pathname): | 248 def makelock(info, pathname): |
210 try: | 249 try: |
211 os.symlink(info, pathname) | 250 os.symlink(info, pathname) |
212 except OSError, why: | 251 except OSError, why: |
213 if why.errno == errno.EEXIST: | 252 if why.errno == errno.EEXIST: |