diff options
| author | Nicolas Paul <n@nc0.fr> | 2023-05-31 00:28:11 +0200 |
|---|---|---|
| committer | Nicolas Paul <n@nc0.fr> | 2023-05-31 00:28:11 +0200 |
| commit | 43be0e328a0e4c8c3d1ff88eb81b82402fcfa7c1 (patch) | |
| tree | 38245b6a8be1ff5b012ffe7986b8ee5d0b82f1f5 /pkg | |
| parent | 5c34ce83e56e8eb8649d8ce831d2cc1d6b5ca5be (diff) | |
Start implementing Starlark execution environment
Signed-off-by: Nicolas Paul <n@nc0.fr>
Diffstat (limited to 'pkg')
| -rw-r--r-- | pkg/config/starlark.go | 98 |
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 ®istered, 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 +} |
