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.logger.Debug("finish plugin conf", logger.NewLoggerPair("name", plugin.Name))
40	return conf, err
41}
42
43func (r *runtime) callPluginForConf(ctx context.Context, module api.Module, log *logger.Logger) (*pluginLib.ConfPlugin, error) {
44	defaultConf := &pluginLib.ConfPlugin{}
45
46	if pluginConf := module.ExportedFunction("pluginConf"); pluginConf != nil {
47		ptrSizeArr, err := pluginConf.Call(ctx)
48		if err != nil {
49			return nil, oops.Wrapf(err, "pluginConf call")
50		}
51		pluginConfPtr := uint32(ptrSizeArr[0] >> 32)
52		pluginConfSize := uint32(ptrSizeArr[0])
53		if pluginConfPtr != 0 {
54			defer func() {
55				r.free(module, []ptrSize{{ptr: uint64(pluginConfPtr), size: uint64(pluginConfSize)}})
56			}()
57		}
58		res, err := r.readString(module, "read memory conf", pluginConfPtr, pluginConfSize)
59		if err != nil {
60			return nil, oops.Wrapf(err, "can't read memory")
61		}
62		if res != "" {
63			log.Debug(fmt.Sprintf("res conf %s", res))
64			if err = json.Unmarshal([]byte(res), &defaultConf); err != nil {
65				log.Debug("Conf receive from guest tinygo", logger.NewLoggerPair("err", err.Error()), logger.NewLoggerPair("json", res))
66				conf, err := r.readASString(module, "read conf", uint32(ptrSizeArr[0]))
67				if err != nil {
68					return nil, oops.Wrapf(err, "can't readASString Configuration")
69				}
70				log.Debug("Conf receive from guest AS", logger.NewLoggerPair("json", conf))
71				if err = json.Unmarshal([]byte(conf), &defaultConf); err != nil {
72					return nil, oops.Wrapf(err, "can't unmarshal Configuration")
73				}
74			}
75		}
76	} else {
77		log.Info("plugin has no pluginConf exported function")
78	}
79	for name := range module.ExportedFunctionDefinitions() {
80		log.Info(fmt.Sprintf("plugin has %s function", name))
81	}
82	return defaultConf, nil
83}