(
scan_dir: Path, relative_path: str | None, expected_digest: str | None
)
| 3433 | |
| 3434 | |
| 3435 | def patch_artifact_preview( |
| 3436 | scan_dir: Path, relative_path: str | None, expected_digest: str | None |
| 3437 | ) -> tuple[str | None, dict[str, int | bool] | None]: |
| 3438 | if relative_path is None or expected_digest is None: |
| 3439 | return None, None |
| 3440 | digest = hashlib.sha256() |
| 3441 | preview = bytearray() |
| 3442 | additions = 0 |
| 3443 | deletions = 0 |
| 3444 | file_count = 0 |
| 3445 | old_headers = 0 |
| 3446 | new_headers = 0 |
| 3447 | at_line_start = True |
| 3448 | try: |
| 3449 | with open_scan_local_file(scan_dir, relative_path) as patch: |
| 3450 | require_bounded_patch_artifact(patch) |
| 3451 | while chunk := patch.readline(1024 * 1024): |
| 3452 | digest.update(chunk) |
| 3453 | if len(preview) <= PATCH_PREVIEW_BYTES: |
| 3454 | preview.extend(chunk[: PATCH_PREVIEW_BYTES + 1 - len(preview)]) |
| 3455 | if at_line_start: |
| 3456 | if chunk.startswith(b"diff --git "): |
| 3457 | file_count += 1 |
| 3458 | elif chunk.startswith(b"+++ "): |
| 3459 | new_headers += 1 |
| 3460 | elif chunk.startswith(b"--- "): |
| 3461 | old_headers += 1 |
| 3462 | elif chunk.startswith(b"+"): |
| 3463 | additions += 1 |
| 3464 | elif chunk.startswith(b"-"): |
| 3465 | deletions += 1 |
| 3466 | at_line_start = chunk.endswith(b"\n") |
| 3467 | except SystemExit: |
| 3468 | return None, None |
| 3469 | if f"sha256:{digest.hexdigest()}" != expected_digest: |
| 3470 | return None, None |
| 3471 | preview_truncated = len(preview) > PATCH_PREVIEW_BYTES |
| 3472 | preview_text = preview[:PATCH_PREVIEW_BYTES].decode("utf-8", errors="replace") |
| 3473 | if preview_truncated: |
| 3474 | preview_text = f"{preview_text}\n... patch preview truncated ..." |
| 3475 | return preview_text, { |
| 3476 | "additions": additions, |
| 3477 | "deletions": deletions, |
| 3478 | "fileCount": file_count or min(old_headers, new_headers), |
| 3479 | "previewTruncated": preview_truncated, |
| 3480 | } |
| 3481 | |
| 3482 | |
| 3483 | def safe_source_path(target: Path, relative_path: str) -> Path | None: |
no test coverage detected