Patchwork [V2] hgwebdir: add support for explicit index files

login
register
mail settings
Submitter Matt Harbison
Date March 15, 2017, 3:26 a.m.
Message ID <d24cb60edbc782ea1ee4.1489548400@Envy>
Download mbox | patch
Permalink /patch/19345/
State Accepted
Headers show

Comments

Matt Harbison - March 15, 2017, 3:26 a.m.
# HG changeset patch
# User Matt Harbison <matt_harbison@yahoo.com>
# Date 1488770552 18000
#      Sun Mar 05 22:22:32 2017 -0500
# Node ID d24cb60edbc782ea1ee4f5625accc83f9ec3e3ca
# Parent  1c48a8278b2f015fca607dfc652823560a5ac580
hgwebdir: add support for explicit index files

This is useful for when repositories are nested in --web-conf, and in the future
with hosted subrepositories.  The previous behavior was only to render an index
at each virtual directory.  There is now an explicit 'index' child for each
virtual directory.  The name was suggested by Yuya, for consistency with the
other method names.

Additionally, there is now an explicit 'index' child for every repository
directory with a nested repository somewhere below it.  This seems more
consistent with each virtual directory hosting an index, and more discoverable
than to only have an index for a directory that directly hosts a nested
repository.  I couldn't figure out how to close the loop and provide one in each
directory without a deeper nested repository, without blocking a committed
'index' file.  Keeping that seems better than rendering an empty index.
Yuya Nishihara - March 18, 2017, 6:51 a.m.
On Tue, 14 Mar 2017 23:26:40 -0400, Matt Harbison wrote:
> # HG changeset patch
> # User Matt Harbison <matt_harbison@yahoo.com>
> # Date 1488770552 18000
> #      Sun Mar 05 22:22:32 2017 -0500
> # Node ID d24cb60edbc782ea1ee4f5625accc83f9ec3e3ca
> # Parent  1c48a8278b2f015fca607dfc652823560a5ac580
> hgwebdir: add support for explicit index files

LGTM. Queued this, thanks.

Patch

diff --git a/mercurial/hgweb/hgwebdir_mod.py b/mercurial/hgweb/hgwebdir_mod.py
--- a/mercurial/hgweb/hgwebdir_mod.py
+++ b/mercurial/hgweb/hgwebdir_mod.py
@@ -254,13 +254,21 @@ 
                 return []
 
             # top-level index
-            elif not virtual:
+
+            repos = dict(self.repos)
+
+            if not virtual or (virtual == 'index' and virtual not in repos):
                 req.respond(HTTP_OK, ctype)
                 return self.makeindex(req, tmpl)
 
             # nested indexes and hgwebs
 
-            repos = dict(self.repos)
+            if virtual.endswith('/index') and virtual not in repos:
+                subdir = virtual[:-len('index')]
+                if any(r.startswith(subdir) for r in repos):
+                    req.respond(HTTP_OK, ctype)
+                    return self.makeindex(req, tmpl, subdir)
+
             virtualrepo = virtual
             while virtualrepo:
                 real = repos.get(virtualrepo)
@@ -352,8 +360,7 @@ 
                             pass
 
                 parts = [name]
-                if 'PATH_INFO' in req.env:
-                    parts.insert(0, req.env['PATH_INFO'].rstrip('/'))
+                parts.insert(0, '/' + subdir.rstrip('/'))
                 if req.env['SCRIPT_NAME']:
                     parts.insert(0, req.env['SCRIPT_NAME'])
                 url = re.sub(r'/+', '/', '/'.join(parts) + '/')
diff --git a/tests/test-hgwebdir.t b/tests/test-hgwebdir.t
--- a/tests/test-hgwebdir.t
+++ b/tests/test-hgwebdir.t
@@ -1566,6 +1566,119 @@ 
   /b/
   /c/
   
