[PATCH 2 of 4 V2] extensions: list up only enabled extensions, if "ui" is specified

FUJIWARA Katsunori foozy at lares.dti.ne.jp
Sat Sep 29 06:28:46 CDT 2012


# HG changeset patch
# User FUJIWARA Katsunori <foozy at lares.dti.ne.jp>
# Date 1348917084 -32400
# Node ID b9c970b1cf86bb02a3126ab25d132eb589d71e69
# Parent  6ed7c5ea60696b1d553fa9ba7117fea74c19613b
extensions: list up only enabled extensions, if "ui" is specified

Before this patch, "extensions.extensions()" always lists up all
loaded extensions. So, commands handling multiple repositories at a
time like below enable extensions unexpectedly.

  - clone from or push to localhost: extensions enabled only in the
    source are enabled also in the destination

  - pull from localhost: extensions enabled only in the destination
    are enabled also in the source

  - recursive execution in subrepo tree: extensions enabled only in
    the parent or some of siblings in the tree are enabled also in
    others

In addition to it, extensions disabled locally may be enabled
unexpectedly.

This patch checks whether each of extensions should be listed up or
not, if "ui" is specified to "extensions.extensions()", and invokes
"reposetup()" of each extensions only for repositories enabling it.

diff -r 6ed7c5ea6069 -r b9c970b1cf86 mercurial/extensions.py
--- a/mercurial/extensions.py	Sat Sep 29 20:11:24 2012 +0900
+++ b/mercurial/extensions.py	Sat Sep 29 20:11:24 2012 +0900
@@ -13,10 +13,18 @@
 _order = []
 _ignore = ['hbisect', 'bookmarks', 'parentrevspec']
 
-def extensions():
+def extensions(ui=None):
+    if ui:
+        def enabled(name):
+            for format in ['%s', 'hgext.%s']:
+                conf = ui.config('extensions', format % name)
+                if conf is not None and not conf.startswith('!'):
+                    return True
+    else:
+        enabled = lambda name: True
     for name in _order:
         module = _extensions[name]
-        if module:
+        if module and enabled(name):
             yield name, module
 
 def find(name):
diff -r 6ed7c5ea6069 -r b9c970b1cf86 mercurial/hg.py
--- a/mercurial/hg.py	Sat Sep 29 20:11:24 2012 +0900
+++ b/mercurial/hg.py	Sat Sep 29 20:11:24 2012 +0900
@@ -93,7 +93,7 @@
     """return a repository object for the specified path"""
     obj = _peerlookup(path).instance(ui, path, create)
     ui = getattr(obj, "ui", ui)
-    for name, module in extensions.extensions():
+    for name, module in extensions.extensions(ui):
         hook = getattr(module, 'reposetup', None)
         if hook:
             hook(ui, obj)
diff -r 6ed7c5ea6069 -r b9c970b1cf86 tests/test-extension.t
--- a/tests/test-extension.t	Sat Sep 29 20:11:24 2012 +0900
+++ b/tests/test-extension.t	Sat Sep 29 20:11:24 2012 +0900
@@ -413,6 +413,7 @@
 
 Disabled extension commands:
 
+  $ ORGHGRCPATH=$HGRCPATH
   $ HGRCPATH=
   $ export HGRCPATH
   $ hg help email
@@ -559,3 +560,134 @@
   ** Python * (glob)
   ** Mercurial Distributed SCM (*) (glob)
   ** Extensions loaded: throw
