aboutsummaryrefslogtreecommitdiff
path: root/scripts/maint/format_changelog.py
diff options
context:
space:
mode:
Diffstat (limited to 'scripts/maint/format_changelog.py')
-rwxr-xr-xscripts/maint/format_changelog.py109
1 files changed, 99 insertions, 10 deletions
diff --git a/scripts/maint/format_changelog.py b/scripts/maint/format_changelog.py
index 32a3d74e31..c84bf3ccf4 100755
--- a/scripts/maint/format_changelog.py
+++ b/scripts/maint/format_changelog.py
@@ -12,6 +12,7 @@
import os
import re
import sys
+import optparse
# ==============================
# Oh, look! It's a cruddy approximation to Knuth's elegant text wrapping
@@ -186,8 +187,49 @@ def body_parser(line):
else:
print "Weird line %r"%line
+def clean_head(head):
+ return head
+
+def head_score(s):
+ m = re.match(r'^ +o (.*)', s)
+ if not m:
+ print >>sys.stderr, "Can't score %r"%s
+ return 99999
+ lw = m.group(1).lower()
+ if lw.startswith("security") and "feature" not in lw:
+ score = -300
+ elif lw.startswith("deprecated versions"):
+ score = -200
+ elif "build require" in lw:
+ score = -100
+ elif lw.startswith("major feature"):
+ score = 00
+ elif lw.startswith("major bug"):
+ score = 50
+ elif lw.startswith("major"):
+ score = 70
+ elif lw.startswith("minor feature"):
+ score = 200
+ elif lw.startswith("minor bug"):
+ score = 250
+ elif lw.startswith("minor"):
+ score = 270
+ else:
+ score = 1000
+
+ if 'secur' in lw:
+ score -= 2
+
+ if "(other)" in lw:
+ score += 2
+
+ if '(' not in lw:
+ score -= 1
+
+ return score
+
class ChangeLog(object):
- def __init__(self):
+ def __init__(self, wrapText=True):
self.prehead = []
self.mainhead = None
self.headtext = []
@@ -195,6 +237,7 @@ class ChangeLog(object):
self.sections = []
self.cursection = None
self.lineno = 0
+ self.wrapText = wrapText
def addLine(self, tp, line):
self.lineno += 1
@@ -249,6 +292,11 @@ class ChangeLog(object):
self.lint_item(item_line, grafs, head_type)
def dumpGraf(self,par,indent1,indent2=-1):
+ if not self.wrapText:
+ for line in par:
+ print line
+ return
+
if indent2 == -1:
indent2 = indent1
text = " ".join(re.sub(r'\s+', ' ', line.strip()) for line in par)
@@ -258,6 +306,22 @@ class ChangeLog(object):
initial_indent=" "*indent1,
subsequent_indent=" "*indent2))
+ def collateAndSortSections(self):
+ heads = []
+ sectionsByHead = { }
+ for _, head, items in self.sections:
+ head = clean_head(head)
+ try:
+ s = sectionsByHead[head]
+ except KeyError:
+ s = sectionsByHead[head] = []
+ heads.append( (head_score(head), head, s) )
+
+ s.extend(items)
+
+ heads.sort()
+ self.sections = [ (0, head, items) for _,head,items in heads ]
+
def dump(self):
if self.prehead:
self.dumpGraf(self.prehead, 0)
@@ -279,20 +343,36 @@ class ChangeLog(object):
print
print
-CL = ChangeLog()
-parser = head_parser
-
-if len(sys.argv) == 1:
+op = optparse.OptionParser(usage="usage: %prog [options] [filename]")
+op.add_option('-W', '--no-wrap', action='store_false',
+ dest='wrapText', default=True,
+ help='Do not re-wrap paragraphs')
+op.add_option('-S', '--no-sort', action='store_false',
+ dest='sort', default=True,
+ help='Do not sort or collate sections')
+op.add_option('-o', '--output', dest='output',
+ default=None, metavar='FILE', help="write output to FILE")
+
+options,args = op.parse_args()
+
+if len(args) > 1:
+ op.error("Too many arguments")
+elif len(args) == 0:
fname = 'ChangeLog'
else:
- fname = sys.argv[1]
+ fname = args[0]
-fname_new = fname+".new"
+if options.output == None:
+ options.output = fname
-sys.stdin = open(fname, 'r')
+if fname != '-':
+ sys.stdin = open(fname, 'r')
nextline = None
+CL = ChangeLog(wrapText=options.wrapText)
+parser = head_parser
+
for line in sys.stdin:
line = line.rstrip()
tp = parser(line)
@@ -307,7 +387,15 @@ for line in sys.stdin:
CL.lint()
-sys.stdout = open(fname_new, 'w')
+if options.output != '-':
+ fname_new = options.output+".new"
+ fname_out = options.output
+ sys.stdout = open(fname_new, 'w')
+else:
+ fname_new = fname_out = None
+
+if options.sort:
+ CL.collateAndSortSections()
CL.dump()
@@ -317,4 +405,5 @@ if nextline is not None:
for line in sys.stdin:
sys.stdout.write(line)
-os.rename(fname_new, fname)
+if fname_new is not None:
+ os.rename(fname_new, fname_out)