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)
13
14// Sync add/remove wasm package in global forge directory
15func (m *Manager) Sync(fileContent []byte) error {
16	errorHandler := oops.With("pluginsDataDir", m.conf.PathDataPlugin()).With("file", fileContent)
17	needReloadPlugins := false
18
19	plugins, err := ParsePlugins(fileContent, false)
20	if err != nil {
21		return oops.Wrapf(err, "can't parse plugins from sync")
22	}
23	entries, err := os.ReadDir(m.conf.PathDataPlugin())
24	if err != nil {
25		if os.IsNotExist(err) {
26			if err := os.MkdirAll(m.conf.PathDataPlugin(), os.ModePerm); err != nil {
27				return errorHandler.Wrapf(err, "can't create plugin directory")
28			}
29			entries = make([]fs.DirEntry, 0)
30		} else {
31			return errorHandler.Wrapf(err, "can't read directory")
32		}
33	}
34	for _, plugin := range plugins {
35		found := false
36		for _, e := range entries {
37			if e.Name() == plugin.Name {
38				found = true
39				if _, err := os.Stat(m.PathWasm(plugin)); err != nil {
40					needReloadPlugins = true
41					m.update(plugin)
42				}
43				break
44			}
45		}
46		if !found {
47			if err := m.add(plugin); err != nil {
48				return errorHandler.Wrap(err)
49			}
50			needReloadPlugins = true
51		}
52	}
53
54	for _, e := range entries {
55		found := false
56		for _, plugin := range plugins {
57			if e.Name() == plugin.Name {
58				found = true
59				break
60			}
61		}
62		if !found {
63			if err := os.Remove(m.conf.GetDirPathDataPlugin(e.Name())); err != nil {
64				return errorHandler.With("plugin", e.Name()).Wrapf(err, "can't delete plugin")
65			}
66			needReloadPlugins = true
67		}
68	}
69
70	if needReloadPlugins {
71		m.reloadPlugins()
72		//todo need to clean module of wazero
73	}
74
75	return nil
76}
77
78func (m *Manager) add(plugin Plugin) error {
79	if plugin.Name == "" {
80		plugin = plugin.DetermineNameAndVersionFromUrl()
81	}
82	if err := os.MkdirAll(m.conf.GetDirPathDataPlugin(plugin.Name), os.ModePerm); err != nil {
83		return oops.With("plugin", plugin.Name).Wrapf(err, "can't MkdirAll")
84	}
85	if err := m.Install(plugin); err != nil {
86		return oops.With("plugin", plugin.Url).Wrapf(err, "can't copy plugin")
87	}
88	return nil
89}
90
91func (m *Manager) update(plugin Plugin) error {
92	if err := m.Install(plugin); err != nil {
93		return oops.With("plugin", plugin.Url).Wrapf(err, "can't copy plugin for update")
94	}
95	return nil
96}