Skip to content

Commit

Permalink
More powerful validation for changelog
Browse files Browse the repository at this point in the history
I've had some trouble with the changelog when rebasing or merging,
so I thought I'd write some more checks.  Now the expected entry
must appear first, all version numbers must be unique and in order,
and no version numbers may be skipped.

See https://xkcd.com/208/
  • Loading branch information
Zac-HD committed May 11, 2017
1 parent 69b7f59 commit b4badec
Showing 1 changed file with 42 additions and 3 deletions.
45 changes: 42 additions & 3 deletions scripts/check-changelog.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
from __future__ import division, print_function, absolute_import

import os
import re
import sys
from datetime import datetime, timedelta

Expand All @@ -34,18 +35,56 @@
print('No source changes found')
sys.exit(0)

found_problem = False

now = datetime.utcnow()
hour = timedelta(hours=1)
acceptable_lines = sorted(set(
'{} - {}'.format(tools.__version__, d.strftime('%Y-%m-%d'))
for d in (now, now + hour, now - hour)
))

for line in tools.changelog().split('\n'):
if line.strip() in acceptable_lines:
pattern = r'\n\d+\.\d+\.\d+ - \d{4}-\d{2}-\d{2}\n'
all_versions = list(map(str.strip, re.findall(pattern, tools.changelog())))

for line in acceptable_lines:
if line == all_versions[0]:
break
elif line in all_versions:
print('Changelog entry %r is not the first entry! Check for '
'merge errors.' % line)
found_problem = True
break
else:
print('No line with version and current date (%s) in the changelog. '
'Remember this will be released as soon as you merge to master!'
% ' or '.join(repr(line) for line in acceptable_lines))
sys.exit(1)
found_problem = True

if all_versions != sorted(all_versions, reverse=True):
print('You edited old release notes and changed the ordering!')
found_problem = True

v_nums = [v.split(' - ')[0] for v in all_versions]
duplicates = sorted(set(v for v in v_nums if v_nums.count(v) > 1))
if duplicates:
plural = 's have' if len(duplicates) > 1 else ' has'
print('The following version%s multiple entries in the '
'changelog: %s' % (plural, ', '.join(map(repr, duplicates))))
found_problem = True

skipped = []
for this, last in zip(v_nums, v_nums[1:]):
maj, minor, patch = map(int, last.split('.'))
if maj <= 1:
break
next_patch, next_minor, next_major = ['%s.%s.%s' % v for v in [
(maj, minor, patch + 1), (maj, minor + 1, 0), (maj + 1, 0, 0)]]
if this not in (next_patch, next_minor, next_major):
skipped.append('Version %r found after %r, expected %r or %r'
% (this, last, next_patch, next_minor))
found_problem = True
if skipped:
print('\n'.join(skipped))

sys.exit(int(found_problem))

0 comments on commit b4badec

Please sign in to comment.