##// END OF EJS Templates
merge crew and main
Benoit Boissinot -
r18652:a5e94bee merge default
parent child Browse files
Show More
@@ -677,9 +677,26 b' class dirstate(object):'
677 677 # step 3: report unseen items in the dmap hash
678 678 if not skipstep3 and not exact:
679 679 visit = sorted([f for f in dmap if f not in results and matchfn(f)])
680 nf = iter(visit).next
681 for st in util.statfiles([join(i) for i in visit]):
682 results[nf()] = st
680 if unknown:
681 # unknown == True means we walked the full directory tree above.
682 # So if a file is not seen it was either a) not matching matchfn
683 # b) ignored, c) missing, or d) under a symlink directory.
684 audit_path = scmutil.pathauditor(self._root)
685
686 for nf in iter(visit):
687 # Report ignored items in the dmap as long as they are not
688 # under a symlink directory.
689 if ignore(nf) and audit_path.check(nf):
690 results[nf] = util.statfiles([join(nf)])[0]
691 else:
692 # It's either missing or under a symlink directory
693 results[nf] = None
694 else:
695 # We may not have walked the full directory tree above,
696 # so stat everything we missed.
697 nf = iter(visit).next
698 for st in util.statfiles([join(i) for i in visit]):
699 results[nf()] = st
683 700 for s in subrepos:
684 701 del results[s]
685 702 del results['.hg']
@@ -11,7 +11,7 b' from i18n import _, gettext'
11 11
12 12 _extensions = {}
13 13 _order = []
14 _ignore = ['hbisect', 'bookmarks', 'parentrevspec']
14 _ignore = ['hbisect', 'bookmarks', 'parentrevspec', 'interhg']
15 15
16 16 def extensions():
17 17 for name in _order:
@@ -1463,6 +1463,39 b' The full set of options is:'
1463 1463 ``templates``
1464 1464 Where to find the HTML templates. Default is install path.
1465 1465
1466 ``websub``
1467 ----------
1468
1469 Web substitution filter definition. You can use this section to
1470 define a set of regular expression substitution patterns which
1471 let you automatically modify the hgweb server output.
1472
1473 The default hgweb templates only apply these substitution patterns
1474 on the revision description fields. You can apply them anywhere
1475 you want when you create your own templates by adding calls to the
1476 "websub" filter (usually after calling the "escape" filter).
1477
1478 This can be used, for example, to convert issue references to links
1479 to your issue tracker, or to convert "markdown-like" syntax into
1480 HTML (see the examples below).
1481
1482 Each entry in this section names a substitution filter.
1483 The value of each entry defines the substitution expression itself.
1484 The websub expressions follow the old interhg extension syntax,
1485 which in turn imitates the Unix sed replacement syntax::
1486
1487 pattername = s/SEARCH_REGEX/REPLACE_EXPRESSION/[i]
1488
1489 You can use any separator other than "/". The final "i" is optional
1490 and indicates that the search must be case insensitive.
1491
1492 Examples::
1493
1494 [websub]
1495 issues = s|issue(\d+)|<a href="http://bts.example.org/issue\1">issue\1</a>|i
1496 italic = s/\b_(\S+)_\b/<i>\1<\/i>/
1497 bold = s/\*\b(\S+)\b\*/<b>\1<\/b>/
1498
1466 1499 ``worker``
1467 1500 ----------
1468 1501
@@ -8,11 +8,13 b''
8 8
9 9 import os
10 10 from mercurial import ui, hg, hook, error, encoding, templater, util, repoview
11 from mercurial.templatefilters import websub
12 from mercurial.i18n import _
11 13 from common import get_stat, ErrorResponse, permhooks, caching
12 14 from common import HTTP_OK, HTTP_NOT_MODIFIED, HTTP_BAD_REQUEST
13 15 from common import HTTP_NOT_FOUND, HTTP_SERVER_ERROR
14 16 from request import wsgirequest
15 import webcommands, protocol, webutil
17 import webcommands, protocol, webutil, re
16 18
17 19 perms = {
18 20 'changegroup': 'pull',
@@ -73,6 +75,7 b' class hgweb(object):'
73 75 # a repo owner may set web.templates in .hg/hgrc to get any file
74 76 # readable by the user running the CGI script
75 77 self.templatepath = self.config('web', 'templates')
78 self.websubtable = self.loadwebsub()
76 79
77 80 # The CGI scripts are often run by a user different from the repo owner.
78 81 # Trust the settings from the .hg/hgrc files by default.
@@ -258,6 +261,47 b' class hgweb(object):'
258 261 return ['']
259 262 return tmpl('error', error=inst.message)
260 263
264 def loadwebsub(self):
265 websubtable = []
266 websubdefs = self.repo.ui.configitems('websub')
267 # we must maintain interhg backwards compatibility
268 websubdefs += self.repo.ui.configitems('interhg')
269 for key, pattern in websubdefs:
270 # grab the delimiter from the character after the "s"
271 unesc = pattern[1]
272 delim = re.escape(unesc)
273
274 # identify portions of the pattern, taking care to avoid escaped
275 # delimiters. the replace format and flags are optional, but
276 # delimiters are required.
277 match = re.match(
278 r'^s%s(.+)(?:(?<=\\\\)|(?<!\\))%s(.*)%s([ilmsux])*$'
279 % (delim, delim, delim), pattern)
280 if not match:
281 self.repo.ui.warn(_("websub: invalid pattern for %s: %s\n")
282 % (key, pattern))
283 continue
284
285 # we need to unescape the delimiter for regexp and format
286 delim_re = re.compile(r'(?<!\\)\\%s' % delim)
287 regexp = delim_re.sub(unesc, match.group(1))
288 format = delim_re.sub(unesc, match.group(2))
289
290 # the pattern allows for 6 regexp flags, so set them if necessary
291 flagin = match.group(3)
292 flags = 0
293 if flagin:
294 for flag in flagin.upper():
295 flags |= re.__dict__[flag]
296
297 try:
298 regexp = re.compile(regexp, flags)
299 websubtable.append((regexp, format))
300 except re.error:
301 self.repo.ui.warn(_("websub: invalid regexp for %s: %s\n")
302 % (key, regexp))
303 return websubtable
304
261 305 def templater(self, req):
262 306
263 307 # determine scheme, port and server name
@@ -311,9 +355,13 b' class hgweb(object):'
311 355 or req.env.get('REPO_NAME')
312 356 or req.url.strip('/') or self.repo.root)
313 357
358 def websubfilter(text):
359 return websub(text, self.websubtable)
360
314 361 # create the templater
315 362
316 363 tmpl = templater.templater(mapfile,
364 filters={"websub": websubfilter},
317 365 defaults={"url": req.url,
318 366 "logourl": logourl,
319 367 "logoimg": logoimg,
@@ -184,6 +184,13 b' class pathauditor(object):'
184 184 # want to add "foo/bar/baz" before checking if there's a "foo/.hg"
185 185 self.auditeddir.update(prefixes)
186 186
187 def check(self, path):
188 try:
189 self(path)
190 return True
191 except (OSError, util.Abort):
192 return False
193
187 194 class abstractvfs(object):
188 195 """Abstract base class; cannot be instantiated"""
189 196
@@ -745,21 +752,14 b' def addremove(repo, pats=[], opts={}, dr'
745 752 ctx = repo[None]
746 753 walkresults = repo.dirstate.walk(m, sorted(ctx.substate), True, False)
747 754 for abs in sorted(walkresults):
748 good = True
749 try:
750 audit_path(abs)
751 except (OSError, util.Abort):
752 good = False
753
754 755 st = walkresults[abs]
755 756 dstate = repo.dirstate[abs]
756 if good and dstate == '?':
757 if dstate == '?' and audit_path.check(abs):
757 758 unknown.append(abs)
758 759 if repo.ui.verbose or not m.exact(abs):
759 760 rel = m.rel(abs)
760 761 repo.ui.status(_('adding %s\n') % ((pats and rel) or abs))
761 elif (dstate != 'r' and
762 (not good or not st or
762 elif (dstate != 'r' and (not st or
763 763 (stat.S_ISDIR(st.st_mode) and not stat.S_ISLNK(st.st_mode)))):
764 764 deleted.append(abs)
765 765 if repo.ui.verbose or not m.exact(abs):
@@ -391,6 +391,15 b' filters = {'
391 391 "xmlescape": xmlescape,
392 392 }
393 393
394 def websub(text, websubtable):
395 """:websub: Any text. Only applies to hgweb. Applies the regular
396 expression replacements defined in the websub section.
397 """
398 if websubtable:
399 for regexp, format in websubtable:
400 text = regexp.sub(format, text)
401 return text
402
394 403 def fillfunc(context, mapping, args):
395 404 if not (1 <= len(args) <= 2):
396 405 raise error.ParseError(_("fill expects one or two arguments"))
@@ -8,7 +8,7 b''
8 8 <i>{author|obfuscate} [{date|rfc822date}] rev {rev}</i><br/>
9 9 </div>
10 10 <div class="log_body">
11 {desc|strip|escape|addbreaks|nonempty}
11 {desc|strip|escape|websub|addbreaks|nonempty}
12 12 <br/>
13 13 <br/>
14 14 </div>
@@ -41,7 +41,7 b' changeset |'
41 41 </table></div>
42 42
43 43 <div class="page_body">
44 {desc|strip|escape|addbreaks|nonempty}
44 {desc|strip|escape|websub|addbreaks|nonempty}
45 45 </div>
46 46 <div class="list_head"></div>
47 47 <div class="title_text">
@@ -56,7 +56,7 b' annotate |'
56 56 </div>
57 57
58 58 <div class="page_path">
59 {desc|strip|escape|addbreaks|nonempty}
59 {desc|strip|escape|websub|addbreaks|nonempty}
60 60 </div>
61 61 <div class="page_body">
62 62 <table>
@@ -56,7 +56,7 b' file |'
56 56 </div>
57 57
58 58 <div class="page_path">
59 {desc|strip|escape|addbreaks|nonempty}
59 {desc|strip|escape|websub|addbreaks|nonempty}
60 60 </div>
61 61
62 62 <div class="page_body">
@@ -2,5 +2,5 b''
2 2 <ul class="changelog-entry">
3 3 <li class="age">{date|rfc822date}</li>
4 4 <li>by <span class="name">{author|obfuscate}</span> <span class="revdate">[{date|rfc822date}] rev {rev}</span></li>
5 <li class="description">{desc|strip|escape|addbreaks|nonempty}</li>
5 <li class="description">{desc|strip|escape|websub|addbreaks|nonempty}</li>
6 6 </ul>
@@ -52,7 +52,7 b''
52 52 {child%changesetchild}
53 53 </dl>
54 54
55 <p class="description">{desc|strip|escape|addbreaks|nonempty}</p>
55 <p class="description">{desc|strip|escape|websub|addbreaks|nonempty}</p>
56 56
57 57 <table>
58 58 {files}
@@ -57,7 +57,7 b''
57 57 <dd>{permissions|permissions}</dd>
58 58 </dl>
59 59
60 <p class="description">{desc|strip|escape|addbreaks|nonempty}</p>
60 <p class="description">{desc|strip|escape|websub|addbreaks|nonempty}</p>
61 61
62 62 <table class="annotated">
63 63 {annotate%annotateline}
@@ -57,7 +57,7 b''
57 57 <dd>{permissions|permissions}</dd>
58 58 </dl>
59 59
60 <p class="description">{desc|strip|escape|addbreaks|nonempty}</p>
60 <p class="description">{desc|strip|escape|websub|addbreaks|nonempty}</p>
61 61
62 62 <div class="source">
63 63 {text%fileline}
@@ -40,7 +40,7 b''
40 40 files, or words in the commit message</div>
41 41 </form>
42 42
43 <div class="description">{desc|strip|escape|nonempty}</div>
43 <div class="description">{desc|strip|escape|websub|nonempty}</div>
44 44
45 45 <table id="changesetEntry">
46 46 <tr>
@@ -46,7 +46,7 b''
46 46 files, or words in the commit message</div>
47 47 </form>
48 48
49 <div class="description">{desc|strip|escape|nonempty}</div>
49 <div class="description">{desc|strip|escape|websub|nonempty}</div>
50 50
51 51 <table id="changesetEntry">
52 52 <tr>
@@ -45,7 +45,7 b''
45 45 files, or words in the commit message</div>
46 46 </form>
47 47
48 <div class="description">{desc|strip|escape|nonempty}</div>
48 <div class="description">{desc|strip|escape|websub|nonempty}</div>
49 49
50 50 <table id="changesetEntry">
51 51 <tr>
@@ -45,7 +45,7 b''
45 45 files, or words in the commit message</div>
46 46 </form>
47 47
48 <div class="description">{desc|strip|escape|nonempty}</div>
48 <div class="description">{desc|strip|escape|websub|nonempty}</div>
49 49
50 50 <table id="changesetEntry">
51 51 <tr>
@@ -44,7 +44,7 b''
44 44 files, or words in the commit message</div>
45 45 </form>
46 46
47 <div class="description">{desc|strip|escape|nonempty}</div>
47 <div class="description">{desc|strip|escape|websub|nonempty}</div>
48 48
49 49 <table id="changesetEntry">
50 50 <tr>
@@ -39,7 +39,7 b''
39 39 </tr>
40 40 <tr>
41 41 <th class="description">description:</th>
42 <td class="description">{desc|strip|escape|addbreaks|nonempty}</td>
42 <td class="description">{desc|strip|escape|websub|addbreaks|nonempty}</td>
43 43 </tr>
44 44 </table>
45 45
@@ -38,7 +38,7 b''
38 38 </tr>
39 39 <tr>
40 40 <td class="metatag">description:</td>
41 <td>{desc|strip|escape|addbreaks|nonempty}</td>
41 <td>{desc|strip|escape|websub|addbreaks|nonempty}</td>
42 42 </tr>
43 43 </table>
44 44
@@ -36,7 +36,7 b''
36 36 <td>{permissions|permissions}</td></tr>
37 37 <tr>
38 38 <td class="metatag">description:</td>
39 <td>{desc|strip|escape|addbreaks|nonempty}</td>
39 <td>{desc|strip|escape|websub|addbreaks|nonempty}</td>
40 40 </tr>
41 41 </table>
42 42
@@ -149,6 +149,10 b' directory moved and symlinked'
149 149 adding foo/a
150 150 $ mv foo bar
151 151 $ ln -s bar foo
152 $ hg status
153 ! foo/a
154 ? bar/a
155 ? foo
152 156
153 157 now addremove should remove old files
154 158
@@ -5,11 +5,15 b''
5 5
6 6 $ cat > .hg/hgrc <<EOF
7 7 > [extensions]
8 > # this is only necessary to check that the mapping from
9 > # interhg to websub works
8 10 > interhg =
9 11 >
12 > [websub]
13 > issues = s|Issue(\d+)|<a href="http://bts.example.org/issue\1">Issue\1</a>|
14 >
10 15 > [interhg]
11 > issues = s|Issue(\d+)|<a href="http://bts.example.org/issue\1">Issue\1</a>|
12 >
16 > # check that we maintain some interhg backwards compatibility...
13 17 > # yes, 'x' is a weird delimiter...
14 18 > markbugs = sxbugx<i class="\x">bug</i>x
15 19 > EOF
@@ -23,9 +27,8 b''
23 27
24 28 log
25 29
26 $ "$TESTDIR/get-with-headers.py" localhost:$HGPORT '' | grep bts
27 <td class="description"><a href="/rev/1b0e7ece6bd6"><a href="http://bts.example.org/issue123">Issue123</a>: fixed the <i class="x">bug</i>!</a><span class="branchhead">default</span> <span class="tag">tip</span> </td>
28
30 $ "$TESTDIR/get-with-headers.py" localhost:$HGPORT "rev/tip" | grep bts
31 <div class="description"><a href="http://bts.example.org/issue123">Issue123</a>: fixed the <i class="x">bug</i>!</div>
29 32 errors
30 33
31 34 $ cat errors.log
General Comments 0
You need to be logged in to leave comments. Login now