hgweb: recurse down collections only if ** in [paths]
authorBenoit Allard <benoit@aeteurope.nl>
Thu, 18 Dec 2008 22:32:48 +0100
changeset 7523 e60aaae83323
parent 7522 2f4a399a8787
child 7524 7fc19b12cb6b
child 7535 9a962209dc28
hgweb: recurse down collections only if ** in [paths] collections: direct child repos only paths *: direct child repos only (like collections) paths **: recursive discovery When ** is used, the mq repository (if any) is also shown.
hgwebdir.cgi
mercurial/hgweb/hgwebdir_mod.py
mercurial/util.py
tests/test-hgwebdir
tests/test-hgwebdir.out
--- a/hgwebdir.cgi	Mon Dec 15 12:02:18 2008 -0800
+++ b/hgwebdir.cgi	Thu Dec 18 22:32:48 2008 +0100
@@ -32,6 +32,7 @@
 # virtual/path2 = /real/path2
 # virtual/root = /real/root/*
 # / = /real/root2/*
+# virtual/root2 = /real/root2/**
 #
 # [collections]
 # /prefix/to/strip/off = /root/of/tree/full/of/repos
@@ -41,15 +42,18 @@
 # * First two lines mount one repository into one virtual path, like
 # '/real/path1' into 'virtual/path1'.
 #
-# * The third entry tells every mercurial repository found in
-# '/real/root', recursively, should be mounted in 'virtual/root'. This
-# format is preferred over the [collections] one, using absolute paths
-# as configuration keys is not supported on every platform (including
-# Windows).
+# * The third entry mounts every mercurial repository found in '/real/root'
+# in 'virtual/root'. This format is preferred over the [collections] one,
+# since using absolute paths as configuration keys is not support on every
+# platform (especially on Windows).
 #
-# * The last entry is a special case mounting all repositories in
+# * The fourth entry is a special case mounting all repositories in
 # /'real/root2' in the root of the virtual directory.
 #
+# * The fifth entry recursively finds all repositories under the real root,
+# and mounts them using their relative path (to given real root) under the
+# virtual root.
+#
 # collections example: say directory tree /foo contains repos /foo/bar,
 # /foo/quux/baz.  Give this config section:
 #   [collections]
--- a/mercurial/hgweb/hgwebdir_mod.py	Mon Dec 15 12:02:18 2008 -0800
+++ b/mercurial/hgweb/hgwebdir_mod.py	Thu Dec 18 22:32:48 2008 +0100
@@ -54,13 +54,18 @@
                 paths = cleannames(cp.items('paths'))
                 for prefix, root in paths:
                     roothead, roottail = os.path.split(root)
-                    if roottail != '*':
+                    # "foo = /bar/*" makes every subrepo of /bar/ to be
+                    # mounted as foo/subrepo
+                    # and "foo = /bar/**" does even recurse inside the
+                    # subdirectories, remember to use it without working dir.
+                    try:
+                        recurse = {'*': False, '**': True}[roottail]
+                    except KeyError:
                         self.repos.append((prefix, root))
                         continue
-                    # "foo = /bar/*" makes every subrepo of /bar/ to be
-                    # mounted as foo/subrepo
                     roothead = os.path.normpath(roothead)
-                    for path in util.walkrepos(roothead, followsym=True):
+                    for path in util.walkrepos(roothead, followsym=True,
+                                               recurse=recurse):
                         path = os.path.normpath(path)
                         name = util.pconvert(path[len(roothead):]).strip('/')
                         if prefix:
--- a/mercurial/util.py	Mon Dec 15 12:02:18 2008 -0800
+++ b/mercurial/util.py	Thu Dec 18 22:32:48 2008 +0100
@@ -1876,7 +1876,7 @@
     else:
         return "%s..." % (text[:maxlength-3])
 
-def walkrepos(path, followsym=False, seen_dirs=None):
+def walkrepos(path, followsym=False, seen_dirs=None, recurse=False):
     '''yield every hg repository under path, recursively.'''
     def errhandler(err):
         if err.filename == path:
