defenseunicorns / maru-runner

The Unicorn Task Runner
Apache License 2.0
11 stars 1 forks source link

Better API for storing and evaluating variable expressions #155

Open marshall007 opened 1 month ago

marshall007 commented 1 month ago

It would be nice if we tracked variables in a context.Context object and had an API for evaluating (potentially) templated string values like so:

interface Variable {
  Default() interface{}
  Value(context.Context) interface{} // interpolated value
  String() string // original expression
  IsExpression() bool // `true` if raw value contains `${{ ... }}` syntax
}

I think this interface could work for task/action inputs, environment variables, and eventually outputs.

// before
runner.Run(taskFile, "default", setVariables)

// internally `runner.Run(...)` mutates `action` with templated values:
action, err := utils.TemplateTaskActions(nil, action, action.With, r.variableConfig.GetSetVariables())
if action.If == "true" {
  // ...
}
// after
ctx := context.Background()
run := runner.New(tasksFile, runner.WithContext(ctx), runner.WithEnv(os.Getenv))

task := run.Task("default", inputs) // run task named `default`
task.Outputs() // => map[string]Variable

// internally `run.Task(...)` etc uses API like:
if action.If.Value(ctx) == "true" {
  // ...
}

This is basically what I was trying to do in #117 (see runner.Resolve(taskName)) but it's a very difficult refactor.

_Originally posted by @marshall007 in https://github.com/defenseunicorns/maru-runner/pull/139#discussion_r1765594139_

marshall007 commented 1 month ago

@zachariahmiller Appreciate the feedback @marshall007. In the interest of our immediate priorities though have to agree with @Racer159. Good tech debt issue or target of that elusive 2.0 we discussed previously that is more fully featured.