X-Git-Url: https://code.grnet.gr/git/ganeti-local/blobdiff_plain/51ef5fe0d0cf7ad3854f369e72011f111724e721..dde3b0d5c06378213c580002472b8887605e7e3c:/autotools/check-news diff --git a/autotools/check-news b/autotools/check-news index 870e31d..1405b58 100755 --- a/autotools/check-news +++ b/autotools/check-news @@ -1,7 +1,7 @@ #!/usr/bin/python # -# Copyright (C) 2011 Google Inc. +# Copyright (C) 2011, 2012, 2013 Google Inc. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -23,43 +23,103 @@ """ +# pylint: disable=C0103 +# [C0103] Invalid name + import sys import time import datetime import locale import fileinput import re +import os DASHES_RE = re.compile(r"^\s*-+\s*$") RELEASED_RE = re.compile(r"^\*\(Released (?P[A-Z][a-z]{2})," r" (?P.+)\)\*$") UNRELEASED_RE = re.compile(r"^\*\(unreleased\)\*$") -VERSION_RE = re.compile(r"^Version \d+(\.\d+)+( (beta|rc)\d+)?$") +VERSION_RE = re.compile(r"^Version (\d+(\.\d+)+( (alpha|beta|rc)\d+)?)$") + +#: How many days release timestamps may be in the future +TIMESTAMP_FUTURE_DAYS_MAX = 3 + +errors = [] + + +def Error(msg): + """Log an error for later display. + + """ + errors.append(msg) + + +def ReqNLines(req, count_empty, lineno, line): + """Check if we have N empty lines before the current one. + + """ + if count_empty < req: + Error("Line %s: Missing empty line(s) before %s," + " %d needed but got only %d" % + (lineno, line, req, count_empty)) + if count_empty > req: + Error("Line %s: Too many empty lines before %s," + " %d needed but got %d" % + (lineno, line, req, count_empty)) + + +def IsAlphaVersion(version): + return "alpha" in version + + +def UpdateAllowUnreleased(allow_unreleased, version_match, release): + if not allow_unreleased: + return False + if IsAlphaVersion(release): + return True + version = version_match.group(1) + if version == release: + return False + return True def main(): # Ensure "C" locale is used curlocale = locale.getlocale() if curlocale != (None, None): - raise Exception("Invalid locale %s" % curlocale) + Error("Invalid locale %s" % curlocale) + + # Get the release version, but replace "~" with " " as the version + # in the NEWS file uses spaces for beta and rc releases. + release = os.environ.get('RELEASE', "").replace("~", " ") prevline = None expect_date = False count_empty = 0 + allow_unreleased = True + found_versions = set() for line in fileinput.input(): line = line.rstrip("\n") - if VERSION_RE.match(line): - if count_empty != 2: - raise Exception("Line %s: Missing 2 empty lines before %s" % - (fileinput.filelineno(), line)) - - if UNRELEASED_RE.match(line) or RELEASED_RE.match(line): - if count_empty != 1: - raise Exception("Line %s: Missing 1 empty line before %s" % - (fileinput.filelineno(), line)) + version_match = VERSION_RE.match(line) + if version_match: + ReqNLines(2, count_empty, fileinput.filelineno(), line) + version = version_match.group(1) + if version in found_versions: + Error("Line %s: Duplicate release %s found" % + (fileinput.filelineno(), version)) + found_versions.add(version) + allow_unreleased = UpdateAllowUnreleased(allow_unreleased, version_match, + release) + + unreleased_match = UNRELEASED_RE.match(line) + if unreleased_match and not allow_unreleased: + Error("Line %s: Unreleased version after current release %s" % + (fileinput.filelineno(), release)) + + if unreleased_match or RELEASED_RE.match(line): + ReqNLines(1, count_empty, fileinput.filelineno(), line) if line: count_empty = 0 @@ -68,11 +128,11 @@ def main(): if DASHES_RE.match(line): if not VERSION_RE.match(prevline): - raise Exception("Line %s: Invalid title" % - (fileinput.filelineno() - 1)) + Error("Line %s: Invalid title" % + (fileinput.filelineno() - 1)) if len(line) != len(prevline): - raise Exception("Line %s: Invalid dashes length" % - (fileinput.filelineno())) + Error("Line %s: Invalid dashes length" % + (fileinput.filelineno())) expect_date = True elif expect_date: @@ -87,26 +147,39 @@ def main(): m = RELEASED_RE.match(line) if not m: - raise Exception("Line %s: Invalid release line" % - fileinput.filelineno()) + Error("Line %s: Invalid release line" % fileinput.filelineno()) + expect_date = False + continue # Including the weekday in the date string does not work as time.strptime # would return an inconsistent result if the weekday is incorrect. parsed_ts = time.mktime(time.strptime(m.group("date"), "%d %b %Y")) parsed = datetime.date.fromtimestamp(parsed_ts) + today = datetime.date.today() + + if (parsed - datetime.timedelta(TIMESTAMP_FUTURE_DAYS_MAX)) > today: + Error("Line %s: %s is more than %s days in the future (today is %s)" % + (fileinput.filelineno(), parsed, TIMESTAMP_FUTURE_DAYS_MAX, + today)) + weekday = parsed.strftime("%a") # Check weekday if m.group("day") != weekday: - raise Exception("Line %s: %s was/is a %s, not %s" % - (fileinput.filelineno(), parsed, weekday, - m.group("day"))) + Error("Line %s: %s was/is a %s, not %s" % + (fileinput.filelineno(), parsed, weekday, + m.group("day"))) expect_date = False prevline = line - sys.exit(0) + if errors: + for msg in errors: + print >> sys.stderr, msg + sys.exit(1) + else: + sys.exit(0) if __name__ == "__main__":