@@ -4,14 +4,23 @@ import (
44 "bytes"
55 "context"
66 "encoding/json"
7+ "errors"
8+ "fmt"
79 "path/filepath"
810
9- "github.com/santhosh-tekuri/jsonschema/v5"
11+ jsvalidate "github.com/santhosh-tekuri/jsonschema/v5"
1012
1113 "github.com/launchrctl/launchr/pkg/cli"
14+ "github.com/launchrctl/launchr/pkg/jsonschema"
1215 "github.com/launchrctl/launchr/pkg/types"
1316)
1417
18+ var (
19+ errInvalidProcessor = errors .New ("invalid configuration, processor is required" )
20+ errTplNotApplicableProcessor = "invalid configuration, processor can't be applied to value of type %s"
21+ errTplNonExistProcessor = "requested processor %q doesn't exist"
22+ )
23+
1524// Action is an action definition with a contextual id (name), working directory path
1625// and a runtime context such as input arguments and options.
1726type Action struct {
@@ -25,8 +34,9 @@ type Action struct {
2534 fpath string // fpath is a path to action definition file.
2635 def * Definition // def is an action definition. Loaded by Loader, may be nil when not initialized.
2736
28- env RunEnvironment // env is the run environment driver to execute the action.
29- input Input // input is a container for env variables.
37+ env RunEnvironment // env is the run environment driver to execute the action.
38+ input Input // input is a container for env variables.
39+ processors map [string ]ValueProcessor // processors are ValueProcessors for manipulating input.
3040}
3141
3242// Input is a container for action input arguments and options.
@@ -68,6 +78,16 @@ func (a *Action) Clone() *Action {
6878 return c
6979}
7080
81+ // SetProcessors sets the value processors for an Action.
82+ func (a * Action ) SetProcessors (list map [string ]ValueProcessor ) {
83+ a .processors = list
84+ }
85+
86+ // GetProcessors returns processors map.
87+ func (a * Action ) GetProcessors () map [string ]ValueProcessor {
88+ return a .processors
89+ }
90+
7191// Reset unsets loaded action to force reload.
7292func (a * Action ) Reset () { a .def = nil }
7393
@@ -128,14 +148,94 @@ func (a *Action) SetInput(input Input) (err error) {
128148 //if err = a.ValidateInput(input); err != nil {
129149 // return err
130150 //}
151+
152+ err = a .processArgs (input .Args )
153+ if err != nil {
154+ return err
155+ }
156+
157+ err = a .processOptions (input .Opts )
158+ if err != nil {
159+ return err
160+ }
161+
131162 a .input = input
132163 // Reset to load the action file again with new replacements.
133164 a .Reset ()
134165 return a .EnsureLoaded ()
135166}
136167
168+ func (a * Action ) processOptions (opts TypeOpts ) error {
169+ for _ , optDef := range a .ActionDef ().Options {
170+ if _ , ok := opts [optDef .Name ]; ! ok {
171+ continue
172+ }
173+
174+ value := opts [optDef .Name ]
175+ toApply := optDef .Process
176+
177+ value , err := a .processValue (value , optDef .Type , toApply )
178+ if err != nil {
179+ return err
180+ }
181+
182+ opts [optDef .Name ] = value
183+ }
184+
185+ return nil
186+ }
187+
188+ func (a * Action ) processArgs (args TypeArgs ) error {
189+ for _ , argDef := range a .ActionDef ().Arguments {
190+ if _ , ok := args [argDef .Name ]; ! ok {
191+ continue
192+ }
193+
194+ value := args [argDef .Name ]
195+ toApply := argDef .Process
196+ value , err := a .processValue (value , argDef .Type , toApply )
197+ if err != nil {
198+ return err
199+ }
200+
201+ args [argDef .Name ] = value
202+ }
203+
204+ return nil
205+ }
206+
207+ func (a * Action ) processValue (value interface {}, valueType jsonschema.Type , toApplyProcessors []ValueProcessDef ) (interface {}, error ) {
208+ newValue := value
209+ processors := a .GetProcessors ()
210+
211+ for _ , processor := range toApplyProcessors {
212+ if processor .Processor == "" {
213+ return value , errInvalidProcessor
214+ }
215+
216+ proc , ok := processors [processor .Processor ]
217+ if ! ok {
218+ return value , fmt .Errorf (errTplNonExistProcessor , processor .Processor )
219+ }
220+
221+ if ! proc .IsApplicable (valueType ) {
222+ return value , fmt .Errorf (errTplNotApplicableProcessor , valueType )
223+ }
224+
225+ processedValue , err := proc .Execute (newValue , processor .Options )
226+ if err != nil {
227+ return value , err
228+ }
229+
230+ newValue = processedValue
231+ }
232+
233+ return newValue , nil
234+ }
235+
137236// ValidateInput validates arguments and options according to
138237// a specified json schema in action definition.
238+ // @todo move to jsonschema
139239func (a * Action ) ValidateInput (inp Input ) error {
140240 jsch := a .JSONSchema ()
141241 // @todo cache jsonschema and resources.
@@ -144,7 +244,7 @@ func (a *Action) ValidateInput(inp Input) error {
144244 return err
145245 }
146246 buf := bytes .NewBuffer (b )
147- c := jsonschema .NewCompiler ()
247+ c := jsvalidate .NewCompiler ()
148248 err = c .AddResource (a .Filepath (), buf )
149249 if err != nil {
150250 return err
0 commit comments