@@ -1901,11 +1901,16 @@
         _add_dir_if_not_there(seen_dirs, path)
     for root, dirs, files in os.walk(path, topdown=True, onerror=errhandler):
         if '.hg' in dirs:
-            dirs[:] = [] # don't descend further
             yield root # found a repository
-            qroot = os.path.join(root, '.hg', 'patches')
-            if os.path.isdir(os.path.join(qroot, '.hg')):
-                yield qroot # we have a patch queue repo here
+            if recurse:
+                # avoid recursing inside the .hg directory
+                # the mq repository is added in any case
+                dirs.remove('.hg')
+                qroot = os.path.join(root, '.hg', 'patches')
+                if os.path.isdir(os.path.join(qroot, '.hg')):
+                    yield qroot # we have a patch queue repo here
+            else:
+                dirs[:] = [] # don't descend further
         elif followsym:
             newdirs = []
             for d in dirs:
--- a/tests/test-hgwebdir	Mon Dec 15 12:02:18 2008 -0800
+++ b/tests/test-hgwebdir	Thu Dec 18 22:32:48 2008 +0100
@@ -8,16 +8,25 @@
 hg init a
 echo a > a/a
 hg --cwd a ci -Ama -d'1 0'
+# create a mercurial queue repository
+hg --cwd a qinit --config extensions.hgext.mq= -c
 
 hg init b
 echo b > b/b
 hg --cwd b ci -Amb -d'2 0'
 
+# create a nested repository
+cd b
+hg init d
+echo d > d/d
+hg --cwd d ci -Amd -d'3 0'
+cd ..
+
 hg init c
 echo c > c/c
 hg --cwd c ci -Amc -d'3 0'
+
 root=`pwd`
-
 cd ..
 
 cat > paths.conf <<EOF
@@ -46,6 +55,7 @@
 t/a/=$root/a
 b=$root/b
 coll=$root/*
+rcoll=$root/**
 EOF
 
 hg serve -p $HGPORT1 -d --pid-file=hg.pid --webdir-conf paths.conf \
@@ -64,6 +74,10 @@
 # Test [paths] '*' extension
 "$TESTDIR/get-with-headers.py" localhost:$HGPORT1 '/coll/?style=raw'
 "$TESTDIR/get-with-headers.py" localhost:$HGPORT1 '/coll/a/file/tip/a?style=raw'
+#test [paths] '**' extension
+"$TESTDIR/get-with-headers.py" localhost:$HGPORT1 '/rcoll/?style=raw'
+"$TESTDIR/get-with-headers.py" localhost:$HGPORT1 '/rcoll/b/d/file/tip/d?style=raw'
+
 
 cat > collections.conf <<EOF
 [collections]
@@ -74,7 +88,7 @@
     -A access-collections.log -E error-collections.log
 cat hg.pid >> $DAEMON_PIDS
 
-echo % should succeed
+echo % collections: should succeed
 "$TESTDIR/get-with-headers.py" localhost:$HGPORT2 '/?style=raw'
 "$TESTDIR/get-with-headers.py" localhost:$HGPORT2 '/a/file/tip/a?style=raw'
 "$TESTDIR/get-with-headers.py" localhost:$HGPORT2 '/b/file/tip/b?style=raw'
--- a/tests/test-hgwebdir.out	Mon Dec 15 12:02:18 2008 -0800
+++ b/tests/test-hgwebdir.out	Thu Dec 18 22:32:48 2008 +0100
@@ -1,5 +1,6 @@
 adding a
 adding b
+adding d
 adding c
 % should give a 404 - file does not exist
 404 Not Found
@@ -32,6 +33,11 @@
 /coll/a/
 /coll/b/
 /coll/c/
+/rcoll/a/
+/rcoll/a/.hg/patches/
+/rcoll/b/
+/rcoll/b/d/
+/rcoll/c/
 /t/a/
 
 200 Script output follows
@@ -115,7 +121,19 @@
 200 Script output follows
 
 a
-% should succeed
+200 Script output follows
+
+
+/rcoll/a/
+/rcoll/a/.hg/patches/
+/rcoll/b/
+/rcoll/b/d/
+/rcoll/c/
+
+200 Script output follows
+
+d
+% collections: should succeed
 200 Script output follows