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,
|
||||
@@ -246,6 +247,43 @@ export class GiteaClient implements GitClient {
|
||||
return commits.map((commit) => toIso(commit.commit?.author?.date));
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Gitea 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}/repos/${encodeURIComponent(ref.owner)}/${encodeURIComponent(ref.name)}`;
|
||||
const headers = this.headers();
|
||||
|
||||
const eintraege = await getJsonSafe<Array<{ name: string; type: string }>>(
|
||||
`${base}/contents`,
|
||||
[],
|
||||
{ headers },
|
||||
);
|
||||
const name = pickReadme(
|
||||
eintraege.filter((eintrag) => eintrag.type === "file").map((eintrag) => eintrag.name),
|
||||
);
|
||||
if (!name) return null;
|
||||
|
||||
const datei = await getJson<{
|
||||
content?: string;
|
||||
encoding?: string;
|
||||
path?: string;
|
||||
html_url?: string | null;
|
||||
}>(`${base}/contents/${encodeURIComponent(name)}`, { headers });
|
||||
if (!datei?.content || datei.encoding !== "base64") return null;
|
||||
|
||||
const { content, truncated } = capReadme(decodeBase64(datei.content));
|
||||
return {
|
||||
content,
|
||||
path: datei.path ?? name,
|
||||
// html_url zeigt auf die Datei; fuer relative Links braucht es das
|
||||
// Verzeichnis darum herum.
|
||||
baseUrl: datei.html_url ? datei.html_url.replace(/\/[^/]*$/, "/") : null,
|
||||
truncated,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
function mapCommitStatus(state: string): CiState {
|
||||
|
||||
Reference in New Issue
Block a user