Skip to content
Snippets Groups Projects
check-header 3.75 KiB
#!/usr/bin/python
#

# Copyright (C) 2011 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
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
# 02110-1301, USA.


"""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

_GPLv2 = [
  "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",
  "the Free Software Foundation; either version 2 of the License, or",
  "(at your option) any later version.",
  "",
  "This program is distributed in the hope that it will be useful, but",
  "WITHOUT ANY WARRANTY; without even the implied warranty of",
  "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU",
  "General Public License for more details.",
  "",
  "You should have received a copy of the GNU General Public License",
  "along with this program; if not, write to the Free Software",
  "Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA",
  "02110-1301, USA.",
  ]


_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)

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

  for licence_line in _GPLv2:
    (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()