annotate hgext/releasenotes.py @ 33436:9bb4decd43b0

repovfs: add a ward to check if locks are properly taken When the appropriate developer warnings are enabled, We wrap 'repo.vfs.audit' to check for locks when accessing file in '.hg' for writing. Another changeset will add a 'ward' for the store vfs (svfs). This check system has caught a handful of locking issues that have been fixed in previous series (mostly in 4.0). I expect another batch to be caught in third party extensions. We introduce two real exceptions from extensions 'blackbox.log' (because a lot of read-only operations add entry to it), and 'last-email.txt' (because 'hg email' is currently a read only operation and there is value to keep it this way). In addition we are currently allowing bisect to operate outside of the lock because the current code is a bit hard to get properly locked for now. Multiple clean up have been made but there is still a couple of them to do and the freeze is coming.
author Boris Feld <boris.feld@octobus.net>
date Tue, 11 Jul 2017 12:38:17 +0200
parents 5814db57941c
children 9a944e908ecf
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
33012
5814db57941c releasenotes: improve parsing around bullet points
Rishabh Madan <rishabhmadan96@gmail.com>
parents: 32778
diff changeset
188 def gatherparagraphsbullets(offset, title=False):
5814db57941c releasenotes: improve parsing around bullet points
Rishabh Madan <rishabhmadan96@gmail.com>
parents: 32778
diff changeset
189 notefragment = []
32778
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'))
33012
5814db57941c releasenotes: improve parsing around bullet points
Rishabh Madan <rishabhmadan96@gmail.com>
parents: 32778
diff changeset
201 if title:
5814db57941c releasenotes: improve parsing around bullet points
Rishabh Madan <rishabhmadan96@gmail.com>
parents: 32778
diff changeset
202 lines = [l[1:].strip() for l in block['lines']]
5814db57941c releasenotes: improve parsing around bullet points
Rishabh Madan <rishabhmadan96@gmail.com>
parents: 32778
diff changeset
203 notefragment.append(lines)
5814db57941c releasenotes: improve parsing around bullet points
Rishabh Madan <rishabhmadan96@gmail.com>
parents: 32778
diff changeset
204 continue
5814db57941c releasenotes: improve parsing around bullet points
Rishabh Madan <rishabhmadan96@gmail.com>
parents: 32778
diff changeset
205 else:
5814db57941c releasenotes: improve parsing around bullet points
Rishabh Madan <rishabhmadan96@gmail.com>
parents: 32778
diff changeset
206 lines = [[l[1:].strip() for l in block['lines']]]
32778
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
207
33012
5814db57941c releasenotes: improve parsing around bullet points
Rishabh Madan <rishabhmadan96@gmail.com>
parents: 32778
diff changeset
208 for block in blocks[i + 1:]:
5814db57941c releasenotes: improve parsing around bullet points
Rishabh Madan <rishabhmadan96@gmail.com>
parents: 32778
diff changeset
209 if block['type'] in ('bullet', 'section'):
5814db57941c releasenotes: improve parsing around bullet points
Rishabh Madan <rishabhmadan96@gmail.com>
parents: 32778
diff changeset
210 break
5814db57941c releasenotes: improve parsing around bullet points
Rishabh Madan <rishabhmadan96@gmail.com>
parents: 32778
diff changeset
211 if block['type'] == 'paragraph':
5814db57941c releasenotes: improve parsing around bullet points
Rishabh Madan <rishabhmadan96@gmail.com>
parents: 32778
diff changeset
212 lines.append(block['lines'])
5814db57941c releasenotes: improve parsing around bullet points
Rishabh Madan <rishabhmadan96@gmail.com>
parents: 32778
diff changeset
213 notefragment.append(lines)
5814db57941c releasenotes: improve parsing around bullet points
Rishabh Madan <rishabhmadan96@gmail.com>
parents: 32778
diff changeset
214 continue
32778
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
215 elif block['type'] != 'paragraph':
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
216 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
217 '%s') % block['type'])
33012
5814db57941c releasenotes: improve parsing around bullet points
Rishabh Madan <rishabhmadan96@gmail.com>
parents: 32778
diff changeset
218 if title:
5814db57941c releasenotes: improve parsing around bullet points
Rishabh Madan <rishabhmadan96@gmail.com>
parents: 32778
diff changeset
219 notefragment.append(block['lines'])
32778
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
220
33012
5814db57941c releasenotes: improve parsing around bullet points
Rishabh Madan <rishabhmadan96@gmail.com>
parents: 32778
diff changeset
221 return notefragment
32778
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
222
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
223 currentsection = None
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
224 for i, block in enumerate(blocks):
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
225 if block['type'] != 'section':
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
226 continue
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 title = block['lines'][0]
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
229
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
230 # 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
231 # work.
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
232 if block['underline'] == '=': # main section
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
233 name = sections.sectionfromtitle(title)
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
234 if not name:
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
235 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
236 title)
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
237
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
238 currentsection = name
33012
5814db57941c releasenotes: improve parsing around bullet points
Rishabh Madan <rishabhmadan96@gmail.com>
parents: 32778
diff changeset
239 bullet_points = gatherparagraphsbullets(i)
5814db57941c releasenotes: improve parsing around bullet points
Rishabh Madan <rishabhmadan96@gmail.com>
parents: 32778
diff changeset
240 if bullet_points:
5814db57941c releasenotes: improve parsing around bullet points
Rishabh Madan <rishabhmadan96@gmail.com>
parents: 32778
diff changeset
241 for para in bullet_points:
5814db57941c releasenotes: improve parsing around bullet points
Rishabh Madan <rishabhmadan96@gmail.com>
parents: 32778
diff changeset
242 notes.addnontitleditem(currentsection, para)
32778
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
243
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
244 elif block['underline'] == '-': # sub-section
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
245 if title == BULLET_SECTION:
33012
5814db57941c releasenotes: improve parsing around bullet points
Rishabh Madan <rishabhmadan96@gmail.com>
parents: 32778
diff changeset
246 bullet_points = gatherparagraphsbullets(i)
5814db57941c releasenotes: improve parsing around bullet points
Rishabh Madan <rishabhmadan96@gmail.com>
parents: 32778
diff changeset
247 for para in bullet_points:
5814db57941c releasenotes: improve parsing around bullet points
Rishabh Madan <rishabhmadan96@gmail.com>
parents: 32778
diff changeset
248 notes.addnontitleditem(currentsection, para)
32778
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
249 else:
33012
5814db57941c releasenotes: improve parsing around bullet points
Rishabh Madan <rishabhmadan96@gmail.com>
parents: 32778
diff changeset
250 paragraphs = gatherparagraphsbullets(i, True)
32778
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
251 notes.addtitleditem(currentsection, title, paragraphs)
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
252 else:
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
253 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
254
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
255 return notes
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 def serializenotes(sections, notes):
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
258 """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
259
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
260 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
261 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
262 """
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
263 lines = []
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
264
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
265 for sectionname, sectiontitle in sections:
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
266 if sectionname not in notes:
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
267 continue
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
268
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
269 lines.append(sectiontitle)
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
270 lines.append('=' * len(sectiontitle))
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
271 lines.append('')
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 # First pass to emit sub-sections.
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
274 for title, paragraphs in notes.titledforsection(sectionname):
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
275 lines.append(title)
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
276 lines.append('-' * len(title))
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
277 lines.append('')
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
278
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
279 wrapper = textwrap.TextWrapper(width=78)
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
280 for i, para in enumerate(paragraphs):
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
281 if i:
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
282 lines.append('')
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
283 lines.extend(wrapper.wrap(' '.join(para)))
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
284
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
285 lines.append('')
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
286
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
287 # Second pass to emit bullet list items.
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
288
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
289 # 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
290 # 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
291 # 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
292 # for the non-titled items.
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
293 nontitled = notes.nontitledforsection(sectionname)
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
294 if notes.titledforsection(sectionname) and nontitled:
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
295 # TODO make configurable.
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
296 lines.append(BULLET_SECTION)
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
297 lines.append('-' * len(BULLET_SECTION))
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
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
300 for paragraphs in nontitled:
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
301 wrapper = textwrap.TextWrapper(initial_indent='* ',
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
302 subsequent_indent=' ',
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
303 width=78)
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
304 lines.extend(wrapper.wrap(' '.join(paragraphs[0])))
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 wrapper = textwrap.TextWrapper(initial_indent=' ',
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
307 subsequent_indent=' ',
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
308 width=78)
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
309 for para in paragraphs[1:]:
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
310 lines.append('')
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
311 lines.extend(wrapper.wrap(' '.join(para)))
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
312
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
313 lines.append('')
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
314
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
315 if lines[-1]:
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
316 lines.append('')
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
317
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
318 return '\n'.join(lines)
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 @command('releasenotes',
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
321 [('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
322 _('[-r REV] FILE'))
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
323 def releasenotes(ui, repo, file_, rev=None):
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
324 """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
325
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
326 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
327 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
328
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
329 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
330 directives. These have the form::
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
331
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
332 .. directive:: title
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
333
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
334 content
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 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
337 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
338 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
339
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
340 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
341 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
342 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
343 section.
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 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
346 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
347
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
348 Section 1
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
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 Section 2
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
354 =========
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 ...
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 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
359
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
360 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
361
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
362 Section
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
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
365 * Release note 1
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
366 * Release note 2
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 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
369
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
370 Section
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
371 =======
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
372
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
373 Note 1 Title
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
374 ------------
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 Description of the first long-form note.
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 Note 2 Title
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
379 ------------
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
380
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
381 Description of the second long-form note.
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
382
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
383 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
384 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
385 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
386 into this parsed set.
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
387
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
388 During release notes merging:
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
389
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
390 * Duplicate items are automatically ignored
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
391 * 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
392 greater than a threshold.
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
393
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
394 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
395 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
396 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
397 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
398 """
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
399 sections = releasenotessections(ui)
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 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
402 incoming = parsenotesfromrevisions(repo, sections.names(), revs)
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
403
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
404 try:
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
405 with open(file_, 'rb') as fh:
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
406 notes = parsereleasenotesfile(sections, fh.read())
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
407 except IOError as e:
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
408 if e.errno != errno.ENOENT:
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
409 raise
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
410
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
411 notes = parsedreleasenotes()
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
412
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
413 notes.merge(ui, incoming)
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 with open(file_, 'wb') as fh:
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
416 fh.write(serializenotes(sections, notes))
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
417
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
418 @command('debugparsereleasenotes', norepo=True)
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
419 def debugparsereleasenotes(ui, path):
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
420 """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
421 if path == '-':
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
422 text = sys.stdin.read()
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
423 else:
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
424 with open(path, 'rb') as fh:
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
425 text = fh.read()
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
426
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
427 sections = releasenotessections(ui)
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
428
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
429 notes = parsereleasenotesfile(sections, text)
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
430
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
431 for section in notes:
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
432 ui.write(_('section: %s\n') % section)
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
433 for title, paragraphs in notes.titledforsection(section):
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
434 ui.write(_(' subsection: %s\n') % title)
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
435 for para in paragraphs:
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
436 ui.write(_(' paragraph: %s\n') % ' '.join(para))
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
437
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
438 for paragraphs in notes.nontitledforsection(section):
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
439 ui.write(_(' bullet point:\n'))
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
440 for para in paragraphs:
91e355a0408b releasenotes: command to manage release notes files
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
441 ui.write(_(' paragraph: %s\n') % ' '.join(para))