From 5974e0f20434c6c873e9636a07a1c64651fe1d62 Mon Sep 17 00:00:00 2001 From: Ian Kerins Date: Thu, 31 Oct 2024 14:11:32 -0400 Subject: [PATCH] Properly serve results from repositories that have no VCS metadata e.g. "plain directory" repositories of the kind produced by `zoekt-index` (as opposed to `zoekt-git-index`). I simply had never tested support for these, and they of course lack properties on the returned JSON objects that are otherwise present. Tolerate certain properties being missing or null. Fixes #30. --- .changeset/happy-goats-pull.md | 5 +++++ src/lib/server/search-api.ts | 14 +++++++------ src/lib/server/zoekt-list-repositories.ts | 25 +++++++++++++++-------- 3 files changed, 29 insertions(+), 15 deletions(-) create mode 100644 .changeset/happy-goats-pull.md diff --git a/.changeset/happy-goats-pull.md b/.changeset/happy-goats-pull.md new file mode 100644 index 0000000..cdfd395 --- /dev/null +++ b/.changeset/happy-goats-pull.md @@ -0,0 +1,5 @@ +--- +"neogrok": patch +--- + +Properly serve results from repositories that have no VCS metadata diff --git a/src/lib/server/search-api.ts b/src/lib/server/search-api.ts index d784ba2..1baf9b7 100644 --- a/src/lib/server/search-api.ts +++ b/src/lib/server/search-api.ts @@ -108,13 +108,13 @@ const searchResultSchema = v.object({ .object({ Repository: v.string(), FileName: v.string(), - Branches: v.array(v.string()), + Branches: v.array(v.string()).optional(), // Will be the empty string if zoekt couldn't figure it out, we // call it Text for both display purposes and for parameterizing // syntax highlighting; Text is the name zoekt will pick for // plain text files it can identify. Language: v.string().map((lang) => lang || "Text"), - Version: v.string(), + Version: v.string().optional(), ChunkMatches: v.array( v .object({ @@ -166,7 +166,7 @@ const searchResultSchema = v.object({ ({ Repository: repository, FileName: fileName, - Branches: branches, + Branches: branches = [], Language: language, Version: version, ChunkMatches: chunkMatches, @@ -241,9 +241,11 @@ const searchResultSchema = v.object({ ), fileName, chunks, - fileUrl: repoUrls[repository] - ?.replaceAll("{{.Version}}", version) - .replaceAll("{{.Path}}", fileName.text), + fileUrl: + version && + repoUrls[repository] + ?.replaceAll("{{.Version}}", version) + .replaceAll("{{.Path}}", fileName.text), // The 'template' is such that the line number can be `join`ed // into it. JSON serializable! lineNumberTemplate: diff --git a/src/lib/server/zoekt-list-repositories.ts b/src/lib/server/zoekt-list-repositories.ts index 967e2d6..4686206 100644 --- a/src/lib/server/zoekt-list-repositories.ts +++ b/src/lib/server/zoekt-list-repositories.ts @@ -89,14 +89,21 @@ const listResultSchema = v.object({ LatestCommitDate: dateSchema, FileURLTemplate: v.string(), CommitURLTemplate: v.string(), - Branches: v.array( - v - .object({ Name: v.string(), Version: v.string() }) - .map(({ Name, Version }) => ({ - name: Name, - version: Version, - })), - ), + Branches: v + .array( + v + .object({ Name: v.string(), Version: v.string() }) + .map(({ Name, Version }) => ({ + name: Name, + version: Version, + })), + ) + // Zoekt returns `null` when there are no branches (e.g. + // the repo is just a directory, no VCS info). To me that + // seems wrong and I think it should be `omitempty`, so + // tolerate both options in case that ever gets fixed. + .nullable() + .optional(), }) .map( ({ @@ -116,7 +123,7 @@ const listResultSchema = v.object({ lastCommit: toISOStringWithoutMs(LatestCommitDate), fileUrlTemplate: FileURLTemplate, commitUrlTemplate: CommitURLTemplate, - branches: Branches, + branches: Branches ?? [], }), ), IndexMetadata: v