Statistics
| Branch: | Tag: | Revision:

root / autotools / check-news @ b1633ed9

History | View | Annotate | Download (5.1 kB)

1 7385c51d Michael Hanselmann
#!/usr/bin/python
2 7385c51d Michael Hanselmann
#
3 7385c51d Michael Hanselmann
4 1657353c Michael Hanselmann
# Copyright (C) 2011, 2012, 2013 Google Inc.
5 7385c51d Michael Hanselmann
#
6 7385c51d Michael Hanselmann
# This program is free software; you can redistribute it and/or modify
7 7385c51d Michael Hanselmann
# it under the terms of the GNU General Public License as published by
8 7385c51d Michael Hanselmann
# the Free Software Foundation; either version 2 of the License, or
9 7385c51d Michael Hanselmann
# (at your option) any later version.
10 7385c51d Michael Hanselmann
#
11 7385c51d Michael Hanselmann
# This program is distributed in the hope that it will be useful, but
12 7385c51d Michael Hanselmann
# WITHOUT ANY WARRANTY; without even the implied warranty of
13 7385c51d Michael Hanselmann
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 7385c51d Michael Hanselmann
# General Public License for more details.
15 7385c51d Michael Hanselmann
#
16 7385c51d Michael Hanselmann
# You should have received a copy of the GNU General Public License
17 7385c51d Michael Hanselmann
# along with this program; if not, write to the Free Software
18 7385c51d Michael Hanselmann
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 7385c51d Michael Hanselmann
# 02110-1301, USA.
20 7385c51d Michael Hanselmann
21 7385c51d Michael Hanselmann
22 7385c51d Michael Hanselmann
"""Script to check NEWS file.
23 7385c51d Michael Hanselmann
24 7385c51d Michael Hanselmann
"""
25 7385c51d Michael Hanselmann
26 f0fa05ac Iustin Pop
# pylint: disable=C0103
27 f0fa05ac Iustin Pop
# [C0103] Invalid name
28 f0fa05ac Iustin Pop
29 7385c51d Michael Hanselmann
import sys
30 7385c51d Michael Hanselmann
import time
31 7385c51d Michael Hanselmann
import datetime
32 7385c51d Michael Hanselmann
import locale
33 7385c51d Michael Hanselmann
import fileinput
34 7385c51d Michael Hanselmann
import re
35 d466fd8b Guido Trotter
import os
36 7385c51d Michael Hanselmann
37 7385c51d Michael Hanselmann
38 7385c51d Michael Hanselmann
DASHES_RE = re.compile(r"^\s*-+\s*$")
39 7385c51d Michael Hanselmann
RELEASED_RE = re.compile(r"^\*\(Released (?P<day>[A-Z][a-z]{2}),"
40 7385c51d Michael Hanselmann
                         r" (?P<date>.+)\)\*$")
41 7385c51d Michael Hanselmann
UNRELEASED_RE = re.compile(r"^\*\(unreleased\)\*$")
42 77721d8b Michele Tartara
VERSION_RE = re.compile(r"^Version (\d+(\.\d+)+( (alpha|beta|rc)\d+)?)$")
43 7385c51d Michael Hanselmann
44 1657353c Michael Hanselmann
#: How many days release timestamps may be in the future
45 1657353c Michael Hanselmann
TIMESTAMP_FUTURE_DAYS_MAX = 3
46 1657353c Michael Hanselmann
47 f0fa05ac Iustin Pop
errors = []
48 f0fa05ac Iustin Pop
49 f0fa05ac Iustin Pop
50 f0fa05ac Iustin Pop
def Error(msg):
51 f0fa05ac Iustin Pop
  """Log an error for later display.
52 f0fa05ac Iustin Pop
53 f0fa05ac Iustin Pop
  """
54 f0fa05ac Iustin Pop
  errors.append(msg)
55 f0fa05ac Iustin Pop
56 f0fa05ac Iustin Pop
57 f0fa05ac Iustin Pop
def ReqNLines(req, count_empty, lineno, line):
58 dadc7864 Michele Tartara
  """Check if we have N empty lines before the current one.
59 f0fa05ac Iustin Pop
60 f0fa05ac Iustin Pop
  """
61 f0fa05ac Iustin Pop
  if count_empty < req:
