Patchwork [5,of,6] lfs: convert to using exthelper to wrap functions

login
register
mail settings
Submitter Matt Harbison
Date Dec. 1, 2018, 4:10 a.m.
Message ID <99150c56ee5f0f709380.1543637459@Envy>
Download mbox | patch
Permalink /patch/36891/
State New
Headers show

Comments

Matt Harbison - Dec. 1, 2018, 4:10 a.m.
# HG changeset patch
# User Matt Harbison <matt_harbison@yahoo.com>
# Date 1543374607 18000
#      Tue Nov 27 22:10:07 2018 -0500
# Node ID 99150c56ee5f0f709380c46717fb283c615a911b
# Parent  9472a31f5d6537265a4a2caa249797e7d8e83046
lfs: convert to using exthelper to wrap functions

I'm not 100% sure that upgraderequirements() can be double annotated safely, but
it seems OK based on printing the address of the function being wrapped.

Patch

diff --git a/hgext/lfs/__init__.py b/hgext/lfs/__init__.py
--- a/hgext/lfs/__init__.py
+++ b/hgext/lfs/__init__.py
@@ -129,30 +129,23 @@  import sys
 from mercurial.i18n import _
 
 from mercurial import (
-    bundle2,
-    changegroup,
-    cmdutil,
     config,
     context,
     error,
     exchange,
     extensions,
+    exthelper,
     filelog,
     filesetlang,
     localrepo,
     minifileset,
     node,
     pycompat,
-    registrar,
     repository,
     revlog,
     scmutil,
     templateutil,
-    upgrade,
     util,
-    vfs as vfsmod,
-    wireprotoserver,
-    wireprotov1server,
 )
 
 from . import (
@@ -167,45 +160,46 @@  from . import (
 # leave the attribute unspecified.
 testedwith = 'ships-with-hg-core'
 
-configtable = {}
-configitem = registrar.configitem(configtable)
+eh = exthelper.exthelper()
+eh.merge(wrapper.eh)
+eh.merge(wireprotolfsserver.eh)
 
-configitem('experimental', 'lfs.serve',
+cmdtable = eh.cmdtable
+configtable = eh.configtable
+extsetup = eh.finalextsetup
+uisetup = eh.finaluisetup
+reposetup = eh.finalreposetup
+
+eh.configitem('experimental', 'lfs.serve',
     default=True,
 )
-configitem('experimental', 'lfs.user-agent',
+eh.configitem('experimental', 'lfs.user-agent',
     default=None,
 )
-configitem('experimental', 'lfs.disableusercache',
+eh.configitem('experimental', 'lfs.disableusercache',
     default=False,
 )
-configitem('experimental', 'lfs.worker-enable',
+eh.configitem('experimental', 'lfs.worker-enable',
     default=False,
 )
 
-configitem('lfs', 'url',
+eh.configitem('lfs', 'url',
     default=None,
 )
-configitem('lfs', 'usercache',
+eh.configitem('lfs', 'usercache',
     default=None,
 )
 # Deprecated
-configitem('lfs', 'threshold',
+eh.configitem('lfs', 'threshold',
     default=None,
 )
-configitem('lfs', 'track',
+eh.configitem('lfs', 'track',
     default='none()',
 )
-configitem('lfs', 'retry',
+eh.configitem('lfs', 'retry',
     default=5,
 )
 
-cmdtable = {}
-command = registrar.command(cmdtable)
-
-templatekeyword = registrar.templatekeyword()
-filesetpredicate = registrar.filesetpredicate()
-
 lfsprocessor = (
     wrapper.readfromstore,
     wrapper.writetostore,
@@ -216,10 +210,12 @@  def featuresetup(ui, supported):
     # don't die on seeing a repo with the lfs requirement
     supported |= {'lfs'}
 
-def uisetup(ui):
+@eh.uisetup
+def _uisetup(ui):
     localrepo.featuresetupfuncs.add(featuresetup)
 
-def reposetup(ui, repo):
+@eh.reposetup
+def _reposetup(ui, repo):
     # Nothing to do with a remote repo
     if not repo.local():
         return
@@ -305,6 +301,7 @@  def _trackedmatcher(repo):
 
     return _match
 
+# Called by remotefilelog
 def wrapfilelog(filelog):
     wrapfunction = extensions.wrapfunction
 
@@ -312,6 +309,7 @@  def wrapfilelog(filelog):
     wrapfunction(filelog, 'renamed', wrapper.filelogrenamed)
     wrapfunction(filelog, 'size', wrapper.filelogsize)
 
+@eh.wrapfunction(localrepo, 'resolverevlogstorevfsoptions')
 def _resolverevlogstorevfsoptions(orig, ui, requirements, features):
     opts = orig(ui, requirements, features)
     for name, module in extensions.extensions(ui):
@@ -326,38 +324,10 @@  def _resolverevlogstorevfsoptions(orig, 
 
     return opts
 
-def extsetup(ui):
+@eh.extsetup
+def _extsetup(ui):
     wrapfilelog(filelog.filelog)
 
-    wrapfunction = extensions.wrapfunction
-
-    wrapfunction(localrepo, 'makefilestorage', wrapper.localrepomakefilestorage)
-    wrapfunction(localrepo, 'resolverevlogstorevfsoptions',
-                 _resolverevlogstorevfsoptions)
-
-    wrapfunction(cmdutil, '_updatecatformatter', wrapper._updatecatformatter)
-    wrapfunction(scmutil, 'wrapconvertsink', wrapper.convertsink)
-
-    wrapfunction(upgrade, '_finishdatamigration',
-                 wrapper.upgradefinishdatamigration)
-
-    wrapfunction(upgrade, 'preservedrequirements',
-                 wrapper.upgraderequirements)
-
-    wrapfunction(upgrade, 'supporteddestrequirements',
-                 wrapper.upgraderequirements)
-
-    wrapfunction(changegroup,
-                 'allsupportedversions',
-                 wrapper.allsupportedversions)
-
-    wrapfunction(exchange, 'push', wrapper.push)
-    wrapfunction(wireprotov1server, '_capabilities', wrapper._capabilities)
-    wrapfunction(wireprotoserver, 'handlewsgirequest',
-                 wireprotolfsserver.handlewsgirequest)
-
-    wrapfunction(context.basefilectx, 'cmp', wrapper.filectxcmp)
-    wrapfunction(context.basefilectx, 'isbinary', wrapper.filectxisbinary)
     context.basefilectx.islfs = wrapper.filectxislfs
 
     scmutil.fileprefetchhooks.add('lfs', wrapper._prefetchfiles)
@@ -367,14 +337,7 @@  def extsetup(ui):
     # "packed1". Using "packed1" with lfs will likely cause trouble.
     exchange._bundlespeccontentopts["v2"]["cg.version"] = "03"
 
-    # bundlerepo uses "vfsmod.readonlyvfs(othervfs)", we need to make sure lfs
-    # options and blob stores are passed from othervfs to the new readonlyvfs.
-    wrapfunction(vfsmod.readonlyvfs, '__init__', wrapper.vfsinit)
-
-    # when writing a bundle via "hg bundle" command, upload related LFS blobs
-    wrapfunction(bundle2, 'writenewbundle', wrapper.writenewbundle)
-
-@filesetpredicate('lfs()')
+@eh.fileset('lfs()')
 def lfsfileset(mctx, x):
     """File that uses LFS storage."""
     # i18n: "lfs" is a keyword
@@ -384,7 +347,7 @@  def lfsfileset(mctx, x):
         return wrapper.pointerfromctx(ctx, f, removed=True) is not None
     return mctx.predicate(lfsfilep, predrepr='<lfs>')
 
-@templatekeyword('lfs_files', requires={'ctx'})
+@eh.templatekw('lfs_files', requires={'ctx'})
 def lfsfiles(context, mapping):
     """List of strings. All files modified, added, or removed by this
     changeset."""
@@ -409,8 +372,8 @@  def lfsfiles(context, mapping):
     f = templateutil._showcompatlist(context, mapping, 'lfs_file', files)
     return templateutil.hybrid(f, files, makemap, pycompat.identity)
 
-@command('debuglfsupload',
-         [('r', 'rev', [], _('upload large files introduced by REV'))])
+@eh.command('debuglfsupload',
+            [('r', 'rev', [], _('upload large files introduced by REV'))])
 def debuglfsupload(ui, repo, **opts):
     """upload lfs blobs added by the working copy parent or given revisions"""
     revs = opts.get(r'rev', [])
diff --git a/hgext/lfs/wireprotolfsserver.py b/hgext/lfs/wireprotolfsserver.py
--- a/hgext/lfs/wireprotolfsserver.py
+++ b/hgext/lfs/wireprotolfsserver.py
@@ -17,8 +17,10 @@  from mercurial.hgweb import (
 )
 
 from mercurial import (
+    exthelper,
     pycompat,
     util,
+    wireprotoserver,
 )
 
 from . import blobstore
@@ -31,6 +33,9 @@  HTTP_METHOD_NOT_ALLOWED = hgwebcommon.HT
 HTTP_NOT_ACCEPTABLE = hgwebcommon.HTTP_NOT_ACCEPTABLE
 HTTP_UNSUPPORTED_MEDIA_TYPE = hgwebcommon.HTTP_UNSUPPORTED_MEDIA_TYPE
 
+eh = exthelper.exthelper()
+
+@eh.wrapfunction(wireprotoserver, 'handlewsgirequest')
 def handlewsgirequest(orig, rctx, req, res, checkperm):
     """Wrap wireprotoserver.handlewsgirequest() to possibly process an LFS
     request if it is left unprocessed by the wrapped method.
diff --git a/hgext/lfs/wrapper.py b/hgext/lfs/wrapper.py
--- a/hgext/lfs/wrapper.py
+++ b/hgext/lfs/wrapper.py
@@ -13,10 +13,21 @@  from mercurial.i18n import _
 from mercurial.node import bin, hex, nullid, short
 
 from mercurial import (
+    bundle2,
+    changegroup,
+    cmdutil,
+    context,
     error,
+    exchange,
+    exthelper,
+    localrepo,
     repository,
     revlog,
+    scmutil,
+    upgrade,
     util,
+    vfs as vfsmod,
+    wireprotov1server,
 )
 
 from mercurial.utils import (
@@ -31,17 +42,22 @@  from . import (
     pointer,
 )
 
+eh = exthelper.exthelper()
+
+@eh.wrapfunction(localrepo, 'makefilestorage')
 def localrepomakefilestorage(orig, requirements, features, **kwargs):
     if b'lfs' in requirements:
         features.add(repository.REPO_FEATURE_LFS)
 
     return orig(requirements=requirements, features=features, **kwargs)
 
+@eh.wrapfunction(changegroup, 'allsupportedversions')
 def allsupportedversions(orig, ui):
     versions = orig(ui)
     versions.add('03')
     return versions
 
+@eh.wrapfunction(wireprotov1server, '_capabilities')
 def _capabilities(orig, repo, proto):
     '''Wrap server command to announce lfs server capability'''
     caps = orig(repo, proto)
@@ -130,6 +146,7 @@  def _islfs(rlog, node=None, rev=None):
     flags = rlog._revlog.flags(rev)
     return bool(flags & revlog.REVIDX_EXTSTORED)
 
+# Wrapping may also be applied by remotefilelog
 def filelogaddrevision(orig, self, text, transaction, link, p1, p2,
                        cachedelta=None, node=None,
                        flags=revlog.REVIDX_DEFAULT_FLAGS, **kwds):
@@ -149,6 +166,7 @@  def filelogaddrevision(orig, self, text,
     return orig(self, text, transaction, link, p1, p2, cachedelta=cachedelta,
                 node=node, flags=flags, **kwds)
 
+# Wrapping may also be applied by remotefilelog
 def filelogrenamed(orig, self, node):
     if _islfs(self, node):
         rawtext = self._revlog.revision(node, raw=True)
@@ -161,6 +179,7 @@  def filelogrenamed(orig, self, node):
             return False
     return orig(self, node)
 
+# Wrapping may also be applied by remotefilelog
 def filelogsize(orig, self, rev):
     if _islfs(self, rev=rev):
         # fast path: use lfs metadata to answer size
@@ -169,6 +188,7 @@  def filelogsize(orig, self, rev):
         return int(metadata['size'])
     return orig(self, rev)
 
+@eh.wrapfunction(context.basefilectx, 'cmp')
 def filectxcmp(orig, self, fctx):
     """returns True if text is different than fctx"""
     # some fctx (ex. hg-git) is not based on basefilectx and do not have islfs
@@ -179,6 +199,7 @@  def filectxcmp(orig, self, fctx):
         return p1.oid() != p2.oid()
     return orig(self, fctx)
 
+@eh.wrapfunction(context.basefilectx, 'isbinary')
 def filectxisbinary(orig, self):
     if self.islfs():
         # fast path: use lfs metadata to answer isbinary
@@ -190,10 +211,12 @@  def filectxisbinary(orig, self):
 def filectxislfs(self):
     return _islfs(self.filelog(), self.filenode())
 
+@eh.wrapfunction(cmdutil, '_updatecatformatter')
 def _updatecatformatter(orig, fm, ctx, matcher, path, decode):
     orig(fm, ctx, matcher, path, decode)
     fm.data(rawdata=ctx[path].rawdata())
 
+@eh.wrapfunction(scmutil, 'wrapconvertsink')
 def convertsink(orig, sink):
     sink = orig(sink)
     if sink.repotype == 'hg':
@@ -219,6 +242,9 @@  def convertsink(orig, sink):
 
     return sink
 
+# bundlerepo uses "vfsmod.readonlyvfs(othervfs)", we need to make sure lfs
+# options and blob stores are passed from othervfs to the new readonlyvfs.
+@eh.wrapfunction(vfsmod.readonlyvfs, '__init__')
 def vfsinit(orig, self, othervfs):
     orig(self, othervfs)
     # copy lfs related options
@@ -290,6 +316,7 @@  def prepush(pushop):
     """
     return uploadblobsfromrevs(pushop.repo, pushop.outgoing.missing)
 
+@eh.wrapfunction(exchange, 'push')
 def push(orig, repo, remote, *args, **kwargs):
     """bail on push if the extension isn't enabled on remote when needed, and
     update the remote store based on the destination path."""
@@ -316,6 +343,8 @@  def push(orig, repo, remote, *args, **kw
     else:
         return orig(repo, remote, *args, **kwargs)
 
+# when writing a bundle via "hg bundle" command, upload related LFS blobs
+@eh.wrapfunction(bundle2, 'writenewbundle')
 def writenewbundle(orig, ui, repo, source, filename, bundletype, outgoing,
                    *args, **kwargs):
     """upload LFS blobs added by outgoing revisions on 'hg bundle'"""
@@ -393,6 +422,7 @@  def uploadblobs(repo, pointers):
     remoteblob = repo.svfs.lfsremoteblobstore
     remoteblob.writebatch(pointers, repo.svfs.lfslocalblobstore)
 
+@eh.wrapfunction(upgrade, '_finishdatamigration')
 def upgradefinishdatamigration(orig, ui, srcrepo, dstrepo, requirements):
     orig(ui, srcrepo, dstrepo, requirements)
 
@@ -407,6 +437,8 @@  def upgradefinishdatamigration(orig, ui,
                 ui.write(_('copying lfs blob %s\n') % oid)
                 lfutil.link(srclfsvfs.join(oid), dstlfsvfs.join(oid))
 
+@eh.wrapfunction(upgrade, 'preservedrequirements')
+@eh.wrapfunction(upgrade, 'supporteddestrequirements')
 def upgraderequirements(orig, repo):
     reqs = orig(repo)
     if 'lfs' in repo.requirements: