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}