[Erp5-report] r16389 - in /erp5/trunk/utils/erp5flakes: ./ bin/

nobody at svn.erp5.org nobody at svn.erp5.org
Sun Sep 16 12:15:20 CEST 2007


Author: jerome
Date: Sun Sep 16 12:15:20 2007
New Revision: 16389

URL: http://svn.erp5.org?rev=16389&view=rev
Log:
initial revision

Added:
    erp5/trunk/utils/erp5flakes/
    erp5/trunk/utils/erp5flakes/README.txt   (with props)
    erp5/trunk/utils/erp5flakes/bin/
    erp5/trunk/utils/erp5flakes/bin/erp5flakes   (with props)
    erp5/trunk/utils/erp5flakes/setup.py

Added: erp5/trunk/utils/erp5flakes/README.txt
URL: http://svn.erp5.org/erp5/trunk/utils/erp5flakes/README.txt?rev=16389&view=auto
==============================================================================
--- erp5/trunk/utils/erp5flakes/README.txt (added)
+++ erp5/trunk/utils/erp5flakes/README.txt Sun Sep 16 12:15:20 2007
@@ -1,0 +1,8 @@
+erp5flakes is a Wrapper around pyflakes to check ERP5 code for errors.
+
+It can parse python code in products or python scripts in business templates,
+in skin folders or workflow.
+
+To use it, simply invoke erp5flakes with the path to products or business
+templates you want to check.
+

Propchange: erp5/trunk/utils/erp5flakes/README.txt
------------------------------------------------------------------------------
    svn:eol-style = native

Added: erp5/trunk/utils/erp5flakes/bin/erp5flakes
URL: http://svn.erp5.org/erp5/trunk/utils/erp5flakes/bin/erp5flakes?rev=16389&view=auto
==============================================================================
--- erp5/trunk/utils/erp5flakes/bin/erp5flakes (added)
+++ erp5/trunk/utils/erp5flakes/bin/erp5flakes Sun Sep 16 12:15:20 2007
@@ -1,0 +1,159 @@
+#!/usr/bin/python
+
+import compiler
+import sys
+import os
+from pyflakes import Checker
+from pyflakes import messages
+import __builtin__
+
+# we need Zope and ERP5Type to check code inside business templates
+zope_software_home = os.environ.get('SOFTWARE_HOME',
+                                    '/usr/lib/zope/lib/python/')
+sys.path.append(zope_software_home)
+import ZODB
+from ZODB.DemoStorage import DemoStorage
+from OFS import XMLExportImport
+customImporters = {  XMLExportImport.magic: XMLExportImport.importXML }
+import Globals
+# load ERP5Type ppml monkey patches
+execfile(os.path.join(zope_software_home,
+              'Products', 'ERP5Type', 'patches', 'ppml.py'))
+
+
+# by default, we ignore warnings about unused imports
+fatal_messages = ( messages.ImportStarUsed, messages.UndefinedName,
+           messages.DuplicateArgument, messages.RedefinedFunction )
+
+def check(codeString, filename, bound_names=()):
+    try:
+        bound_names = [n for n in bound_names if not hasattr(__builtin__, n)]
+        for name in bound_names:
+            setattr(__builtin__, name, 1)
+        try:
+            tree = compiler.parse(codeString)
+        except (SyntaxError, IndentationError):
+            value = sys.exc_info()[1]
+            try:
+                (lineno, offset, line) = value[1][1:]
+            except IndexError:
+                print >> sys.stderr, 'could not compile %r' % (filename,)
+                return 1
+            if line.endswith("\n"):
+                line = line[:-1]
+            print >> sys.stderr, '%s:%d: could not compile' % (filename, lineno)
+            print >> sys.stderr, line
+            print >> sys.stderr, " " * (offset-2), "^"
+            return 1
+        else:
+            warnings = 0
+            w = Checker(tree, filename)
+            w.messages.sort(lambda a, b: cmp(a.lineno, b.lineno))
+            for warning in w.messages:
+                if isinstance(warning, fatal_messages):
+                    warnings += 1
+                    print warning
+            return warnings
+    finally:
+        for name in bound_names:
+            if hasattr(__builtin__, name):
+                delattr(__builtin__, name)
+
+
+def checkZopeProduct(path):
+    warnings = 0
+    for dirpath, dirnames, filenames in os.walk(path):
+        for filename in filenames:
+            if filename.endswith('.py'):
+                filename = os.path.join(dirpath, filename)
+                warnings += check(file(filename, 'U').read(), filename)
+    return warnings
+
+
+def getValidNames(py_script, blacklist_names=()):
+    """Returns the list of known names for this python script.
+    
+    This includes scripts parameters, script bound names and restricted python
+    utilities and auto-imported modules.
+
+    A list of black listed names can be passed. The use case is to turn the use
+    of 'context' in Workflow scripts an error.
+    """
+    name_list = []
+    for n in py_script._bind_names._asgns.values():
+        if n not in blacklist_names:
+            name_list.append(n)
+    for param in py_script.params().split(','):
+        param = param.strip()
+        if '=' in param:
+            name_list.append(param.split('=')[0])
+        elif '*' in param:
+            name_list.append(param.replace('*', ''))
+        else:
+            name_list.append(param)
+
+    restricted_python_names = ['same_type', 'printed', 'string', 'test',
+                                 'math', 'random'] # DateTime ?
+    return name_list + list(restricted_python_names)
+
+
+def checkBusinessTemplate(path):
+    """Checks python scripts in a business templates, from skin folder or
+    workflow scripts.
+    """
+    global _connection
+    _connection = None
+
+    def _getConnection():
+        """get a ZODB connection, open it if needed.
+        """
+        global _connection
+        if _connection is not None:
+            return _connection
+        db = ZODB.DB(DemoStorage(quota=(1<<20)))
+        _connection = db.open()
+        get_transaction().begin()
+        return _connection
+
+    warnings = 0
+    for dirpath, dirnames, filenames in \
+            list(os.walk(os.path.join(path, 'SkinTemplateItem'))) + \
+            list(os.walk(os.path.join(path, 'WorkflowTemplateItem'))):
+        for filename in filenames:
+            if not filename.endswith('.xml'):
+                continue
+            filename = os.path.join(dirpath, filename)
+            file_obj = file(filename)
+            try:
+                if 'Products.PythonScripts.PythonScript' in file_obj.read():
+                    file_obj.seek(0)
+                    obj = _getConnection().importFile(file_obj,
+                                        customImporters=customImporters)
+                    blacklist_names = []
+                    if 'WorkflowTemplateItem' in dirpath:
+                        blacklist_names = ['context']
+                    warnings += check(obj._body, filename,
+                        getValidNames(obj, blacklist_names=blacklist_names))
+            finally:
+                file_obj.close()
+
+    return warnings
+
+
+def isProduct(path):
+    return os.path.exists(os.path.join(path, '__init__.py'))
+
+def isBusinessTemplate(path):
+    return os.path.exists(os.path.join(path, 'bt', 'revision'))
+
+warnings = 0
+for arg in sys.argv[1:]:
+    if isProduct(arg):
+        warnings += checkZopeProduct(arg)
+    elif isBusinessTemplate(arg):
+        warnings += checkBusinessTemplate(arg)
+    else:
+        print >> sys.stderr, 'ignoring path', arg
+
+raise SystemExit(warnings > 0)
+# vim: sw=4

Propchange: erp5/trunk/utils/erp5flakes/bin/erp5flakes
------------------------------------------------------------------------------
    svn:executable = *

Added: erp5/trunk/utils/erp5flakes/setup.py
URL: http://svn.erp5.org/erp5/trunk/utils/erp5flakes/setup.py?rev=16389&view=auto
==============================================================================
--- erp5/trunk/utils/erp5flakes/setup.py (added)
+++ erp5/trunk/utils/erp5flakes/setup.py Sun Sep 16 12:15:20 2007
@@ -1,0 +1,26 @@
+from setuptools import setup
+
+name = "erp5flakes"
+version = '0.1'
+
+setup(
+    name = name,
+    version = version,
+    author = "Jerome Perrin",
+    author_email = "jerome at nexedi.com",
+    description =
+      "A wrapper around pyflakes for ERP5 Products and Business Templates",
+    long_description = file('README.txt').read(),
+    license = "GPL 2",
+    keywords = "erp5 zope2 pyflakes",
+    url = 'https://svn.erp5.org/repos/public/erp5/trunk/utils/%s' % name,
+    classifiers = [
+      "License :: OSI Approved :: GNU General Public License (GPL)",
+      "Framework :: ERP5",
+      "Framework :: Zope2",
+      "Programming Language :: Python",
+      ],
+    scripts = ["bin/erp5flakes"],
+    install_requires = ['pyflakes', ], # ZODB ERP5Type
+  )
+




More information about the Erp5-report mailing list