Beispiel #1
0
    def __init__(
            self,
            log_printer: LogPrinter,
            project_dir: str,
            flush_cache: bool=False):
        """
        Initialize FileCache.

        :param log_printer: A LogPrinter object to use for logging.
        :param project_dir: The root directory of the project to be used
                            as a key identifier.
        :param flush_cache: Flush the cache and rebuild it.
        """
        self.log_printer = log_printer
        self.project_dir = project_dir
        self.current_time = int(time.time())

        cache_data = pickle_load(log_printer, project_dir, {})
        last_time = -1
        if "time" in cache_data:
            last_time = cache_data["time"]
        if not flush_cache and last_time > self.current_time:
            log_printer.warn("It seems like you went back in time - your "
                             "system time is behind the last recorded run "
                             "time on this project. The cache will "
                             "be force flushed.")
            flush_cache = True

        self.data = cache_data.get("files", {})
        if flush_cache:
            self.flush_cache()
Beispiel #2
0
    def __init__(self,
                 log_printer: LogPrinter,
                 project_dir: str,
                 flush_cache: bool = False):
        """
        Initialize FileCache.

        :param log_printer: A LogPrinter object to use for logging.
        :param project_dir: The root directory of the project to be used
                            as a key identifier.
        :param flush_cache: Flush the cache and rebuild it.
        """
        self.log_printer = log_printer
        self.project_dir = project_dir
        self.current_time = int(time.time())

        cache_data = pickle_load(log_printer, project_dir, {})
        last_time = -1
        if "time" in cache_data:
            last_time = cache_data["time"]
        if not flush_cache and last_time > self.current_time:
            log_printer.warn("It seems like you went back in time - your "
                             "system time is behind the last recorded run "
                             "time on this project. The cache will "
                             "be force flushed.")
            flush_cache = True

        self.data = cache_data.get("files", {})
        if flush_cache:
            self.flush_cache()
Beispiel #3
0
    def test_logging(self):
        uut = LogPrinter(StringPrinter(), timestamp_format="")
        uut.log_message(self.log_message, end="")
        self.assertEqual(uut.printer.string, str(self.log_message))

        uut = LogPrinter(StringPrinter(), log_level=LOG_LEVEL.DEBUG)
        uut.log_message(self.log_message, end="")
        self.assertEqual(
            uut.printer.string,
            "[ERROR][" + self.timestamp.strftime("%X") + "] " +
            Constants.COMPLEX_TEST_STRING)

        uut.printer.clear()
        uut.log(LOG_LEVEL.ERROR,
                Constants.COMPLEX_TEST_STRING,
                timestamp=self.timestamp,
                end="")
        self.assertEqual(
            uut.printer.string,
            "[ERROR][" + self.timestamp.strftime("%X") + "] " +
            Constants.COMPLEX_TEST_STRING)

        uut.printer.clear()
        uut.debug(Constants.COMPLEX_TEST_STRING,
                  "d",
                  timestamp=self.timestamp,
                  end="")
        self.assertEqual(
            uut.printer.string,
            "[DEBUG][" + self.timestamp.strftime("%X") + "] " +
            Constants.COMPLEX_TEST_STRING + " d")

        uut.printer.clear()
        uut.log_level = LOG_LEVEL.INFO
        uut.debug(Constants.COMPLEX_TEST_STRING,
                  timestamp=self.timestamp,
                  end="")
        self.assertEqual(uut.printer.string, "")

        uut.printer.clear()
        uut.info(Constants.COMPLEX_TEST_STRING,
                 "d",
                 timestamp=self.timestamp,
                 end="")
        self.assertEqual(
            uut.printer.string,
            "[INFO][" + self.timestamp.strftime("%X") + "] " +
            Constants.COMPLEX_TEST_STRING + " d")

        uut.log_level = LOG_LEVEL.WARNING
        uut.printer.clear()
        uut.debug(Constants.COMPLEX_TEST_STRING,
                  timestamp=self.timestamp,
                  end="")
        self.assertEqual(uut.printer.string, "")

        uut.printer.clear()
        uut.warn(Constants.COMPLEX_TEST_STRING,
                 "d",
                 timestamp=self.timestamp,
                 end="")
        self.assertEqual(
            uut.printer.string,
            "[WARNING][" + self.timestamp.strftime("%X") + "] " +
            Constants.COMPLEX_TEST_STRING + " d")

        uut.printer.clear()
        uut.err(Constants.COMPLEX_TEST_STRING,
                "d",
                timestamp=self.timestamp,
                end="")
        self.assertEqual(
            uut.printer.string,
            "[ERROR][" + self.timestamp.strftime("%X") + "] " +
            Constants.COMPLEX_TEST_STRING + " d")

        uut.log_level = LOG_LEVEL.DEBUG
        uut.printer.clear()
        uut.log_exception(
            "Something failed.",
            NotImplementedError(Constants.COMPLEX_TEST_STRING),
            timestamp=self.timestamp)
        self.assertTrue(uut.printer.string.startswith(
            "[ERROR][" + self.timestamp.strftime("%X") +
            "] Something failed.\n" +
            "[DEBUG][" + self.timestamp.strftime("%X") +
            "] Exception was:"))

        uut.log_level = LOG_LEVEL.INFO
        uut.printer.clear()
        logged = uut.log_exception(
            "Something failed.",
            NotImplementedError(Constants.COMPLEX_TEST_STRING),
            timestamp=self.timestamp,
            end="")
        self.assertTrue(uut.printer.string.startswith(
            "[ERROR][" + self.timestamp.strftime("%X") +
            "] Something failed."))
