diff --git a/ucl/inst_test.go b/ucl/inst_test.go index 06c60a0..7a9149a 100644 --- a/ucl/inst_test.go +++ b/ucl/inst_test.go @@ -174,6 +174,20 @@ func TestInst_Eval_WithSubEnv(t *testing.T) { want1: "hello", want2: "world", }, + { + descr: "exporting procs 1", + eval1: `export say_hello { "hello" } ; hook { say_hello }`, + eval2: `hook { say_hello }`, + want1: "hello", + want2: "hello", + }, + { + descr: "exporting procs 2", + eval1: `$a = "hello" ; export say_hello { $a = "world"; $a } ; hook { say_hello }`, + eval2: `$a = "other" ; hook { say_hello }`, + want1: "world", + want2: "world", + }, } for _, tt := range tests { @@ -193,6 +207,19 @@ func TestInst_Eval_WithSubEnv(t *testing.T) { return nil, nil }) + inst.SetBuiltin("export", func(ctx context.Context, args ucl.CallArgs) (any, error) { + var ( + name string + hookProc ucl.Invokable + ) + + if err := args.Bind(&name, &hookProc); err != nil { + return nil, err + } + inst.SetBuiltinInvokable(name, hookProc) + + return nil, nil + }) res, err := inst.Eval(ctx, strings.NewReader(tt.eval1), ucl.WithSubEnv()) assert.NoError(t, err) diff --git a/ucl/userbuiltin.go b/ucl/userbuiltin.go index 7058b0e..83d72d6 100644 --- a/ucl/userbuiltin.go +++ b/ucl/userbuiltin.go @@ -81,6 +81,10 @@ func (inst *Inst) SetBuiltin(name string, fn BuiltinHandler) { inst.rootEC.addCmd(name, userBuiltin{fn: fn}) } +func (inst *Inst) SetBuiltinInvokable(name string, fn Invokable) { + inst.rootEC.addCmd(name, fn.inv) +} + type userBuiltin struct { fn func(ctx context.Context, args CallArgs) (any, error) }