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 for _, plugin := range plugins {
36 found := false
37 for _, e := range entries {
38 if e.Name() == plugin.Name {
39 found = true
40 m.logger.Debug("check that plugin is downloaded", logger.NewLoggerPair("name", plugin.Name), logger.NewLoggerPair("path", m.PathWasm(plugin)))
41 if _, err := os.Stat(m.PathWasm(plugin)); err != nil {
42 needReloadPlugins = true
43 if err := m.update(plugin); err != nil {
44 m.logger.Error("can't update", err, logger.NewLoggerPair("name", plugin.Name), logger.NewLoggerPair("url", plugin.Url))
45 }
46 }
47 break
48 }
49 }
50 if !found {
51 if err := m.add(plugin); err != nil {
52 m.logger.Error("can't add", err, logger.NewLoggerPair("name", plugin.Name), logger.NewLoggerPair("url", plugin.Url))
53 continue
54 }
55 needReloadPlugins = true
56 }
57 }
58
59 for _, e := range entries {
60 found := false
61 for _, plugin := range plugins {
62 if e.Name() == plugin.Name {
63 found = true
64 break
65 }
66 }
67 if !found {
68 if err := os.Remove(m.conf.GetDirPathDataPlugin(e.Name())); err != nil {
69 m.logger.Error("can't delete", err, logger.NewLoggerPair("name", e.Name()))
70 continue
71 }
72 needReloadPlugins = true
73 }
74 }
75
76 if needReloadPlugins {
77 m.reloadPlugins()
78 //todo need to clean module of wazero
79 }
80
81 return nil
82}
83
84func (m *Manager) add(plugin Plugin) error {
85 if plugin.Name == "" {
86 plugin = plugin.DetermineNameAndVersionFromUrl()
87 }
88 if err := os.MkdirAll(m.conf.GetDirPathDataPlugin(plugin.Name), os.ModePerm); err != nil {
89 return oops.With("plugin", plugin.Name).Wrapf(err, "can't MkdirAll")
90 }
91 if err := m.Install(plugin); err != nil {
92 return oops.With("plugin", plugin.Url).Wrapf(err, "can't copy plugin")
93 }
94 return nil
95}
96
97func (m *Manager) update(plugin Plugin) error {
98 if err := m.Install(plugin); err != nil {
99 return oops.With("plugin", plugin.Url).Wrapf(err, "can't copy plugin for update")
100 }
101 return nil
102}