[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