feat(git): README des Repositories holen
Erspart den Wechsel ins Git, nur um zu sehen, worum ein halbvergessenes Projekt eigentlich ging. GitHub hat einen eigenen Endpunkt, der jede Schreibweise findet - ein Aufruf genuegt. GitLab und Gitea kennen keinen; dort wird erst das Wurzelverzeichnis aufgelistet und dann die gefundene Datei geholt. Erkannt werden README.md und die ueblichen Varianten, Gross- und Kleinschreibung egal; Markdown hat Vorrang, weil nur das wirklich dargestellt werden kann. Geholt wird hoechstens einmal am Tag, wie der Kalender, und mit eigenem Zeitstempel: schlaegt das eine fehl, soll das andere nicht mit blockiert werden. Bei 60 000 Zeichen wird abgeschnitten, aber an einer Zeilengrenze - sonst bliebe womoeglich ein halber Codeblock stehen. Dekodiert wird ueber Buffer und nicht ueber atob, sonst kaemen Umlaute als Kauderwelsch heraus. Kein README ist eine Auskunft, kein Fehlschlag: der Zeitstempel wird dann trotzdem gesetzt, damit nicht jeder Abgleich erneut sucht. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -5,6 +5,7 @@ import {
|
||||
calendarSince,
|
||||
type CommitCalendar,
|
||||
} from "./calendar";
|
||||
import { capReadme, decodeBase64, pickReadme, type RepoReadme } from "./readme";
|
||||
import type {
|
||||
BranchInfo,
|
||||
CiInfo,
|
||||
@@ -227,6 +228,44 @@ export class GitLabClient implements GitClient {
|
||||
return commits.map((commit) => toIso(commit.committed_date ?? commit.created_at));
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* GitLab kennt keinen README-Endpunkt. Erst das Wurzelverzeichnis
|
||||
* auflisten, dann die gefundene Datei holen – zwei Aufrufe.
|
||||
*/
|
||||
async fetchReadme(ref: RepoRef): Promise<RepoReadme | null> {
|
||||
const base = `${this.apiBase}/projects/${this.projectPath(ref)}`;
|
||||
const headers = this.headers();
|
||||
|
||||
const eintraege = await getJsonSafe<Array<{ name: string; type: string }>>(
|
||||
`${base}/repository/tree?per_page=100`,
|
||||
[],
|
||||
{ headers },
|
||||
);
|
||||
const name = pickReadme(
|
||||
eintraege.filter((eintrag) => eintrag.type === "blob").map((eintrag) => eintrag.name),
|
||||
);
|
||||
if (!name) return null;
|
||||
|
||||
const datei = await getJson<{ content?: string; encoding?: string; file_path?: string }>(
|
||||
`${base}/repository/files/${encodeURIComponent(name)}?ref=HEAD`,
|
||||
{ headers },
|
||||
);
|
||||
if (!datei?.content || datei.encoding !== "base64") return null;
|
||||
|
||||
const { content, truncated } = capReadme(decodeBase64(datei.content));
|
||||
const projekt = await getJsonSafe<GitLabProject>(base, {} as GitLabProject, { headers });
|
||||
|
||||
return {
|
||||
content,
|
||||
path: datei.file_path ?? name,
|
||||
baseUrl:
|
||||
projekt?.web_url && projekt.default_branch
|
||||
? `${projekt.web_url}/-/blob/${encodeURIComponent(projekt.default_branch)}/`
|
||||
: null,
|
||||
truncated,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
function mapPipelineState(status: string | null): CiState {
|
||||
|
||||
Reference in New Issue
Block a user