Beispiel #4
0
    def test_logging(self):
        uut = LogPrinter(StringPrinter(), timestamp_format="")
        uut.log_message(self.log_message, end="")
        self.assertEqual(uut.printer.string, str(self.log_message))

        uut = LogPrinter(StringPrinter(), log_level=LOG_LEVEL.DEBUG)
        uut.log_message(self.log_message, end="")
        self.assertEqual(
            uut.printer.string,
            "[ERROR][" + self.timestamp.strftime("%X") + "] " +
            Constants.COMPLEX_TEST_STRING)

        uut.printer.clear()
        uut.log(LOG_LEVEL.ERROR,
                Constants.COMPLEX_TEST_STRING,
                timestamp=self.timestamp,
                end="")
        self.assertEqual(
            uut.printer.string,
            "[ERROR][" + self.timestamp.strftime("%X") + "] " +
            Constants.COMPLEX_TEST_STRING)

        uut.printer.clear()
        uut.debug(Constants.COMPLEX_TEST_STRING,
                  "d",
                  timestamp=self.timestamp,
                  end="")
        self.assertEqual(
            uut.printer.string,
            "[DEBUG][" + self.timestamp.strftime("%X") + "] " +
            Constants.COMPLEX_TEST_STRING + " d")

        uut.printer.clear()
        uut.log_level = LOG_LEVEL.INFO
        uut.debug(Constants.COMPLEX_TEST_STRING,
                  timestamp=self.timestamp,
                  end="")
        self.assertEqual(uut.printer.string, "")

        uut.printer.clear()
        uut.info(Constants.COMPLEX_TEST_STRING,
                 "d",
                 timestamp=self.timestamp,
                 end="")
        self.assertEqual(
            uut.printer.string,
            "[INFO][" + self.timestamp.strftime("%X") + "] " +
            Constants.COMPLEX_TEST_STRING + " d")

        uut.log_level = LOG_LEVEL.WARNING
        uut.printer.clear()
        uut.debug(Constants.COMPLEX_TEST_STRING,
                  timestamp=self.timestamp,
                  end="")
        self.assertEqual(uut.printer.string, "")

        uut.printer.clear()
        uut.warn(Constants.COMPLEX_TEST_STRING,
                 "d",
                 timestamp=self.timestamp,
                 end="")
        self.assertEqual(
            uut.printer.string,
            "[WARNING][" + self.timestamp.strftime("%X") + "] " +
            Constants.COMPLEX_TEST_STRING + " d")

        uut.printer.clear()
        uut.err(Constants.COMPLEX_TEST_STRING,
                "d",
                timestamp=self.timestamp,
                end="")
        self.assertEqual(
            uut.printer.string,
            "[ERROR][" + self.timestamp.strftime("%X") + "] " +
            Constants.COMPLEX_TEST_STRING + " d")

        uut.log_level = LOG_LEVEL.DEBUG
        uut.printer.clear()
        uut.log_exception(
            "Something failed.",
            NotImplementedError(Constants.COMPLEX_TEST_STRING),
            timestamp=self.timestamp)
        self.assertTrue(uut.printer.string.startswith(
            "[ERROR][" + self.timestamp.strftime("%X") +
            "] Something failed.\n" +
            "[DEBUG][" + self.timestamp.strftime("%X") +
            "] Exception was:"))

        uut.log_level = LOG_LEVEL.INFO
        uut.printer.clear()
        logged = uut.log_exception(
            "Something failed.",
            NotImplementedError(Constants.COMPLEX_TEST_STRING),
            timestamp=self.timestamp,
            end="")
        self.assertTrue(uut.printer.string.startswith(
            "[ERROR][" + self.timestamp.strftime("%X") +
            "] Something failed."))
