Statistics
| Branch: | Tag: | Revision:

root / autotools / check-news @ f0fa05ac

History | View | Annotate | Download (3.5 kB)

1 7385c51d Michael Hanselmann
#!/usr/bin/python
2 7385c51d Michael Hanselmann
#
3 7385c51d Michael Hanselmann
4 f0fa05ac Iustin Pop
# Copyright (C) 2011, 2012 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 7385c51d Michael Hanselmann
36 7385c51d Michael Hanselmann
37 7385c51d Michael Hanselmann
DASHES_RE = re.compile(r"^\s*-+\s*$")
38 7385c51d Michael Hanselmann
RELEASED_RE = re.compile(r"^\*\(Released (?P<day>[A-Z][a-z]{2}),"
39 7385c51d Michael Hanselmann
                         r" (?P<date>.+)\)\*$")
40 7385c51d Michael Hanselmann
UNRELEASED_RE = re.compile(r"^\*\(unreleased\)\*$")
41 51ef5fe0 Guido Trotter
VERSION_RE = re.compile(r"^Version \d+(\.\d+)+( (beta|rc)\d+)?$")
42 7385c51d Michael Hanselmann
43 f0fa05ac Iustin Pop
errors = []
44 f0fa05ac Iustin Pop
45 f0fa05ac Iustin Pop
46 f0fa05ac Iustin Pop
def Error(msg):
47 f0fa05ac Iustin Pop
  """Log an error for later display.
48 f0fa05ac Iustin Pop
49 f0fa05ac Iustin Pop
  """
50 f0fa05ac Iustin Pop
  errors.append(msg)
51 f0fa05ac Iustin Pop
52 f0fa05ac Iustin Pop
53 f0fa05ac Iustin Pop
def ReqNLines(req, count_empty, lineno, line):
54 f0fa05ac Iustin Pop
  """Check if we have N empty lines.
55 f0fa05ac Iustin Pop
56 f0fa05ac Iustin Pop
  """
57 f0fa05ac Iustin Pop
  if count_empty < req:
58 f0fa05ac Iustin Pop
    Error("Line %s: Missing empty line(s) before %s,"
59 f0fa05ac Iustin Pop
          " %d needed but got only %d" %
60 f0fa05ac Iustin Pop
          (lineno, line, req, count_empty))
61 f0fa05ac Iustin Pop
  if count_empty > req:
62 f0fa05ac Iustin Pop
    Error("Line %s: Too many empty lines before %s,"
63 f0fa05ac Iustin Pop
          " %d needed but got %d" %
64 f0fa05ac Iustin Pop
          (lineno, line, req, count_empty))
65 f0fa05ac Iustin Pop
66 7385c51d Michael Hanselmann
67 7385c51d Michael Hanselmann
def main():
68 7385c51d Michael Hanselmann
  # Ensure "C" locale is used
69 7385c51d Michael Hanselmann
  curlocale = locale.getlocale()
70 7385c51d Michael Hanselmann
  if curlocale != (None, None):
71 f0fa05ac Iustin Pop
    Error("Invalid locale %s" % curlocale)
72 7385c51d Michael Hanselmann
73 7385c51d Michael Hanselmann
  prevline = None
74 7385c51d Michael Hanselmann
  expect_date = False
75 51ef5fe0 Guido Trotter
  count_empty = 0
76 7385c51d Michael Hanselmann
77 7385c51d Michael Hanselmann
  for line in fileinput.input():
78 7385c51d Michael Hanselmann
    line = line.rstrip("\n")
79 7385c51d Michael Hanselmann
80 51ef5fe0 Guido Trotter
    if VERSION_RE.match(line):
81 f0fa05ac Iustin Pop
      ReqNLines(2, count_empty, fileinput.filelineno(), line)
82 51ef5fe0 Guido Trotter
83 51ef5fe0 Guido Trotter
    if UNRELEASED_RE.match(line) or RELEASED_RE.match(line):
