Skip to content

Commit 3065778

Browse files
authored
fix: mimic --tla-code behavior from jsonnet for functions in main.jsonnet in env discovery (#1251)
Mimic tla code handling from jsonnet
1 parent 0e930c6 commit 3065778

File tree

4 files changed

+96
-1
lines changed

4 files changed

+96
-1
lines changed

pkg/tanka/evaluators.go

+6-1
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,11 @@ func evalJsonnet(path string, impl types.JsonnetImplementation, opts jsonnet.Opt
2020

2121
// evaluate Jsonnet
2222
if opts.EvalScript != "" {
23+
// Determine if the entrypoint is a function.
24+
isFunction, err := jsonnet.Evaluate(path, impl, fmt.Sprintf("std.isFunction(import '%s')", entrypoint), opts)
25+
if err != nil {
26+
return "", fmt.Errorf("evaluating jsonnet in path '%s': %w", path, err)
27+
}
2328
var tla []string
2429
for k := range opts.TLACode {
2530
tla = append(tla, k+"="+k)
@@ -29,7 +34,7 @@ func evalJsonnet(path string, impl types.JsonnetImplementation, opts jsonnet.Opt
2934
%s
3035
`, entrypoint, opts.EvalScript)
3136

32-
if len(tla) != 0 {
37+
if isFunction == "true\n" {
3338
tlaJoin := strings.Join(tla, ", ")
3439
evalScript = fmt.Sprintf(`
3540
function(%s)

pkg/tanka/evaluators_test.go

+58
Original file line numberDiff line numberDiff line change
@@ -52,3 +52,61 @@ func TestEvalJsonnetWithExpression(t *testing.T) {
5252
})
5353
}
5454
}
55+
56+
// An EvalScript with a top-level function containing only optional arguments
57+
// should be evaluated as a function even if no TLAs are provided.
58+
func TestEvalWithOptionalTlas(t *testing.T) {
59+
opts := jsonnet.Opts{
60+
EvalScript: "main.metadata.name",
61+
}
62+
json, err := evalJsonnet("testdata/cases/with-optional-tlas/main.jsonnet", jsonnetImpl, opts)
63+
assert.NoError(t, err)
64+
assert.Equal(t, `"bar-baz"`, strings.TrimSpace(json))
65+
}
66+
67+
// An EvalScript with a top-level function containing should allow passing only
68+
// a subset of the TLAs.
69+
func TestEvalWithOptionalTlasSpecifiedArg2(t *testing.T) {
70+
opts := jsonnet.Opts{
71+
EvalScript: "main.metadata.name",
72+
TLACode: jsonnet.InjectedCode{"baz": "'changed'"},
73+
}
74+
json, err := evalJsonnet("testdata/cases/with-optional-tlas/main.jsonnet", jsonnetImpl, opts)
75+
assert.NoError(t, err)
76+
assert.Equal(t, `"bar-changed"`, strings.TrimSpace(json))
77+
}
78+
79+
// An EvalScript with a top-level function having no arguments should be
80+
// evaluated as a function even if no TLAs are provided.
81+
func TestEvalFunctionWithNoTlas(t *testing.T) {
82+
opts := jsonnet.Opts{
83+
EvalScript: "main.metadata.name",
84+
}
85+
json, err := evalJsonnet("testdata/cases/function-with-zero-params/main.jsonnet", jsonnetImpl, opts)
86+
assert.NoError(t, err)
87+
assert.Equal(t, `"inline"`, strings.TrimSpace(json))
88+
}
89+
90+
// An EvalScript with a top-level function should return an understandable
91+
// error message if an incorrect TLA is provided.
92+
func TestInvalidTlaArg(t *testing.T) {
93+
opts := jsonnet.Opts{
94+
EvalScript: "main",
95+
TLACode: jsonnet.InjectedCode{"foo": "'bar'"},
96+
}
97+
json, err := evalJsonnet("testdata/cases/function-with-zero-params/main.jsonnet", jsonnetImpl, opts)
98+
assert.Contains(t, err.Error(), "function has no parameter foo")
99+
assert.Equal(t, "", json)
100+
}
101+
102+
// Providing a TLA to an EvalScript with a non-function top level mainfile
103+
// should not return an error.
104+
func TestTlaWithNonFunction(t *testing.T) {
105+
opts := jsonnet.Opts{
106+
EvalScript: "main",
107+
TLACode: jsonnet.InjectedCode{"foo": "'bar'"},
108+
}
109+
json, err := evalJsonnet("testdata/cases/withenv/main.jsonnet", jsonnetImpl, opts)
110+
assert.NoError(t, err)
111+
assert.NotEmpty(t, json)
112+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
function() {
2+
apiVersion: 'tanka.dev/v1alpha1',
3+
kind: 'Environment',
4+
metadata: {
5+
name: 'inline',
6+
},
7+
spec: {
8+
apiServer: 'https://localhost',
9+
namespace: 'inline',
10+
},
11+
data: {
12+
apiVersion: 'v1',
13+
kind: 'ConfigMap',
14+
metadata: { name: 'config' },
15+
},
16+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
function(bar='bar', baz='baz') {
2+
apiVersion: 'tanka.dev/v1alpha1',
3+
kind: 'Environment',
4+
metadata: {
5+
name: bar + '-' + baz,
6+
},
7+
spec: {
8+
apiServer: 'https://localhost',
9+
namespace: 'inline',
10+
},
11+
data: {
12+
apiVersion: 'v1',
13+
kind: 'ConfigMap',
14+
metadata: { name: 'config' },
15+
},
16+
}

0 commit comments

Comments
 (0)