Skip to content
This repository has been archived by the owner on May 16, 2024. It is now read-only.

Commit

Permalink
Merge a84855a into a688099
Browse files Browse the repository at this point in the history
  • Loading branch information
moylop260 committed Aug 18, 2015
2 parents a688099 + a84855a commit a3fe3a1
Show file tree
Hide file tree
Showing 13 changed files with 361 additions and 21 deletions.
4 changes: 3 additions & 1 deletion .travis.yml
Expand Up @@ -31,7 +31,9 @@ env:
- INCLUDE="test_module,second_module" UNIT_TEST="1"
- VERSION="7.0" INCLUDE="test_module,second_module" ODOO_REPO="OCA/OCB" # ODOO_REPO usage example
- VERSION="6.1" INCLUDE="test_module,second_module"
- LINT_CHECK="1" TESTS="0"
- LINT_CHECK="1" TESTS="0" PYLINT_EXPECTED_ERRORS="17" TRAVIS_PULL_REQUEST="false" # Use main pylint config file
- VERSION="master" LINT_CHECK="1" TESTS="0" PYLINT_EXPECTED_ERRORS="18" TRAVIS_PULL_REQUEST="true" # Use PR pylint config file
- VERSION="7.0" LINT_CHECK="1" TESTS="0" PYLINT_EXPECTED_ERRORS="17" TRAVIS_PULL_REQUEST="true" # Use PR pylint config file but with params changed by odoo version

install:
- cp -r ../maintainer-quality-tools/ $HOME
Expand Down
1 change: 1 addition & 0 deletions tests/test_repo/broken_module/I0013.py
@@ -0,0 +1 @@
# pylint: skip-file
1 change: 1 addition & 0 deletions tests/test_repo/broken_module/ipdb.py
@@ -0,0 +1 @@
# W0402(deprecated-module) require module present
66 changes: 65 additions & 1 deletion tests/test_repo/broken_module/model.py
@@ -1,8 +1,72 @@

from openerp.osv import orm, fields

import os
import os as os2 # W0404 - duplicated import

import __openerp__ # W0403 - relative import

# w0402 - deprecated module
import pdb # pylint: disable=W0403
import pudb # pylint: disable=W0403
import ipdb # pylint: disable=W0403

class TestModel(orm.Model):

class test_model(orm.Model):
_name = "test.model"
_columns = {
'name': fields.char('Title', 100),
}

def method_test(self, arg1, arg2):
return None

def method_e1124(self):
value = self.method_test(
'arg_param1', arg1='arg_param1')
return value

def method_e1306(self):
return "%s %s" % ('value1')

def method_e1601(self):
print "Hello world!"

def method_w0101(self):
return True
return False

def method_w0102(self, arg1, arg2=[]):
# avoid imported but unused
all_imports = (
os, os2, __openerp__, pdb, pudb, ipdb)
return all_imports

def method_w0104_w0105(self):
2*6*0
"str any effect"

def method_w0109(self):
my_duplicated_key_dict = {
'key1': 'value1',
'key2': 'value2',
'key1': 'value3',
}
return my_duplicated_key_dict

def method_w1401(self):
my_regex_str_bad = '\d'
my_regex_str_good = r'\d'
return my_regex_str_bad, my_regex_str_good


if __name__ == '__main__':

def method_w1111():
return None

VAR1 = method_w1111()

class E0101(object):
def __init__(self):
return 'E0101'
1 change: 1 addition & 0 deletions tests/test_repo/broken_module/pdb.py
@@ -0,0 +1 @@
# W0402(deprecated-module) require module present
1 change: 1 addition & 0 deletions tests/test_repo/broken_module/pudb.py
@@ -0,0 +1 @@
# W0402(deprecated-module) require module present
42 changes: 42 additions & 0 deletions travis/cfg/travis_run_pylint_pr.cfg
@@ -0,0 +1,42 @@
[MASTER]
profile=no
ignore=CVS,.git,scenarios,.bzr,__openerp__.py,__odoo__.py,__terp__.py
persistent=yes
cache-size=500

[MESSAGES CONTROL]
disable=all
enable=invalid-name,

[REPORTS]
msg-template={path}:{line}: [{msg_id}({symbol}), {obj}] {msg}
output-format=colorized
files-output=no
reports=no
evaluation=10.0 - ((float(5 * error + warning + refactor + convention) / statement) * 10)
comment=no

[FORMAT]
indent-string=' '

[BASIC]
class-rgx=[A-Z_][a-zA-Z0-9]{2,45}
module-rgx=.*
const-rgx=.*
function-rgx=.*
method-rgx=.*
attr-rgx=.*
argument-rgx=.*
variable-rgx=.*
inlinevar-rgx=.*

[SIMILARITIES]
ignore-comments=yes
ignore-docstrings=yes

[MISCELLANEOUS]
notes=

[IMPORTS]
deprecated-modules=pdb,pudb,ipdb

23 changes: 23 additions & 0 deletions travis/getaddons.py
Expand Up @@ -9,6 +9,7 @@
import os
import sys

from git_run import GitRun

MANIFEST_FILES = ['__odoo__.py', '__openerp__.py', '__terp__.py']

Expand Down Expand Up @@ -56,6 +57,28 @@ def get_addons(path):
return res


