1196 lines
44 KiB
Python
1196 lines
44 KiB
Python
#!/usr/bin/env python
|
|
# -*- coding: utf-8 -*-
|
|
"""
|
|
creole lint main module
|
|
"""
|
|
import types
|
|
import sys
|
|
import re
|
|
from glob import glob
|
|
from os.path import join, basename, isfile, abspath, normpath, isabs
|
|
from lxml.etree import parse
|
|
|
|
from creole import config, eosfunc
|
|
from pyeole.process import system_code
|
|
from creole.lint.parsetemplate import parse_templates
|
|
from creole.lint.normalize import is_correct
|
|
from creole.var_loader import parse_dtd
|
|
from creole.lxml_parser import parse_xml_file
|
|
from creole.config import FLATTENED_CREOLE_DIR, dtdfilename
|
|
from creole.loader import PopulateTiramisuObjects
|
|
|
|
# variables internes aux dictionnaires
|
|
DICO_TEST_VARS = ['test_', 'tmp_']
|
|
# variables de conteneur calculées dynamiquement
|
|
CONTAINER_VARS = ['container_path_', 'container_ip_', 'container_name_',
|
|
'adresse_ip_ftp', 'adresse_ip_mysql', 'adresse_ip_dhcp',
|
|
'adresse_ip_internet', 'adresse_ip_interbase',
|
|
'adresse_ip_postgresql']
|
|
|
|
# faux-positifs sur les variables d'activation
|
|
EXCLUDE_ACTIVATION_VARS = ['activer_cntlm_eth0', 'activer_cntlm_eth1',
|
|
'activer_cntlm_eth2', 'activer_cntlm_eth3',
|
|
'activer_cntlm_eth4', 'activer_supp_proxy_eth0',
|
|
'activer_bash_completion', 'activer_log_martian',
|
|
'activer_dns_eth0', 'activer_ctrl_alt_suppr',
|
|
'activer_ipv6', 'activer_courier_commun',
|
|
'activer_web_valider_ca', 'activer_admin_passfile',
|
|
'activer_regles_filtrage_port_source',
|
|
'activer_ftp_anonymous_access', 'activer_ftp_access',
|
|
'activer_pydio_local', 'activer_courier_imap_sso',
|
|
'activer_pydio_ftp', 'activer_client_ldap',
|
|
]
|
|
|
|
# templates à ne pas tester par défaut
|
|
EXCLUDE_TMPL = ['/usr/share/eole/creole/distrib/named.conf',
|
|
'/usr/share/eole/creole/distrib/common-squid1.conf',
|
|
'/usr/share/eole/creole/distrib/zstats.cfg',
|
|
'/usr/share/eole/creole/distrib/hosts',
|
|
'/usr/share/eole/creole/distrib/active_tags',
|
|
]
|
|
|
|
# dictionnaires conservés pour compatibilité 2.3
|
|
OLD_DICOS = ['/usr/share/eole/creole/dicos/51_gepi.xml',
|
|
'/usr/share/eole/creole/dicos/51_taskfreak.xml',
|
|
'/usr/share/eole/creole/dicos/51_wordpress.xml',
|
|
'/usr/share/eole/creole/dicos/60_roundcube.xml',
|
|
'/usr/share/eole/creole/dicos/61_ajaxplorer.xml',
|
|
'/usr/share/eole/creole/dicos/61_dokuwiki.xml',
|
|
'/usr/share/eole/creole/dicos/61_fluxbb.xml',
|
|
'/usr/share/eole/creole/dicos/61_piwigo.xml',
|
|
'/usr/share/eole/creole/dicos/51_grr.xml',
|
|
'/usr/share/eole/creole/dicos/51_cdt.xml',
|
|
'/usr/share/eole/creole/dicos/51_piwik.xml',
|
|
'/usr/share/eole/creole/dicos/51_spip.xml',
|
|
]
|
|
|
|
starttoken = '%'
|
|
varstarttoken = '%%'
|
|
builts = [u'ArithmeticError', u'AssertionError', u'AttributeError',
|
|
u'BaseException', u'DeprecationWarning', u'EOFError', u'Ellipsis',
|
|
u'EnvironmentError', u'Exception', u'False', u'FloatingPointError',
|
|
u'FutureWarning', u'GeneratorExit', u'IOError', u'ImportError',
|
|
u'ImportWarning', u'IndentationError', u'IndexError', u'KeyError',
|
|
u'KeyboardInterrupt', u'LookupError', u'MemoryError', u'NameError',
|
|
u'None', u'NotImplemented', u'NotImplementedError', u'OSError',
|
|
u'OverflowError', u'PendingDeprecationWarning', u'ReferenceError',
|
|
u'RuntimeError', u'RuntimeWarning', u'StandardError',
|
|
u'StopIteration', u'SyntaxError', u'SyntaxWarning', u'SystemError',
|
|
u'SystemExit', u'TabError', u'True', u'TypeError',
|
|
u'UnboundLocalError', u'UnicodeDecodeError', u'UnicodeEncodeError',
|
|
u'UnicodeError', u'UnicodeTranslateError', u'UnicodeWarning',
|
|
u'UserWarning', u'ValueError', u'Warning', u'ZeroDivisionError',
|
|
u'_', u'__debug__', u'__doc__', u'__import__', u'__name__', u'abs',
|
|
u'all', u'any', u'apply', u'basestring', u'bool', u'buffer',
|
|
u'callable', u'chr', u'classmethod', u'cmp', u'coerce', u'compile',
|
|
u'complex', u'copyright', u'credits', u'delattr', u'dict', u'dir',
|
|
u'divmod', u'enumerate', u'eval', u'execfile', u'exit', u'file',
|
|
u'filter', u'float', u'frozenset', u'getattr', u'globals',
|
|
u'hasattr', u'hash', u'help', u'hex', u'id', u'input', u'int',
|
|
u'intern', u'isinstance', u'issubclass', u'iter', u'len',
|
|
u'license', u'list', u'locals', u'long', u'map', u'max', u'min',
|
|
u'object', u'oct', u'open', u'ord', u'pow', u'property', u'quit',
|
|
u'range', u'raw_input', u'reduce', u'reload', u'repr', u'reversed',
|
|
u'round', u'set', u'setattr', u'slice', u'sorted', u'staticmethod',
|
|
u'str', u'sum', u'super', u'tuple', u'type', u'unichr', u'unicode',
|
|
u'vars', u'xrange', u'zip']
|
|
builts.append(u'is_defined')
|
|
builts.append(u'split')
|
|
builts.append(u'lower')
|
|
cmd_client = (u'creole_client', ('get', 'get_containers'))
|
|
for func in dir(eosfunc):
|
|
if not func.startswith('_'):
|
|
builts.append(unicode(func, 'utf-8'))
|
|
|
|
# FIXME: je sais pas où la mettre
|
|
def is_container_var(varname):
|
|
"""
|
|
variables de conteneur calculées dynamiquement
|
|
"""
|
|
for var in CONTAINER_VARS:
|
|
if varname.startswith(var):
|
|
return True
|
|
return False
|
|
|
|
class TmplVar():
|
|
def __init__(self, name, fd, line):
|
|
self.name = name
|
|
self.location = []
|
|
self.add_location(fd, line)
|
|
|
|
def add_location(self, fd, line):
|
|
fd = basename(fd)
|
|
self.location.append((fd, line+1))
|
|
|
|
def set_location(self, location):
|
|
self.location = location
|
|
|
|
def get_location(self):
|
|
return self.location
|
|
|
|
class Var():
|
|
def __init__(self, name, description, separator, help, defaultvalue, is_slave):
|
|
self.name = name
|
|
self.description = description
|
|
self.separator = separator
|
|
self.help = help
|
|
self.defaultvalue = defaultvalue
|
|
self.is_slave = is_slave
|
|
|
|
class CreoleLinter:
|
|
"""Base class for linters, collects creole vars and templates
|
|
**has to be launched once and only once**
|
|
"""
|
|
display = True
|
|
class __impl:
|
|
warnno = 1
|
|
warncomment = "Undefined comment"
|
|
""" Implementation of the singleton interface """
|
|
def set_config(self, tmpl_dir_or_file=None):
|
|
if tmpl_dir_or_file != None and type(tmpl_dir_or_file) != str:
|
|
raise TypeError('tmpl_dir_or_file doit être une string')
|
|
if self.tmpl_dir_or_file != None:
|
|
sys.stderr('Tentative de redefinition de tmpl_dir_or_file')
|
|
if tmpl_dir_or_file == None:
|
|
self.tmpl_dir_or_file = config.distrib_dir
|
|
else:
|
|
if not isabs(tmpl_dir_or_file):
|
|
tmpl_dir_or_file = normpath(join(config.distrib_dir, tmpl_dir_or_file))
|
|
if not isfile(tmpl_dir_or_file):
|
|
raise Exception("template doit etre le nom d'un template valide")
|
|
self.tmpl_dir_or_file = tmpl_dir_or_file
|
|
self.eoledirs = config.eoledirs
|
|
self.dtddir = config.dtddir
|
|
self.exclude_var = []
|
|
self.pkgname = None
|
|
|
|
def load_dics(self):
|
|
if self.config is None:
|
|
self._collect_vars_in_dicos()
|
|
|
|
# def load_tmpls(self):
|
|
# if self.tmplvars == None:
|
|
# self._collect_set_vars()
|
|
# self._collect_def_vars()
|
|
# self._collect_for_vars()
|
|
# self._collect_define_vars()
|
|
# self._collect_vars_in_tmplfiles()
|
|
#
|
|
def get_dicos_name(self):
|
|
if self.config is None:
|
|
raise Exception('Dictionnaire non chargé')
|
|
dic = self.variables.keys()
|
|
dic.sort()
|
|
return dic
|
|
|
|
# def get_dicos_files(self):
|
|
# if self.creoledic == None:
|
|
# raise Exception('Dictionnaire non chargé')
|
|
# dic = []
|
|
# for name in self.creoledic.generic['files']:
|
|
# dic.append(basename(name['source']))
|
|
# dic.sort()
|
|
# return dic
|
|
#
|
|
# def get_tmplvars_name(self):
|
|
# if self.tmplvars == None:
|
|
# raise Exception('Template non chargé')
|
|
# tmpl = self.tmplvars.keys()
|
|
# tmpl.sort()
|
|
# return tmpl
|
|
#
|
|
# def get_defvars_name(self):
|
|
# if self.defvars == None:
|
|
# raise Exception('Template non chargé')
|
|
# defv = self.defvars.keys()
|
|
# defv.sort()
|
|
# return defv
|
|
#
|
|
# def get_setvars_name(self):
|
|
# if self.setvars == None:
|
|
# raise Exception('Fonction non chargé')
|
|
# var = self.setvars.keys()
|
|
# var.sort()
|
|
# return var
|
|
#
|
|
# def get_forvars_name(self):
|
|
# if self.forvars == None:
|
|
# raise Exception('Fonction non chargé')
|
|
# var = self.forvars.keys()
|
|
# var.sort()
|
|
# return var
|
|
#
|
|
# def get_tmplvar(self, name):
|
|
# return self.tmplvars[name]
|
|
#
|
|
# def get_separators(self):
|
|
# return self.creoledic.get_separators()
|
|
#
|
|
def get_dico_file_names(self):
|
|
if self.eoledirs == None or self.tmpl_dir_or_file == None:
|
|
raise Exception('Utiliser la methode set_config avant')
|
|
ret = []
|
|
for eoledir in self.eoledirs:
|
|
eoledir = abspath(eoledir)
|
|
if isfile(eoledir):
|
|
ret.append(eoledir)
|
|
else:
|
|
ret.extend(glob(join(eoledir, '*.xml')))
|
|
return ret
|
|
|
|
def get_dtd(self):
|
|
if self.dtddir == None:
|
|
raise Exception('Utiliser la methode set_config avant')
|
|
return join(self.dtddir, 'creole.dtd')
|
|
|
|
def _collect_vars_in_dicos(self):
|
|
if self.eoledirs == None or self.tmpl_dir_or_file == None:
|
|
raise Exception('Utiliser la methode set_config avant')
|
|
|
|
flattened = join(FLATTENED_CREOLE_DIR, 'flattened_creole.xml')
|
|
with file(flattened, 'r') as fhd:
|
|
xmlroot = parse(fhd).getroot()
|
|
tiramisu_objects = PopulateTiramisuObjects()
|
|
tiramisu_objects.parse_dtd(dtdfilename)
|
|
tiramisu_objects.make_tiramisu_objects(xmlroot)
|
|
self.config = tiramisu_objects.build()
|
|
|
|
self.config.read_write()
|
|
self.config.cfgimpl_get_settings().remove('hidden')
|
|
self.config.cfgimpl_get_settings().remove('validator')
|
|
self.config.cfgimpl_get_settings().remove('disabled')
|
|
for path in self.config.creole.make_dict():
|
|
spath = path.split('.')
|
|
vname = spath[-1]
|
|
fname = spath[0]
|
|
is_slave = False
|
|
if len(spath) == 3:
|
|
master = spath[1]
|
|
if master != vname:
|
|
is_slave = True
|
|
option = self.config.unwrap_from_path('creole.' + path)
|
|
self.variables[vname] = Var(vname, option.impl_get_information('doc', None),
|
|
option.impl_get_information('separator', ''),
|
|
option.impl_get_information('help', None),
|
|
option.impl_getdefault(),
|
|
is_slave)
|
|
if fname not in self.families:
|
|
self.families.append(fname)
|
|
|
|
def _parse_tabs_in_dicos(self):
|
|
if self.eoledirs == None or self.tmpl_dir_or_file == None:
|
|
raise Exception('Utiliser la methode set_config avant')
|
|
tabs_in_dics = []
|
|
fnames = []
|
|
for directory in self.eoledirs:
|
|
if isfile(directory):
|
|
fnames.append(directory)
|
|
else:
|
|
fnames.extend(glob(join(directory, "*.xml")))
|
|
for fname in fnames:
|
|
fh = file(fname, 'r')
|
|
content = fh.read()
|
|
if '\t' in content:
|
|
tabs_in_dics.append(fname)
|
|
fh.close()
|
|
return tabs_in_dics
|
|
|
|
def _list_tmpl_files(self):
|
|
if isfile(self.tmpl_dir_or_file):
|
|
return [self.tmpl_dir_or_file]
|
|
ret = []
|
|
for filename in glob(join(self.tmpl_dir_or_file, '*')):
|
|
if filename.startswith('.') or filename.endswith('~'):
|
|
continue
|
|
if filename in EXCLUDE_TMPL:
|
|
print " \\-- template desactivé : {0}".format(filename)
|
|
continue
|
|
ret.append(filename)
|
|
return ret
|
|
|
|
# def _add_collected_var(self, dvar, var, fd, linenb):
|
|
# if dvar.has_key(var):
|
|
# dvar[var].add_location(fd=fd, line=linenb)
|
|
# else:
|
|
# dvar[var] = TmplVar(name=var, fd=fd, line=linenb)
|
|
#
|
|
# def _collect_var_in(self, dvar, var, fd, linenb, exists=False):
|
|
# not_added=True
|
|
# if exists == True:
|
|
# if self.forvars.has_key(var):
|
|
# #si deja en memoire
|
|
# if (basename(fd), linenb+1) in self.forvars[var].location:
|
|
# return
|
|
# self._add_collected_var(self.forvars, var, fd, linenb)
|
|
# not_added=False
|
|
# if self.setvars.has_key(var):
|
|
# self._add_collected_var(self.setvars, var, fd, linenb)
|
|
# not_added=False
|
|
# if self.defvars.has_key(var):
|
|
# self._add_collected_var(self.defvars, var, fd, linenb)
|
|
# not_added=False
|
|
# #test les builtsin seulement si variable
|
|
# if not_added == True and unicode(var, 'utf-8') in builts:
|
|
# #self.builtsvar.append(var)
|
|
# return
|
|
# if not_added == True:
|
|
# self._add_collected_var(dvar, var, fd, linenb)
|
|
#
|
|
# def _collect_vars_in(self, expr, dvar, fd, linenb, tvarstarttoken,
|
|
# exists=False):
|
|
# if self.unknown_client == None:
|
|
# self.unknown_client = []
|
|
# varcreole = re.compile(tvarstarttoken+'([a-zA-Z0-9_\.{}]+)')
|
|
# varcreole2 = re.compile(tvarstarttoken+'(\w+)')
|
|
# varcreolebr = re.compile(tvarstarttoken+'{(\w+)}')
|
|
# varmulti = re.compile('(\w+)\.(\w+)')
|
|
# for var in varcreole.findall(expr):
|
|
# ret = varmulti.match(var)
|
|
# if ret != None:
|
|
# if ret.group(1) == cmd_client[0]:
|
|
# if ret.group(2) not in cmd_client[1]:
|
|
# self.unknown_client.append(TmplVar(name=ret.group(2), fd=fd, line=linenb))
|
|
# else:
|
|
# #%%var.sousvar
|
|
# self._collect_var_in(dvar, ret.group(1), fd, linenb, exists)
|
|
# self._collect_var_in(dvar, ret.group(2), fd, linenb, exists)
|
|
# else:
|
|
# #%%var
|
|
# for var2 in varcreole2.findall(tvarstarttoken+var):
|
|
# self._collect_var_in(dvar, var2, fd, linenb, exists)
|
|
# #%%{var}
|
|
# for var2 in varcreolebr.findall(tvarstarttoken+var):
|
|
# self._collect_var_in(dvar, var2, fd, linenb, exists)
|
|
#
|
|
# def _collect_vars(self, tvars, tpattern, all_char=False, with_var=False, with_vars=True, broken=None):
|
|
# """
|
|
# collect vars in template for a specified pattern
|
|
#
|
|
# :tvars: all collected var are store in this variable
|
|
# :tpattern: re pattern
|
|
# :broken: if set, store broken variable
|
|
# """
|
|
# if tvars == None:
|
|
# tvars = {}
|
|
# tstarttoken = ''
|
|
# tvarstarttoken = ''
|
|
# for tmplfd in self._list_tmpl_files():
|
|
# fh = open(tmplfd, 'r')
|
|
# lines = fh.readlines()
|
|
# length = len(lines)
|
|
# settings = False
|
|
# if tstarttoken != starttoken or \
|
|
# tvarstarttoken != varstarttoken:
|
|
# if all_char:
|
|
# char = '(.*)'
|
|
# else:
|
|
# char = '( *)'
|
|
# pattern = re.compile(char+starttoken+tpattern)
|
|
# tstarttoken = starttoken
|
|
# tvarstarttoken = varstarttoken
|
|
# for linenb in range(length):
|
|
# line = lines[linenb]
|
|
# if line.strip() == '%compiler-settings':
|
|
# settings = True
|
|
# if settings and line.strip() == \
|
|
# '%end compiler-settings'.strip():
|
|
# settings = False
|
|
# if not settings:
|
|
# ret = pattern.match(line.strip())
|
|
# if ret != None:
|
|
# expr = ret.group(2).strip()
|
|
# if with_var:
|
|
# self._collect_var_in(tvars, expr, tmplfd, linenb)
|
|
# if with_vars:
|
|
# self._collect_vars_in(expr,
|
|
# tvars, tmplfd, linenb,
|
|
# tvarstarttoken)
|
|
# len_token = len(varstarttoken)
|
|
# if broken is not None and expr.strip()[:len_token] != tvarstarttoken:
|
|
# broken.append(TmplVar(
|
|
# name=line.strip(),
|
|
# fd=tmplfd, line=linenb))
|
|
# else:
|
|
# tline = line.split('=')
|
|
# tkey = tline[0].strip()
|
|
# if tkey == 'cheetahVarStartToken':
|
|
# tvarstarttoken = tline[1].strip()
|
|
# elif tkey == 'directiveStartToken':
|
|
# tstarttoken = tline[1].strip()
|
|
# pattern = re.compile(tstarttoken+tpattern)
|
|
# fh.close()
|
|
# return tvars
|
|
#
|
|
# def _collect_for_vars(self):
|
|
# """
|
|
# collect all vars generate in 'for'
|
|
# """
|
|
# self.brokenfor = []
|
|
# self.forvars = self._collect_vars(self.forvars, 'for (.+) in (.*)', broken=self.brokenfor)
|
|
#
|
|
# def _collect_def_vars(self):
|
|
# """
|
|
# collect all vars generate in 'def'
|
|
# """
|
|
# self.defvars = self._collect_vars(self.defvars, 'def (.*)\((.*)\)', with_var=True)
|
|
#
|
|
# def _collect_set_vars(self):
|
|
# """
|
|
# collect all vars generate in 'set'
|
|
# """
|
|
# self.setvars = self._collect_vars(self.setvars, 'set (.*)=.*')
|
|
#
|
|
# def _collect_define_vars(self):
|
|
# """
|
|
# collect all vars generate in 'def'
|
|
# """
|
|
# self.var_with_is_defined = self._collect_vars(
|
|
# self.var_with_is_defined,
|
|
# "is_defined\(\'(\w+)\'\)",
|
|
# all_char=True,
|
|
# with_var=True, with_vars=False)
|
|
# ##FIXME pas de support de cheetahVarStartToken, ...
|
|
# #if self.var_with_is_defined == None:
|
|
# # self.var_with_is_defined = {}
|
|
# # pattern = re.compile('(.*) %sis_defined\(\'(\w+)\'\)'%varstarttoken)
|
|
# # for tmplfd in self._list_tmpl_files():
|
|
# # fh = open(tmplfd, 'r')
|
|
# # lines = fh.readlines()
|
|
# # length = len(lines)
|
|
# # for linenb in range(length):
|
|
# # line = lines[linenb]
|
|
# # ret = pattern.match(line)
|
|
# # if ret != None:
|
|
# # self._collect_var_in(self.var_with_is_defined, ret.group(2), tmplfd, linenb)
|
|
# # fh.close()
|
|
#
|
|
# def _collect_vars_in_tmplfiles(self):
|
|
# if self.eoledirs == None or self.tmpl_dir_or_file == None:
|
|
# raise Exception('Utiliser la methode set_config avant')
|
|
# # XXX ".eolvars" is a good placeholder for var names to be kept in touch
|
|
# if self.tmplvars == None:
|
|
# self.tmplvars = {}
|
|
# for tmplfd in self._list_tmpl_files():
|
|
# fh = open(tmplfd, 'r')
|
|
# lines = fh.readlines()
|
|
# length = len(lines)
|
|
# settings = False
|
|
# tvarstarttoken = varstarttoken
|
|
# for linenb in range(length):
|
|
# line = lines[linenb]
|
|
# if line.strip() == '%compiler-settings':
|
|
# settings = True
|
|
# if settings and line.strip() == \
|
|
# '%end compiler-settings'.strip():
|
|
# settings = False
|
|
# if not settings:
|
|
# self._collect_vars_in(line, self.tmplvars, tmplfd,
|
|
# linenb, tvarstarttoken, True)
|
|
# else:
|
|
# tline = line.split('=')
|
|
# tkey = tline[0].strip()
|
|
# if tkey == 'cheetahVarStartToken':
|
|
# tvarstarttoken = tline[1].strip()
|
|
#
|
|
# fh.close()
|
|
#
|
|
# storage for the instance reference
|
|
__instance = None
|
|
|
|
def __init__(self):
|
|
""" Create singleton instance """
|
|
# Check whether we already have an instance
|
|
|
|
if CreoleLinter.__instance is None:
|
|
# Create and remember instance
|
|
CreoleLinter.__instance = CreoleLinter.__impl()
|
|
self.tmpl_dir_or_file = None
|
|
self.eoledirs = None
|
|
self.config = None
|
|
self.variables = {}
|
|
self.families = []
|
|
self.tmplvars = None
|
|
self.forvars = None
|
|
self.defvars = None
|
|
self.setvars = None
|
|
self.unknown_client = None
|
|
self.brokenfor = None
|
|
self.var_with_is_defined = None
|
|
self.exclude_var = None
|
|
self.skip_var = {}
|
|
self.conflevel = 'eole'
|
|
|
|
# Store instance reference as the only member in the handle
|
|
self.__dict__['_CreoleLinter__instance'] = CreoleLinter.__instance
|
|
|
|
def __getattr__(self, attr):
|
|
""" Delegate access to implementation """
|
|
return getattr(self.__instance, attr)
|
|
|
|
def __setattr__(self, attr, value):
|
|
""" Delegate access to implementation """
|
|
return setattr(self.__instance, attr, value)
|
|
|
|
#class SaveItem(CreoleLinter):
|
|
# """
|
|
# eolvars not present in the dicos
|
|
# """
|
|
# name = 'save'
|
|
# warnno = 1
|
|
# warncomment = "Ne pas utiliser la fonction SaveItem comme un test"
|
|
#
|
|
# def process(self):
|
|
# self.load_dics()
|
|
# if self.pkgname == None:
|
|
# raise Exception('fichier creolelint.conf incomplet (name)')
|
|
# filename = join(expanduser('~/.creolelint'), self.pkgname+'.conf')
|
|
# fh = open(filename, 'w')
|
|
# fh.write('vardico = '+str(self.get_dicos_name())+'\n')
|
|
# fh.close()
|
|
# print('fichier sauvegardé')
|
|
#
|
|
# def check(self):
|
|
# return []
|
|
#
|
|
#class OrphansInDicosItem(CreoleLinter):
|
|
# """
|
|
# eolvars not present in the dicos
|
|
# """
|
|
# name = 'orphans_in_dicos'
|
|
# warnno = 8
|
|
# warncomment = "Variable dictionnaire non utilisée dans un template"
|
|
#
|
|
# def check(self):
|
|
# self.load_dics()
|
|
# self.load_tmpls()
|
|
#
|
|
# vars_name = set(self.get_dicos_name())
|
|
# tmplvars_name = set(self.get_tmplvars_name())
|
|
# only_in_dicos = vars_name - tmplvars_name
|
|
# ret = []
|
|
# skip_var = self.skip_var.get(self.name, {})
|
|
# for var in only_in_dicos:
|
|
# if skip_var.has_key(var):
|
|
# continue
|
|
# test_start = False
|
|
# for start in DICO_TEST_VARS:
|
|
# if var.startswith(start):
|
|
# test_start = True
|
|
# break
|
|
# if not test_start:
|
|
# ret.append(self.variables[var])
|
|
# return ret
|
|
#
|
|
#class OrphansInTmplItem(CreoleLinter):
|
|
# """
|
|
# eolvars not present in the templates
|
|
# """
|
|
# name = 'orphans_in_tmpl'
|
|
# warnno = 8
|
|
# warncomment = "Variable template non présente dans le dictionnaire"
|
|
#
|
|
# def check(self):
|
|
# self.load_dics()
|
|
# self.load_tmpls()
|
|
#
|
|
# vars_name = self.get_dicos_name()
|
|
# if self.exclude_var != None:
|
|
# vars_name.extend(self.exclude_var)
|
|
# vars_name=set(vars_name)
|
|
# tmplvars_name = set(self.get_tmplvars_name())
|
|
# only_in_tmpl = tmplvars_name - vars_name
|
|
# #remove is_defined
|
|
# is_defined_name = set(self.var_with_is_defined.keys())
|
|
# only_in_tmpl = only_in_tmpl - is_defined_name
|
|
# set_var = set(self.get_setvars_name())
|
|
# only_in_tmpl = only_in_tmpl - set_var
|
|
# ret = []
|
|
# for var in only_in_tmpl:
|
|
# skipped_location = []
|
|
# for location in self.tmplvars[var].location:
|
|
# if self.skip_var.has_key(self.name) and self.skip_var[self.name].has_key(var):
|
|
# if not location in self.skip_var[self.name][var]:
|
|
# skipped_location.append(location)
|
|
# else:
|
|
# skipped_location.append(location)
|
|
# if skipped_location != []:
|
|
# tmplvar = TmplVar(var, '', 0)
|
|
# tmplvar.set_location(skipped_location)
|
|
# ret.append(tmplvar)
|
|
# #results.append(self.tmplvars[var])
|
|
# return ret
|
|
#
|
|
#class OrphansDefItem(CreoleLinter):
|
|
# name = 'orphans_def'
|
|
# warnno = 7
|
|
# warncomment = "Fonction définie mais non utilisée"
|
|
#
|
|
# def check(self):
|
|
# self.load_tmpls()
|
|
# results = []
|
|
# for defvar in self.get_defvars_name():
|
|
# defname = {}
|
|
# for filedesc, linenb in self.defvars[defvar].location:
|
|
# if not defname.has_key((defvar, filedesc)):
|
|
# defname[(defvar, filedesc)]=linenb
|
|
# else:
|
|
# defname[(defvar, filedesc)]="exists"
|
|
# for defvar, filedesc in defname.keys():
|
|
# if defname[(defvar, filedesc)] != "exists":
|
|
# results.append(TmplVar(name=defvar, fd=filedesc, line=defname[(defvar, filedesc)]))
|
|
#
|
|
# return results
|
|
#
|
|
#class OrphansSetItem(CreoleLinter):
|
|
# name = 'orphans_set'
|
|
# warnno = 7
|
|
# warncomment = "Variable définie dans le template mais non utilisée"
|
|
#
|
|
# def check(self):
|
|
# self.load_tmpls()
|
|
# results = []
|
|
# tmpl_vars = set(self.get_tmplvars_name())
|
|
# for setvar in self.get_setvars_name():
|
|
# setname = {}
|
|
# for filedesc, linenb in self.setvars[setvar].location:
|
|
# if setname.has_key((setvar, filedesc)) == False:
|
|
# setname[(setvar, filedesc)]=linenb
|
|
# else:
|
|
# setname[(setvar, filedesc)]="exists"
|
|
#
|
|
# for setvar, filedesc in setname.keys():
|
|
# if setname[(setvar, filedesc)] != "exists":
|
|
# results.append(TmplVar(name=setvar, fd=filedesc, line=setname[(setvar, filedesc)]))
|
|
#
|
|
# return results
|
|
#
|
|
#class OrphansForItem(CreoleLinter):
|
|
# name = 'orphans_for'
|
|
# warnno = 7
|
|
# warncomment = "Variable définie dans une boucle mais non utilisée"
|
|
#
|
|
# def check(self):
|
|
# self.load_tmpls()
|
|
# results = []
|
|
# for forvar in self.get_forvars_name():
|
|
# forname = {}
|
|
# for filedesc, linenb in self.forvars[forvar].location:
|
|
# if forname.has_key((forvar, filedesc)) == False:
|
|
# forname[(forvar, filedesc)]=linenb
|
|
# else:
|
|
# forname[(forvar, filedesc)]="exists"
|
|
#
|
|
# for forvar, filedesc in forname.keys():
|
|
# if forname[(forvar, filedesc)] != "exists":
|
|
# results.append(TmplVar(name=forvar, fd=filedesc, line=forname[(forvar, filedesc)]))
|
|
# return results
|
|
#
|
|
#class OrphansDicosFilesItem(CreoleLinter):
|
|
# """
|
|
# """
|
|
# name = 'orphans_dicos_files'
|
|
# warnno = 1
|
|
# warncomment = "Template déclaré dans le dicos inexistant"
|
|
#
|
|
# def check(self):
|
|
# self.load_dics()
|
|
#
|
|
# dicos_files = []
|
|
# for filen in self.get_dicos_files():
|
|
# dicos_files.append(basename(filen))
|
|
# dicos_files = set(dicos_files)
|
|
# tmpl_files = []
|
|
# for filen in self._list_tmpl_files():
|
|
# tmpl_files.append(unicode(basename(filen), 'utf-8'))
|
|
# tmpl_files=set(tmpl_files)
|
|
# orphans = dicos_files - tmpl_files
|
|
# ret = []
|
|
# for var in orphans:
|
|
# if self.skip_var.has_key(self.name) and not self.skip_var[self.name].has_key(var):
|
|
# ret.append(var)
|
|
# else:
|
|
# ret.append(var)
|
|
#
|
|
# return ret
|
|
#
|
|
#class OrphansTmplFilesItem(CreoleLinter):
|
|
# """
|
|
# """
|
|
# name = 'orphans_tmpl_files'
|
|
# warnno = 1
|
|
# warncomment = "Template non déclaré dans le dicos"
|
|
#
|
|
# def check(self):
|
|
# self.load_dics()
|
|
#
|
|
# dicos_files = []
|
|
# for filen in self.get_dicos_files():
|
|
# dicos_files.append(basename(filen))
|
|
# dicos_files = set(dicos_files)
|
|
# tmpl_files = []
|
|
# for filen in self._list_tmpl_files():
|
|
# tmpl_files.append(unicode(basename(filen), 'utf-8'))
|
|
# tmpl_files=set(tmpl_files)
|
|
# return tmpl_files - dicos_files
|
|
#
|
|
class WrongDicosNameItem(CreoleLinter):
|
|
name = 'wrong_dicos_name'
|
|
warnno = 6
|
|
warncomment = "Dictionnaire avec un nom invalide"
|
|
|
|
def check(self):
|
|
if self.conflevel == 'common':
|
|
pattern = '(0'
|
|
elif self.conflevel == 'conf':
|
|
pattern = '(1'
|
|
elif self.conflevel == 'eole':
|
|
pattern = '(2'
|
|
else:
|
|
pattern = '([3-9]'
|
|
pattern += '[0-9]_[a-z0-9_]+)'
|
|
cpattern = re.compile(pattern)
|
|
ret = []
|
|
for filename in self.get_dico_file_names():
|
|
name = basename(filename)
|
|
if cpattern.match(name) == None:
|
|
ret.append(name)
|
|
return ret
|
|
|
|
class HiddenIfInDicosItem(CreoleLinter):
|
|
name = 'hidden_if_in_dicos'
|
|
warnno = 5
|
|
warncomment = "Dictionnaire contenant un hidden_if_*"
|
|
|
|
def check(self):
|
|
ret = []
|
|
dtd = parse_dtd(self.get_dtd())
|
|
for filename in self.get_dico_file_names():
|
|
if filename in OLD_DICOS:
|
|
continue
|
|
parse = parse_xml_file(filename, dtd, parse_all=False)
|
|
for cond in parse['conditions'].values():
|
|
if cond[0]['name'].startswith('hidden_if_'):
|
|
ret.append(filename)
|
|
break
|
|
return ret
|
|
|
|
class ConditionWithoutTarget(CreoleLinter):
|
|
name = 'condition_without_target'
|
|
warnno = 5
|
|
warncomment = "Dictionnaire contenant une condition sans target"
|
|
|
|
def check(self):
|
|
ret = []
|
|
|
|
dtd = parse_dtd(self.get_dtd())
|
|
for filename in self.get_dico_file_names():
|
|
if filename in OLD_DICOS:
|
|
continue
|
|
parse = parse_xml_file(filename, dtd, parse_all=False)
|
|
for cond in parse['conditions'].values():
|
|
for con in cond:
|
|
if con['family'] == con['list'] == con['variable'] == []:
|
|
ret.append(filename)
|
|
break
|
|
return ret
|
|
|
|
class ObligatoireInDicosItem(CreoleLinter):
|
|
name = 'obligatoire_in_dicos'
|
|
warnno = 5
|
|
warncomment = "Dictionnaire contenant un check \"obligatoire\""
|
|
|
|
def check(self):
|
|
ret = []
|
|
dtd = parse_dtd(self.get_dtd())
|
|
for filename in self.get_dico_file_names():
|
|
if filename in OLD_DICOS:
|
|
continue
|
|
parse = parse_xml_file(filename, dtd, parse_all=False)
|
|
for cond in parse['checks'].values():
|
|
if cond[0][0] == 'obligatoire':
|
|
ret.append(filename)
|
|
break
|
|
return ret
|
|
|
|
|
|
class FamilyWithoutHelp(CreoleLinter):
|
|
name = 'family_without_help'
|
|
warnno = 5
|
|
warncomment = "Famille sans balise d'aide"
|
|
|
|
def check(self):
|
|
self.load_dics()
|
|
ret = []
|
|
for grp in self.config.creole.iter_groups():
|
|
doc = grp[1].cfgimpl_get_description().impl_get_information('help', None)
|
|
if doc is None:
|
|
ret.append(grp[0])
|
|
return ret
|
|
|
|
class FamilyWithoutIcon(CreoleLinter):
|
|
name = 'family_without_icon'
|
|
warnno = 5
|
|
warncomment = "Famille sans icône spécifique"
|
|
|
|
def check(self):
|
|
self.load_dics()
|
|
ret = []
|
|
for grp in self.config.creole.iter_groups():
|
|
if grp[1].cfgimpl_get_description().impl_get_information('icon') is None:
|
|
ret.append(grp[0])
|
|
return ret
|
|
|
|
#class DefineItem(CreoleLinter):
|
|
# """
|
|
# check for syntaxes
|
|
# """
|
|
# name = 'define'
|
|
# warnno = 4
|
|
# warncomment = "Redéfinition d'un variable d'un dictionnaire"
|
|
#
|
|
# def check(self):
|
|
# """
|
|
# verifie si une variable définie est une variable du dictionnaire
|
|
# """
|
|
# self.load_dics()
|
|
# self.load_tmpls()
|
|
# dicos = set(self.get_dicos_name())
|
|
# defv = set(self.get_defvars_name())
|
|
# ret=[]
|
|
# for var in defv & dicos:
|
|
# ret.append(self.defvars[var])
|
|
# return ret
|
|
#
|
|
class BuiltinsItem(CreoleLinter):
|
|
"""
|
|
verifier si une variable de dico n'est pas dans l'espace de nommage
|
|
"""
|
|
name = 'builtins'
|
|
warnno = 4
|
|
warncomment = "Variable identitique à une fonction python"
|
|
|
|
def check(self):
|
|
self.load_dics()
|
|
# self.load_tmpls()
|
|
ret = []
|
|
#dans le dictionnaire
|
|
for var in set(builts) & set(self.get_dicos_name()):
|
|
ret.append(self.variables[var])
|
|
# #dans les variables de template
|
|
# for var in set(builts) & set(self.get_tmplvars_name()):
|
|
# ret.append(self.tmplvars[var])
|
|
# #dans les boucles for
|
|
# for var in set(builts) & set(self.get_forvars_name()):
|
|
# ret.append(self.forvars[var])
|
|
# #dans la definition de variable dans un template
|
|
# for var in set(builts) & set(self.get_setvars_name()):
|
|
# ret.append(self.setvars[var])
|
|
# #dans les noms de fonction
|
|
# for var in set(builts) & set(self.get_defvars_name()):
|
|
# ret.append(self.defvars[var])
|
|
return ret
|
|
|
|
#class SyntaxForItem(CreoleLinter):
|
|
# """
|
|
# verifie la syntaxe de la ligne for
|
|
# """
|
|
# name = 'syntax_for'
|
|
# warnno = 1
|
|
# warncomment = "Syntaxe de la ligne for incorrect"
|
|
# def check(self):
|
|
# self.load_tmpls()
|
|
# return self.brokenfor
|
|
#
|
|
#class SyntaxVarItem(CreoleLinter):
|
|
# """
|
|
# verifie les variables suivant la syntaxe de pattern
|
|
# """
|
|
# name = 'syntax_var'
|
|
# pattern = '([a-z0-9][a-z0-9]+_[a-z0-9_]+)'
|
|
# warnno = 6
|
|
# warncomment = "La variable ne respecte pas la regexp %s" % pattern
|
|
#
|
|
# def check(self):
|
|
# cpattern = re.compile(self.pattern)
|
|
# self.load_dics()
|
|
# self.load_tmpls()
|
|
# ret=[]
|
|
# #dans le dictionnaire
|
|
# for var in self.get_dicos_name():
|
|
# if cpattern.match(var) == None:
|
|
# ret.append(self.variables[var])
|
|
# #dans les variables de template
|
|
# for var in self.get_tmplvars_name():
|
|
# if cpattern.match(var) == None:
|
|
# skipped_location = []
|
|
# for location in self.tmplvars[var].location:
|
|
# if self.skip_var.has_key(self.name) and self.skip_var[self.name].has_key(var):
|
|
# if not location in self.skip_var[self.name][var]:
|
|
# skipped_location.append(location)
|
|
# else:
|
|
# skipped_location.append(location)
|
|
# if skipped_location != []:
|
|
# tmplvar = TmplVar(var, '', 0)
|
|
# tmplvar.set_location(skipped_location)
|
|
# ret.append(tmplvar)
|
|
# #ret.append(self.tmplvars[var])
|
|
# #dans les boucles for
|
|
# for var in self.get_forvars_name():
|
|
# if cpattern.match(var) == None:
|
|
# ret.append(self.forvars[var])
|
|
# #dans la definition de variable dans un template
|
|
# for var in self.get_setvars_name():
|
|
# if cpattern.match(var) == None:
|
|
# ret.append(self.setvars[var])
|
|
# return ret
|
|
#
|
|
#class ForbiddenTemplateVarItem(CreoleLinter):
|
|
# """
|
|
# vérifie la présence des noms de variable interdits dans les templates
|
|
# """
|
|
# name = 'syntax_var2'
|
|
# warnno = 6
|
|
# warncomment = "Nom de variable interdit dans un template"
|
|
#
|
|
# def check(self):
|
|
# #self.load_dics()
|
|
# self.load_tmpls()
|
|
# ret=[]
|
|
# #dans les variables de template
|
|
# for var in self.get_tmplvars_name():
|
|
# for start in DICO_TEST_VARS:
|
|
# if var.startswith(start):
|
|
# ret.append(var)
|
|
# break
|
|
# return ret
|
|
#
|
|
#class SyntaxFunctionItem(CreoleLinter):
|
|
# """
|
|
# verifie les fonctions suivant la syntaxe de pattern
|
|
# """
|
|
# name = 'syntax_function'
|
|
# pattern = '([a-z0-9][a-z0-9]+_[a-z0-9_]+)'
|
|
# warnno = 6
|
|
# warncomment = "La fonction ne respecte pas la regexp %s" % pattern
|
|
#
|
|
# def check(self):
|
|
# cpattern = re.compile(self.pattern)
|
|
# self.load_tmpls()
|
|
# ret=[]
|
|
# #dans les noms de fonction
|
|
# for var in self.get_defvars_name():
|
|
# if cpattern.match(var) == None:
|
|
# ret.append(self.defvars[var])
|
|
# return ret
|
|
#
|
|
#class OrphansVarHelpItem(CreoleLinter):
|
|
# name = 'orphans_var_help'
|
|
# warnno = 3
|
|
# warncomment = "Aide définie dans le dictionnaire pour une variable inexistante"
|
|
#
|
|
# def check(self):
|
|
# self.load_dics()
|
|
# vars_name = set(self.get_dicos_name())
|
|
# vars_help = set(self.creoledic.get_helps()['variables'].keys())
|
|
# #print vars_help
|
|
# only_in_help = vars_help - vars_name
|
|
# results = []
|
|
# for tmpl in only_in_help:
|
|
# results.append(tmpl)
|
|
# return results
|
|
|
|
#class OrphansFamHelpItem(CreoleLinter):
|
|
# name = 'orphans_fam_help'
|
|
# warnno = 3
|
|
# warncomment = "Aide définie dans le dictionnaire pour une famille inexistante"
|
|
#
|
|
# def check(self):
|
|
# self.load_dics()
|
|
# #FIXME
|
|
# vars_name = set(self.families)
|
|
# vars_help = set(self.creoledic.get_helps()['families'].keys())
|
|
# only_in_help = vars_help - vars_name
|
|
# results = []
|
|
# for tmpl in only_in_help:
|
|
# results.append(tmpl)
|
|
# return results
|
|
#
|
|
class ValidVarLabelItem(CreoleLinter):
|
|
name = 'valid_var_label'
|
|
warnno = 5
|
|
warncomment = "Libellé de variable non valide dans un dictionnaire"
|
|
|
|
def check(self):
|
|
self.load_dics()
|
|
ret = []
|
|
for var in self.variables.values():
|
|
if not is_container_var(var.name):
|
|
ret.extend(is_correct(var.description, var.name))
|
|
return ret
|
|
|
|
class ActivationVarWithoutHelp(CreoleLinter):
|
|
name = 'activation_var_without_help'
|
|
warnno = 5
|
|
warncomment = "Variable d'activation sans balise d'aide"
|
|
|
|
def check(self):
|
|
self.load_dics()
|
|
ret = []
|
|
for var, var_obj in self.variables.items():
|
|
if var.startswith('activer_') and var not in EXCLUDE_ACTIVATION_VARS:
|
|
if var_obj.help is None:
|
|
ret.append(var)
|
|
return ret
|
|
|
|
class ValidSeparatorLabelItem(CreoleLinter):
|
|
name = 'valid_separator_label'
|
|
warnno = 5
|
|
warncomment = "Libellé de séparateur non valide dans un dictionnaire"
|
|
|
|
def check(self):
|
|
self.load_dics()
|
|
ret = []
|
|
|
|
for var, var_obj in self.variables.items():
|
|
if var_obj.separator == '':
|
|
#FIXME: variables de conteneur dynamiques
|
|
continue
|
|
ret.extend(is_correct(var_obj.separator[0], var))
|
|
return ret
|
|
|
|
class ValidHelpLabelItem(CreoleLinter):
|
|
name = 'valid_help_label'
|
|
warnno = 5
|
|
warncomment = "Libellé d'aide non valide dans un dictionnaire"
|
|
|
|
def check(self):
|
|
self.load_dics()
|
|
ret = []
|
|
for var, var_obj in self.variables.items():
|
|
# help/variable
|
|
ret.extend(is_correct(var_obj.help, var))
|
|
for grp in self.config.creole.iter_groups():
|
|
# help/family
|
|
ret.extend(is_correct(grp[1].cfgimpl_get_description().impl_get_information('help', ''),
|
|
grp[0], family=True))
|
|
return ret
|
|
|
|
class ValidSlaveValue(CreoleLinter):
|
|
name = 'valid_slave_value'
|
|
warnno = 5
|
|
warncomment = "Variable esclave avec une liste en valeur défaut"
|
|
|
|
def check(self):
|
|
self.load_dics()
|
|
ret = []
|
|
for var, var_obj in self.variables.items():
|
|
if var_obj.is_slave:
|
|
if len(var_obj.defaultvalue) > 1:
|
|
ret.append(var)
|
|
return ret
|
|
|
|
##class ValidCheckEnumOuiNon(CreoleLinter):
|
|
## name = 'valid_check_enum_ouinon'
|
|
## warnno = 6
|
|
## warncomment = "Variable avec un valid_enum à oui/non au lieu du type oui/non"
|
|
##
|
|
## def check(self):
|
|
## ret = []
|
|
## for var, content in self.creoledic.variables.items():
|
|
## print content
|
|
## if str(type(content)) != "<class 'creole.typeole.OuiNon'>":
|
|
## for check in content.choices:
|
|
## if check[0] == u'valid_enum':
|
|
## for valid_enum in check[1]:
|
|
## if valid_enum['value'].startswith('['):
|
|
## eval_valid_enum = eval(valid_enum['value'])
|
|
## if set(eval_valid_enum) == set(['non', 'oui']):
|
|
## ret.append(var)
|
|
## return ret
|
|
#
|
|
##class ValidCheckEnumOnOff(CreoleLinter):
|
|
## name = 'valid_check_enum_onoff'
|
|
## warnno = 6
|
|
## warncomment = "Variable avec un valid_enum à on/off au lieu du type on/off"
|
|
##
|
|
## def check(self):
|
|
## ret = []
|
|
## for var, content in self.creoledic.variables.items():
|
|
## if str(type(content)) != "<class 'creole.typeole.OnOff'>":
|
|
## for check in content.checks:
|
|
## if check[0] == u'valid_enum':
|
|
## for valid_enum in check[1]:
|
|
## if valid_enum['value'].startswith('['):
|
|
## eval_valid_enum = eval(valid_enum['value'])
|
|
## if set(eval_valid_enum) == set(['on', 'off']):
|
|
## ret.append(var)
|
|
## return ret
|
|
#
|
|
class TabsInDicosItem(CreoleLinter):
|
|
name = 'tabs_in_dicos'
|
|
warnno = 5
|
|
warncomment = "Tabulation dans le dictionnaire au lieu de 4 espaces"
|
|
|
|
def check(self):
|
|
return self._parse_tabs_in_dicos()
|
|
|
|
#class ValidClientOption(CreoleLinter):
|
|
# name = 'valid_client_option'
|
|
# warnno = 6
|
|
# warncomment = "Option inconnu pour %s" % cmd_client[0]
|
|
#
|
|
# def check(self):
|
|
# self.load_tmpls()
|
|
# return self.unknown_client
|
|
|
|
class ValidParseTmpl(CreoleLinter):
|
|
name = 'valid_parse_tmpl'
|
|
warnno = 1
|
|
warncomment = "Template Non valide"
|
|
display = False
|
|
|
|
def check(self):
|
|
parse_templates(self._list_tmpl_files())
|
|
return []
|
|
|
|
|
|
class ValidDTDItem(CreoleLinter):
|
|
name = 'valid_dtd'
|
|
warnno = 1
|
|
warncomment = "DTD Non valide"
|
|
display = False
|
|
|
|
def check(self):
|
|
dtd = self.get_dtd()
|
|
for filename in self.get_dico_file_names():
|
|
system_code(['xmllint', '--noout', '--dtdvalid', dtd, filename])
|
|
return []
|
|
|
|
class OldFwFile(CreoleLinter):
|
|
name = 'old_fw_file'
|
|
warnno = 5
|
|
warncomment = "Ancien fichier eole-firewall présent sur le serveur"
|
|
|
|
def check(self):
|
|
fw_templates = '/usr/share/eole/creole/distrib/*.fw'
|
|
fw_files = '/usr/share/eole/firewall/*.fw'
|
|
return glob(fw_files) + glob(fw_templates)
|
|
|
|
def validate(keyword, ansi, tmpl):
|
|
globs = globals()
|
|
classitem = None
|
|
for cls in globs:
|
|
if cls.startswith('_') and type(globs[cls])!=types.ClassType and cls == 'CreoleLinter' and cls == 'TmplVar':
|
|
continue
|
|
if hasattr(globs[cls], 'name'):
|
|
if globs[cls].name == keyword:
|
|
classitem = globs[cls]
|
|
break
|
|
if classitem == None:
|
|
raise Exception('test %s inconnu'%keyword)
|
|
cl = classitem()
|
|
if cl.eoledirs == None:
|
|
cl.set_config(tmpl_dir_or_file=tmpl)
|
|
ansi.process(cl)
|
|
|