Commit e13aa236 authored by Jérome Perrin's avatar Jérome Perrin

administration: add an action to check python code from a BT

This replaces ERP5Site_checkPythonScriptsWithPyflakes that I guess
nobody was using
parent 40169e05
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="ActionInformation" module="Products.CMFCore.ActionInformation"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>action</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value>
</item>
<item>
<key> <string>categories</string> </key>
<value>
<tuple>
<string>action_type/object_report</string>
</tuple>
</value>
</item>
<item>
<key> <string>category</string> </key>
<value> <string>object_report</string> </value>
</item>
<item>
<key> <string>condition</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>description</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>icon</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>check_python_code</string> </value>
</item>
<item>
<key> <string>permissions</string> </key>
<value>
<tuple>
<string>Manage portal</string>
</tuple>
</value>
</item>
<item>
<key> <string>priority</string> </key>
<value> <float>12.0</float> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>Check Python Code</string> </value>
</item>
<item>
<key> <string>visible</string> </key>
<value> <int>1</int> </value>
</item>
</dictionary>
</pickle>
</record>
<record id="2" aka="AAAAAAAAAAI=">
<pickle>
<global name="Expression" module="Products.CMFCore.Expression"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>text</string> </key>
<value> <string>string:${object_url}/BusinessTemplate_viewCheckPythonCodeDialog</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
"""Return python source code in business template
"""
import json
class Message:
"""A python code linter message, with a link to edit the source code.
Supports both being displayed in a listbox and being printed.
"""
def __init__(self, location, message, edit_url):
self.location = location
self.message = message
self.edit_url = edit_url
def getListItemUrl(self, *args, **kw):
return self.edit_url
def __repr__(self):
return "{}:{}".format(self.location, self.message)
portal = context.getPortalObject()
line_list = []
def checkPythonScript(script_instance, script_path):
"""Check a python script, adding messages to global `line_list`
"""
# printed is from RestrictedPython.RestrictionMutator the rest comes from
# RestrictedPython.Utilities.utility_builtins
extra_builtins = ['printed', 'same_type', 'string', 'sequence', 'random',
'DateTime', 'whrandom', 'reorder', 'sets', 'test', 'math']
for annotation in json.loads(portal.ERP5Site_checkPythonSourceCodeAsJSON(
{'bound_names': extra_builtins +
script_instance.getBindingAssignments().getAssignedNamesInOrder(),
'params': script_instance.params(),
'code': unicode(script_instance.read(), 'utf8')
}))['annotations']:
annotation["script_path"] = script_path
line_list.append(
Message(
location="{script_path}:{row}:{column}".format(**annotation),
message=annotation['text'],
edit_url="{script_path}/manage_main?line={row}".format(**annotation),))
def checkComponent(component_instance):
"""Check a component, adding messages to global `line_list`
"""
for annotation in json.loads(portal.ERP5Site_checkPythonSourceCodeAsJSON(
{'code': unicode(component_instance.getTextContent(), 'utf8')}))['annotations']:
annotation['component_path'] = component_instance.getRelativeUrl()
line_list.append(
Message(
location="{component_path}:{row}:{column}".format(**annotation),
message=annotation["text"],
edit_url="{component_path}?line={row}".format(**annotation),))
# Check scripts
script_container_list = []
for skin_id in context.getTemplateSkinIdList():
script_container_list.append(portal.portal_skins[skin_id])
for workflow_id in context.getTemplateWorkflowIdList():
script_container_list.append(portal.portal_workflow[workflow_id])
for script_container in script_container_list:
for script_path, script_instance in portal.ZopeFind(
script_container,
obj_metatypes=['Script (Python)'],
search_sub=1):
checkPythonScript(script_instance, "%s/%s" % (
portal.portal_url.getRelativeUrl(script_container), script_path))
# Check components
for component_id in (
context.getTemplateExtensionIdList() +
context.getTemplateDocumentIdList() +
context.getTemplateTestIdList()):
checkComponent(portal.portal_components[component_id])
return line_list
......@@ -50,11 +50,11 @@
</item>
<item>
<key> <string>_params</string> </key>
<value> <string></string> </value>
<value> <string>*args, **kw</string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>ERP5Site_checkPythonScriptsWithPyflakes</string> </value>
<value> <string>BusinessTemplate_getPythonSourceCodeMessageList</string> </value>
</item>
</dictionary>
</pickle>
......
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="ERP5 Form" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_bind_names</string> </key>
<value>
<object>
<klass>
<global name="NameAssignments" module="Shared.DC.Scripts.Bindings"/>
</klass>
<tuple/>
<state>
<dictionary>
<item>
<key> <string>_asgns</string> </key>
<value>
<dictionary/>
</value>
</item>
</dictionary>
</state>
</object>
</value>
</item>
<item>
<key> <string>_objects</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>action</string> </key>
<value> <string>BusinessTemplate_viewCheckPythonCodeDialog</string> </value>
</item>
<item>
<key> <string>description</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>edit_order</string> </key>
<value>
<list/>
</value>
</item>
<item>
<key> <string>encoding</string> </key>
<value> <string>UTF-8</string> </value>
</item>
<item>
<key> <string>enctype</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>group_list</string> </key>
<value>
<list>
<string>left</string>
<string>right</string>
<string>center</string>
<string>bottom</string>
<string>hidden</string>
</list>
</value>
</item>
<item>
<key> <string>groups</string> </key>
<value>
<dictionary>
<item>
<key> <string>bottom</string> </key>
<value>
<list>
<string>listbox</string>
</list>
</value>
</item>
<item>
<key> <string>center</string> </key>
<value>
<list/>
</value>
</item>
<item>
<key> <string>hidden</string> </key>
<value>
<list/>
</value>
</item>
<item>
<key> <string>left</string> </key>
<value>
<list/>
</value>
</item>
<item>
<key> <string>right</string> </key>
<value>
<list/>
</value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>BusinessTemplate_viewCheckPythonCodeDialog</string> </value>
</item>
<item>
<key> <string>method</string> </key>
<value> <string>POST</string> </value>
</item>
<item>
<key> <string>name</string> </key>
<value> <string>BusinessTemplate_viewCheckPythonCodeDialog</string> </value>
</item>
<item>
<key> <string>pt</string> </key>
<value> <string>form_dialog</string> </value>
</item>
<item>
<key> <string>row_length</string> </key>
<value> <int>4</int> </value>
</item>
<item>
<key> <string>stored_encoding</string> </key>
<value> <string>UTF-8</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>Check Python Code</string> </value>
</item>
<item>
<key> <string>unicode_mode</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>update_action</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>update_action_title</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
"""Runs pylint/pyflakes on all python scripts.
TODO / BUGS:
* script containing only a comment cannot be parsed
* wouldn't it be better to use this on a business template to check scripts
from the business template ?
"""
import json
def checkPythonSourceCode(script_instance):
# printed is from RestrictedPython.RestrictionMutator the rest comes from
# RestrictedPython.Utilities.utility_builtins
extra_builtins = ['printed', 'same_type', 'string', 'sequence', 'random',
'DateTime', 'whrandom', 'reorder', 'sets', 'test', 'math']
return json.loads(context.ERP5Site_checkPythonSourceCodeAsJSON(
{'bound_names': extra_builtins + script_instance.getBindingAssignments().getAssignedNamesInOrder(),
'params': script_instance.params(),
'code': unicode(script_instance.read(), 'utf8')
}))['annotations']
for script_container in (context.portal_skins, context.portal_workflow):
for script_path, script_instance in context.ZopeFind(script_container, obj_metatypes=['Script (Python)'], search_sub=1):
for annotation in checkPythonSourceCode(script_instance):
annotation["script_path"] = "%s/%s" % (script_container.getId(), script_path)
print "{script_path}:{row}:{column}:{text}".format(**annotation)
return printed
Business Template | check_python_code
Missing Category Document Constraint | predicate
Missing Category Document Constraint | view
portal_actions | consistency
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment