localrepo: move new repo requirements into standalone function (API)
authorGregory Szorc <gregory.szorc@gmail.com>
Mon, 15 Feb 2016 13:20:20 -0800
changeset 28164 ad11edefa7c4
parent 28163 5d3495e394d5
child 28165 c6705c6303dd
localrepo: move new repo requirements into standalone function (API) This patch extracts the code for determining requirements for a new repo into a standalone function. By doing so, future code that will perform an in-place repository upgrade (e.g. to generaldelta) can examine the set of proposed new requirements and possibly take additional actions (such as adding dotencode or fncache) when performing the upgrade. This patch is marked as API because _baserequirements (which was added in b090601a80d1 so extensions could override it) has been removed and will presumably impact whatever extension it was added for. Consumers should be able to monkeypatch the new function to achieve the same functionality. The "create" argument has been dropped because the function is only called in one location and "create" is always true in that case. While it makes logical sense for this code to be a method so extensions can implement a custom repo class / method to override it, this won't actually work. This is because requirements determination occurs during localrepository.__init__ and this is before the "reposetup" "callback" is fired. So, the only way for extensions to customize requirements would be to overwrite localrepo.localrepository or to monkeypatch a function on a module during extsetup(). Since we try to keep localrepository small, we use a standalone function. There is probably room to offer extensions a "hook" point to alter repository creation. But that is scope bloat.
mercurial/localrepo.py
--- a/mercurial/localrepo.py	Mon Feb 15 13:19:07 2016 -0800
+++ b/mercurial/localrepo.py	Mon Feb 15 13:20:20 2016 -0800
@@ -242,9 +242,6 @@
     # only functions defined in module of enabled extensions are invoked
     featuresetupfuncs = set()
 
-    def _baserequirements(self, create):
-        return ['revlogv1']
-
     def __init__(self, baseui, path=None, create=False):
         self.requirements = set()
         self.wvfs = scmutil.vfs(path, expandpath=True, realpath=True)
@@ -282,28 +279,13 @@
 
         if not self.vfs.isdir():
             if create:
-                requirements = set(self._baserequirements(create))
-                if self.ui.configbool('format', 'usestore', True):
-                    requirements.add("store")
-                    if self.ui.configbool('format', 'usefncache', True):
-                        requirements.add("fncache")
-                        if self.ui.configbool('format', 'dotencode', True):
-                            requirements.add('dotencode')
-
-                if scmutil.gdinitconfig(self.ui):
-                    requirements.add("generaldelta")
-                if self.ui.configbool('experimental', 'treemanifest', False):
-                    requirements.add("treemanifest")
-                if self.ui.configbool('experimental', 'manifestv2', False):
-                    requirements.add("manifestv2")
-
-                self.requirements = requirements
+                self.requirements = newreporequirements(self)
 
                 if not self.wvfs.exists():
                     self.wvfs.makedirs()
                 self.vfs.makedir(notindexed=True)
 
-                if 'store' in requirements:
+                if 'store' in self.requirements:
                     self.vfs.mkdir("store")
 
                     # create an invalid changelog
@@ -1969,3 +1951,27 @@
 
 def islocal(path):
     return True
+
+def newreporequirements(repo):
+    """Determine the set of requirements for a new local repository.
+
+    Extensions can wrap this function to specify custom requirements for
+    new repositories.
+    """
+    ui = repo.ui
+    requirements = set(['revlogv1'])
+    if ui.configbool('format', 'usestore', True):
+        requirements.add('store')
+        if ui.configbool('format', 'usefncache', True):
+            requirements.add('fncache')
+            if ui.configbool('format', 'dotencode', True):
+                requirements.add('dotencode')
+
+    if scmutil.gdinitconfig(ui):
+        requirements.add('generaldelta')
+    if ui.configbool('experimental', 'treemanifest', False):
+        requirements.add('treemanifest')
+    if ui.configbool('experimental', 'manifestv2', False):
+        requirements.add('manifestv2')
+
+    return requirements