Patchwork D7311: utils: move the `dirs` definition in pathutil (API)

login
register
mail settings
Submitter phabricator
Date Nov. 9, 2019, 1:12 a.m.
Message ID <ac2eb2e9ed5646b7a8c1e34eea3134fe@localhost.localdomain>
Download mbox | patch
Permalink /patch/43004/
State Not Applicable
Headers show

Comments

phabricator - Nov. 9, 2019, 1:12 a.m.
marmoute edited the summary of this revision.
marmoute retitled this revision from "utils: move the `dirs` definition in a dedicated module (API)" to "utils: move the `dirs` definition in pathutil (API)".
marmoute updated this revision to Diff 17821.

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D7311?vs=17750&id=17821

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D7311/new/

REVISION DETAIL
  https://phab.mercurial-scm.org/D7311

AFFECTED FILES
  hgext/narrow/narrowcommands.py
  hgext/uncommit.py
  mercurial/cmdutil.py
  mercurial/dirstate.py
  mercurial/manifest.py
  mercurial/match.py
  mercurial/pathutil.py
  mercurial/repair.py
  mercurial/util.py

CHANGE DETAILS




To: marmoute, durin42, martinvonz, #hg-reviewers, Alphare, indygreg
Cc: indygreg, mercurial-devel

Patch

diff --git a/mercurial/util.py b/mercurial/util.py
--- a/mercurial/util.py
+++ b/mercurial/util.py
@@ -57,11 +57,8 @@ 
     stringutil,
 )
 
-rustdirs = policy.importrust(r'dirstate', r'Dirs')
-
 base85 = policy.importmod(r'base85')
 osutil = policy.importmod(r'osutil')
-parsers = policy.importmod(r'parsers')
 
 b85decode = base85.b85decode
 b85encode = base85.b85encode
@@ -3494,54 +3491,6 @@ 
     f.flush()
 
 
-class dirs(object):
-    '''a multiset of directory names from a dirstate or manifest'''
-
-    def __init__(self, map, skip=None):
-        self._dirs = {}
-        addpath = self.addpath
-        if isinstance(map, dict) and skip is not None:
-            for f, s in pycompat.iteritems(map):
-                if s[0] != skip:
-                    addpath(f)
-        elif skip is not None:
-            raise error.ProgrammingError(
-                b"skip character is only supported with a dict source"
-            )
-        else:
-            for f in map:
-                addpath(f)
-
-    def addpath(self, path):
-        dirs = self._dirs
-        for base in finddirs(path):
-            if base in dirs:
-                dirs[base] += 1
-                return
-            dirs[base] = 1
-
-    def delpath(self, path):
-        dirs = self._dirs
-        for base in finddirs(path):
-            if dirs[base] > 1:
-                dirs[base] -= 1
-                return
-            del dirs[base]
-
-    def __iter__(self):
-        return iter(self._dirs)
-
-    def __contains__(self, d):
-        return d in self._dirs
-
-
-if safehasattr(parsers, 'dirs'):
-    dirs = parsers.dirs
-
-if rustdirs is not None:
-    dirs = rustdirs
-
-
 def finddirs(path):
     pos = path.rfind(b'/')
     while pos != -1:
diff --git a/mercurial/repair.py b/mercurial/repair.py
--- a/mercurial/repair.py
+++ b/mercurial/repair.py
@@ -24,6 +24,7 @@ 
     exchange,
     obsolete,
     obsutil,
+    pathutil,
     phases,
     pycompat,
     util,
@@ -476,7 +477,7 @@ 
         if b'treemanifest' in repo.requirements:
             # This logic is safe if treemanifest isn't enabled, but also
             # pointless, so we skip it if treemanifest isn't enabled.
-            for dir in util.dirs(seenfiles):
+            for dir in pathutil.dirs(seenfiles):
                 i = b'meta/%s/00manifest.i' % dir
                 d = b'meta/%s/00manifest.d' % dir
 
diff --git a/mercurial/pathutil.py b/mercurial/pathutil.py
--- a/mercurial/pathutil.py
+++ b/mercurial/pathutil.py
@@ -9,10 +9,14 @@ 
 from . import (
     encoding,
     error,
+    policy,
     pycompat,
     util,
 )
 
+rustdirs = policy.importrust(r'dirstate', r'Dirs')
+parsers = policy.importmod(r'parsers')
+
 
 def _lowerclean(s):
     return encoding.hfsignoreclean(s.lower())
@@ -271,6 +275,54 @@ 
         return path
 
 
+class dirs(object):
+    '''a multiset of directory names from a set of file paths'''
+
+    def __init__(self, map, skip=None):
+        self._dirs = {}
+        addpath = self.addpath
+        if isinstance(map, dict) and skip is not None:
+            for f, s in pycompat.iteritems(map):
+                if s[0] != skip:
+                    addpath(f)
+        elif skip is not None:
+            raise error.ProgrammingError(
+                b"skip character is only supported with a dict source"
+            )
+        else:
+            for f in map:
+                addpath(f)
+
+    def addpath(self, path):
+        dirs = self._dirs
+        for base in util.finddirs(path):
+            if base in dirs:
+                dirs[base] += 1
+                return
+            dirs[base] = 1
+
+    def delpath(self, path):
+        dirs = self._dirs
+        for base in util.finddirs(path):
+            if dirs[base] > 1:
+                dirs[base] -= 1
+                return
+            del dirs[base]
+
+    def __iter__(self):
+        return iter(self._dirs)
+
+    def __contains__(self, d):
+        return d in self._dirs
+
+
+if util.safehasattr(parsers, 'dirs'):
+    dirs = parsers.dirs
+
+if rustdirs is not None:
+    dirs = rustdirs
+
+
 # forward two methods from posixpath that do what we need, but we'd
 # rather not let our internals know that we're thinking in posix terms
 # - instead we'll let them be oblivious.
