D7311: utils: move the `dirs` definition in a dedicated module (API)

marmoute (Pierre-Yves David) phabricator at mercurial-scm.org
Fri Nov 8 09:32:19 UTC 2019


marmoute created this revision.
Herald added a reviewer: durin42.
Herald added a reviewer: martinvonz.
Herald added a subscriber: mercurial-devel.
Herald added a reviewer: hg-reviewers.

REVISION SUMMARY
  Before this change, the `dirs` class was accessible through the `mercurial.util`
  module. That module is expected to stay free of scm specific content.
  
  This work is part of a refactoring to unify the revlog index and the nodemap.
  This unification prepare the use of a persistent nodemap.

REPOSITORY
  rHG Mercurial

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/repair.py
  mercurial/util.py
  mercurial/utils/dirstateutil.py

CHANGE DETAILS

diff --git a/mercurial/utils/dirstateutil.py b/mercurial/utils/dirstateutil.py
new file mode 100644
--- /dev/null
+++ b/mercurial/utils/dirstateutil.py
@@ -0,0 +1,59 @@
+from __future__ import absolute_import
+
+from .. import (
+    error,
+    policy,
+    pycompat,
+    util,
+)
+
+rustdirs = policy.importrust(r'dirstate', r'Dirs')
+parsers = policy.importmod(r'parsers')
+
+
+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 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
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
@@ -28,7 +28,10 @@
     pycompat,
     util,
 )
-from .utils import stringutil
+from .utils import (
+    dirstateutil,
+    stringutil,
+)
 
 
 def backupbundle(
@@ -476,7 +479,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 dirstateutil.dirs(seenfiles):
                 i = b'meta/%s/00manifest.i' % dir
                 d = b'meta/%s/00manifest.d' % dir
 
diff --git a/mercurial/match.py b/mercurial/match.py
--- a/mercurial/match.py
+++ b/mercurial/match.py
@@ -22,7 +22,10 @@
     pycompat,
     util,
 )
-from .utils import stringutil
+from .utils import (
+    dirstateutil,
+    stringutil,
+)
 
 rustmod = policy.importrust(r'filepatterns')
 
@@ -595,7 +598,7 @@
 
     @propertycache
     def _dirs(self):
-        return set(util.dirs(self._fileset))
+        return set(dirstateutil.dirs(self._fileset))
 
     def visitdir(self, dir):
         dir = normalizerootdir(dir, b'visitdir')
@@ -760,7 +763,7 @@
 
     @propertycache
     def _dirs(self):
-        return set(util.dirs(self._fileset))
+        return set(dirstateutil.dirs(self._fileset))
 
     def visitdir(self, dir):
         dir = normalizerootdir(dir, b'visitdir')
@@ -1507,8 +1510,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(dirstateutil.dirs(d))
+    p.update(dirstateutil.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
@@ -32,6 +32,7 @@
     repository,
     util as interfaceutil,
 )
+from .utils import dirstateutil
 
 parsers = policy.importmod(r'parsers')
 propertycache = util.propertycache
@@ -494,7 +495,7 @@
 
     @propertycache
     def _dirs(self):
-        return util.dirs(self)
+        return dirstateutil.dirs(self)
 
     def dirs(self):
         return self._dirs
@@ -1104,7 +1105,7 @@
 
     @propertycache
     def _alldirs(self):
-        return util.dirs(self)
+        return dirstateutil.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
@@ -36,6 +36,8 @@
     util as interfaceutil,
 )
 
+from .utils import dirstateutil
+
 parsers = policy.importmod(r'parsers')
 rustmod = policy.importrust(r'dirstate')
 
@@ -1504,11 +1506,11 @@
 
     @propertycache
     def _dirs(self):
-        return util.dirs(self._map, b'r')
+        return dirstateutil.dirs(self._map, b'r')
 
     @propertycache
     def _alldirs(self):
-        return util.dirs(self._map)
+        return dirstateutil.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
@@ -58,6 +58,7 @@
 
 from .utils import (
     dateutil,
+    dirstateutil,
     stringutil,
 )
 
@@ -2606,7 +2607,7 @@
     progress.complete()
 
     # warn about failure to delete explicit files/dirs
-    deleteddirs = util.dirs(deleted)
+    deleteddirs = dirstateutil.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
@@ -33,8 +33,8 @@
     registrar,
     rewriteutil,
     scmutil,
-    util,
 )
+from mercurial.utils import dirstateutil
 
 cmdtable = {}
 command = registrar.command(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 dirstateutil.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
@@ -31,6 +31,7 @@
     wireprototypes,
 )
 from mercurial.interfaces import repository
+from mercurial.utils import dirstateutil
 
 table = {}
 command = registrar.command(table)
@@ -277,7 +278,7 @@
                     todelete.append(f)
             elif f.startswith(b'meta/'):
                 dir = f[5:-13]
-                dirs = sorted(util.dirs({dir})) + [dir]
+                dirs = sorted(dirstateutil.dirs({dir})) + [dir]
                 include = True
                 for d in dirs:
                     visit = newmatch.visitdir(d)



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


More information about the Mercurial-devel mailing list