# HG changeset patch # User FUJIWARA Katsunori # Date 1451401110 -32400 # Node ID 42910f9fffeb7c717bc9fa9237c1782a13ef4ee8 # Parent 60bf90eb8bf89b113b3449849cc0b2bff4bd5e75 revset: use delayregistrar to register predicate in extension easily Previous patch introduced 'revset.predicate' decorator to register revset predicate function easily. But it shouldn't be used in extension directly, because it registers specified function immediately. Registration itself can't be restored, even if extension loading fails after that. Therefore, registration should be delayed until 'uisetup()' or so. This patch uses 'extpredicate' decorator derived from 'delayregistrar' to register predicate in extension easily. This patch also tests whether 'registrar.delayregistrar' avoids function registration if 'setup()' isn't invoked on it, because 'extpredicate' is the first user of it. diff -r 60bf90eb8bf8 -r 42910f9fffeb hgext/largefiles/overrides.py --- a/hgext/largefiles/overrides.py Tue Dec 29 23:58:30 2015 +0900 +++ b/hgext/largefiles/overrides.py Tue Dec 29 23:58:30 2015 +0900 @@ -812,9 +812,11 @@ ui.status(_("%d largefiles cached\n") % numcached) return result +revsetpredicate = revset.extpredicate() + +@revsetpredicate('pulled()') def pulledrevsetsymbol(repo, subset, x): - """``pulled()`` - Changesets that just has been pulled. + """Changesets that just has been pulled. Only available with largefiles from pull --lfrev expressions. diff -r 60bf90eb8bf8 -r 42910f9fffeb hgext/largefiles/uisetup.py --- a/hgext/largefiles/uisetup.py Tue Dec 29 23:58:30 2015 +0900 +++ b/hgext/largefiles/uisetup.py Tue Dec 29 23:58:30 2015 +0900 @@ -9,7 +9,7 @@ '''setup for largefiles extension: uisetup''' from mercurial import archival, cmdutil, commands, extensions, filemerge, hg, \ - httppeer, merge, scmutil, sshpeer, wireproto, revset, subrepo, copies + httppeer, merge, scmutil, sshpeer, wireproto, subrepo, copies from mercurial.i18n import _ from mercurial.hgweb import hgweb_mod, webcommands @@ -83,7 +83,6 @@ ('', 'lfrev', [], _('download largefiles for these revisions'), _('REV'))] entry[1].extend(pullopt) - revset.symbols['pulled'] = overrides.pulledrevsetsymbol entry = extensions.wrapcommand(commands.table, 'clone', overrides.overrideclone) @@ -170,3 +169,5 @@ if name == 'transplant': extensions.wrapcommand(getattr(module, 'cmdtable'), 'transplant', overrides.overridetransplant) + + overrides.revsetpredicate.setup() diff -r 60bf90eb8bf8 -r 42910f9fffeb hgext/mq.py --- a/hgext/mq.py Tue Dec 29 23:58:30 2015 +0900 +++ b/hgext/mq.py Tue Dec 29 23:58:30 2015 +0900 @@ -3558,9 +3558,11 @@ # i18n: column positioning for "hg summary" ui.note(_("mq: (empty queue)\n")) +revsetpredicate = revset.extpredicate() + +@revsetpredicate('mq()') def revsetmq(repo, subset, x): - """``mq()`` - Changesets managed by MQ. + """Changesets managed by MQ. """ revset.getargs(x, 0, 0, _("mq takes no arguments")) applied = set([repo[r.node].rev() for r in repo.mq.applied]) @@ -3596,7 +3598,7 @@ if extmodule.__file__ != __file__: dotable(getattr(extmodule, 'cmdtable', {})) - revset.symbols['mq'] = revsetmq + revsetpredicate.setup() colortable = {'qguard.negative': 'red', 'qguard.positive': 'yellow', diff -r 60bf90eb8bf8 -r 42910f9fffeb hgext/rebase.py --- a/hgext/rebase.py Tue Dec 29 23:58:30 2015 +0900 +++ b/hgext/rebase.py Tue Dec 29 23:58:30 2015 +0900 @@ -64,6 +64,9 @@ branch = repo[None].branch() return repo[branch].rev() +revsetpredicate = revset.extpredicate() + +@revsetpredicate('_destrebase') def _revsetdestrebase(repo, subset, x): # ``_rebasedefaultdest()`` @@ -1238,4 +1241,4 @@ _("use 'hg rebase --continue' or 'hg rebase --abort'")]) # ensure rebased rev are not hidden extensions.wrapfunction(repoview, '_getdynamicblockers', _rebasedvisible) - revset.symbols['_destrebase'] = _revsetdestrebase + revsetpredicate.setup() diff -r 60bf90eb8bf8 -r 42910f9fffeb hgext/transplant.py --- a/hgext/transplant.py Tue Dec 29 23:58:30 2015 +0900 +++ b/hgext/transplant.py Tue Dec 29 23:58:30 2015 +0900 @@ -693,9 +693,11 @@ if cleanupfn: cleanupfn() +revsetpredicate = revset.extpredicate() + +@revsetpredicate('transplanted([set])') def revsettransplanted(repo, subset, x): - """``transplanted([set])`` - Transplanted changesets in set, or all transplanted changesets. + """Transplanted changesets in set, or all transplanted changesets. """ if x: s = revset.getset(repo, subset, x) @@ -711,7 +713,7 @@ return n and revlog.hex(n) or '' def extsetup(ui): - revset.symbols['transplanted'] = revsettransplanted + revsetpredicate.setup() templatekw.keywords['transplanted'] = kwtransplanted cmdutil.unfinishedstates.append( ['series', True, False, _('transplant in progress'), diff -r 60bf90eb8bf8 -r 42910f9fffeb mercurial/revset.py --- a/mercurial/revset.py Tue Dec 29 23:58:30 2015 +0900 +++ b/mercurial/revset.py Tue Dec 29 23:58:30 2015 +0900 @@ -487,11 +487,36 @@ The first string argument of the constructor is used also in online help. + + Use 'extpredicate' instead of this to register revset predicate in + extensions. """ table = symbols formatdoc = "``%s``\n %s" getname = registrar.funcregistrar.parsefuncdecl +class extpredicate(registrar.delayregistrar): + """Decorator to register revset predicate in extensions + + Usage:: + + revsetpredicate = revset.extpredicate() + + @revsetpredicate('mypredicate(arg1, arg2[, arg3])') + def mypredicatefunc(repo, subset, x): + '''Explanation of this revset predicate .... + ''' + pass + + def uisetup(ui): + revsetpredicate.setup() + + 'revsetpredicate' instance above can be used to decorate multiple + functions, and 'setup()' on it registers all such functions at + once. + """ + registrar = predicate + @predicate('_destupdate') def _destupdate(repo, subset, x): # experimental revset for update destination diff -r 60bf90eb8bf8 -r 42910f9fffeb tests/test-revset.t --- a/tests/test-revset.t Tue Dec 29 23:58:30 2015 +0900 +++ b/tests/test-revset.t Tue Dec 29 23:58:30 2015 +0900 @@ -2189,3 +2189,43 @@ [255] $ cd .. + +Test registrar.delayregistrar via revset.extpredicate + +'extpredicate' decorator shouldn't register any functions until +'setup()' on it. + + $ cd repo + + $ cat < $TESTTMP/custompredicate.py + > from mercurial import revset + > + > revsetpredicate = revset.extpredicate() + > + > @revsetpredicate('custom1()') + > def custom1(repo, subset, x): + > return revset.baseset([1]) + > @revsetpredicate('custom2()') + > def custom2(repo, subset, x): + > return revset.baseset([2]) + > + > def uisetup(ui): + > if ui.configbool('custompredicate', 'enabled'): + > revsetpredicate.setup() + > EOF + $ cat < .hg/hgrc + > [extensions] + > custompredicate = $TESTTMP/custompredicate.py + > EOF + + $ hg debugrevspec "custom1()" + hg: parse error: unknown identifier: custom1 + [255] + $ hg debugrevspec "custom2()" + hg: parse error: unknown identifier: custom2 + [255] + $ hg debugrevspec "custom1() or custom2()" --config custompredicate.enabled=true + 1 + 2 + + $ cd ..