diff options
| author | qdp <qdp@tinyerp.com> | 2008-12-16 18:20:15 +0100 |
|---|---|---|
| committer | qdp <qdp@tinyerp.com> | 2008-12-16 18:20:15 +0100 |
| commit | 02694646b6146abfbee2e64a5750189550ec12ce (patch) | |
| tree | ccadc87d5ce34a153a19b67e2b062b52e6a8fed2 /addons/base_module_quality | |
| parent | 2b2c7e256b4b6c6d77333ae833838bc6aa4609f7 (diff) | |
*improvements of base_module_quality:
*defined generic framework, use of inheritance, ...
*restructured
*added config file of pylint
*added speed_test (to be continued)
*removed unecessary files
bzr revid: qdp@tinyerp.com-20081216172015-4o856cgffpytl9ru
Diffstat (limited to 'addons/base_module_quality')
| -rw-r--r-- | addons/base_module_quality/README.txt | 11 | ||||
| -rw-r--r-- | addons/base_module_quality/__terp__.py | 10 | ||||
| -rw-r--r-- | addons/base_module_quality/base_module_quality.py | 11 | ||||
| -rw-r--r-- | addons/base_module_quality/pylint_test/__init__.py | 2 | ||||
| -rw-r--r-- | addons/base_module_quality/pylint_test/pylint_test.py | 34 | ||||
| -rw-r--r-- | addons/base_module_quality/pylint_test/pylint_test_config.txt | 308 | ||||
| -rw-r--r-- | addons/base_module_quality/speed_test/__init__.py (renamed from addons/base_module_quality/wizard/pylint_test/__init__.py) | 3 | ||||
| -rw-r--r-- | addons/base_module_quality/speed_test/speed_test.py | 48 | ||||
| -rw-r--r-- | addons/base_module_quality/wizard/module_quality_check.py | 69 | ||||
| -rw-r--r-- | addons/base_module_quality/wizard/pylint_test/pylint_test.py | 83 |
10 files changed, 412 insertions, 167 deletions
diff --git a/addons/base_module_quality/README.txt b/addons/base_module_quality/README.txt new file mode 100644 index 00000000000..3819448c9c1 --- /dev/null +++ b/addons/base_module_quality/README.txt @@ -0,0 +1,11 @@ +This module provide a generic framework to define your own quality test. + + +All you have to do is to: +* create a folder with your test in 'base_module_quality' (e.g: mkdir base_module_quality\mytest) +* create a .py file in it with same name as the folder you just created (e.g: touch base_module_quality\mytest\mytest.py) +* edit your file and define a class 'quality_check' that + * inherits the class 'abstract_quality_test' (defined in base_module_quality.py) + * implements the __init__() method accordingly to what you want to test. + + diff --git a/addons/base_module_quality/__terp__.py b/addons/base_module_quality/__terp__.py index f80077e2b94..4a4d5b9fc60 100644 --- a/addons/base_module_quality/__terp__.py +++ b/addons/base_module_quality/__terp__.py @@ -24,7 +24,15 @@ "author" : "Tiny", "version" : "1.0", "depends" : ["base",], - "description": "Sample module to check the quality", + "description": """" +This module's aim is to check the quality of other modules. + + It defines a wizard on the list of modules in OpenERP, which allow you to evaluate them on different critera such as: the respect of OpenERP coding standards, the speed efficency... + + + This module also provide generic framework to define your own quality test. For further info, coders may take a look into base_module_quality\README.txt + +""", "init_xml" : [], "update_xml" : ["base_module_quality_wizard.xml"], "category" : "Tiny Specific Modules/Base module quality", diff --git a/addons/base_module_quality/base_module_quality.py b/addons/base_module_quality/base_module_quality.py index 2a49f301b87..13b9de20ce4 100644 --- a/addons/base_module_quality/base_module_quality.py +++ b/addons/base_module_quality/base_module_quality.py @@ -23,7 +23,7 @@ import netsvc from osv import fields, osv -class quality_check(object): +class abstract_quality_check(object): ''' This Class provide... ''' @@ -38,15 +38,6 @@ class quality_check(object): ''' raise 'Not Implemented' - #~ def __get_result__(self, cr, uid, module_ids): - #~ ''' - #~ ''' - #~ return _result - - #~ def __get_detailed_result__(self, cr, uid, module_ids): - #~ ''' - #~ ''' - #~ return _result_details # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/base_module_quality/pylint_test/__init__.py b/addons/base_module_quality/pylint_test/__init__.py index 00dce4b7e0b..10b090b0edd 100644 --- a/addons/base_module_quality/pylint_test/__init__.py +++ b/addons/base_module_quality/pylint_test/__init__.py @@ -20,7 +20,7 @@ # ############################################################################## -import pylint_test +#import pylint_test # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/base_module_quality/pylint_test/pylint_test.py b/addons/base_module_quality/pylint_test/pylint_test.py index c31a5c6599d..1d46830f646 100644 --- a/addons/base_module_quality/pylint_test/pylint_test.py +++ b/addons/base_module_quality/pylint_test/pylint_test.py @@ -23,36 +23,12 @@ import netsvc from osv import fields, osv import os -from base_module_quality import base_module_quality +from tools import config -#~ class _test_pylint(quality_check): +from base_module_quality import base_module_quality - #~ def __init__(self, url, add_folder=None): - #~ print "dans le test" - #~ list_files = os.listdir(url) - #~ new_list = [] - #~ subfolder = {} - #~ for i in list_files: - #~ if os.path.isdir(i): - #~ path = os.path.join(url, i) - #~ new_list.append(os.listdir(path)) - #~ res = _test_pylint(self, path, add_folder=i) - #~ subfolder.update(res) - #~ dict_files = {} - #~ for file in list_files: - #~ if file.split('.')[-1] == 'py' and not file.startswith('__init__'): - #~ file_path = os.path.join(url, file) - #~ res = os.popen('pylint '+file_path+' | tail -4').read() - #~ if res.startswith('Global'): - #~ if add_folder: - #~ dict_files[add_folder + '/' + file] = res - #~ else: - #~ dict_files[file] = res - #~ dict_files.update(subfolder) - #~ print "dict_files", dict_files - #~ return dict_files -class _test_pylint(base_module_quality.quality_check): +class quality_test(base_module_quality.abstract_quality_check): def __init__(self, module_path): self._result = """ @@ -63,6 +39,7 @@ Pylint Test: """ + config_file_path = config['addons_path']+'/base_module_quality/pylint_test/pylint_test_config.txt' list_files = os.listdir(module_path) new_list = [] subfolder = {} @@ -78,9 +55,8 @@ Pylint Test: print list_files for file in list_files: if file.split('.')[-1] == 'py' and not file.endswith('__init__.py') and not file.endswith('__terp__.py'): -#--rcfile=<file> Specify a configuration file. file_path = os.path.join(module_path, file) - res = os.popen('pylint --persistent=n '+file_path).read() + res = os.popen('pylint --rcfile='+config_file_path+' '+file_path).read() n += 1 leftchar = -1 while res[leftchar:leftchar+1] != ' ' and leftchar-1 <= 0: diff --git a/addons/base_module_quality/pylint_test/pylint_test_config.txt b/addons/base_module_quality/pylint_test/pylint_test_config.txt new file mode 100644 index 00000000000..db975430f08 --- /dev/null +++ b/addons/base_module_quality/pylint_test/pylint_test_config.txt @@ -0,0 +1,308 @@ +# lint Python modules using external checkers. +# +# This is the main checker controling the other ones and the reports +# generation. It is itself both a raw checker and an astng checker in order +# to: +# * handle message activation / deactivation at the module level +# * handle some basic but necessary stats'data (number of classes, methods...) +# +[MASTER] + +# Specify a configuration file. +#rcfile= + +# Profiled execution. +profile=no + +# Add <file or directory> to the black list. It should be a base name, not a +# path. You may set this option multiple times. +ignore=CVS + +# Pickle collected data for later comparisons. +persistent=no + +# Set the cache size for astng objects. +cache-size=500 + +# List of plugins (as comma separated values of python modules names) to load, +# usually to register additional checkers. +load-plugins= + + +[COMMANDS] + +# Display a help message for the given message id and exit. The value may be a +# comma separated list of message ids. +#help-msg= + + +[MESSAGES CONTROL] + +# Enable only checker(s) with the given id(s). This option conflict with the +# disable-checker option +#enable-checker= + +# Enable all checker(s) except those with the given id(s). This option conflict +# with the disable-checker option +#disable-checker= + +# Enable all messages in the listed categories. +#enable-msg-cat= + +# Disable all messages in the listed categories. +#disable-msg-cat= + +# Enable the message(s) with the given id(s). +#enable-msg= + +# Disable the message(s) with the given id(s). +#disable-msg= + + +[REPORTS] + +# set the output format. Available formats are text, parseable, colorized and +# html +output-format=text + +# Include message's id in output +include-ids=no + +# Put messages in a separate file for each module / package specified on the +# command line instead of printing them on stdout. Reports (if any) will be +# written in a file name "pylint_global.[txt|html]". +files-output=no + +# Tells wether to display a full report or only the messages +reports=yes + +# Python expression which should return a note less than 10 (10 is the highest +# note).You have access to the variables errors warning, statement which +# respectivly contain the number of errors / warnings messages and the total +# number of statements analyzed. This is used by the global evaluation report +# (R0004). +evaluation=10.0 - ((float(5 * error + warning + refactor + convention) / statement) * 10) + +# Add a comment according to your evaluation note. This is used by the global +# evaluation report (R0004). +comment=no + +# Enable the report(s) with the given id(s). +#enable-report= + +# Disable the report(s) with the given id(s). +#disable-report= + + +# checks for +# * unused variables / imports +# * undefined variables +# * redefinition of variable from builtins or from an outer scope +# * use of variable before assigment +# +[VARIABLES] + +# Tells wether we should check for unused import in __init__ files. +init-import=no + +# A regular expression matching names used for dummy variables (i.e. not used). +dummy-variables-rgx=_|dummy + +# List of additional names supposed to be defined in builtins. Remember that +# you should avoid to define new builtins when possible. +additional-builtins= + + +# try to find bugs in the code using type inference +# +[TYPECHECK] + +# Tells wether missing members accessed in mixin class should be ignored. A +# mixin class is detected if its name ends with "mixin" (case insensitive). +ignore-mixin-members=yes + +# When zope mode is activated, consider the acquired-members option to ignore +# access to some undefined attributes. +zope=no + +# List of members which are usually get through zope's acquisition mecanism and +# so shouldn't trigger E0201 when accessed (need zope=yes to be considered). +acquired-members=REQUEST,acl_users,aq_parent + + +# checks for : +# * doc strings +# * modules / classes / functions / methods / arguments / variables name +# * number of arguments, local variables, branchs, returns and statements in +# functions, methods +# * required module attributes +# * dangerous default values as arguments +# * redefinition of function / method / class +# * uses of the global statement +# +[BASIC] + +# Required attributes for module, separated by a comma +required-attributes= + +# Regular expression which should only match functions or classes name which do +# not require a docstring +no-docstring-rgx=__.*__ + +# Regular expression which should only match correct module names +module-rgx=(([a-z_][a-z0-9_]*)|([A-Z][a-zA-Z0-9]+))$ + +# Regular expression which should only match correct module level names +const-rgx=(([A-Z_][A-Z1-9_]*)|(__.*__))$ + +# Regular expression which should only match correct class names +class-rgx=[A-Z_][a-zA-Z0-9]+$ + +# Regular expression which should only match correct function names +function-rgx=[a-z_][a-z0-9_]{2,30}$ + +# Regular expression which should only match correct method names +method-rgx=[a-z_][a-z0-9_]{2,30}$ + +# Regular expression which should only match correct instance attribute names +attr-rgx=[a-z_][a-z0-9_]{2,30}$ + +# Regular expression which should only match correct argument names +argument-rgx=[a-z_][a-z0-9_]{2,30}$ + +# Regular expression which should only match correct variable names +variable-rgx=[a-z_][a-z0-9_]{2,30}$ + +# Regular expression which should only match correct list comprehension / +# generator expression variable names +inlinevar-rgx=[A-Za-z_][A-Za-z0-9_]*$ + +# Good variable names which should always be accepted, separated by a comma +good-names=i,j,k,ex,Run,_ + +# Bad variable names which should always be refused, separated by a comma +bad-names=foo,bar,baz,toto,tutu,tata + +# List of builtins function names that should not be used, separated by a comma +bad-functions=map,filter,apply,input + + +# checks for +# * external modules dependencies +# * relative / wildcard imports +# * cyclic imports +# * uses of deprecated modules +# +[IMPORTS] + +# Deprecated modules which should not be used, separated by a comma +deprecated-modules=regsub,string,TERMIOS,Bastion,rexec + +# Create a graph of every (i.e. internal and external) dependencies in the +# given file (report R0402 must not be disabled) +import-graph= + +# Create a graph of external dependencies in the given file (report R0402 must +# not be disabled) +ext-import-graph= + +# Create a graph of internal dependencies in the given file (report R0402 must +# not be disabled) +int-import-graph= + + +# checks for : +# * methods without self as first argument +# * overridden methods signature +# * access only to existant members via self +# * attributes not defined in the __init__ method +# * supported interfaces implementation +# * unreachable code +# +[CLASSES] + +# List of interface methods to ignore, separated by a comma. This is used for +# instance to not check methods defines in Zope's Interface base class. +ignore-iface-methods=isImplementedBy,deferred,extends,names,namesAndDescriptions,queryDescriptionFor,getBases,getDescriptionFor,getDoc,getName,getTaggedValue,getTaggedValueTags,isEqualOrExtendedBy,setTaggedValue,isImplementedByInstancesOf,adaptWith,is_implemented_by + +# List of method names used to declare (i.e. assign) instance attributes. +defining-attr-methods=__init__,__new__,setUp + + +# checks for sign of poor/misdesign: +# * number of methods, attributes, local variables... +# * size, complexity of functions, methods +# +[DESIGN] + +# Maximum number of arguments for function / method +max-args=5 + +# Maximum number of locals for function / method body +max-locals=15 + +# Maximum number of return / yield for function / method body +max-returns=6 + +# Maximum number of branch for function / method body +max-branchs=12 + +# Maximum number of statements in function / method body +max-statements=50 + +# Maximum number of parents for a class (see R0901). +max-parents=7 + +# Maximum number of attributes for a class (see R0902). +max-attributes=7 + +# Minimum number of public methods for a class (see R0903). +min-public-methods=2 + +# Maximum number of public methods for a class (see R0904). +max-public-methods=20 + + +# checks for : +# * unauthorized constructions +# * strict indentation +# * line length +# * use of <> instead of != +# +[FORMAT] + +# Maximum number of characters on a single line. +max-line-length=80 + +# Maximum number of lines in a module +max-module-lines=1000 + +# String used as indentation unit. This is usually " " (4 spaces) or "\t" (1 +# tab). +indent-string=' ' + + +# checks for similarities and duplicated code. This computation may be +# memory / CPU intensive, so you should disable it if you experiments some +# problems. +# +[SIMILARITIES] + +# Minimum lines number of a similarity. +min-similarity-lines=4 + +# Ignore comments when computing similarities. +ignore-comments=yes + +# Ignore docstrings when computing similarities. +ignore-docstrings=yes + + +# checks for: +# * warning notes in the code like FIXME, XXX +# * PEP 263: source code with non ascii character but no encoding declaration +# +[MISCELLANEOUS] + +# List of note tags to take in consideration, separated by a comma. +notes=FIXME,XXX,TODO diff --git a/addons/base_module_quality/wizard/pylint_test/__init__.py b/addons/base_module_quality/speed_test/__init__.py index 79bc02a75a6..79850888f41 100644 --- a/addons/base_module_quality/wizard/pylint_test/__init__.py +++ b/addons/base_module_quality/speed_test/__init__.py @@ -20,6 +20,5 @@ # ############################################################################## -import pylint_test -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/base_module_quality/speed_test/speed_test.py b/addons/base_module_quality/speed_test/speed_test.py new file mode 100644 index 00000000000..ca9a93b09f7 --- /dev/null +++ b/addons/base_module_quality/speed_test/speed_test.py @@ -0,0 +1,48 @@ +# -*- encoding: utf-8 -*- +############################################################################## +# +# OpenERP, Open Source Management Solution +# Copyright (C) 2004-2008 Tiny SPRL (<http://tiny.be>). All Rights Reserved +# $Id$ +# +# 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 3 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, see <http://www.gnu.org/licenses/>. +# +############################################################################## + +import netsvc +from osv import fields, osv +import os +from tools import config + +from base_module_quality import base_module_quality + + +class quality_test(base_module_quality.abstract_quality_check): + + def __init__(self, module_path): + self._result = """ +Speed Test: +------------ + + This test checks the speed of the module + + + to be continued... + +""" + return None + + +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: + diff --git a/addons/base_module_quality/wizard/module_quality_check.py b/addons/base_module_quality/wizard/module_quality_check.py index 0e606a70f8e..61cc031261a 100644 --- a/addons/base_module_quality/wizard/module_quality_check.py +++ b/addons/base_module_quality/wizard/module_quality_check.py @@ -27,21 +27,20 @@ import netsvc import sys import tools import os -import pylint -import base_module_quality - -form_check = '''<?xml version="1.0"?> -<form string="Quality check"> - <field name="test" /> -</form>''' - -fields_check = { - 'test': { - 'string':'Tests', 'type':'selection', 'required':True, - 'selection': [('pylint', 'Pylint'), ('othertest','other')], - 'default': lambda *args: 'pylint' - }, - } + + +#~ form_check = '''<?xml version="1.0"?> +#~ <form string="Quality check"> + #~ <field name="test" /> +#~ </form>''' + +#~ fields_check = { + #~ 'test': { + #~ 'string':'Tests', 'type':'selection', 'required':True, + #~ 'selection': [('pylint', 'Pylint'), ('othertest','other')], + #~ 'default': lambda *args: 'pylint' + #~ }, + #~ } view_form = """<?xml version="1.0"?> <form string="Check quality"> @@ -69,46 +68,34 @@ class wiz_quality_check(wizard.interface): from tools import config list_folders=os.listdir(config['addons_path']+'/base_module_quality/') for item in list_folders: - path = config['addons_path']+'/base_module_quality/wizard/'+item + path = config['addons_path']+'/base_module_quality/'+item if os.path.exists(path+'/'+item+'.py') and item not in ['report','wizard', 'security']: pool=pooler.get_pool(cr.dbname) module_data = pool.get('ir.module.module').browse(cr, uid, data['ids']) ad = tools.config['addons_path'] module_path = os.path.join(ad, module_data[0].name) - #import pylint_test - item='base_module_quality.'+item - x = __import__(item) - val = x.__init__(str(module_path)) - print "VALL",x._result + + from base_module_quality import base_module_quality + + item2='base_module_quality.'+item+'.'+item + x = __import__(item2) + x2 = getattr(x,item) + x3 = getattr(x2,item) + val = x3.quality_test(str(module_path)) + string_ret += val._result return {'general_info':string_ret} - #mra version - #~ result = pylint_test._test_pylint(self, url) - #~ string_ret = '' - #~ for i in result: - #~ string_ret = string_ret + i + ':\n' + result[i] - #~ string_ret = "" - #~ if data['form']['test'] == 'pylint': - #~ pool=pooler.get_pool(cr.dbname) - #~ module_data = pool.get('ir.module.module').browse(cr, uid, data['ids']) - #~ from pylint_test import pylint_test - #~ ad = tools.config['addons_path'] - #~ url = os.path.join(ad, module_data[0].name) - #~ result = pylint_test._test_pylint(self, url) - #~ string_ret = '' - #~ for i in result: - #~ string_ret = string_ret + i + ':\n' + result[i] states = { + #~ 'init': { + #~ 'actions': [], + #~ 'result': {'type':'form', 'arch':form_check, 'fields':fields_check, 'state':[('end','Cancel'),('do','Do Test')]} + #~ }, 'init': { - 'actions': [], - 'result': {'type':'form', 'arch':form_check, 'fields':fields_check, 'state':[('end','Cancel'),('do','Do Test')]} - }, - 'do': { 'actions': [_check], 'result': {'type':'form', 'arch':view_form, 'fields':view_field, 'state':[('end','Ok')]}, }, diff --git a/addons/base_module_quality/wizard/pylint_test/pylint_test.py b/addons/base_module_quality/wizard/pylint_test/pylint_test.py deleted file mode 100644 index 6e80e136865..00000000000 --- a/addons/base_module_quality/wizard/pylint_test/pylint_test.py +++ /dev/null @@ -1,83 +0,0 @@ -# -*- encoding: utf-8 -*- -############################################################################## -# -# OpenERP, Open Source Management Solution -# Copyright (C) 2004-2008 Tiny SPRL (<http://tiny.be>). All Rights Reserved -# $Id$ -# -# 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 3 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, see <http://www.gnu.org/licenses/>. -# -############################################################################## - -import netsvc -from osv import fields, osv -import os - - - -class _test_pylint(quality_check): - - def __init__(self, url, add_folder=None): - print "dans le test" - list_files = os.listdir(url) - new_list = [] - subfolder = {} - for i in list_files: - if os.path.isdir(i): - path = os.path.join(url, i) - new_list.append(os.listdir(path)) - res = _test_pylint(self, path, add_folder=i) - subfolder.update(res) - dict_files = {} - for file in list_files: - if file.split('.')[-1] == 'py' and not file.startswith('__init__'): - file_path = os.path.join(url, file) - res = os.popen('pylint '+file_path+' | tail -4').read() - if res.startswith('Global'): - if add_folder: - dict_files[add_folder + '/' + file] = res - else: - dict_files[file] = res - dict_files.update(subfolder) - print "dict_files", dict_files - return dict_files - -_test_pylint() - - -#~ def _test_pylint(self, url, add_folder=None): - #~ list_files = os.listdir(url) - #~ new_list = [] - #~ subfolder = {} - #~ for i in list_files: - #~ if os.path.isdir(i): - #~ path = os.path.join(url, i) - #~ new_list.append(os.listdir(path)) - #~ res = _test_pylint(self, path, add_folder=i) - #~ subfolder.update(res) - #~ dict_files = {} - #~ for file in list_files: - #~ if file.split('.')[-1] == 'py' and not file.startswith('__init__'): - #~ file_path = os.path.join(url, file) - #~ res = os.popen('pylint '+file_path+' | tail -4').read() - #~ if res.startswith('Global'): - #~ if add_folder: - #~ dict_files[add_folder + '/' + file] = res - #~ else: - #~ dict_files[file] = res - #~ dict_files.update(subfolder) - #~ return dict_files - -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: - |
