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: EUPL-1.2
4
5package plugin
6
7import (
8 "io/fs"
9 "os"
10
11 "github.com/samber/oops"
12 "gitroot.dev/server/logger"
13)
14
15// Sync add/remove wasm package in global forge directory
16func (m *Manager) Sync(fileContent []byte) error {
17 errorHandler := oops.With("pluginsDataDir", m.conf.PathDataPlugin()).With("file", fileContent)
18 needReloadPlugins := false
19
20 plugins, err := ParsePlugins(fileContent, false)
21 if err != nil {
22 return oops.Wrapf(err, "can't parse plugins from sync")
23 }
24 entries, err := os.ReadDir(m.conf.PathDataPlugin())
25 if err != nil {
26 if os.IsNotExist(err) {
27 if err := os.MkdirAll(m.conf.PathDataPlugin(), os.ModePerm); err != nil {
28 return errorHandler.Wrapf(err, "can't create plugin directory")
29 }
30 entries = make([]fs.DirEntry, 0)
31 } else {
32 return errorHandler.Wrapf(err, "can't read directory")
33 }
34 }
35 entriesName := make([]string, len(entries))
36 for i, e := range entries {
37 entriesName[i] = e.Name()
38 }
39
40 m.logger.Debug("start sync plugins in root repo", logger.NewLoggerPairNamedSlice("plugins", plugins), logger.NewLoggerPair("directories", entriesName))
41
42 for _, plugin := range plugins {
43 found := false
44 for _, e := range entriesName {
45 if e == plugin.Directory() {
46 found = true
47 m.logger.Debug("check that plugin is downloaded", logger.NewLoggerPair("plugin", plugin.Log()), logger.NewLoggerPair("path", m.PathWasm(plugin)))
48 if _, err := os.Stat(m.PathWasm(plugin)); err != nil {
49 needReloadPlugins = true
50 if err := m.update(plugin); err != nil {
51 m.logger.Error("can't update", err, logger.NewLoggerPair("plugin", plugin.Log()))
52 }
53 }
54 break
55 }
56 }
57 if !found {
58 if err := m.add(plugin); err != nil {
59 m.logger.Error("can't add", err, logger.NewLoggerPair("plugin", plugin.Log()))
60 continue
61 }
62 needReloadPlugins = true
63 }
64 }
65
66 for _, e := range entriesName {
67 found := false
68 for _, plugin := range plugins {
69 if e == plugin.Directory() {
70 found = true
71 break
72 }
73 }
74 if !found {
75 if err := os.Remove(m.conf.GetDirPathDataPlugin(e)); err != nil {
76 m.logger.Error("can't delete", err, logger.NewLoggerPair("name", e))
77 continue
78 }
79 needReloadPlugins = true
80 }
81 }
82
83 if needReloadPlugins {
84 m.logger.Info("need reload plugin")
85 m.reloadPlugins()
86 //todo need to clean module of wazero
87 }
88
89 return nil
90}
91
92func (m *Manager) add(plugin Plugin) error {
93 if err := os.MkdirAll(m.conf.GetDirPathDataPlugin(plugin.Directory()), os.ModePerm); err != nil {
94 return oops.With("plugin", plugin.Log()).Wrapf(err, "can't MkdirAll")
95 }
96 if err := m.Install(plugin); err != nil {
97 return oops.With("plugin", plugin.Log()).Wrapf(err, "can't copy plugin")
98 }
99 return nil
100}
101
102func (m *Manager) update(plugin Plugin) error {
103 if err := m.Install(plugin); err != nil {
104 return oops.With("plugin", plugin.Log()).Wrapf(err, "can't copy plugin for update")
105 }
106 return nil
107}