1# Copyright 2022 The Pigweed Authors 2# 3# Licensed under the Apache License, Version 2.0 (the "License"); you may not 4# use this file except in compliance with the License. You may obtain a copy of 5# the License at 6# 7# https://www.apache.org/licenses/LICENSE-2.0 8# 9# Unless required by applicable law or agreed to in writing, software 10# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 11# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 12# License for the specific language governing permissions and limitations under 13# the License. 14"""Extracts a concise error from a bazel log.""" 15 16from pathlib import Path 17import re 18import sys 19 20 21def parse_bazel_stdout(bazel_stdout: Path) -> str: 22 """Extracts a concise error from a bazel log.""" 23 seen_error: bool = False 24 error_lines: list[str] = [] 25 26 with bazel_stdout.open() as ins: 27 for line in ins: 28 # Trailing whitespace isn't significant, as it doesn't affect the 29 # way the line shows up in the logs. However, leading whitespace may 30 # be significant, especially for compiler error messages. 31 line = line.rstrip() 32 33 if re.match(r'^(ERROR|FAIL):', line): 34 seen_error = True 35 36 if seen_error: 37 # Ignore long lines that just show the environment. 38 if re.search(r' +[\w_]*(PATH|PWD)=.* \\', line): 39 continue 40 41 # Ignore lines that only show bazel sandboxing. 42 if line.strip().startswith(('(cd /', 'exec env')): 43 continue 44 45 if line.strip().startswith('Use --sandbox_debug to see'): 46 continue 47 48 if line.strip().startswith('# Configuration'): 49 continue 50 51 # Ignore passing and skipped tests. 52 if 'PASSED' in line or 'SKIPPED' in line: 53 continue 54 55 # Ignore intermixed lines from other build steps. 56 if re.match(r'\[\s*[\d,]+\s*/\s*[\d,]+\s*\]', line): 57 continue 58 59 if re.match(r'Executed \d+ out of \d+ tests', line): 60 error_lines.append(line) 61 break 62 63 line = re.sub( 64 r'/b/s/w/ir/\S*/bazel-out(/k8-fastbuild)?(/bin)?' 65 r'(/testlogs?)', 66 '<truncated>', 67 line, 68 ) 69 70 error_lines.append(line) 71 72 result = '\n'.join(error_lines) 73 return re.sub(r'\n+', '\n', result) 74 75 76if __name__ == '__main__': 77 print(parse_bazel_stdout(Path(sys.argv[1]))) 78