+  $ killdaemons.py
+  $ cat > paths.conf << EOF
+  > [paths]
+  > /dir1/a_repo = $root/a
+  > /dir1/a_repo/b_repo = $root/b
+  > /dir1/dir2/index = $root/b
+  > EOF
+  $ hg serve -p $HGPORT1 -d --pid-file hg.pid --webdir-conf paths.conf
+  $ cat hg.pid >> $DAEMON_PIDS
+
+  $ echo 'index file' > $root/a/index
+  $ hg --cwd $root/a ci -Am 'add index file'
+  adding index
+
+  $ get-with-headers.py localhost:$HGPORT1 '' | grep 'a_repo'
+  <td><a href="/dir1/a_repo/">dir1/a_repo</a></td>
+  <a href="/dir1/a_repo/atom-log" title="subscribe to repository atom feed">
+  <td><a href="/dir1/a_repo/b_repo/">dir1/a_repo/b_repo</a></td>
+  <a href="/dir1/a_repo/b_repo/atom-log" title="subscribe to repository atom feed">
+
+  $ get-with-headers.py localhost:$HGPORT1 'index' | grep 'a_repo'
+  <td><a href="/dir1/a_repo/">dir1/a_repo</a></td>
+  <a href="/dir1/a_repo/atom-log" title="subscribe to repository atom feed">
+  <td><a href="/dir1/a_repo/b_repo/">dir1/a_repo/b_repo</a></td>
+  <a href="/dir1/a_repo/b_repo/atom-log" title="subscribe to repository atom feed">
+
+  $ get-with-headers.py localhost:$HGPORT1 'dir1' | grep 'a_repo'
+  <td><a href="/dir1/a_repo/">a_repo</a></td>
+  <a href="/dir1/a_repo/atom-log" title="subscribe to repository atom feed">
+  <td><a href="/dir1/a_repo/b_repo/">a_repo/b_repo</a></td>
+  <a href="/dir1/a_repo/b_repo/atom-log" title="subscribe to repository atom feed">
+
+  $ get-with-headers.py localhost:$HGPORT1 'dir1/index' | grep 'a_repo'
+  <td><a href="/dir1/a_repo/">a_repo</a></td>
+  <a href="/dir1/a_repo/atom-log" title="subscribe to repository atom feed">
+  <td><a href="/dir1/a_repo/b_repo/">a_repo/b_repo</a></td>
+  <a href="/dir1/a_repo/b_repo/atom-log" title="subscribe to repository atom feed">
+
+  $ get-with-headers.py localhost:$HGPORT1 'dir1/a_repo' | grep 'a_repo'
+  <link rel="icon" href="/dir1/a_repo/static/hgicon.png" type="image/png" />
+  <link rel="stylesheet" href="/dir1/a_repo/static/style-paper.css" type="text/css" />
+  <script type="text/javascript" src="/dir1/a_repo/static/mercurial.js"></script>
+  <title>dir1/a_repo: log</title>
+     href="/dir1/a_repo/atom-log" title="Atom feed for dir1/a_repo" />
+     href="/dir1/a_repo/rss-log" title="RSS feed for dir1/a_repo" />
+  <img src="/dir1/a_repo/static/hglogo.png" alt="mercurial" /></a>
+  <li><a href="/dir1/a_repo/graph/tip">graph</a></li>
+  <li><a href="/dir1/a_repo/tags">tags</a></li>
+  <li><a href="/dir1/a_repo/bookmarks">bookmarks</a></li>
+  <li><a href="/dir1/a_repo/branches">branches</a></li>
+  <li><a href="/dir1/a_repo/rev/tip">changeset</a></li>
+  <li><a href="/dir1/a_repo/file/tip">browse</a></li>
+   <li><a href="/dir1/a_repo/help">help</a></li>
+  <a href="/dir1/a_repo/atom-log" title="subscribe to atom feed">
+  <img class="atom-logo" src="/dir1/a_repo/static/feed-icon-14x14.png" alt="atom feed" />
+  <h2 class="breadcrumb"><a href="/">Mercurial</a> &gt; <a href="/dir1">dir1</a> &gt; <a href="/dir1/a_repo">a_repo</a> </h2>
+  <form class="search" action="/dir1/a_repo/log">
+  number or hash, or <a href="/dir1/a_repo/help/revsets">revset expression</a>.</div>
+  <a href="/dir1/a_repo/shortlog/tip?revcount=30">less</a>
+  <a href="/dir1/a_repo/shortlog/tip?revcount=120">more</a>
+  | rev 1: <a href="/dir1/a_repo/shortlog/8580ff50825a">(0)</a> <a href="/dir1/a_repo/shortlog/tip">tip</a> 
+     <a href="/dir1/a_repo/rev/71a89161f014">add index file</a>
+     <a href="/dir1/a_repo/rev/8580ff50825a">a</a>
+  <a href="/dir1/a_repo/shortlog/tip?revcount=30">less</a>
+  <a href="/dir1/a_repo/shortlog/tip?revcount=120">more</a>
+  | rev 1: <a href="/dir1/a_repo/shortlog/8580ff50825a">(0)</a> <a href="/dir1/a_repo/shortlog/tip">tip</a> 
+              '/dir1/a_repo/shortlog/%next%',
+
+  $ get-with-headers.py localhost:$HGPORT1 'dir1/a_repo/index' | grep 'a_repo'
+  <h2 class="breadcrumb"><a href="/">Mercurial</a> &gt; <a href="/dir1">dir1</a> &gt; <a href="/dir1/a_repo">a_repo</a> </h2>
+  <td><a href="/dir1/a_repo/b_repo/">b_repo</a></td>
+  <a href="/dir1/a_repo/b_repo/atom-log" title="subscribe to repository atom feed">
+
+Files named 'index' are not blocked
+
+  $ get-with-headers.py localhost:$HGPORT1 'dir1/a_repo/raw-file/tip/index'
+  200 Script output follows
+  
+  index file
+
+Repos named 'index' take precedence over the index file
+
+  $ get-with-headers.py localhost:$HGPORT1 'dir1/dir2/index' | grep 'index'
+  <link rel="icon" href="/dir1/dir2/index/static/hgicon.png" type="image/png" />
+  <meta name="robots" content="index, nofollow" />
+  <link rel="stylesheet" href="/dir1/dir2/index/static/style-paper.css" type="text/css" />
+  <script type="text/javascript" src="/dir1/dir2/index/static/mercurial.js"></script>
+  <title>dir1/dir2/index: log</title>
+     href="/dir1/dir2/index/atom-log" title="Atom feed for dir1/dir2/index" />
+     href="/dir1/dir2/index/rss-log" title="RSS feed for dir1/dir2/index" />
+  <img src="/dir1/dir2/index/static/hglogo.png" alt="mercurial" /></a>
+  <li><a href="/dir1/dir2/index/graph/tip">graph</a></li>
+  <li><a href="/dir1/dir2/index/tags">tags</a></li>
+  <li><a href="/dir1/dir2/index/bookmarks">bookmarks</a></li>
+  <li><a href="/dir1/dir2/index/branches">branches</a></li>
+  <li><a href="/dir1/dir2/index/rev/tip">changeset</a></li>
+  <li><a href="/dir1/dir2/index/file/tip">browse</a></li>
+   <li><a href="/dir1/dir2/index/help">help</a></li>
+  <a href="/dir1/dir2/index/atom-log" title="subscribe to atom feed">
+  <img class="atom-logo" src="/dir1/dir2/index/static/feed-icon-14x14.png" alt="atom feed" />
+  <h2 class="breadcrumb"><a href="/">Mercurial</a> &gt; <a href="/dir1">dir1</a> &gt; <a href="/dir1/dir2">dir2</a> &gt; <a href="/dir1/dir2/index">index</a> </h2>
+  <form class="search" action="/dir1/dir2/index/log">
+  number or hash, or <a href="/dir1/dir2/index/help/revsets">revset expression</a>.</div>
+  <a href="/dir1/dir2/index/shortlog/tip?revcount=30">less</a>
+  <a href="/dir1/dir2/index/shortlog/tip?revcount=120">more</a>
+  | rev 0: <a href="/dir1/dir2/index/shortlog/39505516671b">(0)</a> <a href="/dir1/dir2/index/shortlog/tip">tip</a> 
+     <a href="/dir1/dir2/index/rev/39505516671b">b</a>
+  <a href="/dir1/dir2/index/shortlog/tip?revcount=30">less</a>
+  <a href="/dir1/dir2/index/shortlog/tip?revcount=120">more</a>
+  | rev 0: <a href="/dir1/dir2/index/shortlog/39505516671b">(0)</a> <a href="/dir1/dir2/index/shortlog/tip">tip</a> 
+              '/dir1/dir2/index/shortlog/%next%',
+
+  $ killdaemons.py
 
 paths errors 1