這區是本站最深的章節。每個函數一個預設收縮的 <details> 塊:點開看 signature + 中文講解,核心函數附逐行註解。行數很短的工具函數則用段落式說明帶過。
detect → extract → build → cluster 的資料流主幹。看懂後再往 分析與報告、輸出、維運與安全 延伸。語言抽取器放 extractors 專頁。detect.py(1996 行)· extract.py(5993 行)· build.py(1943 行)· cluster.py(320 行)
extractors/ 語言抽取器
extractor 骨架:models / engine / resolution / registry,加語言抽取的共通模式。graphify/extractors/
analyze.py(749 行)· report.py(300 行)
export + exporters
圖 → graph.json / graph.html / Obsidian vault / SVG / callflow HTML。export.py · exporters/html.py · tree_html.py · callflow_html.py
cli.py(~5000 行)· __main__.py
ops 維運與安全
cache / dedup / ingest / watch / serve / security / validate。cache.py · dedup.py · ingest.py · watch.py · serve.py · security.py · validate.py
tools/skillgen/ · scripts/gen_demo_path.py
tests 測試策略
140 個測試檔 + fixtures 設計——30+ 語言各一份 sample.*,怎麼測跨語言解析。tests/ + tests/fixtures/
對照指南:每頁頂部標示對應的原始檔與行數。程式碼引用自 Apache-2.0 上游,僅用於教學。
程式碼對照區是本站最深的章節。每個函數一個預設收縮的 <details> 塊:點開看 signature + 中文講解,核心函數附逐行註解。這反映了「從文檔到原始碼」的學習路徑。
建議的學習順序:先從主線 pipeline(detect→extract→build→cluster)開始,那是資料流主幹。看懂後再往分析與報告、輸出、維運與安全延伸。
程式碼引用自 Apache-2.0 上游,僅用於教學。這是開源專案「合理使用」的範例。
detect.py 中的 collect_files() 函數。| 錯誤訊息 | 原因 | 解決方式 |
|---|---|---|
code: file not found | 程式碼對照頁面找不到對應的原始檔 | 檢查 repo 版本是否與教學站對齊 |
line number mismatch | 行數與實際檔案不符 | 這是正常的,原始檔會持續演進 |
前面是「追蹤單一函數」;這次是自舉(dogfooding):graphify 官方就用自己管理自己——AGENTS.md 規定「先讀 graph.json、改完程式碼跑 graphify update .」。你要親手複製這個閉環。
graphify extract . 掃自己整個 repo——detect 會過濾 graphify-out/、node_modules 等 noise;確認程式碼走 AST、文件走 Pass 3。dedup.py 影響誰」的假設問題,用 graphify affected dedup 或 path 走一遍,對照自己 grep 的結果。review.md 精神——紀錄「圖哪邊誤導了你」。程式碼對照頁的規模很嚇人(extract.py 5993 行、cli.py 4044 行),但真正的結構不在行數:
extract() 只有兩遍邏輯(逐檔 AST → 跨檔 import 解析),真正的工作在 per-language 的 extract_<lang> 與 _import_* 家族;0.3.0 重構後語言邏輯收斂進 extractors/(LanguageConfig + 通用引擎),extract.py 反而變「dispatcher」。graphify-out/(唯一副作用出口)與快取目錄(cache.py 的讀寫)。測試「純函數」時要 mock 這兩個 I/O 點。build_from_json 有約 500 行 ID 正規化、ghost merge、shrink guard。讀 codebase 的秘訣是先讀「介面 + docstring + 測試」,再決定要不要進實作。extract_<lang> 存在,就代表該語言抽取得很完整」。實際上許多語言只做「結構抽取」(class/function/import),跨檔 calls 解析(Phase 2)需要 resolution 支援——冷門語言(Pascal、Terraform、Apex、Bash 的 source)沒有同等的跨檔解析深度。看到 extract_bash 只代表 Bash 有抽取器,不代表 Bash 的呼叫圖跨檔連得起來。判斷「這個語言支援到多深」要看 tests/fixtures 與 test_languages.py 有沒有對應的跨檔測例。| 症狀 | 可能原因 | 解決方案 |
|---|---|---|
| 某語言抽取器存在但節點極少 | 該語言只有結構抽取、無跨檔解析;或語法太新 tree-sitter grammar 沒涵蓋 | 看 test_languages.py 有沒有該語言的測例;用 fixture 跑 extract 比對預期節點數 |
| trace 到一半找不到函數定義 | 函數在別的模組(extractors/engine.py、install.py 被 re-export) | 用 grep "def " 全 repo 找;注意 __main__.py 的 re-export 連到 install.py |
| 改了純函數,測試卻失敗在「意外副作用」 | 函數偷偷寫了 graphify-out/ 或快取,測試 mock 不完整 | 檢查 tmp_path 是否被寫入;用 monkeypatch 隔離 cache/輸出路徑 |
| 行數對不上教學頁 | 上游在 v8 後持續演進,badge-line 是快照 | 以 github 上的 blob URL 為準;行號只是定位輔助 |
extract_python → _extract_generic → LanguageConfig 的呼叫鏈,指出「引擎 vs 語言設定」真正的分界線在哪一行。