Package linda :: Module libchecks
[hide private]

Source Code for Module linda.libchecks

  1  import sys, os, re, string, traceback, linda 
  2  from linda import root, outputobj, clparser 
  3  from linda.debug import dprint 
  4  from linda.parser.datavalidator import DataValidator 
  5  from linda.parser.debfilename import DebFilenameParser 
  6   
7 -class LindaChecker:
8 """ 9 The LindaChecker class is used by all checks, as they inheriate from it. It provides an initialisation method that sets up internal variables for the 10 check to use, such as: 11 - self.lab: The lab directory itself. 12 - self.err_dict: The error dictionary. There should be no need to access this directly. 13 - self.file: The check file itself. 14 - self.pkg_name: The package name being checked. 15 - self.version: The package version being checked. 16 - self.information: Contains information such as what files are contained in the package, and what 'file', 'objdump' and 'ldd' outputs for each of them. See the documentation on Collector for more information. 17 18 This method also provides a hook method called init, which means checks can also perform their own initisagtion. 19 """
20 - def __init__(self, lab, file, information):
21 self.lab = lab 22 self.err_dict = ErrDict() 23 self.file = file 24 debfn = DebFilenameParser(file) 25 self.pkg_name = debfn.package 26 self.version = debfn.version 27 self.information = information 28 if hasattr(self, 'init'): 29 getattr(self, 'init')()
30
31 - def signal_error(self, tag=None, message=[]):
32 """ 33 This method is called whenever an error is encountered in a package. It adds 34 the tag and data to the internal err_dict object. 35 """ 36 self.err_dict.add_error(tag, message)
37
38 - def is_native(self):
39 """ 40 This method checks if the version of a package is native. It returns false if 41 the package is not native, and returns true if it is. 42 """ 43 if self.version.find('-') != -1: 44 return 0 45 else: 46 return 1
47
48 -class ErrDict:
49 - def __init__(self):
50 self.errs = {}
51
52 - def add_error(self, key, data=[]):
53 if self.errs.has_key(key): 54 self.errs[key].append(data) 55 else: 56 self.errs[key] = [data]
57
58 - def __getitem__(self, key):
59 return self.errs[key]
60
61 - def __delitem__(self, key):
62 del self.errs[key] 63
64 - def keys(self):
65 return self.errs.keys()
66
67 - def clear(self):
68 self.errs.clear()
69
70 -class Checks:
71 - def __init__(self):
72 self.registry = {} 73 self.cur_file = ''
74
75 - def startup_register(self):
76 self.register_all('%s/checks' % root) 77 if not clparser['disable-local']: 78 for dir in (os.path.expanduser('~/.linda/checks'), \ 79 '/etc/linda/checks'): 80 if os.path.isdir(dir): 81 self.register_all(dir) 82 dprint(_("Registry: %s") % self.registry, 3) 83 for type in ('source', 'binary', 'changes', 'udeb'): 84 for level in (1, 2): 85 if self.registry.has_key(type): 86 if self.registry[type].has_key(level): 87 for klass in self.registry[type][level]: 88 dprint(_("%s: %s") % (klass.__name__, \ 89 klass.__file__), 4)
90
91 - def register(self, klass):
92 klass.__file__ = self.cur_file 93 for type in ('source', 'binary', 'changes', 'udeb'): 94 for level in (1, 2): 95 if hasattr(klass, 'check_%s_%s' % (type, level)): 96 self.registry.setdefault(type, {}).setdefault(level, []).\ 97 append(klass)
98
99 - def register_all(self, dir):
100 if not os.path.isdir(dir): 101 return 102 for file in os.listdir(dir): 103 file = os.path.join(dir, file) 104 if file.endswith('.py'): 105 try: 106 self.cur_file = file 107 local_checks = {'_': __builtins__['_'], 'dprint': dprint, \ 108 'DataValidator': DataValidator, 'os': os} 109 execfile(file, local_checks) 110 except StandardError: 111 print _("Failed to import %s.") % file 112 traceback.print_exc(file=sys.stdout)
113
114 - def apply(self, lab, file, information, level):
115 type = self.transliterate(os.path.splitext(file)[1][1:]) 116 if not self.registry.has_key(type): 117 raise CheckRunningException('No checks registered with a type of %s.' % type) 118 if not self.registry[type].has_key(level): 119 raise CheckRunningException('No checks registered with a type of %s, and a level of %d.' % (type, level)) 120 errdicts = {} 121 for klass in self.registry[type][level]: 122 dprint(_("Instantiating check: %s") % klass.__name__) 123 instance = klass(lab, file, information) 124 method = getattr(instance, 'check_' + type + '_' + repr(level)) 125 if hasattr(outputobj, 'group_pre_print'): 126 outputobj.add_type(type, level) 127 outputobj.group_pre_print() 128 dprint(_("Calling %s.%s().") % (klass.__name__, method.__name__)) 129 try: 130 method() 131 except KeyboardInterrupt: 132 print _("Check %s interrupted.") % klass.__name__ 133 if not clparser['quiet'] and clparser['traceback']: 134 traceback.print_exc(file=sys.stdout) 135 except Exception: 136 if not clparser['quiet']: 137 excptype, value = sys.exc_info()[:2] 138 print _("Check %s failed. Exception %s thrown (%s).") % \ 139 (klass.__name__, excptype.__name__, value) 140 if clparser['traceback']: 141 traceback.print_exc(file=sys.stdout) 142 check_dir = os.path.split(os.path.split(instance.__file__)[0])[0] 143 tmp_file = instance.__class__.__name__.lower() 144 if tmp_file.endswith('check'): 145 tmp_file = tmp_file[:-5] 146 data_file = os.path.join(check_dir, 'data', '%s.data' % tmp_file) 147 errdicts[data_file] = instance.err_dict 148 return errdicts
149
150 - def purge(self):
151 checks_to_run = clparser['checks'].replace(' ', '').split(',') 152 list_to_cull = [] 153 for pkg_type in ('binary', 'source'): 154 for level in (1, 2): 155 for x in self.registry[pkg_type][level]: 156 class_str = x.__name__.lower() 157 not_found = 0 158 for y in checks_to_run: 159 if not re.match(y, class_str, re.IGNORECASE + \ 160 re.DOTALL): 161 not_found += 1 162 if not_found == len(checks_to_run): 163 list_to_cull.append(x) 164 for x in list_to_cull: 165 self.registry[pkg_type][level].remove(x) 166 list_to_cull = []
167
168 - def print_checks(self):
169 for pkg_type in clparser['list-checks'][0]: 170 for level in clparser['list-checks'][1]: 171 if self.registry[pkg_type][level]: 172 print "%s checks (level %d): " % (pkg_type.title(), level) 173 for x in self.registry[pkg_type][level]: 174 if x.__doc__ is not None: 175 docstr = x.__doc__ 176 else: 177 docstr = "No doc string." 178 print " - %s: %s" % (x.__name__, docstr)
179
180 - def transliterate(self, type):
181 mapping = {'deb': 'binary', 'dsc': 'source', 'changes': 'changes', \ 182 'udeb': 'udeb'} 183 return mapping[type]
184
185 -class CheckRunningException(Exception):
186 pass
187