~repos /website

#astro#js#html#css

git clone https://pyrossh.dev/repos/website.git

木 Personal website of pyrossh. Built with astrojs, shiki, vite.



src/utils/commit.ts



import Diff2html from "diff2html";
import fs from "fs/promises";
import path from "path";
import { simpleGit } from "simple-git";
import { type FileNode } from "./files";
export interface Commit {
hash: string;
message: string;
body: string;
author_name: string;
author_email: string;
date: string;
branches: string[];
tags: string[];
}
export const collectCommits = (item: { hash: any; message: any; body: any; author_name: any; author_email: any; date: any; refs: string; }) => ({
hash: item.hash,
message: item.message,
body: `${item.message}\n\n${item.body}`,
author_name: item.author_name,
author_email: item.author_email,
date: item.date,
branches: item.refs.split(",").filter((ref: string) => !ref.includes("origin")).map((ref) => ref.trim()),
tags: item.refs.split(",").filter((ref: string) => ref.includes("tag: ")).map((ref) => ref.replace("tag: ", "")),
});
export const getCommits = async (repoPath: string): Promise<Commit[]> => {
const git = simpleGit(repoPath);
const commits = await git.log(["--branches", "--tags"]);
return commits.all.map(collectCommits);
}
export const getFiles = async (repoPath: string): Promise<FileNode[]> => {
const git = simpleGit(repoPath);
const paths = await git.raw(["ls-files"]);
const files = [];
for (const p of paths.split("\n").filter((p) => p.length > 0)) {
try {
const stat = await fs.stat(`${repoPath}/${p}`);
const ext = path.extname(p).replace(".", "");
files.push({
name: p,
ext,
size: stat.size,
isDirectory: stat.isDirectory(),
absolutePath: `${repoPath}/${p}`,
})
} catch (e) {
// Ignore files not found
console.log(e);
}
}
return files;
}
export const getFileHistory = async (repoPath: string, filePath: string): Promise<Commit[]> => {
const git = simpleGit(repoPath);
const stat = await fs.stat(`${repoPath}/${filePath}`);
const isLarge = stat.size > 1024 * 512;
const history = isLarge ? { all: [] } : await git.log([filePath]);
return history.all.map(collectCommits);
}
export const generateHTMLDiff = async (repoPath: string, hash: string): Promise<string> => {
const git = simpleGit(repoPath);
let diff = '';
try {
diff = await git.diff([`${hash}^..${hash}`]);
} catch (e) {
diff = await git.diff([hash]);
}
if (diff.length > 1024 * 512) {
return '<p>Diff too large to display.</p>';
}
const diffJson = Diff2html.parse(diff);
const diffHtml = Diff2html.html(diffJson, {
drawFileList: true,
matching: "lines",
});
return diffHtml;
}