GitRoot
craft your forge, build your project, grow your community freely
1// SPDX-FileCopyrightText: 2025 Romain Maneschi <romain@gitroot.dev>
2//
3// SPDX-License-Identifier: MIT
4
5import { Date } from "date";
6import { JSON } from "json-as";
7import { FS } from "./fs";
8import { PluginRun } from "./plugin";
9
10export * from "./plugin";
11
12@json
13export class ForgeConf {
14 constructor(public domain: string){}
15}
16
17export class Commit {
18 constructor(public branch: string, public hash: string, public message: string, public date: Date, public committer: string) {}
19
20 static build(
21 branch: string,
22 hash: string,
23 message: string,
24 date: Date,
25 committer: string
26 ): Commit {
27 return new Commit(branch, hash, message, date, committer);
28 }
29}
30
31export interface Plugin {
32 init(repoName: string, confHasChanged: boolean, conf: string): void;
33 startCommit(commit: Commit): void;
34 addFile(path: string): void;
35 modFile(fromPath: string, toPath: string): void;
36 delFile(path: string): void;
37 endCommit(commit: Commit): void;
38 finish(): void;
39}
40
41export let __server: Server | null = null;
42
43export class Server {
44 private atLeastOneChange: bool = true;
45 private worktreeFS: FS = new FS("/worktree");
46 private webcontentFS: FS = new FS("/webcontent");
47 private cacheFS: FS = new FS("/cache");
48
49 plugin: Plugin | null = null;
50 run: string = "[]";
51
52 static Register(run: Array<PluginRun>, p: (server: Server) => Plugin): void {
53 const s = new Server();
54 s.plugin = p(s);
55 s.run = JSON.stringify<Array<PluginRun>>(run);
56 __server = s;
57 }
58
59 forgeConf(): ForgeConf {
60 // TODO need issues/a716-conf-external-addr.md to work
61 const ptrSize = _forgeConf();
62 const ptr = u32((ptrSize >> 32) & 0xFFFFFFFF);
63 const size = u32(ptrSize & 0xFFFFFFFF);
64 return JSON.parse<ForgeConf>(String.UTF8.decodeUnsafe(ptr, size));
65 }
66
67 worktree(): FS {
68 return this.worktreeFS;
69 }
70
71 webcontent(): FS {
72 return this.webcontentFS;
73 }
74
75 cache(): FS {
76 return this.cacheFS;
77 }
78
79 modifyContent(filepath: string, content: string): void {
80 this.atLeastOneChange = true;
81 _modifyContent(filepath, content);
82 }
83
84 modifyWebContent(filepath: string, content: string): void {
85 _modifyWebContent(filepath, content);
86 }
87
88 replaceWebContent(filepath: string, oldContent: string, content: string): void {
89 _replaceWebContent(filepath, oldContent, content);
90 }
91
92 modifyCacheContent(filepath: string, content: string): void {
93 _modifyCacheContent(filepath, content);
94 }
95
96 commitAllIfNeeded(message: string): void {
97 if (this.atLeastOneChange) {
98 _commitAll(message);
99 }
100 }
101
102 diffWithParent(hash: string, oldFilepath: string, newFilepath: string): string {
103 const ptrSize = _diffWithParent(hash, oldFilepath, newFilepath);
104 const ptr = u32((ptrSize >> 32) & 0xFFFFFFFF);
105 const size = u32(ptrSize & 0xFFFFFFFF);
106 return String.UTF8.decodeUnsafe(ptr, size);
107 }
108
109 merge(from: string, to: string): void {
110 _merge(from, to);
111 }
112
113 log(message: string): void {
114 _log(message);
115 }
116
117 logError(message: string, error: string): void {
118 _logError(message, error);
119 }
120}
121
122/*
123 * WASI imports part
124 */
125
126@external("gitroot", "forgeConf")
127declare function _forgeConf(): i64
128
129@external("gitroot", "modifyContentAS")
130declare function _modifyContent(filepath: string, content: string): void
131
132@external("gitroot", "modifyWebContentAS")
133declare function _modifyWebContent(filepath: string, content: string): void
134
135@external("gitroot", "replaceWebContentAS")
136declare function _replaceWebContent(filepath: string, oldContent: string, content: string): void
137
138@external("gitroot", "modifyCacheContentAS")
139declare function _modifyCacheContent(filepath: string, content: string): void
140
141@external("gitroot", "commitAllAS")
142declare function _commitAll(message: string): void
143
144@external("gitroot", "diffWithParentAS")
145declare function _diffWithParent(hash: string, oldFilepath: string, newFilepath: string): i64
146
147@external("gitroot", "logAS")
148declare function _log(message: string): void
149
150@external("gitroot", "logErrorAS")
151declare function _logError(message: string, error: string): void
152
153@external("gitroot", "mergeAS")
154declare function _merge(from: string, to: string): void