##// END OF EJS Templates
utils: move the `dirs` definition in pathutil (API)...
marmoute -
r44308:c21aca51 default
parent child Browse files
Show More
@@ -22,6 +22,7 b' from mercurial import ('
22 hg,
22 hg,
23 narrowspec,
23 narrowspec,
24 node,
24 node,
25 pathutil,
25 pycompat,
26 pycompat,
26 registrar,
27 registrar,
27 repair,
28 repair,
@@ -277,7 +278,7 b' def _narrow('
277 todelete.append(f)
278 todelete.append(f)
278 elif f.startswith(b'meta/'):
279 elif f.startswith(b'meta/'):
279 dir = f[5:-13]
280 dir = f[5:-13]
280 dirs = sorted(util.dirs({dir})) + [dir]
281 dirs = sorted(pathutil.dirs({dir})) + [dir]
281 include = True
282 include = True
282 for d in dirs:
283 for d in dirs:
283 visit = newmatch.visitdir(d)
284 visit = newmatch.visitdir(d)
@@ -29,11 +29,11 b' from mercurial import ('
29 error,
29 error,
30 node,
30 node,
31 obsutil,
31 obsutil,
32 pathutil,
32 pycompat,
33 pycompat,
33 registrar,
34 registrar,
34 rewriteutil,
35 rewriteutil,
35 scmutil,
36 scmutil,
36 util,
37 )
37 )
38
38
39 cmdtable = {}
39 cmdtable = {}
@@ -185,7 +185,7 b' def uncommit(ui, repo, *pats, **opts):'
185 # if not everything tracked in that directory can be
185 # if not everything tracked in that directory can be
186 # uncommitted.
186 # uncommitted.
187 if badfiles:
187 if badfiles:
188 badfiles -= {f for f in util.dirs(eligible)}
188 badfiles -= {f for f in pathutil.dirs(eligible)}
189
189
190 for f in sorted(badfiles):
190 for f in sorted(badfiles):
191 if f in s.clean:
191 if f in s.clean:
@@ -2606,7 +2606,7 b' def remove('
2606 progress.complete()
2606 progress.complete()
2607
2607
2608 # warn about failure to delete explicit files/dirs
2608 # warn about failure to delete explicit files/dirs
2609 deleteddirs = util.dirs(deleted)
2609 deleteddirs = pathutil.dirs(deleted)
2610 files = m.files()
2610 files = m.files()
2611 progress = ui.makeprogress(
2611 progress = ui.makeprogress(
2612 _(b'deleting'), total=len(files), unit=_(b'files')
2612 _(b'deleting'), total=len(files), unit=_(b'files')
@@ -1514,11 +1514,11 b' class dirstatemap(object):'
1514
1514
1515 @propertycache
1515 @propertycache
1516 def _dirs(self):
1516 def _dirs(self):
1517 return util.dirs(self._map, b'r')
1517 return pathutil.dirs(self._map, b'r')
1518
1518
1519 @propertycache
1519 @propertycache
1520 def _alldirs(self):
1520 def _alldirs(self):
1521 return util.dirs(self._map)
1521 return pathutil.dirs(self._map)
1522
1522
1523 def _opendirstatefile(self):
1523 def _opendirstatefile(self):
1524 fp, mode = txnutil.trypending(self._root, self._opener, self._filename)
1524 fp, mode = txnutil.trypending(self._root, self._opener, self._filename)
@@ -23,6 +23,7 b' from .pycompat import getattr'
23 from . import (
23 from . import (
24 error,
24 error,
25 mdiff,
25 mdiff,
26 pathutil,
26 policy,
27 policy,
27 pycompat,
28 pycompat,
28 revlog,
29 revlog,
@@ -494,7 +495,7 b' class manifestdict(object):'
494
495
495 @propertycache
496 @propertycache
496 def _dirs(self):
497 def _dirs(self):
497 return util.dirs(self)
498 return pathutil.dirs(self)
498
499
499 def dirs(self):
500 def dirs(self):
500 return self._dirs
501 return self._dirs
@@ -1104,7 +1105,7 b' class treemanifest(object):'
1104
1105
1105 @propertycache
1106 @propertycache
1106 def _alldirs(self):
1107 def _alldirs(self):
1107 return util.dirs(self)
1108 return pathutil.dirs(self)
1108
1109
1109 def dirs(self):
1110 def dirs(self):
1110 return self._alldirs
1111 return self._alldirs
@@ -18,6 +18,7 b' from . import ('
18 encoding,
18 encoding,
19 error,
19 error,
20 pathutil,
20 pathutil,
21 pathutil,
21 policy,
22 policy,
22 pycompat,
23 pycompat,
23 util,
24 util,
@@ -598,7 +599,7 b' class patternmatcher(basematcher):'
598
599
599 @propertycache
600 @propertycache
600 def _dirs(self):
601 def _dirs(self):
601 return set(util.dirs(self._fileset))
602 return set(pathutil.dirs(self._fileset))
602
603
603 def visitdir(self, dir):
604 def visitdir(self, dir):
604 dir = normalizerootdir(dir, b'visitdir')
605 dir = normalizerootdir(dir, b'visitdir')
@@ -629,9 +630,9 b' class patternmatcher(basematcher):'
629 return b'<patternmatcher patterns=%r>' % pycompat.bytestr(self._pats)
630 return b'<patternmatcher patterns=%r>' % pycompat.bytestr(self._pats)
630
631
631
632
632 # This is basically a reimplementation of util.dirs that stores the children
633 # This is basically a reimplementation of pathutil.dirs that stores the
633 # instead of just a count of them, plus a small optional optimization to avoid
634 # children instead of just a count of them, plus a small optional optimization
634 # some directories we don't need.
635 # to avoid some directories we don't need.
635 class _dirchildren(object):
636 class _dirchildren(object):
636 def __init__(self, paths, onlyinclude=None):
637 def __init__(self, paths, onlyinclude=None):
637 self._dirs = {}
638 self._dirs = {}
@@ -763,7 +764,7 b' class exactmatcher(basematcher):'
763
764
764 @propertycache
765 @propertycache
765 def _dirs(self):
766 def _dirs(self):
766 return set(util.dirs(self._fileset))
767 return set(pathutil.dirs(self._fileset))
767
768
768 def visitdir(self, dir):
769 def visitdir(self, dir):
769 dir = normalizerootdir(dir, b'visitdir')
770 dir = normalizerootdir(dir, b'visitdir')
@@ -1510,8 +1511,8 b' def _rootsdirsandparents(kindpats):'
1510 p = set()
1511 p = set()
1511 # Add the parents as non-recursive/exact directories, since they must be
1512 # Add the parents as non-recursive/exact directories, since they must be
1512 # scanned to get to either the roots or the other exact directories.
1513 # scanned to get to either the roots or the other exact directories.
1513 p.update(util.dirs(d))
1514 p.update(pathutil.dirs(d))
1514 p.update(util.dirs(r))
1515 p.update(pathutil.dirs(r))
1515
1516
1516 # FIXME: all uses of this function convert these to sets, do so before
1517 # FIXME: all uses of this function convert these to sets, do so before
1517 # returning.
1518 # returning.
@@ -9,10 +9,14 b' from .i18n import _'
9 from . import (
9 from . import (
10 encoding,
10 encoding,
11 error,
11 error,
12 policy,
12 pycompat,
13 pycompat,
13 util,
14 util,
14 )
15 )
15
16
17 rustdirs = policy.importrust('dirstate', 'Dirs')
18 parsers = policy.importmod('parsers')
19
16
20
17 def _lowerclean(s):
21 def _lowerclean(s):
18 return encoding.hfsignoreclean(s.lower())
22 return encoding.hfsignoreclean(s.lower())
@@ -271,6 +275,58 b' def normasprefix(path):'
271 return path
275 return path
272
276
273
277
278 class dirs(object):
279 '''a multiset of directory names from a set of file paths'''
280
281 def __init__(self, map, skip=None):
282 self._dirs = {}
283 addpath = self.addpath
284 if isinstance(map, dict) and skip is not None:
285 for f, s in pycompat.iteritems(map):
286 if s[0] != skip:
287 addpath(f)
288 elif skip is not None:
289 raise error.ProgrammingError(
290 b"skip character is only supported with a dict source"
291 )
292 else:
293 for f in map:
294 addpath(f)
295
296 def addpath(self, path):
297 dirs = self._dirs
298 for base in util.finddirs(path):
299 if base.endswith(b'/'):
300 raise ValueError(
301 "found invalid consecutive slashes in path: %r" % base
302 )
303 if base in dirs:
304 dirs[base] += 1
305 return
306 dirs[base] = 1
307
308 def delpath(self, path):
309 dirs = self._dirs
310 for base in util.finddirs(path):
311 if dirs[base] > 1:
312 dirs[base] -= 1
313 return
314 del dirs[base]
315
316 def __iter__(self):
317 return iter(self._dirs)
318
319 def __contains__(self, d):
320 return d in self._dirs
321
322
323 if util.safehasattr(parsers, 'dirs'):
324 dirs = parsers.dirs
325
326 if rustdirs is not None:
327 dirs = rustdirs
328
329
274 # forward two methods from posixpath that do what we need, but we'd
330 # forward two methods from posixpath that do what we need, but we'd
275 # rather not let our internals know that we're thinking in posix terms
331 # rather not let our internals know that we're thinking in posix terms
276 # - instead we'll let them be oblivious.
332 # - instead we'll let them be oblivious.
@@ -24,6 +24,7 b' from . import ('
24 exchange,
24 exchange,
25 obsolete,
25 obsolete,
26 obsutil,
26 obsutil,
27 pathutil,
27 phases,
28 phases,
28 pycompat,
29 pycompat,
29 util,
30 util,
@@ -476,7 +477,7 b' def rebuildfncache(ui, repo):'
476 if b'treemanifest' in repo.requirements:
477 if b'treemanifest' in repo.requirements:
477 # This logic is safe if treemanifest isn't enabled, but also
478 # This logic is safe if treemanifest isn't enabled, but also
478 # pointless, so we skip it if treemanifest isn't enabled.
479 # pointless, so we skip it if treemanifest isn't enabled.
479 for dir in util.dirs(seenfiles):
480 for dir in pathutil.dirs(seenfiles):
480 i = b'meta/%s/00manifest.i' % dir
481 i = b'meta/%s/00manifest.i' % dir
481 d = b'meta/%s/00manifest.d' % dir
482 d = b'meta/%s/00manifest.d' % dir
482
483
@@ -57,11 +57,8 b' from .utils import ('
57 stringutil,
57 stringutil,
58 )
58 )
59
59
60 rustdirs = policy.importrust('dirstate', 'Dirs')
61
62 base85 = policy.importmod('base85')
60 base85 = policy.importmod('base85')
63 osutil = policy.importmod('osutil')
61 osutil = policy.importmod('osutil')
64 parsers = policy.importmod('parsers')
65
62
66 b85decode = base85.b85decode
63 b85decode = base85.b85decode
67 b85encode = base85.b85encode
64 b85encode = base85.b85encode
@@ -3494,58 +3491,6 b' def debugstacktrace('
3494 f.flush()
3491 f.flush()
3495
3492
3496
3493
3497 class dirs(object):
3498 '''a multiset of directory names from a dirstate or manifest'''
3499
3500 def __init__(self, map, skip=None):
3501 self._dirs = {}
3502 addpath = self.addpath
3503 if isinstance(map, dict) and skip is not None:
3504 for f, s in pycompat.iteritems(map):
3505 if s[0] != skip:
3506 addpath(f)
3507 elif skip is not None:
3508 raise error.ProgrammingError(
3509 b"skip character is only supported with a dict source"
3510 )
3511 else:
3512 for f in map:
3513 addpath(f)
3514
3515 def addpath(self, path):
3516 dirs = self._dirs
3517 for base in finddirs(path):
3518 if base.endswith(b'/'):
3519 raise ValueError(
3520 "found invalid consecutive slashes in path: %r" % base
3521 )
3522 if base in dirs:
3523 dirs[base] += 1
3524 return
3525 dirs[base] = 1
3526
3527 def delpath(self, path):
3528 dirs = self._dirs
3529 for base in finddirs(path):
3530 if dirs[base] > 1:
3531 dirs[base] -= 1
3532 return
3533 del dirs[base]
3534
3535 def __iter__(self):
3536 return iter(self._dirs)
3537
3538 def __contains__(self, d):
3539 return d in self._dirs
3540
3541
3542 if safehasattr(parsers, 'dirs'):
3543 dirs = parsers.dirs
3544
3545 if rustdirs is not None:
3546 dirs = rustdirs
3547
3548
3549 def finddirs(path):
3494 def finddirs(path):
3550 pos = path.rfind(b'/')
3495 pos = path.rfind(b'/')
3551 while pos != -1:
3496 while pos != -1:
@@ -4,7 +4,7 b' import unittest'
4
4
5 import silenttestrunner
5 import silenttestrunner
6
6
7 from mercurial import util
7 from mercurial import pathutil
8
8
9
9
10 class dirstests(unittest.TestCase):
10 class dirstests(unittest.TestCase):
@@ -13,13 +13,13 b' class dirstests(unittest.TestCase):'
13 (b'a/a/a', [b'a', b'a/a', b'']),
13 (b'a/a/a', [b'a', b'a/a', b'']),
14 (b'alpha/beta/gamma', [b'', b'alpha', b'alpha/beta']),
14 (b'alpha/beta/gamma', [b'', b'alpha', b'alpha/beta']),
15 ]:
15 ]:
16 d = util.dirs({})
16 d = pathutil.dirs({})
17 d.addpath(case)
17 d.addpath(case)
18 self.assertEqual(sorted(d), sorted(want))
18 self.assertEqual(sorted(d), sorted(want))
19
19
20 def testinvalid(self):
20 def testinvalid(self):
21 with self.assertRaises(ValueError):
21 with self.assertRaises(ValueError):
22 d = util.dirs({})
22 d = pathutil.dirs({})
23 d.addpath(b'a//b')
23 d.addpath(b'a//b')
24
24
25
25
General Comments 0
You need to be logged in to leave comments. Login now