Skip to content

Commit

Permalink
fix: templating: allow templating to render empty string as result
Browse files Browse the repository at this point in the history
Signed-off-by: Romain Beuque <romain.beuque@corp.ovh.com>
  • Loading branch information
rbeuque74 committed Mar 23, 2020
1 parent e2b89be commit 4a62900
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 12 deletions.
21 changes: 21 additions & 0 deletions engine/engine_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import (
"github.com/loopfz/gadgeto/zesty"
"github.com/ovh/configstore"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"

"github.com/ovh/utask"
"github.com/ovh/utask/db"
Expand Down Expand Up @@ -625,6 +626,26 @@ func TestBaseOutput(t *testing.T) {
assert.Equal(t, "bar", output["foo"])
}

func TestEmptyStringInput(t *testing.T) {
input := map[string]interface{}{
"quantity": -2.3,
"foo": "",
}
res, err := createResolution("input.yaml", input, nil)
assert.NotNil(t, res)
assert.Nil(t, err)

res, err = runResolution(res)

require.Nilf(t, err, "got error %s", err)
require.NotNil(t, res)
assert.Equal(t, resolution.StateDone, res.State)
assert.Equal(t, step.StateDone, res.Steps["stepOne"].State)

output := res.Steps["stepOne"].Output.(map[string]interface{})
assert.Equal(t, "", output["foo"])
}

func TestScriptPlugin(t *testing.T) {
argv := "world"
res, err := createResolution("execScript.yaml", map[string]interface{}{"argv": argv}, nil)
Expand Down
31 changes: 20 additions & 11 deletions engine/step/apply.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,16 @@ package step
import (
"bytes"
"encoding/json"
"errors"
"reflect"

"github.com/ovh/utask/engine/values"
)

var (
errNotTemplatable = errors.New("value given is not templatable")
)

func resolveObject(val *values.Values, objson json.RawMessage, item interface{}, stepName string) ([]byte, error) {
obj, err := rawResolveObject(val, objson, item, stepName)
if err != nil {
Expand Down Expand Up @@ -61,12 +66,14 @@ func applyMap(val *values.Values, v reflect.Value, item interface{}, stepName st
applySlice(val, mv, item, stepName)
case reflect.String:
newValue, err := applyString(val, mv, item, stepName)
if err != nil {
return err
}

if newValue != "" {
switch err {
case nil:
v.SetMapIndex(iter.Key(), reflect.ValueOf(newValue))
case errNotTemplatable:
// current value Kind is string, but actual type could not be string (e.g. json.Number)
// in that case, we should keep the actual value as it will never be templated
default:
return err
}
}
}
Expand All @@ -90,12 +97,14 @@ func applySlice(val *values.Values, v reflect.Value, item interface{}, stepName
applySlice(val, elem, item, stepName)
case reflect.String:
newValue, err := applyString(val, elem, item, stepName)
if err != nil {
return err
}

if newValue != "" {
switch err {
case nil:
mv.Set(reflect.ValueOf(newValue))
case errNotTemplatable:
// current value Kind is string, but actual type could not be string (e.g. json.Number)
// in that case, we should keep the actual value as it will never be templated
default:
return err
}
}
}
Expand All @@ -107,7 +116,7 @@ func applyString(val *values.Values, v reflect.Value, item interface{}, stepName
strval := v.Interface()
str, ok := strval.(string)
if !ok {
return "", nil
return "", errNotTemplatable
}
resolved, err := val.Apply(str, item, stepName)
if err != nil {
Expand Down
7 changes: 6 additions & 1 deletion engine/templates_tests/input.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,16 @@ inputs:
collection: false
type: number
optional: false
- name: foo
description: A string value
type: string
optional: true
default: ""
steps:
stepOne:
description: first step
idempotent: true
retry_pattern: seconds
action:
type: echo
configuration: {output: {value: "{{.input.quantity}}"}}
configuration: {output: {value: "{{.input.quantity}}", foo: "{{.input.foo}}"}}

0 comments on commit 4a62900

Please sign in to comment.