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}