fix(t39): daemon 端展開 config 的 ~/ 路徑

安裝器成功頁下載的 config.json 把 manifest 寫成 ~/.arcrun-rag/manifest.json——那是給人
看的寫法,Go 不展開波浪號,os.ReadFile 會去找一個字面上叫 "~" 的資料夾。

修在 daemon 端而非前端:用戶自己手打 config、或把設定搬到另一台機器時 ~/ 都該會動,
而前端也拿不到用戶家目錄。manifest 與 watch_folder(s) 全展開;只認 ~/ 與單獨的 ~,
~user 形式不猜(Go 無法解析他人家目錄);拿不到家目錄就原樣返回讓錯誤誠實浮現。

測試 +2(config 展開含 CJK 路徑與絕對路徑不動、expandHome 六種邊界),collector 全套綠。
This commit is contained in:
Claude
2026-07-25 08:18:21 +00:00
parent 125377b899
commit e548c57efa
2 changed files with 82 additions and 0 deletions
+56
View File
@@ -122,3 +122,59 @@ func TestRunDirectOnceMultiRootDryRun(t *testing.T) {
t.Fatalf("rootB 事件錯:%v", byRoot[rootB])
}
}
// t39config 的 `~/` 由 daemon 端展開——安裝器成功頁下載的 config.json 用
// `~/.arcrun-rag/manifest.json` 這種人看的寫法,Go 不展開波浪號=會去找字面上叫 "~" 的資料夾。
func TestLoadDirectConfigExpandsHome(t *testing.T) {
home, err := os.UserHomeDir()
if err != nil || home == "" {
t.Skip("拿不到家目錄,跳過")
}
dir := t.TempDir()
cfgPath := filepath.Join(dir, "config.json")
body := `{
"watch_folders": ["~/Documents/知識庫", "/tmp/絕對路徑不動"],
"manifest": "~/.arcrun-rag/manifest.json",
"cypher_url": "https://cypher.example.workers.dev",
"namespace": "ns1"
}`
if err := os.WriteFile(cfgPath, []byte(body), 0o644); err != nil {
t.Fatal(err)
}
cfg, err := LoadDirectConfig(cfgPath)
if err != nil {
t.Fatalf("LoadDirectConfig: %v", err)
}
wantManifest := filepath.Join(home, ".arcrun-rag/manifest.json")
if cfg.Manifest != wantManifest {
t.Errorf("manifest 未展開:got %q want %q", cfg.Manifest, wantManifest)
}
folders := cfg.Folders()
wantFolder := filepath.Join(home, "Documents/知識庫")
if folders[0] != wantFolder {
t.Errorf("watch_folders[0] 未展開:got %q want %q", folders[0], wantFolder)
}
if folders[1] != "/tmp/絕對路徑不動" {
t.Errorf("絕對路徑不該被動:got %q", folders[1])
}
}
func TestExpandHomeEdgeCases(t *testing.T) {
home, err := os.UserHomeDir()
if err != nil || home == "" {
t.Skip("拿不到家目錄,跳過")
}
cases := map[string]string{
"~": home,
"~/a/b": filepath.Join(home, "a/b"),
"/abs/path": "/abs/path",
"relative/dir": "relative/dir",
"": "",
"~notme/x": "~notme/x", // 只認 `~/``~user` 形式不猜(Go 無法解析他人家目錄)
}
for in, want := range cases {
if got := expandHome(in); got != want {
t.Errorf("expandHome(%q)%qwant %q", in, got, want)
}
}
}