| #!/usr/bin/python |
| # |
| |
| # Copyright (C) 2011, 2014 Google Inc. |
| # All rights reserved. |
| # |
| # Redistribution and use in source and binary forms, with or without |
| # modification, are permitted provided that the following conditions are |
| # met: |
| # |
| # 1. Redistributions of source code must retain the above copyright notice, |
| # this list of conditions and the following disclaimer. |
| # |
| # 2. Redistributions in binary form must reproduce the above copyright |
| # notice, this list of conditions and the following disclaimer in the |
| # documentation and/or other materials provided with the distribution. |
| # |
| # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS |
| # IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED |
| # TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
| # PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR |
| # CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, |
| # EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
| # PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR |
| # PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF |
| # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING |
| # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
| # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| |
| |
| """Script to verify file header. |
| |
| """ |
| |
| # pylint: disable=C0103 |
| # [C0103] Invalid name |
| |
| import sys |
| import re |
| import itertools |
| |
| from ganeti import constants |
| from ganeti import utils |
| from ganeti import compat |
| |
| |
| #: Assume header is always in the first 8kB of a file |
| _READ_SIZE = 8 * 1024 |
| |
| _BSD2 = [ |
| "All rights reserved.", |
| "", |
| "Redistribution and use in source and binary forms, with or without", |
| "modification, are permitted provided that the following conditions are", |
| "met:", |
| "", |
| "1. Redistributions of source code must retain the above copyright notice,", |
| "this list of conditions and the following disclaimer.", |
| "", |
| "2. Redistributions in binary form must reproduce the above copyright", |
| "notice, this list of conditions and the following disclaimer in the", |
| "documentation and/or other materials provided with the distribution.", |
| "", |
| "THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS", |
| "IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED", |
| "TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR", |
| "PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR", |
| "CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,", |
| "EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,", |
| "PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR", |
| "PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF", |
| "LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING", |
| "NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS", |
| "SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.", |
| ] |
| |
| |
| _SHEBANG = re.compile(r"^#(?:|!(?:/usr/bin/python(?:| -u)|/bin/(?:|ba)sh))$") |
| _COPYRIGHT_YEAR = r"20[01][0-9]" |
| _COPYRIGHT = re.compile(r"# Copyright \(C\) (%s(?:, %s)*) Google Inc\.$" % |
| (_COPYRIGHT_YEAR, _COPYRIGHT_YEAR)) |
| _COPYRIGHT_DESC = "Copyright (C) <year>[, <year> ...] Google Inc." |
| _AUTOGEN = "# This file is automatically generated, do not edit!" |
| |
| |
| class HeaderError(Exception): |
| pass |
| |
| |
| def _Fail(lineno, msg): |
| raise HeaderError("Line %s: %s" % (lineno, msg)) |
| |
| |
| def _CheckHeader(getline_fn): |
| (lineno, line) = getline_fn() |
| |
| if line == _AUTOGEN: |
| return |
| |
| if not _SHEBANG.match(line): |
| _Fail(lineno, ("Must contain nothing but a hash character (#) or a" |
| " shebang line (e.g. #!/bin/bash)")) |
| |
| (lineno, line) = getline_fn() |
| |
| if line == _AUTOGEN: |
| return |
| |
| if line != "#": |
| _Fail(lineno, "Must contain nothing but hash character (#)") |
| |
| (lineno, line) = getline_fn() |
| if line: |
| _Fail(lineno, "Must be empty") |
| |
| (lineno, line) = getline_fn() |
| if not _COPYRIGHT.match(line): |
| _Fail(lineno, "Must contain copyright information (%s)" % _COPYRIGHT_DESC) |
| |
| for licence_line in _BSD2: |
| (lineno, line) = getline_fn() |
| if line != ("# %s" % licence_line).rstrip(): |
| _Fail(lineno, "Does not match expected licence line (%s)" % licence_line) |
| |
| (lineno, line) = getline_fn() |
| if line: |
| _Fail(lineno, "Must be empty") |
| |
| |
| def Main(): |
| """Main program. |
| |
| """ |
| fail = False |
| |
| for filename in sys.argv[1:]: |
| content = utils.ReadFile(filename, size=_READ_SIZE) |
| lines = zip(itertools.count(1), content.splitlines()) |
| |
| try: |
| _CheckHeader(compat.partial(lines.pop, 0)) |
| except HeaderError, err: |
| report = str(err) |
| print "%s: %s" % (filename, report) |
| fail = True |
| |
| if fail: |
| sys.exit(constants.EXIT_FAILURE) |
| else: |
| sys.exit(constants.EXIT_SUCCESS) |
| |
| |
| if __name__ == "__main__": |
| Main() |