refactor: 문서 개선 중
This commit is contained in:
@@ -28,6 +28,8 @@ from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import glob
|
||||
import hashlib
|
||||
import json
|
||||
import os
|
||||
import subprocess
|
||||
import sys
|
||||
@@ -55,6 +57,24 @@ def _last_commit_time(rel: str) -> int | None:
|
||||
return int(out) if out.isdigit() else None
|
||||
|
||||
|
||||
def _sha256(path: str) -> str:
|
||||
with open(path, "rb") as fh:
|
||||
return hashlib.sha256(fh.read()).hexdigest()
|
||||
|
||||
|
||||
def _manifest(svg: str) -> tuple[str, dict] | None:
|
||||
name = os.path.basename(svg)[:-4]
|
||||
path = os.path.join(os.path.dirname(svg), f"{name}.manifest.json")
|
||||
if not os.path.isfile(path):
|
||||
return None
|
||||
try:
|
||||
with open(path, encoding="utf-8") as fh:
|
||||
data = json.load(fh)
|
||||
except (OSError, json.JSONDecodeError):
|
||||
return None
|
||||
return path, data
|
||||
|
||||
|
||||
def verify(project: str) -> techlog.Report:
|
||||
rep = techlog.Report(project)
|
||||
base = os.path.join(ROOT, "docs", project, "final")
|
||||
@@ -70,6 +90,40 @@ def verify(project: str) -> techlog.Report:
|
||||
paired += 1
|
||||
spec_rel = os.path.relpath(spec, ROOT)
|
||||
|
||||
manifest = _manifest(svg)
|
||||
if manifest is not None:
|
||||
manifest_path, data = manifest
|
||||
expected_spec = data.get("source_spec_file_sha256")
|
||||
if isinstance(expected_spec, str) and expected_spec:
|
||||
actual_spec = _sha256(spec)
|
||||
if actual_spec != expected_spec:
|
||||
rep.error(
|
||||
"정본을 거치지 않고 바뀐 spec — manifest 불일치",
|
||||
(
|
||||
f"{spec_rel} sha256={actual_spec} · "
|
||||
f"{os.path.relpath(manifest_path, ROOT)} 는 {expected_spec}"
|
||||
),
|
||||
)
|
||||
continue
|
||||
|
||||
output_hashes = data.get("output_sha256")
|
||||
expected_svg = (
|
||||
output_hashes.get(os.path.basename(svg))
|
||||
if isinstance(output_hashes, dict)
|
||||
else None
|
||||
)
|
||||
if isinstance(expected_svg, str) and expected_svg:
|
||||
actual_svg = _sha256(svg)
|
||||
if actual_svg != expected_svg:
|
||||
rep.error(
|
||||
"정본을 거치지 않고 고친 그림 — 산출물 해시",
|
||||
(
|
||||
f"{svg_rel} sha256={actual_svg} · "
|
||||
f"{os.path.relpath(manifest_path, ROOT)} 는 {expected_svg}"
|
||||
),
|
||||
)
|
||||
continue
|
||||
|
||||
if _dirty(svg_rel) and not _dirty(spec_rel):
|
||||
rep.error("정본을 거치지 않고 고친 그림 — 작업 트리",
|
||||
f"{svg_rel} 이 고쳐졌는데 {spec_rel} 은 그대로다")
|
||||
|
||||
Reference in New Issue
Block a user