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}