Statistics
| Branch: | Tag: | Revision:

root / autotools / check-header @ 36c70d4d

History | View | Annotate | Download (3.8 kB)

1
#!/usr/bin/python
2
#
3

    
4
# Copyright (C) 2011 Google Inc.
5
#
6
# This program is free software; you can redistribute it and/or modify
7
# it under the terms of the GNU General Public License as published by
8
# the Free Software Foundation; either version 2 of the License, or
9
# (at your option) any later version.
10
#
11
# This program is distributed in the hope that it will be useful, but
12
# WITHOUT ANY WARRANTY; without even the implied warranty of
13
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
# General Public License for more details.
15
#
16
# You should have received a copy of the GNU General Public License
17
# along with this program; if not, write to the Free Software
18
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19
# 02110-1301, USA.
20

    
21

    
22
"""Script to verify file header.
23

    
24
"""
25

    
26
# pylint: disable=C0103
27
# [C0103] Invalid name
28

    
29
import sys
30
import re
31
import itertools
32

    
33
from ganeti import constants
34
from ganeti import utils
35
from ganeti import compat
36

    
37

    
38
#: Assume header is always in the first 8kB of a file
39
_READ_SIZE = 8 * 1024
40

    
41
_GPLv2 = [
42
  "This program is free software; you can redistribute it and/or modify",
43
  "it under the terms of the GNU General Public License as published by",
44
  "the Free Software Foundation; either version 2 of the License, or",
45
  "(at your option) any later version.",
46
  "",
47
  "This program is distributed in the hope that it will be useful, but",
48
  "WITHOUT ANY WARRANTY; without even the implied warranty of",
49
  "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU",
50
  "General Public License for more details.",
51
  "",
52
  "You should have received a copy of the GNU General Public License",
53
  "along with this program; if not, write to the Free Software",
54
  "Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA",
55
  "02110-1301, USA.",
56
  ]
57

    
58

    
59
_SHEBANG = re.compile(r"^#(?:|!(?:/usr/bin/python(?:| -u)|/bin/(?:|ba)sh))$")
60
_COPYRIGHT_YEAR = r"20[01][0-9]"
61
_COPYRIGHT = re.compile(r"# Copyright \(C\) (%s(?:, %s)*) Google Inc\.$" %
62
                        (_COPYRIGHT_YEAR, _COPYRIGHT_YEAR))
63
_COPYRIGHT_DESC = "Copyright (C) <year>[, <year> ...] Google Inc."
64
_AUTOGEN = "# This file is automatically generated, do not edit!"
65

    
66

    
67
class HeaderError(Exception):
68
  pass
69

    
70

    
71
def _Fail(lineno, msg):
72
  raise HeaderError("Line %s: %s" % (lineno, msg))
73

    
74

    
75
def _CheckHeader(getline_fn):
76
  (lineno, line) = getline_fn()
77

    
78
  if line == _AUTOGEN:
79
    return
80

    
81
  if not _SHEBANG.match(line):
82
    _Fail(lineno, ("Must contain nothing but a hash character (#) or a"
83
                   " shebang line (e.g. #!/bin/bash)"))
84

    
85
  (lineno, line) = getline_fn()
86

    
87
  if line == _AUTOGEN:
88
    return
89

    
90
  if line != "#":
91
    _Fail(lineno, "Must contain nothing but hash character (#)")
92

    
93
  (lineno, line) = getline_fn()
94
  if line:
95
    _Fail(lineno, "Must be empty")
96

    
97
  (lineno, line) = getline_fn()
98
  if not _COPYRIGHT.match(line):
99
    _Fail(lineno, "Must contain copyright information (%s)" % _COPYRIGHT_DESC)
100

    
101
  (lineno, line) = getline_fn()
102
  if line != "#":
103
    _Fail(lineno, "Must contain nothing but hash character (#)")
104

    
105
  for licence_line in _GPLv2:
106
    (lineno, line) = getline_fn()
107
    if line != ("# %s" % licence_line).rstrip():
108
      _Fail(lineno, "Does not match expected licence line (%s)" % licence_line)
109

    
110
  (lineno, line) = getline_fn()
111
  if line:
112
    _Fail(lineno, "Must be empty")
113

    
114

    
115
def Main():
116
  """Main program.
117

    
118
  """
119
  fail = False
120

    
121
  for filename in sys.argv[1:]:
122
    content = utils.ReadFile(filename, size=_READ_SIZE)
123
    lines = zip(itertools.count(1), content.splitlines())
124

    
125
    try:
126
      _CheckHeader(compat.partial(lines.pop, 0))
127
    except HeaderError, err:
128
      report = str(err)
129
      print "%s: %s" % (filename, report)
130
      fail = True
131

    
132
  if fail:
133
    sys.exit(constants.EXIT_FAILURE)
134
  else:
135
    sys.exit(constants.EXIT_SUCCESS)
136

    
137

    
138
if __name__ == "__main__":
139
  Main()