From: Ihar Hrachyshka Date: Fri, 23 Jan 2015 14:02:52 +0000 (+0100) Subject: Remove check_i18n tox target X-Git-Url: https://review.fuel-infra.org/gitweb?a=commitdiff_plain;h=8714ab28090f7a43f5cb3e712d554da0dc58bed7;p=openstack-build%2Fneutron-build.git Remove check_i18n tox target Now that we have hacking rules to check proper localization, drop the target. Change-Id: Idf6e6c9e6096c4b7b2034be94c88460b744b7532 --- diff --git a/tools/check_i18n.py b/tools/check_i18n.py deleted file mode 100644 index 697ad180d..000000000 --- a/tools/check_i18n.py +++ /dev/null @@ -1,153 +0,0 @@ -# Copyright 2012 OpenStack Foundation -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. -from __future__ import print_function - -import compiler -import imp -import os.path -import sys - - -def is_localized(node): - """Check message wrapped by _()""" - if isinstance(node.parent, compiler.ast.CallFunc): - if isinstance(node.parent.node, compiler.ast.Name): - if node.parent.node.name == '_': - return True - return False - - -class ASTWalker(compiler.visitor.ASTVisitor): - - def default(self, node, *args): - for child in node.getChildNodes(): - child.parent = node - compiler.visitor.ASTVisitor.default(self, node, *args) - - -class Visitor(object): - - def __init__(self, filename, i18n_msg_predicates, - msg_format_checkers, debug): - self.filename = filename - self.debug = debug - self.error = 0 - self.i18n_msg_predicates = i18n_msg_predicates - self.msg_format_checkers = msg_format_checkers - with open(filename) as f: - self.lines = f.readlines() - - def visitConst(self, node): - if not isinstance(node.value, str): - return - - if is_localized(node): - for (checker, msg) in self.msg_format_checkers: - if checker(node): - print('%s:%d %s: %s Error: %s' % - (self.filename, node.lineno, - self.lines[node.lineno - 1][:-1], - checker.__name__, msg), - file=sys.stderr) - self.error = 1 - return - if debug: - print('%s:%d %s: %s' % - (self.filename, node.lineno, - self.lines[node.lineno - 1][:-1], - "Pass")) - else: - for (predicate, action, msg) in self.i18n_msg_predicates: - if predicate(node): - if action == 'skip': - if debug: - print('%s:%d %s: %s' % - (self.filename, node.lineno, - self.lines[node.lineno - 1][:-1], - "Pass")) - return - elif action == 'error': - print('%s:%d %s: %s Error: %s' % - (self.filename, node.lineno, - self.lines[node.lineno - 1][:-1], - predicate.__name__, msg), - file=sys.stderr) - self.error = 1 - return - elif action == 'warn': - print('%s:%d %s: %s' % - (self.filename, node.lineno, - self.lines[node.lineno - 1][:-1], - "Warn: %s" % msg)) - return - print('Predicate with wrong action!', file=sys.stderr) - - -def is_file_in_black_list(black_list, f): - for f in black_list: - if os.path.abspath(input_file).startswith( - os.path.abspath(f)): - return True - return False - - -def check_i18n(input_file, i18n_msg_predicates, msg_format_checkers, debug): - input_mod = compiler.parseFile(input_file) - v = compiler.visitor.walk(input_mod, - Visitor(input_file, - i18n_msg_predicates, - msg_format_checkers, - debug), - ASTWalker()) - return v.error - - -if __name__ == '__main__': - input_path = sys.argv[1] - cfg_path = sys.argv[2] - try: - cfg_mod = imp.load_source('', cfg_path) - except Exception: - print("Load cfg module failed", file=sys.stderr) - sys.exit(1) - - i18n_msg_predicates = cfg_mod.i18n_msg_predicates - msg_format_checkers = cfg_mod.msg_format_checkers - black_list = cfg_mod.file_black_list - - debug = False - if len(sys.argv) > 3: - if sys.argv[3] == '-d': - debug = True - - if os.path.isfile(input_path): - sys.exit(check_i18n(input_path, - i18n_msg_predicates, - msg_format_checkers, - debug)) - - error = 0 - for dirpath, dirs, files in os.walk(input_path): - for f in files: - if not f.endswith('.py'): - continue - input_file = os.path.join(dirpath, f) - if is_file_in_black_list(black_list, input_file): - continue - if check_i18n(input_file, - i18n_msg_predicates, - msg_format_checkers, - debug): - error = 1 - sys.exit(error) diff --git a/tools/check_i18n_test_case.txt b/tools/check_i18n_test_case.txt deleted file mode 100644 index 3d1391d94..000000000 --- a/tools/check_i18n_test_case.txt +++ /dev/null @@ -1,67 +0,0 @@ -# test-case for check_i18n.py -# python check_i18n.py check_i18n.txt -d - -# message format checking -# capital checking -msg = _("hello world, error") -msg = _("hello world_var, error") -msg = _('file_list xyz, pass') -msg = _("Hello world, pass") - -# format specifier checking -msg = _("Hello %s world %d, error") -msg = _("Hello %s world, pass") -msg = _("Hello %(var1)s world %(var2)s, pass") - -# message has been localized -# is_localized -msg = _("Hello world, pass") -msg = _("Hello world, pass") % var -LOG.debug(_('Hello world, pass')) -LOG.info(_('Hello world, pass')) -raise x.y.Exception(_('Hello world, pass')) -raise Exception(_('Hello world, pass')) - -# message need be localized -# is_log_callfunc -LOG.debug('hello world, error') -LOG.debug('hello world, error' % xyz) -sys.append('hello world, warn') - -# is_log_i18n_msg_with_mod -LOG.debug(_('Hello world, error') % xyz) - -# default warn -msg = 'hello world, warn' -msg = 'hello world, warn' % var - -# message needn't be localized -# skip only one word -msg = '' -msg = "hello,pass" - -# skip dict -msg = {'hello world, pass': 1} - -# skip list -msg = ["hello world, pass"] - -# skip subscript -msg['hello world, pass'] - -# skip xml marker -msg = ", pass" - -# skip sql statement -msg = "SELECT * FROM xyz WHERE hello=1, pass" -msg = "select * from xyz, pass" - -# skip add statement -msg = 'hello world' + e + 'world hello, pass' - -# skip doc string -""" -Hello world, pass -""" -class Msg: - pass diff --git a/tools/i18n_cfg.py b/tools/i18n_cfg.py deleted file mode 100644 index 5ad1a514d..000000000 --- a/tools/i18n_cfg.py +++ /dev/null @@ -1,97 +0,0 @@ -import compiler -import re - - -def is_log_callfunc(n): - """LOG.xxx('hello %s' % xyz) and LOG('hello')""" - if isinstance(n.parent, compiler.ast.Mod): - n = n.parent - if isinstance(n.parent, compiler.ast.CallFunc): - if isinstance(n.parent.node, compiler.ast.Getattr): - if isinstance(n.parent.node.getChildNodes()[0], - compiler.ast.Name): - if n.parent.node.getChildNodes()[0].name == 'LOG': - return True - return False - - -def is_log_i18n_msg_with_mod(n): - """LOG.xxx("Hello %s" % xyz) should be LOG.xxx("Hello %s", xyz)""" - if not isinstance(n.parent.parent, compiler.ast.Mod): - return False - n = n.parent.parent - if isinstance(n.parent, compiler.ast.CallFunc): - if isinstance(n.parent.node, compiler.ast.Getattr): - if isinstance(n.parent.node.getChildNodes()[0], - compiler.ast.Name): - if n.parent.node.getChildNodes()[0].name == 'LOG': - return True - return False - - -def is_wrong_i18n_format(n): - """Check _('hello %s' % xyz)""" - if isinstance(n.parent, compiler.ast.Mod): - n = n.parent - if isinstance(n.parent, compiler.ast.CallFunc): - if isinstance(n.parent.node, compiler.ast.Name): - if n.parent.node.name == '_': - return True - return False - - -""" -Used for check message need be localized or not. -(predicate_func, action, message) -""" -i18n_msg_predicates = [ - # Skip ['hello world', 1] - (lambda n: isinstance(n.parent, compiler.ast.List), 'skip', ''), - # Skip {'hellow world', 1} - (lambda n: isinstance(n.parent, compiler.ast.Dict), 'skip', ''), - # Skip msg['hello world'] - (lambda n: isinstance(n.parent, compiler.ast.Subscript), 'skip', ''), - # Skip doc string - (lambda n: isinstance(n.parent, compiler.ast.Discard), 'skip', ''), - # Skip msg = "hello", in normal, message should more than one word - (lambda n: len(n.value.strip().split(' ')) <= 1, 'skip', ''), - # Skip msg = 'hello world' + vars + 'world hello' - (lambda n: isinstance(n.parent, compiler.ast.Add), 'skip', ''), - # Skip xml markers msg = "" - (lambda n: len(re.compile("").findall(n.value)) > 0, 'skip', ''), - # Skip sql statement - (lambda n: len( - re.compile("^SELECT.*FROM", flags=re.I).findall(n.value)) > 0, - 'skip', ''), - # LOG.xxx() - (is_log_callfunc, 'error', 'Message must be localized'), - # _('hello %s' % xyz) should be _('hello %s') % xyz - (is_wrong_i18n_format, 'error', - ("Message format was wrong, _('hello %s' % xyz) " - "should be _('hello %s') % xyz")), - # default - (lambda n: True, 'warn', 'Message might need localized') -] - - -""" -Used for checking message format. (checker_func, message) -""" -msg_format_checkers = [ - # If message contain more than on format specifier, it should use - # mapping key - (lambda n: len(re.compile("%[bcdeEfFgGnosxX]").findall(n.value)) > 1, - "The message shouldn't contain more than one format specifier"), - # Check capital - (lambda n: n.value.split(' ')[0].count('_') == 0 and - n.value[0].isalpha() and - n.value[0].islower(), - "First letter must be capital"), - (is_log_i18n_msg_with_mod, - 'LOG.xxx("Hello %s" % xyz) should be LOG.xxx("Hello %s", xyz)') -] - - -file_black_list = ["./neutron/tests/unit", - "./neutron/openstack", - "./neutron/plugins/bigswitch/tests"] diff --git a/tox.ini b/tox.ini index 8a36217e2..b6bce897f 100644 --- a/tox.ini +++ b/tox.ini @@ -56,9 +56,6 @@ commands = neutron-db-manage check_migration whitelist_externals = sh -[testenv:i18n] -commands = python ./tools/check_i18n.py ./neutron ./tools/i18n_cfg.py - [testenv:cover] commands = python setup.py testr --coverage --testr-args='{posargs}'