github.com/tilt-dev/tilt@v0.33.15-0.20240515162809-0a22ed45d8a0/internal/tiltfile/loaddynamic/load.go (about) 1 package loaddynamic 2 3 import ( 4 "go.starlark.net/starlark" 5 6 "github.com/tilt-dev/tilt/internal/tiltfile/starkit" 7 "github.com/tilt-dev/tilt/internal/tiltfile/value" 8 ) 9 10 // Implements the load_dynamic() built-in. 11 // 12 // Most programming languages only support static import - where the module 13 // being loaded and the local variables being bound must be determinable at 14 // compile-time (i.e., without executing the code). 15 // 16 // Dynamic import tends to be fairly contentious. Here's a good discussion on the topic: 17 // 18 // https://github.com/tc39/proposal-dynamic-import 19 // 20 // (TC39 - the JavaScript committee - is a generally good resource for 21 // programming language theory discussion, because there are so many open-source 22 // implementations of the core language.) 23 // 24 // load_dynamic() provides a dynamic import, with semantics similar to nodejs 25 // require(), where it returns a dictionary of symbols that can be introspected 26 // on. It does no binding of local variables. 27 type LoadDynamicFn struct { 28 } 29 30 func NewPlugin() LoadDynamicFn { 31 return LoadDynamicFn{} 32 } 33 34 func (LoadDynamicFn) OnStart(e *starkit.Environment) error { 35 return e.AddBuiltin("load_dynamic", loadDynamic) 36 } 37 38 func loadDynamic(t *starlark.Thread, fn *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) { 39 var p value.Stringable 40 err := starkit.UnpackArgs(t, fn.Name(), args, kwargs, "path", &p) 41 if err != nil { 42 return nil, err 43 } 44 45 module, err := t.Load(t, p.Value) 46 if err != nil { 47 return nil, err 48 } 49 50 dict := starlark.NewDict(len(module)) 51 for key, val := range module { 52 err = dict.SetKey(starlark.String(key), val) 53 if err != nil { 54 return nil, err 55 } 56 } 57 dict.Freeze() 58 return dict, err 59 }