84 f0fa05ac Iustin Pop
      ReqNLines(1, count_empty, fileinput.filelineno(), line)
85 51ef5fe0 Guido Trotter
86 51ef5fe0 Guido Trotter
    if line:
87 51ef5fe0 Guido Trotter
      count_empty = 0
88 51ef5fe0 Guido Trotter
    else:
89 51ef5fe0 Guido Trotter
      count_empty += 1
90 51ef5fe0 Guido Trotter
91 7385c51d Michael Hanselmann
    if DASHES_RE.match(line):
92 51ef5fe0 Guido Trotter
      if not VERSION_RE.match(prevline):
93 f0fa05ac Iustin Pop
        Error("Line %s: Invalid title" %
94 f0fa05ac Iustin Pop
              (fileinput.filelineno() - 1))
95 51ef5fe0 Guido Trotter
      if len(line) != len(prevline):
96 f0fa05ac Iustin Pop
        Error("Line %s: Invalid dashes length" %
97 f0fa05ac Iustin Pop
              (fileinput.filelineno()))
98 7385c51d Michael Hanselmann
      expect_date = True
99 7385c51d Michael Hanselmann
100 7385c51d Michael Hanselmann
    elif expect_date:
101 7385c51d Michael Hanselmann
      if not line:
102 7385c51d Michael Hanselmann
        # Ignore empty lines
103 7385c51d Michael Hanselmann
        continue
104 7385c51d Michael Hanselmann
105 7385c51d Michael Hanselmann
      if UNRELEASED_RE.match(line):
106 7385c51d Michael Hanselmann
        # Ignore unreleased versions
107 7385c51d Michael Hanselmann
        expect_date = False
108 7385c51d Michael Hanselmann
        continue
109 7385c51d Michael Hanselmann
110 7385c51d Michael Hanselmann
      m = RELEASED_RE.match(line)
111 7385c51d Michael Hanselmann
      if not m:
112 f0fa05ac Iustin Pop
        Error("Line %s: Invalid release line" % fileinput.filelineno())
113 7385c51d Michael Hanselmann
114 7385c51d Michael Hanselmann
      # Including the weekday in the date string does not work as time.strptime
115 7385c51d Michael Hanselmann
      # would return an inconsistent result if the weekday is incorrect.
116 7385c51d Michael Hanselmann
      parsed_ts = time.mktime(time.strptime(m.group("date"), "%d %b %Y"))
117 7385c51d Michael Hanselmann
      parsed = datetime.date.fromtimestamp(parsed_ts)
118 7385c51d Michael Hanselmann
      weekday = parsed.strftime("%a")
119 7385c51d Michael Hanselmann
120 7385c51d Michael Hanselmann
      # Check weekday
121 7385c51d Michael Hanselmann
      if m.group("day") != weekday:
122 f0fa05ac Iustin Pop
        Error("Line %s: %s was/is a %s, not %s" %
123 f0fa05ac Iustin Pop
              (fileinput.filelineno(), parsed, weekday,
124 f0fa05ac Iustin Pop
               m.group("day")))
125 7385c51d Michael Hanselmann
126 7385c51d Michael Hanselmann
      expect_date = False
127 7385c51d Michael Hanselmann
128 7385c51d Michael Hanselmann
    prevline = line
129 7385c51d Michael Hanselmann
130 f0fa05ac Iustin Pop
  if errors:
131 f0fa05ac Iustin Pop
    for msg in errors:
132 f0fa05ac Iustin Pop
      print >> sys.stderr, msg
133 f0fa05ac Iustin Pop
    sys.exit(1)
134 f0fa05ac Iustin Pop
  else:
135 f0fa05ac Iustin Pop
    sys.exit(0)
136 7385c51d Michael Hanselmann
137 7385c51d Michael Hanselmann
138 7385c51d Michael Hanselmann
if __name__ == "__main__":
139 7385c51d Michael Hanselmann
  main()