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
  5package gitroot
  6
  7// #include <stdlib.h>
  8import "C"
  9
 10import (
 11	"errors"
 12	"io/fs"
 13	"os"
 14	"runtime"
 15
 16	"github.com/tidwall/gjson"
 17	"gitroot.dev/libs/golang/plugin/model"
 18)
 19
 20type PluginFactory = func(server model.Server) model.Plugin
 21
 22type pServer struct {
 23	plugin           model.Plugin
 24	run              []model.PluginRun
 25	atLeastOneChange bool
 26}
 27
 28var server = &pServer{
 29	atLeastOneChange: false,
 30}
 31
 32func Register(run []model.PluginRun, p PluginFactory) {
 33	server.run = run
 34	server.plugin = p(server)
 35}
 36
 37func (s *pServer) ForgeConf() (model.ForgeConf, error) {
 38	forgeConf := model.ForgeConf{}
 39	ptrSize := _forgeConf()
 40	if ptrSize == 0 {
 41		return forgeConf, errors.New("can't make diff")
 42	}
 43	ptrDiff := uint32(ptrSize >> 32)
 44	sizeDiff := uint32(ptrSize)
 45	forgeConfJson := gjson.Parse(ptrToString(ptrDiff, sizeDiff))
 46	return model.ForgeConf{
 47		Domain: forgeConfJson.Get("domain").String(),
 48	}, nil
 49}
 50
 51func (s *pServer) Worktree() fs.FS {
 52	return os.DirFS("/worktree")
 53}
 54
 55func (s *pServer) Webcontent() fs.FS {
 56	return os.DirFS("/webcontent")
 57}
 58
 59func (s *pServer) Cache() fs.FS {
 60	return os.DirFS("/cache")
 61}
 62
 63func (s *pServer) ModifyContent(filepath, content string) {
 64	s.atLeastOneChange = true
 65	ptr, size := stringToPtr(filepath)
 66	ptr2, size2 := stringToPtr(content)
 67	_modifyContent(ptr, size, ptr2, size2)
 68	runtime.KeepAlive(filepath)
 69	runtime.KeepAlive(content)
 70}
 71
 72func (s *pServer) ModifyWebContent(filepath, content string) {
 73	ptr, size := stringToPtr(filepath)
 74	ptr2, size2 := stringToPtr(content)
 75	_modifyWebContent(ptr, size, ptr2, size2)
 76	runtime.KeepAlive(filepath)
 77	runtime.KeepAlive(content)
 78}
 79
 80func (s *pServer) ReplaceWebContent(filepath, oldContent, content string) {
 81	ptr, size := stringToPtr(filepath)
 82	ptr2, size2 := stringToPtr(oldContent)
 83	ptr3, size3 := stringToPtr(content)
 84	_replaceWebContent(ptr, size, ptr2, size2, ptr3, size3)
 85	runtime.KeepAlive(filepath)
 86	runtime.KeepAlive(oldContent)
 87	runtime.KeepAlive(content)
 88}
 89
 90func (s *pServer) ModifyCacheContent(filepath, content string) {
 91	ptr, size := stringToPtr(filepath)
 92	ptr2, size2 := stringToPtr(content)
 93	_modifyCacheContent(ptr, size, ptr2, size2)
 94	runtime.KeepAlive(filepath)
 95	runtime.KeepAlive(content)
 96}
 97
 98func (s *pServer) CommitAllIfNeeded(message string) {
 99	if s.atLeastOneChange {
100		ptr, size := stringToPtr(message)
101		_commitAll(ptr, size)
102		runtime.KeepAlive(message)
103	}
104}
105
106func (s *pServer) DiffWithParent(hash string, oldFilepath string, newFilePath string) (string, error) {
107	ptrHash, sizeHash := stringToPtr(hash)
108	ptrOldFile, sizeOldFile := stringToPtr(oldFilepath)
109	ptrNewFile, sizeNewFile := stringToPtr(newFilePath)
110	ptrSizeDiff := _diffWithParent(ptrHash, sizeHash, ptrOldFile, sizeOldFile, ptrNewFile, sizeNewFile)
111	if ptrSizeDiff == 0 {
112		return "", errors.New("can't make diff")
113	}
114	ptrDiff := uint32(ptrSizeDiff >> 32)
115	sizeDiff := uint32(ptrSizeDiff)
116	return ptrToString(ptrDiff, sizeDiff), nil
117}
118
119func (s *pServer) Log(message string) {
120	ptr, size := stringToPtr(message)
121	_log(ptr, size)
122	runtime.KeepAlive(message)
123}
124
125func (s *pServer) LogError(message string, err error) {
126	ptr, size := stringToPtr(message)
127	errPtr, errSize := stringToPtr(err.Error())
128	_logError(ptr, size, errPtr, errSize)
129	runtime.KeepAlive(message)
130	runtime.KeepAlive(err)
131}
132
133func (s *pServer) Merge(from string, to string) {
134	fromPtr, fromSize := stringToPtr(from)
135	toPtr, toSize := stringToPtr(to)
136	_merge(fromPtr, fromSize, toPtr, toSize)
137	runtime.KeepAlive(from)
138	runtime.KeepAlive(to)
139}
140
141func (s *pServer) Commits(from string, to string) ([]model.Commit, error) {
142	fromPtr, fromSize := stringToPtr(from)
143	toPtr, toSize := stringToPtr(to)
144	ptrSizeDiff := _commits(fromPtr, fromSize, toPtr, toSize)
145	runtime.KeepAlive(from)
146	runtime.KeepAlive(to)
147	if ptrSizeDiff == 0 {
148		return nil, errors.New("can't get commits")
149	}
150	ptrDiff := uint32(ptrSizeDiff >> 32)
151	sizeDiff := uint32(ptrSizeDiff)
152	return model.CommitsFromString(ptrToString(ptrDiff, sizeDiff)), nil
153}