diff --git a/tests/patch/kdoc/test.py b/tests/patch/kdoc/test.py index e6d3216..e00307e 100644 --- a/tests/patch/kdoc/test.py +++ b/tests/patch/kdoc/test.py @@ -30,7 +30,8 @@ class KdocWarning: # Note: *not* part of comparison, or hash! line : Optional[int] = dataclasses.field(repr=True, compare=False) # The content of the warning (excluding kind, file, line) - content : str = dataclasses.field(repr=True, compare=True) + content : Optional[str] = dataclasses.field(repr=True, compare=True) + parsed : bool = dataclasses.field(repr=True, compare=True) @classmethod def from_text(self, line, extra=None): @@ -60,14 +61,35 @@ def from_text(self, line, extra=None): content = m['content'] if extra: content += '\n' + extra - else: - kind = 'Unknown' - file = None - line = None - content = message - return KdocWarning(message, kind=kind, file=file, line=line, - content=content) + return KdocWarning(message, kind=kind, file=file, line=line, + content=content, parsed=True) + + # Check for line-number only warnings produced by certain buggy + # versions of kernel-doc. These will get treated as unparsed but + # all such warnings will compare identically to each other. + line_only_parser = re.compile( + r""" + ^ # Start of string + (?Pwarning|error): # Severity + \s+ # Spacing + (?P[0-9]+) # Line number + $ # End of string + """, + re.VERBOSE | re.IGNORECASE) + + m = line_only_parser.match(line) + if m: + kind = m['kind'] + line = m['line'] + + return KdocWarning(message, kind=kind, file=None, line=line, + content=None, parsed=False) + + # The warning text didn't match a known format. Such warnings will be + # counted to ensure that we don't increase this count over time. + return KdocWarning(message, kind='Unknown', file=None, line=None, + content=line, parsed=False) def __str__(self): return self.message @@ -80,20 +102,28 @@ def parse_warnings(lines, logs) -> List[KdocWarning]: # Walk through lines and convert to warning objects for i, line in enumerate(lines): + # Skip lines already merged into previous warning if skip: skip = False continue + # Ignore blank lines + if not line.strip(): + continue + + # Check if we should merge the next line with this warning + extra = None if line.endswith(':') and i + 1 < length: extra = lines[i + 1] skip = True - elif not line.strip(): - continue - else: - logs += [": " + line.strip()] - extra = None - warnings.append(KdocWarning.from_text(line, extra)) + # Parse line into warning object + warning = KdocWarning.from_text(line, extra); + + if not warning.parsed: + logs += [f': {line.strip()}'] + + warnings.append(warning) return warnings @@ -181,6 +211,10 @@ def kdoc(tree, patch, _result_dir) -> Tuple[int, str, str]: new_count = len(new_warnings) rm_count = len(rm_warnings) + # Count the number of warnings which we failed to parse + current_unparsed = len([x for x in current_warnings if not x.parsed]) + incumbent_unparsed = len([x for x in incumbent_warnings if not x.parsed]) + desc = f'Warnings before: {incumbent_count} after: {current_count}' brac = [] if new_count: @@ -213,4 +247,8 @@ def kdoc(tree, patch, _result_dir) -> Tuple[int, str, str]: for f, count in file_breakdown.items(): log += [f'{count:6} {f}'] + if current_unparsed > incumbent_unparsed: + ret = 1 + log += ["", f'Number of parse failures increased from {incumbent_unparsed} to {current_unparsed}.'] + return ret, desc, "\n".join(log)