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	"encoding/json"
 12	"errors"
 13	"io/fs"
 14	"os"
 15	"runtime"
 16	"time"
 17)
 18
 19type PluginFactory = func(server Server) Plugin
 20
 21type Commit struct {
 22	Branch    string
 23	Hash      string
 24	Message   string
 25	Date      time.Time
 26	Committer string
 27}
 28
 29type Plugin interface {
 30	Init(repoName string, confHasChanged bool, serializedConf string) error
 31	StartCommit(commit Commit) error
 32	AddFile(path string) error
 33	ModFile(fromPath string, toPath string) error
 34	DelFile(path string) error
 35	EndCommit(commit Commit) error
 36	Finish() error
 37}
 38
 39type Server interface {
 40	Worktree() fs.FS
 41	Webcontent() fs.FS
 42	Cache() fs.FS
 43	ModifyContent(filepath, content string)
 44	ModifyWebContent(filepath, content string)
 45	ModifyCacheContent(filepath, content string)
 46	CommitAllIfNeeded(message string)
 47	DiffWithParent(hash string, oldFilepath string, newFilepath string) (string, error)
 48	Log(message string)
 49	LogError(message string, err error)
 50	Merge(from string, to string)
 51}
 52
 53type pServer struct {
 54	plugin           Plugin
 55	run              string
 56	atLeastOneChange bool
 57}
 58
 59var server = &pServer{
 60	atLeastOneChange: false,
 61}
 62
 63func Register(run []PluginRun, p PluginFactory) {
 64	if j, err := json.Marshal(run); err == nil {
 65		server.run = string(j)
 66	} else {
 67		server.LogError("can't marshal conf", err)
 68	}
 69	server.plugin = p(server)
 70}
 71
 72func (s *pServer) Worktree() fs.FS {
 73	return os.DirFS("/worktree")
 74}
 75
 76func (s *pServer) Webcontent() fs.FS {
 77	return os.DirFS("/webcontent")
 78}
 79
 80func (s *pServer) Cache() fs.FS {
 81	return os.DirFS("/cache")
 82}
 83
 84func (s *pServer) ModifyContent(filepath, content string) {
 85	s.atLeastOneChange = true
 86	ptr, size := stringToPtr(filepath)
 87	ptr2, size2 := stringToPtr(content)
 88	_modifyContent(ptr, size, ptr2, size2)
 89	runtime.KeepAlive(filepath)
 90	runtime.KeepAlive(content)
 91}
 92
 93func (s *pServer) ModifyWebContent(filepath, content string) {
 94	ptr, size := stringToPtr(filepath)
 95	ptr2, size2 := stringToPtr(content)
 96	_modifyWebContent(ptr, size, ptr2, size2)
 97	runtime.KeepAlive(filepath)
 98	runtime.KeepAlive(content)
 99}
100
101func (s *pServer) ModifyCacheContent(filepath, content string) {
102	ptr, size := stringToPtr(filepath)
103	ptr2, size2 := stringToPtr(content)
104	_modifyCacheContent(ptr, size, ptr2, size2)
105	runtime.KeepAlive(filepath)
106	runtime.KeepAlive(content)
107}
108
109func (s *pServer) CommitAllIfNeeded(message string) {
110	if s.atLeastOneChange {
111		ptr, size := stringToPtr(message)
112		_commitAll(ptr, size)
113		runtime.KeepAlive(message)
114	}
115}
116
117func (s *pServer) DiffWithParent(hash string, oldFilepath string, newFilePath string) (string, error) {
118	ptrHash, sizeHash := stringToPtr(hash)
119	ptrOldFile, sizeOldFile := stringToPtr(oldFilepath)
120	ptrNewFile, sizeNewFile := stringToPtr(newFilePath)
121	ptrSizeDiff := _diffWithParent(ptrHash, sizeHash, ptrOldFile, sizeOldFile, ptrNewFile, sizeNewFile)
122	if ptrSizeDiff == 0 {
123		return "", errors.New("can't make diff")
124	}
125	ptrDiff := uint32(ptrSizeDiff >> 32)
126	sizeDiff := uint32(ptrSizeDiff)
127	return ptrToString(ptrDiff, sizeDiff), nil
128}
129
130func (s *pServer) Log(message string) {
131	ptr, size := stringToPtr(message)
132	_log(ptr, size)
133	runtime.KeepAlive(message)
134}
135
136func (s *pServer) LogError(message string, err error) {
137	ptr, size := stringToPtr(message)
138	errPtr, errSize := stringToPtr(err.Error())
139	_logError(ptr, size, errPtr, errSize)
140	runtime.KeepAlive(message)
141	runtime.KeepAlive(err)
142}
143
144func (s *pServer) Merge(from string, to string) {
145	fromPtr, fromSize := stringToPtr(from)
146	toPtr, toSize := stringToPtr(to)
147	_merge(fromPtr, fromSize, toPtr, toSize)
148	runtime.KeepAlive(from)
149	runtime.KeepAlive(to)
150}