summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNicolas Paul <n@nc0.fr>2023-05-31 00:28:11 +0200
committerNicolas Paul <n@nc0.fr>2023-05-31 00:28:11 +0200
commit43be0e328a0e4c8c3d1ff88eb81b82402fcfa7c1 (patch)
tree38245b6a8be1ff5b012ffe7986b8ee5d0b82f1f5
parent5c34ce83e56e8eb8649d8ce831d2cc1d6b5ca5be (diff)
Start implementing Starlark execution environment
Signed-off-by: Nicolas Paul <n@nc0.fr>
-rw-r--r--pkg/config/starlark.go98
1 files changed, 98 insertions, 0 deletions
diff --git a/pkg/config/starlark.go b/pkg/config/starlark.go
new file mode 100644
index 0000000..39adcf9
--- /dev/null
+++ b/pkg/config/starlark.go
@@ -0,0 +1,98 @@
+package config
+
+import (
+ "fmt"
+ "go.nc0.fr/svgu/pkg/types"
+ "go.starlark.net/starlark"
+)
+
+var registered types.Index
+
+// ExecConfig configures the Starlark environment and executes the given
+// configuration file "fl".
+// The function returns a list of registered modules, or an error if something
+// went wrong.
+func ExecConfig(fl string) (*types.Index, error) {
+ th := &starlark.Thread{
+ Name: "exec " + fl,
+ Load: load,
+ }
+
+ // TODO(nc0): add built-ins
+ env := starlark.StringDict{
+ "index": starlark.NewBuiltin("index", InternIndex),
+ "module": starlark.NewBuiltin("module", InternModule),
+ }
+
+ registered = types.Index{}
+ if _, err := starlark.ExecFile(th, fl, nil, env); err != nil {
+ return &types.Index{}, err
+ }
+
+ return &registered, nil
+}
+
+// load loads a module from the given path.
+func load(t *starlark.Thread, module string) (starlark.StringDict, error) {
+ switch module {
+ // todo: add libs
+ }
+
+ return nil, fmt.Errorf("unknown module %q", module)
+}
+
+// Injected built-ins.
+
+// InternIndex represents the built-in function "index".
+// index(domain) initializes a new index with the given domain.
+func InternIndex(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple,
+ kwargs []starlark.Tuple) (starlark.Value, error) {
+ var domain string
+ if err := starlark.UnpackArgs("index", args, kwargs,
+ "domain", &domain); err != nil {
+ return nil, err
+ }
+
+ registered.SetDomain(domain)
+
+ return starlark.None, nil
+}
+
+// InternModule represents the built-in function "module".
+// module(name, vcs, repo, dir=None, file=None) registers a new module into the
+// index.
+func InternModule(_ *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple,
+ kwargs []starlark.Tuple) (starlark.Value, error) {
+
+ var name, vcs, repo, dir, file string
+ if err := starlark.UnpackArgs("module", args, kwargs, "name",
+ &name, "vcs", &vcs, "repo", &repo, "dir?", &dir, "file?", &file); err != nil {
+ return nil, err
+ }
+
+ var v types.Vcs
+ switch vcs {
+ case "git":
+ v = types.VcsGit
+ case "hg":
+ v = types.VcsMercurial
+ case "svn":
+ v = types.VcsSubversion
+ case "fossil":
+ v = types.VcsFossil
+ case "bzr":
+ v = types.VcsBazaar
+ default:
+ return nil, fmt.Errorf("unknown vcs %q", vcs)
+ }
+
+ registered.AddModule(name, types.Module{
+ Path: name,
+ Vcs: v,
+ Repo: repo,
+ Dir: dir,
+ File: file,
+ })
+
+ return starlark.None, nil
+}