annotate hgext/releasenotes.py @ 32778:91e355a0408b

releasenotes: command to manage release notes files Per discussion on the mailing list, we want better release notes for Mercurial. This patch introduces an extension that provides a command for producing release notes files. Functionality is implemented as an extension because it could be useful outside of the Mercurial project and because there is some code (like rst parsing) that already exists in Mercurial and it doesn't make sense to reinvent the wheel. The general idea with the extension is that changeset authors declare release notes in commit messages using rst directives. Periodically (such as at publishing or release time), a project maintainer runs `hg releasenotes` to extract release notes fragments from commit messages and format them to an auto-generated release notes file. More details are explained inline in docstrings. There are several things that need addressed before this is ready for prime time: * Moar tests * Interactive merge mode * Implement similarity detection for individual notes items * Support customizing section names/titles * Parsing improvements for bullet lists and paragraphs * Document which rst primitives can be parsed * Retain arbitrary content (e.g. header section/paragraphs) from existing release notes file * Better error messages (line numbers, hints, etc)
author Gregory Szorc <gregory.szorc@gmail.com>
date Fri, 02 Jun 2017 23:33:30 +0200
parents
children 5814db57941c
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
32778
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
1 # Copyright 2017-present Gregory Szorc <gregory.szorc@gmail.com>
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
2 #
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
3 # This software may be used and distributed according to the terms of the
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
4 # GNU General Public License version 2 or any later version.
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
5
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
6 """generate release notes from commit messages (EXPERIMENTAL)
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
7
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
8 It is common to maintain files detailing changes in a project between
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
9 releases. Maintaining these files can be difficult and time consuming.
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
10 The :hg:`releasenotes` command provided by this extension makes the
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
11 process simpler by automating it.
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
12 """
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
13
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
14 from __future__ import absolute_import
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
15
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
16 import errno
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
17 import re
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
18 import sys
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
19 import textwrap
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
20
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
21 from mercurial.i18n import _
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
22 from mercurial import (
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
23 error,
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
24 minirst,
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
25 registrar,
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
26 scmutil,
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
27 )
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
28
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
29 cmdtable = {}
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
30 command = registrar.command(cmdtable)
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
31
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
32 # Note for extension authors: ONLY specify testedwith = 'ships-with-hg-core' for
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
33 # extensions which SHIP WITH MERCURIAL. Non-mainline extensions should
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
34 # be specifying the version(s) of Mercurial they are tested with, or
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
35 # leave the attribute unspecified.
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
36 testedwith = 'ships-with-hg-core'
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
37
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
38 DEFAULT_SECTIONS = [
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
39 ('feature', _('New Features')),
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
40 ('bc', _('Backwards Compatibility Changes')),
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
41 ('fix', _('Bug Fixes')),
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
42 ('perf', _('Performance Improvements')),
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
43 ('api', _('API Changes')),
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
44 ]
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
45
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
46 RE_DIRECTIVE = re.compile('^\.\. ([a-zA-Z0-9_]+)::\s*([^$]+)?$')
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
47
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
48 BULLET_SECTION = _('Other Changes')
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
49
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
50 class parsedreleasenotes(object):
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
51 def __init__(self):
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
52 self.sections = {}
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
53
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
54 def __contains__(self, section):
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
55 return section in self.sections
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
56
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
57 def __iter__(self):
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
58 return iter(sorted(self.sections))
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
59
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
60 def addtitleditem(self, section, title, paragraphs):
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
61 """Add a titled release note entry."""
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
62 self.sections.setdefault(section, ([], []))
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
63 self.sections[section][0].append((title, paragraphs))
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
64
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
65 def addnontitleditem(self, section, paragraphs):
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
66 """Adds a non-titled release note entry.
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
67
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
68 Will be rendered as a bullet point.
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
69 """
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
70 self.sections.setdefault(section, ([], []))
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
71 self.sections[section][1].append(paragraphs)
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
72
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
73 def titledforsection(self, section):
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
74 """Returns titled entries in a section.
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
75
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
76 Returns a list of (title, paragraphs) tuples describing sub-sections.
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
77 """
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
78 return self.sections.get(section, ([], []))[0]
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
79
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
80 def nontitledforsection(self, section):
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
81 """Returns non-titled, bulleted paragraphs in a section."""
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
82 return self.sections.get(section, ([], []))[1]
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
83
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
84 def hastitledinsection(self, section, title):
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
85 return any(t[0] == title for t in self.titledforsection(section))
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
86
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
87 def merge(self, ui, other):
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
88 """Merge another instance into this one.
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
89
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
90 This is used to combine multiple sources of release notes together.
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
91 """
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
92 for section in other:
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
93 for title, paragraphs in other.titledforsection(section):
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
94 if self.hastitledinsection(section, title):
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
95 # TODO prompt for resolution if different and running in
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
96 # interactive mode.
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
97 ui.write(_('%s already exists in %s section; ignoring\n') %
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
98 (title, section))
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
99 continue
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
100
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
101 # TODO perform similarity comparison and try to match against
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
102 # existing.
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
103 self.addtitleditem(section, title, paragraphs)
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
104
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
105 for paragraphs in other.nontitledforsection(section):
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
106 if paragraphs in self.nontitledforsection(section):
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
107 continue
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
108
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
109 # TODO perform similarily comparison and try to match against
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
110 # existing.
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
111 self.addnontitleditem(section, paragraphs)
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
112
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
113 class releasenotessections(object):
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
114 def __init__(self, ui):
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
115 # TODO support defining custom sections from config.
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
116 self._sections = list(DEFAULT_SECTIONS)
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
117
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
118 def __iter__(self):
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
119 return iter(self._sections)
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
120
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
121 def names(self):
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
122 return [t[0] for t in self._sections]
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
123
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
124 def sectionfromtitle(self, title):
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
125 for name, value in self._sections:
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
126 if value == title:
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
127 return name
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
128
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
129 return None
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
130
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
131 def parsenotesfromrevisions(repo, directives, revs):
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
132 notes = parsedreleasenotes()
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
133
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
134 for rev in revs:
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
135 ctx = repo[rev]
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
136
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
137 blocks, pruned = minirst.parse(ctx.description(),
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
138 admonitions=directives)
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
139
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
140 for i, block in enumerate(blocks):
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
141 if block['type'] != 'admonition':
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
142 continue
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
143
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
144 directive = block['admonitiontitle']
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
145 title = block['lines'][0].strip() if block['lines'] else None
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
146
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
147 if i + 1 == len(blocks):
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
148 raise error.Abort(_('release notes directive %s lacks content')
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
149 % directive)
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
150
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
151 # Now search ahead and find all paragraphs attached to this
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
152 # admonition.
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
153 paragraphs = []
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
154 for j in range(i + 1, len(blocks)):
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
155 pblock = blocks[j]
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
156
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
157 # Margin blocks may appear between paragraphs. Ignore them.
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
158 if pblock['type'] == 'margin':
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
159 continue
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
160
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
161 if pblock['type'] != 'paragraph':
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
162 raise error.Abort(_('unexpected block in release notes '
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
163 'directive %s') % directive)
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
164
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
165 if pblock['indent'] > 0:
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
166 paragraphs.append(pblock['lines'])
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
167 else:
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
168 break
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
169
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
170 # TODO consider using title as paragraph for more concise notes.
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
171 if not paragraphs:
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
172 raise error.Abort(_('could not find content for release note '
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
173 '%s') % directive)
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
174
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
175 if title:
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
176 notes.addtitleditem(directive, title, paragraphs)
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
177 else:
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
178 notes.addnontitleditem(directive, paragraphs)
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
179
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
180 return notes
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
181
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
182 def parsereleasenotesfile(sections, text):
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
183 """Parse text content containing generated release notes."""
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
184 notes = parsedreleasenotes()
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
185
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
186 blocks = minirst.parse(text)[0]
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
187
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
188 def gatherparagraphs(offset):
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
189 paragraphs = []
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
190
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
191 for i in range(offset + 1, len(blocks)):
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
192 block = blocks[i]
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
193
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
194 if block['type'] == 'margin':
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
195 continue
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
196 elif block['type'] == 'section':
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
197 break
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
198 elif block['type'] == 'bullet':
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
199 if block['indent'] != 0:
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
200 raise error.Abort(_('indented bullet lists not supported'))
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
201
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
202 lines = [l[1:].strip() for l in block['lines']]
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
203 paragraphs.append(lines)
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
204 continue
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
205 elif block['type'] != 'paragraph':
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
206 raise error.Abort(_('unexpected block type in release notes: '
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
207 '%s') % block['type'])
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
208
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
209 paragraphs.append(block['lines'])
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
210
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
211 return paragraphs
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
212
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
213 currentsection = None
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
214 for i, block in enumerate(blocks):
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
215 if block['type'] != 'section':
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
216 continue
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
217
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
218 title = block['lines'][0]
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
219
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
220 # TODO the parsing around paragraphs and bullet points needs some
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
221 # work.
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
222 if block['underline'] == '=': # main section
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
223 name = sections.sectionfromtitle(title)
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
224 if not name:
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
225 raise error.Abort(_('unknown release notes section: %s') %
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
226 title)
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
227
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
228 currentsection = name
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
229 paragraphs = gatherparagraphs(i)
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
230 if paragraphs:
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
231 notes.addnontitleditem(currentsection, paragraphs)
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
232
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
233 elif block['underline'] == '-': # sub-section
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
234 paragraphs = gatherparagraphs(i)
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
235
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
236 if title == BULLET_SECTION:
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
237 notes.addnontitleditem(currentsection, paragraphs)
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
238 else:
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
239 notes.addtitleditem(currentsection, title, paragraphs)
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
240 else:
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
241 raise error.Abort(_('unsupported section type for %s') % title)
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
242
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
243 return notes
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
244
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
245 def serializenotes(sections, notes):
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
246 """Serialize release notes from parsed fragments and notes.
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
247
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
248 This function essentially takes the output of ``parsenotesfromrevisions()``
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
249 and ``parserelnotesfile()`` and produces output combining the 2.
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
250 """
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
251 lines = []
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
252
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
253 for sectionname, sectiontitle in sections:
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
254 if sectionname not in notes:
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
255 continue
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
256
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
257 lines.append(sectiontitle)
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
258 lines.append('=' * len(sectiontitle))
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
259 lines.append('')
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
260
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
261 # First pass to emit sub-sections.
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
262 for title, paragraphs in notes.titledforsection(sectionname):
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
263 lines.append(title)
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
264 lines.append('-' * len(title))
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
265 lines.append('')
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
266
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
267 wrapper = textwrap.TextWrapper(width=78)
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
268 for i, para in enumerate(paragraphs):
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
269 if i:
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
270 lines.append('')
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
271 lines.extend(wrapper.wrap(' '.join(para)))
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
272
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
273 lines.append('')
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
274
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
275 # Second pass to emit bullet list items.
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
276
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
277 # If the section has titled and non-titled items, we can't
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
278 # simply emit the bullet list because it would appear to come
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
279 # from the last title/section. So, we emit a new sub-section
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
280 # for the non-titled items.
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
281 nontitled = notes.nontitledforsection(sectionname)
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
282 if notes.titledforsection(sectionname) and nontitled:
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
283 # TODO make configurable.
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
284 lines.append(BULLET_SECTION)
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
285 lines.append('-' * len(BULLET_SECTION))
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
286 lines.append('')
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
287
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
288 for paragraphs in nontitled:
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
289 wrapper = textwrap.TextWrapper(initial_indent='* ',
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
290 subsequent_indent=' ',
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
291 width=78)
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
292 lines.extend(wrapper.wrap(' '.join(paragraphs[0])))
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
293
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
294 wrapper = textwrap.TextWrapper(initial_indent=' ',
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
295 subsequent_indent=' ',
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
296 width=78)
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
297 for para in paragraphs[1:]:
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
298 lines.append('')
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
299 lines.extend(wrapper.wrap(' '.join(para)))
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
300
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
301 lines.append('')
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
302
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
303 if lines[-1]:
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
304 lines.append('')
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
305
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
306 return '\n'.join(lines)
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
307
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
308 @command('releasenotes',
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
309 [('r', 'rev', '', _('revisions to process for release notes'), _('REV'))],
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
310 _('[-r REV] FILE'))
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
311 def releasenotes(ui, repo, file_, rev=None):
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
312 """parse release notes from commit messages into an output file
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
313
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
314 Given an output file and set of revisions, this command will parse commit
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
315 messages for release notes then add them to the output file.
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
316
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
317 Release notes are defined in commit messages as ReStructuredText
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
318 directives. These have the form::
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
319
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
320 .. directive:: title
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
321
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
322 content
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
323
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
324 Each ``directive`` maps to an output section in a generated release notes
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
325 file, which itself is ReStructuredText. For example, the ``.. feature::``
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
326 directive would map to a ``New Features`` section.
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
327
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
328 Release note directives can be either short-form or long-form. In short-
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
329 form, ``title`` is omitted and the release note is rendered as a bullet
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
330 list. In long form, a sub-section with the title ``title`` is added to the
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
331 section.
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
332
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
333 The ``FILE`` argument controls the output file to write gathered release
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
334 notes to. The format of the file is::
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
335
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
336 Section 1
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
337 =========
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
338
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
339 ...
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
340
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
341 Section 2
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
342 =========
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
343
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
344 ...
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
345
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
346 Only sections with defined release notes are emitted.
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
347
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
348 If a section only has short-form notes, it will consist of bullet list::
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
349
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
350 Section
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
351 =======
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
352
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
353 * Release note 1
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
354 * Release note 2
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
355
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
356 If a section has long-form notes, sub-sections will be emitted::
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
357
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
358 Section
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
359 =======
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
360
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
361 Note 1 Title
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
362 ------------
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
363
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
364 Description of the first long-form note.
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
365
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
366 Note 2 Title
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
367 ------------
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
368
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
369 Description of the second long-form note.
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
370
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
371 If the ``FILE`` argument points to an existing file, that file will be
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
372 parsed for release notes having the format that would be generated by this
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
373 command. The notes from the processed commit messages will be *merged*
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
374 into this parsed set.
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
375
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
376 During release notes merging:
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
377
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
378 * Duplicate items are automatically ignored
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
379 * Items that are different are automatically ignored if the similarity is
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
380 greater than a threshold.
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
381
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
382 This means that the release notes file can be updated independently from
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
383 this command and changes should not be lost when running this command on
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
384 that file. A particular use case for this is to tweak the wording of a
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
385 release note after it has been added to the release notes file.
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
386 """
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
387 sections = releasenotessections(ui)
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
388
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
389 revs = scmutil.revrange(repo, [rev or 'not public()'])
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
390 incoming = parsenotesfromrevisions(repo, sections.names(), revs)
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
391
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
392 try:
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
393 with open(file_, 'rb') as fh:
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
394 notes = parsereleasenotesfile(sections, fh.read())
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
395 except IOError as e:
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
396 if e.errno != errno.ENOENT:
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
397 raise
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
398
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
399 notes = parsedreleasenotes()
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
400
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
401 notes.merge(ui, incoming)
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
402
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
403 with open(file_, 'wb') as fh:
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
404 fh.write(serializenotes(sections, notes))
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
405
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
406 @command('debugparsereleasenotes', norepo=True)
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
407 def debugparsereleasenotes(ui, path):
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
408 """parse release notes and print resulting data structure"""
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
409 if path == '-':
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
410 text = sys.stdin.read()
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
411 else:
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
412 with open(path, 'rb') as fh:
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
413 text = fh.read()
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
414
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
415 sections = releasenotessections(ui)
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
416
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
417 notes = parsereleasenotesfile(sections, text)
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
418
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
419 for section in notes:
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
420 ui.write(_('section: %s\n') % section)
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
421 for title, paragraphs in notes.titledforsection(section):
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
422 ui.write(_(' subsection: %s\n') % title)
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
423 for para in paragraphs:
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
424 ui.write(_(' paragraph: %s\n') % ' '.join(para))
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
425
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
426 for paragraphs in notes.nontitledforsection(section):
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
427 ui.write(_(' bullet point:\n'))
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
428 for para in paragraphs:
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
429 ui.write(_(' paragraph: %s\n') % ' '.join(para))