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