feat: 문서 구조 변경 및 tech-visual 스킬 추가
This commit is contained in:
Executable
+91
@@ -0,0 +1,91 @@
|
||||
#!/usr/bin/env python3
|
||||
"""tech-log-tree.json 을 다시 만든다.
|
||||
|
||||
SSOT(final/document.md)에서 뽑은 글감과 이미 쓴 기록을 한 파일에 모은다. 기록 파일이
|
||||
정본이므로 이 스크립트는 그것을 읽어 채우고, 아직 글이 없는 글감은 사람이 적은 항목을
|
||||
그대로 둔다.
|
||||
|
||||
python3 scripts/build-tech-log-tree.py [프로젝트 ...]
|
||||
"""
|
||||
from __future__ import annotations
|
||||
import json, re, sys, glob, os, datetime
|
||||
|
||||
KINDS = ["case", "concept", "reference", "question", "decision"]
|
||||
ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
||||
|
||||
|
||||
def front_matter(path: str) -> dict:
|
||||
text = open(path, encoding="utf-8").read()
|
||||
if not text.startswith("---"):
|
||||
return {}
|
||||
end = text.find("\n---", 3)
|
||||
out = {}
|
||||
for line in text[3:end].splitlines():
|
||||
m = re.match(r"^([a-zA-Z_]+):\s*(.*)$", line)
|
||||
if m:
|
||||
out[m.group(1)] = m.group(2).strip().strip('"')
|
||||
return out
|
||||
|
||||
|
||||
def build(project: str) -> dict:
|
||||
base = os.path.join(ROOT, "docs", project)
|
||||
studio = os.path.join(base, "tech-log-studio")
|
||||
tree_path = os.path.join(studio, "tech-log-tree.json")
|
||||
previous = {}
|
||||
if os.path.exists(tree_path):
|
||||
previous = json.load(open(tree_path, encoding="utf-8"))
|
||||
|
||||
ssot = "final/document.md" if os.path.exists(os.path.join(base, "final/document.md")) else None
|
||||
topics = {}
|
||||
for topic_dir in sorted(d for d in glob.glob(os.path.join(studio, "*")) if os.path.isdir(d)):
|
||||
topic = os.path.basename(topic_dir)
|
||||
entry = {"topic": topic, "kinds": {}}
|
||||
for kind in KINDS:
|
||||
items = []
|
||||
for f in sorted(glob.glob(os.path.join(topic_dir, kind, "*.md"))):
|
||||
fm = front_matter(f)
|
||||
text = open(f, encoding="utf-8").read()
|
||||
items.append({
|
||||
"title": fm.get("title", os.path.basename(f)),
|
||||
"slug": fm.get("slug", ""),
|
||||
"file": os.path.relpath(f, studio),
|
||||
"status": fm.get("status", "미작성"),
|
||||
"studioId": fm.get("id", ""),
|
||||
"assets": len(re.findall(r"^ - key: ", text, re.M)),
|
||||
"evidence": len(re.findall(r"^ - \.\./", text, re.M)),
|
||||
})
|
||||
# 아직 글이 없는 글감은 지난 tree 에서 가져와 유지한다
|
||||
written = {i["slug"] for i in items if i["slug"]}
|
||||
for old in previous.get("topics", {}).get(topic, {}).get("kinds", {}).get(kind, []):
|
||||
if not old.get("file") and old.get("slug") not in written:
|
||||
items.append(old)
|
||||
entry["kinds"][kind] = items
|
||||
topics[topic] = entry
|
||||
|
||||
return {
|
||||
"project": project,
|
||||
"ssot": ssot,
|
||||
"generatedAt": datetime.date.today().isoformat(),
|
||||
"note": "글감 목록이다. file 이 있으면 이미 쓴 기록이고, 없으면 아직 쓰지 않은 글감이다.",
|
||||
"topics": topics,
|
||||
}
|
||||
|
||||
|
||||
def main(argv: list[str]) -> int:
|
||||
projects = argv[1:] or [
|
||||
os.path.basename(os.path.dirname(p))
|
||||
for p in glob.glob(os.path.join(ROOT, "docs/*/tech-log-studio"))
|
||||
]
|
||||
for project in sorted(projects):
|
||||
tree = build(project)
|
||||
out = os.path.join(ROOT, "docs", project, "tech-log-studio", "tech-log-tree.json")
|
||||
with open(out, "w", encoding="utf-8") as fh:
|
||||
json.dump(tree, fh, ensure_ascii=False, indent=2)
|
||||
fh.write("\n")
|
||||
n = sum(len(v) for t in tree["topics"].values() for v in t["kinds"].values())
|
||||
print(f"{os.path.relpath(out, ROOT)} — 주제 {len(tree['topics'])} · 글감 {n}")
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
raise SystemExit(main(sys.argv))
|
||||
Reference in New Issue
Block a user