[PATCH] hgweb: support directory and subrepository navigation when descend mode is disabled
Matt Mackall
mpm at selenic.com
Sun Jan 29 19:25:38 UTC 2012
On Sun, 2012-01-29 at 20:03 +0100, Paul Boddie wrote:
> # HG changeset patch
> # User Paul Boddie <paul at boddie.org.uk>
> # Date 1327863292 -3600
> # Branch stable
> # Node ID 967d0f22ee70762029beb539e15daf97b36ace86
> # Parent f8955a7f82e6a06a682cd95631fd1c5e55f46103
> hgweb: support directory and subrepository navigation when descend mode is disabled
a) it's not clear that this won't be a security surprise to existing
users
b) we're in the middle of the 2.1 code freeze, please resend after Feb 1
for discussion
> diff -r f8955a7f82e6 -r 967d0f22ee70 mercurial/hgweb/hgwebdir_mod.py
> --- a/mercurial/hgweb/hgwebdir_mod.py Fri Jan 27 03:00:32 2012 +0100
> +++ b/mercurial/hgweb/hgwebdir_mod.py Sun Jan 29 19:54:52 2012 +0100
> @@ -245,12 +245,61 @@
> def rawentries(subdir="", **map):
>
> descend = self.ui.configbool('web', 'descend', True)
> + seenrepos = set()
> + seendirs = set()
> for name, path in self.repos:
>
> if not name.startswith(subdir):
> continue
> name = name[len(subdir):]
> + directory = False
> +
> if not descend and '/' in name:
> + nameparts = name.split('/')
> + rootname = nameparts[0]
> +
> + if rootname in seendirs:
> + continue
> + elif rootname in seenrepos:
> + pass
> + else:
> + directory = True
> + name = rootname
> +
> + # redefine the path to refer to the directory
> + discarded = '/'.join(nameparts[1:])
> +
> + # remove name parts plus accompanying slash
> + path = path[:-len(discarded) - 1]
> +
> + parts = [name]
> + if 'PATH_INFO' in req.env:
> + parts.insert(0, req.env['PATH_INFO'].rstrip('/'))
> + if req.env['SCRIPT_NAME']:
> + parts.insert(0, req.env['SCRIPT_NAME'])
> + url = re.sub(r'/+', '/', '/'.join(parts) + '/')
> +
> + # show either a directory entry or a repository
> + if directory:
> + # get the directory's time information
> + try:
> + d = (get_mtime(path), util.makedate()[1])
> + except OSError:
> + continue
> +
> + row = dict(contact="",
> + contact_sort="",
> + name=name,
> + name_sort=name,
> + url=url,
> + description="",
> + description_sort="",
> + lastchange=d,
> + lastchange_sort=d[1]-d[0],
> + archives=[])
> +
> + seendirs.add(name)
> + yield row
> continue
>
> u = self.ui.copy()
> @@ -267,13 +316,6 @@
>
> if not self.read_allowed(u, req):
> continue
> -
> - parts = [name]
> - if 'PATH_INFO' in req.env:
> - parts.insert(0, req.env['PATH_INFO'].rstrip('/'))
> - if req.env['SCRIPT_NAME']:
> - parts.insert(0, req.env['SCRIPT_NAME'])
> - url = re.sub(r'/+', '/', '/'.join(parts) + '/')
>
> # update time with local timezone
> try:
> @@ -302,6 +344,8 @@
> lastchange=d,
> lastchange_sort=d[1]-d[0],
> archives=archivelist(u, "tip", url))
> +
> + seenrepos.add(name)
> yield row
>
> sortdefault = None, False
> diff -r f8955a7f82e6 -r 967d0f22ee70 tests/test-hgwebdir.t
> --- a/tests/test-hgwebdir.t Fri Jan 27 03:00:32 2012 +0100
> +++ b/tests/test-hgwebdir.t Sun Jan 29 19:54:52 2012 +0100
> @@ -30,6 +30,28 @@
> $ echo c > c/c
> $ hg --cwd c ci -Amc -d'3 0'
> adding c
> +
> +create a subdirectory containing repositories and subrepositories
> +
> + $ mkdir notrepo
> + $ cd notrepo
> + $ hg init e
> + $ echo e > e/e
> + $ hg --cwd e ci -Ame -d'4 0'
> + adding e
> + $ hg init e/e2
> + $ echo e2 > e/e2/e2
> + $ hg --cwd e/e2 ci -Ame2 -d '4 0'
> + adding e2
> + $ hg init f
> + $ echo f > f/f
> + $ hg --cwd f ci -Amf -d'4 0'
> + adding f
> + $ hg init f/f2
> + $ echo f2 > f/f2/f2
> + $ hg --cwd f/f2 ci -Amf2 -d '4 0'
> + adding f2
> + $ cd ..
>
> create repository without .hg/store
>
> @@ -119,20 +141,32 @@
> /coll/a/.hg/patches/
> /coll/b/
> /coll/c/
> + /coll/notrepo/e/
> + /coll/notrepo/f/
> /rcoll/a/
> /rcoll/a/.hg/patches/
> /rcoll/b/
> /rcoll/b/d/
> /rcoll/c/
> + /rcoll/notrepo/e/
> + /rcoll/notrepo/e/e2/
> + /rcoll/notrepo/f/
> + /rcoll/notrepo/f/f2/
> /star/webdir/a/
> /star/webdir/a/.hg/patches/
> /star/webdir/b/
> /star/webdir/c/
> + /star/webdir/notrepo/e/
> + /star/webdir/notrepo/f/
> /starstar/webdir/a/
> /starstar/webdir/a/.hg/patches/
> /starstar/webdir/b/
> /starstar/webdir/b/d/
> /starstar/webdir/c/
> + /starstar/webdir/notrepo/e/
> + /starstar/webdir/notrepo/e/e2/
> + /starstar/webdir/notrepo/f/
> + /starstar/webdir/notrepo/f/f2/
> /astar/
> /astar/.hg/patches/
>
> @@ -217,6 +251,22 @@
> </tr>
>
> <tr class="parity0">
> + <td><a href="/coll/notrepo/e/?style=paper">coll/notrepo/e</a></td>
> + <td>unknown</td>
> + <td>Foo Bar <foo.bar@example.com></td>
> + <td class="age">*</td> (glob)
> + <td class="indexlinks"></td>
> + </tr>
> +
> + <tr class="parity1">
> + <td><a href="/coll/notrepo/f/?style=paper">coll/notrepo/f</a></td>
> + <td>unknown</td>
> + <td>Foo Bar <foo.bar@example.com></td>
> + <td class="age">*</td> (glob)
> + <td class="indexlinks"></td>
> + </tr>
> +
> + <tr class="parity0">
> <td><a href="/rcoll/a/?style=paper">rcoll/a</a></td>
> <td>unknown</td>
> <td>Foo Bar <foo.bar@example.com></td>
> @@ -257,6 +307,38 @@
> </tr>
>
> <tr class="parity1">
> + <td><a href="/rcoll/notrepo/e/?style=paper">rcoll/notrepo/e</a></td>
> + <td>unknown</td>
> + <td>Foo Bar <foo.bar@example.com></td>
> + <td class="age">*</td> (glob)
> + <td class="indexlinks"></td>
> + </tr>
> +
> + <tr class="parity0">
> + <td><a href="/rcoll/notrepo/e/e2/?style=paper">rcoll/notrepo/e/e2</a></td>
> + <td>unknown</td>
> + <td>Foo Bar <foo.bar@example.com></td>
> + <td class="age">*</td> (glob)
> + <td class="indexlinks"></td>
> + </tr>
> +
> + <tr class="parity1">
> + <td><a href="/rcoll/notrepo/f/?style=paper">rcoll/notrepo/f</a></td>
> + <td>unknown</td>
> + <td>Foo Bar <foo.bar@example.com></td>
> + <td class="age">*</td> (glob)
> + <td class="indexlinks"></td>
> + </tr>
> +
> + <tr class="parity0">
> + <td><a href="/rcoll/notrepo/f/f2/?style=paper">rcoll/notrepo/f/f2</a></td>
> + <td>unknown</td>
> + <td>Foo Bar <foo.bar@example.com></td>
> + <td class="age">*</td> (glob)
> + <td class="indexlinks"></td>
> + </tr>
> +
> + <tr class="parity1">
> <td><a href="/star/webdir/a/?style=paper">star/webdir/a</a></td>
> <td>unknown</td>
> <td>Foo Bar <foo.bar@example.com></td>
> @@ -282,6 +364,22 @@
>
> <tr class="parity0">
> <td><a href="/star/webdir/c/?style=paper">star/webdir/c</a></td>
> + <td>unknown</td>
> + <td>Foo Bar <foo.bar@example.com></td>
> + <td class="age">*</td> (glob)
> + <td class="indexlinks"></td>
> + </tr>
> +
> + <tr class="parity1">
> + <td><a href="/star/webdir/notrepo/e/?style=paper">star/webdir/notrepo/e</a></td>
> + <td>unknown</td>
> + <td>Foo Bar <foo.bar@example.com></td>
> + <td class="age">*</td> (glob)
> + <td class="indexlinks"></td>
> + </tr>
> +
> + <tr class="parity0">
> + <td><a href="/star/webdir/notrepo/f/?style=paper">star/webdir/notrepo/f</a></td>
> <td>unknown</td>
> <td>Foo Bar <foo.bar@example.com></td>
> <td class="age">*</td> (glob)
> @@ -322,6 +420,38 @@
>
> <tr class="parity1">
> <td><a href="/starstar/webdir/c/?style=paper">starstar/webdir/c</a></td>
> + <td>unknown</td>
> + <td>Foo Bar <foo.bar@example.com></td>
> + <td class="age">*</td> (glob)
> + <td class="indexlinks"></td>
> + </tr>
> +
> + <tr class="parity0">
> + <td><a href="/starstar/webdir/notrepo/e/?style=paper">starstar/webdir/notrepo/e</a></td>
> + <td>unknown</td>
> + <td>Foo Bar <foo.bar@example.com></td>
> + <td class="age">*</td> (glob)
> + <td class="indexlinks"></td>
> + </tr>
> +
> + <tr class="parity1">
> + <td><a href="/starstar/webdir/notrepo/e/e2/?style=paper">starstar/webdir/notrepo/e/e2</a></td>
> + <td>unknown</td>
> + <td>Foo Bar <foo.bar@example.com></td>
> + <td class="age">*</td> (glob)
> + <td class="indexlinks"></td>
> + </tr>
> +
> + <tr class="parity0">
> + <td><a href="/starstar/webdir/notrepo/f/?style=paper">starstar/webdir/notrepo/f</a></td>
> + <td>unknown</td>
> + <td>Foo Bar <foo.bar@example.com></td>
> + <td class="age">*</td> (glob)
> + <td class="indexlinks"></td>
> + </tr>
> +
> + <tr class="parity1">
> + <td><a href="/starstar/webdir/notrepo/f/f2/?style=paper">starstar/webdir/notrepo/f/f2</a></td>
> <td>unknown</td>
> <td>Foo Bar <foo.bar@example.com></td>
> <td class="age">*</td> (glob)
> @@ -489,6 +619,8 @@
> /coll/a/.hg/patches/
> /coll/b/
> /coll/c/
> + /coll/notrepo/e/
> + /coll/notrepo/f/
>
> $ "$TESTDIR/get-with-headers.py" localhost:$HGPORT1 '/coll/a/file/tip/a?style=raw'
> 200 Script output follows
> @@ -506,11 +638,63 @@
> /rcoll/b/
> /rcoll/b/d/
> /rcoll/c/
> + /rcoll/notrepo/e/
> + /rcoll/notrepo/e/e2/
> + /rcoll/notrepo/f/
> + /rcoll/notrepo/f/f2/
>
> $ "$TESTDIR/get-with-headers.py" localhost:$HGPORT1 '/rcoll/b/d/file/tip/d?style=raw'
> 200 Script output follows
>
> d
> +
> +Test descend = False
> +
> + $ "$TESTDIR/killdaemons.py"
> + $ cat >> paths.conf <<EOF
> + > [web]
> + > descend=false
> + > EOF
> + $ hg serve -p $HGPORT1 -d --pid-file=hg.pid --webdir-conf paths.conf \
> + > -A access-paths.log -E error-paths-3.log
> + $ cat hg.pid >> $DAEMON_PIDS
> + $ "$TESTDIR/get-with-headers.py" localhost:$HGPORT1 '/rcoll/?style=raw'
> + 200 Script output follows
> +
> +
> + /rcoll/a/
> + /rcoll/a/.hg/patches/
> + /rcoll/b/
> + /rcoll/b/d/
> + /rcoll/c/
> + /rcoll/notrepo/
> +
> +
> +Test intermediate directories
> +
> + $ "$TESTDIR/get-with-headers.py" localhost:$HGPORT1 '/rcoll/notrepo/?style=raw'
> + 200 Script output follows
> +
> +
> + /rcoll/notrepo/e/
> + /rcoll/notrepo/e/e2/
> + /rcoll/notrepo/f/
> + /rcoll/notrepo/f/f2/
> +
> +
> +Test repositories inside intermediate directories
> +
> + $ "$TESTDIR/get-with-headers.py" localhost:$HGPORT1 '/rcoll/notrepo/e/file/tip/e?style=raw'
> + 200 Script output follows
> +
> + e
> +
> +Test subrepositories inside intermediate directories
> +
> + $ "$TESTDIR/get-with-headers.py" localhost:$HGPORT1 '/rcoll/notrepo/f/f2/file/tip/f2?style=raw'
> + 200 Script output follows
> +
> + f2
>
> Test [paths] '*' in a repo root
>
> @@ -536,6 +720,7 @@
> 200 Script output follows
>
>
> + /t/
> /c/
>
> $ "$TESTDIR/get-with-headers.py" localhost:$HGPORT1 '/t/?style=raw'
> @@ -617,6 +802,8 @@
> /a/.hg/patches/
> /b/
> /c/
> + /notrepo/e/
> + /notrepo/f/
>
> $ "$TESTDIR/get-with-headers.py" localhost:$HGPORT2 '/a/file/tip/a?style=raw'
> 200 Script output follows
> _______________________________________________
> Mercurial-devel mailing list
> Mercurial-devel at selenic.com
> http://selenic.com/mailman/listinfo/mercurial-devel
--
Mathematics is the supreme nostalgia of our time.
More information about the Mercurial-devel
mailing list