Mercurial > hg
comparison hgext/releasenotes.py @ 33881:6a49c74b1e8f
releasenotes: add check flag for use of admonitions and its validity
While using releasenotes extension, we will be using admonitions in commit messages.
The check (-c) flag will look for an admonition within the message. If it exists, it will
verify if it is stated under default or custom admonition. The check fails if the
admonition is not present in any of them. It also suggests similar admonitions
in case the admonition is invalid.
Differential Revision: https://phab.mercurial-scm.org/D368
author | Rishabh Madan <rishabhmadan96@gmail.com> |
---|---|
date | Sun, 13 Aug 2017 19:58:45 +0530 |
parents | 589fda7895da |
children | 2a37459aedf2 |
comparison
equal
deleted
inserted
replaced
33880:edf503e5dfd4 | 33881:6a49c74b1e8f |
---|---|
11 process simpler by automating it. | 11 process simpler by automating it. |
12 """ | 12 """ |
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 |
19 import textwrap | 20 import textwrap |
20 | 21 |
240 | 241 |
241 if '.hgreleasenotes' in ctx: | 242 if '.hgreleasenotes' in ctx: |
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 |
248 for rev in revs: | 281 for rev in revs: |
249 ctx = repo[rev] | 282 ctx = repo[rev] |
430 lines.append('') | 463 lines.append('') |
431 | 464 |
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 |
441 messages for release notes then add them to the output file. | 476 messages for release notes then add them to the output file. |
442 | 477 |
509 this command and changes should not be lost when running this command on | 544 this command and changes should not be lost when running this command on |
510 that file. A particular use case for this is to tweak the wording of a | 545 that file. A particular use case for this is to tweak the wording of a |
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: |
519 with open(file_, 'rb') as fh: | 558 with open(file_, 'rb') as fh: |
520 notes = parsereleasenotesfile(sections, fh.read()) | 559 notes = parsereleasenotesfile(sections, fh.read()) |