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 "./src/fs";
  7import {
  8  _call,
  9  _canCall,
 10  _commitAll,
 11  _commits,
 12  _diffWithParent,
 13  _exec,
 14  _forgeConf,
 15  _log,
 16  _logError,
 17  _merge,
 18  _report,
 19} from "./src/imports";
 20import { Call } from "./src/model/call";
 21import { Commit } from "./src/model/commit";
 22import { Exec, ExecStatus } from "./src/model/exec";
 23import { ForgeConf } from "./src/model/forgeconf";
 24import { PluginRun } from "./src/model/pluginrun";
 25import { Report, ReportToGitroot } from "./src/model/report";
 26import { exportFuncCallback, Server } from "./src/model/server";
 27import { Plugin } from "./src/plugin";
 28
 29export * from "./src/index";
 30
 31export let __server: server | null = null;
 32
 33export function Register(
 34  run: Array<PluginRun>,
 35  p: (server: Server) => Plugin,
 36): void {
 37  const s = new server();
 38  s.plugin = p(s);
 39  s.run = run;
 40  __server = s;
 41}
 42
 43type ReporterCallback = (report: Report) => void;
 44
 45class PluginOption {
 46  constructor(public reporter: ReporterCallback) {}
 47}
 48
 49class server implements Server {
 50  private worktreeFS: FS = new FS(FsBaseWorktree);
 51  private webcontentFS: FS = new FS(FsBaseWebcontent);
 52  private cacheFS: FS = new FS(FsBaseCache);
 53  private exportedFuncs: Map<string, exportFuncCallback> = new Map<
 54    string,
 55    exportFuncCallback
 56  >();
 57
 58  plugin: Plugin | null = null;
 59  run: Array<PluginRun> = [];
 60  pluginOption: PluginOption | null = null;
 61
 62  addPluginOption(opt: PluginOption): void {
 63    this.pluginOption = opt;
 64  }
 65
 66  getExportedFuncs(name: string): exportFuncCallback {
 67    return this.exportedFuncs.get(name);
 68  }
 69
 70  forgeConf(): ForgeConf {
 71    const ptrSize = _forgeConf();
 72    const ptr = u32((ptrSize >> 32) & 0xffffffff);
 73    const size = u32(ptrSize & 0xffffffff);
 74    return JSON.parse<ForgeConf>(String.UTF8.decodeUnsafe(ptr, size));
 75  }
 76
 77  worktree(): FS {
 78    return this.worktreeFS;
 79  }
 80
 81  webcontent(): FS {
 82    return this.webcontentFS;
 83  }
 84
 85  cache(): FS {
 86    return this.cacheFS;
 87  }
 88
 89  commitAllIfNeeded(message: string): void {
 90    _commitAll(message);
 91  }
 92
 93  diffWithParent(
 94    hash: string,
 95    oldFilepath: string,
 96    newFilepath: string,
 97  ): string {
 98    const ptrSize = _diffWithParent(hash, oldFilepath, newFilepath);
 99    const ptr = u32((ptrSize >> 32) & 0xffffffff);
100    const size = u32(ptrSize & 0xffffffff);
101    return String.UTF8.decodeUnsafe(ptr, size);
102  }
103
104  merge(from: string, to: string): void {
105    _merge(from, to);
106  }
107
108  log(message: string): void {
109    _log(message);
110  }
111
112  logError(message: string, error: string): void {
113    _logError(message, error);
114  }
115
116  commits(from: string, to: string): Array<Commit> {
117    const ptrSize = _commits(from, to);
118    const ptr = u32((ptrSize >> 32) & 0xffffffff);
119    const size = u32(ptrSize & 0xffffffff);
120    return JSON.parse<Array<Commit>>(String.UTF8.decodeUnsafe(ptr, size));
121  }
122
123  exec(exec: Exec): ExecStatus {
124    const execJson = JSON.stringify(exec);
125    const ptrSize = _exec(execJson);
126    const ptr = u32((ptrSize >> 32) & 0xffffffff);
127    const size = u32(ptrSize & 0xffffffff);
128    return JSON.parse<ExecStatus>(String.UTF8.decodeUnsafe(ptr, size));
129  }
130
131  report(level: string, content: Array<string>): void {
132    const reportMarshalled = JSON.stringify(
133      new ReportToGitroot(level, content),
134    );
135    _report(reportMarshalled);
136  }
137
138  reportToPlugin(report: Report): void {
139    if (this.pluginOption != null) {
140      this.pluginOption!.reporter(report);
141    }
142  }
143
144  exportFunc(name: string, callback: exportFuncCallback): void {
145    this.exportedFuncs.set(name, callback);
146  }
147
148  canCallFunc(plugin: string, name: string, args: Map<string, string>): bool {
149    const call = new Call(plugin, name, args);
150    const callJson = JSON.stringify(call);
151    return _canCall(callJson) != 0;
152  }
153
154  callFunc(
155    plugin: string,
156    name: string,
157    args: Map<string, string>,
158  ): ExecStatus {
159    const call = new Call(plugin, name, args);
160    const callJson = JSON.stringify(call);
161    const ptrSize = _call(callJson);
162    const ptrRes = u32(ptrSize >> 32);
163    const sizeRes = u32(ptrSize);
164    return JSON.parse<ExecStatus>(String.UTF8.decodeUnsafe(ptrRes, sizeRes));
165  }
166}