Patchwork [2,of,2,V3] lfs: register the flag processors per repository

login
register
mail settings
Submitter Matt Harbison
Date Oct. 13, 2018, 3:41 a.m.
Message ID <ae3bc2b74520fd510c43.1539402090@Envy>
Download mbox | patch
Permalink /patch/35805/
State Accepted
Headers show

Comments

Matt Harbison - Oct. 13, 2018, 3:41 a.m.
# HG changeset patch
# User Matt Harbison <matt_harbison@yahoo.com>
# Date 1538626646 14400
#      Thu Oct 04 00:17:26 2018 -0400
# Node ID ae3bc2b74520fd510c431d02c6266fe0d21adca4
# Parent  fad7f4426a669a4f3b29ebda547b23a64d9e9326
lfs: register the flag processors per repository

Previously, enabling the extension for any repo in commandserver or hgweb would
enable the flags on all repos.  Since localrepo.resolverevlogstorevfsoptions()
is called so early, the check to see if the extension is enabled on the repo
(which hasn't been instantiated yet) is a bit awkward.  But I don't see a better
way.
Yuya Nishihara - Oct. 13, 2018, 4:26 a.m.
On Fri, 12 Oct 2018 23:41:30 -0400, Matt Harbison wrote:
> # HG changeset patch
> # User Matt Harbison <matt_harbison@yahoo.com>
> # Date 1538626646 14400
> #      Thu Oct 04 00:17:26 2018 -0400
> # Node ID ae3bc2b74520fd510c431d02c6266fe0d21adca4
> # Parent  fad7f4426a669a4f3b29ebda547b23a64d9e9326
> lfs: register the flag processors per repository

Queued, thanks.

> +def _resolverevlogstorevfsoptions(orig, ui, requirements, features):
> +    opts = orig(ui, requirements, features)
> +    for name, module in extensions.extensions(ui):
> +        if module == sys.modules[__name__]:

I've changed '==' to 'is', which seems more common.

Patch

diff --git a/hgext/lfs/__init__.py b/hgext/lfs/__init__.py
--- a/hgext/lfs/__init__.py
+++ b/hgext/lfs/__init__.py
@@ -124,6 +124,8 @@  Configs::
 
 from __future__ import absolute_import
 
+import sys
+
 from mercurial.i18n import _
 
 from mercurial import (
@@ -204,6 +206,12 @@  command = registrar.command(cmdtable)
 templatekeyword = registrar.templatekeyword()
 filesetpredicate = registrar.filesetpredicate()
 
+lfsprocessor = (
+    wrapper.readfromstore,
+    wrapper.writetostore,
+    wrapper.bypasscheckhash,
+)
+
 def featuresetup(ui, supported):
     # don't die on seeing a repo with the lfs requirement
     supported |= {'lfs'}
@@ -302,12 +310,28 @@  def wrapfilelog(filelog):
     wrapfunction(filelog, 'renamed', wrapper.filelogrenamed)
     wrapfunction(filelog, 'size', wrapper.filelogsize)
 
+def _resolverevlogstorevfsoptions(orig, ui, requirements, features):
+    opts = orig(ui, requirements, features)
+    for name, module in extensions.extensions(ui):
+        if module == sys.modules[__name__]:
+            if revlog.REVIDX_EXTSTORED in opts[b'flagprocessors']:
+                msg = (_(b"cannot register multiple processors on flag '%#x'.")
+                       % revlog.REVIDX_EXTSTORED)
+                raise error.Abort(msg)
+
+            opts[b'flagprocessors'][revlog.REVIDX_EXTSTORED] = lfsprocessor
+            break
+
+    return opts
+
 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)
@@ -334,15 +358,6 @@  def extsetup(ui):
     wrapfunction(context.basefilectx, 'isbinary', wrapper.filectxisbinary)
     context.basefilectx.islfs = wrapper.filectxislfs
 
-    revlog.addflagprocessor(
-        revlog.REVIDX_EXTSTORED,
-        (
-            wrapper.readfromstore,
-            wrapper.writetostore,
-            wrapper.bypasscheckhash,
-        ),
-    )
-
     scmutil.fileprefetchhooks.add('lfs', wrapper._prefetchfiles)
 
     # Make bundle choose changegroup3 instead of changegroup2. This affects
diff --git a/tests/test-lfs-serve.t b/tests/test-lfs-serve.t
--- a/tests/test-lfs-serve.t
+++ b/tests/test-lfs-serve.t
@@ -35,6 +35,26 @@  make command server magic visible
   $ hg init server
   $ SERVER_REQUIRES="$TESTTMP/server/.hg/requires"
 
+  $ cat > $TESTTMP/debugprocessors.py <<EOF
+  > from mercurial import (
+  >     cmdutil,
+  >     commands,
+  >     pycompat,
+  >     registrar,
+  > )
+  > cmdtable = {}
+  > command = registrar.command(cmdtable)
+  > @command(b'debugprocessors', [], b'FILE')
+  > def debugprocessors(ui, repo, file_=None, **opts):
+  >     opts = pycompat.byteskwargs(opts)
+  >     opts[b'changelog'] = False
+  >     opts[b'manifest'] = False
+  >     opts[b'dir'] = False
+  >     rl = cmdutil.openrevlog(repo, b'debugprocessors', file_, opts)
+  >     for flag, proc in rl._flagprocessors.iteritems():
+  >         ui.status(b"registered processor '%#x'\n" % (flag))
+  > EOF
+
 Skip the experimental.changegroup3=True config.  Failure to agree on this comes
 first, and causes a "ValueError: no common changegroup version" or "abort:
 HTTP Error 500: Internal Server Error", if the extension is only loaded on one
@@ -42,6 +62,8 @@  side.  If that *is* enabled, the subsequ
 for flag '0x2000'!" if the extension is only loaded on one side (possibly also
 masked by the Internal Server Error message).
   $ cat >> $HGRCPATH <<EOF
