示例#1
0
    def _cache_file(self, src_path):
        """
        Load the data from `self._xml_roots`
        for `src_path`, if it hasn't been already.
        """
        # If we have not yet loaded this source file
        if src_path not in self._info_cache:
            # We only want to keep violations that show up in each xml source.
            # Thus, each time, we take the intersection.  However, to do this
            # we must treat the first time as a special case and just add all
            # the violations from the first xml report.
            violations = None

            # A line is measured if it is measured in any of the reports, so
            # we take set union each time and can just start with the empty set
            measured = set()

            # Loop through the files that contain the xml roots
            for xml_document in self._xml_roots:
                line_nodes = self._get_src_path_line_nodes(xml_document,
                                                           src_path)

                if line_nodes is None:
                    continue

                # First case, need to define violations initially
                if violations is None:
                    violations = set(
                        Violation(int(line.get('number')), None)
                        for line in line_nodes
                        if int(line.get('hits', 0)) == 0)

                # If we already have a violations set,
                # take the intersection of the new
                # violations set and its old self
                else:
                    violations = violations & set(
                        Violation(int(line.get('number')), None)
                        for line in line_nodes
                        if int(line.get('hits', 0)) == 0
                    )

                # Measured is the union of itself and the new measured
                measured = measured | set(
                    int(line.get('number')) for line in line_nodes
                )

            # If we don't have any information about the source file,
            # don't report any violations
            if violations is None:
                violations = set()

            self._info_cache[src_path] = (violations, measured)
示例#2
0
    def parse_reports(self, reports):
        """
        Args:
            reports: list[str] - output from the report
        Return:
            A dict[Str:Violation]
            Violation is a simple named tuple Defined above
        """
        violations_dict = defaultdict(list)
        for report in reports:
            xml_document = etree.fromstring("".join(report))
            bugs = xml_document.findall(".//BugInstance")
            for bug in bugs:
                category = bug.get('category')
                short_message = bug.find('ShortMessage').text
                line = bug.find('SourceLine')
                if line.get('start') is None or line.get('end') is None:
                    continue
                start = int(line.get('start'))
                end = int(line.get('end'))
                for line_number in range(start, end + 1):
                    error_str = "{}: {}".format(category, short_message)
                    violation = Violation(line_number, error_str)
                    filename = GitPathTool.relative_path(
                        line.get('sourcepath'))
                    violations_dict[filename].append(violation)

        return violations_dict
示例#3
0
    def parse_reports(self, reports):
        """
        Args:
            reports: list[str] - output from the report
        Return:
            A dict[Str:Violation]
            Violation is a simple named tuple Defined above
        """
        violations_dict = defaultdict(list)
        for report in reports:
            output_lines = report.splitlines()

            for line in output_lines:
                match = self.cppcheck_expression.match(line)

                # Ignore any line that isn't matched
                # (for example, snippets from the source code)
                if match is not None:

                    (cppcheck_src_path, line_number, message) = match.groups()

                    violation = Violation(int(line_number), message)
                    violations_dict[cppcheck_src_path].append(violation)

        return violations_dict
    def parse_reports(self, reports):
        """
        Args:
            reports: list[str] - output from the report
        Return:
            A dict[Str:Violation]
            Violation is a simple named tuple Defined above
        """
        violations_dict = defaultdict(list)
        for report in reports:
            output_lines = report.split("\n")

            for output_line_number, line in enumerate(output_lines):
                match = self.pylint_expression.match(line)

                # Ignore any line that isn't matched
                # (for example, snippets from the source code)
                if match is not None:

                    (
                        pylint_src_path,
                        line_number,
                        pylint_code,
                        function_name,
                        message,
                    ) = match.groups()
                    if pylint_code == self.dupe_code_violation:
                        files_involved = self._process_dupe_code_violation(
                            output_lines, output_line_number, message
                        )
                    else:
                        files_involved = [(pylint_src_path, line_number)]

                    for violation in files_involved:
                        pylint_src_path, line_number = violation
                        # If we're looking for a particular source file,
                        # ignore any other source files.
                        if function_name:
                            error_str = "{}: {}: {}".format(
                                pylint_code, function_name, message
                            )
                        else:
                            error_str = f"{pylint_code}: {message}"

                        violation = Violation(int(line_number), error_str)
                        violations_dict[pylint_src_path].append(violation)

        return violations_dict
示例#5
0
    def violations(src_path: str) -> List[Violation]:
        """Return list of violations.

        Given the path to a .sql file, analyze it and return a list of
        violations (i.e. formatting or style issues).
        """
        linter = Linter(config=FluffConfig.from_root())
        linted_path = linter.lint_path(src_path,
                                       ignore_non_existent_files=True)
        result = []
        for violation in linted_path.get_violations():
            try:
                # Normal SQLFluff warnings
                message = f"{violation.rule_code()}: {violation.description}"
            except AttributeError:
                # Parse errors
                message = str(violation)
            result.append(Violation(violation.line_no, message))
        return result