Beispiel #5
0
def main(debug=False):
    configure_logging()

    args = None  # to have args variable in except block when parse_args fails
    try:
        console_printer = ConsolePrinter()
        log_printer = LogPrinter(console_printer)
        # Note: We parse the args here once to check whether to show bears or
        # not.
        args = default_arg_parser().parse_args()
        if args.debug:
            req_ipdb = PipRequirement('ipdb')
            if not req_ipdb.is_installed():
                logging.error(
                    '--debug flag requires ipdb. '
                    'You can install it with:\n%s',
                    ' '.join(req_ipdb.install_command()))
                sys.exit(13)

        if debug or args.debug:
            args.log_level = 'DEBUG'

        # Defer imports so if e.g. --help is called they won't be run
        from coalib.coala_modes import (mode_format, mode_json,
                                        mode_non_interactive, mode_normal)
        from coalib.output.ConsoleInteraction import (
            show_bears, show_language_bears_capabilities)

        console_printer = ConsolePrinter(print_colored=not args.no_color)
        configure_logging(not args.no_color)

        if args.json:  # needs to be checked in order to display bears in json
            return mode_json(args, debug=debug)

        if args.show_bears:
            from coalib.settings.ConfigurationGathering import (get_all_bears)
            filtered_bears = get_all_bears(log_printer)
            if args.filter_by_language:
                log_printer.warn("'--filter-by-language ...' is deprecated. "
                                 "Use '--filter-by language ...' instead.")
                if args.filter_by is None:
                    args.filter_by = []
                args.filter_by.append(['language'] + args.filter_by_language)
            if args.filter_by:
                # Each iteration of the following loop applies
                # filters one by one provided as arguments
                for filter_by in args.filter_by:
                    filter_by_x, *filter_args = filter_by
                    try:
                        filtered_bears = FilterHelper.get_filtered_bears(
                            filter_by_x, filter_args, filtered_bears)
                    except InvalidFilterException as ex:
                        # If filter is not available
                        console_printer.print(ex)
                        return 2

            local_bears, global_bears = filtered_bears
            show_bears(local_bears, global_bears, args.show_description
                       or args.show_details, args.show_details,
                       console_printer)

            return 0
        elif args.show_capabilities:
            from coalib.collecting.Collectors import (
                filter_capabilities_by_languages)
            local_bears, _ = FilterHelper.get_filtered_bears(
                'language', args.show_capabilities)
            capabilities = filter_capabilities_by_languages(
                local_bears, args.show_capabilities)
            show_language_bears_capabilities(capabilities, console_printer)

            return 0

    except BaseException as exception:  # pylint: disable=broad-except
        if not isinstance(exception, SystemExit):
            if args and args.debug:
                import ipdb
                with ipdb.launch_ipdb_on_exception():
                    raise

            if debug:
                raise

        return get_exitcode(exception, log_printer)

    if args.format:
        return mode_format(args, debug=debug)

    if args.non_interactive:
        return mode_non_interactive(console_printer, args, debug=debug)

    return mode_normal(console_printer, log_printer, args, debug=debug)
