Skip to content

Commit 462aa74

Browse files
committed
feat(details): fetch cachyos pkgbuilds from github
1 parent e6ec1b3 commit 462aa74

File tree

3 files changed

+87
-162
lines changed

3 files changed

+87
-162
lines changed

src/components/PackageDetails.tsx

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import {
1111
CardHeader,
1212
CardTitle,
1313
} from '@/components/ui/card';
14-
import {cachyosPaths} from '@/lib/cachy';
14+
import {fetchPkgbuilds, PkgbuildMap} from '@/lib/github';
1515
import {BriefPackageList, PackageDetails} from '@/lib/types';
1616
import {
1717
getDownloadMirrorUrl,
@@ -24,11 +24,11 @@ type PackageDetailsComponentProps = {
2424
pkgSplits: BriefPackageList;
2525
};
2626

27-
export default function PackageDetailsComponent({
27+
export default async function PackageDetailsComponent({
2828
pkg,
2929
pkgSplits,
3030
}: PackageDetailsComponentProps) {
31-
const sourceUrl = getSourceUrl(pkg);
31+
const sourceUrl = await getSourceUrl(pkg);
3232
return (
3333
<>
3434
<div className="mb-4">
@@ -226,14 +226,21 @@ function formatBytes(bytes: number, decimals = 2): string {
226226
return `${parseFloat((bytes / Math.pow(k, i)).toFixed(dm))} ${sizes[i]}`;
227227
}
228228

229-
function getSourceUrl(pkg: PackageDetails): null | string {
229+
async function getSourceUrl(pkg: PackageDetails): Promise<null | string> {
230230
const isRebuilded = ['-core-', '-extra-'].some(needle =>
231231
pkg.repo_name.includes(needle)
232232
);
233233

234-
const cachyosPath = cachyosPaths[pkg.pkg_name as keyof typeof cachyosPaths];
235-
if (!isRebuilded && cachyosPath) {
236-
return `https://github.com/CachyOS/CachyOS-PKGBUILDS/tree/master/${cachyosPath}`;
234+
let cachyosPaths: PkgbuildMap = {};
235+
try {
236+
cachyosPaths = await fetchPkgbuilds();
237+
} catch (error) {
238+
console.error('Failed to fetch CachyOS PKGBUILDS:', error);
239+
}
240+
241+
const pkgbuildPath = cachyosPaths[pkg.pkg_name];
242+
if (!isRebuilded && pkgbuildPath) {
243+
return `https://github.com/CachyOS/CachyOS-PKGBUILDS/tree/master/${pkgbuildPath}`;
237244
}
238245

239246
if (!isRebuilded || !pkg.pkg_base) {

src/lib/cachy.ts

Lines changed: 0 additions & 155 deletions
This file was deleted.

src/lib/github.ts

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
import {z} from 'zod';
2+
3+
const GitTreeItemSchema = z.object({
4+
mode: z.string(),
5+
path: z.string(),
6+
sha: z.string(),
7+
size: z.number().optional(),
8+
type: z.enum(['blob', 'tree', 'commit']),
9+
url: z.url(),
10+
});
11+
12+
const GitTreeResponseSchema = z.object({
13+
sha: z.string(),
14+
tree: z.array(GitTreeItemSchema),
15+
truncated: z.boolean(),
16+
url: z.url(),
17+
});
18+
19+
export type GitTreeResponse = z.infer<typeof GitTreeResponseSchema>;
20+
21+
/**
22+
* Maps package names to their relative PKGBUILD paths.
23+
* @example { "linux-cachyos": "linux-cachyos", "linux-api-headers": "toolchain/linux-api-headers" }
24+
*/
25+
export type PkgbuildMap = Record<string, string>;
26+
27+
export async function fetchPkgbuilds(
28+
params: {
29+
owner?: string;
30+
ref?: string;
31+
repo?: string;
32+
token?: string;
33+
} = {}
34+
): Promise<PkgbuildMap> {
35+
const {
36+
owner = 'CachyOS',
37+
ref = 'master',
38+
repo = 'CachyOS-PKGBUILDS',
39+
token = process.env.GITHUB_TOKEN,
40+
} = params;
41+
42+
const url = `https://api.github.com/repos/${encodeURIComponent(owner)}/${encodeURIComponent(
43+
repo
44+
)}/git/trees/${encodeURIComponent(ref)}?recursive=1`;
45+
46+
const res = await fetch(url, {
47+
headers: {
48+
Accept: 'application/vnd.github+json',
49+
'User-Agent': 'CachyOS/public-dashboard',
50+
'X-GitHub-Api-Version': '2022-11-28',
51+
...(token ? {Authorization: `Bearer ${token}`} : {}),
52+
},
53+
next: {revalidate: 3600},
54+
});
55+
56+
if (!res.ok) {
57+
const text = await res.text();
58+
throw new Error(
59+
`GitHub API error ${res.status}: ${text || res.statusText}`
60+
);
61+
}
62+
63+
const json = await res.json();
64+
const data = GitTreeResponseSchema.parse(json);
65+
66+
return data.tree
67+
.filter(node => node.path.endsWith('PKGBUILD'))
68+
.map(node => node.path.replace(/\/PKGBUILD$/, ''))
69+
.reduce((acc, path) => {
70+
acc[path.split('/').pop() ?? ''] = path;
71+
return acc;
72+
}, {} as PkgbuildMap);
73+
}

0 commit comments

Comments
 (0)