Mercurial > hg
comparison hgext/releasenotes.py @ 33571:9a944e908ecf
releasenotes: add custom admonitions support for release notes
By default, the extension has default sections like fix, feature, perf etc.. This
patch allow user to add support for custom admonition. In order to add a custom
admonition, one needs to have a .hgreleasenotes file inside the repository. All the
custom directive with name specified under the tag [sections] will be
usable by the extension. One important thing to keep in mind is if there exists any
custom admonitions with same key as default then they will override the default ones.
author | Rishabh Madan <rishabhmadan96@gmail.com> |
---|---|
date | Tue, 18 Jul 2017 23:04:08 +0530 |
parents | 5814db57941c |
children | 3748098d072a |
comparison
equal
deleted
inserted
replaced
33570:e470f12d7d05 | 33571:9a944e908ecf |
---|---|
18 import sys | 18 import sys |
19 import textwrap | 19 import textwrap |
20 | 20 |
21 from mercurial.i18n import _ | 21 from mercurial.i18n import _ |
22 from mercurial import ( | 22 from mercurial import ( |
23 config, | |
23 error, | 24 error, |
24 minirst, | 25 minirst, |
25 registrar, | 26 registrar, |
26 scmutil, | 27 scmutil, |
28 util, | |
27 ) | 29 ) |
28 | 30 |
29 cmdtable = {} | 31 cmdtable = {} |
30 command = registrar.command(cmdtable) | 32 command = registrar.command(cmdtable) |
31 | 33 |
109 # TODO perform similarily comparison and try to match against | 111 # TODO perform similarily comparison and try to match against |
110 # existing. | 112 # existing. |
111 self.addnontitleditem(section, paragraphs) | 113 self.addnontitleditem(section, paragraphs) |
112 | 114 |
113 class releasenotessections(object): | 115 class releasenotessections(object): |
114 def __init__(self, ui): | 116 def __init__(self, ui, repo=None): |
115 # TODO support defining custom sections from config. | 117 if repo: |
116 self._sections = list(DEFAULT_SECTIONS) | 118 sections = util.sortdict(DEFAULT_SECTIONS) |
119 custom_sections = getcustomadmonitions(repo) | |
120 if custom_sections: | |
121 sections.update(custom_sections) | |
122 self._sections = list(sections.iteritems()) | |
123 else: | |
124 self._sections = list(DEFAULT_SECTIONS) | |
117 | 125 |
118 def __iter__(self): | 126 def __iter__(self): |
119 return iter(self._sections) | 127 return iter(self._sections) |
120 | 128 |
121 def names(self): | 129 def names(self): |
125 for name, value in self._sections: | 133 for name, value in self._sections: |
126 if value == title: | 134 if value == title: |
127 return name | 135 return name |
128 | 136 |
129 return None | 137 return None |
138 | |
139 def getcustomadmonitions(repo): | |
140 ctx = repo['.'] | |
141 p = config.config() | |
142 | |
143 def read(f, sections=None, remap=None): | |
144 if f in ctx: | |
145 data = ctx[f].data() | |
146 p.parse(f, data, sections, remap, read) | |
147 else: | |
148 raise error.Abort(_(".hgreleasenotes file \'%s\' not found") % | |
149 repo.pathto(f)) | |
150 | |
151 if '.hgreleasenotes' in ctx: | |
152 read('.hgreleasenotes') | |
153 return p['sections'] | |
130 | 154 |
131 def parsenotesfromrevisions(repo, directives, revs): | 155 def parsenotesfromrevisions(repo, directives, revs): |
132 notes = parsedreleasenotes() | 156 notes = parsedreleasenotes() |
133 | 157 |
134 for rev in revs: | 158 for rev in revs: |
394 This means that the release notes file can be updated independently from | 418 This means that the release notes file can be updated independently from |
395 this command and changes should not be lost when running this command on | 419 this command and changes should not be lost when running this command on |
396 that file. A particular use case for this is to tweak the wording of a | 420 that file. A particular use case for this is to tweak the wording of a |
397 release note after it has been added to the release notes file. | 421 release note after it has been added to the release notes file. |
398 """ | 422 """ |
399 sections = releasenotessections(ui) | 423 sections = releasenotessections(ui, repo) |
400 | 424 |
401 revs = scmutil.revrange(repo, [rev or 'not public()']) | 425 revs = scmutil.revrange(repo, [rev or 'not public()']) |
402 incoming = parsenotesfromrevisions(repo, sections.names(), revs) | 426 incoming = parsenotesfromrevisions(repo, sections.names(), revs) |
403 | 427 |
404 try: | 428 try: |
414 | 438 |
415 with open(file_, 'wb') as fh: | 439 with open(file_, 'wb') as fh: |
416 fh.write(serializenotes(sections, notes)) | 440 fh.write(serializenotes(sections, notes)) |
417 | 441 |
418 @command('debugparsereleasenotes', norepo=True) | 442 @command('debugparsereleasenotes', norepo=True) |
419 def debugparsereleasenotes(ui, path): | 443 def debugparsereleasenotes(ui, path, repo=None): |
420 """parse release notes and print resulting data structure""" | 444 """parse release notes and print resulting data structure""" |
421 if path == '-': | 445 if path == '-': |
422 text = sys.stdin.read() | 446 text = sys.stdin.read() |
423 else: | 447 else: |
424 with open(path, 'rb') as fh: | 448 with open(path, 'rb') as fh: |
425 text = fh.read() | 449 text = fh.read() |
426 | 450 |
427 sections = releasenotessections(ui) | 451 sections = releasenotessections(ui, repo) |
428 | 452 |
429 notes = parsereleasenotesfile(sections, text) | 453 notes = parsereleasenotesfile(sections, text) |
430 | 454 |
431 for section in notes: | 455 for section in notes: |
432 ui.write(_('section: %s\n') % section) | 456 ui.write(_('section: %s\n') % section) |