##// END OF EJS Templates
hgweb: descend empty directories in web view...
Ry4an Brase -
r7305:c21d236c default
parent child Browse files
Show More
@@ -0,0 +1,28 b''
1 #!/bin/sh
2 # Test chains of near empty directories, terminating 3 different ways:
3 # - a1: file at level 4 (deepest)
4 # - b1: two dirs at level 3
5 # - e1: file at level 2
6
7 echo % Set up the repo
8 hg init test
9 cd test
10 mkdir -p a1/a2/a3/a4
11 mkdir -p b1/b2/b3/b4
12 mkdir -p b1/b2/c3/c4
13 mkdir -p d1/d2/d3/d4
14 echo foo > a1/a2/a3/a4/foo
15 echo foo > b1/b2/b3/b4/foo
16 echo foo > b1/b2/c3/c4/foo
17 echo foo > d1/d2/d3/d4/foo
18 echo foo > d1/d2/foo
19 hg ci -Ama
20
21 hg serve -n test -p $HGPORT -d --pid-file=hg.pid -E errors.log
22 cat hg.pid >> $DAEMON_PIDS
23
24 echo % manifest with descending
25 "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '/file'
26
27 echo % ERRORS ENCOUNTERED
28 cat errors.log
@@ -0,0 +1,51 b''
1 % Set up the repo
2 adding a1/a2/a3/a4/foo
3 adding b1/b2/b3/b4/foo
4 adding b1/b2/c3/c4/foo
5 adding d1/d2/d3/d4/foo
6 adding d1/d2/foo
7 % manifest with descending
8 200 Script output follows
9
10 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
11 <html>
12 <head>
13 <link rel="icon" href="/static/hgicon.png" type="image/png">
14 <meta name="robots" content="index, nofollow" />
15 <link rel="stylesheet" href="/static/style.css" type="text/css" />
16
17 <title>test: files for changeset 9087c84a0f5d</title>
18 </head>
19 <body>
20
21 <div class="buttons">
22 <a href="/log/0">changelog</a>
23 <a href="/shortlog/0">shortlog</a>
24 <a href="/graph">graph</a>
25 <a href="/tags">tags</a>
26 <a href="/rev/9087c84a0f5d">changeset</a>
27
28 </div>
29
30 <h2>files for changeset 9087c84a0f5d: /</h2>
31
32 <table cellpadding="0" cellspacing="0">
33 <tr class="parity0">
34 <td><tt>drwxr-xr-x</tt>&nbsp;
35 <td>&nbsp;
36 <td>&nbsp;
37 <td><a href="/file/9087c84a0f5d/">[up]</a>
38 </tr>
39 <tr class="parity1"><td><tt>drwxr-xr-x</tt>&nbsp;<td>&nbsp;<td>&nbsp;<td><a href="/file/9087c84a0f5d/a1">a1/</a> <a href="/file/9087c84a0f5d/a1/a2/a3/a4">a2/a3/a4</a><tr class="parity0"><td><tt>drwxr-xr-x</tt>&nbsp;<td>&nbsp;<td>&nbsp;<td><a href="/file/9087c84a0f5d/b1">b1/</a> <a href="/file/9087c84a0f5d/b1/b2">b2</a><tr class="parity1"><td><tt>drwxr-xr-x</tt>&nbsp;<td>&nbsp;<td>&nbsp;<td><a href="/file/9087c84a0f5d/d1">d1/</a> <a href="/file/9087c84a0f5d/d1/d2">d2</a>
40
41 </table>
42
43 <div class="logo">
44 <a href="http://www.selenic.com/mercurial/">
45 <img src="/static/hglogo.png" width=75 height=90 border=0 alt="mercurial"></a>
46 </div>
47
48 </body>
49 </html>
50
51 % ERRORS ENCOUNTERED
@@ -264,6 +264,7 b' def manifest(web, req, tmpl):'
264 node = ctx.node()
264 node = ctx.node()
265
265
266 files = {}
266 files = {}
267 dirs = {}
267 parity = paritygen(web.stripecount)
268 parity = paritygen(web.stripecount)
268
269
269 if path and path[-1] != "/":
270 if path and path[-1] != "/":
@@ -275,20 +276,25 b' def manifest(web, req, tmpl):'
275 if f[:l] != path:
276 if f[:l] != path:
276 continue
277 continue
277 remain = f[l:]
278 remain = f[l:]
278 idx = remain.find('/')
279 elements = remain.split('/')
279 if idx != -1:
280 if len(elements) == 1:
280 remain = remain[:idx+1]
281 files[remain] = f
281 n = None
282 else:
282 files[remain] = (f, n)
283 h = dirs # need to retain ref to dirs (root)
284 for elem in elements[0:-1]:
285 if elem not in h:
286 h[elem] = {}
287 h = h[elem]
288 if len(h) > 1:
289 break
290 h[None] = None # denotes files present
283
291
284 if not files:
292 if not files and not dirs:
285 raise ErrorResponse(HTTP_NOT_FOUND, 'path not found: ' + path)
293 raise ErrorResponse(HTTP_NOT_FOUND, 'path not found: ' + path)
286
294
287 def filelist(**map):
295 def filelist(**map):
288 for f in util.sort(files):
296 for f in util.sort(files):
289 full, fnode = files[f]
297 full = files[f]
290 if not fnode:
291 continue
292
298
293 fctx = ctx.filectx(full)
299 fctx = ctx.filectx(full)
294 yield {"file": full,
300 yield {"file": full,
@@ -299,14 +305,21 b' def manifest(web, req, tmpl):'
299 "permissions": mf.flags(full)}
305 "permissions": mf.flags(full)}
300
306
301 def dirlist(**map):
307 def dirlist(**map):
302 for f in util.sort(files):
308 for d in util.sort(dirs):
303 full, fnode = files[f]
304 if fnode:
305 continue
306
309
310 emptydirs = []
311 h = dirs[d]
312 while isinstance(h, dict) and len(h) == 1:
313 k,v = h.items()[0]
314 if v:
315 emptydirs.append(k)
316 h = v
317
318 path = "%s%s" % (abspath, d)
307 yield {"parity": parity.next(),
319 yield {"parity": parity.next(),
308 "path": "%s%s" % (abspath, f),
320 "path": path,
309 "basename": f[:-1]}
321 "emptydirs": "/".join(emptydirs),
322 "basename": d}
310
323
311 return tmpl("manifest",
324 return tmpl("manifest",
312 rev=ctx.rev(),
325 rev=ctx.rev(),
@@ -23,7 +23,7 b' searchentry = shortlogentry.tmpl'
23 changeset = changeset.tmpl
23 changeset = changeset.tmpl
24 manifest = manifest.tmpl
24 manifest = manifest.tmpl
25
25
26 direntry = '<tr class="fileline parity{parity}"><td class="name"><a href="{url}file/{node|short}{path|urlescape}{sessionvars%urlparameter}"><img src="{staticurl}coal-folder.png"> {basename|escape}/</a><td class="size"></td><td class="permissions">drwxr-xr-x</td></tr>'
26 direntry = '<tr class="fileline parity{parity}"><td class="name"><a href="{url}file/{node|short}{path|urlescape}{sessionvars%urlparameter}"><img src="{staticurl}coal-folder.png"> {basename|escape}/</a> <a href="{url}file/{node|short}{path|urlescape}/{emptydirs|urlescape}{sessionvars%urlparameter}">{emptydirs|escape}</a><td class="size"></td><td class="permissions">drwxr-xr-x</td></tr>'
27 fileentry = '<tr class="fileline parity{parity}"><td class="filename"><a href="{url}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}#l1"><img src="{staticurl}coal-file.png"> {basename|escape}</a></td><td class="size">{size}</td><td class="permissions">{permissions|permissions}</td></tr>'
27 fileentry = '<tr class="fileline parity{parity}"><td class="filename"><a href="{url}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}#l1"><img src="{staticurl}coal-file.png"> {basename|escape}</a></td><td class="size">{size}</td><td class="permissions">{permissions|permissions}</td></tr>'
28
28
29 filerevision = filerevision.tmpl
29 filerevision = filerevision.tmpl
@@ -19,7 +19,7 b' changelogentry = changelogentry.tmpl'
19 searchentry = changelogentry.tmpl
19 searchentry = changelogentry.tmpl
20 changeset = changeset.tmpl
20 changeset = changeset.tmpl
21 manifest = manifest.tmpl
21 manifest = manifest.tmpl
22 direntry = '<tr class="parity#parity#"><td style="font-family:monospace">drwxr-xr-x</td><td style="font-family:monospace"></td><td style="font-family:monospace"></td><td><a href="#url#file/#node|short##path|urlescape#{sessionvars%urlparameter}">#basename|escape#</a></td><td class="link"><a href="#url#file/#node|short##path|urlescape#{sessionvars%urlparameter}">files</a></td></tr>'
22 direntry = '<tr class="parity#parity#"><td style="font-family:monospace">drwxr-xr-x</td><td style="font-family:monospace"></td><td style="font-family:monospace"></td><td><a href="#url#file/#node|short##path|urlescape#{sessionvars%urlparameter}">#basename|escape#</a> <a href="#url#file/#node|short##path|urlescape#/#emptydirs|urlescape#{sessionvars%urlparameter}">#emptydirs|escape#</a></td><td class="link"><a href="#url#file/#node|short##path|urlescape#{sessionvars%urlparameter}">files</a></td></tr>'
23 fileentry = '<tr class="parity#parity#"><td style="font-family:monospace">#permissions|permissions#</td><td style="font-family:monospace" align=right>#date|isodate#</td><td style="font-family:monospace" align=right>#size#</td><td class="list"><a class="list" href="#url#file/#node|short#/#file|urlescape#{sessionvars%urlparameter}">#basename|escape#</a></td><td class="link"><a href="#url#file/#node|short#/#file|urlescape#{sessionvars%urlparameter}">file</a> | <a href="#url#log/#node|short#/#file|urlescape#{sessionvars%urlparameter}">revisions</a> | <a href="#url#annotate/#node|short#/#file|urlescape#{sessionvars%urlparameter}">annotate</a></td></tr>'
23 fileentry = '<tr class="parity#parity#"><td style="font-family:monospace">#permissions|permissions#</td><td style="font-family:monospace" align=right>#date|isodate#</td><td style="font-family:monospace" align=right>#size#</td><td class="list"><a class="list" href="#url#file/#node|short#/#file|urlescape#{sessionvars%urlparameter}">#basename|escape#</a></td><td class="link"><a href="#url#file/#node|short#/#file|urlescape#{sessionvars%urlparameter}">file</a> | <a href="#url#log/#node|short#/#file|urlescape#{sessionvars%urlparameter}">revisions</a> | <a href="#url#annotate/#node|short#/#file|urlescape#{sessionvars%urlparameter}">annotate</a></td></tr>'
24 filerevision = filerevision.tmpl
24 filerevision = filerevision.tmpl
25 fileannotate = fileannotate.tmpl
25 fileannotate = fileannotate.tmpl
@@ -19,7 +19,7 b' changelogentry = changelogentry.tmpl'
19 searchentry = changelogentry.tmpl
19 searchentry = changelogentry.tmpl
20 changeset = changeset.tmpl
20 changeset = changeset.tmpl
21 manifest = manifest.tmpl
21 manifest = manifest.tmpl
22 direntry = '<tr class="parity#parity#"><td><tt>drwxr-xr-x</tt>&nbsp;<td>&nbsp;<td>&nbsp;<td><a href="#url#file/#node|short##path|urlescape#{sessionvars%urlparameter}">#basename|escape#/</a>'
22 direntry = '<tr class="parity#parity#"><td><tt>drwxr-xr-x</tt>&nbsp;<td>&nbsp;<td>&nbsp;<td><a href="#url#file/#node|short##path|urlescape#{sessionvars%urlparameter}">#basename|escape#/</a> <a href="#url#file/#node|short##path|urlescape#/#emptydirs|urlescape#{sessionvars%urlparameter}">#emptydirs|urlescape#</a>'
23 fileentry = '<tr class="parity#parity#"><td><tt>#permissions|permissions#</tt>&nbsp;<td align=right><tt class="date">#date|isodate#</tt>&nbsp;<td align=right><tt>#size#</tt>&nbsp;<td><a href="#url#file/#node|short#/#file|urlescape#{sessionvars%urlparameter}">#basename|escape#</a>'
23 fileentry = '<tr class="parity#parity#"><td><tt>#permissions|permissions#</tt>&nbsp;<td align=right><tt class="date">#date|isodate#</tt>&nbsp;<td align=right><tt>#size#</tt>&nbsp;<td><a href="#url#file/#node|short#/#file|urlescape#{sessionvars%urlparameter}">#basename|escape#</a>'
24 filerevision = filerevision.tmpl
24 filerevision = filerevision.tmpl
25 fileannotate = fileannotate.tmpl
25 fileannotate = fileannotate.tmpl
@@ -23,7 +23,7 b' searchentry = ../coal/shortlogentry.tmpl'
23 changeset = ../coal/changeset.tmpl
23 changeset = ../coal/changeset.tmpl
24 manifest = ../coal/manifest.tmpl
24 manifest = ../coal/manifest.tmpl
25
25
26 direntry = '<tr class="fileline parity{parity}"><td class="name"><a href="{url}file/{node|short}{path|urlescape}{sessionvars%urlparameter}"><img src="{staticurl}coal-folder.png"> {basename|escape}/</a><td class="size"></td><td class="permissions">drwxr-xr-x</td></tr>'
26 direntry = '<tr class="fileline parity{parity}"><td class="name"><a href="{url}file/{node|short}{path|urlescape}{sessionvars%urlparameter}"><img src="{staticurl}coal-folder.png"> {basename|escape}/</a> <a href="{url}file/{node|short}{path|urlescape}/{emptydirs|urlescape}{sessionvars%urlparameter}">{emptydirs|escape}</a><td class="size"></td><td class="permissions">drwxr-xr-x</td></tr>'
27 fileentry = '<tr class="fileline parity{parity}"><td class="filename"><a href="{url}file/{node|short}/{file|urlescape}#l1{sessionvars%urlparameter}"><img src="{staticurl}coal-file.png"> {basename|escape}</a></td><td class="size">{size}</td><td class="permissions">{permissions|permissions}</td></tr>'
27 fileentry = '<tr class="fileline parity{parity}"><td class="filename"><a href="{url}file/{node|short}/{file|urlescape}#l1{sessionvars%urlparameter}"><img src="{staticurl}coal-file.png"> {basename|escape}</a></td><td class="size">{size}</td><td class="permissions">{permissions|permissions}</td></tr>'
28
28
29 filerevision = ../coal/filerevision.tmpl
29 filerevision = ../coal/filerevision.tmpl
General Comments 0
You need to be logged in to leave comments. Login now