From f6cbcc0623478ad75fd535fd1939b7b47d40449a Mon Sep 17 00:00:00 2001 From: Michael Hanselmann <hansmi@google.com> Date: Tue, 30 Aug 2011 13:44:59 +0200 Subject: [PATCH] Add check for standalone modules' imports This check will abort if one of the standalone modules (currently lib/rapi/client.py and tools/ganeti-listrunner) imports anything from the Ganeti source directory. Signed-off-by: Michael Hanselmann <hansmi@google.com> Reviewed-by: Iustin Pop <iustin@google.com> --- Makefile.am | 12 +++++- autotools/check-imports | 92 ++++++++++++++++++++++++++++++++++++++++ autotools/run-in-tempdir | 1 + 3 files changed, 104 insertions(+), 1 deletion(-) create mode 100755 autotools/check-imports diff --git a/Makefile.am b/Makefile.am index 444b53e26..0a9b95edd 100644 --- a/Makefile.am +++ b/Makefile.am @@ -24,6 +24,7 @@ CHECK_PYTHON_CODE = $(top_srcdir)/autotools/check-python-code CHECK_MAN = $(top_srcdir)/autotools/check-man CHECK_VERSION = $(top_srcdir)/autotools/check-version CHECK_NEWS = $(top_srcdir)/autotools/check-news +CHECK_IMPORTS = $(top_srcdir)/autotools/check-imports DOCPP = $(top_srcdir)/autotools/docpp REPLACE_VARS_SED = autotools/replace_vars.sed CONVERT_CONSTANTS = $(top_srcdir)/autotools/convert-constants @@ -540,6 +541,7 @@ EXTRA_DIST = \ pylintrc \ autotools/build-bash-completion \ autotools/check-python-code \ + autotools/check-imports \ autotools/check-man \ autotools/check-news \ autotools/check-tar \ @@ -752,6 +754,7 @@ srclink_files = \ check_python_code = \ $(BUILD_BASH_COMPLETION) \ + $(CHECK_IMPORTS) \ $(DOCPP) \ $(all_python_code) @@ -762,9 +765,14 @@ lint_python_code = \ $(dist_tools_PYTHON) \ $(pkglib_python_scripts) \ $(BUILD_BASH_COMPLETION) \ + $(CHECK_IMPORTS) \ $(DOCPP) \ $(PYTHON_BOOTSTRAP) +standalone_python_modules = \ + lib/rapi/client.py \ + tools/ganeti-listrunner + test/daemon-util_unittest.bash: daemons/daemon-util test/ganeti-cleaner_unittest.bash: daemons/ganeti-cleaner @@ -1048,10 +1056,12 @@ check-dirs: $(BUILT_SOURCES) if test -n "$$error"; then exit 1; else exit 0; fi; \ } -check-local: check-dirs +.PHONY: check-local +check-local: check-dirs $(BUILT_SOURCES) $(CHECK_PYTHON_CODE) $(check_python_code) $(CHECK_VERSION) $(VERSION) $(top_srcdir)/NEWS $(CHECK_NEWS) < $(top_srcdir)/NEWS + PYTHONPATH=. $(RUN_IN_TEMPDIR) $(CURDIR)/$(CHECK_IMPORTS) $(CURDIR) $(standalone_python_modules) expver=$(VERSION_MAJOR).$(VERSION_MINOR); \ if test "`head -n 1 $(top_srcdir)/README`" != "Ganeti $$expver"; then \ echo "Incorrect version in README, expected $$expver"; \ diff --git a/autotools/check-imports b/autotools/check-imports new file mode 100755 index 000000000..d50cb31ee --- /dev/null +++ b/autotools/check-imports @@ -0,0 +1,92 @@ +#!/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 check module imports. + +""" + +# pylint: disable=C0103 +# C0103: Invalid name + +import sys + +# All modules imported after this line are removed from the global list before +# importing a module to be checked +_STANDARD_MODULES = sys.modules.keys() + +import os.path + +from ganeti import build + + +def main(): + args = sys.argv[1:] + + # Get references to functions used later on + load_module = build.LoadModule + abspath = os.path.abspath + commonprefix = os.path.commonprefix + normpath = os.path.normpath + + script_path = abspath(__file__) + srcdir = normpath(abspath(args.pop(0))) + + assert "ganeti" in sys.modules + + for filename in args: + # Reset global state + for name in sys.modules.keys(): + if name not in _STANDARD_MODULES: + sys.modules.pop(name, None) + + assert "ganeti" not in sys.modules + + # Load module (this might import other modules) + module = load_module(filename) + + result = [] + + for (name, checkmod) in sorted(sys.modules.items()): + if checkmod is None or checkmod == module: + continue + + try: + checkmodpath = getattr(checkmod, "__file__") + except AttributeError: + # Built-in module + pass + else: + abscheckmodpath = os.path.abspath(checkmodpath) + + if abscheckmodpath == script_path: + # Ignore check script + continue + + if commonprefix([abscheckmodpath, srcdir]) == srcdir: + result.append(name) + + if result: + raise Exception("Module '%s' has illegal imports: %s" % + (filename, ", ".join(result))) + + +if __name__ == "__main__": + main() diff --git a/autotools/run-in-tempdir b/autotools/run-in-tempdir index e32f86339..48a166ac7 100755 --- a/autotools/run-in-tempdir +++ b/autotools/run-in-tempdir @@ -10,6 +10,7 @@ trap "rm -rf $tmpdir" EXIT cp -r autotools daemons scripts lib tools test $tmpdir mv $tmpdir/lib $tmpdir/ganeti +ln -T -s $tmpdir/ganeti $tmpdir/lib mkdir -p $tmpdir/htools if [ -e htools/test ]; then cp -p htools/test $tmpdir/htools/ -- GitLab