website

#astro#js#html#css

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

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


9ec4783 — pyrossh 2025-11-21T14:02:12+05:30
update commit diff

Generated files not shown: bun.lock

package.json CHANGED
@@ -32,12 +32,13 @@
32
32
  "timeago.js": "^4.0.2"
33
33
  },
34
34
  "devDependencies": {
35
- "@aws-sdk/client-sts": "^3.932.0",
36
35
  "@aws-sdk/client-s3": "^3.932.0",
37
- "@iconify-json/mdi": "^1.2.3",
36
+ "@aws-sdk/client-sts": "^3.932.0",
38
37
  "@iconify-json/material-symbols": "^1.2.39",
38
+ "@iconify-json/mdi": "^1.2.3",
39
39
  "@playwright/test": "^1.52.0",
40
40
  "@tauri-apps/cli": "^2.9.1",
41
- "@types/bun": "^1.3.2"
41
+ "@types/bun": "^1.3.2",
42
+ "diff2html": "^3.4.52"
42
43
  }
43
44
  }
src/content.config.ts CHANGED
@@ -24,7 +24,6 @@ export const collections = {
24
24
  const readmePath = repoPath + "/README.md";
25
25
  console.log("loading repo " + repoPath)
26
26
  const git = simpleGit(repoPath)
27
- // "-p",
28
27
  const commits = await git.log(["--branches", "--tags"]);
29
28
  const paths = await git.raw(["ls-files"]);
30
29
  const files = [];
@@ -32,7 +31,7 @@ export const collections = {
32
31
  try {
33
32
  const stat = await fs.stat(`${repoPath}/${p}`);
34
33
  const isLarge = stat.size > 1024 * 512;
35
- const history = isLarge ? { all: [] } : await git.log(["-p", p]);
34
+ const history = isLarge ? { all: [] } : await git.log([p]);
36
35
  files.push({
37
36
  name: p,
38
37
  absolutePath: `${repoPath}/${p}`,
@@ -58,6 +57,7 @@ export const collections = {
58
57
  badges: r.badges || [],
59
58
  commits: commits.all.map(collectCommits),
60
59
  files: fileTree,
60
+ absolutePath: repoPath,
61
61
  },
62
62
  rendered: readmeContent,
63
63
  });
@@ -75,6 +75,7 @@ export const collections = {
75
75
  })).optional(),
76
76
  commits: z.array(CommitSchema),
77
77
  files: z.array(FileNodeSchema),
78
+ absolutePath: z.string(),
78
79
  }),
79
80
  }),
80
81
  content: defineCollection({
src/pages/repos/[...repoId]/commits/[...hash]/index.astro CHANGED
@@ -3,6 +3,8 @@ import { type CollectionEntry, getCollection } from "astro:content";
3
3
  import RepoLayout from "@/layouts/RepoLayout.astro";
4
4
  import Commit from "@/components/Commit.astro";
5
5
  import type { Commit as CommitType } from "../../../../../utils/files";
6
+ import { generateHTMLDiff } from "@/utils/diff";
7
+ import "diff2html/bundles/css/diff2html.min.css";
6
8
 
7
9
  export async function getStaticPaths() {
8
10
  const repos = await getCollection("repos");
@@ -23,9 +25,10 @@ type Props = {
23
25
  };
24
26
 
25
27
  const { repo, commit } = Astro.props;
28
+ const diffHtml = await generateHTMLDiff(repo.data.absolutePath, commit.hash);
26
29
  ---
27
30
 
28
31
  <RepoLayout repo={repo}>
29
32
  <Commit repoId={repo.id} commit={commit} />
30
- <p>WIP: Show Diff summary</p>
33
+ <div set:html={diffHtml} />
31
34
  </RepoLayout>
src/utils/diff.ts ADDED
@@ -0,0 +1,13 @@
1
+ import Diff2html from "diff2html";
2
+ import { simpleGit } from "simple-git";
3
+
4
+ export const generateHTMLDiff = async (repoPath: string, hash: string, file?: string): Promise<string> => {
5
+ const git = simpleGit(repoPath);
6
+ const diff = await git.diff([`${hash}^..${hash}`].concat(file ? [file] : []));
7
+ const diffJson = Diff2html.parse(diff);
8
+ const diffHtml = Diff2html.html(diffJson, {
9
+ drawFileList: true,
10
+ matching: "lines",
11
+ });
12
+ return diffHtml;
13
+ }
src/utils/files.ts CHANGED
@@ -16,7 +16,6 @@ export interface Commit {
16
16
  date: string;
17
17
  branches: string[];
18
18
  tags: string[];
19
- diff?: string;
20
19
  }
21
20
 
22
21
  export interface FileNode {
@@ -39,7 +38,6 @@ export const CommitSchema = z.object({
39
38
  date: z.string(),
40
39
  branches: z.array(z.string()),
41
40
  tags: z.array(z.string()),
42
- diff: z.string().optional(),
43
41
  });
44
42
 
45
43
  export const FileNodeSchema: z.ZodType<FileNode> = z.lazy(() =>