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