class StringConstants: THIS_IS_A_BUG = _("This is a bug. We are sorry for the inconvenience. " "Please contact the developers for assistance.") OBJ_NOT_ACCESSIBLE = _("{} is not accessible and will be ignored!") TRUE_STRINGS = [ '1', "on", 'y', 'yes', "yeah", "sure", 'true', 'definitely', 'yup', "right" ] FALSE_STRINGS = ['0', 'off', 'n', 'no', 'nope', 'nah', 'false', "wrong"] # This string contains many unicode characters to challenge tests. COMPLEX_TEST_STRING = ("4 r34l ch4ll3n63: 123 ÄÖü ABc @€¥ §&% {[( ←↓→↑ " "ĦŊħ ß°^ \\\n\u2192") # Results from coverage for unittests are stored here. COVERAGE_DIR = "./.coverageresults" # Path to the coalib directory coalib_root = os.path.join(os.path.dirname(inspect.getfile(_)), os.path.pardir) # Path to the directory containing the default bears coalib_bears_root = os.path.join(coalib_root, os.path.pardir, "bears") system_coafile = os.path.join(coalib_root, "default_coafile") user_coafile = os.path.join(os.path.expanduser("~"), ".coarc")
def _validate_results(self, result_list, name, args, kwargs): if result_list is None: return None if not isinstance(result_list, list): self.err(_("The results from the bear {bear} couldn't be processed" " with arguments {arglist}, {kwarglist}.") .format(bear=name, arglist=args, kwarglist=kwargs)) self.debug(_("The return value of the {bear} is an instance of" " {ret} but should be an instance of list.") .format(bear=name, ret=result_list.__class__)) return None for result in result_list: if not isinstance(result, Result): self.err(_("The results from the bear {bear} could only be" "partially processed with arguments {arglist}, " "{kwarglist}") .format(bear=name, arglist=args, kwarglist=kwargs)) self.debug(_("One of the results in the list for the bear " "{bear} is an instance of {ret} but it should be " "an instance of Result") .format(bear=name, ret=result.__class__)) result_list.remove(result) return result_list
def test_require_settings(self): self.assertRaises(TypeError, self.uut.acquire_settings, 0) self.assertEqual(self.uut.acquire_settings({0: 0}), {}) self.assertEqual( self.uut.acquire_settings({"setting": ["help text", "SomeBear"]}), { "setting": self.uut.STR_GET_VAL_FOR_SETTING.format( "setting", "help text", "SomeBear") }) self.assertEqual( self.uut.acquire_settings( {"setting": ["help text", "SomeBear", "AnotherBear"]}), { "setting": self.uut.STR_GET_VAL_FOR_SETTING.format( "setting", "help text", "SomeBear" + _(" and ") + "AnotherBear") }) self.assertEqual( self.uut.acquire_settings({ "setting": ["help text", "SomeBear", "AnotherBear", "YetAnotherBear"] }), { "setting": self.uut.STR_GET_VAL_FOR_SETTING.format( "setting", "help text", "SomeBear, AnotherBear" + _(" and ") + "YetAnotherBear") })
def require_setting(log_printer, setting_name, arr): """ This method is responsible for prompting a user about a missing setting and taking its value as input from the user. :param log_printer: Printer responsible for logging the messages. :param setting_name: Name od the setting missing :param arr: a list containing a description in [0] and the name of the bears who need this setting in [1] and following. """ if not isinstance(arr, list) or len(arr) < 2: log_printer.log(LOG_LEVEL.WARNING, _("One of the given settings ({}) is not properly " "described.").format(str(setting_name))) return None if len(arr) == 2: needed = arr[1] else: needed = ", ".join(arr[1:-1]) + _(" and ") + arr[-1] return input(STR_GET_VAL_FOR_SETTING.format(str(setting_name), str(arr[0]), needed))
def choose_action(console_printer, actions): """ Presents the actions available to the user and takes as input the action the user wants to choose. :param console_printer: Object to print messages on the console. :param actions: Actions available to the user. :return: Return choice of action of user. """ console_printer.print(format_line( _("The following options are applicable to this result:"))) while True: console_printer.print(format_line(" 0: " + _("Do nothing."))) for i, action in enumerate(actions): console_printer.print(format_line("{:>2}: {}".format(i + 1, action.desc))) try: line = format_line(_("Please enter the number of the action " "you want to execute. ")) choice = int(input(line)) if 0 <= choice <= len(actions): return choice except ValueError: pass console_printer.print(format_line(_("Please enter a valid number.")))
def test_str_conversion(self): self.assertEqual(_("INFO"), RESULT_SEVERITY.__str__(RESULT_SEVERITY.INFO)) self.assertEqual(_("NORMAL"), RESULT_SEVERITY.__str__(RESULT_SEVERITY.NORMAL)) self.assertEqual(_("MAJOR"), RESULT_SEVERITY.__str__(RESULT_SEVERITY.MAJOR))
def get_file_dict(filename_list, log_printer): """ Reads all files into a dictionary. :param filename_list: List of names of paths to files to get contents of. :param log_printer: The logger which logs errors. :return: Reads the content of each file into a dictionary with filenames as keys. """ file_dict = {} for filename in filename_list: try: with open(filename, "r", encoding="utf-8") as _file: file_dict[filename] = _file.readlines() except UnicodeDecodeError: log_printer.warn(_("Failed to read file '{}'. It seems to contain " "non-unicode characters. Leaving it " "out.".format(filename))) except Exception as exception: # pragma: no cover log_printer.log_exception(_("Failed to read file '{}' because of " "an unknown error. Leaving it " "out.").format(filename), exception, log_level=LOG_LEVEL.WARNING) return file_dict
def fail_acquire_settings(log_printer, settings_names_dict): """ This method throws an exception if any setting needs to be acquired. :param log_printer: Printer responsible for logging the messages. :param settings: A dictionary with the settings name as key and a list containing a description in [0] and the name of the bears who need this setting in [1] and following. :raises AssertionError: If any setting is required. :raises TypeError: If `settings_names_dict` is not a dictionary. """ if not isinstance(settings_names_dict, dict): raise TypeError("The settings_names_dict parameter has to be a " "dictionary.") required_settings = settings_names_dict.keys() if len(required_settings) != 0: msg = _("During execution, we found that some required" "settings were not provided. They are:\n") for name, setting in settings_names_dict.items(): msg += _("{} (from {}) - {}".format(name, setting[1], setting[0])) log_printer.err(msg) raise AssertionError
def _validate_results(self, result_list, name, args, kwargs): if result_list is None: return None if not isinstance(result_list, list): self.err( _("The results from the bear {bear} couldn't be processed" " with arguments {arglist}, {kwarglist}.").format( bear=name, arglist=args, kwarglist=kwargs)) self.debug( _("The return value of the {bear} is an instance of" " {ret} but should be an instance of list.").format( bear=name, ret=result_list.__class__)) return None for result in result_list: if not isinstance(result, Result): self.err( _("The results from the bear {bear} could only be" "partially processed with arguments {arglist}, " "{kwarglist}").format(bear=name, arglist=args, kwarglist=kwargs)) self.debug( _("One of the results in the list for the bear " "{bear} is an instance of {ret} but it should be " "an instance of Result").format(bear=name, ret=result.__class__)) result_list.remove(result) return result_list
def test_require_settings(self): self.assertRaises(TypeError, self.uut.acquire_settings, 0) self.assertEqual(self.uut.acquire_settings({0: 0}), {}) self.assertEqual(self.uut.acquire_settings({"setting": ["help text", "SomeBear"]}), {"setting": self.uut.STR_GET_VAL_FOR_SETTING.format( "setting", "help text", "SomeBear")}) self.assertEqual(self.uut.acquire_settings({"setting": ["help text", "SomeBear", "AnotherBear"]}), {"setting": self.uut.STR_GET_VAL_FOR_SETTING.format( "setting", "help text", "SomeBear" + _(" and ") + "AnotherBear")}) self.assertEqual(self.uut.acquire_settings({"setting": ["help text", "SomeBear", "AnotherBear", "YetAnotherBear"]}), {"setting": self.uut.STR_GET_VAL_FOR_SETTING.format( "setting", "help text", "SomeBear, AnotherBear" + _(" and ") + "YetAnotherBear")})
def test_print_bears_empty(self): with retrieve_stdout() as stdout: bears = {} print_bears(self.log_printer.printer, bears, True) self.assertEqual(_("No bears to show.") + "\n", stdout.getvalue()) with retrieve_stdout() as stdout: bears = {} print_bears(self.log_printer.printer, bears, False) self.assertEqual(_("No bears to show.") + "\n", stdout.getvalue())
def test_to_str(self): self.uut.message = StringConstants.COMPLEX_TEST_STRING self.uut.log_level = LOG_LEVEL.ERROR self.assertEqual(str(self.uut), "[{}] {}".format(_("ERROR"), StringConstants.COMPLEX_TEST_STRING)) self.uut.log_level = LOG_LEVEL.WARNING self.assertEqual(str(self.uut), "[{}] {}".format(_("WARNING"), StringConstants.COMPLEX_TEST_STRING)) self.uut.log_level = LOG_LEVEL.DEBUG self.assertEqual(str(self.uut), "[{}] {}".format(_("DEBUG"), StringConstants.COMPLEX_TEST_STRING)) self.uut.log_level = 5 self.assertEqual(str(self.uut), "[{}] {}".format(_("ERROR"), StringConstants.COMPLEX_TEST_STRING))
def run_local_bears_on_file(message_queue, timeout, file_dict, local_bear_list, local_result_dict, control_queue, filename): """ This method runs a list of local bears on one file. :param message_queue: A queue that contains messages of type errors/warnings/debug statements to be printed in the Log. :param timeout: The queue blocks at most timeout seconds for a free slot to execute the put operation on. After the timeout it returns queue Full exception. :param file_dict: Dictionary that contains contents of files. :param local_bear_list: List of local bears to run on file. :param local_result_dict: A Manager.dict that will be used to store local bear results. A list of all local bear results will be stored with the filename as key. :param control_queue: If any result gets written to the result_dict a tuple containing a CONTROL_ELEMENT (to indicate what kind of event happened) and either a bear name(for global results) or a file name to indicate the result will be put to the queue. :param filename: The name of file on which to run the bears. """ if filename not in file_dict: send_msg(message_queue, timeout, LOG_LEVEL.ERROR, _("An internal error occurred."), Constants.THIS_IS_A_BUG) send_msg(message_queue, timeout, LOG_LEVEL.DEBUG, _("The given file through the queue is not in the file " "dictionary.")) return local_result_list = [] for bear_instance in local_bear_list: result = run_local_bear(message_queue, timeout, local_result_list, file_dict, bear_instance, filename) if result is not None: local_result_list.extend(result) local_result_dict[filename] = local_result_list control_queue.put((CONTROL_ELEMENT.LOCAL, filename))
def test_process_timestamp(self): reference_timestamp = datetime.datetime(2015, 7, 3, 20, 30, 0).timetuple() self.assertEqual( _("Just Now"), timestamp_diff(reference_timestamp, reference_timestamp)) timestamp = datetime.datetime(2014, 7, 1, 0, 0, 0).timetuple() self.assertEqual("2014", timestamp_diff(timestamp, reference_timestamp)) timestamp = datetime.datetime(2015, 7, 1, 0, 0, 0).timetuple() self.assertEqual(_("Wednesday"), timestamp_diff(timestamp, reference_timestamp)) timestamp = datetime.datetime(2015, 6, 1, 0, 0, 0).timetuple() self.assertEqual(_("June"), timestamp_diff(timestamp, reference_timestamp)) timestamp = datetime.datetime(2015, 7, 3, 15, 0, 0).timetuple() self.assertEqual(_("5 hours ago"), timestamp_diff(timestamp, reference_timestamp)) timestamp = datetime.datetime(2015, 7, 3, 20, 29, 0).timetuple() self.assertEqual(_("A minute ago"), timestamp_diff(timestamp, reference_timestamp)) timestamp = datetime.datetime(2015, 7, 3, 20, 0, 0).timetuple() self.assertEqual(_("30 minutes ago"), timestamp_diff(timestamp, reference_timestamp)) timestamp = datetime.datetime(2015, 7, 2, 0, 0, 0).timetuple() self.assertEqual(_("Yesterday"), timestamp_diff(timestamp, reference_timestamp)) timestamp = datetime.datetime(2015, 7, 3, 0, 0, 0).timetuple() self.assertEqual(_("Today"), timestamp_diff(timestamp, reference_timestamp)) timestamp = datetime.datetime(2015, 6, 23, 0, 0, 0).timetuple() self.assertEqual(_("1 week ago"), timestamp_diff(timestamp, reference_timestamp))
def test_process_timestamp(self): reference_timestamp = datetime.datetime( 2015, 7, 3, 20, 30, 0).timetuple() self.assertEqual(_("Just Now"), timestamp_diff(reference_timestamp, reference_timestamp)) timestamp = datetime.datetime(2014, 7, 1, 0, 0, 0).timetuple() self.assertEqual("2014", timestamp_diff(timestamp, reference_timestamp)) timestamp = datetime.datetime(2015, 7, 1, 0, 0, 0).timetuple() self.assertEqual(_("Wednesday"), timestamp_diff(timestamp, reference_timestamp)) timestamp = datetime.datetime(2015, 6, 1, 0, 0, 0).timetuple() self.assertEqual(_("June"), timestamp_diff(timestamp, reference_timestamp)) timestamp = datetime.datetime(2015, 7, 3, 15, 0, 0).timetuple() self.assertEqual(_("5 hours ago"), timestamp_diff( timestamp, reference_timestamp)) timestamp = datetime.datetime(2015, 7, 3, 20, 29, 0).timetuple() self.assertEqual(_("A minute ago"), timestamp_diff(timestamp, reference_timestamp)) timestamp = datetime.datetime(2015, 7, 3, 20, 0, 0).timetuple() self.assertEqual(_("30 minutes ago"), timestamp_diff(timestamp, reference_timestamp)) timestamp = datetime.datetime(2015, 7, 2, 0, 0, 0).timetuple() self.assertEqual(_("Yesterday"), timestamp_diff(timestamp, reference_timestamp)) timestamp = datetime.datetime(2015, 7, 3, 0, 0, 0).timetuple() self.assertEqual(_("Today"), timestamp_diff(timestamp, reference_timestamp)) timestamp = datetime.datetime(2015, 6, 23, 0, 0, 0).timetuple() self.assertEqual(_("1 week ago"), timestamp_diff(timestamp, reference_timestamp))
def _get_log_prefix(self, log_level, timestamp): datetime_string = timestamp.strftime(self.timestamp_format) if datetime_string != "": datetime_string = "[" + datetime_string + "]" return '[{}]{} '.format({ LOG_LEVEL.DEBUG: _("DEBUG"), LOG_LEVEL.WARNING: _("WARNING"), LOG_LEVEL.ERROR: _("ERROR") }.get(log_level, _("ERROR")), datetime_string)
def test_print_bears_no_sections(self): with retrieve_stdout() as stdout: bears = {SomeBear: []} print_bears(self.log_printer.printer, bears) expected_string = "SomeBear:\n" expected_string += " " + "Some Description." + "\n\n" expected_string += " " + _("No sections.") + "\n\n" expected_string += " " + _("No needed settings.") + "\n\n" expected_string += " " + _("No optional settings.") + "\n\n" self.assertEqual(expected_string, stdout.getvalue())
def test_bool_conversion(self): self.assertEqual(bool(self.uut), True) self.uut.value = _("yeah") self.assertEqual(bool(self.uut), True) self.uut = StringConverter("y") self.assertEqual(bool(self.uut), True) self.uut = StringConverter(_("nope")) self.assertEqual(bool(self.uut), False) self.uut = StringConverter(" i dont know ") self.assertRaises(ValueError, bool, self.uut)
def test_bad_bear(self): self.uut = BadTestBear(self.settings, self.queue) self.uut.execute() self.check_message(LOG_LEVEL.DEBUG, _("Running bear {}...").format("BadTestBear")) self.check_message( LOG_LEVEL.WARNING, _("Bear {} failed to run. Take a look at debug " "messages for further " "information.").format( "BadTestBear" ), ) # debug message contains custom content, dont test this here self.queue.get()
def test_message_queue(self): self.uut.execute() self.check_message(LOG_LEVEL.DEBUG, _("Setting up bear {}...").format("TestBear")) self.check_message(LOG_LEVEL.DEBUG, "set=up") self.check_message(LOG_LEVEL.DEBUG, _("Running bear {}...").format("TestBear")) self.check_message(LOG_LEVEL.WARNING, _("A string to test translations.")) self.check_message(LOG_LEVEL.DEBUG, _("Tearing down bear {}...").format("TestBear")) self.check_message(LOG_LEVEL.ERROR, "teardown")
def test_static_functions(self): with retrieve_stdout() as stdout: print_section_beginning(self.console_printer, Section("name")) self.assertEqual(stdout.getvalue(), _("Executing section " "{name}...").format(name="name") + "\n") with retrieve_stdout() as stdout: nothing_done(self.console_printer) self.assertEqual(stdout.getvalue(), _("No existent section was targeted or enabled. " "Nothing to do.") + "\n")
def test_static_functions(self): q = queue.Queue() # 0:-1 to strip of the trailing newline character self.uut._print = lambda string: q.put(string[0:-1]) self.uut.begin_section(Section("name")) self.assertEqual(q.get(timeout=0), _("Executing section " "{name}...").format(name="name")) self.uut.did_nothing() self.assertEqual(q.get(timeout=0), _("No existent section was targeted or enabled. " "Nothing to do."))
def test_message_queue(self): self.uut.run() self.check_message(LOG_LEVEL.DEBUG, _("Setting up bear {}...").format("TestBear")) self.check_message(LOG_LEVEL.DEBUG, "set=up") self.check_message(LOG_LEVEL.DEBUG, _("Running bear {}...").format("TestBear")) self.check_message(LOG_LEVEL.WARNING, _("A string to test translations.")) self.check_message(LOG_LEVEL.DEBUG, _("Tearing down bear {}...").format("TestBear")) self.check_message(LOG_LEVEL.ERROR, "teardown")
def test_bad_bear(self): self.uut = BadTestBear(self.settings, self.queue) self.uut.run() self.check_message(LOG_LEVEL.DEBUG, _("Setting up bear {}...").format("BadTestBear")) self.check_message(LOG_LEVEL.DEBUG, _("Running bear {}...").format("BadTestBear")) self.check_message(LOG_LEVEL.DEBUG, _("Tearing down bear {}...").format("BadTestBear")) self.check_message(LOG_LEVEL.WARNING, _("Bear {} failed to run").format("BadTestBear")) self.queue.get( ) # debug message contains custom content, dont test this here
def test_bad_bear(self): self.uut = BadTestBear(self.settings, self.queue) self.uut.execute() self.check_message(LOG_LEVEL.DEBUG, _("Setting up bear {}...").format("BadTestBear")) self.check_message(LOG_LEVEL.DEBUG, _("Running bear {}...").format("BadTestBear")) self.check_message(LOG_LEVEL.DEBUG, _("Tearing down bear {}...").format("BadTestBear")) self.check_message(LOG_LEVEL.WARNING, _("Bear {} failed to run.").format("BadTestBear")) # debug message contains custom content, dont test this here self.queue.get()
def test_print_bears_no_optional_settings(self): with retrieve_stdout() as stdout: bears = {TestBear2: ["test"]} print_bears(self.log_printer.printer, bears) expected_string = "TestBear2:\n" expected_string += " Test bear 2 description.\n\n" expected_string += " " + _("Used in:") + "\n" expected_string += " * test\n\n" expected_string += " " + _("Needed Settings:") + "\n" expected_string += " * setting1: Required Setting.\n\n" expected_string += " " + _("No optional settings.") + "\n\n" self.assertEqual(expected_string, stdout.getvalue())
def run_bear(message_queue, timeout, bear_instance, *args, **kwargs): """ This method is responsible for executing the instance of a bear. It also reports or logs errors if any occur during the execution of that bear instance. :param message_queue: A queue that contains messages of type errors/warnings/debug statements to be printed in the Log. :param timeout: The queue blocks at most timeout seconds for a free slot to execute the put operation on. After the timeout it returns queue Full exception. :param bear_instance: The instance of the bear to be executed. :param args: The arguments that are to be passed to the bear. :param kwargs: The keyword arguments that are to be passed to the bear. :return: Returns a valid list of objects of the type Result if the bear executed succesfully. None otherwise. """ if kwargs.get("dependency_results", True) is None: del kwargs["dependency_results"] name = bear_instance.__class__.__name__ try: result_list = bear_instance.execute(*args, **kwargs) except: send_msg(message_queue, timeout, LOG_LEVEL.ERROR, _("The bear {bear} failed to run with the arguments " "{arglist}, {kwarglist}. Skipping bear...") .format(bear=name, arglist=args, kwarglist=kwargs)) send_msg(message_queue, timeout, LOG_LEVEL.DEBUG, _("Traceback for error in bear {bear}:") .format(bear=name), traceback.format_exc(), delimiter="\n") return None return validate_results(message_queue, timeout, result_list, name, args, kwargs)
def get_exitcode(exception, log_printer=None): log_printer = log_printer or LogPrinter(NullPrinter()) exitcode = 0 if isinstance(exception, KeyboardInterrupt): # Ctrl+C print(_("Program terminated by user.")) exitcode = 130 elif isinstance(exception, EOFError): # Ctrl+D print(_("Found EOF. Exiting gracefully.")) elif isinstance(exception, SystemExit): exitcode = exception.code elif isinstance(exception, BaseException): log_printer.log_exception(Constants.CRASH_MESSAGE, exception) exitcode = 255 return exitcode
def test_print_bears_no_needed_settings(self): with retrieve_stdout() as stdout: bears = {SomeOtherBear: ["test"]} print_bears(self.log_printer.printer, bears) expected_string = "SomeOtherBear:\n" expected_string += " " + "This is a Bear." + "\n\n" expected_string += " " + _("Used in:") + "\n" expected_string += " * test\n\n" expected_string += " " + _("No needed settings.") + "\n\n" expected_string += " " + _("Optional Settings:") + "\n" expected_string += " * setting: This is an optional setting. (" expected_string += _("Optional, defaults to '{}'.").format("None") expected_string += ")\n\n" self.assertEqual(expected_string, stdout.getvalue())
def test_static_functions(self): q = queue.Queue() # 0:-1 to strip of the trailing newline character self.uut._print = lambda string: q.put(string[0:-1]) self.uut.begin_section(Section("name")) self.assertEqual( q.get(timeout=0), _("Executing section " "{name}...").format(name="name")) self.uut.did_nothing() self.assertEqual( q.get(timeout=0), _("No existent section was targeted or enabled. " "Nothing to do."))
def test_translation_marking(self): self.set_lang("de_DE.UTF8") string = "A not directly translated test string." self.assertEqual(i18n.N_("A not directly translated test string."), string) self.assertEqual(i18n._(string), "Ein indirekt übersetzter test String.")
def icollect_bears(bear_dirs, bear_names, kinds, log_printer): """ Collect all bears from bear directories that have a matching kind. :param bear_dirs: directory name or list of such that can contain bears :param bear_names: names of bears :param kinds: list of bear kinds to be collected :param log_printer: log_printer to handle logging :return: iterator that yields bear classes """ for bear_dir in filter(os.path.isdir, icollect(bear_dirs)): for bear_name in bear_names: for matching_file in iglob( os.path.join(bear_dir, bear_name + '.py')): try: for bear in _import_bears(matching_file, kinds): yield bear except BaseException as exception: log_printer.log_exception( _("Unable to collect bears from {file}. Probably the " "file is malformed or the module code raises an " "exception.").format(file=matching_file), exception, log_level=LOG_LEVEL.WARNING)
def run(self, filename, file, cs_keywords: list, ci_keywords: list): ''' Checks the code files for given keywords. :param cs_keywords: A list of keywords to search for (case sensitive). Usual examples are TODO and FIXME. :param ci_keywords: A list of keywords to search for (case insensitive). ''' for i in range(len(ci_keywords)): ci_keywords[i] = ci_keywords[i].lower() for line_number, line in enumerate(file): found_kws = [] for keyword in cs_keywords: if keyword in line: found_kws.append(keyword) for keyword in ci_keywords: if keyword in line.lower(): found_kws.append(keyword) if found_kws != []: yield Result( origin=self, message=_("Line contains the following keywords:") + "\n" + ", ".join(found_kws), file=filename, line_nr=line_number + 1)
def _load_configuration(self, arg_list): self.cli_sections = self.cli_parser.reparse(arg_list=arg_list) try: self.default_section = self.conf_parser.reparse( os.path.abspath( os.path.join(StringConstants.coalib_root, "default_coafile")))["default"] except self.conf_parser.FileNotFoundError: self.cli_sections["default"].retrieve_logging_objects() self.cli_sections["default"].log_printer.err( _("The global default coafile for the settings was not found. " "It seems your installation is broken.") + " " + StringConstants.THIS_IS_A_BUG) raise SystemExit for section in self.cli_sections: self.cli_sections[section].defaults = self.default_section try: config = os.path.abspath( str(self.cli_sections["default"].get("config", "./coafile"))) self.conf_sections = self.conf_parser.reparse(config) # We'll get the default section as default section for every section in this dict with this # Furthermore we will have the CLI Values take precedence over the conf values. self._merge_section_dicts() except self.conf_parser.FileNotFoundError: self.conf_sections = self.cli_sections
def log_exception(self, message, exception, log_level=LOG_LEVEL.ERROR, timestamp=None, **kwargs): """ If the log_level of the printer is greater than DEBUG, it prints only the message. If it is DEBUG or lower, it shows the message along with the traceback of the exception. :param message: The message to print. :param exception: The exception to print. :param log_level: The log_level of this message (not used when logging the traceback. Tracebacks always have a level of DEBUG). :param timestamp: The time at which this log occured. Defaults to the current time. :param kwargs: Keyword arguments to be passed when logging the message (not used when logging the traceback). """ if not isinstance(exception, BaseException): raise TypeError("log_exception can only log derivatives of " "BaseException.") traceback_str = "\n".join(traceback.format_exception(type(exception), exception, exception.__traceback__)) self.log(log_level, message, timestamp=timestamp, **kwargs) self.log_message( LogMessage(LOG_LEVEL.DEBUG, _("Exception was:") + "\n" + traceback_str, timestamp=timestamp), **kwargs )
def run_bear(self, filename, file, max_line_length: int, tab_width: int = SpacingHelper.DEFAULT_TAB_WIDTH): """ Yields results for all lines longer than the given maximum line length. :param max_line_length: Maximum number of characters for a line. :param tab_width: Number of spaces to show for one tab. """ results = [] bearname = self.__class__.__name__ spacing_helper = SpacingHelper.from_section(section=self.section) for line_number, line in enumerate(file): line = spacing_helper.replace_tabs_with_spaces(line) if len(line) > max_line_length + 1: results.append( Result(origin=bearname, message=_("Line is longer than allowed.") + " ({actual} > {maximum})".format( actual=len(line), maximum=max_line_length), file=filename, line_nr=line_number + 1)) return results
def _get_log_prefix(self, log_level, timestamp): datetime_string = timestamp.strftime(self.timestamp_format) if datetime_string != "": datetime_string = "[" + datetime_string + "]" return "[{}]{}".format(_(LOG_LEVEL.reverse.get(log_level, "ERROR")), datetime_string)
def _is_target(self, file_path): """ :param file_path: absolute path to a file :return: Bool value to determine if the file should be collected This method assumes that the given path lies in a directory that should be collected. However it will check if the path is a subpath of an ignored directory. """ for ignored_path in self._ignored_files: if file_path.startswith(ignored_path): return False try: if self._regex != "$" and re.match(self._regex, os.path.split(file_path)[1]): return True except re.error: self.log_printer.warn( _("One of the given regexes ('{regex}') was not valid and will be ignored. The error " "was '{error}'.").format(regex=self._regex, error=sys.exc_info()[1])) self._regex = "$" # Do not use this regex anymore file_type = os.path.splitext( os.path.basename(file_path))[1].lower().lstrip('.') if self._allowed_types is None or file_type in self._allowed_types: return True else: return False
def retrieve_logging_objects(self): """ Creates an appropriate log printer and interactor according to the settings. """ log_type = str(self.get("log_type", "console")).lower() output_type = str(self.get("output", "console")).lower() str_log_level = str(self.get("log_level", "")).upper() log_level = LOG_LEVEL.str_dict.get(str_log_level, LOG_LEVEL.WARNING) if log_type == "console": self.log_printer = ConsolePrinter(log_level=log_level) else: try: # ConsolePrinter is the only printer which may not throw an # exception (if we have no bugs though) so well fallback to him # if some other printer fails if log_type == "none": self.log_printer = NullPrinter() else: self.log_printer = FilePrinter(filename=log_type, log_level=log_level) except: self.log_printer = ConsolePrinter(log_level=log_level) self.log_printer.log( LOG_LEVEL.WARNING, _("Failed to instantiate the logging method '{}'. Falling " "back to console output.").format(log_type)) if output_type == "none": self.interactor = NullInteractor(log_printer=self.log_printer) else: self.interactor = ConsoleInteractor.from_section( self, log_printer=self.log_printer)
def run(self, filename, file, max_line_length: int, tab_width: int=SpacingHelper.DEFAULT_TAB_WIDTH): """ Yields results for all lines longer than the given maximum line length. :param max_line_length: Maximum number of characters for a line. :param tab_width: Number of spaces to show for one tab. """ results = [] spacing_helper = SpacingHelper.from_section(section=self.section) for line_number, line in enumerate(file): line = spacing_helper.replace_tabs_with_spaces(line) if len(line) > max_line_length + 1: results.append( Result(origin=self, message=_("Line is longer than allowed.") + " ({actual} > {maximum})".format( actual=len(line), maximum=max_line_length), file=filename, line_nr=line_number + 1)) return results
def print_result(self, result, file_dict): """ Prints the result appropriate to the output medium. :param result: A derivative of Result. :param file_dict: A dictionary containing all files with filename as key. """ if not isinstance(result, Result): self.log_printer.warn( _("One of the results can not be printed " "since it is not a valid derivative of " "the coala result class.")) return self._print_result(result) actions = result.get_actions() if actions == []: return action_dict = {} metadata_list = [] for action in actions: metadata = action.get_metadata() action_dict[metadata.name] = action metadata_list.append(metadata) action_name, section = self._print_actions(metadata_list) if action_name is None: return chosen_action = action_dict[action_name] chosen_action.apply_from_section(result, file_dict, self.file_diff_dict, section)
def nothing_done(console_printer): """ Will be called after processing a coafile when nothing had to be done, i.e. no section was enabled/targeted. """ console_printer.print(_("No existent section was targeted or enabled. " "Nothing to do."))
def run(self, dependency_results: dict, max_clone_difference: float = 0.185): """ Checks the given code for similar functions that are probably redundant. :param max_clone_difference: The maximum difference a clone should have. """ differences = dependency_results[ClangFunctionDifferenceBear.__name__][0].contents count_matrices = dependency_results[ClangFunctionDifferenceBear.__name__][1].contents self.debug("Creating results...") for function_1, function_2, difference in differences: if difference < max_clone_difference: yield Result( self.__class__.__name__, _( "Code clone found. The other occurrence is at file " "{file}, line {line}, function {function}. The " "difference is {difference}." ).format(file=function_2[0], line=function_2[1], function=function_2[2], difference=difference), file=function_1[0], severity=RESULT_SEVERITY.MAJOR, line_nr=function_1[1], debug_msg=[count_matrices[function_1], count_matrices[function_2]], )
def test_translation_marking(self): set_lang("de_DE.UTF8") string = "A not directly translated test string." self.assertEqual(i18n.N_("A not directly translated test string."), string) self.assertEqual(i18n._(string), "Ein indirekt übersetzter test String.")
def retrieve_logging_objects(self): """ Creates an appropriate log printer and interactor according to the settings. """ log_type = str(self.get("log_type", "console")).lower() log_level = LOG_LEVEL.from_str(str(self.get("log_level", "none"))) if log_type == "console": self.log_printer = ConsolePrinter(log_level=log_level) else: try: # ConsolePrinter is the only printer which may not throw an exception (if we have no bugs though) # so well fallback to him if some other printer fails if log_type == "none": self.log_printer = NullPrinter() else: self.log_printer = FilePrinter(filename=log_type, log_level=log_level) except: self.log_printer = ConsolePrinter(log_level=log_level) self.log_printer.log( LOG_LEVEL.WARNING, _("Failed to instantiate the logging method '{}'. Falling back " "to console output.").format(log_type)) # We currently only offer console interactor, so we'll ignore the output setting for now self.interactor = ConsoleInteractor.from_section( self, log_printer=self.log_printer)
def execute(self, *args, **kwargs): name = self.__class__.__name__ try: self.debug(_("Running bear {}...").format(name)) return self.run_bear_from_section(args, kwargs) except: self.warn( _("Bear {} failed to run. Take a look at debug messages for " "further information.").format(name)) self.debug( _("The bear {bear} raised an exception. If you are the writer " "of this bear, please make sure to catch all exceptions. If " "not and this error annoys you, you might want to get in " "contact with the writer of this bear.\n\nTraceback " "information is provided below:\n\n{traceback}" "\n").format(bear=name, traceback=traceback.format_exc()))
def run_bear(self, filename, file, cs_keywords: list, ci_keywords: list): """ Checks the code files for given keywords. :param cs_keywords: A list of keywords to search for case sensitively. Usual examples are TODO and FIXME. :param ci_keywords: A list of keywords to search for case insensitively. """ results = [] bearname = self.__class__.__name__ for i in range(len(ci_keywords)): ci_keywords[i] = ci_keywords[i].lower() for line_number, line in enumerate(file): found_kws = [] for kw in cs_keywords: if kw in line: found_kws.append(kw) for kw in ci_keywords: if kw in line.lower(): found_kws.append(kw) if found_kws != []: results.append( Result(origin=bearname, message=_("Line contains the following keywords:") + "\n" + ", ".join(found_kws), file=filename, line_nr=line_number + 1)) return results
def _get_log_prefix(self, log_level, timestamp): datetime_string = timestamp.strftime(self.timestamp_format) if datetime_string != "": datetime_string = "[" + datetime_string + "]" return '[{}]{} '.format(_(LOG_LEVEL.reverse.get(log_level, "ERROR")), datetime_string)
def _choose_action(self, actions): while True: for i, action in enumerate(actions): self.print( self._format_line("{:>2}: {}".format(i + 1, action.desc))) try: line = self._format_line( _("Please enter the number of the " "action you want to execute. ")) choice = int(input(line)) if 0 <= choice <= len(actions): return choice except ValueError: pass self.print(self._format_line(_("Please enter a valid number.")))
def _require_setting(self, setting_name, arr): if not isinstance(arr, list) or len(arr) < 2: self.log_printer.log( LOG_LEVEL.WARNING, _("One of the given settings ({}) are not properly " "described.").format(str(setting_name))) return None if len(arr) == 2: needed = arr[1] else: # Translators: this is the and that connects the last two items of an enumeration (1st, 2nd AND 3rd) needed = ", ".join(arr[1:-1]) + _(" and ") + arr[-1] return input( self.STR_GET_VAL_FOR_SETTING.format(str(setting_name), str(arr[0]), needed))
def __run_local_bears(self, filename): if filename not in self.file_dict: self.err(_("An internal error occurred."), StringConstants.THIS_IS_A_BUG) self.debug( _("The given file through the queue is not in the " "file dictionary.")) return self._local_result_list = [] for bear_instance in self.local_bear_list: r = self.__run_local_bear(bear_instance, filename) if r is not None: self._local_result_list.extend(r) self.local_result_dict[filename] = self._local_result_list self.control_queue.put((CONTROL_ELEMENT.LOCAL, filename))
def __init__(self): """ Raises EnvironmentError if VoiceOutput is impossible. """ Printer.__init__(self) # TODO retrieve language from get_locale and select appropriate voice try: self.espeak = subprocess.Popen(['espeak'], stdin=subprocess.PIPE) except OSError: # pragma: no cover print( _("eSpeak doesn't seem to be installed. You cannot use the voice output feature without eSpeak. " "It can be downloaded from http://espeak.sourceforge.net/ or installed via your usual package " "repositories.")) raise EnvironmentError except: # pragma: no cover print(_("Failed to execute eSpeak. An unknown error occurred."), StringConstants.THIS_IS_A_BUG) raise EnvironmentError
def test_to_str(self): self.uut.message = StringConstants.COMPLEX_TEST_STRING self.uut.log_level = LOG_LEVEL.ERROR self.assertEqual( str(self.uut), "[{}] {}".format(_("ERROR"), StringConstants.COMPLEX_TEST_STRING)) self.uut.log_level = LOG_LEVEL.WARNING self.assertEqual( str(self.uut), "[{}] {}".format(_("WARNING"), StringConstants.COMPLEX_TEST_STRING)) self.uut.log_level = LOG_LEVEL.DEBUG self.assertEqual( str(self.uut), "[{}] {}".format(_("DEBUG"), StringConstants.COMPLEX_TEST_STRING)) self.uut.log_level = 5 self.assertEqual( str(self.uut), "[{}] {}".format(_("ERROR"), StringConstants.COMPLEX_TEST_STRING))
def _get_param(param, section, annotation, log_printer): if annotation is None: annotation = lambda x: x try: return annotation(section[param]) except: log_printer.warn( _("Unable to convert {param} to the desired " "data type.").format(param=param)) return section[param]
def run(self, filename, file, *args): """ Counts the lines of each file. """ return [ Result(origin=self, message=_("This file has {count} lines.").format( count=len(file)), severity=RESULT_SEVERITY.INFO, file=filename) ]
def _print_actions(self, actions): self.print( self._format_line( _("The following options are applicable to this result:"))) choice = self._choose_action(actions) if choice == 0: return None, None return self._get_action_info(actions[choice - 1])
def _run_bear(self, bear_instance, *args, **kwargs): if kwargs.get("dependency_results", True) is None: del kwargs["dependency_results"] name = bear_instance.__class__.__name__ try: result_list = bear_instance.execute(*args, **kwargs) except: self.err( _("The bear {bear} failed to run with the arguments " "{arglist}, {kwarglist}. Skipping bear...").format( bear=name, arglist=args, kwarglist=kwargs)) self.debug( _("Traceback for error in bear {bear}:").format(bear=name), traceback.format_exc(), delimiter="\n") return None return self._validate_results(result_list, name, args, kwargs)
def __run_global_bear(self, global_bear_instance, dependency_results): if not isinstance(global_bear_instance, GlobalBear) \ or global_bear_instance.kind() != BEAR_KIND.GLOBAL: self.warn( _("A given global bear ({}) is not valid. " "Leaving it out...").format( global_bear_instance.__class__.__name__), StringConstants.THIS_IS_A_BUG) return None kwargs = {"dependency_results": dependency_results} return self._run_bear(global_bear_instance, **kwargs)
def test_logging(self): uut = TestLogPrinter(timestamp_format="") self.assertEqual((str(self.log_message), "special"), uut.log_message(self.log_message, end="", special_arg="special")) uut = TestLogPrinter(log_level=LOG_LEVEL.DEBUG) ts = datetime.today() self.assertEqual(("[" + _("ERROR") + "][" + ts.strftime("%X") + "] " + StringConstants.COMPLEX_TEST_STRING, "test"), uut.log_message(self.log_message, timestamp=ts, end="")) self.assertEqual(("[" + _("ERROR") + "][" + ts.strftime("%X") + "] " + StringConstants.COMPLEX_TEST_STRING, "test"), uut.log(LOG_LEVEL.ERROR, StringConstants.COMPLEX_TEST_STRING, timestamp=ts, end="")) self.assertEqual(("[" + _("DEBUG") + "][" + ts.strftime("%X") + "] " + StringConstants.COMPLEX_TEST_STRING, "test"), uut.debug(StringConstants.COMPLEX_TEST_STRING, timestamp=ts, end="")) uut.log_level = LOG_LEVEL.WARNING self.assertEqual( None, uut.debug(StringConstants.COMPLEX_TEST_STRING, timestamp=ts, end="")) self.assertEqual(("[" + _("WARNING") + "][" + ts.strftime("%X") + "] " + StringConstants.COMPLEX_TEST_STRING, "test"), uut.warn(StringConstants.COMPLEX_TEST_STRING, timestamp=ts, end="")) self.assertEqual(("[" + _("ERROR") + "][" + ts.strftime("%X") + "] " + StringConstants.COMPLEX_TEST_STRING, "test"), uut.err(StringConstants.COMPLEX_TEST_STRING, timestamp=ts, end="")) logged = uut.log_exception("Something failed.", NotImplementedError( StringConstants.COMPLEX_TEST_STRING), timestamp=ts, end="") self.assertTrue( logged[0].startswith("[" + _("ERROR") + "][" + ts.strftime("%X") + "] Something failed.\n\n" + _("Exception was:") + "\n"))