+  > [extensions]
+  > debugprocessors = $TESTTMP/debugprocessors.py
   > [experimental]
   > lfs.disableusercache = True
   > [lfs]
@@ -51,6 +73,8 @@  masked by the Internal Server Error mess
   > push_ssl=False
   > EOF
 
+  $ cp $HGRCPATH $HGRCPATH.orig
+
 #if lfsremote-on
   $ hg --config extensions.lfs= -R server \
   >    serve -p $HGPORT -d --pid-file=hg.pid --errorlog=$TESTTMP/errors.log
@@ -307,6 +331,103 @@  lfs content, and the extension enabled.
   $ hg identify http://localhost:$HGPORT
   c729025cc5e3
 
+  $ mv $HGRCPATH $HGRCPATH.tmp
+  $ cp $HGRCPATH.orig $HGRCPATH
+
+  >>> from __future__ import absolute_import
+  >>> from hgclient import check, readchannel, runcommand
+  >>> @check
+  ... def checkflags(server):
+  ...     readchannel(server)
+  ...     print('')
+  ...     print('# LFS required- both lfs and non-lfs revlogs have 0x2000 flag')
+  ...     runcommand(server, ['debugprocessors', 'lfs.bin', '-R',
+  ...                '../server'])
+  ...     runcommand(server, ['debugprocessors', 'nonlfs2.txt', '-R',
+  ...                '../server'])
+  ...     runcommand(server, ['config', 'extensions', '--cwd',
+  ...                '../server'])
+  ... 
+  ...     print("\n# LFS not enabled- revlogs don't have 0x2000 flag")
+  ...     runcommand(server, ['debugprocessors', 'nonlfs3.txt'])
+  ...     runcommand(server, ['config', 'extensions'])
+  
+  # LFS required- both lfs and non-lfs revlogs have 0x2000 flag
+  *** runcommand debugprocessors lfs.bin -R ../server
+  registered processor '0x8000'
+  registered processor '0x2000'
+  *** runcommand debugprocessors nonlfs2.txt -R ../server
+  registered processor '0x8000'
+  registered processor '0x2000'
+  *** runcommand config extensions --cwd ../server
+  extensions.debugprocessors=$TESTTMP/debugprocessors.py
+  extensions.lfs=
+  
+  # LFS not enabled- revlogs don't have 0x2000 flag
+  *** runcommand debugprocessors nonlfs3.txt
+  registered processor '0x8000'
+  *** runcommand config extensions
+  extensions.debugprocessors=$TESTTMP/debugprocessors.py
+
+  $ rm $HGRCPATH
+  $ mv $HGRCPATH.tmp $HGRCPATH
+
+  $ hg clone $TESTTMP/client $TESTTMP/nonlfs -qr 0 --config extensions.lfs=
+  $ cat >> $TESTTMP/nonlfs/.hg/hgrc <<EOF
+  > [extensions]
+  > lfs = !
+  > EOF
+
+  >>> from __future__ import absolute_import, print_function
+  >>> from hgclient import check, readchannel, runcommand
+  >>> @check
+  ... def checkflags2(server):
+  ...     readchannel(server)
+  ...     print('')
+  ...     print('# LFS enabled- both lfs and non-lfs revlogs have 0x2000 flag')
+  ...     runcommand(server, ['debugprocessors', 'lfs.bin', '-R',
+  ...                '../server'])
+  ...     runcommand(server, ['debugprocessors', 'nonlfs2.txt', '-R',
+  ...                '../server'])
+  ...     runcommand(server, ['config', 'extensions', '--cwd',
+  ...                '../server'])
+  ... 
+  ...     print('\n# LFS enabled without requirement- revlogs have 0x2000 flag')
+  ...     runcommand(server, ['debugprocessors', 'nonlfs3.txt'])
+  ...     runcommand(server, ['config', 'extensions'])
+  ... 
+  ...     print("\n# LFS disabled locally- revlogs don't have 0x2000 flag")
+  ...     runcommand(server, ['debugprocessors', 'nonlfs.txt', '-R',
+  ...                '../nonlfs'])
+  ...     runcommand(server, ['config', 'extensions', '--cwd',
+  ...                '../nonlfs'])
+  
+  # LFS enabled- both lfs and non-lfs revlogs have 0x2000 flag
+  *** runcommand debugprocessors lfs.bin -R ../server
+  registered processor '0x8000'
+  registered processor '0x2000'
+  *** runcommand debugprocessors nonlfs2.txt -R ../server
+  registered processor '0x8000'
+  registered processor '0x2000'
+  *** runcommand config extensions --cwd ../server
+  extensions.debugprocessors=$TESTTMP/debugprocessors.py
+  extensions.lfs=
+  
+  # LFS enabled without requirement- revlogs have 0x2000 flag
+  *** runcommand debugprocessors nonlfs3.txt
+  registered processor '0x8000'
+  registered processor '0x2000'
+  *** runcommand config extensions
+  extensions.debugprocessors=$TESTTMP/debugprocessors.py
+  extensions.lfs=
+  
+  # LFS disabled locally- revlogs don't have 0x2000 flag
+  *** runcommand debugprocessors nonlfs.txt -R ../nonlfs
+  registered processor '0x8000'
+  *** runcommand config extensions --cwd ../nonlfs
+  extensions.debugprocessors=$TESTTMP/debugprocessors.py
+  extensions.lfs=!
+
 --------------------------------------------------------------------------------
 Case #6: client with lfs content and the extension enabled; server with
 lfs content, and the extension enabled.