示例#6
0
 def parse_reports(self, reports):
     """
     Args:
         reports: list[str] - output from the report
     Return:
         A dict[Str:Violation]
         Violation is a simple named tuple Defined above
     """
     violations_dict = defaultdict(list)
     for report in reports:
         xml_document = etree.fromstring("".join(report))
         files = xml_document.findall(".//file")
         for file_tree in files:
             for error in file_tree.findall('error'):
                 line_number = error.get('line')
                 error_str = "{}: {}".format(error.get('severity'),
                                             error.get('message'))
                 violation = Violation(int(line_number), error_str)
                 filename = GitPathTool.relative_path(file_tree.get('name'))
                 violations_dict[filename].append(violation)
     return violations_dict
示例#7
0
    def violations(src_path):
        """Return list of violations.

        Given the path to a .sql file, analyze it and return a list of
        violations (i.e. formatting or style issues).

        :param src_path:
        :return: list of Violation
        """
        linter = Linter(config=FluffConfig())
        linted_path = linter.lint_path(src_path,
                                       ignore_non_existent_files=True)
        result = []
        for violation in linted_path.get_violations():
            try:
                # Normal SQLFluff warnings
                message = violation.description
            except AttributeError:
                # Parse errors
                message = str(violation)
            result.append(Violation(violation.line_no(), message))
        return result
    def parse_reports(self, reports):
        """
        Args:
            reports: list[str] - output from the report
        Return:
            A dict[Str:Violation]
            Violation is a simple named tuple Defined above
        """
        violations_dict = defaultdict(list)
        for report in reports:
            xml_document = etree.fromstring("".join(report))
            node_files = xml_document.findall(".//file")
            for node_file in node_files:
                for error in node_file.findall("violation"):
                    line_number = error.get("beginline")
                    error_str = "{}: {}".format(error.get("rule"), error.text.strip())
                    violation = Violation(int(line_number), error_str)
                    filename = GitPathTool.relative_path(node_file.get("name"))
                    filename = filename.replace(os.sep, "/")
                    violations_dict[filename].append(violation)

        return violations_dict
    def violations(self, src_path):
        """Return list of violations.

        Given the path to a .sql file, analyze it and return a list of
        violations (i.e. formatting or style issues).

        :param src_path:
        :return: list of Violation
        """
        linter = get_linter(get_config())
        linter.output_func = None
        linted_path = linter.lint_path(src_path)
        result = []
        for violation in linted_path.files[0].violations:
            try:
                # Normal SQLFluff warnings
                message = violation.description
            except AttributeError:
                # Parse errors
                message = str(violation)
            result.append(Violation(violation.line_no(), message))
        return result
示例#10
0
    def _cache_file(self, src_path):
        """
        Load the data from `self._xml_roots`
        for `src_path`, if it hasn't been already.
        """
        # If we have not yet loaded this source file
        if src_path not in self._info_cache:
            # We only want to keep violations that show up in each xml source.
            # Thus, each time, we take the intersection.  However, to do this
            # we must treat the first time as a special case and just add all
            # the violations from the first xml report.
            violations = None

            # A line is measured if it is measured in any of the reports, so
            # we take set union each time and can just start with the empty set
            measured = set()

            # Loop through the files that contain the xml roots
            for xml_document in self._xml_roots:
                if xml_document.findall(".[@clover]"):
                    # see etc/schema/clover.xsd at  https://bitbucket.org/atlassian/clover/src
                    line_nodes = self._get_src_path_line_nodes_clover(
                        xml_document, src_path)
                    _number = "num"
                    _hits = "count"
                elif xml_document.findall(".[@name]"):
                    # https://github.com/jacoco/jacoco/blob/master/org.jacoco.report/src/org/jacoco/report/xml/report.dtd
                    line_nodes = self._get_src_path_line_nodes_jacoco(
                        xml_document, src_path)
                    _number = "nr"
                    _hits = "ci"
                else:
                    # https://github.com/cobertura/web/blob/master/htdocs/xml/coverage-04.dtd
                    line_nodes = self._get_src_path_line_nodes_cobertura(
                        xml_document, src_path)
                    _number = "number"
                    _hits = "hits"
                if line_nodes is None:
                    continue

                # First case, need to define violations initially
                if violations is None:
                    violations = {
                        Violation(int(line.get(_number)), None)
                        for line in line_nodes if int(line.get(_hits, 0)) == 0
                    }

                # If we already have a violations set,
                # take the intersection of the new
                # violations set and its old self
                else:
                    violations = violations & {
                        Violation(int(line.get(_number)), None)
                        for line in line_nodes if int(line.get(_hits, 0)) == 0
                    }

                # Measured is the union of itself and the new measured
                measured = measured | {
                    int(line.get(_number))
                    for line in line_nodes
                }

            # If we don't have any information about the source file,
            # don't report any violations
            if violations is None:
                violations = set()

            self._info_cache[src_path] = (violations, measured)