62 f0fa05ac Iustin Pop
    Error("Line %s: Missing empty line(s) before %s,"
63 f0fa05ac Iustin Pop
          " %d needed but got only %d" %
64 f0fa05ac Iustin Pop
          (lineno, line, req, count_empty))
65 f0fa05ac Iustin Pop
  if count_empty > req:
66 f0fa05ac Iustin Pop
    Error("Line %s: Too many empty lines before %s,"
67 f0fa05ac Iustin Pop
          " %d needed but got %d" %
68 f0fa05ac Iustin Pop
          (lineno, line, req, count_empty))
69 f0fa05ac Iustin Pop
70 7385c51d Michael Hanselmann
71 77721d8b Michele Tartara
def IsAlphaVersion(version):
72 77721d8b Michele Tartara
  return "alpha" in version
73 77721d8b Michele Tartara
74 77721d8b Michele Tartara
75 77721d8b Michele Tartara
def UpdateAllowUnreleased(allow_unreleased, version_match, release):
76 77721d8b Michele Tartara
  if not allow_unreleased:
77 77721d8b Michele Tartara
    return False
78 77721d8b Michele Tartara
  if IsAlphaVersion(release):
79 77721d8b Michele Tartara
    return True
80 77721d8b Michele Tartara
  version = version_match.group(1)
81 77721d8b Michele Tartara
  if version == release:
82 77721d8b Michele Tartara
    return False
83 77721d8b Michele Tartara
  return True
84 77721d8b Michele Tartara
85 77721d8b Michele Tartara
86 7385c51d Michael Hanselmann
def main():
87 7385c51d Michael Hanselmann
  # Ensure "C" locale is used
88 7385c51d Michael Hanselmann
  curlocale = locale.getlocale()
89 7385c51d Michael Hanselmann
  if curlocale != (None, None):
90 f0fa05ac Iustin Pop
    Error("Invalid locale %s" % curlocale)
91 7385c51d Michael Hanselmann
92 d466fd8b Guido Trotter
  # Get the release version, but replace "~" with " " as the version
93 d466fd8b Guido Trotter
  # in the NEWS file uses spaces for beta and rc releases.
94 d466fd8b Guido Trotter
  release = os.environ.get('RELEASE', "").replace("~", " ")
95 d466fd8b Guido Trotter
96 7385c51d Michael Hanselmann
  prevline = None
97 7385c51d Michael Hanselmann
  expect_date = False
98 51ef5fe0 Guido Trotter
  count_empty = 0
99 d466fd8b Guido Trotter
  allow_unreleased = True
100 d466fd8b Guido Trotter
  found_versions = set()
101 7385c51d Michael Hanselmann
102 7385c51d Michael Hanselmann
  for line in fileinput.input():
103 7385c51d Michael Hanselmann
    line = line.rstrip("\n")
104 7385c51d Michael Hanselmann
105 d466fd8b Guido Trotter
    version_match = VERSION_RE.match(line)
106 d466fd8b Guido Trotter
    if version_match:
107 f0fa05ac Iustin Pop
      ReqNLines(2, count_empty, fileinput.filelineno(), line)
108 d466fd8b Guido Trotter
      version = version_match.group(1)
109 d466fd8b Guido Trotter
      if version in found_versions:
110 d466fd8b Guido Trotter
        Error("Line %s: Duplicate release %s found" %
111 d466fd8b Guido Trotter
              (fileinput.filelineno(), version))
112 d466fd8b Guido Trotter
      found_versions.add(version)
113 77721d8b Michele Tartara
      allow_unreleased = UpdateAllowUnreleased(allow_unreleased, version_match,
114 77721d8b Michele Tartara
                                               release)
115 d466fd8b Guido Trotter
116 d466fd8b Guido Trotter
    unreleased_match = UNRELEASED_RE.match(line)
117 d466fd8b Guido Trotter
    if unreleased_match and not allow_unreleased:
118 d466fd8b Guido Trotter
      Error("Line %s: Unreleased version after current release %s" %
119 d466fd8b Guido Trotter
            (fileinput.filelineno(), release))
120 d466fd8b Guido Trotter
121 d466fd8b Guido Trotter
    if unreleased_match or RELEASED_RE.match(line):
122 f0fa05ac Iustin Pop
      ReqNLines(1, count_empty, fileinput.filelineno(), line)
123 51ef5fe0 Guido Trotter
124 51ef5fe0 Guido Trotter
    if line:
125 51ef5fe0 Guido Trotter
      count_empty = 0
