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