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	"context"
 9	"encoding/json"
10	"fmt"
11
12	"github.com/samber/oops"
13	"github.com/tetratelabs/wazero/api"
14	pluginLib "gitroot.dev/libs/golang/plugin/model"
15	"gitroot.dev/server/logger"
16)
17
18func (r *runtime) conf(ctx context.Context, plugin Plugin) (*pluginLib.ConfPlugin, error) {
19	r.repo = nil
20	r.plugin = plugin
21	r.command = nil
22	timerStop := r.logger.Time(fmt.Sprintf("Timer %s", plugin.Name))
23	defer timerStop()
24
25	r.logger.Debug("start plugin conf", logger.NewLoggerPair("name", plugin.Name))
26
27	m, err := r.loadModule(ctx, plugin, nil) //no fs for conf
28	if err != nil {
29		r.logger.Error("loadModule for conf error", err, logger.NewLoggerPair("name", plugin.Name))
30		return nil, err
31	}
32	defer r.garbage()
33
34	conf, err := r.callPluginForConf(ctx, m, r.logger.NewSubLogger(plugin.Name))
35	if err != nil {
36		r.logger.Error("finish plugin conf with error", err, logger.NewLoggerPair("name", plugin.Name))
37	}
38
39	r.garbageMemory(m)
40
41	r.logger.Debug("finish plugin conf", logger.NewLoggerPair("name", plugin.Name))
42	return conf, err
43}
44
45func (r *runtime) callPluginForConf(ctx context.Context, module api.Module, log *logger.Logger) (*pluginLib.ConfPlugin, error) {
46	defaultConf := &pluginLib.ConfPlugin{}
47
48	if pluginConf := module.ExportedFunction("pluginConf"); pluginConf != nil {
49		ptrSizeArr, err := pluginConf.Call(ctx)
50		if err != nil {
51			return nil, oops.Wrapf(err, "pluginConf call")
52		}
53		pluginConfPtr := uint32(ptrSizeArr[0] >> 32)
54		pluginConfSize := uint32(ptrSizeArr[0])
55		if pluginConfPtr != 0 {
56			defer func() {
57				r.free(module, []ptrSize{{ptr: uint64(pluginConfPtr), size: uint64(pluginConfSize)}})
58			}()
59		}
60		res, err := r.readString(module, "read memory conf", pluginConfPtr, pluginConfSize)
61		if err != nil {
62			return nil, oops.Wrapf(err, "can't read memory")
63		}
64		if res != "" {
65			log.Debug(fmt.Sprintf("res conf %s", res))
66			if err = json.Unmarshal([]byte(res), &defaultConf); err != nil {
67				log.Debug("Conf receive from guest tinygo", logger.NewLoggerPair("err", err.Error()), logger.NewLoggerPair("json", res))
68				conf, err := r.readASString(module, "read conf", uint32(ptrSizeArr[0]))
69				if err != nil {
70					return nil, oops.Wrapf(err, "can't readASString Configuration")
71				}
72				log.Debug("Conf receive from guest AS", logger.NewLoggerPair("json", conf))
73				if err = json.Unmarshal([]byte(conf), &defaultConf); err != nil {
74					return nil, oops.Wrapf(err, "can't unmarshal Configuration")
75				}
76			}
77		}
78	} else {
79		log.Info("plugin has no pluginConf exported function")
80	}
81	for name := range module.ExportedFunctionDefinitions() {
82		log.Info(fmt.Sprintf("plugin has %s function", name))
83	}
84	return defaultConf, nil
85}