def get_modules_changed(path, ref='HEAD'):
'''Get modules changed from git diff-index {ref}
:param path: String path of git repo
:param ref: branch or remote/branch or sha to compare
:return: List of paths of modules changed
'''
git_run_obj = GitRun(os.path.join(path, '.git'))
git_run_obj.run(['fetch'] + ref.split('/'))
items_changed = git_run_obj.get_items_changed(ref)
folders_changed = set([
item_changed.split('/')[0]
for item_changed in items_changed
if '/' in item_changed]
)
modules = set(get_modules(path))
modules_changed = list(modules & folders_changed)
modules_changed_path = [
os.path.join(path, module_changed)
for module_changed in modules_changed]
return modules_changed_path


def main(argv=None):
if argv is None:
argv = sys.argv
Expand Down
36 changes: 36 additions & 0 deletions travis/git_run.py
@@ -0,0 +1,36 @@
# -*- coding: utf-8 -*-

import subprocess


class GitRun(object):
def __init__(self, repo_path):
self.repo_path = repo_path

def run(self, command):
"""Execute git command in bash
:param list command: Git cmd to execute in self.repo_path
:return: String output of command executed.
"""
cmd = ['git', '--git-dir=' + self.repo_path] + command
try:
res = subprocess.check_output(cmd)
except subprocess.CalledProcessError:
res = None
if isinstance(res, basestring):
res = res.strip('\n')
return res

def get_items_changed(self, base_ref='HEAD'):
"""Get name of items changed in self.repo_path
This is a wrapper method of git command:
git diff-index --name-only --cached {base_ref}
:param base_ref: String of branch or sha base.
e.g. "master" or "SHA_NUMBER"
:return: List of name of items changed
"""
command = ['diff-index', '--name-only',
'--cached', base_ref]
res = self.run(command)
items = res.split('\n') if res else []
return items
98 changes: 98 additions & 0 deletions travis/run_pylint.py
@@ -0,0 +1,98 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-

from __future__ import print_function

import os
import sys

import click
import pylint.lint

CLICK_DIR = click.Path(exists=True, dir_okay=True, resolve_path=True)


def get_count_fails(linter_stats):
"""Verify the dictionary statistics to get number of errors.
:param linter_stats: Dict of type pylint.lint.Run().linter.stats
:return: Integer with quantity of fails found.
"""
count = 0
for msg in linter_stats['by_msg']:
count += linter_stats['by_msg'][msg]
return count


def get_subpaths(paths):
"""Get list of subdirectories
if `__init__.py` file not exists in root path then
get subdirectories.
Why? More info here:
https://www.mail-archive.com/code-quality@python.org/msg00294.html
:param paths: List of paths
:return: Return list of paths with subdirectories.
"""
subpaths = []
for path in paths:
subpaths.append(path)
if not os.path.isfile(os.path.join(path, '__init__.py')):
subpaths.extend(
[os.path.join(path, item)
for item in os.listdir(path)
if os.path.isdir(os.path.join(path, item))])
return subpaths


def run_pylint(paths, cfg, sys_paths=None, extra_params=None):
"""Execute pylint command from original python library
:param paths: List of paths of python modules to check pylint
:param cfg: String name of pylint configuration file
:param sys_paths: List of paths to append to sys path
:param extra_params: List of parameters extra to append
in pylint command
:return: Dict with python linter stats
"""
if sys_paths is None:
sys_paths = []
if extra_params is None:
extra_params = []
sys.path.extend(sys_paths)
cmd = ['--rcfile=' + cfg]
cmd.extend(extra_params)
subpaths = get_subpaths(paths)
cmd.extend(subpaths)
pylint_res = pylint.lint.Run(cmd, exit=False)
return pylint_res.linter.stats


@click.command()
@click.option('paths', '--path', envvar='TRAVIS_BUILD_DIR',
multiple=True, type=CLICK_DIR, required=True,
help="Addons paths to check pylint")
@click.option('--config-file', '-c',
type=click.File('r', lazy=True), required=True,
help="Pylint config file")
@click.option('--sys-paths', '-sys-path', envvar='PYTHONPATH',
multiple=True, type=CLICK_DIR,
help="Additional paths to append in sys path.")
@click.option('--extra-params', '-extra-param', multiple=True,
help="Extra pylint params to append "
"in pylint command")
def main(paths, config_file, sys_paths=None, extra_params=None):
"""Script to run pylint command with additional params
to check fails of odoo modules.
If expected errors is equal to count fails found then
this program exit with zero otherwise exit with counted fails"""
stats = run_pylint(
list(paths), config_file.name, sys_paths=sys_paths,
extra_params=extra_params)
count_fails = get_count_fails(stats)
return count_fails


if __name__ == '__main__':
try:
exit(main(standalone_mode=False))
except click.ClickException as e:
e.show()
exit(e.exit_code)
3 changes: 3 additions & 0 deletions travis/self_tests
Expand Up @@ -30,3 +30,6 @@ assert travis_helpers.red(u'test') == u"\033[1;31mtest\033[0;m"
assert travis_helpers.green(u'test') == u"\033[1;32mtest\033[0;m"
assert travis_helpers.yellow(u'test') == u"\033[1;33mtest\033[0;m"
assert travis_helpers.yellow_light(u'test') == u"\033[33mtest\033[0;m"

# Testing git run from getaddons
getaddons.get_modules_changed(repo_dir)

0 comments on commit a3fe3a1

Please sign in to comment.