fork of https://github.com/sourcegraph/zoekt
0

Configure Feed

Select the types of activity you want to include in your feed.

use repo URL as an identifier

Signed-off-by: Seongmin Lee <git@boltless.me>

author
Seongmin Lee
date (Jun 26, 2026, 1:43 AM +0900) commit cfc4aa0d parent f80c7e09 change-id zozuxxuz
+67 -37
+10 -7
index/eval.go
··· 289 289 } 290 290 291 291 fileMatch := zoekt.FileMatch{ 292 - Repository: md.Name, 292 + Repository: md.URL, 293 293 RepositoryID: md.ID, 294 294 RepositoryPriority: md.GetPriority(), 295 295 FileName: string(d.fileName(nextDoc)), ··· 357 357 358 358 for _, md := range d.repoMetaData { 359 359 r := md 360 - addRepo(&res, &r) 360 + // Key by URL: it is the unique repo identity and matches 361 + // FileMatch.Repository (also set to the URL). Subrepos are keyed by 362 + // their Name, matching FileMatch.SubRepositoryName. 363 + addRepo(&res, r.URL, &r) 361 364 for _, v := range r.SubRepoMap { 362 - addRepo(&res, v) 365 + addRepo(&res, v.Name, v) 363 366 } 364 367 } 365 368 ··· 371 374 return &res, nil 372 375 } 373 376 374 - func addRepo(res *zoekt.SearchResult, repo *zoekt.Repository) { 377 + func addRepo(res *zoekt.SearchResult, key string, repo *zoekt.Repository) { 375 378 if res.RepoURLs == nil { 376 379 res.RepoURLs = map[string]string{} 377 380 } 378 - res.RepoURLs[repo.Name] = repo.FileURLTemplate 381 + res.RepoURLs[key] = repo.FileURLTemplate 379 382 380 383 if res.LineFragments == nil { 381 384 res.LineFragments = map[string]string{} 382 385 } 383 - res.LineFragments[repo.Name] = repo.LineFragmentTemplate 386 + res.LineFragments[key] = repo.LineFragmentTemplate 384 387 } 385 388 386 389 // Gather matches from this document. The matches are returned in document ··· 547 550 } 548 551 549 552 include = func(rle *zoekt.RepoListEntry) bool { 550 - _, ok := foundRepos[rle.Repository.Name] 553 + _, ok := foundRepos[rle.Repository.URL] 551 554 return ok 552 555 } 553 556 }
+18 -4
index/index_test.go
··· 1640 1640 1641 1641 sres := searchForTest(t, b, &query.Substring{Pattern: "bla"}) 1642 1642 1643 - if sres.RepoURLs["name"] != "file-url" { 1644 - t.Errorf("got RepoURLs %v, want {name: URL}", sres.RepoURLs) 1643 + // RepoURLs/LineFragments are keyed by the repo's URL (its unique identity). 1644 + if sres.RepoURLs["URL"] != "file-url" { 1645 + t.Errorf("got RepoURLs %v, want {URL: file-url}", sres.RepoURLs) 1645 1646 } 1646 - if sres.LineFragments["name"] != "fragment" { 1647 - t.Errorf("got URLs %v, want {name: URL}", sres.LineFragments) 1647 + if sres.LineFragments["URL"] != "fragment" { 1648 + t.Errorf("got URLs %v, want {URL: fragment}", sres.LineFragments) 1648 1649 } 1649 1650 } 1650 1651 ··· 3639 3640 chunkOpts, 3640 3641 ) 3641 3642 wantSingleMatch(res, "f2") 3643 + }) 3644 + 3645 + // type:filematch is the default result granularity. The wrapper must be 3646 + // treated as a passthrough to the child instead of crashing the shard. 3647 + t.Run("TypeFileMatch", func(t *testing.T) { 3648 + res := searchForTest(t, b, 3649 + &query.Type{ 3650 + Type: query.TypeFileMatch, 3651 + Child: &query.Substring{Pattern: "needle"}, 3652 + }) 3653 + if len(res.Files) != 2 { 3654 + t.Fatalf("got %d file matches, want 2", len(res.Files)) 3655 + } 3642 3656 }) 3643 3657 } 3644 3658
+5 -1
index/matchtree.go
··· 1057 1057 1058 1058 case *query.Type: 1059 1059 if s.Type != query.TypeFileName { 1060 - break 1060 + // TypeFileMatch is the default result granularity, so the 1061 + // wrapper carries no extra match semantics: match the child 1062 + // directly. TypeRepo is normally stripped before reaching a 1063 + // shard, but handle it the same way to avoid a panic. 1064 + return d.newMatchTree(s.Child, opt) 1061 1065 } 1062 1066 1063 1067 ct, err := d.newMatchTree(s.Child, opt)
+8 -4
internal/e2e/e2e_index_test.go
··· 50 50 ShardMax: 1024, 51 51 RepositoryDescription: zoekt.Repository{ 52 52 Name: "repo", 53 + URL: "repo", 53 54 }, 54 55 Parallelism: 2, 55 56 SizeMax: 1 << 20, ··· 123 124 // use retryTest to allow for the directory watcher to notice the meta 124 125 // file 125 126 retryTest(t, func(fatalf func(format string, args ...any)) { 126 - // Add a .meta file for each shard with repo.Name set to 127 - // "repo-mutated". We do this inside retry helper since we have noticed 128 - // some flakiness on github CI. 127 + // Add a .meta file for each shard with repo.URL set to 128 + // "repo-mutated" (URL is the repo identity surfaced as 129 + // FileMatch.Repository). We do this inside retry helper since we have 130 + // noticed some flakiness on github CI. 129 131 for _, p := range fs { 130 132 repos, _, err := index.ReadMetadataPath(p) 131 133 if err != nil { 132 134 t.Fatal(err) 133 135 } 134 - repos[0].Name = "repo-mutated" 136 + repos[0].URL = "repo-mutated" 135 137 b, err := json.Marshal(repos[0]) 136 138 if err != nil { 137 139 t.Fatal(err) ··· 391 393 ShardMax: 1024, 392 394 RepositoryDescription: zoekt.Repository{ 393 395 Name: "repo", 396 + URL: "repo", 394 397 FileURLTemplate: "url", 395 398 }, 396 399 Parallelism: 2, ··· 429 432 430 433 opts.RepositoryDescription = zoekt.Repository{ 431 434 Name: "repo2", 435 + URL: "repo2", 432 436 FileURLTemplate: "url2", 433 437 } 434 438
+11 -9
search/shards.go
··· 835 835 return 836 836 } 837 837 838 - send := func(repoName string, a, b int, stats zoekt.Stats) { 838 + send := func(repoURL string, a, b int, stats zoekt.Stats) { 839 839 index.SortFiles(result.Files[a:b]) 840 840 841 - filteredRepoURLs := map[string]string{repoName: result.RepoURLs[repoName]} 842 - filteredLineFragments := map[string]string{repoName: result.LineFragments[repoName]} 841 + // FileMatch.Repository holds the repo's unique key (its URL), which is 842 + // also the key used for RepoURLs/LineFragments. 843 + filteredRepoURLs := map[string]string{repoURL: result.RepoURLs[repoURL]} 844 + filteredLineFragments := map[string]string{repoURL: result.LineFragments[repoURL]} 843 845 844 846 // Filter RepoURLs and LineFragments to only those of repoName and its 845 847 // subRepositories if there are subRepositories ··· 874 876 875 877 var startIndex, endIndex int 876 878 curRepoID := result.Files[0].RepositoryID 877 - curRepoName := result.Files[0].Repository 879 + curRepoURL := result.Files[0].Repository 878 880 879 881 fm := zoekt.FileMatch{} 880 882 for endIndex, fm = range result.Files { 881 883 if curRepoID != fm.RepositoryID { 882 884 // Stats must stay aggregate-able, hence we sent the aggregate stats with the 883 885 // last event. 884 - send(curRepoName, startIndex, endIndex, zoekt.Stats{}) 886 + send(curRepoURL, startIndex, endIndex, zoekt.Stats{}) 885 887 886 888 startIndex = endIndex 887 889 curRepoID = fm.RepositoryID 888 - curRepoName = fm.Repository 890 + curRepoURL = fm.Repository 889 891 } 890 892 } 891 893 892 - send(curRepoName, startIndex, endIndex+1, result.Stats) 894 + send(curRepoURL, startIndex, endIndex+1, result.Stats) 893 895 } 894 896 895 897 func observeMetrics(sr *zoekt.SearchResult) { ··· 1073 1075 agg.Stats.Add(&r.rl.Stats) 1074 1076 1075 1077 for _, r := range r.rl.Repos { 1076 - prev, ok := uniq[r.Repository.Name] 1078 + prev, ok := uniq[r.Repository.URL] 1077 1079 if !ok { 1078 1080 cp := *r // We need to copy because we mutate r.Stats when merging duplicates 1079 - uniq[r.Repository.Name] = &cp 1081 + uniq[r.Repository.URL] = &cp 1080 1082 } else { 1081 1083 prev.Stats.Add(&r.Stats) 1082 1084 }
+4 -1
search/shards_test.go
··· 429 429 repo := &zoekt.Repository{ 430 430 ID: uint32(i + 1), 431 431 Name: repoName, 432 + URL: repoName, 432 433 Metadata: metadata, 433 434 } 434 435 ··· 645 646 { 646 647 ID: 1234, 647 648 Name: "repo-a", 649 + URL: "url-a", 648 650 Branches: []zoekt.RepositoryBranch{{Name: "main"}, {Name: "dev"}}, 649 651 RawConfig: map[string]string{"repoid": "1234"}, 650 652 }, 651 653 { 652 654 Name: "repo-b", 655 + URL: "url-b", 653 656 Branches: []zoekt.RepositoryBranch{{Name: "main"}, {Name: "dev"}}, 654 657 }, 655 658 } ··· 938 941 939 942 var nextShardNum int 940 943 addShard := func(repo string, rawConfig map[string]string, docs ...index.Document) { 941 - r := &zoekt.Repository{Name: repo} 944 + r := &zoekt.Repository{Name: repo, URL: repo} 942 945 r.RawConfig = rawConfig 943 946 b := testShardBuilder(t, r, docs...) 944 947 shard := searcherForTest(t, b)
+11 -11
web/e2e_test.go
··· 307 307 "json basic test", 308 308 FileMatch{ 309 309 FileName: "f2", 310 - Repo: "name", 310 + Repo: "repo-url", 311 311 Matches: []Match{ 312 312 { 313 313 FileName: "f2", ··· 384 384 "no context doesn't return Before or After", 385 385 FileMatch{ 386 386 FileName: "f2", 387 - Repo: "name", 387 + Repo: "repo-url", 388 388 Matches: []Match{ 389 389 { 390 390 FileName: "f2", ··· 404 404 "filename does not return Before or After", 405 405 FileMatch{ 406 406 FileName: "f2", 407 - Repo: "name", 407 + Repo: "repo-url", 408 408 Matches: []Match{ 409 409 { 410 410 FileName: "f2", ··· 422 422 "context returns Before and After", 423 423 FileMatch{ 424 424 FileName: "f2", 425 - Repo: "name", 425 + Repo: "repo-url", 426 426 Matches: []Match{ 427 427 { 428 428 FileName: "f2", ··· 444 444 "index at start returns After but no Before", 445 445 FileMatch{ 446 446 FileName: "f2", 447 - Repo: "name", 447 + Repo: "repo-url", 448 448 Matches: []Match{ 449 449 { 450 450 FileName: "f2", ··· 465 465 "index at end returns Before but no After", 466 466 FileMatch{ 467 467 FileName: "f2", 468 - Repo: "name", 468 + Repo: "repo-url", 469 469 Matches: []Match{ 470 470 { 471 471 FileName: "f2", ··· 486 486 "index with large context at end returns whole document", 487 487 FileMatch{ 488 488 FileName: "f2", 489 - Repo: "name", 489 + Repo: "repo-url", 490 490 Matches: []Match{ 491 491 { 492 492 FileName: "f2", ··· 507 507 "index with large context at start returns whole document", 508 508 FileMatch{ 509 509 FileName: "f2", 510 - Repo: "name", 510 + Repo: "repo-url", 511 511 Matches: []Match{ 512 512 { 513 513 FileName: "f2", ··· 528 528 "context returns whitespaces lines", 529 529 FileMatch{ 530 530 FileName: "f4", 531 - Repo: "name", 531 + Repo: "repo-url", 532 532 Matches: []Match{ 533 533 { 534 534 FileName: "f4", ··· 550 550 "context returns new lines", 551 551 FileMatch{ 552 552 FileName: "f3", 553 - Repo: "name", 553 + Repo: "repo-url", 554 554 Matches: []Match{ 555 555 { 556 556 FileName: "f3", ··· 572 572 "context returns empty end line", 573 573 FileMatch{ 574 574 FileName: "f5", 575 - Repo: "name", 575 + Repo: "repo-url", 576 576 Matches: []Match{ 577 577 { 578 578 FileName: "f5",