def load_rules(args, add_rules=(), add_dirs=()): """Load rules from set directories Keyword Arguments: add_rules {tuple} -- Additional builtin rulesets to be loaded (default: {[]}) add_dirs {tuple} -- Additional directories to parse for rules (default: {[]}) Returns: list -- Class instances of loaded rules """ res = [] _rule_file = get_rulefile() _path_list = { 'base': {'path': 'rule_base', 'builtin': True}, } for ar in add_rules: _path_list[ar] = {'path': 'rule_{a}'.format(a=ar), 'builtin': True} for ar in add_dirs: _path_list['additional_{a}'.format(a=os.path.basename(ar))] = { 'path': ar, 'builtin': False} # pragma: no cover for _, v in _path_list.items(): if v['builtin']: _searchpath = os.path.join(os.path.dirname( os.path.abspath(__file__)), v['path']) else: _searchpath = os.path.join(v['path']) # pragma: no cover sys.path.append(os.path.dirname(v['path'])) # pragma: no cover packages = pkgutil.walk_packages(path=[_searchpath]) for _, name, _ in packages: if v['builtin']: name = __name__.split('.')[0] + '.' + v['path'] + '.' + name else: name = os.path.basename(v['path']) + '.' + name # pragma: no cover try: mod = importlib.import_module(name) for m in inspect.getmembers(mod, inspect.isclass): try: if issubclass(m[1], Rule): inst = m[1]() _potential_ids = [ inst.ID] + ['{a}.{b}'.format(a=inst.ID, b=x) for x in inst.Appendix] if any(_potential_ids): if _rule_file and not any(x in _rule_file for x in _potential_ids): continue # pragma: no cover res.append(inst) except Exception: # pragma: no cover pass # pragma: no cover except Exception as e: # pragma: no cover if not args.quiet: # pragma: no cover print( # noqa: T001 this print is fine here 'Can\'t load rule {rule} -> {exp}'.format(rule=name, exp=e)) # pragma: no cover return res
def finding(self, _file, _line, override_msg=None, appendix=None): """Called by rule to indicate a finding Arguments: _file {str} -- Full path to file or origin _line {int} -- Line number in file Keyword Arguments: override_msg {str} -- Optional string which overrides the set standard message (default: {None}) appendix {str} -- Optional appendix to rule ID (default: {None}) Returns: str -- Human readable finding (possibly with color codes) """ if not self.OnAppend and _file.endswith(".bbappend"): return [] if self.OnlyAppend and not _file.endswith(".bbappend"): return [] if override_msg is None: override_msg = self.Msg _severity = self.Severity _rule_file = get_rulefile() _id = self.ID if appendix: _id += "." + appendix if _rule_file and self.ID in _rule_file: _severity = _rule_file[self.ID] or self.Severity if _severity == "info" and get_noinfo(): return [] if _severity == "warning" and get_nowarn(): return [] if _line <= 0: # Fix those issues, that don't come with a line _line = 1 if get_color(): if _severity == "error": return [(_line, "{}:{}{}:{}:{}:{}{}".format( os.path.abspath(_file), Fore.RED, _line, _severity, _id, override_msg, Style.RESET_ALL))] elif _severity == "warning": return [(_line, "{}:{}{}:{}:{}:{}{}".format( os.path.abspath(_file), Fore.YELLOW, _line, _severity, _id, override_msg, Style.RESET_ALL))] else: return [(_line, "{}:{}{}:{}:{}:{}{}".format( os.path.abspath(_file), Fore.GREEN, _line, _severity, _id, override_msg, Style.RESET_ALL))] return [(_line, "{}:{}:{}:{}:{}".format(os.path.abspath(_file), _line, _severity, _id, override_msg))]
def load_rules(args, add_rules=[], add_dirs=[]): """Load rules from set directories Keyword Arguments: add_rules {list} -- Additional builtin rulesets to be loaded (default: {[]}) add_dirs {list} -- Additional directories to parse for rules (default: {[]}) Returns: list -- Class instances of loaded rules """ res = [] _rule_file = get_rulefile() _path_list = {"base": {"path": "rule_base", "builtin": True}} for ar in add_rules: _path_list[ar] = {"path": "rule_{}".format(ar), "builtin": True} for ar in add_dirs: _path_list["additional_{}".format(os.path.basename(ar))] = { "path": ar, "builtin": False } for _, v in _path_list.items(): if v["builtin"]: _searchpath = os.path.join( os.path.dirname(os.path.abspath(__file__)), v["path"]) else: _searchpath = os.path.join(v["path"]) sys.path.append(os.path.dirname(v["path"])) packages = pkgutil.walk_packages(path=[_searchpath]) for _, name, _ in packages: if v["builtin"]: name = __name__.split(".")[0] + "." + v["path"] + "." + name else: name = os.path.basename(v["path"]) + "." + name try: mod = importlib.import_module(name) for m in inspect.getmembers(mod, inspect.isclass): try: if issubclass(m[1], Rule): inst = m[1]() if inst.ID: if _rule_file and inst.ID not in _rule_file: continue res.append(inst) except Exception: pass except Exception as e: if not args.quiet: print("Can't load rule {} -> {}".format(name, e)) return res
def get_severity(self, appendix=None): """Get the configured severity for this rule, if it is enabled. Keyword Arguments: appendix {str} -- Potential subrule name (default: {None}) Returns: str -- Severity for this rule if it is enabled, {None} if disabled. """ _rule_file = get_rulefile() if not _rule_file: return self.Severity _subid = None if appendix is None else f'{self.ID}.{appendix}' if _subid and _subid in _rule_file: _severity = _rule_file[_subid] elif self.ID in _rule_file: _severity = _rule_file[self.ID] else: # rule not in rulefile return None return _severity if _severity != '' else self.Severity
def __get_const_and_rulefile(l, key): res = l _rulefile = {**get_rulefile(), **get_constantfile()} if key in _rulefile.keys() and isinstance(_rulefile[key], list): res += _rulefile[key] return res
def __get_const_and_rulefile_dict(l, key): res = l _rulefile = {**get_rulefile(), **get_constantfile()} if key in _rulefile.keys() and isinstance(_rulefile[key], dict): res = {**res, **_rulefile[key]} return res