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 { JSON } from "json-as";
6import { FS, FsBaseCache, FsBaseWebcontent, FsBaseWorktree } from "./fs";
7import {
8 _call,
9 _can_call,
10 _commitAll,
11 _commits,
12 _diffWithParent,
13 _exec,
14 _forgeConf,
15 _log,
16 _logError,
17 _merge,
18 _modifyCacheContent,
19 _modifyContent,
20 _modifyWebContent,
21 _replaceWebContent,
22 _report,
23} from "./imports";
24import { Call } from "./model/call";
25import { Commit, CommitStr } from "./model/commit";
26import { Exec, ExecStatus } from "./model/exec";
27import { ForgeConf } from "./model/forgeconf";
28import { Plugin } from "./model/plugin";
29import { PluginRun } from "./model/pluginrun";
30import { exportFuncCallback, Server } from "./model/server";
31import { ReportToGitroot } from "./server";
32
33export * from "./model/index";
34
35export let __server: server | null = null;
36
37export const Register = function (
38 run: Array<PluginRun>,
39 p: (server: Server) => Plugin,
40): void {
41 const s = new server();
42 s.plugin = p(s);
43 s.run = run;
44 __server = s;
45};
46
47class server implements Server {
48 private atLeastOneChange: bool = true;
49 private worktreeFS: FS = new FS(FsBaseWorktree);
50 private webcontentFS: FS = new FS(FsBaseWebcontent);
51 private cacheFS: FS = new FS(FsBaseCache);
52 private exportedFuncs: Map<string, exportFuncCallback> = new Map<
53 string,
54 exportFuncCallback
55 >();
56
57 plugin: Plugin | null = null;
58 run: Array<PluginRun> = [];
59
60 forgeConf(): ForgeConf {
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 // @deprecated use worktree().writeContent
80 modifyContent(filepath: string, content: string): void {
81 this.atLeastOneChange = true;
82 _modifyContent(filepath, content);
83 }
84
85 // @deprecated use webcontent().writeContent
86 modifyWebContent(filepath: string, content: string): void {
87 _modifyWebContent(filepath, content);
88 }
89
90 // @deprecated use webcontent().replaceContent
91 replaceWebContent(
92 filepath: string,
93 oldContent: string,
94 content: string,
95 ): void {
96 _replaceWebContent(filepath, oldContent, content);
97 }
98
99 // @deprecated use cache().writeContent
100 modifyCacheContent(filepath: string, content: string): void {
101 _modifyCacheContent(filepath, content);
102 }
103
104 commitAllIfNeeded(message: string): void {
105 if (this.atLeastOneChange) {
106 _commitAll(message);
107 }
108 }
109
110 diffWithParent(
111 hash: string,
112 oldFilepath: string,
113 newFilepath: string,
114 ): string {
115 const ptrSize = _diffWithParent(hash, oldFilepath, newFilepath);
116 const ptr = u32((ptrSize >> 32) & 0xffffffff);
117 const size = u32(ptrSize & 0xffffffff);
118 return String.UTF8.decodeUnsafe(ptr, size);
119 }
120
121 merge(from: string, to: string): void {
122 _merge(from, to);
123 }
124
125 log(message: string): void {
126 _log(message);
127 }
128
129 logError(message: string, error: string): void {
130 _logError(message, error);
131 }
132
133 commits(from: string, to: string): Array<Commit> {
134 const ptrSize = _commits(from, to);
135 const ptr = u32((ptrSize >> 32) & 0xffffffff);
136 const size = u32(ptrSize & 0xffffffff);
137 const commits = JSON.parse<Array<CommitStr>>(
138 String.UTF8.decodeUnsafe(ptr, size),
139 );
140 return commits.map((c) => c.toCommit());
141 }
142
143 exec(exec: Exec): ExecStatus {
144 const execJson = JSON.stringify(exec);
145 const ptrSize = _exec(execJson);
146 const ptr = u32((ptrSize >> 32) & 0xffffffff);
147 const size = u32(ptrSize & 0xffffffff);
148 return JSON.parse<ExecStatus>(String.UTF8.decodeUnsafe(ptr, size));
149 }
150
151 report(level: string, content: Array<string>): void {
152 const reportMarshalled = JSON.stringify(
153 new ReportToGitroot(level, content),
154 );
155 _report(reportMarshalled);
156 }
157
158 exportFunc(name: string, callback: exportFuncCallback): void {
159 this.exportedFuncs.set(name, callback);
160 }
161
162 canCallFunc(plugin: string, name: string, args: Map<string, string>): bool {
163 const call = new Call(plugin, name, args);
164 const callJson = JSON.stringify(call);
165 return _can_call(callJson) != 0;
166 }
167
168 callFunc(
169 plugin: string,
170 name: string,
171 args: Map<string, string>,
172 ): ExecStatus {
173 const call = new Call(plugin, name, args);
174 const callJson = JSON.stringify(call);
175 const ptrSize = _call(callJson);
176 const ptrRes = u32(ptrSize >> 32);
177 const sizeRes = u32(ptrSize);
178 return JSON.parse<ExecStatus>(String.UTF8.decodeUnsafe(ptrRes, sizeRes));
179 }
180}