diff --git a/mercurial/match.py b/mercurial/match.py
--- a/mercurial/match.py
+++ b/mercurial/match.py
@@ -18,6 +18,7 @@ 
     encoding,
     error,
     pathutil,
+    pathutil,
     policy,
     pycompat,
     util,
@@ -595,7 +596,7 @@ 
 
     @propertycache
     def _dirs(self):
-        return set(util.dirs(self._fileset))
+        return set(pathutil.dirs(self._fileset))
 
     def visitdir(self, dir):
         dir = normalizerootdir(dir, b'visitdir')
@@ -626,9 +627,9 @@ 
         return b'<patternmatcher patterns=%r>' % pycompat.bytestr(self._pats)
 
 
-# This is basically a reimplementation of util.dirs that stores the children
-# instead of just a count of them, plus a small optional optimization to avoid
-# some directories we don't need.
+# This is basically a reimplementation of pathutil.dirs that stores the
+# children instead of just a count of them, plus a small optional optimization
+# to avoid some directories we don't need.
 class _dirchildren(object):
     def __init__(self, paths, onlyinclude=None):
         self._dirs = {}
@@ -760,7 +761,7 @@ 
 
     @propertycache
     def _dirs(self):
-        return set(util.dirs(self._fileset))
+        return set(pathutil.dirs(self._fileset))
 
     def visitdir(self, dir):
         dir = normalizerootdir(dir, b'visitdir')
@@ -1507,8 +1508,8 @@ 
     p = set()
     # Add the parents as non-recursive/exact directories, since they must be
     # scanned to get to either the roots or the other exact directories.
-    p.update(util.dirs(d))
-    p.update(util.dirs(r))
+    p.update(pathutil.dirs(d))
+    p.update(pathutil.dirs(r))
 
     # FIXME: all uses of this function convert these to sets, do so before
     # returning.
diff --git a/mercurial/manifest.py b/mercurial/manifest.py
--- a/mercurial/manifest.py
+++ b/mercurial/manifest.py
@@ -23,6 +23,7 @@ 
 from . import (
     error,
     mdiff,
+    pathutil,
     policy,
     pycompat,
     revlog,
@@ -494,7 +495,7 @@ 
 
     @propertycache
     def _dirs(self):
-        return util.dirs(self)
+        return pathutil.dirs(self)
 
     def dirs(self):
         return self._dirs
@@ -1104,7 +1105,7 @@ 
 
     @propertycache
     def _alldirs(self):
-        return util.dirs(self)
+        return pathutil.dirs(self)
 
     def dirs(self):
         return self._alldirs
diff --git a/mercurial/dirstate.py b/mercurial/dirstate.py
--- a/mercurial/dirstate.py
+++ b/mercurial/dirstate.py
@@ -1504,11 +1504,11 @@ 
 
     @propertycache
     def _dirs(self):
-        return util.dirs(self._map, b'r')
+        return pathutil.dirs(self._map, b'r')
 
     @propertycache
     def _alldirs(self):
-        return util.dirs(self._map)
+        return pathutil.dirs(self._map)
 
     def _opendirstatefile(self):
         fp, mode = txnutil.trypending(self._root, self._opener, self._filename)
diff --git a/mercurial/cmdutil.py b/mercurial/cmdutil.py
--- a/mercurial/cmdutil.py
+++ b/mercurial/cmdutil.py
@@ -2606,7 +2606,7 @@ 
     progress.complete()
 
     # warn about failure to delete explicit files/dirs
-    deleteddirs = util.dirs(deleted)
+    deleteddirs = pathutil.dirs(deleted)
     files = m.files()
     progress = ui.makeprogress(
         _(b'deleting'), total=len(files), unit=_(b'files')
diff --git a/hgext/uncommit.py b/hgext/uncommit.py
--- a/hgext/uncommit.py
+++ b/hgext/uncommit.py
@@ -29,11 +29,11 @@ 
     error,
     node,
     obsutil,
+    pathutil,
     pycompat,
     registrar,
     rewriteutil,
     scmutil,
-    util,
 )
 
 cmdtable = {}
@@ -185,7 +185,7 @@ 
             # if not everything tracked in that directory can be
             # uncommitted.
             if badfiles:
-                badfiles -= {f for f in util.dirs(eligible)}
+                badfiles -= {f for f in pathutil.dirs(eligible)}
 
             for f in sorted(badfiles):
                 if f in s.clean:
diff --git a/hgext/narrow/narrowcommands.py b/hgext/narrow/narrowcommands.py
--- a/hgext/narrow/narrowcommands.py
+++ b/hgext/narrow/narrowcommands.py
@@ -22,6 +22,7 @@ 
     hg,
     narrowspec,
     node,
+    pathutil,
     pycompat,
     registrar,
     repair,
@@ -277,7 +278,7 @@ 
                     todelete.append(f)
             elif f.startswith(b'meta/'):
                 dir = f[5:-13]
-                dirs = sorted(util.dirs({dir})) + [dir]
+                dirs = sorted(pathutil.dirs({dir})) + [dir]
                 include = True
                 for d in dirs:
                     visit = newmatch.visitdir(d)