126 51ef5fe0 Guido Trotter
    else:
127 51ef5fe0 Guido Trotter
      count_empty += 1
128 51ef5fe0 Guido Trotter
129 7385c51d Michael Hanselmann
    if DASHES_RE.match(line):
130 51ef5fe0 Guido Trotter
      if not VERSION_RE.match(prevline):
131 f0fa05ac Iustin Pop
        Error("Line %s: Invalid title" %
132 f0fa05ac Iustin Pop
              (fileinput.filelineno() - 1))
133 51ef5fe0 Guido Trotter
      if len(line) != len(prevline):
134 f0fa05ac Iustin Pop
        Error("Line %s: Invalid dashes length" %
135 f0fa05ac Iustin Pop
              (fileinput.filelineno()))
136 7385c51d Michael Hanselmann
      expect_date = True
137 7385c51d Michael Hanselmann
138 7385c51d Michael Hanselmann
    elif expect_date:
139 7385c51d Michael Hanselmann
      if not line:
140 7385c51d Michael Hanselmann
        # Ignore empty lines
141 7385c51d Michael Hanselmann
        continue
142 7385c51d Michael Hanselmann
143 7385c51d Michael Hanselmann
      if UNRELEASED_RE.match(line):
144 7385c51d Michael Hanselmann
        # Ignore unreleased versions
145 7385c51d Michael Hanselmann
        expect_date = False
146 7385c51d Michael Hanselmann
        continue
147 7385c51d Michael Hanselmann
148 7385c51d Michael Hanselmann
      m = RELEASED_RE.match(line)
149 7385c51d Michael Hanselmann
      if not m:
150 f0fa05ac Iustin Pop
        Error("Line %s: Invalid release line" % fileinput.filelineno())
151 9495d2f2 Guido Trotter
        expect_date = False
152 9495d2f2 Guido Trotter
        continue
153 7385c51d Michael Hanselmann
154 7385c51d Michael Hanselmann
      # Including the weekday in the date string does not work as time.strptime
155 7385c51d Michael Hanselmann
      # would return an inconsistent result if the weekday is incorrect.
156 7385c51d Michael Hanselmann
      parsed_ts = time.mktime(time.strptime(m.group("date"), "%d %b %Y"))
157 7385c51d Michael Hanselmann
      parsed = datetime.date.fromtimestamp(parsed_ts)
158 1657353c Michael Hanselmann
      today = datetime.date.today()
159 1657353c Michael Hanselmann
160 1657353c Michael Hanselmann
      if (parsed - datetime.timedelta(TIMESTAMP_FUTURE_DAYS_MAX)) > today:
161 1657353c Michael Hanselmann
        Error("Line %s: %s is more than %s days in the future (today is %s)" %
162 1657353c Michael Hanselmann
              (fileinput.filelineno(), parsed, TIMESTAMP_FUTURE_DAYS_MAX,
163 1657353c Michael Hanselmann
               today))
164 1657353c Michael Hanselmann
165 7385c51d Michael Hanselmann
      weekday = parsed.strftime("%a")
166 7385c51d Michael Hanselmann
167 7385c51d Michael Hanselmann
      # Check weekday
168 7385c51d Michael Hanselmann
      if m.group("day") != weekday:
169 f0fa05ac Iustin Pop
        Error("Line %s: %s was/is a %s, not %s" %
170 f0fa05ac Iustin Pop
              (fileinput.filelineno(), parsed, weekday,
171 f0fa05ac Iustin Pop
               m.group("day")))
172 7385c51d Michael Hanselmann
173 7385c51d Michael Hanselmann
      expect_date = False
174 7385c51d Michael Hanselmann
175 7385c51d Michael Hanselmann
    prevline = line
176 7385c51d Michael Hanselmann
177 f0fa05ac Iustin Pop
  if errors:
178 f0fa05ac Iustin Pop
    for msg in errors:
179 f0fa05ac Iustin Pop
      print >> sys.stderr, msg
180 f0fa05ac Iustin Pop
    sys.exit(1)
181 f0fa05ac Iustin Pop
  else:
182 f0fa05ac Iustin Pop
    sys.exit(0)
183 7385c51d Michael Hanselmann
184 7385c51d Michael Hanselmann
185 7385c51d Michael Hanselmann
if __name__ == "__main__":
186 7385c51d Michael Hanselmann
  main()