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}