class CoalaViewActivatable(GObject.Object, Gedit.ViewActivatable):
    """
    A class inherited from Gedit.ViewActivatable - it gets created for every
    gedit view. This class has a property `view` which is the Gedit.View that
    the class is related to. From the Gedit.View, the Gedit.Document associated
    to it can be got using `view.get_buffer()`.
    """
    __gtype_name__ = "CoalaViewActivatable"

    view = GObject.Property(type=Gedit.View)

    def __init__(self):
        GObject.Object.__init__(self)
        self.log_printer = LogPrinter(ConsolePrinter())

    def do_activate(self):
        """
        This function is called when the view is created - it will
        be called only once in a lifetime of a view.
        """
        self.register_marks()
        self.view.get_buffer().connect("saved", lambda x: self.analyze())

    def register_marks(self):
        """
        Creates mark-attributes for all result severities.
        """
        self.view.set_show_line_marks(True)
        for name, val in RESULT_SEVERITY.str_dict.items():
            attr = GtkSource.MarkAttributes()
            attr.set_icon_name(RESULT_SEVERITY_ICONS[val])
            attr.connect("query_tooltip_markup", self.show_mark_tooltip)
            self.view.set_mark_attributes(get_mark_category(name), attr, 0)
            self.log_printer.info("Mark attribute created for", name)

    def show_mark_tooltip(self, mark_attr, mark):
        result = getattr(mark, COALA_KEY + "Result")
        return str(result.origin) + ": " + str(result.message)

    def show_result(self, result):
        """
        Takes a result and shows it in gedit's UI.

        :param result: The result to display.
        """
        document = self.view.get_buffer()

        for sourcerange in result.affected_code:

            _iter = document.get_iter_at_line(sourcerange.start.line-1)
            mark = document.create_source_mark(
                None,
                get_mark_category(result.severity),
                _iter)
            setattr(mark, COALA_KEY + "Result", result)
            self.log_printer.info("Created mark at", sourcerange.start.line)

    def analyze(self):
        """
        This function fetches the location of the file in this view
        and runs coala on it.
        """
        document = self.view.get_buffer()
        location = document.get_location()
        if location == None:
            self.log_printer.warn("coala cannot run on unsaved files")
            return

        results = CoalaViewActivatable.run_coala(location.get_path())

        document.remove_source_marks(document.get_start_iter(),
                                     document.get_end_iter())
        for section_results in results.values():
            for result in section_results:
                self.show_result(result)

    @staticmethod
    def run_coala(path):
        """
        Run coala on the file at the given path. The config file is got using
        the `find-config` option of coala.

        :param path: The path of the file to analyze.
        :return:     The result dictionary from coala.
        """
        results = {}
        log_printer = LogPrinter(ConsolePrinter())
        cwd = os.getcwd()
        try:
            os.chdir(os.path.dirname(path))
            args = ["--find-config", "--limit-files", path, '-S',
                    'autoapply=false']
            sections, local_bears, global_bears, targets = (
                # Use `lambda *args: True` so that `gather_configuration` does
                # nothing when it needs to request settings from user.
                gather_configuration(lambda *args: True,
                                     log_printer,
                                     arg_list=args))

            for section_name in sections:
                section = sections[section_name]
                if not section.is_enabled(targets):
                    continue

                section_result = execute_section(
                    section=section,
                    global_bear_list=global_bears[section_name],
                    local_bear_list=local_bears[section_name],
                    print_results=lambda *args: True,
                    log_printer=log_printer)

                results_for_section = []
                for i in 1, 2:
                    for value in section_result[i].values():
                        for result in value:
                            if isinstance(result, HiddenResult):
                                continue
                            results_for_section.append(result)
                results[section_name] = results_for_section
        except BaseException as exception:
            log_printer.log_exception(str(exception), exception)
        finally:
            os.chdir(cwd)

        return results
