Mercurial > public > mercurial-scm > hg
comparison mercurial/pathutil.py @ 45942:89a2afe31e82
formating: upgrade to black 20.8b1
This required a couple of small tweaks to un-confuse black, but now it
works. Big formatting changes come from:
* Dramatically improved collection-splitting logic upstream
* Black having a strong (correct IMO) opinion that """ is better than '''
Differential Revision: https://phab.mercurial-scm.org/D9430
author | Augie Fackler <raf@durin42.com> |
---|---|
date | Fri, 27 Nov 2020 17:03:29 -0500 |
parents | 233ee525dcef |
children | 5d483e3bb60e |
comparison
equal
deleted
inserted
replaced
45941:346af7687c6f | 45942:89a2afe31e82 |
---|---|
22 def _lowerclean(s): | 22 def _lowerclean(s): |
23 return encoding.hfsignoreclean(s.lower()) | 23 return encoding.hfsignoreclean(s.lower()) |
24 | 24 |
25 | 25 |
26 class pathauditor(object): | 26 class pathauditor(object): |
27 '''ensure that a filesystem path contains no banned components. | 27 """ensure that a filesystem path contains no banned components. |
28 the following properties of a path are checked: | 28 the following properties of a path are checked: |
29 | 29 |
30 - ends with a directory separator | 30 - ends with a directory separator |
31 - under top-level .hg | 31 - under top-level .hg |
32 - starts at the root of a windows drive | 32 - starts at the root of a windows drive |
42 stored history. | 42 stored history. |
43 | 43 |
44 If 'cached' is set to True, audited paths and sub-directories are cached. | 44 If 'cached' is set to True, audited paths and sub-directories are cached. |
45 Be careful to not keep the cache of unmanaged directories for long because | 45 Be careful to not keep the cache of unmanaged directories for long because |
46 audited paths may be replaced with symlinks. | 46 audited paths may be replaced with symlinks. |
47 ''' | 47 """ |
48 | 48 |
49 def __init__(self, root, callback=None, realfs=True, cached=False): | 49 def __init__(self, root, callback=None, realfs=True, cached=False): |
50 self.audited = set() | 50 self.audited = set() |
51 self.auditeddir = set() | 51 self.auditeddir = set() |
52 self.root = root | 52 self.root = root |
57 self.normcase = util.normcase | 57 self.normcase = util.normcase |
58 else: | 58 else: |
59 self.normcase = lambda x: x | 59 self.normcase = lambda x: x |
60 | 60 |
61 def __call__(self, path, mode=None): | 61 def __call__(self, path, mode=None): |
62 '''Check the relative path. | 62 """Check the relative path. |
63 path may contain a pattern (e.g. foodir/**.txt)''' | 63 path may contain a pattern (e.g. foodir/**.txt)""" |
64 | 64 |
65 path = util.localpath(path) | 65 path = util.localpath(path) |
66 normpath = self.normcase(path) | 66 normpath = self.normcase(path) |
67 if normpath in self.audited: | 67 if normpath in self.audited: |
68 return | 68 return |
162 self.auditeddir.clear() | 162 self.auditeddir.clear() |
163 self._cached = False | 163 self._cached = False |
164 | 164 |
165 | 165 |
166 def canonpath(root, cwd, myname, auditor=None): | 166 def canonpath(root, cwd, myname, auditor=None): |
167 '''return the canonical path of myname, given cwd and root | 167 """return the canonical path of myname, given cwd and root |
168 | 168 |
169 >>> def check(root, cwd, myname): | 169 >>> def check(root, cwd, myname): |
170 ... a = pathauditor(root, realfs=False) | 170 ... a = pathauditor(root, realfs=False) |
171 ... try: | 171 ... try: |
172 ... return canonpath(root, cwd, myname, a) | 172 ... return canonpath(root, cwd, myname, a) |
202 'filename' | 202 'filename' |
203 >>> unixonly(b'/repo', b'/repo', b'filename', b'filename') | 203 >>> unixonly(b'/repo', b'/repo', b'filename', b'filename') |
204 'filename' | 204 'filename' |
205 >>> unixonly(b'/repo', b'/repo/subdir', b'filename', b'subdir/filename') | 205 >>> unixonly(b'/repo', b'/repo/subdir', b'filename', b'subdir/filename') |
206 'subdir/filename' | 206 'subdir/filename' |
207 ''' | 207 """ |
208 if util.endswithsep(root): | 208 if util.endswithsep(root): |
209 rootsep = root | 209 rootsep = root |
210 else: | 210 else: |
211 rootsep = root + pycompat.ossep | 211 rootsep = root + pycompat.ossep |
212 name = myname | 212 name = myname |
264 _(b"%s not under root '%s'") % (myname, root), hint=hint | 264 _(b"%s not under root '%s'") % (myname, root), hint=hint |
265 ) | 265 ) |
266 | 266 |
267 | 267 |
268 def normasprefix(path): | 268 def normasprefix(path): |
269 '''normalize the specified path as path prefix | 269 """normalize the specified path as path prefix |
270 | 270 |
271 Returned value can be used safely for "p.startswith(prefix)", | 271 Returned value can be used safely for "p.startswith(prefix)", |
272 "p[len(prefix):]", and so on. | 272 "p[len(prefix):]", and so on. |
273 | 273 |
274 For efficiency, this expects "path" argument to be already | 274 For efficiency, this expects "path" argument to be already |
278 | 278 |
279 >>> normasprefix(b'/foo/bar').replace(pycompat.ossep, b'/') | 279 >>> normasprefix(b'/foo/bar').replace(pycompat.ossep, b'/') |
280 '/foo/bar/' | 280 '/foo/bar/' |
281 >>> normasprefix(b'/').replace(pycompat.ossep, b'/') | 281 >>> normasprefix(b'/').replace(pycompat.ossep, b'/') |
282 '/' | 282 '/' |
283 ''' | 283 """ |
284 d, p = os.path.splitdrive(path) | 284 d, p = os.path.splitdrive(path) |
285 if len(p) != len(pycompat.ossep): | 285 if len(p) != len(pycompat.ossep): |
286 return path + pycompat.ossep | 286 return path + pycompat.ossep |
287 else: | 287 else: |
288 return path | 288 return path |
298 | 298 |
299 class dirs(object): | 299 class dirs(object): |
300 '''a multiset of directory names from a set of file paths''' | 300 '''a multiset of directory names from a set of file paths''' |
301 | 301 |
302 def __init__(self, map, skip=None): | 302 def __init__(self, map, skip=None): |
303 ''' | 303 """ |
304 a dict map indicates a dirstate while a list indicates a manifest | 304 a dict map indicates a dirstate while a list indicates a manifest |
305 ''' | 305 """ |
306 self._dirs = {} | 306 self._dirs = {} |
307 addpath = self.addpath | 307 addpath = self.addpath |
308 if isinstance(map, dict) and skip is not None: | 308 if isinstance(map, dict) and skip is not None: |
309 for f, s in pycompat.iteritems(map): | 309 for f, s in pycompat.iteritems(map): |
310 if s[0] != skip: | 310 if s[0] != skip: |