+
+Restore HGRCPATH
+
+  $ HGRCPATH=$ORGHGRCPATH
+  $ export HGRCPATH
+
+Commands handling multiple repositories at a time should invoke only
+"reposetup()" of extensions enabling in the target repository.
+
+  $ mkdir reposetup-test
+  $ cd reposetup-test
+
+  $ cat > $TESTTMP/reposetuptest.py <<EOF
+  > from mercurial import extensions
+  > def reposetup(ui, repo):
+  >     ui.write('reposetup() for %s\n' % (repo.root))
+  > EOF
+  $ hg init src
+  $ echo a > src/a
+  $ hg -R src commit -Am '#0 at src/a'
+  adding a
+  $ echo '[extensions]' >> src/.hg/hgrc
+  $ echo '# enable extension locally' >> src/.hg/hgrc
+  $ echo "reposetuptest = $TESTTMP/reposetuptest.py" >> src/.hg/hgrc
+  $ hg -R src status
+  reposetup() for $TESTTMP/reposetup-test/src
+
+  $ hg clone -U src clone-dst1
+  reposetup() for $TESTTMP/reposetup-test/src
+  $ hg init push-dst1
+  $ hg -q -R src push push-dst1
+  reposetup() for $TESTTMP/reposetup-test/src
+  $ hg init pull-src1
+  $ hg -q -R pull-src1 pull src
+  reposetup() for $TESTTMP/reposetup-test/src
+
+  $ echo '[extensions]' >> $HGRCPATH
+  $ echo '# disable extension globally and explicitly' >> $HGRCPATH
+  $ echo 'reposetuptest = !' >> $HGRCPATH
+  $ hg clone -U src clone-dst2
+  reposetup() for $TESTTMP/reposetup-test/src
+  $ hg init push-dst2
+  $ hg -q -R src push push-dst2
+  reposetup() for $TESTTMP/reposetup-test/src
+  $ hg init pull-src2
+  $ hg -q -R pull-src2 pull src
+  reposetup() for $TESTTMP/reposetup-test/src
+
+  $ echo '[extensions]' >> $HGRCPATH
+  $ echo '# enable extension globally' >> $HGRCPATH
+  $ echo "reposetuptest = $TESTTMP/reposetuptest.py" >> $HGRCPATH
+  $ hg clone -U src clone-dst3
+  reposetup() for $TESTTMP/reposetup-test/src
+  reposetup() for $TESTTMP/reposetup-test/clone-dst3
+  $ hg init push-dst3
+  reposetup() for $TESTTMP/reposetup-test/push-dst3
+  $ hg -q -R src push push-dst3
+  reposetup() for $TESTTMP/reposetup-test/src
+  reposetup() for $TESTTMP/reposetup-test/push-dst3
+  $ hg init pull-src3
+  reposetup() for $TESTTMP/reposetup-test/pull-src3
+  $ hg -q -R pull-src3 pull src
+  reposetup() for $TESTTMP/reposetup-test/pull-src3
+  reposetup() for $TESTTMP/reposetup-test/src
+
+  $ echo '[extensions]' >> src/.hg/hgrc
+  $ echo '# disable extension locally' >> src/.hg/hgrc
+  $ echo 'reposetuptest = !' >> src/.hg/hgrc
+  $ hg clone -U src clone-dst4
+  reposetup() for $TESTTMP/reposetup-test/clone-dst4
+  $ hg init push-dst4
+  reposetup() for $TESTTMP/reposetup-test/push-dst4
+  $ hg -q -R src push push-dst4
+  reposetup() for $TESTTMP/reposetup-test/push-dst4
+  $ hg init pull-src4
+  reposetup() for $TESTTMP/reposetup-test/pull-src4
+  $ hg -q -R pull-src4 pull src
+  reposetup() for $TESTTMP/reposetup-test/pull-src4
+
+# disabling in command line overlays with all configuration
+  $ hg --config extensions.reposetuptest=! clone -U src clone-dst5
+  $ hg --config extensions.reposetuptest=! init push-dst5
+  $ hg --config extensions.reposetuptest=! -q -R src push push-dst5
+  $ hg --config extensions.reposetuptest=! init pull-src5
+  $ hg --config extensions.reposetuptest=! -q -R pull-src5 pull src
+
+  $ echo '[extensions]' >> $HGRCPATH
+  $ echo '# disable extension globally and explicitly' >> $HGRCPATH
+  $ echo 'reposetuptest = !' >> $HGRCPATH
+  $ hg init parent
+  $ hg init parent/sub1
+  $ echo 1 > parent/sub1/1
+  $ hg -R parent/sub1 commit -Am '#0 at parent/sub1'
+  adding 1
+  $ hg init parent/sub2
+  $ hg init parent/sub2/sub21
+  $ echo 21 > parent/sub2/sub21/21
+  $ hg -R parent/sub2/sub21 commit -Am '#0 at parent/sub2/sub21'
+  adding 21
+  $ cat > parent/sub2/.hgsub <<EOF
+  > sub21 = sub21
+  > EOF
+  $ hg -R parent/sub2 commit -Am '#0 at parent/sub2'
+  adding .hgsub
+  $ hg init parent/sub3
+  $ echo 3 > parent/sub3/3
+  $ hg -R parent/sub3 commit -Am '#0 at parent/sub3'
+  adding 3
+  $ cat > parent/.hgsub <<EOF
+  > sub1 = sub1
+  > sub2 = sub2
+  > sub3 = sub3
+  > EOF
+  $ hg -R parent commit -Am '#0 at parent'
+  adding .hgsub
+  $ echo '[extensions]' >> parent/.hg/hgrc
+  $ echo '# enable extension locally' >> parent/.hg/hgrc
+  $ echo "reposetuptest = $TESTTMP/reposetuptest.py" >> parent/.hg/hgrc
+  $ cp parent/.hg/hgrc parent/sub2/.hg/hgrc
+  $ hg -R parent status -S -A
+  reposetup() for $TESTTMP/reposetup-test/parent
+  reposetup() for $TESTTMP/reposetup-test/parent/sub2
+  C .hgsub
+  C .hgsubstate
+  C sub1/1
+  C sub2/.hgsub
+  C sub2/.hgsubstate
+  C sub2/sub21/21
+  C sub3/3
+
+  $ cd ..


More information about the Mercurial-devel mailing list