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: