|
1 | 1 | """Compile all projects, used by `make test`."""
|
2 | 2 |
|
| 3 | +from collections.abc import Generator |
3 | 4 | from dataclasses import dataclass
|
4 | 5 | from os import environ
|
5 | 6 | from pathlib import Path
|
|
20 | 21 |
|
21 | 22 |
|
22 | 23 | def log(message: str | Any) -> None:
|
23 |
| - """Write to stdout and the SUMMARY file.""" |
| 24 | + """Write markdown `message` to stdout and the SUMMARY file.""" |
24 | 25 | if not isinstance(message, str):
|
25 | 26 | message = str(message)
|
26 | 27 |
|
27 |
| - print(message) |
| 28 | + print(message, end="\n\n") |
28 | 29 | with SUMMARY.open("a", encoding="utf-8") as f:
|
29 |
| - f.write(message + "\n") |
| 30 | + f.write(message + "\n\n") |
| 31 | + |
| 32 | + |
| 33 | +def parse_log(file: Path) -> Generator[str]: |
| 34 | + """Collect key errors from a log file.""" |
| 35 | + with file.open(encoding="utf-8") as f: |
| 36 | + for line in f: |
| 37 | + if line.startswith("!"): |
| 38 | + yield line.strip() |
| 39 | + |
| 40 | + |
| 41 | +def collect_errors(directory: Path) -> Generator[tuple[Path, Generator[str]]]: |
| 42 | + """Read all log files in the `directory` and collect key errors.""" |
| 43 | + for file in directory.glob("*.log"): |
| 44 | + yield file.relative_to(directory), parse_log(file) |
30 | 45 |
|
31 | 46 |
|
32 | 47 | @dataclass
|
@@ -68,9 +83,19 @@ def execute(self) -> CalledProcessError | None:
|
68 | 83 | env=None if self.env is None else {**environ, **self.env},
|
69 | 84 | check=True,
|
70 | 85 | )
|
71 |
| - except CalledProcessError as error: |
| 86 | + except CalledProcessError as running_error: |
72 | 87 | log(f"💥{self.icon} 无法编译 {self.name}。")
|
73 |
| - return error |
| 88 | + for file, errors in collect_errors(self.directory): |
| 89 | + log( |
| 90 | + "\n".join( |
| 91 | + [ |
| 92 | + f"- `{file}`:", |
| 93 | + # LaTeX 习惯写 `file.sty',需避免 markdown 解析 |
| 94 | + *(f" - ```{e}```" for e in errors), |
| 95 | + ] |
| 96 | + ) |
| 97 | + ) |
| 98 | + return running_error |
74 | 99 |
|
75 | 100 | duration = perf_counter() - start
|
76 | 101 | log(f"✅{self.icon} 可正常编译 {self.name}:⌛ {duration:.1f} 秒。")
|
|
0 commit comments