Show More
@@ -13,6 +13,7 b' process simpler by automating it.' | |||||
13 |
|
13 | |||
14 | from __future__ import absolute_import |
|
14 | from __future__ import absolute_import | |
15 |
|
15 | |||
|
16 | import difflib | |||
16 | import errno |
|
17 | import errno | |
17 | import re |
|
18 | import re | |
18 | import sys |
|
19 | import sys | |
@@ -242,6 +243,38 b' def getcustomadmonitions(repo):' | |||||
242 | read('.hgreleasenotes') |
|
243 | read('.hgreleasenotes') | |
243 | return p['sections'] |
|
244 | return p['sections'] | |
244 |
|
245 | |||
|
246 | def checkadmonitions(ui, repo, directives, revs): | |||
|
247 | """ | |||
|
248 | Checks the commit messages for admonitions and their validity. | |||
|
249 | ||||
|
250 | .. abcd:: | |||
|
251 | ||||
|
252 | First paragraph under this admonition | |||
|
253 | ||||
|
254 | For this commit message, using `hg releasenotes -r . --check` | |||
|
255 | returns: Invalid admonition 'abcd' present in changeset 3ea92981e103 | |||
|
256 | ||||
|
257 | As admonition 'abcd' is neither present in default nor custom admonitions | |||
|
258 | """ | |||
|
259 | for rev in revs: | |||
|
260 | ctx = repo[rev] | |||
|
261 | admonition = re.search(RE_DIRECTIVE, ctx.description()) | |||
|
262 | if admonition: | |||
|
263 | if admonition.group(1) in directives: | |||
|
264 | continue | |||
|
265 | else: | |||
|
266 | ui.write(_("Invalid admonition '%s' present in changeset %s" | |||
|
267 | "\n") % (admonition.group(1), ctx.hex()[:12])) | |||
|
268 | sim = lambda x: difflib.SequenceMatcher(None, | |||
|
269 | admonition.group(1), x).ratio() | |||
|
270 | ||||
|
271 | similar = [s for s in directives if sim(s) > 0.6] | |||
|
272 | if len(similar) == 1: | |||
|
273 | ui.write(_("(did you mean %s?)\n") % similar[0]) | |||
|
274 | elif similar: | |||
|
275 | ss = ", ".join(sorted(similar)) | |||
|
276 | ui.write(_("(did you mean one of %s?)\n") % ss) | |||
|
277 | ||||
245 | def parsenotesfromrevisions(repo, directives, revs): |
|
278 | def parsenotesfromrevisions(repo, directives, revs): | |
246 | notes = parsedreleasenotes() |
|
279 | notes = parsedreleasenotes() | |
247 |
|
280 | |||
@@ -432,9 +465,11 b' def serializenotes(sections, notes):' | |||||
432 | return '\n'.join(lines) |
|
465 | return '\n'.join(lines) | |
433 |
|
466 | |||
434 | @command('releasenotes', |
|
467 | @command('releasenotes', | |
435 |
[('r', 'rev', '', _('revisions to process for release notes'), _('REV')) |
|
468 | [('r', 'rev', '', _('revisions to process for release notes'), _('REV')), | |
436 | _('[-r REV] FILE')) |
|
469 | ('c', 'check', False, _('checks for validity of admonitions (if any)'), | |
437 | def releasenotes(ui, repo, file_, rev=None): |
|
470 | _('REV'))], | |
|
471 | _('hg releasenotes [-r REV] [-c] FILE')) | |||
|
472 | def releasenotes(ui, repo, file_=None, **opts): | |||
438 | """parse release notes from commit messages into an output file |
|
473 | """parse release notes from commit messages into an output file | |
439 |
|
474 | |||
440 | Given an output file and set of revisions, this command will parse commit |
|
475 | Given an output file and set of revisions, this command will parse commit | |
@@ -511,8 +546,12 b' def releasenotes(ui, repo, file_, rev=No' | |||||
511 | release note after it has been added to the release notes file. |
|
546 | release note after it has been added to the release notes file. | |
512 | """ |
|
547 | """ | |
513 | sections = releasenotessections(ui, repo) |
|
548 | sections = releasenotessections(ui, repo) | |
|
549 | rev = opts.get('rev') | |||
514 |
|
550 | |||
515 | revs = scmutil.revrange(repo, [rev or 'not public()']) |
|
551 | revs = scmutil.revrange(repo, [rev or 'not public()']) | |
|
552 | if opts.get('check'): | |||
|
553 | return checkadmonitions(ui, repo, sections.names(), revs) | |||
|
554 | ||||
516 | incoming = parsenotesfromrevisions(repo, sections.names(), revs) |
|
555 | incoming = parsenotesfromrevisions(repo, sections.names(), revs) | |
517 |
|
556 | |||
518 | try: |
|
557 | try: |
@@ -378,3 +378,32 b' Overriding default sections (For eg. by ' | |||||
378 |
|
378 | |||
379 | * Adds a new feature. |
|
379 | * Adds a new feature. | |
380 |
|
380 | |||
|
381 | $ cd .. | |||
|
382 | ||||
|
383 | Testing output for the --check (-c) flag | |||
|
384 | ||||
|
385 | $ hg init check-flag | |||
|
386 | $ cd check-flag | |||
|
387 | ||||
|
388 | $ touch a | |||
|
389 | $ hg -q commit -A -l - << EOF | |||
|
390 | > .. asf:: | |||
|
391 | > | |||
|
392 | > First paragraph under this admonition. | |||
|
393 | > EOF | |||
|
394 | ||||
|
395 | Suggest similar admonition in place of the invalid one. | |||
|
396 | ||||
|
397 | $ hg releasenotes -r . -c | |||
|
398 | Invalid admonition 'asf' present in changeset 4026fe9e1c20 | |||
|
399 | ||||
|
400 | $ touch b | |||
|
401 | $ hg -q commit -A -l - << EOF | |||
|
402 | > .. fixes:: | |||
|
403 | > | |||
|
404 | > First paragraph under this admonition. | |||
|
405 | > EOF | |||
|
406 | ||||
|
407 | $ hg releasenotes -r . -c | |||
|
408 | Invalid admonition 'fixes' present in changeset 0e7130d2705c | |||
|
409 | (did you mean fix?) |
General Comments 0
You need to be logged in to leave comments.
Login now