class CoalaViewActivatable(GObject.Object, Gedit.ViewActivatable):
    """
    A class inherited from Gedit.ViewActivatable - it gets created for every
    gedit view. This class has a property `view` which is the Gedit.View that
    the class is related to. From the Gedit.View, the Gedit.Document associated
    to it can be got using `view.get_buffer()`.
    """
    __gtype_name__ = "CoalaViewActivatable"

    view = GObject.Property(type=Gedit.View)

    def __init__(self):
        GObject.Object.__init__(self)
        self.log_printer = LogPrinter(ConsolePrinter())

    def do_activate(self):
        """
        This function is called when the view is created - it will
        be called only once in a lifetime of a view.
        """
        self.register_marks()
        self.view.get_buffer().connect("saved", lambda x: self.analyze())

    def register_marks(self):
        """
        Creates mark-attributes for all result severities.
        """
        self.view.set_show_line_marks(True)
        for name, val in RESULT_SEVERITY.str_dict.items():
            attr = GtkSource.MarkAttributes()
            attr.set_icon_name(RESULT_SEVERITY_ICONS[val])
            attr.connect("query_tooltip_markup", self.show_mark_tooltip)
            self.view.set_mark_attributes(get_mark_category(name), attr, 0)
            self.log_printer.info("Mark attribute created for", name)

    def show_mark_tooltip(self, mark_attr, mark):
        result = getattr(mark, COALA_KEY + "Result")
        return str(result.origin) + ": " + str(result.message)

    def show_result(self, result):
        """
        Takes a result and shows it in gedit's UI.

        :param result: The result to display.
        """
        document = self.view.get_buffer()

        for sourcerange in result.affected_code:

            _iter = document.get_iter_at_line(sourcerange.start.line - 1)
            mark = document.create_source_mark(
                None, get_mark_category(result.severity), _iter)
            setattr(mark, COALA_KEY + "Result", result)
            self.log_printer.info("Created mark at", sourcerange.start.line)

    def analyze(self):
        """
        This function fetches the location of the file in this view
        and runs coala on it.
        """
        document = self.view.get_buffer()
        location = document.get_location()
        if location == None:
            self.log_printer.warn("coala cannot run on unsaved files")
            return

        results = CoalaViewActivatable.run_coala(location.get_path())

        document.remove_source_marks(document.get_start_iter(),
                                     document.get_end_iter())
        for section_results in results.values():
            for result in section_results:
                self.show_result(result)

    @staticmethod
    def run_coala(path):
        """
        Run coala on the file at the given path. The config file is got using
        the `find-config` option of coala.

        :param path: The path of the file to analyze.
        :return:     The result dictionary from coala.
        """
        results = {}
        log_printer = LogPrinter(ConsolePrinter())
        cwd = os.getcwd()
        try:
            os.chdir(os.path.dirname(path))
            args = [
                "--find-config", "--limit-files", path, '-S', 'autoapply=false'
            ]
            sections, local_bears, global_bears, targets = (
                # Use `lambda *args: True` so that `gather_configuration` does
                # nothing when it needs to request settings from user.
                gather_configuration(lambda *args: True,
                                     log_printer,
                                     arg_list=args))

            for section_name in sections:
                section = sections[section_name]
                if not section.is_enabled(targets):
                    continue

                section_result = execute_section(
                    section=section,
                    global_bear_list=global_bears[section_name],
                    local_bear_list=local_bears[section_name],
                    print_results=lambda *args: True,
                    log_printer=log_printer)

                results_for_section = []
                for i in 1, 2:
                    for value in section_result[i].values():
                        for result in value:
                            if isinstance(result, HiddenResult):
                                continue
                            results_for_section.append(result)
                results[section_name] = results_for_section
        except BaseException as exception:
            log_printer.log_exception(str(exception), exception)
        finally:
            os.chdir(cwd)

        return results