comparison mercurial/pathutil.py @ 43523:c21aca51b392

utils: move the `dirs` definition in pathutil (API) Before this change, the `dirs` class was accessible through the `mercurial.util` module. That module is expected to stay free of scm specific content. The `pathutil` destination has been selection by Martin von Zweigbergk. This work is part of a refactoring to unify the revlog index and the nodemap. This unification prepare the use of a persistent nodemap. Differential Revision: https://phab.mercurial-scm.org/D7311
author Pierre-Yves David <pierre-yves.david@octobus.net>
date Wed, 06 Nov 2019 14:13:19 +0100
parents 687b865b95ad
children 0b7733719d21
comparison
equal deleted inserted replaced
43522:ce96be208ea4 43523:c21aca51b392
7 7
8 from .i18n import _ 8 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 )
16
17 rustdirs = policy.importrust('dirstate', 'Dirs')
18 parsers = policy.importmod('parsers')
15 19
16 20
17 def _lowerclean(s): 21 def _lowerclean(s):
18 return encoding.hfsignoreclean(s.lower()) 22 return encoding.hfsignoreclean(s.lower())
19 23
269 return path + pycompat.ossep 273 return path + pycompat.ossep
270 else: 274 else:
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.
277 join = posixpath.join 333 join = posixpath.join
278 dirname = posixpath.dirname 334 dirname = posixpath.dirname