diff --git a/test/examples/code-ref/code.py b/test/examples/code-ref/code.py new file mode 100644 index 0000000..0ce5511 --- /dev/null +++ b/test/examples/code-ref/code.py @@ -0,0 +1,4 @@ + +def update(x): + x["value"] = x["value"] + 1 + return x \ No newline at end of file diff --git a/test/examples/code-ref/pipeline.yaml b/test/examples/code-ref/pipeline.yaml new file mode 100644 index 0000000..084a057 --- /dev/null +++ b/test/examples/code-ref/pipeline.yaml @@ -0,0 +1,26 @@ + +class: Playbook +name: codeTest + +inputs: + startData: + embedded: + - {"value": 0, "name": "alice"} + - {"value": 1, "name": "bob"} + - {"value": 2, "name": "charlie"} + + +pipelines: + codeTest: + - from: startData + - map: + method: update + gpython: + $ref: code.py + - map: + method: update + gpython: | + def update(x): + x["value"] = x["value"] + 1 + return x + - debug: {} \ No newline at end of file diff --git a/transform/code_block.go b/transform/code_block.go new file mode 100644 index 0000000..015171e --- /dev/null +++ b/transform/code_block.go @@ -0,0 +1,45 @@ +package transform + +import ( + "encoding/json" + "fmt" + "os" + "path/filepath" +) + +type CodeBlock struct { + Code string + Ref string + BaseDir string +} + +func (cb *CodeBlock) UnmarshalJSON(data []byte) error { + if err := json.Unmarshal(data, &cb.Code); err == nil { + return nil + } + ref := map[string]any{} + if err := json.Unmarshal(data, &ref); err == nil { + if path, ok := ref["$ref"]; ok { + if pathStr, ok := path.(string); ok { + cb.Ref = pathStr + return nil + } + } + } + return fmt.Errorf("unknown code block type") +} + +func (cb *CodeBlock) SetBaseDir(path string) { + cb.BaseDir = path +} + +func (cb *CodeBlock) String() string { + if cb.Ref != "" { + path := filepath.Join(cb.BaseDir, cb.Ref) + data, err := os.ReadFile(path) + if err == nil { + cb.Code = string(data) + } + } + return cb.Code +} diff --git a/transform/mapping.go b/transform/mapping.go index a2d3ab6..1496010 100644 --- a/transform/mapping.go +++ b/transform/mapping.go @@ -11,9 +11,9 @@ import ( ) type MapStep struct { - Method string `json:"method" jsonschema_description:"Name of function to call"` - Python string `json:"python" jsonschema_description:"Python code to be run"` - GPython string `json:"gpython" jsonschema_description:"Python code to be run using GPython"` + Method string `json:"method" jsonschema_description:"Name of function to call"` + Python string `json:"python" jsonschema_description:"Python code to be run"` + GPython *CodeBlock `json:"gpython" jsonschema_description:"Python code to be run using GPython"` } type mapProcess struct { @@ -30,10 +30,11 @@ func (ms *MapStep) Init(task task.RuntimeTask) (Processor, error) { log.Printf("Compile Error: %s", err) } return &mapProcess{ms, c}, nil - } else if ms.GPython != "" { + } else if ms.GPython != nil { log.Printf("Init Map: %s", ms.GPython) + ms.GPython.SetBaseDir(task.BaseDir()) e := evaluate.GetEngine("gpython", task.WorkDir()) - c, err := e.Compile(ms.GPython, ms.Method) + c, err := e.Compile(ms.GPython.String(), ms.Method) if err != nil { log.Printf("Compile Error: %s", err) }