Skip to content
Snippets Groups Projects
Commit 5d3c30df authored by Michael Hanselmann's avatar Michael Hanselmann
Browse files

Add tool to check Python file headers


Ensures licence and copyright headers are correct.

Signed-off-by: default avatarMichael Hanselmann <hansmi@google.com>
Reviewed-by: default avatarRené Nussbaumer <rn@google.com>
parent 769582be
No related branches found
No related tags found
No related merge requests found
......@@ -21,6 +21,7 @@ ACLOCAL_AMFLAGS = -I autotools
BUILD_BASH_COMPLETION = $(top_srcdir)/autotools/build-bash-completion
RUN_IN_TEMPDIR = $(top_srcdir)/autotools/run-in-tempdir
CHECK_PYTHON_CODE = $(top_srcdir)/autotools/check-python-code
CHECK_HEADER = $(top_srcdir)/autotools/check-header
CHECK_MAN = $(top_srcdir)/autotools/check-man
CHECK_VERSION = $(top_srcdir)/autotools/check-version
CHECK_NEWS = $(top_srcdir)/autotools/check-news
......@@ -560,6 +561,7 @@ EXTRA_DIST = \
pylintrc \
autotools/build-bash-completion \
autotools/build-rpc \
autotools/check-header \
autotools/check-python-code \
autotools/check-imports \
autotools/check-man \
......@@ -804,6 +806,7 @@ srclink_files = \
check_python_code = \
$(BUILD_BASH_COMPLETION) \
$(CHECK_IMPORTS) \
$(CHECK_HEADER) \
$(DOCPP) \
$(all_python_code)
......@@ -815,6 +818,7 @@ lint_python_code = \
$(pkglib_python_scripts) \
$(BUILD_BASH_COMPLETION) \
$(CHECK_IMPORTS) \
$(CHECK_HEADER) \
$(DOCPP) \
$(PYTHON_BOOTSTRAP)
......@@ -829,6 +833,7 @@ pep8_python_code = \
$(dist_tools_PYTHON) \
$(pkglib_python_scripts) \
$(BUILD_BASH_COMPLETION) \
$(CHECK_HEADER) \
$(DOCPP) \
$(PYTHON_BOOTSTRAP) \
qa
......@@ -1124,6 +1129,7 @@ check-dirs: $(BUILT_SOURCES)
.PHONY: check-local
check-local: check-dirs $(BUILT_SOURCES)
$(CHECK_PYTHON_CODE) $(check_python_code)
PYTHONPATH=. $(CHECK_HEADER) $(check_python_code)
$(CHECK_VERSION) $(VERSION) $(top_srcdir)/NEWS
$(CHECK_NEWS) < $(top_srcdir)/NEWS
PYTHONPATH=. $(RUN_IN_TEMPDIR) $(CURDIR)/$(CHECK_IMPORTS) . $(standalone_python_modules)
......
#!/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-msg=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()
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment